@agent-native/core 0.52.0 → 0.54.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 +41 -95
- 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 +64 -1
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +73 -2
- package/dist/action.js.map +1 -1
- package/dist/agent/index.d.ts +1 -0
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +1 -0
- package/dist/agent/index.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 +45 -0
- package/dist/agent/observational-memory/read.d.ts.map +1 -0
- package/dist/agent/observational-memory/read.js +97 -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/processors.d.ts +146 -0
- package/dist/agent/processors.d.ts.map +1 -0
- package/dist/agent/processors.js +122 -0
- package/dist/agent/processors.js.map +1 -0
- package/dist/agent/production-agent.d.ts +25 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +341 -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 +48 -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 +99 -0
- package/dist/agent/tool-call-journal.d.ts.map +1 -0
- package/dist/agent/tool-call-journal.js +212 -0
- package/dist/agent/tool-call-journal.js.map +1 -0
- package/dist/agent/types.d.ts +35 -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 +2 -2
- package/dist/cli/connect.d.ts.map +1 -1
- package/dist/cli/connect.js +92 -24
- 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.d.ts.map +1 -1
- package/dist/cli/mcp.js +11 -5
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/plan-local.d.ts +66 -5
- package/dist/cli/plan-local.d.ts.map +1 -1
- package/dist/cli/plan-local.js +622 -21
- package/dist/cli/plan-local.js.map +1 -1
- package/dist/cli/skills.d.ts +2 -2
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +108 -62
- 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/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/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.map +1 -1
- package/dist/coding-tools/run-code.js +18 -2
- package/dist/coding-tools/run-code.js.map +1 -1
- 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/extensions/fetch-tool.d.ts.map +1 -1
- package/dist/extensions/fetch-tool.js +80 -15
- package/dist/extensions/fetch-tool.js.map +1 -1
- package/dist/extensions/web-content.d.ts +61 -0
- package/dist/extensions/web-content.d.ts.map +1 -0
- package/dist/extensions/web-content.js +468 -0
- package/dist/extensions/web-content.js.map +1 -0
- package/dist/extensions/web-search-tool.js +3 -3
- package/dist/extensions/web-search-tool.js.map +1 -1
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +4 -1
- package/dist/mcp/build-server.js.map +1 -1
- 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/provider-api/corpus-jobs.d.ts +80 -0
- package/dist/provider-api/corpus-jobs.d.ts.map +1 -1
- package/dist/provider-api/corpus-jobs.js +219 -22
- package/dist/provider-api/corpus-jobs.js.map +1 -1
- package/dist/provider-api/index.d.ts +24 -32
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +28 -1
- package/dist/provider-api/index.js.map +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 +119 -111
- package/dist/server/agent-chat-plugin.js.map +1 -1
- 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/better-auth-instance.d.ts +7 -0
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +90 -0
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +7 -4
- package/dist/server/core-routes-plugin.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/deep-link.d.ts +7 -0
- package/dist/server/deep-link.d.ts.map +1 -1
- package/dist/server/deep-link.js +13 -2
- package/dist/server/deep-link.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 +2 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -1
- package/dist/server/index.js.map +1 -1
- package/dist/templates/default/.agents/skills/actions/SKILL.md +52 -1
- package/dist/templates/default/.agents/skills/security/SKILL.md +22 -0
- package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +52 -1
- package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -4
- package/dist/templates/workspace-core/.agents/skills/harness-agents/SKILL.md +20 -0
- package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +31 -0
- package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +22 -0
- package/docs/content/actions.md +50 -0
- package/docs/content/agent-teams.md +32 -0
- package/docs/content/blueprint-installer.md +73 -0
- package/docs/content/durable-resume.md +49 -0
- package/docs/content/evals.md +141 -0
- package/docs/content/external-agents.md +2 -2
- package/docs/content/human-approval.md +101 -0
- package/docs/content/observability.md +21 -0
- package/docs/content/observational-memory.md +63 -0
- package/docs/content/plan-plugin.md +5 -0
- package/docs/content/pr-visual-recap.md +9 -5
- package/docs/content/processors.md +99 -0
- package/docs/content/sandbox-adapters.md +134 -0
- package/docs/content/template-plan.md +97 -21
- package/package.json +10 -1
- package/src/templates/default/.agents/skills/actions/SKILL.md +52 -1
- package/src/templates/default/.agents/skills/security/SKILL.md +22 -0
- package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +52 -1
- package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -4
- package/src/templates/workspace-core/.agents/skills/harness-agents/SKILL.md +20 -0
- package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +31 -0
- package/src/templates/workspace-core/.agents/skills/security/SKILL.md +22 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tunable thresholds for Observational Memory compaction.
|
|
3
|
+
*
|
|
4
|
+
* Defaults are conservative and overridable per call. Deploy-level
|
|
5
|
+
* AGENT_NATIVE_* env overrides let an operator dial compaction without a
|
|
6
|
+
* redeploy; an invalid/missing value always falls back to the named default.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Once a thread's UNOBSERVED messages exceed this many tokens, the Observer
|
|
10
|
+
* compacts them into a single dense, dated observation entry.
|
|
11
|
+
*/
|
|
12
|
+
export const DEFAULT_OBSERVATION_TOKEN_THRESHOLD = 30_000;
|
|
13
|
+
/**
|
|
14
|
+
* Once the persisted observation log itself exceeds this many tokens, the
|
|
15
|
+
* Reflector condenses the observations into a higher-level reflection.
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_REFLECTION_TOKEN_THRESHOLD = 40_000;
|
|
18
|
+
/**
|
|
19
|
+
* How many of the most-recent thread messages to always keep verbatim in the
|
|
20
|
+
* read-side context (the "recent raw messages" tier). These are never folded
|
|
21
|
+
* into an observation, so the agent always sees the latest turns in full.
|
|
22
|
+
*/
|
|
23
|
+
export const DEFAULT_RECENT_RAW_MESSAGE_COUNT = 12;
|
|
24
|
+
/** Cap on the Observer's output so one observation can't itself blow the budget. */
|
|
25
|
+
export const DEFAULT_OBSERVATION_MAX_OUTPUT_TOKENS = 4_000;
|
|
26
|
+
/** Cap on the Reflector's output. */
|
|
27
|
+
export const DEFAULT_REFLECTION_MAX_OUTPUT_TOKENS = 2_000;
|
|
28
|
+
function readEnvInt(raw, fallback) {
|
|
29
|
+
if (!raw)
|
|
30
|
+
return fallback;
|
|
31
|
+
const parsed = Number.parseInt(raw, 10);
|
|
32
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
33
|
+
}
|
|
34
|
+
export function resolveObservationalMemoryConfig(overrides = {}) {
|
|
35
|
+
return {
|
|
36
|
+
observationTokenThreshold: overrides.observationTokenThreshold ??
|
|
37
|
+
readEnvInt(process.env.AGENT_NATIVE_OM_OBSERVATION_TOKEN_THRESHOLD, DEFAULT_OBSERVATION_TOKEN_THRESHOLD),
|
|
38
|
+
reflectionTokenThreshold: overrides.reflectionTokenThreshold ??
|
|
39
|
+
readEnvInt(process.env.AGENT_NATIVE_OM_REFLECTION_TOKEN_THRESHOLD, DEFAULT_REFLECTION_TOKEN_THRESHOLD),
|
|
40
|
+
recentRawMessageCount: overrides.recentRawMessageCount ??
|
|
41
|
+
readEnvInt(process.env.AGENT_NATIVE_OM_RECENT_RAW_MESSAGE_COUNT, DEFAULT_RECENT_RAW_MESSAGE_COUNT),
|
|
42
|
+
observationMaxOutputTokens: overrides.observationMaxOutputTokens ??
|
|
43
|
+
DEFAULT_OBSERVATION_MAX_OUTPUT_TOKENS,
|
|
44
|
+
reflectionMaxOutputTokens: overrides.reflectionMaxOutputTokens ??
|
|
45
|
+
DEFAULT_REFLECTION_MAX_OUTPUT_TOKENS,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/agent/observational-memory/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAG,MAAM,CAAC;AAE1D;;;GAGG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG,MAAM,CAAC;AAEzD;;;;GAIG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,EAAE,CAAC;AAEnD,oFAAoF;AACpF,MAAM,CAAC,MAAM,qCAAqC,GAAG,KAAK,CAAC;AAE3D,qCAAqC;AACrC,MAAM,CAAC,MAAM,oCAAoC,GAAG,KAAK,CAAC;AAE1D,SAAS,UAAU,CAAC,GAAuB,EAAE,QAAgB;IAC3D,IAAI,CAAC,GAAG;QAAE,OAAO,QAAQ,CAAC;IAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;AACnE,CAAC;AAWD,MAAM,UAAU,gCAAgC,CAC9C,YAAgD,EAAE;IAElD,OAAO;QACL,yBAAyB,EACvB,SAAS,CAAC,yBAAyB;YACnC,UAAU,CACR,OAAO,CAAC,GAAG,CAAC,2CAA2C,EACvD,mCAAmC,CACpC;QACH,wBAAwB,EACtB,SAAS,CAAC,wBAAwB;YAClC,UAAU,CACR,OAAO,CAAC,GAAG,CAAC,0CAA0C,EACtD,kCAAkC,CACnC;QACH,qBAAqB,EACnB,SAAS,CAAC,qBAAqB;YAC/B,UAAU,CACR,OAAO,CAAC,GAAG,CAAC,wCAAwC,EACpD,gCAAgC,CACjC;QACH,0BAA0B,EACxB,SAAS,CAAC,0BAA0B;YACpC,qCAAqC;QACvC,yBAAyB,EACvB,SAAS,CAAC,yBAAyB;YACnC,oCAAoC;KACvC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Tunable thresholds for Observational Memory compaction.\n *\n * Defaults are conservative and overridable per call. Deploy-level\n * AGENT_NATIVE_* env overrides let an operator dial compaction without a\n * redeploy; an invalid/missing value always falls back to the named default.\n */\n\n/**\n * Once a thread's UNOBSERVED messages exceed this many tokens, the Observer\n * compacts them into a single dense, dated observation entry.\n */\nexport const DEFAULT_OBSERVATION_TOKEN_THRESHOLD = 30_000;\n\n/**\n * Once the persisted observation log itself exceeds this many tokens, the\n * Reflector condenses the observations into a higher-level reflection.\n */\nexport const DEFAULT_REFLECTION_TOKEN_THRESHOLD = 40_000;\n\n/**\n * How many of the most-recent thread messages to always keep verbatim in the\n * read-side context (the \"recent raw messages\" tier). These are never folded\n * into an observation, so the agent always sees the latest turns in full.\n */\nexport const DEFAULT_RECENT_RAW_MESSAGE_COUNT = 12;\n\n/** Cap on the Observer's output so one observation can't itself blow the budget. */\nexport const DEFAULT_OBSERVATION_MAX_OUTPUT_TOKENS = 4_000;\n\n/** Cap on the Reflector's output. */\nexport const DEFAULT_REFLECTION_MAX_OUTPUT_TOKENS = 2_000;\n\nfunction readEnvInt(raw: string | undefined, fallback: number): number {\n if (!raw) return fallback;\n const parsed = Number.parseInt(raw, 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;\n}\n\n/** Resolved thresholds, applying env overrides over the named defaults. */\nexport interface ObservationalMemoryConfig {\n observationTokenThreshold: number;\n reflectionTokenThreshold: number;\n recentRawMessageCount: number;\n observationMaxOutputTokens: number;\n reflectionMaxOutputTokens: number;\n}\n\nexport function resolveObservationalMemoryConfig(\n overrides: Partial<ObservationalMemoryConfig> = {},\n): ObservationalMemoryConfig {\n return {\n observationTokenThreshold:\n overrides.observationTokenThreshold ??\n readEnvInt(\n process.env.AGENT_NATIVE_OM_OBSERVATION_TOKEN_THRESHOLD,\n DEFAULT_OBSERVATION_TOKEN_THRESHOLD,\n ),\n reflectionTokenThreshold:\n overrides.reflectionTokenThreshold ??\n readEnvInt(\n process.env.AGENT_NATIVE_OM_REFLECTION_TOKEN_THRESHOLD,\n DEFAULT_REFLECTION_TOKEN_THRESHOLD,\n ),\n recentRawMessageCount:\n overrides.recentRawMessageCount ??\n readEnvInt(\n process.env.AGENT_NATIVE_OM_RECENT_RAW_MESSAGE_COUNT,\n DEFAULT_RECENT_RAW_MESSAGE_COUNT,\n ),\n observationMaxOutputTokens:\n overrides.observationMaxOutputTokens ??\n DEFAULT_OBSERVATION_MAX_OUTPUT_TOKENS,\n reflectionMaxOutputTokens:\n overrides.reflectionMaxOutputTokens ??\n DEFAULT_REFLECTION_MAX_OUTPUT_TOKENS,\n };\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observational Memory (OM) — background compaction of a long agent thread into
|
|
3
|
+
* a dated, three-tier context (recent raw messages → dense observations →
|
|
4
|
+
* higher-level reflections) so long-running threads cost far fewer tokens and
|
|
5
|
+
* stay prompt-cache stable.
|
|
6
|
+
*
|
|
7
|
+
* Public surface:
|
|
8
|
+
* - `buildObservationalContext` — read API returning the three tiers, injected
|
|
9
|
+
* into the turn's prompt assembly by the agent loop for long threads.
|
|
10
|
+
* - `maybeCompactThread` — decoupled compactor the agent loop calls after a
|
|
11
|
+
* turn; runs the Observer then the Reflector.
|
|
12
|
+
* - `runObserver` / `runReflector` — the individual compaction passes.
|
|
13
|
+
* - store helpers + the migration plugin factory (registered as a default
|
|
14
|
+
* framework plugin so the table is created on startup).
|
|
15
|
+
*/
|
|
16
|
+
export { resolveObservationalMemoryConfig, DEFAULT_OBSERVATION_TOKEN_THRESHOLD, DEFAULT_REFLECTION_TOKEN_THRESHOLD, DEFAULT_RECENT_RAW_MESSAGE_COUNT, DEFAULT_OBSERVATION_MAX_OUTPUT_TOKENS, DEFAULT_REFLECTION_MAX_OUTPUT_TOKENS, type ObservationalMemoryConfig, } from "./config.js";
|
|
17
|
+
export { insertObservationalMemory, listObservationalMemory, getObservedThroughIndex, getObservationLogTokens, __resetObservationalMemoryTableCache, type InsertObservationalMemoryInput, type ListObservationalMemoryOptions, } from "./store.js";
|
|
18
|
+
export { runInternalAgentCall, type InternalAgentRunOptions, type InternalAgentRunFn, } from "./internal-run.js";
|
|
19
|
+
export { runObserver, type RunObserverOptions, type RunObserverResult, } from "./observer.js";
|
|
20
|
+
export { runReflector, type RunReflectorOptions, type RunReflectorResult, } from "./reflector.js";
|
|
21
|
+
export { maybeCompactThread, type MaybeCompactThreadOptions, type MaybeCompactThreadResult, } from "./compactor.js";
|
|
22
|
+
export { buildObservationalContext, hasObservationalMemory, serializeObservationalMemoryBlock, type BuildObservationalContextOptions, } from "./read.js";
|
|
23
|
+
export { createObservationalMemoryPlugin, defaultObservationalMemoryPlugin, } from "./plugin.js";
|
|
24
|
+
export { OBSERVATIONAL_MEMORY_MIGRATIONS } from "./migrations.js";
|
|
25
|
+
export type { ObservationalMemoryTier, ObservationalMemoryEntry, ObservationalMemoryOwner, ObservationalContext, } from "./types.js";
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/observational-memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,gCAAgC,EAChC,mCAAmC,EACnC,kCAAkC,EAClC,gCAAgC,EAChC,qCAAqC,EACrC,oCAAoC,EACpC,KAAK,yBAAyB,GAC/B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,EACvB,oCAAoC,EACpC,KAAK,8BAA8B,EACnC,KAAK,8BAA8B,GACpC,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,oBAAoB,EACpB,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,WAAW,EACX,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACvB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,GAC9B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,iCAAiC,EACjC,KAAK,gCAAgC,GACtC,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,+BAA+B,EAC/B,gCAAgC,GACjC,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,+BAA+B,EAAE,MAAM,iBAAiB,CAAC;AAElE,YAAY,EACV,uBAAuB,EACvB,wBAAwB,EACxB,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observational Memory (OM) — background compaction of a long agent thread into
|
|
3
|
+
* a dated, three-tier context (recent raw messages → dense observations →
|
|
4
|
+
* higher-level reflections) so long-running threads cost far fewer tokens and
|
|
5
|
+
* stay prompt-cache stable.
|
|
6
|
+
*
|
|
7
|
+
* Public surface:
|
|
8
|
+
* - `buildObservationalContext` — read API returning the three tiers, injected
|
|
9
|
+
* into the turn's prompt assembly by the agent loop for long threads.
|
|
10
|
+
* - `maybeCompactThread` — decoupled compactor the agent loop calls after a
|
|
11
|
+
* turn; runs the Observer then the Reflector.
|
|
12
|
+
* - `runObserver` / `runReflector` — the individual compaction passes.
|
|
13
|
+
* - store helpers + the migration plugin factory (registered as a default
|
|
14
|
+
* framework plugin so the table is created on startup).
|
|
15
|
+
*/
|
|
16
|
+
export { resolveObservationalMemoryConfig, DEFAULT_OBSERVATION_TOKEN_THRESHOLD, DEFAULT_REFLECTION_TOKEN_THRESHOLD, DEFAULT_RECENT_RAW_MESSAGE_COUNT, DEFAULT_OBSERVATION_MAX_OUTPUT_TOKENS, DEFAULT_REFLECTION_MAX_OUTPUT_TOKENS, } from "./config.js";
|
|
17
|
+
export { insertObservationalMemory, listObservationalMemory, getObservedThroughIndex, getObservationLogTokens, __resetObservationalMemoryTableCache, } from "./store.js";
|
|
18
|
+
export { runInternalAgentCall, } from "./internal-run.js";
|
|
19
|
+
export { runObserver, } from "./observer.js";
|
|
20
|
+
export { runReflector, } from "./reflector.js";
|
|
21
|
+
export { maybeCompactThread, } from "./compactor.js";
|
|
22
|
+
export { buildObservationalContext, hasObservationalMemory, serializeObservationalMemoryBlock, } from "./read.js";
|
|
23
|
+
export { createObservationalMemoryPlugin, defaultObservationalMemoryPlugin, } from "./plugin.js";
|
|
24
|
+
export { OBSERVATIONAL_MEMORY_MIGRATIONS } from "./migrations.js";
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/agent/observational-memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,gCAAgC,EAChC,mCAAmC,EACnC,kCAAkC,EAClC,gCAAgC,EAChC,qCAAqC,EACrC,oCAAoC,GAErC,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,EACvB,oCAAoC,GAGrC,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,oBAAoB,GAGrB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,WAAW,GAGZ,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,YAAY,GAGb,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,kBAAkB,GAGnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,iCAAiC,GAElC,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,+BAA+B,EAC/B,gCAAgC,GACjC,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,+BAA+B,EAAE,MAAM,iBAAiB,CAAC","sourcesContent":["/**\n * Observational Memory (OM) — background compaction of a long agent thread into\n * a dated, three-tier context (recent raw messages → dense observations →\n * higher-level reflections) so long-running threads cost far fewer tokens and\n * stay prompt-cache stable.\n *\n * Public surface:\n * - `buildObservationalContext` — read API returning the three tiers, injected\n * into the turn's prompt assembly by the agent loop for long threads.\n * - `maybeCompactThread` — decoupled compactor the agent loop calls after a\n * turn; runs the Observer then the Reflector.\n * - `runObserver` / `runReflector` — the individual compaction passes.\n * - store helpers + the migration plugin factory (registered as a default\n * framework plugin so the table is created on startup).\n */\n\nexport {\n resolveObservationalMemoryConfig,\n DEFAULT_OBSERVATION_TOKEN_THRESHOLD,\n DEFAULT_REFLECTION_TOKEN_THRESHOLD,\n DEFAULT_RECENT_RAW_MESSAGE_COUNT,\n DEFAULT_OBSERVATION_MAX_OUTPUT_TOKENS,\n DEFAULT_REFLECTION_MAX_OUTPUT_TOKENS,\n type ObservationalMemoryConfig,\n} from \"./config.js\";\n\nexport {\n insertObservationalMemory,\n listObservationalMemory,\n getObservedThroughIndex,\n getObservationLogTokens,\n __resetObservationalMemoryTableCache,\n type InsertObservationalMemoryInput,\n type ListObservationalMemoryOptions,\n} from \"./store.js\";\n\nexport {\n runInternalAgentCall,\n type InternalAgentRunOptions,\n type InternalAgentRunFn,\n} from \"./internal-run.js\";\n\nexport {\n runObserver,\n type RunObserverOptions,\n type RunObserverResult,\n} from \"./observer.js\";\nexport {\n runReflector,\n type RunReflectorOptions,\n type RunReflectorResult,\n} from \"./reflector.js\";\n\nexport {\n maybeCompactThread,\n type MaybeCompactThreadOptions,\n type MaybeCompactThreadResult,\n} from \"./compactor.js\";\n\nexport {\n buildObservationalContext,\n hasObservationalMemory,\n serializeObservationalMemoryBlock,\n type BuildObservationalContextOptions,\n} from \"./read.js\";\n\nexport {\n createObservationalMemoryPlugin,\n defaultObservationalMemoryPlugin,\n} from \"./plugin.js\";\n\nexport { OBSERVATIONAL_MEMORY_MIGRATIONS } from \"./migrations.js\";\n\nexport type {\n ObservationalMemoryTier,\n ObservationalMemoryEntry,\n ObservationalMemoryOwner,\n ObservationalContext,\n} from \"./types.js\";\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
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 type { AgentEngine } from "../engine/types.js";
|
|
15
|
+
export interface InternalAgentRunOptions {
|
|
16
|
+
systemPrompt: string;
|
|
17
|
+
prompt: string;
|
|
18
|
+
maxOutputTokens?: number;
|
|
19
|
+
/** Pre-resolved engine; resolved from the registry when omitted. */
|
|
20
|
+
engine?: AgentEngine;
|
|
21
|
+
/** Pre-resolved model; resolved from the engine's stored/default when omitted. */
|
|
22
|
+
model?: string;
|
|
23
|
+
timeoutMs?: number;
|
|
24
|
+
signal?: AbortSignal;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Run one tool-less internal agent call and return the collected text.
|
|
28
|
+
*
|
|
29
|
+
* Resolution goes through `resolveEngine` / `getStoredModelForEngine` /
|
|
30
|
+
* `normalizeModelForEngine` — identical to the eval runner — so the compactor
|
|
31
|
+
* uses whatever provider/model the app is configured for. No model is ever
|
|
32
|
+
* hardcoded here.
|
|
33
|
+
*/
|
|
34
|
+
export declare function runInternalAgentCall(options: InternalAgentRunOptions): Promise<string>;
|
|
35
|
+
/** The shape the Observer/Reflector depend on — injectable for tests. */
|
|
36
|
+
export type InternalAgentRunFn = (options: InternalAgentRunOptions) => Promise<string>;
|
|
37
|
+
//# sourceMappingURL=internal-run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal-run.d.ts","sourceRoot":"","sources":["../../../src/agent/observational-memory/internal-run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAStD,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAsCjB;AAED,yEAAyE;AACzE,MAAM,MAAM,kBAAkB,GAAG,CAC/B,OAAO,EAAE,uBAAuB,KAC7B,OAAO,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -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"}
|