Skip to content

Commit f50f97e

Browse files
Skobeltsynclaude
andcommitted
release: v0.4.4
First Maven Central release after v0.4.2. Folds in 13 commits: - KSP arc: #1700 validation, #1701 data-class schema gen, #1702 sealed schema gen, #1703 toLlmDescription codegen, #1704 constructFromMap codegen, #1705 reflect-free runtime - `wrap` operator (#1698) + guessing-game tests (#1699) - BC pin completeness (was v0.4.3, never published) (#1695) - Bouncy Castle verification-metadata trust for 1.84 + Gradle 9.5.0 src.zip + Kotlin 2.3.20 metadata - Gradle wrapper 9.4.1 → 9.5.0 - kotlinx-coroutines 1.10.2 → 1.11.0 Internal `v0.4.3` tag exists on GitHub from the BC ksp-pin work but was never uploaded to Sonatype — its content is in 0.4.4. Consumers skipping straight from 0.4.2 to 0.4.4 see all of it. The KSP arc + reflect-free runtime is the headline: - :agents-kt-ksp processor now does real work (#1018 skeleton retired). Generates `<FQN>__GeneratedSchema.kt` per @generable class carrying JSON_SCHEMA, LLM_DESCRIPTION, and (for eligible shapes) @JvmStatic constructFromMap. - Runtime KClass.jsonSchema / toLlmDescription / constructFromMap prefer the generated constant; reflection fallback wrapped via ReflectionFallback.withReflection for graceful LinkageError degradation. - kotlin-reflect dropped from runtime classpath (compileOnly). Published POM contains zero kotlin-reflect references — consumers see a ~3.5 MB lighter dep tree if they apply KSP. Source-compatible with 0.4.2. New public API surface only (`wrap` infix; `:agents-kt-ksp` processor capabilities). Drop-in for the existing API. Test count: 973 root + 56 KSP = 1029 unit tests, 0 failures. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 3200b95 commit f50f97e

5 files changed

Lines changed: 133 additions & 71 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@
22

33
All notable changes to Agents.KT are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Pre-1.0, minor bumps may add new public API; existing API surface is preserved.
44

5-
## [0.4.3] — 2026-05-12
5+
## [0.4.4] — 2026-05-13
6+
7+
First Maven Central release after **v0.4.2**. Internal tags `v0.4.3` (BC pin completeness) existed on GitHub but never reached Maven Central; their content is folded into 0.4.4 alongside the KSP arc and the `wrap` operator. Skip straight to 0.4.4:
8+
9+
```kotlin
10+
implementation("ai.deep-code:agents-kt:0.4.4")
11+
```
12+
13+
## [0.4.3-unpublished] — 2026-05-12
614

715
### Added
816
- **KSP validation pass for `@Generable`** — the `:agents-kt-ksp` skeleton that's shipped since 0.3.0 (#1018) is now wired to do real work. The processor walks every `@Generable` class in the consumer's compilation and emits compile-time errors for shapes the framework can't actually construct from JSON: non-sealed interfaces, annotation classes, enums, abstract classes, and classes without a parameterised primary constructor. Sealed types short-circuit — they route through the polymorphic / `type` discriminator path that `GenerableSupport.sealedJsonSchema` already handles. Errors point at the offending declaration so the IDE shows red squiggles where the user can fix them. Schema-generation pass (replacing runtime reflection) is the next KSP increment; this issue closes the validation half (#1700).

PUBLISHING.md

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ Escape newlines as `\n` for the property file.
5757
./gradlew publishMavenCentralPublicationToMavenLocal
5858
```
5959

60-
Artifacts land in `~/.m2/repository/ai/deep-code/agents-kt/0.4.3/`.
60+
Artifacts land in `~/.m2/repository/ai/deep-code/agents-kt/0.4.4/`.
6161

6262
### 2. Generate checksums and create bundle
6363

6464
```bash
65-
SRC=~/.m2/repository/ai/deep-code/agents-kt/0.4.3
66-
DEST=build/bundle/ai/deep-code/agents-kt/0.4.3
65+
SRC=~/.m2/repository/ai/deep-code/agents-kt/0.4.4
66+
DEST=build/bundle/ai/deep-code/agents-kt/0.4.4
6767
mkdir -p "$DEST"
6868

6969
for f in "$SRC"/agents-kt-*; do
@@ -78,17 +78,17 @@ done
7878

7979
```bash
8080
cd build/bundle
81-
zip -r ../agents-kt-0.4.3-bundle.zip ai/
81+
zip -r ../agents-kt-0.4.4-bundle.zip ai/
8282
```
8383

84-
The ZIP must contain the full path: `ai/deep-code/agents-kt/0.4.3/...`
84+
The ZIP must contain the full path: `ai/deep-code/agents-kt/0.4.4/...`
8585

8686
## Upload to Central Portal
8787

8888
1. Go to [central.sonatype.com](https://central.sonatype.com)**Deployments****Publish Component**
89-
2. **Deployment Name:** `ai.deep-code:agents-kt:0.4.3`
89+
2. **Deployment Name:** `ai.deep-code:agents-kt:0.4.4`
9090
3. **Description:** `Typed Kotlin DSL framework for AI agent systems`
91-
4. Upload `build/agents-kt-0.4.3-bundle.zip`
91+
4. Upload `build/agents-kt-0.4.4-bundle.zip`
9292
5. Wait for validation to pass
9393
6. Click **Publish**
9494

@@ -99,27 +99,27 @@ Propagation to Maven Central search takes 10-30 minutes after publishing.
9999
Each artifact needs: the file itself, `.asc` (GPG signature), `.md5`, and `.sha1`.
100100

101101
```
102-
ai/deep-code/agents-kt/0.4.3/
103-
agents-kt-0.4.3.jar
104-
agents-kt-0.4.3.jar.asc
105-
agents-kt-0.4.3.jar.md5
106-
agents-kt-0.4.3.jar.sha1
107-
agents-kt-0.4.3-sources.jar
108-
agents-kt-0.4.3-sources.jar.asc
109-
agents-kt-0.4.3-sources.jar.md5
110-
agents-kt-0.4.3-sources.jar.sha1
111-
agents-kt-0.4.3-javadoc.jar
112-
agents-kt-0.4.3-javadoc.jar.asc
113-
agents-kt-0.4.3-javadoc.jar.md5
114-
agents-kt-0.4.3-javadoc.jar.sha1
115-
agents-kt-0.4.3.pom
116-
agents-kt-0.4.3.pom.asc
117-
agents-kt-0.4.3.pom.md5
118-
agents-kt-0.4.3.pom.sha1
119-
agents-kt-0.4.3.module
120-
agents-kt-0.4.3.module.asc
121-
agents-kt-0.4.3.module.md5
122-
agents-kt-0.4.3.module.sha1
102+
ai/deep-code/agents-kt/0.4.4/
103+
agents-kt-0.4.4.jar
104+
agents-kt-0.4.4.jar.asc
105+
agents-kt-0.4.4.jar.md5
106+
agents-kt-0.4.4.jar.sha1
107+
agents-kt-0.4.4-sources.jar
108+
agents-kt-0.4.4-sources.jar.asc
109+
agents-kt-0.4.4-sources.jar.md5
110+
agents-kt-0.4.4-sources.jar.sha1
111+
agents-kt-0.4.4-javadoc.jar
112+
agents-kt-0.4.4-javadoc.jar.asc
113+
agents-kt-0.4.4-javadoc.jar.md5
114+
agents-kt-0.4.4-javadoc.jar.sha1
115+
agents-kt-0.4.4.pom
116+
agents-kt-0.4.4.pom.asc
117+
agents-kt-0.4.4.pom.md5
118+
agents-kt-0.4.4.pom.sha1
119+
agents-kt-0.4.4.module
120+
agents-kt-0.4.4.module.asc
121+
agents-kt-0.4.4.module.md5
122+
agents-kt-0.4.4.module.sha1
123123
```
124124

125125
## Version Bump

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ Use Maven Central for published artifacts and tags for immutable release points.
200200
```kotlin
201201
// build.gradle.kts
202202
dependencies {
203-
implementation("ai.deep-code:agents-kt:0.4.3")
203+
implementation("ai.deep-code:agents-kt:0.4.4")
204204
}
205205
```
206206

RELEASE_NOTES.md

Lines changed: 94 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,117 @@
1-
# Agents.KT v0.4.3Complete BC Pin Across Both Modules
1+
# Agents.KT v0.4.4KSP, `wrap`, and reflect-free runtime
22

3-
**Release date:** 2026-05-12
3+
**Release date:** 2026-05-13
44

5-
Functionally identical to v0.4.2. Consumer-visible POMs and `runtimeClasspath` are byte-for-byte the same. The only change is finishing what v0.4.2 started — pinning BouncyCastle 1.84 in the `:agents-kt-ksp` subproject too, so all four dependabot advisories can finally clear.
5+
First Maven Central release after **v0.4.2**. The internal `v0.4.3` tag existed on GitHub but never reached Maven Central — its content (BC pin completeness across both Gradle modules) is folded into 0.4.4 alongside the KSP arc, the `wrap` operator, and a reflect-free runtime.
66

7-
## What changed since v0.4.2
7+
```kotlin
8+
implementation("ai.deep-code:agents-kt:0.4.4")
9+
```
10+
11+
Same artifact coordinates as before. Drop-in for 0.4.2 — every new public API has defaults; existing 0.4.x code compiles unchanged.
12+
13+
---
814

9-
v0.4.2 added explicit `compileOnly("org.bouncycastle:*:1.84")` declarations + a `force(...)` block to the **root** `build.gradle.kts`, giving Dependabot visible 1.84 nodes in the root project's submitted graph.
15+
## What's new since v0.4.2
1016

11-
But the **`:agents-kt-ksp` subproject** never got the same treatment. Its `kotlinBouncyCastleConfiguration` kept resolving to BC 1.80 transitively (Kotlin Gradle plugin pulls it for jar signing), and Dependabot's per-subproject graph submission kept showing 1.80, keeping the four advisories alive.
17+
### The KSP arc — `@Generable` is now compile-time
1218

13-
v0.4.3 mirrors the v0.4.2 fix into `agents-kt-ksp/build.gradle.kts`:
19+
A six-step progression replaces every reflection walk for `@Generable` types with KSP-generated companion objects. Apply `:agents-kt-ksp` in your build and:
1420

1521
```kotlin
16-
// agents-kt-ksp/build.gradle.kts
17-
configurations.all {
18-
resolutionStrategy {
19-
force(
20-
"org.bouncycastle:bcprov-jdk18on:1.84",
21-
"org.bouncycastle:bcpg-jdk18on:1.84",
22-
"org.bouncycastle:bcpkix-jdk18on:1.84",
23-
"org.bouncycastle:bcutil-jdk18on:1.84",
24-
)
25-
}
22+
// build.gradle.kts
23+
plugins {
24+
id("com.google.devtools.ksp") version "2.3.7-1.x"
2625
}
27-
2826
dependencies {
29-
// ... existing deps ...
30-
compileOnly("org.bouncycastle:bcprov-jdk18on:1.84")
31-
compileOnly("org.bouncycastle:bcpg-jdk18on:1.84")
32-
compileOnly("org.bouncycastle:bcpkix-jdk18on:1.84")
33-
compileOnly("org.bouncycastle:bcutil-jdk18on:1.84")
27+
implementation("ai.deep-code:agents-kt:0.4.4")
28+
ksp("ai.deep-code:agents-kt-ksp:0.4.4")
3429
}
3530
```
3631

37-
Stale BC 1.80 entries in `gradle/verification-metadata.xml` (cumulative cruft from the original 1.80 era) were also pruned — only the 1.84 checksums remain.
38-
39-
After v0.4.3 lands on `main`, the next `gradle/actions/dependency-submission` workflow run submits a clean 1.84-everywhere graph for both modules, and the four dependabot alerts should clear.
32+
What lights up for every `@Generable` class in your code:
4033

41-
## Inherited from v0.4.2
34+
| What runs today | What ships in 0.4.4 with KSP applied |
35+
|---|---|
36+
| `KClass.jsonSchema()` walks the class reflectively on every call | Reads a `const val JSON_SCHEMA: String` baked at compile time. Byte-identical output. (#1701, #1702) |
37+
| `KClass.toLlmDescription()` walks + checks `@Guide` annotations | Reads a `const val LLM_DESCRIPTION: String`. `@LlmDescription(text)` override is baked into the constant. (#1703) |
38+
| `KClass.constructFromMap(map)` reflects to find the primary ctor and invokes via `callBy` | Calls a `@JvmStatic constructFromMap(Map<*,Any?>): T?` with named-arg construction. Strict overflow / type rejection preserved (#665, #855). (#1704) |
39+
| Sealed roots reflect through `sealedSubclasses` | Generated `oneOf` schema with `"type"` discriminators; generated dispatch by type-name to each variant's `constructFromMap`. (#1702, #1704) |
4240

43-
Same as v0.4.2 — see the v0.4.2 release notes for the full feature set since 0.3.0:
41+
**Compile-time error coverage.** The processor also catches `@Generable` misuses at build time — non-sealed interfaces, annotation classes, enums, abstract classes, classes without a parameterised primary constructor, and fields with types outside the supported set (`String`, `Int`, `Long`, `Double`, `Float`, `Boolean`, `List<T>`, nested `@Generable`). What used to be a silent `{"type":"string"}` fallback at runtime is now a red squiggle in the IDE (#1700, #1701).
4442

45-
- Three model providers — Ollama, Claude, OpenAI (#1644, #1656)
46-
- LiveRunner precheck hook + `OllamaPreflight` (#1132)
47-
- Live typed-args integration tests across all three providers (#1675)
48-
- `ModelConfig.toString()` masks `apiKey` (#1665)
49-
- Ollama wire-shape fix: `content: null` on assistant tool-call turns (#1694)
50-
- Dependency refresh: `kotlinx-coroutines` 1.11.0, Gradle 9.5.0
51-
- BC 1.84 pinned visibly in root module (#1695, v0.4.2)
43+
**`kotlin-reflect` is no longer on the runtime classpath.** Moved from `implementation` to `compileOnly` in the published POM. Consumers see a ~3.5 MB lighter dependency tree. Reflection-using fallback paths still work for consumers who add `kotlin-reflect` themselves; for everyone else, the `ReflectionFallback.withReflection { ... }` wrap catches `LinkageError` and degrades gracefully — typed-tool deserialization returns null and routes through `onError.invalidArgs` instead of crashing (#1705).
5244

53-
## Migration from v0.4.2
45+
**Defensive emission gate.** Sealed `@Generable` parents whose variants aren't visible to KSP (incremental-compile race, edge cases) skip schema emission; reflection takes over at runtime against the full JVM hierarchy. Single safety net for the case where the codegen view of the world is incomplete (#1705).
5446

55-
Drop-in. Nothing to do.
47+
### The `wrap` operator — teacher / student prompt override
5648

57-
## Migration from 0.3.x
49+
`teacher wrap student` is a new composition operator: the teacher agent's String output becomes the student's system prompt for one call only. The student's baked-in prompt is restored after.
5850

5951
```kotlin
60-
implementation("ai.deep-code:agents-kt:0.4.3")
52+
val teacher = agent<String, String>("teacher") {
53+
skills { skill<String, String>("brief", "Produce a prompt") {
54+
implementedBy { topic -> "You are a $topic specialist. Answer concisely." }
55+
} }
56+
}
57+
val worker = agent<String, String>("worker") {
58+
prompt("baked-in default")
59+
model { claude("claude-haiku-4-5-20251001"); apiKey = key }
60+
skills { skill<String, String>("answer", "Answer using the prompt") { tools() } }
61+
}
62+
63+
val pipeline = teacher wrap worker
64+
val result = pipeline("Kotlin coroutines")
65+
// teacher emits "You are a Kotlin coroutines specialist. Answer concisely."
66+
// worker invokes Claude with that as its system prompt
6167
```
6268

63-
(Or skip directly from 0.3.x to 0.4.3; v0.4.0, v0.4.1, and v0.4.2 details are in their own release notes if you want the breadcrumb trail.)
69+
Two framings the test suite proves out:
70+
71+
- **Education** — one generalist student is reused across many narrow jobs because the teacher hands it task-specific context. Headline test: the teacher tells the student to compute Fibonacci via a `fib` tool; same student, different prompts, different jobs (#1698).
72+
- **Security** — the teacher locks down the student's task surface for the call. The student can't drift to its default prompt. Demonstrated by the guessing-game test (#1699): an oracle agent narrows the search window after each round; the guesser agent reads the teacher-supplied prompt and binary-searches to find the secret.
73+
74+
Live cross-provider proof in the integration suite: Claude as the teacher emits the prompt, Ollama as the student computes `fib(10)` via its registered tool (#1698 live test).
75+
76+
`wrap` returns a `Pipeline<IN, OUT>`, so it composes with `then` / `Pipeline.loop {}` / the rest. Closes the last open Phase 1 PRD item.
77+
78+
### BouncyCastle pin completeness
79+
80+
Internal tag `v0.4.3` existed on GitHub to complete the BC 1.84 pin in the `:agents-kt-ksp` subproject too, plus prune stale 1.80 entries from `gradle/verification-metadata.xml`. That work is folded into 0.4.4 (#1695, never reached Maven Central). The four dependabot advisories on `main` (BCprov / BCpg / BCpkix / BCutil 1.80) should clear after the next scanner pass.
81+
82+
### Other
83+
84+
- Gradle wrapper 9.4.1 → 9.5.0 (was prepped during the BC pass).
85+
- `kotlinx-coroutines-core` and `kotlinx-coroutines-test` 1.10.2 → 1.11.0.
86+
- Live integration tests for the wrap operator across Claude (teacher) + Ollama (student) (#1698 live test, #1699 live test).
87+
88+
---
89+
90+
## Migration
91+
92+
### From v0.4.2 (the previous published release)
93+
94+
Drop-in for the existing API surface. Two consumer-side changes to be aware of:
95+
96+
1. **`kotlin-reflect` is no longer on the runtime classpath.** If you don't apply `:agents-kt-ksp` AND you use `@Generable` types, the reflection paths degrade to null returns + placeholder schemas. Recommended fix: apply `:agents-kt-ksp` (covers every `@Generable` hot path). Alternative: add `kotlin-reflect` to your own dependency declarations.
97+
98+
2. **`wrap` is new infix syntax.** Code that uses `wrap` as a function name on its own types won't collide unless it's also `infix`-on-Agent-targeted; conflict is unlikely. Aliasing `import agents_engine.composition.wrap.wrap as wrapInto` if needed.
99+
100+
### From v0.3.x or earlier
101+
102+
Same as v0.4.2 migration (three model providers, fail-fast precheck, masked `apiKey` toString) — see the v0.4.2 release notes for the full intermediate-jump story — plus the v0.4.4 changes above.
103+
104+
---
105+
106+
## What's next
107+
108+
Open PRD items after this release:
109+
110+
- **Constrained-decoding integration** — wire the already-generated `JSON_SCHEMA` constants into Ollama's structured-output mode, Anthropic's `tool` JSON-mode, and OpenAI's `response_format` JSON-mode. Provider-side enforcement instead of the prompt-fragment approach.
111+
- **`Tool<IN, OUT>` hierarchy + `McpTool<IN, OUT>`** — unlocks typed `grants { tools(writeFile, mcpServer.fooTool) }` permissions.
112+
- **Structure-level budgets**`budget { }` on Pipeline / Forum / Parallel / Loop.
113+
- **Streaming (`Flow<LlmResponseChunk>`)** — the dead-air-spinner killer; touches `ModelClient` and all three adapters.
114+
- **Native CLI binary (GraalVM)** — KSP-generated code is now AOT-friendly, so this is unblocked.
115+
- **Gemini adapter** — finishes the multi-provider line.
116+
117+
Full breakdown in [`docs/roadmap.md`](docs/roadmap.md).

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ plugins {
66
}
77

88
group = "ai.deep-code"
9-
version = "0.4.3"
9+
version = "0.4.4"
1010

1111
repositories {
1212
mavenCentral()

0 commit comments

Comments
 (0)