@superblocksteam/vite-plugin-file-sync 2.0.123 → 2.0.124-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-service/agent/prompts/build-base-system-prompt.d.ts +16 -1
- package/dist/ai-service/agent/prompts/build-base-system-prompt.d.ts.map +1 -1
- package/dist/ai-service/agent/prompts/build-base-system-prompt.js +27 -1
- package/dist/ai-service/agent/prompts/build-base-system-prompt.js.map +1 -1
- package/dist/ai-service/agent/prompts/build-security-scan-prompt.d.ts.map +1 -1
- package/dist/ai-service/agent/prompts/build-security-scan-prompt.js +3 -1
- package/dist/ai-service/agent/prompts/build-security-scan-prompt.js.map +1 -1
- package/dist/ai-service/agent/tools/apis/api-comparator.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/apis/api-comparator.js +1 -4
- package/dist/ai-service/agent/tools/apis/api-comparator.js.map +1 -1
- package/dist/ai-service/agent/tools/apis/api-testing-state.js +7 -0
- package/dist/ai-service/agent/tools/apis/api-testing-state.js.map +1 -1
- package/dist/ai-service/agent/tools/apis/get-api-docs.d.ts +1 -1
- package/dist/ai-service/agent/tools/apis/write-api.d.ts +2 -2
- package/dist/ai-service/agent/tools/build-capture-screenshot.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-capture-screenshot.js +11 -33
- package/dist/ai-service/agent/tools/build-capture-screenshot.js.map +1 -1
- package/dist/ai-service/agent/tools/build-copy-directory.d.ts +1 -1
- package/dist/ai-service/agent/tools/build-finalize.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-finalize.js +11 -2
- package/dist/ai-service/agent/tools/build-finalize.js.map +1 -1
- package/dist/ai-service/agent/tools/build-install-packages.d.ts +41 -1
- package/dist/ai-service/agent/tools/build-install-packages.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-install-packages.js +208 -0
- package/dist/ai-service/agent/tools/build-install-packages.js.map +1 -1
- package/dist/ai-service/agent/tools/build-lookup-npm-package.d.ts +28 -0
- package/dist/ai-service/agent/tools/build-lookup-npm-package.d.ts.map +1 -0
- package/dist/ai-service/agent/tools/build-lookup-npm-package.js +78 -0
- package/dist/ai-service/agent/tools/build-lookup-npm-package.js.map +1 -0
- package/dist/ai-service/agent/tools/build-manage-checklist.d.ts +4 -4
- package/dist/ai-service/agent/tools/build-navigate-preview.d.ts +16 -0
- package/dist/ai-service/agent/tools/build-navigate-preview.d.ts.map +1 -0
- package/dist/ai-service/agent/tools/build-navigate-preview.js +68 -0
- package/dist/ai-service/agent/tools/build-navigate-preview.js.map +1 -0
- package/dist/ai-service/agent/tools/build-write-file.d.ts +1 -1
- package/dist/ai-service/agent/tools/databases/dev-database.d.ts +9 -9
- package/dist/ai-service/agent/tools/index.d.ts +2 -0
- package/dist/ai-service/agent/tools/index.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/index.js +2 -0
- package/dist/ai-service/agent/tools/index.js.map +1 -1
- package/dist/ai-service/agent/tools/integrations/execute-request.d.ts +3 -3
- package/dist/ai-service/agent/tools/report-security-findings.d.ts +11 -5
- package/dist/ai-service/agent/tools/report-security-findings.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/report-security-findings.js +1 -0
- package/dist/ai-service/agent/tools/report-security-findings.js.map +1 -1
- package/dist/ai-service/agent/tools.d.ts.map +1 -1
- package/dist/ai-service/agent/tools.js +3 -1
- package/dist/ai-service/agent/tools.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/git.d.ts +2 -2
- package/dist/ai-service/agent/tools2/tools/grep.d.ts +2 -2
- package/dist/ai-service/agent/tools2/tools/update-test-case-status.d.ts +2 -2
- package/dist/ai-service/app-interface/npm-error-parser.d.ts +161 -0
- package/dist/ai-service/app-interface/npm-error-parser.d.ts.map +1 -0
- package/dist/ai-service/app-interface/npm-error-parser.js +510 -0
- package/dist/ai-service/app-interface/npm-error-parser.js.map +1 -0
- package/dist/ai-service/app-interface/npm-package-lookup.d.ts +286 -0
- package/dist/ai-service/app-interface/npm-package-lookup.d.ts.map +1 -0
- package/dist/ai-service/app-interface/npm-package-lookup.js +793 -0
- package/dist/ai-service/app-interface/npm-package-lookup.js.map +1 -0
- package/dist/ai-service/app-interface/npm-registry.d.ts +735 -47
- package/dist/ai-service/app-interface/npm-registry.d.ts.map +1 -1
- package/dist/ai-service/app-interface/npm-registry.js +1882 -153
- package/dist/ai-service/app-interface/npm-registry.js.map +1 -1
- package/dist/ai-service/app-interface/shell.d.ts +118 -1
- package/dist/ai-service/app-interface/shell.d.ts.map +1 -1
- package/dist/ai-service/app-interface/shell.js +579 -157
- package/dist/ai-service/app-interface/shell.js.map +1 -1
- package/dist/ai-service/app-skills/manager.d.ts +1 -1
- package/dist/ai-service/app-skills/manager.d.ts.map +1 -1
- package/dist/ai-service/app-skills/manager.js +39 -7
- package/dist/ai-service/app-skills/manager.js.map +1 -1
- package/dist/ai-service/checklist/api-migration-checklist-gate.d.ts +9 -0
- package/dist/ai-service/checklist/api-migration-checklist-gate.d.ts.map +1 -0
- package/dist/ai-service/checklist/api-migration-checklist-gate.js +30 -0
- package/dist/ai-service/checklist/api-migration-checklist-gate.js.map +1 -0
- package/dist/ai-service/checklist/api-migration-origins.d.ts +4 -0
- package/dist/ai-service/checklist/api-migration-origins.d.ts.map +1 -0
- package/dist/ai-service/checklist/api-migration-origins.js +8 -0
- package/dist/ai-service/checklist/api-migration-origins.js.map +1 -0
- package/dist/ai-service/checklist/persisted-checklist-store.d.ts +2 -3
- package/dist/ai-service/checklist/persisted-checklist-store.d.ts.map +1 -1
- package/dist/ai-service/checklist/persisted-checklist-store.js +6 -7
- package/dist/ai-service/checklist/persisted-checklist-store.js.map +1 -1
- package/dist/ai-service/context-archive-paths.d.ts +4 -0
- package/dist/ai-service/context-archive-paths.d.ts.map +1 -0
- package/dist/ai-service/context-archive-paths.js +28 -0
- package/dist/ai-service/context-archive-paths.js.map +1 -0
- package/dist/ai-service/context-download.d.ts +3 -1
- package/dist/ai-service/context-download.d.ts.map +1 -1
- package/dist/ai-service/context-download.js +48 -9
- package/dist/ai-service/context-download.js.map +1 -1
- package/dist/ai-service/context-upload.d.ts +3 -2
- package/dist/ai-service/context-upload.d.ts.map +1 -1
- package/dist/ai-service/context-upload.js +44 -26
- package/dist/ai-service/context-upload.js.map +1 -1
- package/dist/ai-service/dev-database-client.d.ts +3 -11
- package/dist/ai-service/dev-database-client.d.ts.map +1 -1
- package/dist/ai-service/dev-database-client.js.map +1 -1
- package/dist/ai-service/features.d.ts +4 -0
- package/dist/ai-service/features.d.ts.map +1 -1
- package/dist/ai-service/features.js +8 -0
- package/dist/ai-service/features.js.map +1 -1
- package/dist/ai-service/filter-disabled-tools-for-migration.d.ts.map +1 -1
- package/dist/ai-service/filter-disabled-tools-for-migration.js +4 -0
- package/dist/ai-service/filter-disabled-tools-for-migration.js.map +1 -1
- package/dist/ai-service/index.d.ts +94 -0
- package/dist/ai-service/index.d.ts.map +1 -1
- package/dist/ai-service/index.js +564 -17
- package/dist/ai-service/index.js.map +1 -1
- package/dist/ai-service/llm/client.d.ts +38 -3
- package/dist/ai-service/llm/client.d.ts.map +1 -1
- package/dist/ai-service/llm/client.js +73 -22
- package/dist/ai-service/llm/client.js.map +1 -1
- package/dist/ai-service/llm/context-v2/adapter.d.ts +3 -1
- package/dist/ai-service/llm/context-v2/adapter.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/adapter.js +11 -11
- package/dist/ai-service/llm/context-v2/adapter.js.map +1 -1
- package/dist/ai-service/llm/context-v2/compaction/client-side.d.ts +44 -0
- package/dist/ai-service/llm/context-v2/compaction/client-side.d.ts.map +1 -0
- package/dist/ai-service/llm/context-v2/compaction/client-side.js +170 -0
- package/dist/ai-service/llm/context-v2/compaction/client-side.js.map +1 -0
- package/dist/ai-service/llm/context-v2/compaction/compaction-strategy.d.ts +56 -0
- package/dist/ai-service/llm/context-v2/compaction/compaction-strategy.d.ts.map +1 -0
- package/dist/ai-service/llm/context-v2/compaction/compaction-strategy.js +9 -0
- package/dist/ai-service/llm/context-v2/compaction/compaction-strategy.js.map +1 -0
- package/dist/ai-service/llm/context-v2/compaction/index.d.ts +5 -0
- package/dist/ai-service/llm/context-v2/compaction/index.d.ts.map +1 -0
- package/dist/ai-service/llm/context-v2/compaction/index.js +3 -0
- package/dist/ai-service/llm/context-v2/compaction/index.js.map +1 -0
- package/dist/ai-service/llm/context-v2/compaction/server-side.d.ts +30 -0
- package/dist/ai-service/llm/context-v2/compaction/server-side.d.ts.map +1 -0
- package/dist/ai-service/llm/context-v2/compaction/server-side.js +130 -0
- package/dist/ai-service/llm/context-v2/compaction/server-side.js.map +1 -0
- package/dist/ai-service/llm/context-v2/context-management.d.ts +203 -0
- package/dist/ai-service/llm/context-v2/context-management.d.ts.map +1 -0
- package/dist/ai-service/llm/context-v2/context-management.js +183 -0
- package/dist/ai-service/llm/context-v2/context-management.js.map +1 -0
- package/dist/ai-service/llm/context-v2/context.d.ts +64 -22
- package/dist/ai-service/llm/context-v2/context.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/context.js +233 -157
- package/dist/ai-service/llm/context-v2/context.js.map +1 -1
- package/dist/ai-service/llm/context-v2/conversation-context.d.ts +24 -7
- package/dist/ai-service/llm/context-v2/conversation-context.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/conversation-context.js +1 -1
- package/dist/ai-service/llm/context-v2/index.d.ts +0 -4
- package/dist/ai-service/llm/context-v2/index.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/index.js +0 -4
- package/dist/ai-service/llm/context-v2/index.js.map +1 -1
- package/dist/ai-service/llm/context-v2/manager.d.ts +24 -3
- package/dist/ai-service/llm/context-v2/manager.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/manager.js +146 -4
- package/dist/ai-service/llm/context-v2/manager.js.map +1 -1
- package/dist/ai-service/llm/context-v2/migrations/v1-to-v2.d.ts +2 -7
- package/dist/ai-service/llm/context-v2/migrations/v1-to-v2.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/migrations/v1-to-v2.js +5 -73
- package/dist/ai-service/llm/context-v2/migrations/v1-to-v2.js.map +1 -1
- package/dist/ai-service/llm/context-v2/storage/event-store.d.ts +57 -0
- package/dist/ai-service/llm/context-v2/storage/event-store.d.ts.map +1 -0
- package/dist/ai-service/llm/context-v2/storage/event-store.js +10 -0
- package/dist/ai-service/llm/context-v2/storage/event-store.js.map +1 -0
- package/dist/ai-service/llm/context-v2/storage/event-types.d.ts +50 -0
- package/dist/ai-service/llm/context-v2/storage/event-types.d.ts.map +1 -0
- package/dist/ai-service/llm/context-v2/storage/event-types.js +10 -0
- package/dist/ai-service/llm/context-v2/storage/event-types.js.map +1 -0
- package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.d.ts +87 -0
- package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.d.ts.map +1 -0
- package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.js +184 -0
- package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.js.map +1 -0
- package/dist/ai-service/llm/context-v2/storage/migration.d.ts +49 -0
- package/dist/ai-service/llm/context-v2/storage/migration.d.ts.map +1 -0
- package/dist/ai-service/llm/context-v2/storage/migration.js +126 -0
- package/dist/ai-service/llm/context-v2/storage/migration.js.map +1 -0
- package/dist/ai-service/llm/context-v2/types.d.ts +16 -11
- package/dist/ai-service/llm/context-v2/types.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/types.js +2 -2
- package/dist/ai-service/llm/context-v2/types.js.map +1 -1
- package/dist/ai-service/llm/impl/clark.d.ts +8 -0
- package/dist/ai-service/llm/impl/clark.d.ts.map +1 -1
- package/dist/ai-service/llm/impl/clark.js +8 -0
- package/dist/ai-service/llm/impl/clark.js.map +1 -1
- package/dist/ai-service/llm/interaction/adapters/vercel.d.ts.map +1 -1
- package/dist/ai-service/llm/interaction/adapters/vercel.js +17 -1
- package/dist/ai-service/llm/interaction/adapters/vercel.js.map +1 -1
- package/dist/ai-service/llm/provider.d.ts.map +1 -1
- package/dist/ai-service/llm/provider.js +1 -3
- package/dist/ai-service/llm/provider.js.map +1 -1
- package/dist/ai-service/llm/stream/observers/context.d.ts +23 -0
- package/dist/ai-service/llm/stream/observers/context.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/observers/context.js +62 -0
- package/dist/ai-service/llm/stream/observers/context.js.map +1 -1
- package/dist/ai-service/llm/tool-context-integrity.d.ts +25 -0
- package/dist/ai-service/llm/tool-context-integrity.d.ts.map +1 -0
- package/dist/ai-service/llm/tool-context-integrity.js +141 -0
- package/dist/ai-service/llm/tool-context-integrity.js.map +1 -0
- package/dist/ai-service/skills/system/superblocks-migration/skill.generated.d.ts +1 -1
- package/dist/ai-service/skills/system/superblocks-migration/skill.generated.d.ts.map +1 -1
- package/dist/ai-service/skills/system/superblocks-migration/skill.generated.js +6 -1
- package/dist/ai-service/skills/system/superblocks-migration/skill.generated.js.map +1 -1
- package/dist/ai-service/skills/system/third-party-migration/skill.generated.d.ts +1 -1
- package/dist/ai-service/skills/system/third-party-migration/skill.generated.d.ts.map +1 -1
- package/dist/ai-service/skills/system/third-party-migration/skill.generated.js +3 -2
- package/dist/ai-service/skills/system/third-party-migration/skill.generated.js.map +1 -1
- package/dist/ai-service/state-machine/clark-fsm.d.ts +23 -2
- package/dist/ai-service/state-machine/clark-fsm.d.ts.map +1 -1
- package/dist/ai-service/state-machine/clark-fsm.js +37 -2
- package/dist/ai-service/state-machine/clark-fsm.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/agent-planning.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/agent-planning.js +29 -2
- package/dist/ai-service/state-machine/handlers/agent-planning.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/awaiting-user.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/awaiting-user.js +9 -0
- package/dist/ai-service/state-machine/handlers/awaiting-user.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/llm-generating.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/llm-generating.js +25 -2
- package/dist/ai-service/state-machine/handlers/llm-generating.js.map +1 -1
- package/dist/ai-service/state-machine/helpers/fetch-with-reconnect-retry.d.ts +6 -0
- package/dist/ai-service/state-machine/helpers/fetch-with-reconnect-retry.d.ts.map +1 -0
- package/dist/ai-service/state-machine/helpers/fetch-with-reconnect-retry.js +36 -0
- package/dist/ai-service/state-machine/helpers/fetch-with-reconnect-retry.js.map +1 -0
- package/dist/ai-service/state-machine/helpers/stable-peer.d.ts +30 -1
- package/dist/ai-service/state-machine/helpers/stable-peer.d.ts.map +1 -1
- package/dist/ai-service/state-machine/helpers/stable-peer.js +85 -2
- package/dist/ai-service/state-machine/helpers/stable-peer.js.map +1 -1
- package/dist/ai-service/state-machine/helpers/user-preferences.d.ts +8 -0
- package/dist/ai-service/state-machine/helpers/user-preferences.d.ts.map +1 -0
- package/dist/ai-service/state-machine/helpers/user-preferences.js +11 -0
- package/dist/ai-service/state-machine/helpers/user-preferences.js.map +1 -0
- package/dist/ai-service/template-renderer.d.ts +18 -1
- package/dist/ai-service/template-renderer.d.ts.map +1 -1
- package/dist/ai-service/template-renderer.js +73 -12
- package/dist/ai-service/template-renderer.js.map +1 -1
- package/dist/ai-service/types.d.ts +157 -0
- package/dist/ai-service/types.d.ts.map +1 -1
- package/dist/ai-service/types.js +137 -0
- package/dist/ai-service/types.js.map +1 -1
- package/dist/ai-service/util/llm-config-utils.d.ts +21 -22
- package/dist/ai-service/util/llm-config-utils.d.ts.map +1 -1
- package/dist/ai-service/util/llm-config-utils.js +40 -67
- package/dist/ai-service/util/llm-config-utils.js.map +1 -1
- package/dist/file-sync-vite-plugin.d.ts.map +1 -1
- package/dist/file-sync-vite-plugin.js +5 -0
- package/dist/file-sync-vite-plugin.js.map +1 -1
- package/dist/file-system-helpers.d.ts +17 -0
- package/dist/file-system-helpers.d.ts.map +1 -1
- package/dist/file-system-helpers.js +22 -0
- package/dist/file-system-helpers.js.map +1 -1
- package/dist/git-service/index.d.ts.map +1 -1
- package/dist/git-service/index.js +15 -1
- package/dist/git-service/index.js.map +1 -1
- package/dist/migration/migration-routes.d.ts.map +1 -1
- package/dist/migration/migration-routes.js +26 -3
- package/dist/migration/migration-routes.js.map +1 -1
- package/dist/migration/translation-prompt.d.ts.map +1 -1
- package/dist/migration/translation-prompt.js +5 -0
- package/dist/migration/translation-prompt.js.map +1 -1
- package/dist/migration-templates/app-fullstack/package.json +2 -2
- package/dist/policy-gate-callback-mapper.d.ts +24 -0
- package/dist/policy-gate-callback-mapper.d.ts.map +1 -0
- package/dist/policy-gate-callback-mapper.js +61 -0
- package/dist/policy-gate-callback-mapper.js.map +1 -0
- package/dist/policy-gate-runner.d.ts +32 -0
- package/dist/policy-gate-runner.d.ts.map +1 -0
- package/dist/policy-gate-runner.js +191 -0
- package/dist/policy-gate-runner.js.map +1 -0
- package/dist/router-parser.d.ts.map +1 -1
- package/dist/router-parser.js +107 -11
- package/dist/router-parser.js.map +1 -1
- package/dist/sync-service/list-dir.d.ts.map +1 -1
- package/dist/sync-service/list-dir.js +13 -3
- package/dist/sync-service/list-dir.js.map +1 -1
- package/package.json +28 -10
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ModelMessage, UserModelMessage, SystemModelMessage, LanguageModelUsage } from "ai";
|
|
2
2
|
import type { LLMObsTracer } from "../../llmobs/tracer.js";
|
|
3
|
+
import type { CompactionStrategy } from "./compaction/compaction-strategy.js";
|
|
3
4
|
import type { ContextOptionsV2, CachingConfig } from "./config.js";
|
|
4
|
-
import type {
|
|
5
|
+
import type { EventStore } from "./storage/event-store.js";
|
|
6
|
+
import type { ContextRecordV2, ContextId, ModeState, AttachmentsRecord, CompactionSummary, CompactionCallbacks } from "./types.js";
|
|
5
7
|
/** Strip base64 media from screenshot tool results, replacing with a text placeholder. */
|
|
6
8
|
export declare function stripScreenshotMediaFromToolMessage(msg: ModelMessage): ModelMessage;
|
|
7
9
|
export interface Context {
|
|
@@ -10,16 +12,29 @@ export interface Context {
|
|
|
10
12
|
addResponse(response: ModelMessage, usage: LanguageModelUsage): Promise<void>;
|
|
11
13
|
getMessages(): Promise<ModelMessage[]>;
|
|
12
14
|
}
|
|
13
|
-
export type {
|
|
15
|
+
export type { ModeState };
|
|
14
16
|
export interface ContextV2Options {
|
|
15
17
|
rootDir: string;
|
|
16
|
-
summarizationModel: LanguageModel;
|
|
17
18
|
config?: Partial<ContextOptionsV2>;
|
|
18
19
|
caching?: Partial<CachingConfig>;
|
|
19
20
|
onPersist?: (record: ContextRecordV2) => Promise<void>;
|
|
20
|
-
compactionCallbacks?: CompactionCallbacks;
|
|
21
21
|
tracer?: LLMObsTracer;
|
|
22
22
|
getModeState?: () => ModeState | undefined;
|
|
23
|
+
/** Event store for appending live conversation events (prompt_sent, response_received). */
|
|
24
|
+
eventStore?: EventStore;
|
|
25
|
+
/**
|
|
26
|
+
* Full context identifier (appId + userId + name) used to partition event
|
|
27
|
+
* log writes. Keying on `appId` alone would let two users sharing the same
|
|
28
|
+
* application surface each other's conversation history.
|
|
29
|
+
*/
|
|
30
|
+
contextId?: ContextId;
|
|
31
|
+
/**
|
|
32
|
+
* Compaction strategy. Defaults to {@link ServerSideCompactionStrategy} when
|
|
33
|
+
* not provided so tests and ad-hoc callers can construct a ContextV2 without
|
|
34
|
+
* picking one. Production code paths (via ContextManagerV2) always supply a
|
|
35
|
+
* strategy derived from runtime config.
|
|
36
|
+
*/
|
|
37
|
+
compaction?: CompactionStrategy;
|
|
23
38
|
}
|
|
24
39
|
export declare class ContextV2 implements Context {
|
|
25
40
|
private systemPrompt?;
|
|
@@ -27,23 +42,32 @@ export declare class ContextV2 implements Context {
|
|
|
27
42
|
private attachments?;
|
|
28
43
|
private config;
|
|
29
44
|
private caching;
|
|
30
|
-
private summarizationModel;
|
|
31
45
|
private queue;
|
|
32
46
|
private onPersist?;
|
|
33
|
-
private compactionCallbacks?;
|
|
34
47
|
private tracer?;
|
|
35
48
|
private rootDir;
|
|
36
|
-
private pendingInputSummaries;
|
|
37
|
-
private pendingOutputSummaries;
|
|
38
|
-
private pendingProtection;
|
|
39
49
|
private skillsNeedReload;
|
|
40
50
|
private getModeState?;
|
|
51
|
+
private readonly eventStore?;
|
|
52
|
+
private readonly contextId?;
|
|
53
|
+
private compaction;
|
|
54
|
+
private compactionCallbacks?;
|
|
41
55
|
private isDisposed;
|
|
42
56
|
constructor(options: ContextV2Options);
|
|
43
|
-
setCompactionCallbacks(callbacks: CompactionCallbacks | undefined): void;
|
|
44
57
|
updateConfig(config: Partial<ContextOptionsV2>): void;
|
|
58
|
+
/**
|
|
59
|
+
* Swap the active compaction strategy on a live context. Called from
|
|
60
|
+
* `ContextManagerV2.getOrCreateContext` on a cache hit when the
|
|
61
|
+
* incoming `contextManagement` selection (derived from the per-request
|
|
62
|
+
* LD flag) differs from whatever the cached context was first
|
|
63
|
+
* constructed with. Without this, the first caller's strategy locks
|
|
64
|
+
* in for the lifetime of the cache entry and the kill-switch flag
|
|
65
|
+
* silently no-ops.
|
|
66
|
+
*/
|
|
67
|
+
setCompactionStrategy(strategy: CompactionStrategy): void;
|
|
45
68
|
dispose(): void;
|
|
46
69
|
storeSummary(toolCallId: string, summary: CompactionSummary): void;
|
|
70
|
+
setCompactionCallbacks(callbacks: CompactionCallbacks | undefined): void;
|
|
47
71
|
markSkillsNeedReload(): void;
|
|
48
72
|
checkAndClearSkillsNeedReload(): boolean;
|
|
49
73
|
setAttachments(attachments: AttachmentsRecord): void;
|
|
@@ -52,25 +76,43 @@ export declare class ContextV2 implements Context {
|
|
|
52
76
|
static fromRecord(record: ContextRecordV2, options: ContextV2Options): ContextV2;
|
|
53
77
|
toRecord(): ContextRecordV2;
|
|
54
78
|
setSystemPrompt(prompt: SystemModelMessage): void;
|
|
55
|
-
|
|
56
|
-
|
|
79
|
+
addUserMessage(message: UserModelMessage): Promise<void>;
|
|
80
|
+
addResponse(response: ModelMessage, usage: LanguageModelUsage): Promise<void>;
|
|
57
81
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
82
|
+
* Runs the configured compaction strategy after the most recent response
|
|
83
|
+
* has been stored. For the server-side strategy this is a no-op; for the
|
|
84
|
+
* client-side strategy it may replace `this.messages` with a compacted set
|
|
85
|
+
* and flip `skillsNeedReload`.
|
|
86
|
+
*
|
|
87
|
+
* Defers when `this.messages` ends in an assistant turn whose `tool_use`
|
|
88
|
+
* blocks haven't been matched by a `tool_result` message yet. Running
|
|
89
|
+
* compaction at that point would summarize the assistant message away;
|
|
90
|
+
* when the matching tool result arrives in the next step it would
|
|
91
|
+
* reference a `toolCallId` that no longer exists, and
|
|
92
|
+
* `repairOrphanedToolResults` would strip it on the next `getMessages`.
|
|
93
|
+
* Waiting for the tool result to arrive first means both halves of the
|
|
94
|
+
* pair are summarized together — no orphan.
|
|
95
|
+
*
|
|
96
|
+
* Triggered from both assistant and tool responses (drop the original
|
|
97
|
+
* assistant-only gate) so the deferred run can fire on the tool_result
|
|
98
|
+
* that closes out a step's pending tool calls.
|
|
61
99
|
*/
|
|
62
|
-
private
|
|
63
|
-
addUserMessage(message: UserModelMessage): Promise<void>;
|
|
64
|
-
addResponse(response: ModelMessage, usage: LanguageModelUsage, options?: {
|
|
65
|
-
skipCompaction?: boolean;
|
|
66
|
-
}): Promise<void>;
|
|
100
|
+
private runCompactionIfNeeded;
|
|
67
101
|
getMessages(): Promise<ModelMessage[]>;
|
|
102
|
+
onCompactionDetected(): Promise<void>;
|
|
103
|
+
/**
|
|
104
|
+
* Returns deduplicated tool names from messages marked as protected.
|
|
105
|
+
* Delegates to the active compaction strategy.
|
|
106
|
+
*/
|
|
107
|
+
getProtectedToolNames(): string[];
|
|
108
|
+
private appendEvent;
|
|
109
|
+
private appendCompactionWindow;
|
|
110
|
+
private toEventLogEntry;
|
|
68
111
|
/**
|
|
69
112
|
* Returns the last known input token count from the most recent assistant message.
|
|
70
113
|
* This represents the cumulative context size at the time of that turn.
|
|
71
114
|
*/
|
|
72
115
|
private getLastKnownInputTokens;
|
|
73
116
|
private persist;
|
|
74
|
-
private compactIfNeeded;
|
|
75
117
|
}
|
|
76
118
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../src/ai-service/llm/context-v2/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../src/ai-service/llm/context-v2/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import { getPrefixedLogger } from "../../../util/logger.js";
|
|
2
|
-
import { buildModeMessage } from "../../util/mode-message.js";
|
|
3
2
|
import { findBreakpoints } from "./caching.js";
|
|
4
|
-
import {
|
|
3
|
+
import { ServerSideCompactionStrategy } from "./compaction/server-side.js";
|
|
5
4
|
import { DEFAULT_OPTIONS, DEFAULT_CACHING } from "./config.js";
|
|
6
5
|
import { OperationQueue } from "./operation-queue.js";
|
|
7
|
-
import { getTotalInputTokens
|
|
8
|
-
import { toStoredMessage, toSdkMessages, CACHE_BREAKPOINT_PROVIDER_OPTIONS, normalizeToolMessage, stripUndefinedFromToolOutputs, repairBrokenToolCalls, repairOrphanedToolResults, normalizeReasoningProviderOptions, stripUnsignedReasoning, stripTrailingAssistantPrefill, } from "./types.js";
|
|
6
|
+
import { getTotalInputTokens } from "./token-tracker.js";
|
|
7
|
+
import { toStoredMessage, toSdkMessages, CACHE_BREAKPOINT_PROVIDER_OPTIONS, normalizeToolMessage, stripUndefinedFromToolOutputs, repairBrokenToolCalls, repairOrphanedToolResults, normalizeReasoningProviderOptions, stripUnsignedReasoning, stripTrailingAssistantPrefill, extractTokenUsage, } from "./types.js";
|
|
9
8
|
import { uniquifyFilePartFilenames } from "./uniquify-filenames.js";
|
|
10
9
|
const logger = getPrefixedLogger("[context-v2]");
|
|
10
|
+
/**
|
|
11
|
+
* Whether an assistant message contains `tool-call` content parts whose
|
|
12
|
+
* matching `tool-result` messages have not been stored yet. Used by
|
|
13
|
+
* `runCompactionIfNeeded` to defer compaction past the assistant turn that
|
|
14
|
+
* produced the call until the tool result arrives (otherwise the assistant
|
|
15
|
+
* tool_use gets summarized away and the upcoming tool_result is orphaned).
|
|
16
|
+
*/
|
|
17
|
+
function hasPendingToolCalls(msg) {
|
|
18
|
+
if (msg.role !== "assistant" || !Array.isArray(msg.content)) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return msg.content.some((part) => typeof part === "object" &&
|
|
22
|
+
part !== null &&
|
|
23
|
+
"type" in part &&
|
|
24
|
+
part.type === "tool-call");
|
|
25
|
+
}
|
|
11
26
|
/** Check if a tool message contains an unstripped screenshot media result. */
|
|
12
27
|
function hasScreenshotMedia(msg) {
|
|
13
28
|
if (msg.role !== "tool" || !Array.isArray(msg.content)) {
|
|
@@ -65,51 +80,60 @@ export class ContextV2 {
|
|
|
65
80
|
attachments;
|
|
66
81
|
config;
|
|
67
82
|
caching;
|
|
68
|
-
summarizationModel;
|
|
69
83
|
queue = new OperationQueue();
|
|
70
84
|
onPersist;
|
|
71
|
-
compactionCallbacks;
|
|
72
85
|
tracer;
|
|
73
86
|
rootDir;
|
|
74
|
-
// Pending summaries waiting to be attached to messages
|
|
75
|
-
pendingInputSummaries = new Map();
|
|
76
|
-
pendingOutputSummaries = new Map();
|
|
77
|
-
// Pending protection flags for tool calls (e.g., system skill reads)
|
|
78
|
-
pendingProtection = new Set();
|
|
79
87
|
skillsNeedReload = false;
|
|
80
88
|
getModeState;
|
|
89
|
+
eventStore;
|
|
90
|
+
contextId;
|
|
91
|
+
compaction;
|
|
92
|
+
compactionCallbacks;
|
|
81
93
|
// When disposed, this context may still be referenced by in-flight streams.
|
|
82
94
|
// Keep it inert so stale generations cannot persist cleared history.
|
|
83
95
|
isDisposed = false;
|
|
84
96
|
constructor(options) {
|
|
85
97
|
this.rootDir = options.rootDir;
|
|
86
|
-
this.summarizationModel = options.summarizationModel;
|
|
87
98
|
this.config = { ...DEFAULT_OPTIONS, ...options.config };
|
|
88
99
|
this.caching = { ...DEFAULT_CACHING, ...options.caching };
|
|
89
100
|
this.onPersist = options.onPersist;
|
|
90
|
-
this.compactionCallbacks = options.compactionCallbacks;
|
|
91
101
|
this.tracer = options.tracer;
|
|
92
102
|
this.getModeState = options.getModeState;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
this.
|
|
103
|
+
this.eventStore = options.eventStore;
|
|
104
|
+
this.contextId = options.contextId;
|
|
105
|
+
this.compaction = options.compaction ?? new ServerSideCompactionStrategy();
|
|
96
106
|
}
|
|
97
107
|
updateConfig(config) {
|
|
98
108
|
this.config = { ...this.config, ...config };
|
|
109
|
+
this.compaction.updateConfig(config);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Swap the active compaction strategy on a live context. Called from
|
|
113
|
+
* `ContextManagerV2.getOrCreateContext` on a cache hit when the
|
|
114
|
+
* incoming `contextManagement` selection (derived from the per-request
|
|
115
|
+
* LD flag) differs from whatever the cached context was first
|
|
116
|
+
* constructed with. Without this, the first caller's strategy locks
|
|
117
|
+
* in for the lifetime of the cache entry and the kill-switch flag
|
|
118
|
+
* silently no-ops.
|
|
119
|
+
*/
|
|
120
|
+
setCompactionStrategy(strategy) {
|
|
121
|
+
if (this.compaction === strategy)
|
|
122
|
+
return;
|
|
123
|
+
this.compaction = strategy;
|
|
124
|
+
this.compaction.updateConfig(this.config);
|
|
125
|
+
this.compaction.setCallbacks(this.compactionCallbacks);
|
|
99
126
|
}
|
|
100
127
|
dispose() {
|
|
101
128
|
this.isDisposed = true;
|
|
102
129
|
this.onPersist = undefined;
|
|
103
130
|
}
|
|
104
131
|
storeSummary(toolCallId, summary) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
this.
|
|
109
|
-
|
|
110
|
-
if (summary.protected) {
|
|
111
|
-
this.pendingProtection.add(toolCallId);
|
|
112
|
-
}
|
|
132
|
+
this.compaction.storeSummary(toolCallId, summary);
|
|
133
|
+
}
|
|
134
|
+
setCompactionCallbacks(callbacks) {
|
|
135
|
+
this.compactionCallbacks = callbacks;
|
|
136
|
+
this.compaction.setCallbacks(callbacks);
|
|
113
137
|
}
|
|
114
138
|
markSkillsNeedReload() {
|
|
115
139
|
this.skillsNeedReload = true;
|
|
@@ -154,70 +178,16 @@ export class ContextV2 {
|
|
|
154
178
|
setSystemPrompt(prompt) {
|
|
155
179
|
this.systemPrompt = toStoredMessage(prompt);
|
|
156
180
|
}
|
|
157
|
-
collectPendingInputSummaries(message) {
|
|
158
|
-
if (message.role !== "assistant" || typeof message.content === "string") {
|
|
159
|
-
return undefined;
|
|
160
|
-
}
|
|
161
|
-
const toolCallIds = message.content
|
|
162
|
-
.filter((p) => p.type === "tool-call" && p.toolCallId)
|
|
163
|
-
.map((p) => p.toolCallId);
|
|
164
|
-
const summaries = {};
|
|
165
|
-
for (const id of toolCallIds) {
|
|
166
|
-
const summary = this.pendingInputSummaries.get(id);
|
|
167
|
-
if (summary) {
|
|
168
|
-
summaries[id] = summary;
|
|
169
|
-
this.pendingInputSummaries.delete(id);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
return Object.keys(summaries).length > 0 ? summaries : undefined;
|
|
173
|
-
}
|
|
174
|
-
collectPendingOutputSummaries(message) {
|
|
175
|
-
if (message.role !== "tool" || !Array.isArray(message.content)) {
|
|
176
|
-
return undefined;
|
|
177
|
-
}
|
|
178
|
-
const toolCallIds = message.content
|
|
179
|
-
.filter((p) => p.type === "tool-result" && p.toolCallId)
|
|
180
|
-
.map((p) => p.toolCallId);
|
|
181
|
-
const summaries = {};
|
|
182
|
-
for (const id of toolCallIds) {
|
|
183
|
-
const summary = this.pendingOutputSummaries.get(id);
|
|
184
|
-
if (summary) {
|
|
185
|
-
summaries[id] = summary;
|
|
186
|
-
this.pendingOutputSummaries.delete(id);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
return Object.keys(summaries).length > 0 ? summaries : undefined;
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Collect protection flags for tool results in this message.
|
|
193
|
-
* Returns a record mapping toolCallId to protection status, or undefined if none are protected.
|
|
194
|
-
* Clears the pending protection flags as they are consumed.
|
|
195
|
-
*/
|
|
196
|
-
collectPendingProtection(message) {
|
|
197
|
-
if (message.role !== "tool" || !Array.isArray(message.content)) {
|
|
198
|
-
return undefined;
|
|
199
|
-
}
|
|
200
|
-
const toolCallIds = message.content
|
|
201
|
-
.filter((p) => p.type === "tool-result" && p.toolCallId)
|
|
202
|
-
.map((p) => p.toolCallId);
|
|
203
|
-
const protectedResults = {};
|
|
204
|
-
for (const id of toolCallIds) {
|
|
205
|
-
if (this.pendingProtection.has(id)) {
|
|
206
|
-
protectedResults[id] = true;
|
|
207
|
-
this.pendingProtection.delete(id);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return Object.keys(protectedResults).length > 0
|
|
211
|
-
? protectedResults
|
|
212
|
-
: undefined;
|
|
213
|
-
}
|
|
214
181
|
async addUserMessage(message) {
|
|
215
182
|
return this.queue.enqueue(async () => {
|
|
216
|
-
|
|
183
|
+
const storedMessage = toStoredMessage(message);
|
|
184
|
+
this.messages.push(storedMessage);
|
|
185
|
+
await this.appendEvent("prompt_sent", storedMessage);
|
|
217
186
|
});
|
|
218
187
|
}
|
|
219
|
-
async addResponse(response, usage
|
|
220
|
-
|
|
188
|
+
async addResponse(response, usage) {
|
|
189
|
+
await this.queue.enqueue(async () => {
|
|
190
|
+
let storedResponse;
|
|
221
191
|
switch (response.role) {
|
|
222
192
|
case "assistant": {
|
|
223
193
|
// Total input tokens = non-cached + cached (prompt caching splits these)
|
|
@@ -227,14 +197,14 @@ export class ContextV2 {
|
|
|
227
197
|
// Use the higher of reported tokens or last known to maintain monotonicity.
|
|
228
198
|
const lastKnownTokens = this.getLastKnownInputTokens();
|
|
229
199
|
const cumulativeInputTokens = Math.max(reportedInputTokens, lastKnownTokens);
|
|
230
|
-
// Collect pending input summaries for tool-calls in this message
|
|
231
|
-
const toolSummaries = this.collectPendingInputSummaries(response);
|
|
232
200
|
normalizeReasoningProviderOptions(response);
|
|
233
|
-
this.
|
|
201
|
+
const extraMeta = this.compaction.collectAssistantMetadata(response) ?? {};
|
|
202
|
+
storedResponse = toStoredMessage(response, {
|
|
234
203
|
cumulativeInputTokens,
|
|
235
204
|
tokenCount: usage.outputTokens,
|
|
236
|
-
...
|
|
237
|
-
})
|
|
205
|
+
...extraMeta,
|
|
206
|
+
});
|
|
207
|
+
this.messages.push(storedResponse);
|
|
238
208
|
break;
|
|
239
209
|
}
|
|
240
210
|
case "tool": {
|
|
@@ -253,31 +223,97 @@ export class ContextV2 {
|
|
|
253
223
|
logger.info(`Stripped media from ${strippedCount} older screenshot(s)`);
|
|
254
224
|
}
|
|
255
225
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
const protectedResults = this.collectPendingProtection(normalized);
|
|
260
|
-
this.messages.push(toStoredMessage(normalized, {
|
|
261
|
-
...(toolSummaries && { toolSummaries }),
|
|
262
|
-
...(protectedResults && { protected: protectedResults }),
|
|
263
|
-
}));
|
|
226
|
+
const extraMeta = this.compaction.collectToolMetadata(normalized) ?? {};
|
|
227
|
+
storedResponse = toStoredMessage(normalized, extraMeta);
|
|
228
|
+
this.messages.push(storedResponse);
|
|
264
229
|
break;
|
|
265
230
|
}
|
|
266
231
|
default:
|
|
267
|
-
|
|
232
|
+
storedResponse = toStoredMessage(response);
|
|
233
|
+
this.messages.push(storedResponse);
|
|
268
234
|
break;
|
|
269
235
|
}
|
|
270
|
-
if (
|
|
271
|
-
|
|
236
|
+
if (response.role === "assistant" || response.role === "tool") {
|
|
237
|
+
const eventUsage = response.role === "assistant" ? extractTokenUsage(usage) : undefined;
|
|
238
|
+
await this.appendEvent("response_received", storedResponse, eventUsage);
|
|
272
239
|
}
|
|
273
240
|
await this.persist();
|
|
274
241
|
});
|
|
242
|
+
// After the queued write completes, give the compaction strategy a chance
|
|
243
|
+
// to react. Server-side is a no-op; client-side may compact this.messages
|
|
244
|
+
// and flip skillsNeedReload. Must be `await` (not `return`) because the
|
|
245
|
+
// earlier `await ... .enqueue(...)` already settles before we reach here
|
|
246
|
+
// — a `return` over the previous line would have made this unreachable.
|
|
247
|
+
await this.runCompactionIfNeeded(response, usage);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Runs the configured compaction strategy after the most recent response
|
|
251
|
+
* has been stored. For the server-side strategy this is a no-op; for the
|
|
252
|
+
* client-side strategy it may replace `this.messages` with a compacted set
|
|
253
|
+
* and flip `skillsNeedReload`.
|
|
254
|
+
*
|
|
255
|
+
* Defers when `this.messages` ends in an assistant turn whose `tool_use`
|
|
256
|
+
* blocks haven't been matched by a `tool_result` message yet. Running
|
|
257
|
+
* compaction at that point would summarize the assistant message away;
|
|
258
|
+
* when the matching tool result arrives in the next step it would
|
|
259
|
+
* reference a `toolCallId` that no longer exists, and
|
|
260
|
+
* `repairOrphanedToolResults` would strip it on the next `getMessages`.
|
|
261
|
+
* Waiting for the tool result to arrive first means both halves of the
|
|
262
|
+
* pair are summarized together — no orphan.
|
|
263
|
+
*
|
|
264
|
+
* Triggered from both assistant and tool responses (drop the original
|
|
265
|
+
* assistant-only gate) so the deferred run can fire on the tool_result
|
|
266
|
+
* that closes out a step's pending tool calls.
|
|
267
|
+
*/
|
|
268
|
+
async runCompactionIfNeeded(response, usage) {
|
|
269
|
+
if (this.isDisposed)
|
|
270
|
+
return;
|
|
271
|
+
if (response.role !== "assistant" && response.role !== "tool")
|
|
272
|
+
return;
|
|
273
|
+
return this.queue.enqueue(async () => {
|
|
274
|
+
const last = this.messages[this.messages.length - 1];
|
|
275
|
+
if (!last)
|
|
276
|
+
return;
|
|
277
|
+
if (last.role === "assistant" && hasPendingToolCalls(last)) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
const result = await this.compaction.afterResponse({
|
|
281
|
+
messages: this.messages,
|
|
282
|
+
usage,
|
|
283
|
+
});
|
|
284
|
+
if (result.messages) {
|
|
285
|
+
this.messages = result.messages;
|
|
286
|
+
}
|
|
287
|
+
if (result.skillsNeedReload) {
|
|
288
|
+
this.skillsNeedReload = true;
|
|
289
|
+
}
|
|
290
|
+
if (result.eventLogAnchor && result.messages) {
|
|
291
|
+
await this.appendCompactionWindow(result.messages);
|
|
292
|
+
}
|
|
293
|
+
if (result.messages) {
|
|
294
|
+
await this.persist();
|
|
295
|
+
}
|
|
296
|
+
});
|
|
275
297
|
}
|
|
276
298
|
async getMessages() {
|
|
277
299
|
return this.queue.enqueue(async () => {
|
|
300
|
+
// Strip system-role messages from the conversation array before
|
|
301
|
+
// building the wire payload. The `compaction_received` marker
|
|
302
|
+
// (written by `onCompactionDetected`, surfaced by
|
|
303
|
+
// `JsonlEventStore.loadMessages` as the anchor StoredMessage, and
|
|
304
|
+
// inserted in memory by `ServerSideCompactionStrategy`) carries
|
|
305
|
+
// `role: "system"` and is useful as an in-memory / on-disk
|
|
306
|
+
// breadcrumb but is not a valid conversation turn — Anthropic
|
|
307
|
+
// (and most other providers) only accept system messages at the
|
|
308
|
+
// start of the request, routed through the dedicated `system`
|
|
309
|
+
// parameter we set from `this.systemPrompt` below. Letting the
|
|
310
|
+
// marker through would put a second system-role message in the
|
|
311
|
+
// middle of the `messages` array and 400 the request on the
|
|
312
|
+
// first post-compaction turn.
|
|
313
|
+
const conversationMessages = this.messages.filter((msg) => msg.role !== "system");
|
|
278
314
|
const allMessages = this.systemPrompt
|
|
279
|
-
? [this.systemPrompt, ...
|
|
280
|
-
: [...
|
|
315
|
+
? [this.systemPrompt, ...conversationMessages]
|
|
316
|
+
: [...conversationMessages];
|
|
281
317
|
// Convert to SDK format (removes _superblocks metadata)
|
|
282
318
|
const sanitized = toSdkMessages(allMessages);
|
|
283
319
|
// Normalize malformed tool outputs and repair broken tool calls.
|
|
@@ -332,6 +368,101 @@ export class ContextV2 {
|
|
|
332
368
|
return deduped;
|
|
333
369
|
});
|
|
334
370
|
}
|
|
371
|
+
async onCompactionDetected() {
|
|
372
|
+
// Serialize with `addUserMessage` / `addResponse` / `getMessages`: this
|
|
373
|
+
// method is driven by the stream observer and can otherwise interleave
|
|
374
|
+
// with a queued write, leading to lost mutations or torn state.
|
|
375
|
+
await this.queue.enqueue(async () => {
|
|
376
|
+
const result = this.compaction.onCompactionDetected(this.messages);
|
|
377
|
+
if (result.messages) {
|
|
378
|
+
this.messages = result.messages;
|
|
379
|
+
}
|
|
380
|
+
if (result.skillsNeedReload) {
|
|
381
|
+
this.skillsNeedReload = true;
|
|
382
|
+
}
|
|
383
|
+
if (!this.eventStore || !this.contextId) {
|
|
384
|
+
logger.info("Server-side compaction detected (no event store configured)");
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
const marker = result.messages?.[0];
|
|
388
|
+
const entry = {
|
|
389
|
+
type: "compaction_received",
|
|
390
|
+
timestamp: marker?._superblocks?.timestamp ?? Date.now(),
|
|
391
|
+
role: "system",
|
|
392
|
+
content: marker?.content ?? "Server-side compaction applied",
|
|
393
|
+
};
|
|
394
|
+
const retainedMessages = result.messages?.slice(1) ?? [];
|
|
395
|
+
try {
|
|
396
|
+
await this.eventStore.appendEvent(this.contextId, entry);
|
|
397
|
+
for (const message of retainedMessages) {
|
|
398
|
+
await this.eventStore.appendEvent(this.contextId, this.toEventLogEntry(message));
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
catch (err) {
|
|
402
|
+
logger.error(`Failed to append compaction_received event: ${err}`);
|
|
403
|
+
}
|
|
404
|
+
logger.info(`Server-side compaction detected, wrote compaction_received event and replayed ${retainedMessages.length} retained message(s)`);
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Returns deduplicated tool names from messages marked as protected.
|
|
409
|
+
* Delegates to the active compaction strategy.
|
|
410
|
+
*/
|
|
411
|
+
getProtectedToolNames() {
|
|
412
|
+
return this.compaction.getProtectedToolNames(this.messages);
|
|
413
|
+
}
|
|
414
|
+
async appendEvent(type, message, usage) {
|
|
415
|
+
if (!this.eventStore || !this.contextId) {
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
const raw = message;
|
|
419
|
+
const providerMetadata = raw.providerMetadata;
|
|
420
|
+
const entry = {
|
|
421
|
+
type,
|
|
422
|
+
timestamp: message._superblocks?.timestamp ?? Date.now(),
|
|
423
|
+
role: message.role,
|
|
424
|
+
content: message.content,
|
|
425
|
+
...(message._superblocks != null
|
|
426
|
+
? { _superblocks: message._superblocks }
|
|
427
|
+
: {}),
|
|
428
|
+
...(providerMetadata != null ? { providerMetadata } : {}),
|
|
429
|
+
...(usage && { usage }),
|
|
430
|
+
};
|
|
431
|
+
try {
|
|
432
|
+
await this.eventStore.appendEvent(this.contextId, entry);
|
|
433
|
+
}
|
|
434
|
+
catch (err) {
|
|
435
|
+
logger.error(`Failed to append ${type} event: ${err}`);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
async appendCompactionWindow(messages) {
|
|
439
|
+
if (!this.eventStore || !this.contextId) {
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
try {
|
|
443
|
+
for (const message of messages) {
|
|
444
|
+
await this.eventStore.appendEvent(this.contextId, this.toEventLogEntry(message));
|
|
445
|
+
}
|
|
446
|
+
logger.info(`Wrote ${messages.length} client-side compaction message(s) to event log`);
|
|
447
|
+
}
|
|
448
|
+
catch (err) {
|
|
449
|
+
logger.error(`Failed to append client-side compaction window: ${err}`);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
toEventLogEntry(message) {
|
|
453
|
+
const raw = message;
|
|
454
|
+
const providerMetadata = raw.providerMetadata;
|
|
455
|
+
return {
|
|
456
|
+
type: message.role === "user" ? "prompt_sent" : "response_received",
|
|
457
|
+
timestamp: message._superblocks?.timestamp ?? Date.now(),
|
|
458
|
+
role: message.role,
|
|
459
|
+
content: message.content,
|
|
460
|
+
...(message._superblocks != null
|
|
461
|
+
? { _superblocks: message._superblocks }
|
|
462
|
+
: {}),
|
|
463
|
+
...(providerMetadata != null ? { providerMetadata } : {}),
|
|
464
|
+
};
|
|
465
|
+
}
|
|
335
466
|
/**
|
|
336
467
|
* Returns the last known input token count from the most recent assistant message.
|
|
337
468
|
* This represents the cumulative context size at the time of that turn.
|
|
@@ -358,60 +489,5 @@ export class ContextV2 {
|
|
|
358
489
|
}
|
|
359
490
|
}
|
|
360
491
|
}
|
|
361
|
-
async compactIfNeeded(usage) {
|
|
362
|
-
const llmReportedTokens = getTotalTokens(usage);
|
|
363
|
-
const threshold = this.config.contextLimit -
|
|
364
|
-
this.config.maxOutputTokens -
|
|
365
|
-
this.config.contextBufferTokens;
|
|
366
|
-
if (llmReportedTokens <= threshold) {
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
369
|
-
logger.info(`Compaction triggered: ${llmReportedTokens} tokens > ${threshold} threshold ` +
|
|
370
|
-
`(${this.messages.length} messages)`);
|
|
371
|
-
const result = await compact({
|
|
372
|
-
messages: this.messages,
|
|
373
|
-
usage,
|
|
374
|
-
model: this.summarizationModel,
|
|
375
|
-
config: this.config,
|
|
376
|
-
callbacks: this.compactionCallbacks,
|
|
377
|
-
tracer: this.tracer,
|
|
378
|
-
rootDir: this.rootDir,
|
|
379
|
-
});
|
|
380
|
-
let phase = "none";
|
|
381
|
-
if (result.phase2Applied) {
|
|
382
|
-
phase = "phase1+phase2";
|
|
383
|
-
}
|
|
384
|
-
else if (result.phase1Applied) {
|
|
385
|
-
phase = "phase1";
|
|
386
|
-
}
|
|
387
|
-
logger.info(`Compaction complete (${phase}): saved ${result.tokensSaved} tokens, ${this.messages.length}→${result.messages.length} messages`);
|
|
388
|
-
this.messages = result.messages.map((msg) => ({
|
|
389
|
-
...msg,
|
|
390
|
-
_superblocks: {
|
|
391
|
-
...msg._superblocks,
|
|
392
|
-
timestamp: msg._superblocks?.timestamp ?? Date.now(),
|
|
393
|
-
},
|
|
394
|
-
}));
|
|
395
|
-
if (result.phase2Applied) {
|
|
396
|
-
// Re-inject mode context that was lost when messages were replaced by the summary.
|
|
397
|
-
try {
|
|
398
|
-
const modeState = this.getModeState?.();
|
|
399
|
-
if (modeState) {
|
|
400
|
-
this.messages.push(toStoredMessage({
|
|
401
|
-
role: "user",
|
|
402
|
-
content: buildModeMessage(modeState.mode, modeState.planApproved),
|
|
403
|
-
}));
|
|
404
|
-
logger.info(`Re-injected mode context after phase 2 compaction (mode=${modeState.mode})`);
|
|
405
|
-
}
|
|
406
|
-
else if (this.getModeState) {
|
|
407
|
-
logger.warn("Phase 2 compaction completed but getModeState() returned undefined; " +
|
|
408
|
-
"mode context will NOT be re-injected");
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
catch (err) {
|
|
412
|
-
logger.error(`Failed to re-inject mode state after phase 2 compaction: ${err}`);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
492
|
}
|
|
417
493
|
//# sourceMappingURL=context.js.map
|