@aexhq/agentloop-pi 6.1.3 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -1
- package/dist/index.mjs +5 -1
- package/dist/loop.component.wasm +0 -0
- package/index.d.ts +2 -0
- package/package.json +9 -5
- package/src/index.mjs +2 -0
- package/src/logic.mjs +11 -2
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ siblings. For hosted applications, publish bytes with Aex's attachment API and r
|
|
|
62
62
|
Compaction explicitly resets the response format and installs a summary only after `end_turn`;
|
|
63
63
|
a truncated, refused, or unknown summary leaves the original saved context intact.
|
|
64
64
|
|
|
65
|
-
Version 6.
|
|
65
|
+
Version 6.2 targets Brain SDK 0.25 and preserves the 0.23 WIT and URL-media contract. Existing sessions keep their
|
|
66
66
|
immutable loop implementation; create new sessions to adopt the updated loop. Keep matching
|
|
67
67
|
server/artifacts for recovery. An upgrade does not migrate or delete session data.
|
|
68
68
|
|
|
@@ -81,3 +81,17 @@ without rebuilding Wasm. Run `npm test -w packages/loop-pi` for the Component bu
|
|
|
81
81
|
tests, then the compiled journeys described in the repository README. All release gates remain
|
|
82
82
|
required. A rebuilt Component needs a new admission and session. Package source is not a public
|
|
83
83
|
logic-library entry point, and existing sessions keep their admitted implementation.
|
|
84
|
+
|
|
85
|
+
## Hosted structured output
|
|
86
|
+
|
|
87
|
+
Set `output: { schema: jsonSchema, maxCorrections: 2 }` on the loop to validate JSON Schema
|
|
88
|
+
2020-12 inside the hosted turn. `z.toJSONSchema(schema)` supplies a schema from Zod. Schemas
|
|
89
|
+
compile strictly before model effects: unknown keywords, unresolved external references and
|
|
90
|
+
unsupported patterns fail explicitly. Standard formats are validated without coercion.
|
|
91
|
+
|
|
92
|
+
Corrections run without tools and retain previous results. They finish in the same turn when
|
|
93
|
+
using `session.submit()`, without a client process driving extra turns. Only a valid final
|
|
94
|
+
answer emits `assistant_message`; its parsed value is the turn result. Refusal, truncation,
|
|
95
|
+
provider failure and cancellation do not trigger formatting retries. Corrections default to
|
|
96
|
+
two, with a supported range of zero through ten. Application business rules still belong in
|
|
97
|
+
its tools or persistence boundary.
|
package/dist/index.mjs
CHANGED
|
@@ -9,7 +9,11 @@ var options = z.object({
|
|
|
9
9
|
// contextWindow - reserveTokens, keep ~keepRecentTokens of recent messages.
|
|
10
10
|
reserveTokens: z.number().int().positive().default(16384),
|
|
11
11
|
keepRecentTokens: z.number().int().positive().default(2e4),
|
|
12
|
-
compaction: z.boolean().default(true)
|
|
12
|
+
compaction: z.boolean().default(true),
|
|
13
|
+
output: z.strictObject({
|
|
14
|
+
schema: z.union([z.boolean(), z.record(z.string(), z.unknown())]),
|
|
15
|
+
maxCorrections: z.number().int().min(0).max(10).default(2)
|
|
16
|
+
}).optional()
|
|
13
17
|
}).strict();
|
|
14
18
|
var pi = agentloop({
|
|
15
19
|
options,
|
package/dist/loop.component.wasm
CHANGED
|
Binary file
|
package/index.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export interface PiOptions {
|
|
|
12
12
|
readonly keepRecentTokens?: number;
|
|
13
13
|
/** Disable automatic compaction entirely. Default true (enabled). */
|
|
14
14
|
readonly compaction?: boolean;
|
|
15
|
+
/** Hosted JSON Schema 2020-12 validation. Corrections run without tools in the same turn. */
|
|
16
|
+
readonly output?: { readonly schema: boolean | Readonly<Record<string, unknown>>; readonly maxCorrections?: number };
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export declare const pi: (options: PiOptions) => PlacedAgentloop;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aexhq/agentloop-pi",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"description": "Pi-style parallel-Tool Brain extension",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -19,7 +19,10 @@
|
|
|
19
19
|
"tag": "next"
|
|
20
20
|
},
|
|
21
21
|
"exports": {
|
|
22
|
-
".": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./index.d.ts",
|
|
24
|
+
"import": "./dist/index.mjs"
|
|
25
|
+
},
|
|
23
26
|
"./package.json": "./package.json"
|
|
24
27
|
},
|
|
25
28
|
"files": [
|
|
@@ -37,8 +40,9 @@
|
|
|
37
40
|
"prepack": "npm run build"
|
|
38
41
|
},
|
|
39
42
|
"dependencies": {
|
|
40
|
-
"@aexhq/brain": "0.
|
|
43
|
+
"@aexhq/brain": "0.25.1",
|
|
44
|
+
"ajv": "8.20.0",
|
|
45
|
+
"ajv-formats": "3.0.1",
|
|
41
46
|
"zod": "4.4.3"
|
|
42
|
-
}
|
|
43
|
-
"devDependencies": {}
|
|
47
|
+
}
|
|
44
48
|
}
|
package/src/index.mjs
CHANGED
|
@@ -9,6 +9,8 @@ const options = z.object({
|
|
|
9
9
|
reserveTokens: z.number().int().positive().default(16_384),
|
|
10
10
|
keepRecentTokens: z.number().int().positive().default(20_000),
|
|
11
11
|
compaction: z.boolean().default(true),
|
|
12
|
+
output: z.strictObject({ schema: z.union([z.boolean(), z.record(z.string(), z.unknown())]),
|
|
13
|
+
maxCorrections: z.number().int().min(0).max(10).default(2) }).optional(),
|
|
12
14
|
}).strict();
|
|
13
15
|
|
|
14
16
|
export const pi = agentloop({
|
package/src/logic.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { toolPlacement } from "../../../shared/tool-placement.mjs";
|
|
2
2
|
import { observeEvents } from "../../../shared/loop-events.mjs";
|
|
3
3
|
import { toolResult } from "../../../shared/tool-output.mjs";
|
|
4
|
+
import { structuredOutput } from "../../../shared/structured-output.mjs";
|
|
4
5
|
|
|
5
6
|
const CHECKPOINT_PREFIX = "Context checkpoint from earlier in this conversation:\n\n";
|
|
6
7
|
|
|
@@ -64,6 +65,7 @@ export async function runPi(input, context) {
|
|
|
64
65
|
...input.configuration,
|
|
65
66
|
};
|
|
66
67
|
const placement = toolPlacement(input.tools, options);
|
|
68
|
+
const output = structuredOutput(options.output);
|
|
67
69
|
const transcript = cloneJson(input.transcript);
|
|
68
70
|
const observed_sequence = await observeEvents(context, transcript, (await context.kv.read("observed_sequence")) ?? 0);
|
|
69
71
|
const saved = await context.kv.read("checkpoint");
|
|
@@ -111,7 +113,7 @@ export async function runPi(input, context) {
|
|
|
111
113
|
await context.setTranscript(transcript);
|
|
112
114
|
await context.kv.put("checkpoint", checkpoint);
|
|
113
115
|
}
|
|
114
|
-
const { message, stop_reason } = await context.model({ messages: transcript, tools: placement.definitions });
|
|
116
|
+
const { message, stop_reason } = await context.model(output?.request(transcript, placement.definitions) ?? { messages: transcript, tools: placement.definitions });
|
|
115
117
|
transcript.push(message);
|
|
116
118
|
await context.setTranscript(transcript);
|
|
117
119
|
await context.kv.put("checkpoint", checkpoint);
|
|
@@ -119,9 +121,16 @@ export async function runPi(input, context) {
|
|
|
119
121
|
.filter((block) => block.type === "tool_use")
|
|
120
122
|
.map((block) => ({ call_id: block.id, name: block.name, input: block.input }));
|
|
121
123
|
if (calls.length === 0) {
|
|
124
|
+
const final = output?.accept(text(message), stop_reason);
|
|
125
|
+
if (final?.correction) {
|
|
126
|
+
transcript.push(final.correction);
|
|
127
|
+
await context.setTranscript(transcript);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
122
130
|
await context.emit("output_emitted", { type: "assistant_message", message: text(message) });
|
|
123
|
-
return {};
|
|
131
|
+
return final ? { result: final.value } : {};
|
|
124
132
|
}
|
|
133
|
+
if (output?.correcting) output.rejectTools();
|
|
125
134
|
if (stop_reason === "max_tokens") {
|
|
126
135
|
transcript.push({
|
|
127
136
|
role: "user",
|