@agent-native/core 0.51.15 → 0.53.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 +42 -96
- package/blueprints/action/crud.md +98 -0
- package/blueprints/channel/discord.md +74 -0
- package/blueprints/provider/stripe.md +87 -0
- package/blueprints/sandbox/docker.md +78 -0
- package/dist/action.d.ts +24 -0
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +4 -0
- package/dist/action.js.map +1 -1
- package/dist/agent/observational-memory/compactor.d.ts +43 -0
- package/dist/agent/observational-memory/compactor.d.ts.map +1 -0
- package/dist/agent/observational-memory/compactor.js +50 -0
- package/dist/agent/observational-memory/compactor.js.map +1 -0
- package/dist/agent/observational-memory/config.d.ts +37 -0
- package/dist/agent/observational-memory/config.d.ts.map +1 -0
- package/dist/agent/observational-memory/config.js +48 -0
- package/dist/agent/observational-memory/config.js.map +1 -0
- package/dist/agent/observational-memory/index.d.ts +26 -0
- package/dist/agent/observational-memory/index.d.ts.map +1 -0
- package/dist/agent/observational-memory/index.js +25 -0
- package/dist/agent/observational-memory/index.js.map +1 -0
- package/dist/agent/observational-memory/internal-run.d.ts +37 -0
- package/dist/agent/observational-memory/internal-run.d.ts.map +1 -0
- package/dist/agent/observational-memory/internal-run.js +59 -0
- package/dist/agent/observational-memory/internal-run.js.map +1 -0
- package/dist/agent/observational-memory/message-text.d.ts +13 -0
- package/dist/agent/observational-memory/message-text.d.ts.map +1 -0
- package/dist/agent/observational-memory/message-text.js +46 -0
- package/dist/agent/observational-memory/message-text.js.map +1 -0
- package/dist/agent/observational-memory/migrations.d.ts +13 -0
- package/dist/agent/observational-memory/migrations.d.ts.map +1 -0
- package/dist/agent/observational-memory/migrations.js +43 -0
- package/dist/agent/observational-memory/migrations.js.map +1 -0
- package/dist/agent/observational-memory/observer.d.ts +37 -0
- package/dist/agent/observational-memory/observer.d.ts.map +1 -0
- package/dist/agent/observational-memory/observer.js +82 -0
- package/dist/agent/observational-memory/observer.js.map +1 -0
- package/dist/agent/observational-memory/plugin.d.ts +16 -0
- package/dist/agent/observational-memory/plugin.d.ts.map +1 -0
- package/dist/agent/observational-memory/plugin.js +26 -0
- package/dist/agent/observational-memory/plugin.js.map +1 -0
- package/dist/agent/observational-memory/prompts.d.ts +27 -0
- package/dist/agent/observational-memory/prompts.d.ts.map +1 -0
- package/dist/agent/observational-memory/prompts.js +42 -0
- package/dist/agent/observational-memory/prompts.js.map +1 -0
- package/dist/agent/observational-memory/read.d.ts +47 -0
- package/dist/agent/observational-memory/read.d.ts.map +1 -0
- package/dist/agent/observational-memory/read.js +99 -0
- package/dist/agent/observational-memory/read.js.map +1 -0
- package/dist/agent/observational-memory/reflector.d.ts +31 -0
- package/dist/agent/observational-memory/reflector.d.ts.map +1 -0
- package/dist/agent/observational-memory/reflector.js +76 -0
- package/dist/agent/observational-memory/reflector.js.map +1 -0
- package/dist/agent/observational-memory/schema.d.ts +267 -0
- package/dist/agent/observational-memory/schema.d.ts.map +1 -0
- package/dist/agent/observational-memory/schema.js +48 -0
- package/dist/agent/observational-memory/schema.js.map +1 -0
- package/dist/agent/observational-memory/store.d.ts +52 -0
- package/dist/agent/observational-memory/store.d.ts.map +1 -0
- package/dist/agent/observational-memory/store.js +197 -0
- package/dist/agent/observational-memory/store.js.map +1 -0
- package/dist/agent/observational-memory/types.d.ts +61 -0
- package/dist/agent/observational-memory/types.d.ts.map +1 -0
- package/dist/agent/observational-memory/types.js +9 -0
- package/dist/agent/observational-memory/types.js.map +1 -0
- package/dist/agent/production-agent.d.ts +15 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +240 -1
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
- package/dist/agent/run-loop-with-resume.js +49 -0
- package/dist/agent/run-loop-with-resume.js.map +1 -1
- package/dist/agent/run-store.d.ts +17 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +55 -0
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/runtime-context.d.ts +30 -0
- package/dist/agent/runtime-context.d.ts.map +1 -1
- package/dist/agent/runtime-context.js +54 -1
- package/dist/agent/runtime-context.js.map +1 -1
- package/dist/agent/tool-call-journal.d.ts +101 -0
- package/dist/agent/tool-call-journal.d.ts.map +1 -0
- package/dist/agent/tool-call-journal.js +214 -0
- package/dist/agent/tool-call-journal.js.map +1 -0
- package/dist/agent/types.d.ts +24 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/cli/add.d.ts +109 -0
- package/dist/cli/add.d.ts.map +1 -0
- package/dist/cli/add.js +352 -0
- package/dist/cli/add.js.map +1 -0
- package/dist/cli/connect.d.ts +5 -4
- package/dist/cli/connect.d.ts.map +1 -1
- package/dist/cli/connect.js +157 -48
- package/dist/cli/connect.js.map +1 -1
- package/dist/cli/eval.d.ts +17 -0
- package/dist/cli/eval.d.ts.map +1 -0
- package/dist/cli/eval.js +121 -0
- package/dist/cli/eval.js.map +1 -0
- package/dist/cli/index.js +44 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-config-writers.d.ts +20 -13
- package/dist/cli/mcp-config-writers.d.ts.map +1 -1
- package/dist/cli/mcp-config-writers.js +152 -13
- package/dist/cli/mcp-config-writers.js.map +1 -1
- package/dist/cli/mcp.d.ts +2 -2
- package/dist/cli/mcp.d.ts.map +1 -1
- package/dist/cli/mcp.js +50 -196
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/plan-local.d.ts +69 -6
- package/dist/cli/plan-local.d.ts.map +1 -1
- package/dist/cli/plan-local.js +517 -23
- package/dist/cli/plan-local.js.map +1 -1
- package/dist/cli/recap.d.ts.map +1 -1
- package/dist/cli/recap.js +1 -1
- package/dist/cli/recap.js.map +1 -1
- package/dist/cli/skills.d.ts +13 -6
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +287 -111
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +118 -92
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +16 -0
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-engine-key.d.ts +6 -4
- package/dist/client/agent-engine-key.d.ts.map +1 -1
- package/dist/client/agent-engine-key.js +9 -6
- package/dist/client/agent-engine-key.js.map +1 -1
- package/dist/client/chat/run-recovery.js +1 -1
- package/dist/client/chat/run-recovery.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +20 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +32 -7
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +7 -14
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +13 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +21 -0
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/coding-tools/run-code.d.ts +7 -0
- package/dist/coding-tools/run-code.d.ts.map +1 -1
- package/dist/coding-tools/run-code.js +21 -106
- package/dist/coding-tools/run-code.js.map +1 -1
- package/dist/coding-tools/sandbox/adapter.d.ts +79 -0
- package/dist/coding-tools/sandbox/adapter.d.ts.map +1 -0
- package/dist/coding-tools/sandbox/adapter.js +24 -0
- package/dist/coding-tools/sandbox/adapter.js.map +1 -0
- package/dist/coding-tools/sandbox/index.d.ts +51 -0
- package/dist/coding-tools/sandbox/index.d.ts.map +1 -0
- package/dist/coding-tools/sandbox/index.js +79 -0
- package/dist/coding-tools/sandbox/index.js.map +1 -0
- package/dist/coding-tools/sandbox/local-child-process-adapter.d.ts +24 -0
- package/dist/coding-tools/sandbox/local-child-process-adapter.d.ts.map +1 -0
- package/dist/coding-tools/sandbox/local-child-process-adapter.js +141 -0
- package/dist/coding-tools/sandbox/local-child-process-adapter.js.map +1 -0
- package/dist/db/client.d.ts +4 -2
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +6 -4
- package/dist/db/client.js.map +1 -1
- package/dist/deploy/route-discovery.d.ts.map +1 -1
- package/dist/deploy/route-discovery.js +1 -0
- package/dist/deploy/route-discovery.js.map +1 -1
- package/dist/eval/agent-runner.d.ts +63 -0
- package/dist/eval/agent-runner.d.ts.map +1 -0
- package/dist/eval/agent-runner.js +142 -0
- package/dist/eval/agent-runner.js.map +1 -0
- package/dist/eval/define-eval.d.ts +29 -0
- package/dist/eval/define-eval.d.ts.map +1 -0
- package/dist/eval/define-eval.js +43 -0
- package/dist/eval/define-eval.js.map +1 -0
- package/dist/eval/index.d.ts +18 -0
- package/dist/eval/index.d.ts.map +1 -0
- package/dist/eval/index.js +17 -0
- package/dist/eval/index.js.map +1 -0
- package/dist/eval/report.d.ts +8 -0
- package/dist/eval/report.d.ts.map +1 -0
- package/dist/eval/report.js +44 -0
- package/dist/eval/report.js.map +1 -0
- package/dist/eval/runner.d.ts +67 -0
- package/dist/eval/runner.d.ts.map +1 -0
- package/dist/eval/runner.js +256 -0
- package/dist/eval/runner.js.map +1 -0
- package/dist/eval/scorer.d.ts +83 -0
- package/dist/eval/scorer.d.ts.map +1 -0
- package/dist/eval/scorer.js +195 -0
- package/dist/eval/scorer.js.map +1 -0
- package/dist/eval/types.d.ts +162 -0
- package/dist/eval/types.d.ts.map +1 -0
- package/dist/eval/types.js +20 -0
- package/dist/eval/types.js.map +1 -0
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +100 -1
- package/dist/observability/traces.js.map +1 -1
- package/dist/observability/tracing.d.ts +73 -0
- package/dist/observability/tracing.d.ts.map +1 -0
- package/dist/observability/tracing.js +126 -0
- package/dist/observability/tracing.js.map +1 -0
- package/dist/onboarding/default-steps.d.ts.map +1 -1
- package/dist/onboarding/default-steps.js +4 -1
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/provider-api/actions/query-staged-dataset.d.ts +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.js +10 -3
- package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +4 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +9 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +118 -110
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +37 -0
- package/dist/server/agent-engine-api-key-route.d.ts.map +1 -0
- package/dist/server/agent-engine-api-key-route.js +105 -0
- package/dist/server/agent-engine-api-key-route.js.map +1 -0
- package/dist/server/agent-teams.d.ts +62 -0
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +99 -2
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +17 -10
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/create-server.js +1 -1
- package/dist/server/create-server.js.map +1 -1
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +2 -0
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +33 -1
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +17 -4
- package/dist/templates/workspace-core/.agents/skills/harness-agents/SKILL.md +20 -0
- package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +20 -0
- package/docs/content/agent-teams.md +32 -0
- package/docs/content/blueprint-installer.md +73 -0
- package/docs/content/evals.md +141 -0
- package/docs/content/pr-visual-recap.md +7 -4
- package/docs/content/sandbox-adapters.md +134 -0
- package/docs/content/template-plan.md +20 -8
- package/package.json +5 -1
- package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +17 -4
- package/src/templates/workspace-core/.agents/skills/harness-agents/SKILL.md +20 -0
- package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +20 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tiny headless internal-agent-call seam for Observational Memory.
|
|
3
|
+
*
|
|
4
|
+
* The Observer and Reflector each need a single, tool-less LLM round-trip:
|
|
5
|
+
* "here is some text, compress it". Rather than touch `production-agent.ts`,
|
|
6
|
+
* this reuses the SAME pattern the evals lane built — resolve a provider-
|
|
7
|
+
* agnostic engine + model from the registry (NEVER hardcode a model) and drive
|
|
8
|
+
* one `engine.stream()` to completion, collecting the text. It mirrors the
|
|
9
|
+
* `analyzeContext().judge` helper in `eval/agent-runner.ts`.
|
|
10
|
+
*
|
|
11
|
+
* Everything is injectable so tests can supply a fake engine and assert no real
|
|
12
|
+
* model is ever called.
|
|
13
|
+
*/
|
|
14
|
+
import { resolveEngine, getStoredModelForEngine, normalizeModelForEngine, } from "../engine/index.js";
|
|
15
|
+
const DEFAULT_INTERNAL_RUN_TIMEOUT_MS = 60_000;
|
|
16
|
+
/**
|
|
17
|
+
* Run one tool-less internal agent call and return the collected text.
|
|
18
|
+
*
|
|
19
|
+
* Resolution goes through `resolveEngine` / `getStoredModelForEngine` /
|
|
20
|
+
* `normalizeModelForEngine` — identical to the eval runner — so the compactor
|
|
21
|
+
* uses whatever provider/model the app is configured for. No model is ever
|
|
22
|
+
* hardcoded here.
|
|
23
|
+
*/
|
|
24
|
+
export async function runInternalAgentCall(options) {
|
|
25
|
+
const engine = options.engine ?? (await resolveEngine({ engineOption: undefined }));
|
|
26
|
+
const modelCandidate = options.model ??
|
|
27
|
+
(await getStoredModelForEngine(engine)) ??
|
|
28
|
+
engine.defaultModel;
|
|
29
|
+
const model = normalizeModelForEngine(engine, modelCandidate);
|
|
30
|
+
const controller = new AbortController();
|
|
31
|
+
const signal = options.signal ?? controller.signal;
|
|
32
|
+
const timer = options.signal
|
|
33
|
+
? undefined
|
|
34
|
+
: setTimeout(() => controller.abort(), options.timeoutMs ?? DEFAULT_INTERNAL_RUN_TIMEOUT_MS);
|
|
35
|
+
let out = "";
|
|
36
|
+
try {
|
|
37
|
+
const stream = engine.stream({
|
|
38
|
+
model,
|
|
39
|
+
systemPrompt: options.systemPrompt,
|
|
40
|
+
messages: [
|
|
41
|
+
{ role: "user", content: [{ type: "text", text: options.prompt }] },
|
|
42
|
+
],
|
|
43
|
+
tools: [],
|
|
44
|
+
abortSignal: signal,
|
|
45
|
+
maxOutputTokens: options.maxOutputTokens ?? 4_000,
|
|
46
|
+
temperature: 0,
|
|
47
|
+
});
|
|
48
|
+
for await (const event of stream) {
|
|
49
|
+
if (event.type === "text-delta")
|
|
50
|
+
out += event.text;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
if (timer)
|
|
55
|
+
clearTimeout(timer);
|
|
56
|
+
}
|
|
57
|
+
return out.trim();
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=internal-run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal-run.js","sourceRoot":"","sources":["../../../src/agent/observational-memory/internal-run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,+BAA+B,GAAG,MAAM,CAAC;AAc/C;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAgC;IAEhC,MAAM,MAAM,GACV,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,aAAa,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IACvE,MAAM,cAAc,GAClB,OAAO,CAAC,KAAK;QACb,CAAC,MAAM,uBAAuB,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,CAAC,YAAY,CAAC;IACtB,MAAM,KAAK,GAAG,uBAAuB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAE9D,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC;IACnD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM;QAC1B,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,UAAU,CACR,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EACxB,OAAO,CAAC,SAAS,IAAI,+BAA+B,CACrD,CAAC;IAEN,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAC3B,KAAK;YACL,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,QAAQ,EAAE;gBACR,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE;aACpE;YACD,KAAK,EAAE,EAAE;YACT,WAAW,EAAE,MAAM;YACnB,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,KAAK;YACjD,WAAW,EAAE,CAAC;SACf,CAAC,CAAC;QACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;gBAAE,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC;QACrD,CAAC;IACH,CAAC;YAAS,CAAC;QACT,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACpB,CAAC","sourcesContent":["/**\n * Tiny headless internal-agent-call seam for Observational Memory.\n *\n * The Observer and Reflector each need a single, tool-less LLM round-trip:\n * \"here is some text, compress it\". Rather than touch `production-agent.ts`,\n * this reuses the SAME pattern the evals lane built — resolve a provider-\n * agnostic engine + model from the registry (NEVER hardcode a model) and drive\n * one `engine.stream()` to completion, collecting the text. It mirrors the\n * `analyzeContext().judge` helper in `eval/agent-runner.ts`.\n *\n * Everything is injectable so tests can supply a fake engine and assert no real\n * model is ever called.\n */\n\nimport type { AgentEngine } from \"../engine/types.js\";\nimport {\n resolveEngine,\n getStoredModelForEngine,\n normalizeModelForEngine,\n} from \"../engine/index.js\";\n\nconst DEFAULT_INTERNAL_RUN_TIMEOUT_MS = 60_000;\n\nexport interface InternalAgentRunOptions {\n systemPrompt: string;\n prompt: string;\n maxOutputTokens?: number;\n /** Pre-resolved engine; resolved from the registry when omitted. */\n engine?: AgentEngine;\n /** Pre-resolved model; resolved from the engine's stored/default when omitted. */\n model?: string;\n timeoutMs?: number;\n signal?: AbortSignal;\n}\n\n/**\n * Run one tool-less internal agent call and return the collected text.\n *\n * Resolution goes through `resolveEngine` / `getStoredModelForEngine` /\n * `normalizeModelForEngine` — identical to the eval runner — so the compactor\n * uses whatever provider/model the app is configured for. No model is ever\n * hardcoded here.\n */\nexport async function runInternalAgentCall(\n options: InternalAgentRunOptions,\n): Promise<string> {\n const engine =\n options.engine ?? (await resolveEngine({ engineOption: undefined }));\n const modelCandidate =\n options.model ??\n (await getStoredModelForEngine(engine)) ??\n engine.defaultModel;\n const model = normalizeModelForEngine(engine, modelCandidate);\n\n const controller = new AbortController();\n const signal = options.signal ?? controller.signal;\n const timer = options.signal\n ? undefined\n : setTimeout(\n () => controller.abort(),\n options.timeoutMs ?? DEFAULT_INTERNAL_RUN_TIMEOUT_MS,\n );\n\n let out = \"\";\n try {\n const stream = engine.stream({\n model,\n systemPrompt: options.systemPrompt,\n messages: [\n { role: \"user\", content: [{ type: \"text\", text: options.prompt }] },\n ],\n tools: [],\n abortSignal: signal,\n maxOutputTokens: options.maxOutputTokens ?? 4_000,\n temperature: 0,\n });\n for await (const event of stream) {\n if (event.type === \"text-delta\") out += event.text;\n }\n } finally {\n if (timer) clearTimeout(timer);\n }\n return out.trim();\n}\n\n/** The shape the Observer/Reflector depend on — injectable for tests. */\nexport type InternalAgentRunFn = (\n options: InternalAgentRunOptions,\n) => Promise<string>;\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render engine messages to a compact plain-text transcript for the compactor
|
|
3
|
+
* window, and account their tokens. Reuses the existing context-xray token
|
|
4
|
+
* accounting so OM thresholds match what the rest of the framework counts.
|
|
5
|
+
*/
|
|
6
|
+
import type { EngineMessage } from "../engine/types.js";
|
|
7
|
+
/** Flatten one engine message to a single labeled line block. */
|
|
8
|
+
export declare function messageToText(message: EngineMessage): string;
|
|
9
|
+
/** Render a contiguous window of messages to one text blob. */
|
|
10
|
+
export declare function windowToText(messages: EngineMessage[]): string;
|
|
11
|
+
/** Token count for a window of messages (reuses framework tokenizer). */
|
|
12
|
+
export declare function countWindowTokens(messages: EngineMessage[]): Promise<number>;
|
|
13
|
+
//# sourceMappingURL=message-text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-text.d.ts","sourceRoot":"","sources":["../../../src/agent/observational-memory/message-text.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAc5D;AAED,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,CAK9D;AAED,yEAAyE;AACzE,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,aAAa,EAAE,GACxB,OAAO,CAAC,MAAM,CAAC,CAGjB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render engine messages to a compact plain-text transcript for the compactor
|
|
3
|
+
* window, and account their tokens. Reuses the existing context-xray token
|
|
4
|
+
* accounting so OM thresholds match what the rest of the framework counts.
|
|
5
|
+
*/
|
|
6
|
+
import { countMessageTokens } from "../context-xray/tokenize.js";
|
|
7
|
+
/** Flatten one engine message to a single labeled line block. */
|
|
8
|
+
export function messageToText(message) {
|
|
9
|
+
const parts = [];
|
|
10
|
+
for (const part of message.content) {
|
|
11
|
+
if (part.type === "text" || part.type === "thinking") {
|
|
12
|
+
if (part.text.trim())
|
|
13
|
+
parts.push(part.text);
|
|
14
|
+
}
|
|
15
|
+
else if (part.type === "tool-call") {
|
|
16
|
+
parts.push(`[tool:${part.name}] ${safeJson(part.input)}`.trim());
|
|
17
|
+
}
|
|
18
|
+
else if (part.type === "tool-result") {
|
|
19
|
+
parts.push(`[tool-result] ${part.content}`.trim());
|
|
20
|
+
}
|
|
21
|
+
// image/file parts are intentionally omitted from the text window.
|
|
22
|
+
}
|
|
23
|
+
const body = parts.join("\n");
|
|
24
|
+
return body ? `${message.role}: ${body}` : "";
|
|
25
|
+
}
|
|
26
|
+
/** Render a contiguous window of messages to one text blob. */
|
|
27
|
+
export function windowToText(messages) {
|
|
28
|
+
return messages
|
|
29
|
+
.map(messageToText)
|
|
30
|
+
.filter((line) => line.length > 0)
|
|
31
|
+
.join("\n\n");
|
|
32
|
+
}
|
|
33
|
+
/** Token count for a window of messages (reuses framework tokenizer). */
|
|
34
|
+
export async function countWindowTokens(messages) {
|
|
35
|
+
const { tokens } = await countMessageTokens(messages);
|
|
36
|
+
return tokens;
|
|
37
|
+
}
|
|
38
|
+
function safeJson(value) {
|
|
39
|
+
try {
|
|
40
|
+
return JSON.stringify(value) ?? "";
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return "";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=message-text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-text.js","sourceRoot":"","sources":["../../../src/agent/observational-memory/message-text.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,iEAAiE;AACjE,MAAM,UAAU,aAAa,CAAC,OAAsB;IAClD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACnC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACrD,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QACnE,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,mEAAmE;IACrE,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAChD,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,YAAY,CAAC,QAAyB;IACpD,OAAO,QAAQ;SACZ,GAAG,CAAC,aAAa,CAAC;SAClB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SACjC,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,QAAyB;IAEzB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACtD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC","sourcesContent":["/**\n * Render engine messages to a compact plain-text transcript for the compactor\n * window, and account their tokens. Reuses the existing context-xray token\n * accounting so OM thresholds match what the rest of the framework counts.\n */\n\nimport type { EngineMessage } from \"../engine/types.js\";\nimport { countMessageTokens } from \"../context-xray/tokenize.js\";\n\n/** Flatten one engine message to a single labeled line block. */\nexport function messageToText(message: EngineMessage): string {\n const parts: string[] = [];\n for (const part of message.content) {\n if (part.type === \"text\" || part.type === \"thinking\") {\n if (part.text.trim()) parts.push(part.text);\n } else if (part.type === \"tool-call\") {\n parts.push(`[tool:${part.name}] ${safeJson(part.input)}`.trim());\n } else if (part.type === \"tool-result\") {\n parts.push(`[tool-result] ${part.content}`.trim());\n }\n // image/file parts are intentionally omitted from the text window.\n }\n const body = parts.join(\"\\n\");\n return body ? `${message.role}: ${body}` : \"\";\n}\n\n/** Render a contiguous window of messages to one text blob. */\nexport function windowToText(messages: EngineMessage[]): string {\n return messages\n .map(messageToText)\n .filter((line) => line.length > 0)\n .join(\"\\n\\n\");\n}\n\n/** Token count for a window of messages (reuses framework tokenizer). */\nexport async function countWindowTokens(\n messages: EngineMessage[],\n): Promise<number> {\n const { tokens } = await countMessageTokens(messages);\n return tokens;\n}\n\nfunction safeJson(value: unknown): string {\n try {\n return JSON.stringify(value) ?? \"\";\n } catch {\n return \"\";\n }\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { MigrationEntry } from "../../db/migrations.js";
|
|
2
|
+
/**
|
|
3
|
+
* Additive-only migrations for Observational Memory.
|
|
4
|
+
*
|
|
5
|
+
* These run under their OWN bookkeeping table (`_observational_memory_migrations`)
|
|
6
|
+
* so the version space is independent of core/org/context-xray — see
|
|
7
|
+
* `db/migrations.ts` for why each module owns its own version space.
|
|
8
|
+
*
|
|
9
|
+
* Strictly additive: a new table plus its hot-path indexes. Never drops,
|
|
10
|
+
* renames, or destructively alters anything.
|
|
11
|
+
*/
|
|
12
|
+
export declare const OBSERVATIONAL_MEMORY_MIGRATIONS: MigrationEntry[];
|
|
13
|
+
//# sourceMappingURL=migrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/agent/observational-memory/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D;;;;;;;;;GASG;AACH,eAAO,MAAM,+BAA+B,EAAE,cAAc,EA+B3D,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Additive-only migrations for Observational Memory.
|
|
3
|
+
*
|
|
4
|
+
* These run under their OWN bookkeeping table (`_observational_memory_migrations`)
|
|
5
|
+
* so the version space is independent of core/org/context-xray — see
|
|
6
|
+
* `db/migrations.ts` for why each module owns its own version space.
|
|
7
|
+
*
|
|
8
|
+
* Strictly additive: a new table plus its hot-path indexes. Never drops,
|
|
9
|
+
* renames, or destructively alters anything.
|
|
10
|
+
*/
|
|
11
|
+
export const OBSERVATIONAL_MEMORY_MIGRATIONS = [
|
|
12
|
+
{
|
|
13
|
+
version: 1,
|
|
14
|
+
sql: `CREATE TABLE IF NOT EXISTS observational_memory (
|
|
15
|
+
id TEXT PRIMARY KEY,
|
|
16
|
+
thread_id TEXT NOT NULL,
|
|
17
|
+
tier TEXT NOT NULL,
|
|
18
|
+
text TEXT NOT NULL,
|
|
19
|
+
token_estimate INTEGER NOT NULL DEFAULT 0,
|
|
20
|
+
source_start_index INTEGER,
|
|
21
|
+
source_end_index INTEGER,
|
|
22
|
+
source_message_count INTEGER NOT NULL DEFAULT 0,
|
|
23
|
+
created_at INTEGER NOT NULL,
|
|
24
|
+
updated_at INTEGER NOT NULL,
|
|
25
|
+
owner_email TEXT NOT NULL DEFAULT 'local@localhost',
|
|
26
|
+
org_id TEXT,
|
|
27
|
+
visibility TEXT NOT NULL DEFAULT 'private'
|
|
28
|
+
)`,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
// Hot path: read a thread's entries of a given tier, ordered by recency.
|
|
32
|
+
version: 2,
|
|
33
|
+
sql: `CREATE INDEX IF NOT EXISTS observational_memory_thread_tier_idx
|
|
34
|
+
ON observational_memory(thread_id, tier, created_at)`,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
// Hot path: owner-scoped reads for ownable-table access checks.
|
|
38
|
+
version: 3,
|
|
39
|
+
sql: `CREATE INDEX IF NOT EXISTS observational_memory_thread_owner_idx
|
|
40
|
+
ON observational_memory(thread_id, owner_email)`,
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../../src/agent/observational-memory/migrations.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAqB;IAC/D;QACE,OAAO,EAAE,CAAC;QACV,GAAG,EAAE;;;;;;;;;;;;;;MAcH;KACH;IACD;QACE,yEAAyE;QACzE,OAAO,EAAE,CAAC;QACV,GAAG,EAAE;2DACkD;KACxD;IACD;QACE,gEAAgE;QAChE,OAAO,EAAE,CAAC;QACV,GAAG,EAAE;sDAC6C;KACnD;CACF,CAAC","sourcesContent":["import type { MigrationEntry } from \"../../db/migrations.js\";\n\n/**\n * Additive-only migrations for Observational Memory.\n *\n * These run under their OWN bookkeeping table (`_observational_memory_migrations`)\n * so the version space is independent of core/org/context-xray — see\n * `db/migrations.ts` for why each module owns its own version space.\n *\n * Strictly additive: a new table plus its hot-path indexes. Never drops,\n * renames, or destructively alters anything.\n */\nexport const OBSERVATIONAL_MEMORY_MIGRATIONS: MigrationEntry[] = [\n {\n version: 1,\n sql: `CREATE TABLE IF NOT EXISTS observational_memory (\n id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n tier TEXT NOT NULL,\n text TEXT NOT NULL,\n token_estimate INTEGER NOT NULL DEFAULT 0,\n source_start_index INTEGER,\n source_end_index INTEGER,\n source_message_count INTEGER NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n owner_email TEXT NOT NULL DEFAULT 'local@localhost',\n org_id TEXT,\n visibility TEXT NOT NULL DEFAULT 'private'\n )`,\n },\n {\n // Hot path: read a thread's entries of a given tier, ordered by recency.\n version: 2,\n sql: `CREATE INDEX IF NOT EXISTS observational_memory_thread_tier_idx\n ON observational_memory(thread_id, tier, created_at)`,\n },\n {\n // Hot path: owner-scoped reads for ownable-table access checks.\n version: 3,\n sql: `CREATE INDEX IF NOT EXISTS observational_memory_thread_owner_idx\n ON observational_memory(thread_id, owner_email)`,\n },\n];\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Observer.
|
|
3
|
+
*
|
|
4
|
+
* When a thread's UNOBSERVED messages exceed the observation token threshold,
|
|
5
|
+
* the Observer runs ONE internal (tool-less) agent call to compress that window
|
|
6
|
+
* into a dense, dated observation log, persists it as a `tier: "observation"`
|
|
7
|
+
* entry, and marks those messages observed (recorded via the entry's
|
|
8
|
+
* `sourceEndIndex`, which `getObservedThroughIndex` reads back).
|
|
9
|
+
*
|
|
10
|
+
* It does NOT touch the agent loop — the internal call goes through the shared
|
|
11
|
+
* `runInternalAgentCall` seam (provider-agnostic, mockable).
|
|
12
|
+
*/
|
|
13
|
+
import type { EngineMessage } from "../engine/types.js";
|
|
14
|
+
import { type ObservationalMemoryConfig } from "./config.js";
|
|
15
|
+
import { type InternalAgentRunFn } from "./internal-run.js";
|
|
16
|
+
import type { ObservationalMemoryEntry, ObservationalMemoryOwner } from "./types.js";
|
|
17
|
+
export interface RunObserverOptions extends ObservationalMemoryOwner {
|
|
18
|
+
threadId: string;
|
|
19
|
+
/** The full, ordered thread messages. */
|
|
20
|
+
messages: EngineMessage[];
|
|
21
|
+
config?: Partial<ObservationalMemoryConfig>;
|
|
22
|
+
/** Internal-run seam — defaults to the real one; injected in tests. */
|
|
23
|
+
runInternal?: InternalAgentRunFn;
|
|
24
|
+
}
|
|
25
|
+
export interface RunObserverResult {
|
|
26
|
+
/** True when an observation was produced and persisted. */
|
|
27
|
+
observed: boolean;
|
|
28
|
+
entry?: ObservationalMemoryEntry;
|
|
29
|
+
/** Tokens in the unobserved window that was considered. */
|
|
30
|
+
unobservedTokens: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Compact a thread's unobserved tail into an observation IF it exceeds the
|
|
34
|
+
* token threshold; otherwise no-op.
|
|
35
|
+
*/
|
|
36
|
+
export declare function runObserver(options: RunObserverOptions): Promise<RunObserverResult>;
|
|
37
|
+
//# sourceMappingURL=observer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer.d.ts","sourceRoot":"","sources":["../../../src/agent/observational-memory/observer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,aAAa,CAAC;AAMrB,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,kBAAmB,SAAQ,wBAAwB;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAC5C,uEAAuE;IACvE,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,wBAAwB,CAAC;IACjC,2DAA2D;IAC3D,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CAqE5B"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Observer.
|
|
3
|
+
*
|
|
4
|
+
* When a thread's UNOBSERVED messages exceed the observation token threshold,
|
|
5
|
+
* the Observer runs ONE internal (tool-less) agent call to compress that window
|
|
6
|
+
* into a dense, dated observation log, persists it as a `tier: "observation"`
|
|
7
|
+
* entry, and marks those messages observed (recorded via the entry's
|
|
8
|
+
* `sourceEndIndex`, which `getObservedThroughIndex` reads back).
|
|
9
|
+
*
|
|
10
|
+
* It does NOT touch the agent loop — the internal call goes through the shared
|
|
11
|
+
* `runInternalAgentCall` seam (provider-agnostic, mockable).
|
|
12
|
+
*/
|
|
13
|
+
import { countTextTokens } from "../context-xray/tokenize.js";
|
|
14
|
+
import { resolveObservationalMemoryConfig, } from "./config.js";
|
|
15
|
+
import { getObservedThroughIndex, insertObservationalMemory, listObservationalMemory, } from "./store.js";
|
|
16
|
+
import { runInternalAgentCall, } from "./internal-run.js";
|
|
17
|
+
import { countWindowTokens, windowToText } from "./message-text.js";
|
|
18
|
+
import { OBSERVER_SYSTEM_PROMPT, buildObserverPrompt } from "./prompts.js";
|
|
19
|
+
/**
|
|
20
|
+
* Compact a thread's unobserved tail into an observation IF it exceeds the
|
|
21
|
+
* token threshold; otherwise no-op.
|
|
22
|
+
*/
|
|
23
|
+
export async function runObserver(options) {
|
|
24
|
+
const config = resolveObservationalMemoryConfig(options.config);
|
|
25
|
+
const owner = {
|
|
26
|
+
ownerEmail: options.ownerEmail,
|
|
27
|
+
orgId: options.orgId ?? null,
|
|
28
|
+
};
|
|
29
|
+
const observedThrough = await getObservedThroughIndex({
|
|
30
|
+
...owner,
|
|
31
|
+
threadId: options.threadId,
|
|
32
|
+
});
|
|
33
|
+
const startIndex = observedThrough + 1;
|
|
34
|
+
const unobserved = options.messages.slice(startIndex);
|
|
35
|
+
if (unobserved.length === 0) {
|
|
36
|
+
return { observed: false, unobservedTokens: 0 };
|
|
37
|
+
}
|
|
38
|
+
const unobservedTokens = await countWindowTokens(unobserved);
|
|
39
|
+
if (unobservedTokens < config.observationTokenThreshold) {
|
|
40
|
+
return { observed: false, unobservedTokens };
|
|
41
|
+
}
|
|
42
|
+
const windowText = windowToText(unobserved);
|
|
43
|
+
if (!windowText.trim()) {
|
|
44
|
+
return { observed: false, unobservedTokens };
|
|
45
|
+
}
|
|
46
|
+
// Feed prior observations as continuity context so the new log doesn't repeat
|
|
47
|
+
// already-compacted history.
|
|
48
|
+
const priorObservations = (await listObservationalMemory({
|
|
49
|
+
...owner,
|
|
50
|
+
threadId: options.threadId,
|
|
51
|
+
tier: "observation",
|
|
52
|
+
}))
|
|
53
|
+
.map((entry) => entry.text)
|
|
54
|
+
.join("\n\n");
|
|
55
|
+
const run = options.runInternal ?? runInternalAgentCall;
|
|
56
|
+
const observationText = await run({
|
|
57
|
+
systemPrompt: OBSERVER_SYSTEM_PROMPT,
|
|
58
|
+
prompt: buildObserverPrompt({
|
|
59
|
+
threadId: options.threadId,
|
|
60
|
+
windowText,
|
|
61
|
+
priorObservations,
|
|
62
|
+
}),
|
|
63
|
+
maxOutputTokens: config.observationMaxOutputTokens,
|
|
64
|
+
});
|
|
65
|
+
if (!observationText.trim()) {
|
|
66
|
+
return { observed: false, unobservedTokens };
|
|
67
|
+
}
|
|
68
|
+
const { tokens: tokenEstimate } = await countTextTokens(observationText);
|
|
69
|
+
const endIndex = options.messages.length - 1;
|
|
70
|
+
const entry = await insertObservationalMemory({
|
|
71
|
+
...owner,
|
|
72
|
+
threadId: options.threadId,
|
|
73
|
+
tier: "observation",
|
|
74
|
+
text: observationText,
|
|
75
|
+
tokenEstimate,
|
|
76
|
+
sourceStartIndex: startIndex,
|
|
77
|
+
sourceEndIndex: endIndex,
|
|
78
|
+
sourceMessageCount: unobserved.length,
|
|
79
|
+
});
|
|
80
|
+
return { observed: true, entry, unobservedTokens };
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=observer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer.js","sourceRoot":"","sources":["../../../src/agent/observational-memory/observer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EACL,gCAAgC,GAEjC,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,oBAAoB,GAErB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAuB3E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAA2B;IAE3B,MAAM,MAAM,GAAG,gCAAgC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChE,MAAM,KAAK,GAA6B;QACtC,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI;KAC7B,CAAC;IAEF,MAAM,eAAe,GAAG,MAAM,uBAAuB,CAAC;QACpD,GAAG,KAAK;QACR,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,eAAe,GAAG,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACtD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC;IAClD,CAAC;IAED,MAAM,gBAAgB,GAAG,MAAM,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC7D,IAAI,gBAAgB,GAAG,MAAM,CAAC,yBAAyB,EAAE,CAAC;QACxD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC/C,CAAC;IAED,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;QACvB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC/C,CAAC;IAED,8EAA8E;IAC9E,6BAA6B;IAC7B,MAAM,iBAAiB,GAAG,CACxB,MAAM,uBAAuB,CAAC;QAC5B,GAAG,KAAK;QACR,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,IAAI,EAAE,aAAa;KACpB,CAAC,CACH;SACE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;SAC1B,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,IAAI,oBAAoB,CAAC;IACxD,MAAM,eAAe,GAAG,MAAM,GAAG,CAAC;QAChC,YAAY,EAAE,sBAAsB;QACpC,MAAM,EAAE,mBAAmB,CAAC;YAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,UAAU;YACV,iBAAiB;SAClB,CAAC;QACF,eAAe,EAAE,MAAM,CAAC,0BAA0B;KACnD,CAAC,CAAC;IAEH,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5B,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC/C,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,eAAe,CAAC,eAAe,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAE7C,MAAM,KAAK,GAAG,MAAM,yBAAyB,CAAC;QAC5C,GAAG,KAAK;QACR,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,IAAI,EAAE,aAAa;QACnB,IAAI,EAAE,eAAe;QACrB,aAAa;QACb,gBAAgB,EAAE,UAAU;QAC5B,cAAc,EAAE,QAAQ;QACxB,kBAAkB,EAAE,UAAU,CAAC,MAAM;KACtC,CAAC,CAAC;IAEH,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;AACrD,CAAC","sourcesContent":["/**\n * The Observer.\n *\n * When a thread's UNOBSERVED messages exceed the observation token threshold,\n * the Observer runs ONE internal (tool-less) agent call to compress that window\n * into a dense, dated observation log, persists it as a `tier: \"observation\"`\n * entry, and marks those messages observed (recorded via the entry's\n * `sourceEndIndex`, which `getObservedThroughIndex` reads back).\n *\n * It does NOT touch the agent loop — the internal call goes through the shared\n * `runInternalAgentCall` seam (provider-agnostic, mockable).\n */\n\nimport type { EngineMessage } from \"../engine/types.js\";\nimport { countTextTokens } from \"../context-xray/tokenize.js\";\nimport {\n resolveObservationalMemoryConfig,\n type ObservationalMemoryConfig,\n} from \"./config.js\";\nimport {\n getObservedThroughIndex,\n insertObservationalMemory,\n listObservationalMemory,\n} from \"./store.js\";\nimport {\n runInternalAgentCall,\n type InternalAgentRunFn,\n} from \"./internal-run.js\";\nimport { countWindowTokens, windowToText } from \"./message-text.js\";\nimport { OBSERVER_SYSTEM_PROMPT, buildObserverPrompt } from \"./prompts.js\";\nimport type {\n ObservationalMemoryEntry,\n ObservationalMemoryOwner,\n} from \"./types.js\";\n\nexport interface RunObserverOptions extends ObservationalMemoryOwner {\n threadId: string;\n /** The full, ordered thread messages. */\n messages: EngineMessage[];\n config?: Partial<ObservationalMemoryConfig>;\n /** Internal-run seam — defaults to the real one; injected in tests. */\n runInternal?: InternalAgentRunFn;\n}\n\nexport interface RunObserverResult {\n /** True when an observation was produced and persisted. */\n observed: boolean;\n entry?: ObservationalMemoryEntry;\n /** Tokens in the unobserved window that was considered. */\n unobservedTokens: number;\n}\n\n/**\n * Compact a thread's unobserved tail into an observation IF it exceeds the\n * token threshold; otherwise no-op.\n */\nexport async function runObserver(\n options: RunObserverOptions,\n): Promise<RunObserverResult> {\n const config = resolveObservationalMemoryConfig(options.config);\n const owner: ObservationalMemoryOwner = {\n ownerEmail: options.ownerEmail,\n orgId: options.orgId ?? null,\n };\n\n const observedThrough = await getObservedThroughIndex({\n ...owner,\n threadId: options.threadId,\n });\n const startIndex = observedThrough + 1;\n const unobserved = options.messages.slice(startIndex);\n if (unobserved.length === 0) {\n return { observed: false, unobservedTokens: 0 };\n }\n\n const unobservedTokens = await countWindowTokens(unobserved);\n if (unobservedTokens < config.observationTokenThreshold) {\n return { observed: false, unobservedTokens };\n }\n\n const windowText = windowToText(unobserved);\n if (!windowText.trim()) {\n return { observed: false, unobservedTokens };\n }\n\n // Feed prior observations as continuity context so the new log doesn't repeat\n // already-compacted history.\n const priorObservations = (\n await listObservationalMemory({\n ...owner,\n threadId: options.threadId,\n tier: \"observation\",\n })\n )\n .map((entry) => entry.text)\n .join(\"\\n\\n\");\n\n const run = options.runInternal ?? runInternalAgentCall;\n const observationText = await run({\n systemPrompt: OBSERVER_SYSTEM_PROMPT,\n prompt: buildObserverPrompt({\n threadId: options.threadId,\n windowText,\n priorObservations,\n }),\n maxOutputTokens: config.observationMaxOutputTokens,\n });\n\n if (!observationText.trim()) {\n return { observed: false, unobservedTokens };\n }\n\n const { tokens: tokenEstimate } = await countTextTokens(observationText);\n const endIndex = options.messages.length - 1;\n\n const entry = await insertObservationalMemory({\n ...owner,\n threadId: options.threadId,\n tier: \"observation\",\n text: observationText,\n tokenEstimate,\n sourceStartIndex: startIndex,\n sourceEndIndex: endIndex,\n sourceMessageCount: unobserved.length,\n });\n\n return { observed: true, entry, unobservedTokens };\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nitro plugin that applies the Observational Memory migrations under its own
|
|
3
|
+
* bookkeeping table. Mirrors `context-xray/plugin.ts`.
|
|
4
|
+
*
|
|
5
|
+
* NOT YET registered in the default plugin set — registering it means editing
|
|
6
|
+
* shared bootstrap files (server/framework-request-handler.ts,
|
|
7
|
+
* deploy/route-discovery.ts), which is deferred to the same follow-up that
|
|
8
|
+
* wires `buildObservationalContext` into production-agent.ts. Until then the
|
|
9
|
+
* store's `ensureTable()` creates the table lazily on first use, so OM is fully
|
|
10
|
+
* functional without the plugin.
|
|
11
|
+
*/
|
|
12
|
+
type NitroPluginDef = (nitroApp: any) => void | Promise<void>;
|
|
13
|
+
export declare function createObservationalMemoryPlugin(): NitroPluginDef;
|
|
14
|
+
export declare const defaultObservationalMemoryPlugin: NitroPluginDef;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/agent/observational-memory/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,KAAK,cAAc,GAAG,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9D,wBAAgB,+BAA+B,IAAI,cAAc,CAUhE;AAED,eAAO,MAAM,gCAAgC,EAAE,cACZ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nitro plugin that applies the Observational Memory migrations under its own
|
|
3
|
+
* bookkeeping table. Mirrors `context-xray/plugin.ts`.
|
|
4
|
+
*
|
|
5
|
+
* NOT YET registered in the default plugin set — registering it means editing
|
|
6
|
+
* shared bootstrap files (server/framework-request-handler.ts,
|
|
7
|
+
* deploy/route-discovery.ts), which is deferred to the same follow-up that
|
|
8
|
+
* wires `buildObservationalContext` into production-agent.ts. Until then the
|
|
9
|
+
* store's `ensureTable()` creates the table lazily on first use, so OM is fully
|
|
10
|
+
* functional without the plugin.
|
|
11
|
+
*/
|
|
12
|
+
import { awaitBootstrap, markDefaultPluginProvided, } from "../../server/framework-request-handler.js";
|
|
13
|
+
import { runMigrations } from "../../db/migrations.js";
|
|
14
|
+
import { OBSERVATIONAL_MEMORY_MIGRATIONS } from "./migrations.js";
|
|
15
|
+
export function createObservationalMemoryPlugin() {
|
|
16
|
+
const migrate = runMigrations(OBSERVATIONAL_MEMORY_MIGRATIONS, {
|
|
17
|
+
table: "_observational_memory_migrations",
|
|
18
|
+
});
|
|
19
|
+
return async (nitroApp) => {
|
|
20
|
+
markDefaultPluginProvided(nitroApp, "observational-memory");
|
|
21
|
+
await awaitBootstrap(nitroApp);
|
|
22
|
+
await migrate(nitroApp);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export const defaultObservationalMemoryPlugin = createObservationalMemoryPlugin();
|
|
26
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/agent/observational-memory/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,cAAc,EACd,yBAAyB,GAC1B,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,+BAA+B,EAAE,MAAM,iBAAiB,CAAC;AAIlE,MAAM,UAAU,+BAA+B;IAC7C,MAAM,OAAO,GAAG,aAAa,CAAC,+BAA+B,EAAE;QAC7D,KAAK,EAAE,kCAAkC;KAC1C,CAAC,CAAC;IAEH,OAAO,KAAK,EAAE,QAAa,EAAE,EAAE;QAC7B,yBAAyB,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;QAC5D,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC/B,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,gCAAgC,GAC3C,+BAA+B,EAAE,CAAC","sourcesContent":["/**\n * Nitro plugin that applies the Observational Memory migrations under its own\n * bookkeeping table. Mirrors `context-xray/plugin.ts`.\n *\n * NOT YET registered in the default plugin set — registering it means editing\n * shared bootstrap files (server/framework-request-handler.ts,\n * deploy/route-discovery.ts), which is deferred to the same follow-up that\n * wires `buildObservationalContext` into production-agent.ts. Until then the\n * store's `ensureTable()` creates the table lazily on first use, so OM is fully\n * functional without the plugin.\n */\n\nimport {\n awaitBootstrap,\n markDefaultPluginProvided,\n} from \"../../server/framework-request-handler.js\";\nimport { runMigrations } from \"../../db/migrations.js\";\nimport { OBSERVATIONAL_MEMORY_MIGRATIONS } from \"./migrations.js\";\n\ntype NitroPluginDef = (nitroApp: any) => void | Promise<void>;\n\nexport function createObservationalMemoryPlugin(): NitroPluginDef {\n const migrate = runMigrations(OBSERVATIONAL_MEMORY_MIGRATIONS, {\n table: \"_observational_memory_migrations\",\n });\n\n return async (nitroApp: any) => {\n markDefaultPluginProvided(nitroApp, \"observational-memory\");\n await awaitBootstrap(nitroApp);\n await migrate(nitroApp);\n };\n}\n\nexport const defaultObservationalMemoryPlugin: NitroPluginDef =\n createObservationalMemoryPlugin();\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System prompts for the Observer and Reflector compaction passes.
|
|
3
|
+
*
|
|
4
|
+
* Both prompts insist on DATED output and preservation of task status, names,
|
|
5
|
+
* dates, and decisions — the facts a long autonomous run rots and loses. The
|
|
6
|
+
* compacted text replaces raw turns in the prompt, so it must stay dense,
|
|
7
|
+
* factual, and chronological rather than narrative.
|
|
8
|
+
*/
|
|
9
|
+
export declare const OBSERVER_SYSTEM_PROMPT = "You are the Observer for a long-running agent thread. You compress a span of raw conversation into a single DENSE, DATED observation log that will REPLACE those raw messages in future context.\n\nRules:\n- Output a chronological, bulleted log. Prefix entries with a date/time when one is present in the source.\n- Preserve precisely: task status (what is done / in progress / blocked / decided), proper names (people, files, functions, repos, branches, IDs), exact dates, numbers, and decisions with their rationale.\n- Preserve unresolved questions, TODOs, and error states verbatim enough to act on later.\n- Drop pleasantries, restated context, and redundant tool chatter. Never invent facts.\n- Be terse. This is a memory record, not prose. No preamble, no summary-of-summary, just the log.";
|
|
10
|
+
export declare const REFLECTOR_SYSTEM_PROMPT = "You are the Reflector for a long-running agent thread. You condense an existing log of dated OBSERVATIONS into a smaller set of higher-level REFLECTIONS that will sit above the observations in future context.\n\nRules:\n- Roll many low-level observations up into durable, higher-level statements: overall goal and current status, key decisions and why, stable facts (names, identifiers, constraints), and open threads.\n- Keep dates on anything time-sensitive. Keep proper names and identifiers exact.\n- Do not lose any still-open task, blocker, or unresolved decision.\n- Be terse and factual. Output a chronological/thematic bulleted list. No preamble.";
|
|
11
|
+
/**
|
|
12
|
+
* Build the Observer user prompt for a window of raw thread text.
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildObserverPrompt(input: {
|
|
15
|
+
threadId: string;
|
|
16
|
+
windowText: string;
|
|
17
|
+
priorObservations?: string;
|
|
18
|
+
}): string;
|
|
19
|
+
/**
|
|
20
|
+
* Build the Reflector user prompt over the current observation log.
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildReflectorPrompt(input: {
|
|
23
|
+
threadId: string;
|
|
24
|
+
observationsText: string;
|
|
25
|
+
priorReflections?: string;
|
|
26
|
+
}): string;
|
|
27
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/agent/observational-memory/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,sBAAsB,+xBAO+D,CAAC;AAEnG,eAAO,MAAM,uBAAuB,opBAMgD,CAAC;AAErF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,MAAM,CAKT;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,GAAG,MAAM,CAKT"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System prompts for the Observer and Reflector compaction passes.
|
|
3
|
+
*
|
|
4
|
+
* Both prompts insist on DATED output and preservation of task status, names,
|
|
5
|
+
* dates, and decisions — the facts a long autonomous run rots and loses. The
|
|
6
|
+
* compacted text replaces raw turns in the prompt, so it must stay dense,
|
|
7
|
+
* factual, and chronological rather than narrative.
|
|
8
|
+
*/
|
|
9
|
+
export const OBSERVER_SYSTEM_PROMPT = `You are the Observer for a long-running agent thread. You compress a span of raw conversation into a single DENSE, DATED observation log that will REPLACE those raw messages in future context.
|
|
10
|
+
|
|
11
|
+
Rules:
|
|
12
|
+
- Output a chronological, bulleted log. Prefix entries with a date/time when one is present in the source.
|
|
13
|
+
- Preserve precisely: task status (what is done / in progress / blocked / decided), proper names (people, files, functions, repos, branches, IDs), exact dates, numbers, and decisions with their rationale.
|
|
14
|
+
- Preserve unresolved questions, TODOs, and error states verbatim enough to act on later.
|
|
15
|
+
- Drop pleasantries, restated context, and redundant tool chatter. Never invent facts.
|
|
16
|
+
- Be terse. This is a memory record, not prose. No preamble, no summary-of-summary, just the log.`;
|
|
17
|
+
export const REFLECTOR_SYSTEM_PROMPT = `You are the Reflector for a long-running agent thread. You condense an existing log of dated OBSERVATIONS into a smaller set of higher-level REFLECTIONS that will sit above the observations in future context.
|
|
18
|
+
|
|
19
|
+
Rules:
|
|
20
|
+
- Roll many low-level observations up into durable, higher-level statements: overall goal and current status, key decisions and why, stable facts (names, identifiers, constraints), and open threads.
|
|
21
|
+
- Keep dates on anything time-sensitive. Keep proper names and identifiers exact.
|
|
22
|
+
- Do not lose any still-open task, blocker, or unresolved decision.
|
|
23
|
+
- Be terse and factual. Output a chronological/thematic bulleted list. No preamble.`;
|
|
24
|
+
/**
|
|
25
|
+
* Build the Observer user prompt for a window of raw thread text.
|
|
26
|
+
*/
|
|
27
|
+
export function buildObserverPrompt(input) {
|
|
28
|
+
const prior = input.priorObservations?.trim()
|
|
29
|
+
? `Existing observation log (for continuity — do NOT repeat it, only summarize the NEW messages below):\n${input.priorObservations.trim()}\n\n`
|
|
30
|
+
: "";
|
|
31
|
+
return `${prior}New raw messages to compress into the observation log (thread ${input.threadId}):\n\n${input.windowText}`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build the Reflector user prompt over the current observation log.
|
|
35
|
+
*/
|
|
36
|
+
export function buildReflectorPrompt(input) {
|
|
37
|
+
const prior = input.priorReflections?.trim()
|
|
38
|
+
? `Existing reflections (for continuity — refine/extend, do not duplicate):\n${input.priorReflections.trim()}\n\n`
|
|
39
|
+
: "";
|
|
40
|
+
return `${prior}Observation log to condense into higher-level reflections (thread ${input.threadId}):\n\n${input.observationsText}`;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/agent/observational-memory/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;kGAO4D,CAAC;AAEnG,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;oFAM6C,CAAC;AAErF;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAInC;IACC,MAAM,KAAK,GAAG,KAAK,CAAC,iBAAiB,EAAE,IAAI,EAAE;QAC3C,CAAC,CAAC,yGAAyG,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM;QAC/I,CAAC,CAAC,EAAE,CAAC;IACP,OAAO,GAAG,KAAK,iEAAiE,KAAK,CAAC,QAAQ,SAAS,KAAK,CAAC,UAAU,EAAE,CAAC;AAC5H,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAIpC;IACC,MAAM,KAAK,GAAG,KAAK,CAAC,gBAAgB,EAAE,IAAI,EAAE;QAC1C,CAAC,CAAC,6EAA6E,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM;QAClH,CAAC,CAAC,EAAE,CAAC;IACP,OAAO,GAAG,KAAK,qEAAqE,KAAK,CAAC,QAAQ,SAAS,KAAK,CAAC,gBAAgB,EAAE,CAAC;AACtI,CAAC","sourcesContent":["/**\n * System prompts for the Observer and Reflector compaction passes.\n *\n * Both prompts insist on DATED output and preservation of task status, names,\n * dates, and decisions — the facts a long autonomous run rots and loses. The\n * compacted text replaces raw turns in the prompt, so it must stay dense,\n * factual, and chronological rather than narrative.\n */\n\nexport const OBSERVER_SYSTEM_PROMPT = `You are the Observer for a long-running agent thread. You compress a span of raw conversation into a single DENSE, DATED observation log that will REPLACE those raw messages in future context.\n\nRules:\n- Output a chronological, bulleted log. Prefix entries with a date/time when one is present in the source.\n- Preserve precisely: task status (what is done / in progress / blocked / decided), proper names (people, files, functions, repos, branches, IDs), exact dates, numbers, and decisions with their rationale.\n- Preserve unresolved questions, TODOs, and error states verbatim enough to act on later.\n- Drop pleasantries, restated context, and redundant tool chatter. Never invent facts.\n- Be terse. This is a memory record, not prose. No preamble, no summary-of-summary, just the log.`;\n\nexport const REFLECTOR_SYSTEM_PROMPT = `You are the Reflector for a long-running agent thread. You condense an existing log of dated OBSERVATIONS into a smaller set of higher-level REFLECTIONS that will sit above the observations in future context.\n\nRules:\n- Roll many low-level observations up into durable, higher-level statements: overall goal and current status, key decisions and why, stable facts (names, identifiers, constraints), and open threads.\n- Keep dates on anything time-sensitive. Keep proper names and identifiers exact.\n- Do not lose any still-open task, blocker, or unresolved decision.\n- Be terse and factual. Output a chronological/thematic bulleted list. No preamble.`;\n\n/**\n * Build the Observer user prompt for a window of raw thread text.\n */\nexport function buildObserverPrompt(input: {\n threadId: string;\n windowText: string;\n priorObservations?: string;\n}): string {\n const prior = input.priorObservations?.trim()\n ? `Existing observation log (for continuity — do NOT repeat it, only summarize the NEW messages below):\\n${input.priorObservations.trim()}\\n\\n`\n : \"\";\n return `${prior}New raw messages to compress into the observation log (thread ${input.threadId}):\\n\\n${input.windowText}`;\n}\n\n/**\n * Build the Reflector user prompt over the current observation log.\n */\nexport function buildReflectorPrompt(input: {\n threadId: string;\n observationsText: string;\n priorReflections?: string;\n}): string {\n const prior = input.priorReflections?.trim()\n ? `Existing reflections (for continuity — refine/extend, do not duplicate):\\n${input.priorReflections.trim()}\\n\\n`\n : \"\";\n return `${prior}Observation log to condense into higher-level reflections (thread ${input.threadId}):\\n\\n${input.observationsText}`;\n}\n"]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read API for Observational Memory.
|
|
3
|
+
*
|
|
4
|
+
* `buildObservationalContext` assembles the three tiers — reflections (highest
|
|
5
|
+
* level) + observations (dense) + the recent raw message tail — into a single
|
|
6
|
+
* structure ready to fold into a prompt. It is intentionally NOT wired into
|
|
7
|
+
* production-agent.ts here; see the exported seam note below and the package
|
|
8
|
+
* barrel export so the wire-up is one call later.
|
|
9
|
+
*
|
|
10
|
+
* Token-cheap by construction: a long thread is represented by its compacted
|
|
11
|
+
* tiers plus only the last N raw turns, instead of the entire transcript.
|
|
12
|
+
*/
|
|
13
|
+
import type { EngineMessage } from "../engine/types.js";
|
|
14
|
+
import { type ObservationalMemoryConfig } from "./config.js";
|
|
15
|
+
import type { ObservationalContext, ObservationalMemoryOwner } from "./types.js";
|
|
16
|
+
export interface BuildObservationalContextOptions extends ObservationalMemoryOwner {
|
|
17
|
+
threadId: string;
|
|
18
|
+
/** The full, ordered thread messages — the recent tail is taken from here. */
|
|
19
|
+
messages: EngineMessage[];
|
|
20
|
+
config?: Partial<ObservationalMemoryConfig>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* SEAM (deferred wire-up): build the three-tier Observational Memory context
|
|
24
|
+
* for a thread. The returned tiers are ready to be injected into the turn's
|
|
25
|
+
* prompt assembly.
|
|
26
|
+
*
|
|
27
|
+
* TODO(charlie-merge): inject buildObservationalContext output into the turn
|
|
28
|
+
* context assembly in production-agent.ts once the lazy-skill context changes
|
|
29
|
+
* land. The intended shape: replace the older raw-message prefix (everything
|
|
30
|
+
* before `recentMessages`) with the `reflections` + `observations` text, keep
|
|
31
|
+
* `recentMessages` verbatim, and prepend a short "Observational Memory" system
|
|
32
|
+
* section. This module deliberately does not edit production-agent.ts.
|
|
33
|
+
*/
|
|
34
|
+
/** True when this thread has at least one persisted observation or reflection. */
|
|
35
|
+
export declare function hasObservationalMemory(context: ObservationalContext): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Serialize the reflections + observations tiers into a single, clearly
|
|
38
|
+
* delimited prompt block. The recent-raw-message tail is NOT serialized here —
|
|
39
|
+
* it stays as verbatim engine messages — so this block represents only the
|
|
40
|
+
* compacted older history that replaces the raw prefix.
|
|
41
|
+
*
|
|
42
|
+
* Returns an empty string when there is nothing compacted yet, so callers can
|
|
43
|
+
* cheaply skip injection for short threads.
|
|
44
|
+
*/
|
|
45
|
+
export declare function serializeObservationalMemoryBlock(context: ObservationalContext): string;
|
|
46
|
+
export declare function buildObservationalContext(options: BuildObservationalContextOptions): Promise<ObservationalContext>;
|
|
47
|
+
//# sourceMappingURL=read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/agent/observational-memory/read.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,aAAa,CAAC;AAGrB,OAAO,KAAK,EACV,oBAAoB,EAEpB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,gCAAiC,SAAQ,wBAAwB;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC;CAC7C;AAMD;;;;;;;;;;;GAWG;AACH,kFAAkF;AAClF,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAE7E;AAED;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,oBAAoB,GAC5B,MAAM,CAuBR;AAED,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,oBAAoB,CAAC,CAwC/B"}
|