@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
|
@@ -1,22 +1,39 @@
|
|
|
1
1
|
import type { AgentMessage } from '@earendil-works/pi-agent-core';
|
|
2
|
+
import type { Api, Model } from '@earendil-works/pi-ai/compat';
|
|
2
3
|
import type { Config } from '../config/schema.js';
|
|
3
|
-
import { type CompactionConfig, type CompactionResult } from '../agent/memory/compaction.js';
|
|
4
|
+
import { type CompactionConfig, type CompactionExecutionOptions, type CompactionResult } from '../agent/memory/compaction.js';
|
|
4
5
|
import { type WindowConfig } from '../agent/memory/window.js';
|
|
5
6
|
import { type SessionMetadataSeed } from '../storage/sqlite/index.js';
|
|
6
7
|
import type { XopcSessionTranscriptV1 } from './transcript-format.js';
|
|
7
8
|
import { type TranscriptStoredRow, type XopcTranscriptContextEntry } from './session-context-for-llm.js';
|
|
8
|
-
import type { SessionMetadata, SessionDetail, SessionListQuery, PaginatedResult, GlobalSessionStats, ExportFormat,
|
|
9
|
+
import type { SessionMetadata, SessionDetail, SessionListQuery, PaginatedResult, GlobalSessionStats, ExportFormat, CompactionBoundarySummary } from './types.js';
|
|
9
10
|
import { SessionStatus } from './types.js';
|
|
10
11
|
import type { Message } from './types.js';
|
|
11
12
|
import type { SessionTranscriptUpdate } from './transcript-events.js';
|
|
12
13
|
export interface SessionStoreOptions {
|
|
13
14
|
config: Config;
|
|
14
15
|
}
|
|
16
|
+
export interface SessionCompactionHooks {
|
|
17
|
+
before?: (event: {
|
|
18
|
+
sessionKey: string;
|
|
19
|
+
messageCount: number;
|
|
20
|
+
tokenCount: number;
|
|
21
|
+
}) => Promise<void> | void;
|
|
22
|
+
after?: (event: {
|
|
23
|
+
sessionKey: string;
|
|
24
|
+
messageCount: number;
|
|
25
|
+
tokenCount: number;
|
|
26
|
+
compactedCount: number;
|
|
27
|
+
}) => Promise<void> | void;
|
|
28
|
+
}
|
|
15
29
|
export declare class SessionStore {
|
|
16
30
|
private options;
|
|
17
31
|
private window;
|
|
18
32
|
private compactor;
|
|
33
|
+
private compactionHooks;
|
|
19
34
|
constructor(options: SessionStoreOptions, windowConfig?: Partial<WindowConfig>, compactionConfig?: Partial<CompactionConfig>);
|
|
35
|
+
setCompactionHooks(hooks: SessionCompactionHooks): void;
|
|
36
|
+
private runCompactionHook;
|
|
20
37
|
private resolveWorkspaceCwd;
|
|
21
38
|
private runStoreMutation;
|
|
22
39
|
initialize(): Promise<void>;
|
|
@@ -110,6 +127,11 @@ export declare class SessionStore {
|
|
|
110
127
|
saveMessages(key: string, messages: AgentMessage[], options?: {
|
|
111
128
|
metadata?: SessionMetadataSeed;
|
|
112
129
|
}): Promise<void>;
|
|
130
|
+
deleteUserRound(key: string, userRoundIndex: number): Promise<{
|
|
131
|
+
deleted: number;
|
|
132
|
+
removedMessages: AgentMessage[];
|
|
133
|
+
remainingMessages: AgentMessage[];
|
|
134
|
+
} | null>;
|
|
113
135
|
getWindowStats(messages: AgentMessage[]): {
|
|
114
136
|
total: number;
|
|
115
137
|
system: number;
|
|
@@ -118,31 +140,16 @@ export declare class SessionStore {
|
|
|
118
140
|
tool: number;
|
|
119
141
|
needsTrim: boolean;
|
|
120
142
|
};
|
|
121
|
-
needsCompaction(key: string, messages: AgentMessage[], contextWindow: number): {
|
|
122
|
-
needed: boolean;
|
|
123
|
-
reason: string;
|
|
124
|
-
usagePercent?: number;
|
|
125
|
-
};
|
|
126
|
-
prepareCompaction(key: string, messages: AgentMessage[], contextWindow: number): {
|
|
127
|
-
needsCompaction: boolean;
|
|
128
|
-
messages: AgentMessage[];
|
|
129
|
-
stats: {
|
|
130
|
-
needed: boolean;
|
|
131
|
-
reason: string;
|
|
132
|
-
usagePercent?: number;
|
|
133
|
-
};
|
|
134
|
-
};
|
|
135
143
|
applyCompaction(key: string, messages: AgentMessage[], result: CompactionResult): Promise<AgentMessage[]>;
|
|
136
|
-
compact(key: string, messages: AgentMessage[],
|
|
144
|
+
compact(key: string, messages: AgentMessage[], model: Model<Api>, instructions?: string, force?: boolean, executionOptions?: CompactionExecutionOptions): Promise<CompactionResult>;
|
|
137
145
|
getCompactionStats(key: string): Promise<{
|
|
138
146
|
compactionCount: number;
|
|
139
147
|
totalTokensBefore: number;
|
|
140
148
|
totalTokensAfter: number;
|
|
141
|
-
lastCompactionAt:
|
|
149
|
+
lastCompactionAt: string;
|
|
142
150
|
}>;
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
restoreCompactionCheckpoint(key: string, checkpointId: string): Promise<void>;
|
|
151
|
+
listCompactionBoundaries(key: string): Promise<CompactionBoundarySummary[]>;
|
|
152
|
+
restoreBeforeCompactionBoundary(key: string, compactionId: string): Promise<void>;
|
|
146
153
|
deleteSession(key: string): Promise<boolean>;
|
|
147
154
|
load(key: string, options?: {
|
|
148
155
|
fromArchive?: boolean;
|
|
@@ -169,9 +176,7 @@ export declare class SessionStore {
|
|
|
169
176
|
estimateTokens(messages: AgentMessage[]): number;
|
|
170
177
|
private loadDisplayMessages;
|
|
171
178
|
private paginateDisplayMessages;
|
|
172
|
-
private displayMessageIdentity;
|
|
173
179
|
private messageContent;
|
|
174
|
-
private isCompactionSummaryMessage;
|
|
175
180
|
private extractTextContent;
|
|
176
181
|
private injectPostCompactionContext;
|
|
177
182
|
private convertMessages;
|
|
@@ -3,18 +3,19 @@ import { createLogger } from "../utils/logger/index.js";
|
|
|
3
3
|
import { init_logger } from "../utils/logger.js";
|
|
4
4
|
import { requireXopcDatabase } from "../storage/sqlite/connection.js";
|
|
5
5
|
import "./types.js";
|
|
6
|
-
import { buildSessionContextForLlm, buildSessionDisplayMessages, mergeLlmMessagesPreservingContextRows, transcriptRowsFromJsonArray } from "./session-context-for-llm.js";
|
|
6
|
+
import { buildSessionContextForLlm, buildSessionDisplayMessages, isRuntimeOnlyTranscriptMessage, isTranscriptCompactionEntry, mergeLlmMessagesPreservingContextRows, transcriptRowsFromJsonArray } from "./session-context-for-llm.js";
|
|
7
7
|
import { estimateTokensFromMessages } from "../storage/sqlite/row-mappers.js";
|
|
8
8
|
import { deleteSessionRecord, ensureSessionRecord, findSessionKeyBySessionId, getGlobalSessionStats, getSessionMetadata, listSessionMetadata, listSessionsByAgent, patchSessionMetadata, resetSessionRecord } from "../storage/sqlite/session-repository.js";
|
|
9
|
-
import {
|
|
9
|
+
import { appendCompactionBoundary, appendTranscriptEntry, listCompactionBoundaries, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreBeforeCompactionBoundary } from "../storage/sqlite/transcript-repository.js";
|
|
10
10
|
import "../storage/sqlite/index.js";
|
|
11
11
|
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
12
12
|
import { readPostCompactionContext } from "../agent/reply/post-compaction-context.js";
|
|
13
13
|
import { SessionCompactor } from "../agent/memory/compaction.js";
|
|
14
|
+
import { resolveCompactionPolicy } from "../agent/memory/compaction-policy.js";
|
|
14
15
|
import { SlidingWindow } from "../agent/memory/window.js";
|
|
15
|
-
import { normalizeCompactionCheckpointId } from "./compaction-checkpoints.js";
|
|
16
16
|
import { isAppendOnlyLlmTranscriptMessage } from "./transcript-stats.js";
|
|
17
17
|
import { transcriptRowsToClientHistory } from "./client-history.js";
|
|
18
|
+
import { computeTranscriptUserRoundDeleteRange } from "./user-round-delete.js";
|
|
18
19
|
//#region src/session/store.ts
|
|
19
20
|
init_paths_state();
|
|
20
21
|
init_logger();
|
|
@@ -23,11 +24,30 @@ const INDEX_VERSION = "1.0";
|
|
|
23
24
|
var SessionStore = class {
|
|
24
25
|
window;
|
|
25
26
|
compactor;
|
|
27
|
+
compactionHooks = {};
|
|
26
28
|
constructor(options, windowConfig, compactionConfig) {
|
|
27
29
|
this.options = options;
|
|
28
30
|
this.window = new SlidingWindow(windowConfig);
|
|
29
31
|
this.compactor = new SessionCompactor(compactionConfig);
|
|
30
32
|
}
|
|
33
|
+
setCompactionHooks(hooks) {
|
|
34
|
+
this.compactionHooks = hooks;
|
|
35
|
+
}
|
|
36
|
+
async runCompactionHook(phase, event) {
|
|
37
|
+
try {
|
|
38
|
+
if (phase === "before") await this.compactionHooks.before?.(event);
|
|
39
|
+
else await this.compactionHooks.after?.({
|
|
40
|
+
...event,
|
|
41
|
+
compactedCount: event.compactedCount ?? 0
|
|
42
|
+
});
|
|
43
|
+
} catch (err) {
|
|
44
|
+
log.warn({
|
|
45
|
+
err,
|
|
46
|
+
phase,
|
|
47
|
+
sessionKey: event.sessionKey
|
|
48
|
+
}, `Session compaction ${phase} hook failed`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
31
51
|
resolveWorkspaceCwd(sessionKey) {
|
|
32
52
|
return resolveEffectiveAgentProfileForSession(this.options.config, sessionKey).resolvedWorkspacePath;
|
|
33
53
|
}
|
|
@@ -94,8 +114,7 @@ var SessionStore = class {
|
|
|
94
114
|
limit,
|
|
95
115
|
offset: hasBeforeCursor ? void 0 : offset,
|
|
96
116
|
beforeIndex: hasBeforeCursor ? parsedBefore : void 0,
|
|
97
|
-
includeContext: true
|
|
98
|
-
includeArchived: true
|
|
117
|
+
includeContext: true
|
|
99
118
|
});
|
|
100
119
|
const messages = transcriptRowsToClientHistory(page.rows);
|
|
101
120
|
const endIndex = hasBeforeCursor ? Math.min(page.total, Math.max(0, parsedBefore)) : Math.max(0, page.total - offset);
|
|
@@ -242,16 +261,19 @@ var SessionStore = class {
|
|
|
242
261
|
if (!metadata?.sessionId) return null;
|
|
243
262
|
const rows = await this.loadTranscriptRows(key);
|
|
244
263
|
const compactions = [];
|
|
245
|
-
for (const row of rows) if (row
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
264
|
+
for (const row of rows) if (isTranscriptCompactionEntry(row)) compactions.push({
|
|
265
|
+
at: row.at,
|
|
266
|
+
baseSeq: row.baseSeq,
|
|
267
|
+
plannerVersion: row.plannerVersion,
|
|
268
|
+
summaryModelRef: row.summaryModelRef,
|
|
269
|
+
qualityAudit: row.qualityAudit,
|
|
270
|
+
summary: row.summary,
|
|
271
|
+
messages: row.messages,
|
|
272
|
+
firstKeptIndex: row.firstKeptIndex,
|
|
273
|
+
tokensBefore: row.tokensBefore,
|
|
274
|
+
tokensAfter: row.tokensAfter,
|
|
275
|
+
restoredFromCompactionId: row.restoredFromCompactionId
|
|
276
|
+
});
|
|
255
277
|
return {
|
|
256
278
|
type: "xopc_session_transcript",
|
|
257
279
|
version: 1,
|
|
@@ -346,34 +368,42 @@ var SessionStore = class {
|
|
|
346
368
|
replaceTranscriptRows(key, mergeLlmMessagesPreservingContextRows(await this.loadTranscriptRows(key), messages));
|
|
347
369
|
});
|
|
348
370
|
}
|
|
371
|
+
async deleteUserRound(key, userRoundIndex) {
|
|
372
|
+
return this.runStoreMutation(async () => {
|
|
373
|
+
requireXopcDatabase();
|
|
374
|
+
const canonicalRows = (await this.loadTranscriptRows(key)).filter((row) => !isTranscriptCompactionEntry(row) && !isRuntimeOnlyTranscriptMessage(row));
|
|
375
|
+
const range = computeTranscriptUserRoundDeleteRange(canonicalRows, userRoundIndex);
|
|
376
|
+
if (!range) return null;
|
|
377
|
+
const removedRows = canonicalRows.slice(range.startIndex, range.startIndex + range.count);
|
|
378
|
+
const remainingRows = canonicalRows.slice(0, range.startIndex).concat(canonicalRows.slice(range.startIndex + range.count));
|
|
379
|
+
const removedMessages = buildSessionDisplayMessages(removedRows);
|
|
380
|
+
const remainingMessages = buildSessionDisplayMessages(remainingRows);
|
|
381
|
+
replaceTranscriptRows(key, remainingRows);
|
|
382
|
+
return {
|
|
383
|
+
deleted: removedMessages.length,
|
|
384
|
+
removedMessages,
|
|
385
|
+
remainingMessages
|
|
386
|
+
};
|
|
387
|
+
});
|
|
388
|
+
}
|
|
349
389
|
getWindowStats(messages) {
|
|
350
390
|
return this.window.getStats(messages);
|
|
351
391
|
}
|
|
352
|
-
needsCompaction(key, messages, contextWindow) {
|
|
353
|
-
return this.compactor.needsCompaction(messages, contextWindow);
|
|
354
|
-
}
|
|
355
|
-
prepareCompaction(key, messages, contextWindow) {
|
|
356
|
-
const result = this.compactor.needsCompaction(messages, contextWindow);
|
|
357
|
-
return {
|
|
358
|
-
needsCompaction: result.needed,
|
|
359
|
-
messages,
|
|
360
|
-
stats: result
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
392
|
async applyCompaction(key, messages, result) {
|
|
364
393
|
const compacted = this.compactor.applyCompaction(messages, result);
|
|
365
394
|
return this.runStoreMutation(async () => {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
replaceTranscriptRows(key, merged, { appendCompaction: {
|
|
395
|
+
appendCompactionBoundary(key, {
|
|
396
|
+
type: "compaction",
|
|
369
397
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
398
|
+
plannerVersion: result.plannerVersion ?? 2,
|
|
399
|
+
summaryModelRef: result.summaryModelRef ?? "unknown",
|
|
400
|
+
qualityAudit: result.qualityAudit ?? "disabled",
|
|
370
401
|
summary: result.summary,
|
|
402
|
+
messages: compacted,
|
|
371
403
|
firstKeptIndex: result.firstKeptIndex,
|
|
372
404
|
tokensBefore: result.tokensBefore,
|
|
373
405
|
tokensAfter: result.tokensAfter
|
|
374
|
-
}
|
|
375
|
-
const metadata = await this.getMetadata(key);
|
|
376
|
-
if (metadata) await this.updateMetadata(key, { compactedCount: metadata.compactedCount + 1 });
|
|
406
|
+
});
|
|
377
407
|
log.info({
|
|
378
408
|
key,
|
|
379
409
|
tokensBefore: result.tokensBefore,
|
|
@@ -384,37 +414,44 @@ var SessionStore = class {
|
|
|
384
414
|
return compacted;
|
|
385
415
|
});
|
|
386
416
|
}
|
|
387
|
-
async compact(key, messages,
|
|
388
|
-
const
|
|
389
|
-
|
|
417
|
+
async compact(key, messages, model, instructions, force, executionOptions) {
|
|
418
|
+
const tokenCount = this.estimateTokens(messages);
|
|
419
|
+
await this.runCompactionHook("before", {
|
|
420
|
+
sessionKey: key,
|
|
421
|
+
messageCount: messages.length,
|
|
422
|
+
tokenCount
|
|
423
|
+
});
|
|
424
|
+
const result = await this.compactor.compact(messages, model, instructions, force, executionOptions);
|
|
425
|
+
if (result.compacted) {
|
|
426
|
+
const compacted = await this.applyCompaction(key, messages, result);
|
|
427
|
+
await this.runCompactionHook("after", {
|
|
428
|
+
sessionKey: key,
|
|
429
|
+
messageCount: compacted.length,
|
|
430
|
+
tokenCount: result.tokensAfter,
|
|
431
|
+
compactedCount: Math.max(0, Math.min(messages.length, result.firstKeptIndex))
|
|
432
|
+
});
|
|
433
|
+
}
|
|
390
434
|
return result;
|
|
391
435
|
}
|
|
392
436
|
async getCompactionStats(key) {
|
|
393
|
-
|
|
394
|
-
|
|
437
|
+
if (!await this.getMetadata(key)) return void 0;
|
|
438
|
+
const boundaries = listCompactionBoundaries(key);
|
|
395
439
|
return {
|
|
396
|
-
compactionCount:
|
|
397
|
-
totalTokensBefore: 0,
|
|
398
|
-
totalTokensAfter: 0,
|
|
399
|
-
lastCompactionAt:
|
|
440
|
+
compactionCount: boundaries.length,
|
|
441
|
+
totalTokensBefore: boundaries.reduce((sum, boundary) => sum + boundary.tokensBefore, 0),
|
|
442
|
+
totalTokensAfter: boundaries.reduce((sum, boundary) => sum + boundary.tokensAfter, 0),
|
|
443
|
+
lastCompactionAt: boundaries[0]?.createdAt
|
|
400
444
|
};
|
|
401
445
|
}
|
|
402
|
-
async
|
|
403
|
-
requireXopcDatabase();
|
|
404
|
-
return listCompactionCheckpoints(key);
|
|
405
|
-
}
|
|
406
|
-
async getCompactionCheckpointDetail(key, checkpointId) {
|
|
446
|
+
async listCompactionBoundaries(key) {
|
|
407
447
|
requireXopcDatabase();
|
|
408
|
-
|
|
409
|
-
if (!id) return null;
|
|
410
|
-
return getCompactionCheckpointDetail(key, id);
|
|
448
|
+
return listCompactionBoundaries(key);
|
|
411
449
|
}
|
|
412
|
-
async
|
|
450
|
+
async restoreBeforeCompactionBoundary(key, compactionId) {
|
|
413
451
|
return this.runStoreMutation(async () => {
|
|
414
452
|
requireXopcDatabase();
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
restoreCompactionCheckpoint(key, id);
|
|
453
|
+
if (!compactionId.trim()) throw new Error("compactionId is required");
|
|
454
|
+
restoreBeforeCompactionBoundary(key, compactionId);
|
|
418
455
|
});
|
|
419
456
|
}
|
|
420
457
|
async deleteSession(key) {
|
|
@@ -553,20 +590,7 @@ var SessionStore = class {
|
|
|
553
590
|
}
|
|
554
591
|
async loadDisplayMessages(key) {
|
|
555
592
|
requireXopcDatabase();
|
|
556
|
-
|
|
557
|
-
const rowSets = [];
|
|
558
|
-
for (const checkpoint of [...checkpoints].reverse()) rowSets.push(loadCheckpointRows(key, checkpoint.id));
|
|
559
|
-
rowSets.push(await this.loadTranscriptRows(key));
|
|
560
|
-
const messages = [];
|
|
561
|
-
const seen = /* @__PURE__ */ new Set();
|
|
562
|
-
for (const rows of rowSets) for (const message of buildSessionDisplayMessages(rows)) {
|
|
563
|
-
if (this.isCompactionSummaryMessage(message)) continue;
|
|
564
|
-
const identity = this.displayMessageIdentity(message);
|
|
565
|
-
if (seen.has(identity)) continue;
|
|
566
|
-
seen.add(identity);
|
|
567
|
-
messages.push(message);
|
|
568
|
-
}
|
|
569
|
-
return messages;
|
|
593
|
+
return buildSessionDisplayMessages(await this.loadTranscriptRows(key));
|
|
570
594
|
}
|
|
571
595
|
paginateDisplayMessages(messages, options = {}) {
|
|
572
596
|
const total = messages.length;
|
|
@@ -588,24 +612,9 @@ var SessionStore = class {
|
|
|
588
612
|
endIndex
|
|
589
613
|
};
|
|
590
614
|
}
|
|
591
|
-
displayMessageIdentity(message) {
|
|
592
|
-
const record = message;
|
|
593
|
-
return JSON.stringify({
|
|
594
|
-
role: message.role,
|
|
595
|
-
timestamp: record.timestamp,
|
|
596
|
-
toolCallId: record.toolCallId ?? record.tool_call_id,
|
|
597
|
-
toolName: record.toolName,
|
|
598
|
-
content: this.messageContent(message)
|
|
599
|
-
});
|
|
600
|
-
}
|
|
601
615
|
messageContent(msg) {
|
|
602
616
|
return msg.content;
|
|
603
617
|
}
|
|
604
|
-
isCompactionSummaryMessage(msg) {
|
|
605
|
-
if (msg.role !== "user") return false;
|
|
606
|
-
const text = this.extractTextContent(this.messageContent(msg)).trim();
|
|
607
|
-
return /^\[Previous conversation summary\]/i.test(text);
|
|
608
|
-
}
|
|
609
618
|
extractTextContent(content) {
|
|
610
619
|
if (typeof content === "string") return content;
|
|
611
620
|
if (Array.isArray(content)) {
|
|
@@ -621,9 +630,11 @@ var SessionStore = class {
|
|
|
621
630
|
return "";
|
|
622
631
|
}
|
|
623
632
|
async injectPostCompactionContext(key) {
|
|
633
|
+
const policy = resolveCompactionPolicy(this.options.config);
|
|
624
634
|
const contextText = readPostCompactionContext({
|
|
625
635
|
cfg: this.options.config,
|
|
626
|
-
sessionKey: key
|
|
636
|
+
sessionKey: key,
|
|
637
|
+
sectionNames: policy.postCompactionSections
|
|
627
638
|
});
|
|
628
639
|
if (!contextText?.trim()) return;
|
|
629
640
|
try {
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* API-level transcript summary types (authoritative storage is SQLite `transcript_entries`).
|
|
3
3
|
*/
|
|
4
|
-
import type { TranscriptStoredRow } from './session-context-for-llm.js';
|
|
4
|
+
import type { TranscriptStoredRow, XopcTranscriptCompactionEntry } from './session-context-for-llm.js';
|
|
5
5
|
export declare const XOPC_SESSION_TRANSCRIPT_TYPE: "xopc_session_transcript";
|
|
6
6
|
export declare const CURRENT_SESSION_TRANSCRIPT_VERSION = 1;
|
|
7
7
|
/** Record appended when context compaction runs (mirrors pi `CompactionEntry` audit fields). */
|
|
8
|
-
export
|
|
9
|
-
at: string;
|
|
10
|
-
summary: string;
|
|
11
|
-
firstKeptIndex: number;
|
|
12
|
-
tokensBefore: number;
|
|
13
|
-
tokensAfter: number;
|
|
14
|
-
}
|
|
8
|
+
export type TranscriptCompactionRecord = Omit<XopcTranscriptCompactionEntry, 'type'>;
|
|
15
9
|
/** Synthetic document shape returned by {@link SessionStore.loadTranscriptDocument} for API parity. */
|
|
16
10
|
export interface XopcSessionTranscriptV1 {
|
|
17
11
|
type: typeof XOPC_SESSION_TRANSCRIPT_TYPE;
|
|
@@ -179,12 +179,14 @@ export interface SessionExport {
|
|
|
179
179
|
/** Full on-disk rows (LLM + `kind: 'context'`) for audit / round-trip. */
|
|
180
180
|
transcriptRows: TranscriptStoredRow[];
|
|
181
181
|
}
|
|
182
|
-
/**
|
|
183
|
-
export interface
|
|
182
|
+
/** Append-only context boundary produced by compaction or logical restoration. */
|
|
183
|
+
export interface CompactionBoundarySummary {
|
|
184
184
|
id: string;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
188
|
-
export interface CompactionCheckpointDetail extends CompactionCheckpointSummary {
|
|
185
|
+
seq: number;
|
|
186
|
+
createdAt: string;
|
|
189
187
|
messageCount: number;
|
|
188
|
+
tokensBefore: number;
|
|
189
|
+
tokensAfter: number;
|
|
190
|
+
summaryPreview: string;
|
|
191
|
+
restoredFromCompactionId?: string;
|
|
190
192
|
}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import type
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
* assistant / tool / toolResult row until the next user (or EOF).
|
|
5
|
-
*/
|
|
6
|
-
export declare function computeUserRoundDeleteRange(messages: readonly AgentMessage[], userRoundIndex: number): {
|
|
1
|
+
import { type TranscriptStoredRow } from './session-context-for-llm.js';
|
|
2
|
+
/** Raw transcript range for one UI-visible user turn. */
|
|
3
|
+
export declare function computeTranscriptUserRoundDeleteRange(rows: readonly TranscriptStoredRow[], userRoundIndex: number): {
|
|
7
4
|
startIndex: number;
|
|
8
5
|
count: number;
|
|
9
6
|
} | null;
|
|
@@ -1,33 +1,29 @@
|
|
|
1
|
+
import { isTranscriptCustomMessageEntry } from "./session-context-for-llm.js";
|
|
1
2
|
//#region src/session/user-round-delete.ts
|
|
2
|
-
function
|
|
3
|
-
return
|
|
3
|
+
function isVisibleUserRow(row) {
|
|
4
|
+
if (isTranscriptCustomMessageEntry(row)) return row.display !== false;
|
|
5
|
+
return row.role === "user";
|
|
4
6
|
}
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*/
|
|
9
|
-
function computeUserRoundDeleteRange(messages, userRoundIndex) {
|
|
10
|
-
if (userRoundIndex < 0 || messages.length === 0) return null;
|
|
7
|
+
/** Raw transcript range for one UI-visible user turn. */
|
|
8
|
+
function computeTranscriptUserRoundDeleteRange(rows, userRoundIndex) {
|
|
9
|
+
if (!Number.isInteger(userRoundIndex) || userRoundIndex < 0 || rows.length === 0) return null;
|
|
11
10
|
let userCount = 0;
|
|
12
11
|
let startIndex = -1;
|
|
13
|
-
for (let
|
|
14
|
-
if (!
|
|
12
|
+
for (let index = 0; index < rows.length; index += 1) {
|
|
13
|
+
if (!isVisibleUserRow(rows[index])) continue;
|
|
15
14
|
if (userCount === userRoundIndex) {
|
|
16
|
-
startIndex =
|
|
15
|
+
startIndex = index;
|
|
17
16
|
break;
|
|
18
17
|
}
|
|
19
18
|
userCount += 1;
|
|
20
19
|
}
|
|
21
20
|
if (startIndex < 0) return null;
|
|
22
21
|
let end = startIndex + 1;
|
|
23
|
-
while (end <
|
|
24
|
-
if (isUserRole(String(messages[end]?.role ?? ""))) break;
|
|
25
|
-
end += 1;
|
|
26
|
-
}
|
|
22
|
+
while (end < rows.length && !isVisibleUserRow(rows[end])) end += 1;
|
|
27
23
|
return {
|
|
28
24
|
startIndex,
|
|
29
25
|
count: end - startIndex
|
|
30
26
|
};
|
|
31
27
|
}
|
|
32
28
|
//#endregion
|
|
33
|
-
export {
|
|
29
|
+
export { computeTranscriptUserRoundDeleteRange };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export type ConnectorLearningMode = 'bootstrap' | 'incremental';
|
|
2
|
+
export type ConnectorLearningStatus = 'queued' | 'running' | 'completed' | 'failed' | 'paused';
|
|
3
|
+
export type ConnectorLearningPhase = 'queued' | 'fetching' | 'indexing' | 'deriving' | 'completed';
|
|
4
|
+
export type ConnectorLearningJob = {
|
|
5
|
+
id: string;
|
|
6
|
+
idempotencyKey: string;
|
|
7
|
+
connectorId: string;
|
|
8
|
+
connectionId: string;
|
|
9
|
+
sourceInstanceId: string;
|
|
10
|
+
agentId: string;
|
|
11
|
+
mode: ConnectorLearningMode;
|
|
12
|
+
status: ConnectorLearningStatus;
|
|
13
|
+
phase: ConnectorLearningPhase;
|
|
14
|
+
itemsDiscovered: number;
|
|
15
|
+
itemsIndexed: number;
|
|
16
|
+
candidatesCreated: number;
|
|
17
|
+
attemptCount: number;
|
|
18
|
+
error?: string;
|
|
19
|
+
nextRunAt?: string;
|
|
20
|
+
startedAt?: string;
|
|
21
|
+
finishedAt?: string;
|
|
22
|
+
createdAt: string;
|
|
23
|
+
updatedAt: string;
|
|
24
|
+
};
|
|
25
|
+
export declare function enqueueConnectorLearningJob(input: {
|
|
26
|
+
connectorId: string;
|
|
27
|
+
connectionId: string;
|
|
28
|
+
sourceInstanceId: string;
|
|
29
|
+
agentId: string;
|
|
30
|
+
mode: ConnectorLearningMode;
|
|
31
|
+
idempotencyKey: string;
|
|
32
|
+
nextRunAt?: number;
|
|
33
|
+
nowMs?: number;
|
|
34
|
+
}): ConnectorLearningJob;
|
|
35
|
+
export declare function claimNextConnectorLearningJob(nowMs?: number): ConnectorLearningJob | null;
|
|
36
|
+
export declare function recoverStaleConnectorLearningJobs(staleBeforeMs: number, nowMs?: number): number;
|
|
37
|
+
export declare function setConnectorLearningPaused(connectionId: string, paused: boolean, nowMs?: number): number;
|
|
38
|
+
export declare function updateConnectorLearningJob(id: string, patch: Partial<Pick<ConnectorLearningJob, 'status' | 'phase' | 'itemsDiscovered' | 'itemsIndexed' | 'candidatesCreated' | 'error'>> & {
|
|
39
|
+
nextRunAt?: number | null;
|
|
40
|
+
finished?: boolean;
|
|
41
|
+
nowMs?: number;
|
|
42
|
+
}): ConnectorLearningJob;
|
|
43
|
+
export declare function listConnectorLearningJobs(options?: {
|
|
44
|
+
sourceInstanceId?: string;
|
|
45
|
+
connectionId?: string;
|
|
46
|
+
limit?: number;
|
|
47
|
+
}): ConnectorLearningJob[];
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
//#region src/storage/sqlite/connector-learning-repository.ts
|
|
4
|
+
function iso(value) {
|
|
5
|
+
return value == null ? void 0 : new Date(value).toISOString();
|
|
6
|
+
}
|
|
7
|
+
function fromRow(row) {
|
|
8
|
+
return {
|
|
9
|
+
id: row.job_id,
|
|
10
|
+
idempotencyKey: row.idempotency_key,
|
|
11
|
+
connectorId: row.connector_id,
|
|
12
|
+
connectionId: row.connection_id,
|
|
13
|
+
sourceInstanceId: row.source_instance_id,
|
|
14
|
+
agentId: row.agent_id,
|
|
15
|
+
mode: row.mode,
|
|
16
|
+
status: row.status,
|
|
17
|
+
phase: row.phase,
|
|
18
|
+
itemsDiscovered: row.items_discovered,
|
|
19
|
+
itemsIndexed: row.items_indexed,
|
|
20
|
+
candidatesCreated: row.candidates_created,
|
|
21
|
+
attemptCount: row.attempt_count,
|
|
22
|
+
...row.error ? { error: row.error } : {},
|
|
23
|
+
...iso(row.next_run_at) ? { nextRunAt: iso(row.next_run_at) } : {},
|
|
24
|
+
...iso(row.started_at) ? { startedAt: iso(row.started_at) } : {},
|
|
25
|
+
...iso(row.finished_at) ? { finishedAt: iso(row.finished_at) } : {},
|
|
26
|
+
createdAt: new Date(row.created_at).toISOString(),
|
|
27
|
+
updatedAt: new Date(row.updated_at).toISOString()
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function enqueueConnectorLearningJob(input) {
|
|
31
|
+
const now = input.nowMs ?? Date.now();
|
|
32
|
+
runSqliteWriteTransaction((db) => {
|
|
33
|
+
db.prepare(`INSERT INTO connector_learning_jobs (
|
|
34
|
+
job_id, idempotency_key, connector_id, connection_id, source_instance_id,
|
|
35
|
+
agent_id, mode, status, phase, next_run_at, created_at, updated_at
|
|
36
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, 'queued', 'queued', ?, ?, ?)
|
|
37
|
+
ON CONFLICT(idempotency_key) DO NOTHING`).run(randomUUID(), input.idempotencyKey, input.connectorId, input.connectionId, input.sourceInstanceId, input.agentId, input.mode, input.nextRunAt ?? now, now, now);
|
|
38
|
+
});
|
|
39
|
+
return fromRow(getSqliteDatabase().prepare("SELECT * FROM connector_learning_jobs WHERE idempotency_key = ?").get(input.idempotencyKey));
|
|
40
|
+
}
|
|
41
|
+
function claimNextConnectorLearningJob(nowMs = Date.now()) {
|
|
42
|
+
return runSqliteWriteTransaction((db) => {
|
|
43
|
+
const row = db.prepare(`SELECT * FROM connector_learning_jobs
|
|
44
|
+
WHERE status IN ('queued', 'failed') AND attempt_count < 5 AND COALESCE(next_run_at, 0) <= ?
|
|
45
|
+
ORDER BY next_run_at ASC, created_at ASC LIMIT 1`).get(nowMs);
|
|
46
|
+
if (!row) return null;
|
|
47
|
+
if (db.prepare(`UPDATE connector_learning_jobs SET
|
|
48
|
+
status = 'running', phase = 'fetching', attempt_count = attempt_count + 1,
|
|
49
|
+
error = NULL, started_at = COALESCE(started_at, ?), updated_at = ?
|
|
50
|
+
WHERE job_id = ? AND status IN ('queued', 'failed')`).run(nowMs, nowMs, row.job_id).changes !== 1) return null;
|
|
51
|
+
return fromRow(db.prepare("SELECT * FROM connector_learning_jobs WHERE job_id = ?").get(row.job_id));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
function recoverStaleConnectorLearningJobs(staleBeforeMs, nowMs = Date.now()) {
|
|
55
|
+
return runSqliteWriteTransaction((db) => Number(db.prepare(`UPDATE connector_learning_jobs SET
|
|
56
|
+
status = CASE WHEN attempt_count >= 5 THEN 'paused' ELSE 'failed' END,
|
|
57
|
+
error = 'Interrupted while learning; queued for recovery.',
|
|
58
|
+
next_run_at = CASE WHEN attempt_count >= 5 THEN NULL ELSE ? END,
|
|
59
|
+
finished_at = ?, updated_at = ?
|
|
60
|
+
WHERE status = 'running' AND updated_at < ?`).run(nowMs, nowMs, nowMs, staleBeforeMs).changes));
|
|
61
|
+
}
|
|
62
|
+
function setConnectorLearningPaused(connectionId, paused, nowMs = Date.now()) {
|
|
63
|
+
return runSqliteWriteTransaction((db) => Number(db.prepare(paused ? `UPDATE connector_learning_jobs SET status = 'paused', next_run_at = NULL, updated_at = ?
|
|
64
|
+
WHERE connection_id = ? AND status IN ('queued', 'failed', 'running')` : `UPDATE connector_learning_jobs SET status = 'queued', next_run_at = ?, updated_at = ?
|
|
65
|
+
WHERE connection_id = ? AND status = 'paused'`).run(...paused ? [nowMs, connectionId] : [
|
|
66
|
+
nowMs,
|
|
67
|
+
nowMs,
|
|
68
|
+
connectionId
|
|
69
|
+
]).changes));
|
|
70
|
+
}
|
|
71
|
+
function updateConnectorLearningJob(id, patch) {
|
|
72
|
+
const now = patch.nowMs ?? Date.now();
|
|
73
|
+
const fields = ["updated_at = ?"];
|
|
74
|
+
const values = [now];
|
|
75
|
+
const add = (column, value) => {
|
|
76
|
+
if (value === void 0) return;
|
|
77
|
+
fields.push(`${column} = ?`);
|
|
78
|
+
values.push(value);
|
|
79
|
+
};
|
|
80
|
+
add("status", patch.status);
|
|
81
|
+
add("phase", patch.phase);
|
|
82
|
+
add("items_discovered", patch.itemsDiscovered);
|
|
83
|
+
add("items_indexed", patch.itemsIndexed);
|
|
84
|
+
add("candidates_created", patch.candidatesCreated);
|
|
85
|
+
add("error", patch.error);
|
|
86
|
+
add("next_run_at", patch.nextRunAt);
|
|
87
|
+
if (patch.finished) add("finished_at", now);
|
|
88
|
+
values.push(id);
|
|
89
|
+
getSqliteDatabase().prepare(`UPDATE connector_learning_jobs SET ${fields.join(", ")} WHERE job_id = ?`).run(...values);
|
|
90
|
+
const row = getSqliteDatabase().prepare("SELECT * FROM connector_learning_jobs WHERE job_id = ?").get(id);
|
|
91
|
+
if (!row) throw new Error(`Connector learning job not found: ${id}`);
|
|
92
|
+
return fromRow(row);
|
|
93
|
+
}
|
|
94
|
+
function listConnectorLearningJobs(options = {}) {
|
|
95
|
+
const clauses = [];
|
|
96
|
+
const values = [];
|
|
97
|
+
if (options.sourceInstanceId) {
|
|
98
|
+
clauses.push("source_instance_id = ?");
|
|
99
|
+
values.push(options.sourceInstanceId);
|
|
100
|
+
}
|
|
101
|
+
if (options.connectionId) {
|
|
102
|
+
clauses.push("connection_id = ?");
|
|
103
|
+
values.push(options.connectionId);
|
|
104
|
+
}
|
|
105
|
+
const limit = Math.max(1, Math.min(options.limit ?? 100, 500));
|
|
106
|
+
return getSqliteDatabase().prepare(`SELECT * FROM connector_learning_jobs ${clauses.length ? `WHERE ${clauses.join(" AND ")}` : ""}
|
|
107
|
+
ORDER BY created_at DESC LIMIT ?`).all(...values, limit).map(fromRow);
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
export { claimNextConnectorLearningJob, enqueueConnectorLearningJob, listConnectorLearningJobs, recoverStaleConnectorLearningJobs, setConnectorLearningPaused, updateConnectorLearningJob };
|