@aexhq/agentloop-pi 2.0.1 → 2.1.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 CHANGED
@@ -30,3 +30,10 @@ const session = await brain.sessions.create({
30
30
 
31
31
  The component is built by this package's publisher. Brain consumes the resulting Component and
32
32
  does not compile its JavaScript source.
33
+
34
+ The loop reads paginated session Events before each turn and saves its observation cursor in
35
+ slots. Interrupted turns and environment failures enter the transcript as runtime observations.
36
+ A failed tool result goes back to the model with `is_error`; the loop does not retry it automatically.
37
+ Brain can release execution between turns without losing this transcript or cursor. Physical
38
+ browser and sandbox state follows the Environment provider's TTL and may be lost. The official
39
+ `tool-env` inspection and lifecycle tool is planned after the MVP.
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aexhq/agentloop-pi",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "Pi-style parallel-Tool Brain extension",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -34,7 +34,7 @@
34
34
  "prepack": "npm run build"
35
35
  },
36
36
  "dependencies": {
37
- "@aexhq/brain": "0.16.1",
37
+ "@aexhq/brain": "0.17.0",
38
38
  "zod": "4.4.3"
39
39
  },
40
40
  "devDependencies": {}
package/src/component.mjs CHANGED
@@ -25,6 +25,7 @@ export async function turn(input) {
25
25
  system: input.system,
26
26
  tools: JSON.parse(input.toolsJson),
27
27
  }, {
28
+ events: (after) => JSON.parse(hosted(() => host.events(BigInt(after)))),
28
29
  model: (request) => JSON.parse(hosted(() => host.model(JSON.stringify(request)))),
29
30
  dispatch: (calls) => JSON.parse(hosted(() => host.dispatch(JSON.stringify(calls)))),
30
31
  emit: (kind, data) => hosted(() => host.emit(kind, JSON.stringify(data ?? null))),
package/src/logic.mjs CHANGED
@@ -1,3 +1,5 @@
1
+ import { observeEvents } from "../../../shared/loop-events.mjs";
2
+
1
3
  const CHECKPOINT_PREFIX = "Context checkpoint from earlier in this conversation:\n\n";
2
4
 
3
5
  const SUMMARIZATION_PROMPT = `The messages above are a conversation to summarize. Create a structured context checkpoint summary that another LLM will use to continue the work.
@@ -58,6 +60,7 @@ export async function runPi(input, context) {
58
60
  ...input.configuration,
59
61
  };
60
62
  const transcript = cloneJson(input.transcript);
63
+ const observed_sequence = await observeEvents(context, transcript, input.slots.observed_sequence ?? 0);
61
64
  const saved = input.slots.checkpoint;
62
65
  const checkpoint = saved === undefined ? { summary: null } : cloneJson(saved);
63
66
  const body = () => checkpoint.summary === null ? transcript : transcript.slice(1);
@@ -101,7 +104,7 @@ export async function runPi(input, context) {
101
104
  .map((block) => ({ call_id: block.id, name: block.name, input: block.input }));
102
105
  if (calls.length === 0) {
103
106
  await context.emit("output_emitted", { type: "assistant_message", message: text(message) });
104
- return { transcript, slots: { checkpoint } };
107
+ return { transcript, slots: { checkpoint, observed_sequence } };
105
108
  }
106
109
  if (stop_reason === "max_tokens") {
107
110
  transcript.push({