@xopcai/xopc 0.0.170 → 0.0.172
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/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-CkUp1qvf.js → activity-store-C3Y-bESI.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DDuem4HM.js → agent-avatar-dicebear-CPyev9P7.js} +1 -1
- package/dist/gateway/static/root/assets/agents-Bf_kK2Ay.js +2 -0
- package/dist/gateway/static/root/assets/{api-BnuPQhJW.js → api-B7qEr_Rw.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-DdZw8Hi1.js → app-management-settings-panel-Br_9-7fs.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BN8Vk2bX.js → appearance-settings-uyLcRPai.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-DXFCP5-1.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-C82MaDQj.js → archive-plugin-B19REnR5.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-uilrwSdW.js → attachment-load-DLWCC4Yi.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-CkDZjAmy.js → automation-suggestion-card-ky5S5lly.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-D8pT1o2O.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-B7NTL0_T.js → binary-plugins-CtPEzLlo.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-D_LDNlB-.js → block-editor-CQVR4Xij.js} +32 -32
- package/dist/gateway/static/root/assets/browser-settings-page-Bav_skKN.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-UFVUzn4v.js → browser-workflow-inputs-CimCGbhq.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-CGgC0N92.js → browser-workflows-page-DewuCw3p.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BHaYYo9E.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-DUIorGUd.js → capability-presets-api-B5RTs-Az.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-settings-panel-PTz00nR4.js → capability-presets-settings-panel-BgchTh81.js} +1 -1
- package/dist/gateway/static/root/assets/{channel-recipient-api-BYwSB8c6.js → channel-recipient-api-Czu0YzIZ.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-BP0e62wt.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-DBWKfeGe.js +1 -0
- package/dist/gateway/static/root/assets/connector-logo-Di3gnR_D.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-CC5kh0de.js +2 -0
- package/dist/gateway/static/root/assets/{desktop-pet-CkT98fPT.js → desktop-pet-D-ZUNHhn.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DkbIzdA3.js → desktop-pet-settings-C3L6AI8_.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-dBQvj1sG.js → directory-picker-path-field-Dvq4iG6P.js} +1 -1
- package/dist/gateway/static/root/assets/dreaming-settings-D9i54kWO.js +3 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-BfxoIiNo.js → extension-debug-page-BecQjU0J.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-EIJ3wIb7.js → extension-page-BeVkPSm-.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DBBec51N.js → extension-settings-page-DMoo2mKx.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-4_u53Ufq.js → gateway-config-api-Bthb3_6v.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-v9kJM59H.js → gateway-settings-Bh8nPvJQ.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-CXITih5d.js → gateway-startup-retry-D3USVm9D.js} +1 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-Dp0AyDHI.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-CNt7nrdS.js +4 -0
- package/dist/gateway/static/root/assets/{goals-config-api-D54YQPon.js → goals-config-api-C_2QWBtb.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-Bm_NZFiZ.js +2 -0
- package/dist/gateway/static/root/assets/{goals-settings-DDezXaVi.js → goals-settings-DhL643tc.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-CRsIUeZN.js → heartbeat-settings-COVFwp7C.js} +1 -1
- package/dist/gateway/static/root/assets/{image-generation-api-CY6cQUHL.js → image-generation-api-BNQlnwpU.js} +1 -1
- package/dist/gateway/static/root/assets/index-C_XSKOH6.css +1 -0
- package/dist/gateway/static/root/assets/{index-Dfq2laZe.js → index-DUasAutC.js} +67 -67
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-D9k7EDdY.js → keyboard-shortcuts-settings-DfdJRJVy.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-DZwkD1co.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-DbaiBolh.js → local-apps-page-BvCPOgoi.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-Dqp9H2Uf.js → locale-store-BP0vD37A.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-DoCY0Mm9.js → logs-page-dNL0Y1dA.js} +3 -3
- package/dist/gateway/static/root/assets/{markdown-split-BGlQR-Be.js → markdown-split-YO1rDk9m.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-BpaeV6f_.js → media-plugins-CU_RRf-q.js} +1 -1
- package/dist/gateway/static/root/assets/messages-BWtP5TFz.js +3 -0
- package/dist/gateway/static/root/assets/{notes-page-Cd2HpciM.js → notes-page-CeFiOK3S.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-B8MKxpZb.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-DyimBUp_.js → page-tabs-tiHmRJUA.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BKZulEYr.js → preview-open-alternatives-CU6XgaCz.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-Bjz9BxBY.js → product-open-page-Dn4_qor4.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-CWBuuX-S.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-BJSsLsXH.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-DXJDb8vB.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-BPTqb2_r.js → save-bar-controls-edDUIbXo.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-YN0D81Dk.js → schedule-field-DqJO_5Yb.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-BmY5PSS2.js → schema-form-CMh0jzy5.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DeHpWgxM.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-Cf-TEYUd.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-B-RhgD_p.js → settings-form-section-Bb0Bc3nJ.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-DkPupX2B.js → settings-loading-skeleton-DQhADvz1.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-2QBMvaxj.js → settings-page-b0M5HukN.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-CtrW-LD6.js → settings-page-layout-hvjtIjvh.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BFyfed_g.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BezIW1n9.js → share-preview-page-rbeaOpTg.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-CYnH9sTt.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-Cr8_m-jS.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-Chtc1xDO.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-WAFhKyAu.js → system-settings-panel-BHo_hgnL.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-BiC0gIBa.js → theme-store-C3KnnjcU.js} +1 -1
- package/dist/gateway/static/root/assets/time-picker-D-G-uwVJ.js +1 -0
- package/dist/gateway/static/root/assets/{typed-models-lib-WAQO3F_8.js → typed-models-lib-DtRnG-YI.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-CKlfsSeU.js → use-channel-catalog-CWWItX2g.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-D7qMR26X.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-BAFHF0_v.js → voice-api-key-field-BTnltQHZ.js} +1 -1
- package/dist/gateway/static/root/assets/work-discovery-page-CpqFZze9.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-t4dXpGC0.js +1 -0
- package/dist/gateway/static/root/assets/work-page-BXwDKiMZ.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-1OP4HyvS.js → workflow-run-setup-panel-D7vKChFZ.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-Bos9HyqT.js +11 -0
- package/dist/gateway/static/root/index.html +7 -7
- package/dist/package.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +71 -24
- package/dist/src/agent/embedded/run-turn.js +68 -4
- package/dist/src/agent/inbound/inbound-loop.d.ts +0 -2
- package/dist/src/agent/inbound/inbound-loop.js +0 -2
- package/dist/src/agent/memory/builtin-provider.js +4 -4
- package/dist/src/agent/memory/compaction-planner.d.ts +16 -0
- package/dist/src/agent/memory/compaction-planner.js +152 -0
- package/dist/src/agent/memory/compaction-policy.d.ts +10 -0
- package/dist/src/agent/memory/compaction-policy.js +24 -0
- package/dist/src/agent/memory/compaction.d.ts +21 -22
- package/dist/src/agent/memory/compaction.js +220 -194
- package/dist/src/agent/memory/context-budget.d.ts +40 -0
- package/dist/src/agent/memory/context-budget.js +106 -0
- package/dist/src/agent/memory/manager.d.ts +4 -1
- package/dist/src/agent/memory/manager.js +8 -3
- package/dist/src/agent/memory/understanding/service.d.ts +2 -0
- package/dist/src/agent/memory/understanding/service.js +11 -9
- package/dist/src/agent/orchestration/context-overflow.d.ts +1 -0
- package/dist/src/agent/orchestration/context-overflow.js +19 -0
- package/dist/src/agent/orchestration/loop-guard.js +13 -9
- package/dist/src/agent/reply/post-compaction-context.d.ts +4 -0
- package/dist/src/agent/reply/post-compaction-context.js +5 -3
- package/dist/src/agent/service/process-direct-one-shot.js +1 -2
- package/dist/src/agent/service/process-direct-streaming.js +1 -2
- package/dist/src/agent/service.d.ts +1 -2
- package/dist/src/agent/service.js +16 -44
- package/dist/src/agent/session/session-inspector.js +10 -2
- package/dist/src/automations/domain/validation.d.ts +8 -8
- package/dist/src/automations/draft/automation-draft-validator.d.ts +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/config/schema.d.ts +17 -1
- package/dist/src/connectors/composio-sessions.d.ts +1 -0
- package/dist/src/connectors/composio-sessions.js +14 -5
- package/dist/src/connectors/composio-triggers.d.ts +1 -1
- package/dist/src/connectors/composio-triggers.js +4 -3
- package/dist/src/connectors/composio.js +1 -0
- package/dist/src/connectors/{connector-memory-sync.d.ts → connected-source-ingestion.d.ts} +11 -4
- package/dist/src/connectors/{connector-memory-sync.js → connected-source-ingestion.js} +49 -101
- package/dist/src/connectors/connected-source-normalizers.d.ts +15 -0
- package/dist/src/connectors/connected-source-normalizers.js +186 -0
- package/dist/src/connectors/connector-identity.d.ts +2 -0
- package/dist/src/connectors/connector-identity.js +29 -0
- package/dist/src/connectors/learning-coordinator.d.ts +25 -0
- package/dist/src/connectors/learning-coordinator.js +214 -0
- package/dist/src/connectors/learning-recipes.d.ts +22 -0
- package/dist/src/connectors/learning-recipes.js +121 -0
- package/dist/src/connectors/runtime-status.d.ts +1 -8
- package/dist/src/connectors/runtime-status.js +4 -29
- package/dist/src/gateway/hono/lib/config-payload.d.ts +23 -0
- package/dist/src/gateway/hono/lib/config-payload.js +3 -0
- package/dist/src/gateway/hono/routes/config-patch/misc.d.ts +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +28 -0
- package/dist/src/gateway/hono/routes/connectors.js +76 -118
- package/dist/src/gateway/hono/routes/models.js +24 -0
- package/dist/src/gateway/hono/routes/public-gateway.js +3 -2
- package/dist/src/gateway/hono/routes/sessions.js +17 -42
- package/dist/src/gateway/hono/routes/you.js +86 -5
- package/dist/src/gateway/service/sessions-api.d.ts +2 -3
- package/dist/src/gateway/service/sessions-api.js +4 -7
- package/dist/src/gateway/service.d.ts +5 -2
- package/dist/src/gateway/service.js +16 -11
- package/dist/src/knowledge/connected-understanding-pipeline.d.ts +19 -0
- package/dist/src/knowledge/connected-understanding-pipeline.js +268 -0
- package/dist/src/knowledge/index.d.ts +1 -0
- package/dist/src/knowledge/index.js +2 -1
- package/dist/src/knowledge/ingestion-service.d.ts +6 -4
- package/dist/src/knowledge/ingestion-service.js +13 -10
- package/dist/src/knowledge/local-folder-adapter.js +1 -0
- package/dist/src/knowledge/people-graph.js +43 -110
- package/dist/src/knowledge/types.d.ts +3 -0
- package/dist/src/providers/xopc-cloud-account-service.d.ts +40 -0
- package/dist/src/providers/xopc-cloud-account-service.js +65 -0
- package/dist/src/session/index.d.ts +1 -2
- package/dist/src/session/index.js +1 -2
- package/dist/src/session/init-session-turn.d.ts +0 -1
- package/dist/src/session/init-session-turn.js +1 -2
- package/dist/src/session/manager.d.ts +11 -17
- package/dist/src/session/manager.js +11 -14
- package/dist/src/session/session-context-for-llm.d.ts +19 -1
- package/dist/src/session/session-context-for-llm.js +87 -129
- package/dist/src/session/store.d.ts +28 -23
- package/dist/src/session/store.js +94 -83
- package/dist/src/session/transcript-format.d.ts +2 -8
- package/dist/src/session/types.d.ts +8 -6
- package/dist/src/session/user-round-delete.d.ts +3 -6
- package/dist/src/session/user-round-delete.js +12 -16
- package/dist/src/storage/sqlite/connector-learning-repository.d.ts +47 -0
- package/dist/src/storage/sqlite/connector-learning-repository.js +110 -0
- package/dist/src/storage/sqlite/index.d.ts +4 -2
- package/dist/src/storage/sqlite/index.js +5 -3
- package/dist/src/storage/sqlite/knowledge-repository.d.ts +4 -2
- package/dist/src/storage/sqlite/knowledge-repository.js +24 -13
- package/dist/src/storage/sqlite/migrations/060_remove_runtime_transcript_messages.sql +45 -0
- package/dist/src/storage/sqlite/migrations/061_drop_compaction_checkpoints.sql +2 -0
- package/dist/src/storage/sqlite/migrations/062_connector_learning_jobs.sql +27 -0
- package/dist/src/storage/sqlite/migrations/063_knowledge_collection_scopes.sql +14 -0
- package/dist/src/storage/sqlite/migrations/064_user_claims.sql +60 -0
- package/dist/src/storage/sqlite/migrations/065_knowledge_item_scope_identity.sql +116 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/schema.sql +0 -19
- package/dist/src/storage/sqlite/transcript-repository.d.ts +6 -11
- package/dist/src/storage/sqlite/transcript-repository.js +90 -84
- package/dist/src/storage/sqlite/user-claims-repository.d.ts +101 -0
- package/dist/src/storage/sqlite/user-claims-repository.js +241 -0
- package/dist/src/user-context/config.d.ts +67 -2
- package/dist/src/user-context/config.js +36 -3
- package/dist/src/user-context/projection.d.ts +36 -1
- package/dist/src/user-context/projection.js +84 -6
- package/dist/src/work-discovery/service.js +1 -0
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/agents-BiaQhiQp.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-CuL8Q4yF.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-TZOluRNp.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-C-l6O68Z.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BW8c0xPp.js +0 -7
- package/dist/gateway/static/root/assets/channels-settings-h9CsE0GT.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-C058Mcfr.js +0 -1
- package/dist/gateway/static/root/assets/connector-logo-CsbegNqi.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-BWALafGW.js +0 -2
- package/dist/gateway/static/root/assets/dreaming-settings-DkdnKMZx.js +0 -3
- package/dist/gateway/static/root/assets/goal-create-dialog-y2Y3p7_k.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-DuzL-alv.js +0 -4
- package/dist/gateway/static/root/assets/goals-page-OeLtfKI2.js +0 -2
- package/dist/gateway/static/root/assets/index-o4uaOGKT.css +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-3ssYIEK6.js +0 -2
- package/dist/gateway/static/root/assets/messages-KEk-hTFt.js +0 -3
- package/dist/gateway/static/root/assets/notes-workbench-CatZNAPc.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-DJUOgqm4.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-BQQAD_nu.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-fIGXTTnA.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BuU-8FCe.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DlKoeZm3.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BSUcDFnb.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-Bk2-SwGJ.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-e_Fx1kVC.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-D_cCADfj.js +0 -2
- package/dist/gateway/static/root/assets/time-picker-fqRXpNJV.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-9Ov4htPW.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-DGN2FxWv.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-HmyWSgUo.js +0 -1
- package/dist/gateway/static/root/assets/work-page-D3iKVjFq.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-B5L4SFw4.js +0 -11
- package/dist/src/agent/lifecycle/handlers/compaction.d.ts +0 -13
- package/dist/src/agent/lifecycle/handlers/compaction.js +0 -18
- package/dist/src/connectors/memory-sync-coordinator.d.ts +0 -28
- package/dist/src/connectors/memory-sync-coordinator.js +0 -162
- package/dist/src/connectors/memory-sync-profile.d.ts +0 -13
- package/dist/src/connectors/memory-sync-profile.js +0 -73
- package/dist/src/session/compaction-checkpoints.d.ts +0 -8
- package/dist/src/session/compaction-checkpoints.js +0 -19
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?v=20260713-1" />
|
|
12
12
|
<link rel="manifest" href="/site.webmanifest?v=20260713-1" />
|
|
13
13
|
<title>XOPC — Turn goals into loops. Keep what matters moving.</title>
|
|
14
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-DUasAutC.js"></script>
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-aKtaBQYM.js">
|
|
16
16
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-zJ_50EbN.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-BOUWij0V.js">
|
|
@@ -24,17 +24,17 @@
|
|
|
24
24
|
<link rel="modulepreload" crossorigin href="/assets/check-DUBLcKHA.js">
|
|
25
25
|
<link rel="modulepreload" crossorigin href="/assets/circle-alert-BEjgurr2.js">
|
|
26
26
|
<link rel="modulepreload" crossorigin href="/assets/middleware-Pd0e8Igk.js">
|
|
27
|
-
<link rel="modulepreload" crossorigin href="/assets/messages-
|
|
28
|
-
<link rel="modulepreload" crossorigin href="/assets/locale-store-
|
|
27
|
+
<link rel="modulepreload" crossorigin href="/assets/messages-BWtP5TFz.js">
|
|
28
|
+
<link rel="modulepreload" crossorigin href="/assets/locale-store-BP0vD37A.js">
|
|
29
29
|
<link rel="modulepreload" crossorigin href="/assets/cn-JdwAhgNB.js">
|
|
30
30
|
<link rel="modulepreload" crossorigin href="/assets/schemas-DgQq6Z5S.js">
|
|
31
31
|
<link rel="modulepreload" crossorigin href="/assets/product-delivery-BTRT9kCS.js">
|
|
32
32
|
<link rel="modulepreload" crossorigin href="/assets/config-reload-event-Bjh2zoKp.js">
|
|
33
33
|
<link rel="modulepreload" crossorigin href="/assets/copy-to-clipboard-HOJ79TWv.js">
|
|
34
|
-
<link rel="modulepreload" crossorigin href="/assets/gateway-startup-retry-
|
|
35
|
-
<link rel="modulepreload" crossorigin href="/assets/activity-store-
|
|
36
|
-
<link rel="modulepreload" crossorigin href="/assets/theme-store-
|
|
37
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
34
|
+
<link rel="modulepreload" crossorigin href="/assets/gateway-startup-retry-D3USVm9D.js">
|
|
35
|
+
<link rel="modulepreload" crossorigin href="/assets/activity-store-C3Y-bESI.js">
|
|
36
|
+
<link rel="modulepreload" crossorigin href="/assets/theme-store-C3KnnjcU.js">
|
|
37
|
+
<link rel="stylesheet" crossorigin href="/assets/index-C_XSKOH6.css">
|
|
38
38
|
</head>
|
|
39
39
|
<body>
|
|
40
40
|
<div id="root"></div>
|
package/dist/package.js
CHANGED
|
@@ -2,6 +2,8 @@ import { createLogger } from "../../utils/logger/index.js";
|
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { init_providers, resolveModel } from "../../providers/index.js";
|
|
4
4
|
import { resolveAgentTurnTimeoutMs } from "../orchestration/run-agent-turn-with-timeout.js";
|
|
5
|
+
import { evaluateContextBudget } from "../memory/context-budget.js";
|
|
6
|
+
import { resolveCompactionPolicy } from "../memory/compaction-policy.js";
|
|
5
7
|
import { runXopcEmbeddedTurn } from "./run-turn.js";
|
|
6
8
|
import { applyStartupContextToUserMessage } from "../reply/apply-turn-user-enrichment.js";
|
|
7
9
|
import { mergeTurnTools, resolveEmbeddedMcpToolsForTurn } from "../mcp/resolve-embedded-mcp-tools.js";
|
|
@@ -46,14 +48,6 @@ async function runEmbeddedTurnForSession(params) {
|
|
|
46
48
|
const thinkingLevel = params.thinkingOverride ?? agent.state.thinkingLevel;
|
|
47
49
|
const workspaceDir = agentManager.getResolvedWorkspaceForSession(sessionKey);
|
|
48
50
|
const config = params.getConfig?.();
|
|
49
|
-
await maybeAutoCompactBeforeTurn({
|
|
50
|
-
sessionKey,
|
|
51
|
-
sessionStore,
|
|
52
|
-
agentManager,
|
|
53
|
-
model,
|
|
54
|
-
config,
|
|
55
|
-
onEvent: params.onEvent
|
|
56
|
-
});
|
|
57
51
|
let userMessageForTurn = userMessage;
|
|
58
52
|
if (params.applyStartupContext !== false) userMessageForTurn = await applyStartupContextToUserMessage({
|
|
59
53
|
userMessage,
|
|
@@ -74,6 +68,20 @@ async function runEmbeddedTurnForSession(params) {
|
|
|
74
68
|
});
|
|
75
69
|
const turnTools = mergeTurnTools(tools, mcpResolved.tools);
|
|
76
70
|
try {
|
|
71
|
+
await maybeAutoCompactBeforeTurn({
|
|
72
|
+
sessionKey,
|
|
73
|
+
sessionStore,
|
|
74
|
+
agentManager,
|
|
75
|
+
model,
|
|
76
|
+
config,
|
|
77
|
+
systemPrompt,
|
|
78
|
+
userMessage: userMessageForTurn,
|
|
79
|
+
tools: turnTools,
|
|
80
|
+
imageCount: params.llmImages?.length ?? 0,
|
|
81
|
+
fallbackModels: resolvedCandidates.slice(1).map((candidate) => candidate.model),
|
|
82
|
+
abortSignal: params.abortSignal,
|
|
83
|
+
onEvent: params.onEvent
|
|
84
|
+
});
|
|
77
85
|
log.info({
|
|
78
86
|
sessionKey,
|
|
79
87
|
runId,
|
|
@@ -167,28 +175,61 @@ async function runEmbeddedTurnForSession(params) {
|
|
|
167
175
|
}
|
|
168
176
|
})();
|
|
169
177
|
}
|
|
178
|
+
function serializedTranscriptBytes(messages) {
|
|
179
|
+
return Buffer.byteLength(JSON.stringify(messages), "utf8");
|
|
180
|
+
}
|
|
170
181
|
async function maybeAutoCompactBeforeTurn(opts) {
|
|
171
|
-
const { sessionKey, sessionStore, agentManager, model, config, onEvent } = opts;
|
|
172
|
-
|
|
173
|
-
if (config.userContext.memory.retention?.compaction === false) return;
|
|
174
|
-
} catch {}
|
|
182
|
+
const { sessionKey, sessionStore, agentManager, model, config, systemPrompt, userMessage, tools, imageCount, fallbackModels, abortSignal, onEvent } = opts;
|
|
183
|
+
const policy = resolveCompactionPolicy(config);
|
|
175
184
|
const contextWindow = model.contextWindow ?? 128e3;
|
|
176
185
|
const messages = await sessionStore.load(sessionKey);
|
|
177
|
-
const
|
|
178
|
-
|
|
186
|
+
const activeTranscriptBytes = serializedTranscriptBytes(messages);
|
|
187
|
+
const byteLimitExceeded = policy.enabled && activeTranscriptBytes > policy.maxActiveTranscriptBytes;
|
|
188
|
+
const budget = evaluateContextBudget({
|
|
189
|
+
messages,
|
|
190
|
+
contextWindow,
|
|
191
|
+
systemPrompt,
|
|
192
|
+
currentUserMessage: userMessage,
|
|
193
|
+
tools,
|
|
194
|
+
imageCount,
|
|
195
|
+
triggerThreshold: policy.triggerThreshold,
|
|
196
|
+
reserveTokens: policy.reserveTokens,
|
|
197
|
+
minToolResultKeepChars: policy.minToolResultKeepChars,
|
|
198
|
+
canCompact: messages.length >= policy.minMessagesBeforeCompact
|
|
199
|
+
});
|
|
200
|
+
if (!byteLimitExceeded && (budget.route === "fits" || budget.route === "truncate_tool_results_only")) return;
|
|
201
|
+
if (!policy.enabled) {
|
|
202
|
+
if (budget.estimatedTokens <= budget.hardLimitTokens) return;
|
|
203
|
+
if (budget.estimatedTokens - budget.reducibleToolResultTokens <= budget.hardLimitTokens) return;
|
|
204
|
+
throw new Error(`Context budget exceeded (${budget.estimatedTokens}/${budget.hardLimitTokens} tokens) and compaction is disabled`);
|
|
205
|
+
}
|
|
179
206
|
log.info({
|
|
180
207
|
sessionKey,
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
208
|
+
route: budget.route,
|
|
209
|
+
estimatedTokens: budget.estimatedTokens,
|
|
210
|
+
usagePercent: budget.usagePercent,
|
|
211
|
+
contextWindow,
|
|
212
|
+
activeTranscriptBytes,
|
|
213
|
+
maxActiveTranscriptBytes: policy.maxActiveTranscriptBytes,
|
|
214
|
+
byteLimitExceeded
|
|
184
215
|
}, "Pre-turn auto-compaction triggered");
|
|
185
216
|
onEvent?.({
|
|
186
217
|
type: "compaction",
|
|
187
218
|
status: "started",
|
|
188
|
-
tokensBefore:
|
|
219
|
+
tokensBefore: budget.estimatedTokens
|
|
189
220
|
});
|
|
190
221
|
try {
|
|
191
|
-
|
|
222
|
+
let summaryModel = model;
|
|
223
|
+
let summaryFallbackModels = fallbackModels;
|
|
224
|
+
if (policy.model) {
|
|
225
|
+
summaryModel = resolveModel(policy.model);
|
|
226
|
+
const summaryRef = `${summaryModel.provider}/${summaryModel.id}`;
|
|
227
|
+
summaryFallbackModels = [model, ...fallbackModels].filter((candidate) => `${candidate.provider}/${candidate.id}` !== summaryRef);
|
|
228
|
+
}
|
|
229
|
+
const result = await sessionStore.compact(sessionKey, messages, summaryModel, void 0, byteLimitExceeded || budget.estimatedTokens > budget.hardLimitTokens, {
|
|
230
|
+
fallbackModels: summaryFallbackModels,
|
|
231
|
+
signal: abortSignal
|
|
232
|
+
});
|
|
192
233
|
if (result.compacted) {
|
|
193
234
|
agentManager.removeAgent(sessionKey);
|
|
194
235
|
log.info({
|
|
@@ -203,20 +244,26 @@ async function maybeAutoCompactBeforeTurn(opts) {
|
|
|
203
244
|
tokensAfter: result.tokensAfter,
|
|
204
245
|
summary: result.summary.length > 200 ? `${result.summary.slice(0, 200)}…` : result.summary
|
|
205
246
|
});
|
|
206
|
-
} else
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
247
|
+
} else {
|
|
248
|
+
if (byteLimitExceeded || budget.estimatedTokens > budget.hardLimitTokens) throw new Error(byteLimitExceeded ? `Active transcript size exceeded (${activeTranscriptBytes}/${policy.maxActiveTranscriptBytes} bytes) but no safe compaction range was available` : `Context budget exceeded (${budget.estimatedTokens}/${budget.hardLimitTokens} tokens) but no safe compaction range was available`);
|
|
249
|
+
onEvent?.({
|
|
250
|
+
type: "compaction",
|
|
251
|
+
status: "skipped"
|
|
252
|
+
});
|
|
253
|
+
}
|
|
210
254
|
} catch (err) {
|
|
211
255
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
212
256
|
log.warn({
|
|
213
257
|
err,
|
|
214
|
-
sessionKey
|
|
258
|
+
sessionKey,
|
|
259
|
+
estimatedTokens: budget.estimatedTokens,
|
|
260
|
+
activeTranscriptBytes
|
|
215
261
|
}, `Pre-turn auto-compaction failed: ${errorMessage}`);
|
|
216
262
|
onEvent?.({
|
|
217
263
|
type: "compaction",
|
|
218
264
|
status: "skipped"
|
|
219
265
|
});
|
|
266
|
+
if (byteLimitExceeded || budget.estimatedTokens > budget.hardLimitTokens) throw err;
|
|
220
267
|
}
|
|
221
268
|
}
|
|
222
269
|
//#endregion
|
|
@@ -3,11 +3,13 @@ import { init_logger } from "../../utils/logger.js";
|
|
|
3
3
|
import { resolveAgentTurnTimeoutMs, runAgentTurnWithTimeout } from "../orchestration/run-agent-turn-with-timeout.js";
|
|
4
4
|
import { wrapStreamFnForXopcExtensions } from "./xopc-stream-bridge.js";
|
|
5
5
|
import { acquireEmbeddedSessionRunner, resolveEmbeddedTranscriptInputs } from "./session-runner.js";
|
|
6
|
-
import { getAssistantTurnErrorMessage, isAssistantTurnAborted, isAssistantTurnFailed, maybeRetryTurnAfterTransientLlmFailure } from "../orchestration/llm-turn-retry.js";
|
|
6
|
+
import { getAssistantTurnErrorMessage, isAssistantTurnAborted, isAssistantTurnFailed, maybeRetryTurnAfterTransientLlmFailure, stripTrailingErrorAssistantMessages } from "../orchestration/llm-turn-retry.js";
|
|
7
|
+
import { pruneToolResultsToFit } from "../memory/context-budget.js";
|
|
7
8
|
import { abortEmbeddedRun, queueEmbeddedSteer, registerEmbeddedRun, unregisterEmbeddedRun } from "./runs.js";
|
|
8
9
|
import { lastAssistantPlainText, subscribeEmbeddedSessionEvents } from "./subscribe-session.js";
|
|
9
10
|
import { detectToolLoops } from "../orchestration/loop-guard.js";
|
|
10
11
|
import { tryApplySessionTranscriptHygiene } from "../transcript/transcript-hygiene.js";
|
|
12
|
+
import { isContextOverflowError } from "../orchestration/context-overflow.js";
|
|
11
13
|
//#region src/agent/embedded/run-turn.ts
|
|
12
14
|
init_logger();
|
|
13
15
|
const log = createLogger("EmbeddedRun");
|
|
@@ -23,6 +25,13 @@ function extractTextFromContent(content) {
|
|
|
23
25
|
}).map((block) => block.text).join("");
|
|
24
26
|
}
|
|
25
27
|
function extractRecentToolCalls(messages) {
|
|
28
|
+
const resultByToolCallId = /* @__PURE__ */ new Map();
|
|
29
|
+
for (const message of messages) {
|
|
30
|
+
if (message.role !== "toolResult") continue;
|
|
31
|
+
const toolCallId = message.toolCallId;
|
|
32
|
+
if (typeof toolCallId !== "string" || !toolCallId) continue;
|
|
33
|
+
resultByToolCallId.set(toolCallId, truncateForLog(extractTextFromContent(message.content)));
|
|
34
|
+
}
|
|
26
35
|
const calls = [];
|
|
27
36
|
for (const message of messages) {
|
|
28
37
|
if (message.role !== "assistant" || !Array.isArray(message.content)) continue;
|
|
@@ -30,7 +39,8 @@ function extractRecentToolCalls(messages) {
|
|
|
30
39
|
const toolCall = block;
|
|
31
40
|
calls.push({
|
|
32
41
|
name: toolCall.name,
|
|
33
|
-
params: toolCall.arguments
|
|
42
|
+
params: toolCall.arguments,
|
|
43
|
+
...toolCall.id && resultByToolCallId.has(toolCall.id) ? { resultPreview: resultByToolCallId.get(toolCall.id) } : {}
|
|
34
44
|
});
|
|
35
45
|
}
|
|
36
46
|
}
|
|
@@ -56,6 +66,33 @@ function userMessageToPromptText(message) {
|
|
|
56
66
|
}).map((block) => block.text).join("");
|
|
57
67
|
return "";
|
|
58
68
|
}
|
|
69
|
+
async function maybeRecoverContextOverflow(params) {
|
|
70
|
+
const errorMessage = getAssistantTurnErrorMessage(params.agent);
|
|
71
|
+
if (!errorMessage || !isContextOverflowError(errorMessage)) return false;
|
|
72
|
+
const messages = stripTrailingErrorAssistantMessages(params.agent.state.messages);
|
|
73
|
+
log.warn({
|
|
74
|
+
sessionKey: params.sessionKey,
|
|
75
|
+
errorMessage,
|
|
76
|
+
messageCount: messages.length
|
|
77
|
+
}, "Provider rejected the context window; compacting and retrying the same turn");
|
|
78
|
+
params.onEvent?.({
|
|
79
|
+
type: "compaction",
|
|
80
|
+
status: "started"
|
|
81
|
+
});
|
|
82
|
+
const result = await params.sessionStore.compact(params.sessionKey, messages, params.model, "Preserve the current pending user request verbatim and retain every fact needed to answer it.", true);
|
|
83
|
+
if (!result.compacted) throw new Error(`Context overflow recovery could not find a safe compaction range: ${errorMessage}`);
|
|
84
|
+
params.agent.state.messages = await params.sessionStore.load(params.sessionKey);
|
|
85
|
+
params.onEvent?.({
|
|
86
|
+
type: "compaction",
|
|
87
|
+
status: "completed",
|
|
88
|
+
tokensBefore: result.tokensBefore,
|
|
89
|
+
tokensAfter: result.tokensAfter,
|
|
90
|
+
summary: result.summary.length > 200 ? `${result.summary.slice(0, 200)}…` : result.summary
|
|
91
|
+
});
|
|
92
|
+
await params.agent.continue();
|
|
93
|
+
await params.agent.waitForIdle();
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
59
96
|
async function runXopcEmbeddedTurn(params) {
|
|
60
97
|
const { sessionKey, runId, userMessage, model, tools, systemPrompt, thinkingLevel, workspaceDir, sessionStore, onEvent } = params;
|
|
61
98
|
const timeoutMs = params.timeoutMs || resolveAgentTurnTimeoutMs();
|
|
@@ -85,11 +122,11 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
85
122
|
messages: hygienicMessages
|
|
86
123
|
};
|
|
87
124
|
if (loopGuard.injection || loopGuard.hiddenTools.size > 0) {
|
|
88
|
-
const messages = loopGuard.injection ? [...
|
|
125
|
+
const messages = loopGuard.injection ? [...hygienicMessages, {
|
|
89
126
|
role: "user",
|
|
90
127
|
content: loopGuard.injection,
|
|
91
128
|
timestamp: Date.now()
|
|
92
|
-
}] :
|
|
129
|
+
}] : hygienicMessages;
|
|
93
130
|
const contextTools = loopGuard.hiddenTools.size > 0 && context.tools ? context.tools.filter((t) => !loopGuard.hiddenTools.has(t.name)) : context.tools;
|
|
94
131
|
effectiveContext = {
|
|
95
132
|
...context,
|
|
@@ -97,6 +134,26 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
97
134
|
tools: contextTools
|
|
98
135
|
};
|
|
99
136
|
}
|
|
137
|
+
const pruned = pruneToolResultsToFit({
|
|
138
|
+
messages: effectiveContext.messages,
|
|
139
|
+
contextWindow: streamModel.contextWindow ?? 128e3,
|
|
140
|
+
systemPrompt: effectiveContext.systemPrompt,
|
|
141
|
+
tools: effectiveContext.tools,
|
|
142
|
+
canCompact: false
|
|
143
|
+
});
|
|
144
|
+
if (pruned.prunedToolResults > 0) {
|
|
145
|
+
effectiveContext = {
|
|
146
|
+
...effectiveContext,
|
|
147
|
+
messages: pruned.messages
|
|
148
|
+
};
|
|
149
|
+
log.warn({
|
|
150
|
+
sessionKey,
|
|
151
|
+
runId,
|
|
152
|
+
prunedToolResults: pruned.prunedToolResults,
|
|
153
|
+
estimatedTokens: pruned.evaluation.estimatedTokens,
|
|
154
|
+
hardLimitTokens: pruned.evaluation.hardLimitTokens
|
|
155
|
+
}, "Pruned old tool results to fit the model context window");
|
|
156
|
+
}
|
|
100
157
|
log.debug({
|
|
101
158
|
sessionKey,
|
|
102
159
|
runId,
|
|
@@ -157,6 +214,13 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
157
214
|
sessionKey,
|
|
158
215
|
log
|
|
159
216
|
});
|
|
217
|
+
await maybeRecoverContextOverflow({
|
|
218
|
+
agent: session.agent,
|
|
219
|
+
model: resolvedModel,
|
|
220
|
+
sessionKey,
|
|
221
|
+
sessionStore,
|
|
222
|
+
onEvent
|
|
223
|
+
});
|
|
160
224
|
}, timeoutMs);
|
|
161
225
|
if (isAssistantTurnAborted(session.agent)) return {
|
|
162
226
|
ok: true,
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
* dependencies are injected so this class is unit-testable and the inbound
|
|
14
14
|
* pipeline can evolve without touching `AgentService`.
|
|
15
15
|
*/
|
|
16
|
-
import type { AgentMessage } from '@earendil-works/pi-agent-core';
|
|
17
16
|
import type { MessageBus } from '../../infra/bus/index.js';
|
|
18
17
|
import type { Config } from '../../config/schema.js';
|
|
19
18
|
import type { ChannelManager } from '../../channels/manager.js';
|
|
@@ -52,7 +51,6 @@ export interface InboundLoopConfig {
|
|
|
52
51
|
/** Returns the visible last assistant text used for outbound + persistent-goal hook. */
|
|
53
52
|
getLastAssistantPlainText: (sessionKey: string) => string;
|
|
54
53
|
/** Pre-turn auto-compaction (only used by system messages). */
|
|
55
|
-
checkAndCompact: (sessionKey: string, messages: AgentMessage[]) => Promise<void>;
|
|
56
54
|
/** Fire-and-forget auto-title (no-ops for cron/heartbeat keys). */
|
|
57
55
|
enqueueMaybeAutoTitleAfterPersist: (sessionKey: string) => void;
|
|
58
56
|
/** Effective merged config snapshot. */
|
|
@@ -206,8 +206,6 @@ var InboundLoop = class {
|
|
|
206
206
|
this.log.debug({ sessionKey: context.sessionKey }, "Processing system message");
|
|
207
207
|
await this.cfg.sessionHydrator.workspace(context.sessionKey);
|
|
208
208
|
await this.cfg.sessionHydrator.model(context.sessionKey);
|
|
209
|
-
const messages = await this.cfg.sessionStore.load(context.sessionKey);
|
|
210
|
-
await this.cfg.checkAndCompact(context.sessionKey, messages);
|
|
211
209
|
const systemMessage = {
|
|
212
210
|
role: "user",
|
|
213
211
|
content: [{
|
|
@@ -170,8 +170,8 @@ var BuiltinMemoryProvider = class {
|
|
|
170
170
|
projectId: request.scope?.projectId,
|
|
171
171
|
content: request.content,
|
|
172
172
|
source: {
|
|
173
|
-
|
|
174
|
-
|
|
173
|
+
provider: this.id,
|
|
174
|
+
...request.source ?? {}
|
|
175
175
|
},
|
|
176
176
|
confidence: request.confidence,
|
|
177
177
|
tags: request.tags,
|
|
@@ -208,9 +208,9 @@ var BuiltinMemoryProvider = class {
|
|
|
208
208
|
sessionKey: request.scope?.sessionKey,
|
|
209
209
|
content: request.content,
|
|
210
210
|
source: {
|
|
211
|
-
...request.source ?? {},
|
|
212
211
|
provider: this.id,
|
|
213
|
-
path: sourcePathForTarget(target)
|
|
212
|
+
path: sourcePathForTarget(target),
|
|
213
|
+
...request.source ?? {}
|
|
214
214
|
},
|
|
215
215
|
tags: request.tags,
|
|
216
216
|
canonicalKey: request.canonicalKey,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AgentMessage } from '@earendil-works/pi-agent-core';
|
|
2
|
+
export interface CompactionUnit {
|
|
3
|
+
messages: AgentMessage[];
|
|
4
|
+
text: string;
|
|
5
|
+
estimatedTokens: number;
|
|
6
|
+
}
|
|
7
|
+
export interface CompactionChunk {
|
|
8
|
+
text: string;
|
|
9
|
+
estimatedTokens: number;
|
|
10
|
+
messageCount: number;
|
|
11
|
+
oversized: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function serializeMessageForCompaction(message: AgentMessage): string;
|
|
14
|
+
export declare function buildCompactionUnits(messages: readonly AgentMessage[]): CompactionUnit[];
|
|
15
|
+
export declare function planCompactionChunks(messages: readonly AgentMessage[], maxChunkTokens: number): CompactionChunk[];
|
|
16
|
+
export declare function extractExactIdentifiers(messages: readonly AgentMessage[], limit?: number): string[];
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { readAgentMessageContent } from "./agent-message-access.js";
|
|
2
|
+
import { estimateTextTokens } from "./context-budget.js";
|
|
3
|
+
//#region src/agent/memory/compaction-planner.ts
|
|
4
|
+
function safeJson(value, maxChars = 8e3) {
|
|
5
|
+
let text;
|
|
6
|
+
try {
|
|
7
|
+
text = JSON.stringify(value, (_key, nested) => {
|
|
8
|
+
if (typeof nested === "string" && nested.length > 4e3) return `${nested.slice(0, 2e3)}\n… [${nested.length - 4e3} chars omitted] …\n${nested.slice(-2e3)}`;
|
|
9
|
+
return nested;
|
|
10
|
+
});
|
|
11
|
+
} catch {
|
|
12
|
+
text = String(value);
|
|
13
|
+
}
|
|
14
|
+
if (text.length <= maxChars) return text;
|
|
15
|
+
const half = Math.floor((maxChars - 80) / 2);
|
|
16
|
+
return `${text.slice(0, half)}\n… [structured value truncated] …\n${text.slice(-half)}`;
|
|
17
|
+
}
|
|
18
|
+
function valueRecord(value) {
|
|
19
|
+
return value && typeof value === "object" ? value : void 0;
|
|
20
|
+
}
|
|
21
|
+
function serializeContentBlock(block) {
|
|
22
|
+
const record = valueRecord(block);
|
|
23
|
+
if (!record) return safeJson(block);
|
|
24
|
+
const type = String(record.type ?? "unknown");
|
|
25
|
+
if (type === "text") return String(record.text ?? "");
|
|
26
|
+
if (type === "toolCall") return [
|
|
27
|
+
"[Tool call]",
|
|
28
|
+
`name: ${String(record.name ?? "unknown")}`,
|
|
29
|
+
`id: ${String(record.id ?? record.toolCallId ?? "unknown")}`,
|
|
30
|
+
`arguments: ${safeJson(record.arguments ?? record.args ?? {})}`
|
|
31
|
+
].join("\n");
|
|
32
|
+
if (type === "image" || type === "audio" || type === "video" || type === "file") {
|
|
33
|
+
const metadata = { ...record };
|
|
34
|
+
delete metadata.data;
|
|
35
|
+
delete metadata.bytes;
|
|
36
|
+
delete metadata.base64;
|
|
37
|
+
return `[${type} content]\nmetadata: ${safeJson(metadata, 2e3)}`;
|
|
38
|
+
}
|
|
39
|
+
if (type === "thinking" || type === "reasoning" || type === "reasoning_details") return "[Assistant private reasoning omitted from compaction input]";
|
|
40
|
+
return `[${type} block]\n${safeJson(record)}`;
|
|
41
|
+
}
|
|
42
|
+
function serializeMessageForCompaction(message) {
|
|
43
|
+
const record = message;
|
|
44
|
+
const raw = readAgentMessageContent(message);
|
|
45
|
+
const content = typeof raw === "string" ? raw : Array.isArray(raw) ? raw.map(serializeContentBlock).filter(Boolean).join("\n\n") : safeJson(raw);
|
|
46
|
+
const metadata = [];
|
|
47
|
+
if (message.role === "toolResult") {
|
|
48
|
+
metadata.push(`tool: ${String(record.toolName ?? "unknown")}`);
|
|
49
|
+
metadata.push(`toolCallId: ${String(record.toolCallId ?? "unknown")}`);
|
|
50
|
+
metadata.push(`status: ${record.isError === true ? "error" : "success"}`);
|
|
51
|
+
if (record.details != null) metadata.push(`details: ${safeJson(record.details, 4e3)}`);
|
|
52
|
+
}
|
|
53
|
+
return [
|
|
54
|
+
`### ${message.role}`,
|
|
55
|
+
...metadata,
|
|
56
|
+
content
|
|
57
|
+
].filter(Boolean).join("\n");
|
|
58
|
+
}
|
|
59
|
+
function toolCallIds(message) {
|
|
60
|
+
if (message.role !== "assistant") return /* @__PURE__ */ new Set();
|
|
61
|
+
const raw = readAgentMessageContent(message);
|
|
62
|
+
if (!Array.isArray(raw)) return /* @__PURE__ */ new Set();
|
|
63
|
+
const ids = /* @__PURE__ */ new Set();
|
|
64
|
+
for (const block of raw) {
|
|
65
|
+
const record = valueRecord(block);
|
|
66
|
+
if (record?.type !== "toolCall") continue;
|
|
67
|
+
const id = record.id ?? record.toolCallId;
|
|
68
|
+
if (typeof id === "string" && id) ids.add(id);
|
|
69
|
+
}
|
|
70
|
+
return ids;
|
|
71
|
+
}
|
|
72
|
+
function isMatchingToolResult(message, ids) {
|
|
73
|
+
if (message.role !== "toolResult") return false;
|
|
74
|
+
const id = message.toolCallId;
|
|
75
|
+
return typeof id === "string" && ids.has(id);
|
|
76
|
+
}
|
|
77
|
+
function buildCompactionUnits(messages) {
|
|
78
|
+
const units = [];
|
|
79
|
+
for (let index = 0; index < messages.length; index += 1) {
|
|
80
|
+
const group = [messages[index]];
|
|
81
|
+
const ids = toolCallIds(messages[index]);
|
|
82
|
+
if (ids.size > 0) while (index + 1 < messages.length && isMatchingToolResult(messages[index + 1], ids)) {
|
|
83
|
+
index += 1;
|
|
84
|
+
group.push(messages[index]);
|
|
85
|
+
}
|
|
86
|
+
const text = group.map(serializeMessageForCompaction).join("\n\n");
|
|
87
|
+
units.push({
|
|
88
|
+
messages: group,
|
|
89
|
+
text,
|
|
90
|
+
estimatedTokens: estimateTextTokens(text) + 16
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return units;
|
|
94
|
+
}
|
|
95
|
+
function truncateOversizedUnit(text, maxTokens) {
|
|
96
|
+
const maxChars = Math.max(800, maxTokens * 4);
|
|
97
|
+
if (text.length <= maxChars) return text;
|
|
98
|
+
const marker = `\n\n[Oversized atomic message group: ${text.length - maxChars} characters omitted from the middle]\n\n`;
|
|
99
|
+
const side = Math.max(200, Math.floor((maxChars - marker.length) / 2));
|
|
100
|
+
return `${text.slice(0, side)}${marker}${text.slice(-side)}`;
|
|
101
|
+
}
|
|
102
|
+
function planCompactionChunks(messages, maxChunkTokens) {
|
|
103
|
+
const chunks = [];
|
|
104
|
+
let parts = [];
|
|
105
|
+
let tokens = 0;
|
|
106
|
+
let messageCount = 0;
|
|
107
|
+
const flush = () => {
|
|
108
|
+
if (parts.length === 0) return;
|
|
109
|
+
chunks.push({
|
|
110
|
+
text: parts.join("\n\n"),
|
|
111
|
+
estimatedTokens: tokens,
|
|
112
|
+
messageCount,
|
|
113
|
+
oversized: false
|
|
114
|
+
});
|
|
115
|
+
parts = [];
|
|
116
|
+
tokens = 0;
|
|
117
|
+
messageCount = 0;
|
|
118
|
+
};
|
|
119
|
+
for (const unit of buildCompactionUnits(messages)) {
|
|
120
|
+
if (unit.estimatedTokens > maxChunkTokens) {
|
|
121
|
+
flush();
|
|
122
|
+
const text = truncateOversizedUnit(unit.text, maxChunkTokens);
|
|
123
|
+
chunks.push({
|
|
124
|
+
text,
|
|
125
|
+
estimatedTokens: estimateTextTokens(text),
|
|
126
|
+
messageCount: unit.messages.length,
|
|
127
|
+
oversized: true
|
|
128
|
+
});
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (tokens > 0 && tokens + unit.estimatedTokens > maxChunkTokens) flush();
|
|
132
|
+
parts.push(unit.text);
|
|
133
|
+
tokens += unit.estimatedTokens;
|
|
134
|
+
messageCount += unit.messages.length;
|
|
135
|
+
}
|
|
136
|
+
flush();
|
|
137
|
+
return chunks;
|
|
138
|
+
}
|
|
139
|
+
const IDENTIFIER_PATTERN = /(?:\/?[\w.-]+\/)+(?:[\w.@-]+)|https?:\/\/[^\s)>]+|\b[0-9a-f]{8,64}\b|\b\d{4}-\d{2}-\d{2}\b|\bport\s+\d{2,5}\b/gi;
|
|
140
|
+
function extractExactIdentifiers(messages, limit = 12) {
|
|
141
|
+
const text = messages.map(serializeMessageForCompaction).join("\n");
|
|
142
|
+
const found = /* @__PURE__ */ new Set();
|
|
143
|
+
for (const match of text.matchAll(IDENTIFIER_PATTERN)) {
|
|
144
|
+
const identifier = match[0].trim();
|
|
145
|
+
if (identifier.length < 4) continue;
|
|
146
|
+
found.add(identifier);
|
|
147
|
+
if (found.size >= limit) break;
|
|
148
|
+
}
|
|
149
|
+
return [...found];
|
|
150
|
+
}
|
|
151
|
+
//#endregion
|
|
152
|
+
export { buildCompactionUnits, extractExactIdentifiers, planCompactionChunks, serializeMessageForCompaction };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Config } from '../../config/schema.js';
|
|
2
|
+
import { type CompactionConfig } from './compaction.js';
|
|
3
|
+
export interface ResolvedCompactionPolicy extends CompactionConfig {
|
|
4
|
+
reserveTokens: number;
|
|
5
|
+
model?: string;
|
|
6
|
+
minToolResultKeepChars: number;
|
|
7
|
+
maxActiveTranscriptBytes: number;
|
|
8
|
+
postCompactionSections: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare function resolveCompactionPolicy(config?: Config): ResolvedCompactionPolicy;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { DEFAULT_COMPACTION_CONFIG } from "./compaction.js";
|
|
2
|
+
//#region src/agent/memory/compaction-policy.ts
|
|
3
|
+
const POLICY_DEFAULTS = {
|
|
4
|
+
...DEFAULT_COMPACTION_CONFIG,
|
|
5
|
+
reserveTokens: 8192,
|
|
6
|
+
minToolResultKeepChars: 1e3,
|
|
7
|
+
maxActiveTranscriptBytes: 2e6,
|
|
8
|
+
postCompactionSections: ["Session Startup", "Red Lines"]
|
|
9
|
+
};
|
|
10
|
+
function resolveCompactionPolicy(config) {
|
|
11
|
+
const configured = config?.userContext.memory.retention?.compaction;
|
|
12
|
+
if (!configured) return {
|
|
13
|
+
...POLICY_DEFAULTS,
|
|
14
|
+
postCompactionSections: [...POLICY_DEFAULTS.postCompactionSections]
|
|
15
|
+
};
|
|
16
|
+
return {
|
|
17
|
+
...POLICY_DEFAULTS,
|
|
18
|
+
...configured,
|
|
19
|
+
accumulateUsage: true,
|
|
20
|
+
postCompactionSections: [...configured.postCompactionSections]
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { resolveCompactionPolicy };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type { AgentMessage } from '@earendil-works/pi-agent-core';
|
|
2
|
-
import { type
|
|
3
|
-
import { type ConversationSummary } from './summary-generator.js';
|
|
2
|
+
import { type Api, type Model } from '@earendil-works/pi-ai/compat';
|
|
4
3
|
export interface CompactionResult {
|
|
5
4
|
summary: string;
|
|
6
5
|
firstKeptIndex: number;
|
|
7
6
|
tokensBefore: number;
|
|
8
7
|
tokensAfter: number;
|
|
9
8
|
compacted: boolean;
|
|
10
|
-
|
|
9
|
+
plannerVersion?: number;
|
|
10
|
+
summaryModelRef?: string;
|
|
11
|
+
qualityAudit?: 'passed' | 'disabled';
|
|
11
12
|
compactedUsage?: {
|
|
12
13
|
input: number;
|
|
13
14
|
output: number;
|
|
@@ -17,17 +18,22 @@ export interface CompactionResult {
|
|
|
17
18
|
}
|
|
18
19
|
export interface CompactionConfig {
|
|
19
20
|
enabled: boolean;
|
|
20
|
-
mode: 'extractive' | 'abstractive' | 'structured';
|
|
21
|
-
reserveTokens: number;
|
|
22
21
|
triggerThreshold: number;
|
|
23
22
|
minMessagesBeforeCompact: number;
|
|
24
|
-
|
|
23
|
+
keepRecentTokens: number;
|
|
24
|
+
recentTurnsPreserve: number;
|
|
25
25
|
summaryMaxTokens: number;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
summaryChunkTokens: number;
|
|
27
|
+
summaryTimeoutMs: number;
|
|
28
|
+
summaryRetries: number;
|
|
29
|
+
qualityGuard: boolean;
|
|
29
30
|
accumulateUsage: boolean;
|
|
30
31
|
}
|
|
32
|
+
export interface CompactionExecutionOptions {
|
|
33
|
+
fallbackModels?: Array<Model<Api>>;
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
}
|
|
36
|
+
export declare const DEFAULT_COMPACTION_CONFIG: CompactionConfig;
|
|
31
37
|
interface MessageUsage {
|
|
32
38
|
input: number;
|
|
33
39
|
output: number;
|
|
@@ -36,20 +42,13 @@ interface MessageUsage {
|
|
|
36
42
|
}
|
|
37
43
|
export declare function accumulateUsage(messages: AgentMessage[]): MessageUsage | undefined;
|
|
38
44
|
export declare class SessionCompactor {
|
|
39
|
-
private
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
needed: boolean;
|
|
44
|
-
reason: string;
|
|
45
|
-
usagePercent?: number;
|
|
46
|
-
};
|
|
47
|
-
compact(messages: AgentMessage[], instructions?: string, force?: boolean): Promise<CompactionResult>;
|
|
45
|
+
private readonly config;
|
|
46
|
+
constructor(config?: Partial<CompactionConfig>);
|
|
47
|
+
getConfig(): Readonly<CompactionConfig>;
|
|
48
|
+
compact(messages: AgentMessage[], model: Model<Api>, instructions?: string, force?: boolean, options?: CompactionExecutionOptions): Promise<CompactionResult>;
|
|
48
49
|
private generateSummary;
|
|
49
|
-
private
|
|
50
|
-
private formatMessages;
|
|
51
|
-
private extractiveSummary;
|
|
52
|
-
estimateTotalTokens(messages: AgentMessage[]): number;
|
|
50
|
+
private callSummaryModels;
|
|
53
51
|
applyCompaction(messages: AgentMessage[], result: CompactionResult): AgentMessage[];
|
|
52
|
+
estimateTotalTokens(messages: AgentMessage[]): number;
|
|
54
53
|
}
|
|
55
54
|
export {};
|