@orion-agents/orion-code 0.1.8 → 0.1.9
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/CHANGELOG.md +445 -0
- package/README.md +15 -6
- package/README.zh-CN.md +26 -7
- package/dist/agents/coordinator.d.ts.map +1 -1
- package/dist/agents/coordinator.js +49 -9
- package/dist/agents/coordinator.js.map +1 -1
- package/dist/agents/fork.d.ts +5 -1
- package/dist/agents/fork.d.ts.map +1 -1
- package/dist/agents/fork.js +9 -10
- package/dist/agents/fork.js.map +1 -1
- package/dist/agents/worker-pool.d.ts.map +1 -1
- package/dist/agents/worker-pool.js +8 -3
- package/dist/agents/worker-pool.js.map +1 -1
- package/dist/cli.js +6 -6
- package/dist/cli.js.map +1 -1
- package/dist/commands/context-tool-command-handlers.d.ts.map +1 -1
- package/dist/commands/context-tool-command-handlers.js +42 -0
- package/dist/commands/context-tool-command-handlers.js.map +1 -1
- package/dist/commands/model-command-handlers.d.ts +1 -1
- package/dist/commands/model-command-handlers.d.ts.map +1 -1
- package/dist/commands/model-command-handlers.js +166 -1
- package/dist/commands/model-command-handlers.js.map +1 -1
- package/dist/commands/session-command-handlers.d.ts.map +1 -1
- package/dist/commands/session-command-handlers.js +97 -5
- package/dist/commands/session-command-handlers.js.map +1 -1
- package/dist/commands/session-commands.js +2 -2
- package/dist/commands/session-commands.js.map +1 -1
- package/dist/commands/types.d.ts +6 -0
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/framework/index.d.ts +5 -3
- package/dist/framework/index.d.ts.map +1 -1
- package/dist/framework/index.js +9 -1
- package/dist/framework/index.js.map +1 -1
- package/dist/framework/query.d.ts +26 -4
- package/dist/framework/query.d.ts.map +1 -1
- package/dist/framework/query.js +319 -62
- package/dist/framework/query.js.map +1 -1
- package/dist/framework/stop-decision.d.ts +56 -0
- package/dist/framework/stop-decision.d.ts.map +1 -0
- package/dist/framework/stop-decision.js +36 -0
- package/dist/framework/stop-decision.js.map +1 -0
- package/dist/framework/tool-scheduler.d.ts +5 -0
- package/dist/framework/tool-scheduler.d.ts.map +1 -1
- package/dist/framework/tool-scheduler.js +24 -9
- package/dist/framework/tool-scheduler.js.map +1 -1
- package/dist/harness/assembler.d.ts.map +1 -1
- package/dist/harness/assembler.js +77 -19
- package/dist/harness/assembler.js.map +1 -1
- package/dist/harness/capability-profile.d.ts +3 -0
- package/dist/harness/capability-profile.d.ts.map +1 -0
- package/dist/harness/capability-profile.js +44 -0
- package/dist/harness/capability-profile.js.map +1 -0
- package/dist/harness/capsule.d.ts.map +1 -1
- package/dist/harness/capsule.js +22 -3
- package/dist/harness/capsule.js.map +1 -1
- package/dist/harness/compact-benchmark-corpus.d.ts +10 -0
- package/dist/harness/compact-benchmark-corpus.d.ts.map +1 -0
- package/dist/harness/compact-benchmark-corpus.js +56 -0
- package/dist/harness/compact-benchmark-corpus.js.map +1 -0
- package/dist/harness/context-harness.d.ts +23 -3
- package/dist/harness/context-harness.d.ts.map +1 -1
- package/dist/harness/context-harness.js +183 -11
- package/dist/harness/context-harness.js.map +1 -1
- package/dist/harness/contract.d.ts.map +1 -1
- package/dist/harness/contract.js +106 -11
- package/dist/harness/contract.js.map +1 -1
- package/dist/harness/drift-guard.d.ts +2 -1
- package/dist/harness/drift-guard.d.ts.map +1 -1
- package/dist/harness/drift-guard.js +315 -20
- package/dist/harness/drift-guard.js.map +1 -1
- package/dist/harness/evidence.d.ts.map +1 -1
- package/dist/harness/evidence.js +25 -12
- package/dist/harness/evidence.js.map +1 -1
- package/dist/harness/index.d.ts +7 -2
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +19 -1
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/ledger.d.ts.map +1 -1
- package/dist/harness/ledger.js +44 -14
- package/dist/harness/ledger.js.map +1 -1
- package/dist/harness/progress-controller.d.ts +14 -0
- package/dist/harness/progress-controller.d.ts.map +1 -0
- package/dist/harness/progress-controller.js +110 -0
- package/dist/harness/progress-controller.js.map +1 -0
- package/dist/harness/state.d.ts.map +1 -1
- package/dist/harness/state.js +5 -2
- package/dist/harness/state.js.map +1 -1
- package/dist/harness/stop-controller.d.ts +15 -0
- package/dist/harness/stop-controller.d.ts.map +1 -0
- package/dist/harness/stop-controller.js +87 -0
- package/dist/harness/stop-controller.js.map +1 -0
- package/dist/harness/types.d.ts +137 -0
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/verification.d.ts +7 -0
- package/dist/harness/verification.d.ts.map +1 -0
- package/dist/harness/verification.js +122 -0
- package/dist/harness/verification.js.map +1 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/ink-ui/screens/ReplScreen.d.ts +3 -0
- package/dist/ink-ui/screens/ReplScreen.d.ts.map +1 -1
- package/dist/ink-ui/screens/ReplScreen.js +30 -5
- package/dist/ink-ui/screens/ReplScreen.js.map +1 -1
- package/dist/memory/index.d.ts +1 -0
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +1 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/prompt-context.d.ts +42 -0
- package/dist/memory/prompt-context.d.ts.map +1 -0
- package/dist/memory/prompt-context.js +129 -0
- package/dist/memory/prompt-context.js.map +1 -0
- package/dist/runtime/chat-compact.d.ts +26 -0
- package/dist/runtime/chat-compact.d.ts.map +1 -0
- package/dist/runtime/chat-compact.js +132 -0
- package/dist/runtime/chat-compact.js.map +1 -0
- package/dist/runtime/chat-controller.d.ts.map +1 -1
- package/dist/runtime/chat-controller.js +64 -74
- package/dist/runtime/chat-controller.js.map +1 -1
- package/dist/runtime/goals/coordinator.d.ts +3 -0
- package/dist/runtime/goals/coordinator.d.ts.map +1 -1
- package/dist/runtime/goals/coordinator.js +5 -15
- package/dist/runtime/goals/coordinator.js.map +1 -1
- package/dist/runtime/goals/prompt.js +1 -1
- package/dist/runtime/goals/prompt.js.map +1 -1
- package/dist/runtime/goals/stop-policy.d.ts +9 -0
- package/dist/runtime/goals/stop-policy.d.ts.map +1 -0
- package/dist/runtime/goals/stop-policy.js +83 -0
- package/dist/runtime/goals/stop-policy.js.map +1 -0
- package/dist/runtime/goals/types.d.ts +0 -1
- package/dist/runtime/goals/types.d.ts.map +1 -1
- package/dist/runtime/goals/types.js +0 -1
- package/dist/runtime/goals/types.js.map +1 -1
- package/dist/runtime/model-coordinator.d.ts +44 -1
- package/dist/runtime/model-coordinator.d.ts.map +1 -1
- package/dist/runtime/model-coordinator.js +161 -19
- package/dist/runtime/model-coordinator.js.map +1 -1
- package/dist/runtime/subagents/index.d.ts +1 -1
- package/dist/runtime/subagents/index.d.ts.map +1 -1
- package/dist/runtime/subagents/index.js.map +1 -1
- package/dist/runtime/subagents/production.d.ts +6 -2
- package/dist/runtime/subagents/production.d.ts.map +1 -1
- package/dist/runtime/subagents/production.js +25 -6
- package/dist/runtime/subagents/production.js.map +1 -1
- package/dist/runtime/subagents/runner.d.ts +12 -1
- package/dist/runtime/subagents/runner.d.ts.map +1 -1
- package/dist/runtime/subagents/runner.js +62 -1
- package/dist/runtime/subagents/runner.js.map +1 -1
- package/dist/runtime/subagents/runtime-integration.d.ts.map +1 -1
- package/dist/runtime/subagents/runtime-integration.js +2 -1
- package/dist/runtime/subagents/runtime-integration.js.map +1 -1
- package/dist/runtime/subagents/supervisor.d.ts.map +1 -1
- package/dist/runtime/subagents/supervisor.js +6 -0
- package/dist/runtime/subagents/supervisor.js.map +1 -1
- package/dist/runtime/subagents/types.d.ts +4 -1
- package/dist/runtime/subagents/types.d.ts.map +1 -1
- package/dist/runtime/subagents/types.js.map +1 -1
- package/dist/runtime/ui-events.d.ts +2 -0
- package/dist/runtime/ui-events.d.ts.map +1 -1
- package/dist/runtime/ui-events.js.map +1 -1
- package/dist/services/compact/auto-compact.d.ts +82 -2
- package/dist/services/compact/auto-compact.d.ts.map +1 -1
- package/dist/services/compact/auto-compact.js +226 -44
- package/dist/services/compact/auto-compact.js.map +1 -1
- package/dist/services/compact/compact.d.ts +54 -37
- package/dist/services/compact/compact.d.ts.map +1 -1
- package/dist/services/compact/compact.js +512 -127
- package/dist/services/compact/compact.js.map +1 -1
- package/dist/services/compact/coordinator.d.ts +5 -1
- package/dist/services/compact/coordinator.d.ts.map +1 -1
- package/dist/services/compact/coordinator.js +10 -1
- package/dist/services/compact/coordinator.js.map +1 -1
- package/dist/services/compact/fingerprint.d.ts +27 -0
- package/dist/services/compact/fingerprint.d.ts.map +1 -0
- package/dist/services/compact/fingerprint.js +69 -0
- package/dist/services/compact/fingerprint.js.map +1 -0
- package/dist/services/compact/index.d.ts +7 -5
- package/dist/services/compact/index.d.ts.map +1 -1
- package/dist/services/compact/index.js +19 -6
- package/dist/services/compact/index.js.map +1 -1
- package/dist/services/compact/planner.d.ts +41 -0
- package/dist/services/compact/planner.d.ts.map +1 -0
- package/dist/services/compact/planner.js +102 -0
- package/dist/services/compact/planner.js.map +1 -0
- package/dist/services/compact/semantic-summary.d.ts +93 -0
- package/dist/services/compact/semantic-summary.d.ts.map +1 -0
- package/dist/services/compact/semantic-summary.js +158 -0
- package/dist/services/compact/semantic-summary.js.map +1 -0
- package/dist/services/compact/summary-generator.d.ts +23 -0
- package/dist/services/compact/summary-generator.d.ts.map +1 -1
- package/dist/services/compact/summary-generator.js +173 -39
- package/dist/services/compact/summary-generator.js.map +1 -1
- package/dist/services/file-context.d.ts.map +1 -1
- package/dist/services/file-context.js +29 -33
- package/dist/services/file-context.js.map +1 -1
- package/dist/services/global-config.d.ts +6 -0
- package/dist/services/global-config.d.ts.map +1 -1
- package/dist/services/global-config.js +8 -0
- package/dist/services/global-config.js.map +1 -1
- package/dist/services/llm.d.ts +3 -0
- package/dist/services/llm.d.ts.map +1 -1
- package/dist/services/llm.js +7 -0
- package/dist/services/llm.js.map +1 -1
- package/dist/services/project-instructions.d.ts.map +1 -1
- package/dist/services/project-instructions.js +10 -17
- package/dist/services/project-instructions.js.map +1 -1
- package/dist/services/safe-project-reader.d.ts +30 -0
- package/dist/services/safe-project-reader.d.ts.map +1 -0
- package/dist/services/safe-project-reader.js +141 -0
- package/dist/services/safe-project-reader.js.map +1 -0
- package/dist/services/session-storage.d.ts +134 -5
- package/dist/services/session-storage.d.ts.map +1 -1
- package/dist/services/session-storage.js +727 -57
- package/dist/services/session-storage.js.map +1 -1
- package/dist/services/usage-state.d.ts +7 -0
- package/dist/services/usage-state.d.ts.map +1 -1
- package/dist/services/usage-state.js +117 -16
- package/dist/services/usage-state.js.map +1 -1
- package/dist/skills/runtime.d.ts.map +1 -1
- package/dist/skills/runtime.js +34 -35
- package/dist/skills/runtime.js.map +1 -1
- package/docs/migration/v0.1.8-to-v0.1.9.md +60 -0
- package/docs/plan/v0.1.9-release-checklist.md +64 -0
- package/docs/readme.md +27 -0
- package/npm-shrinkwrap.json +14 -38
- package/package.json +5 -1
- package/dist/services/compact/micro-compact.d.ts +0 -21
- package/dist/services/compact/micro-compact.d.ts.map +0 -1
- package/dist/services/compact/micro-compact.js +0 -99
- package/dist/services/compact/micro-compact.js.map +0 -1
|
@@ -1,160 +1,545 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* orion code - Compact 服务
|
|
4
|
-
*
|
|
5
|
-
* 长对话压缩服务,减少上下文长度同时保留关键信息。
|
|
6
|
-
* 参考 OpenClaude 的 compact/ 目录实现。
|
|
7
|
-
*/
|
|
2
|
+
/** Semantic, group-safe conversation compaction. */
|
|
8
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.CompactCandidateValidationError = void 0;
|
|
5
|
+
exports.prepareCompactCandidate = prepareCompactCandidate;
|
|
6
|
+
exports.validateCompactCandidate = validateCompactCandidate;
|
|
7
|
+
exports.commitCompactCandidate = commitCompactCandidate;
|
|
9
8
|
exports.compactMessages = compactMessages;
|
|
10
9
|
exports.needsCompact = needsCompact;
|
|
11
|
-
|
|
10
|
+
const crypto_1 = require("crypto");
|
|
12
11
|
const summary_generator_1 = require("./summary-generator");
|
|
13
12
|
const harness_1 = require("../../harness");
|
|
13
|
+
const token_estimate_1 = require("../../utils/token-estimate");
|
|
14
|
+
const fingerprint_1 = require("./fingerprint");
|
|
15
|
+
const planner_1 = require("./planner");
|
|
16
|
+
const semantic_summary_1 = require("./semantic-summary");
|
|
14
17
|
const tool_call_groups_1 = require("./tool-call-groups");
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
const CONTEXT_SUMMARY_PREFIX = '[Context Summary]\n';
|
|
19
|
+
const SUMMARY_ACK = 'I understand the context. I will continue the conversation with this background information.';
|
|
20
|
+
class CompactCandidateValidationError extends Error {
|
|
21
|
+
constructor(validation) {
|
|
22
|
+
super(validation.errors.map(error => `${error.code}: ${error.message}`).join('; '));
|
|
23
|
+
this.validation = validation;
|
|
24
|
+
this.name = 'CompactCandidateValidationError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.CompactCandidateValidationError = CompactCandidateValidationError;
|
|
18
28
|
const DEFAULT_OPTIONS = {
|
|
19
29
|
maxMessages: 20,
|
|
20
30
|
keepToolCalls: true,
|
|
21
31
|
keepSystemMessage: true,
|
|
22
|
-
threshold: 0,
|
|
32
|
+
threshold: 0,
|
|
23
33
|
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
34
|
+
function cloneMessages(messages) {
|
|
35
|
+
return messages.map(message => ({
|
|
36
|
+
...message,
|
|
37
|
+
tool_calls: message.tool_calls?.map(call => ({
|
|
38
|
+
...call,
|
|
39
|
+
function: { ...call.function },
|
|
40
|
+
})),
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
function uniqueStrings(values) {
|
|
44
|
+
return [
|
|
45
|
+
...new Set(values.map(value => value?.trim()).filter((value) => !!value)),
|
|
46
|
+
];
|
|
47
|
+
}
|
|
48
|
+
function invariantItemId(kind, material) {
|
|
49
|
+
const digest = (0, crypto_1.createHash)('sha256').update(material, 'utf8').digest('hex').slice(0, 20);
|
|
50
|
+
return `ctx-${kind}-${digest}`;
|
|
51
|
+
}
|
|
52
|
+
function invariantItem(params) {
|
|
53
|
+
const id = invariantItemId(params.kind, `${params.sourceRefs.join('\0')}\0${params.text}`);
|
|
54
|
+
return {
|
|
55
|
+
id,
|
|
56
|
+
groupId: `harness:${id}`,
|
|
57
|
+
kind: params.kind,
|
|
58
|
+
priority: 'must_keep',
|
|
59
|
+
sourceRefs: [...params.sourceRefs],
|
|
60
|
+
tokenEstimate: (0, token_estimate_1.estimateMessagesTokens)([{ role: 'system', content: params.text }]),
|
|
61
|
+
taskEpoch: params.taskEpoch,
|
|
62
|
+
expires: 'task',
|
|
63
|
+
text: params.text,
|
|
64
|
+
sourceRole: 'system',
|
|
65
|
+
messageIndexes: { start: -1, end: -1 },
|
|
66
|
+
status: params.status,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function structuredProjectionLine(label, value, maxLength = 280) {
|
|
70
|
+
const normalized = value.replace(/\s+/g, ' ').trim();
|
|
71
|
+
const prefix = `${label}: `;
|
|
72
|
+
if (prefix.length + normalized.length <= maxLength)
|
|
73
|
+
return `${prefix}${normalized}`;
|
|
74
|
+
const ref = (0, crypto_1.createHash)('sha256').update(normalized, 'utf8').digest('hex').slice(0, 16);
|
|
75
|
+
const suffix = ` [full-ref:${ref}]`;
|
|
76
|
+
const available = Math.max(0, maxLength - prefix.length - suffix.length);
|
|
77
|
+
return `${prefix}${normalized.slice(0, available)}${suffix}`;
|
|
78
|
+
}
|
|
79
|
+
function renderDeterministicSemanticSummary(summary, maxLength) {
|
|
80
|
+
const lines = ['[Semantic Snapshot v1]'];
|
|
81
|
+
if (summary.requestedFocus) {
|
|
82
|
+
lines.push(structuredProjectionLine('Requested focus', summary.requestedFocus));
|
|
83
|
+
}
|
|
84
|
+
if (summary.projectInstructions) {
|
|
85
|
+
lines.push(structuredProjectionLine('Project compact instructions', summary.projectInstructions));
|
|
49
86
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
87
|
+
if (summary.objective)
|
|
88
|
+
lines.push(structuredProjectionLine('Objective', summary.objective));
|
|
89
|
+
if (summary.activeInstruction) {
|
|
90
|
+
lines.push(structuredProjectionLine('Active instruction', summary.activeInstruction));
|
|
91
|
+
}
|
|
92
|
+
for (const criterion of summary.criterionStates ?? []) {
|
|
93
|
+
lines.push(structuredProjectionLine(`Criterion ${criterion.id} [${criterion.status}]`, `${criterion.statement}${criterion.evidenceRefs.length ? ` | evidence=${criterion.evidenceRefs.join(',')}` : ''}`));
|
|
94
|
+
}
|
|
95
|
+
const appendValues = (label, values) => {
|
|
96
|
+
for (const value of values ?? [])
|
|
97
|
+
lines.push(structuredProjectionLine(label, value));
|
|
98
|
+
};
|
|
99
|
+
appendValues('Constraint', summary.constraints);
|
|
100
|
+
appendValues('Non-goal', summary.nonGoals);
|
|
101
|
+
appendValues('Decision', summary.decisions);
|
|
102
|
+
appendValues('Completed', summary.completed);
|
|
103
|
+
appendValues('Pending', summary.pending);
|
|
104
|
+
appendValues('Blocker', summary.blockers);
|
|
105
|
+
appendValues('Verification passed', summary.successfulVerifications);
|
|
106
|
+
appendValues('Verification failed', summary.failedVerifications);
|
|
107
|
+
appendValues('Changed file', summary.changedFiles);
|
|
108
|
+
appendValues('Open question', summary.openQuestions);
|
|
109
|
+
if (summary.nextAction)
|
|
110
|
+
lines.push(structuredProjectionLine('Next action', summary.nextAction));
|
|
111
|
+
lines.push(`Source boundary: ${summary.coverage.groupCount} groups / ${summary.coverage.messageCount} messages`);
|
|
112
|
+
const selected = [];
|
|
113
|
+
const omitted = [];
|
|
114
|
+
let used = 0;
|
|
115
|
+
for (const line of lines) {
|
|
116
|
+
const needed = line.length + (selected.length > 0 ? 1 : 0);
|
|
117
|
+
if (used + needed <= maxLength) {
|
|
118
|
+
selected.push(line);
|
|
119
|
+
used += needed;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
omitted.push(line);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (omitted.length > 0) {
|
|
126
|
+
const ref = (0, crypto_1.createHash)('sha256').update(omitted.join('\n'), 'utf8').digest('hex').slice(0, 16);
|
|
127
|
+
const receipt = `Omitted structured lines: ${omitted.length} [full-ref:${ref}]`;
|
|
128
|
+
while (selected.length > 1 && selected.join('\n').length + receipt.length + 1 > maxLength) {
|
|
129
|
+
omitted.unshift(selected.pop());
|
|
130
|
+
}
|
|
131
|
+
if (receipt.length <= maxLength)
|
|
132
|
+
selected.push(receipt);
|
|
133
|
+
}
|
|
134
|
+
return selected.join('\n');
|
|
135
|
+
}
|
|
136
|
+
function enrichSemanticSummary(summary, options) {
|
|
137
|
+
const state = options.harnessState;
|
|
138
|
+
const capsule = state?.capsule ?? options.contextCapsule;
|
|
139
|
+
const contract = state?.contract ?? capsule?.contract;
|
|
140
|
+
const capability = state?.capabilityProfile;
|
|
141
|
+
const taskEpoch = Math.max(1, state?.taskEpoch ?? contract?.taskEpoch ?? summary.taskEpoch);
|
|
142
|
+
const criterionStates = contract?.criteria?.map(criterion => ({
|
|
143
|
+
id: criterion.id,
|
|
144
|
+
statement: criterion.statement,
|
|
145
|
+
status: criterion.status ?? 'pending',
|
|
146
|
+
evidenceRefs: [...criterion.evidenceRefs],
|
|
147
|
+
}));
|
|
148
|
+
const boundEvidenceRefs = uniqueStrings((criterionStates ?? []).flatMap(criterion => criterion.evidenceRefs));
|
|
149
|
+
const evidenceByRef = new Map();
|
|
150
|
+
for (const record of state?.evidenceIndex ?? []) {
|
|
151
|
+
const value = { content: record.content, status: record.verificationStatus };
|
|
152
|
+
evidenceByRef.set(record.id, value);
|
|
153
|
+
evidenceByRef.set(`evidence:${record.id}`, value);
|
|
154
|
+
}
|
|
155
|
+
for (const entry of state?.ledger ?? []) {
|
|
156
|
+
const rawSuccess = entry.metadata?.success;
|
|
157
|
+
const status = rawSuccess === true ? 'passed' : rawSuccess === false ? 'failed' : 'unknown';
|
|
158
|
+
const value = { content: entry.content, status };
|
|
159
|
+
evidenceByRef.set(entry.id, value);
|
|
160
|
+
evidenceByRef.set(`ledger:${entry.id}`, value);
|
|
161
|
+
}
|
|
162
|
+
const invariantItems = [];
|
|
163
|
+
if (contract) {
|
|
164
|
+
invariantItems.push(invariantItem({
|
|
165
|
+
kind: 'contract',
|
|
166
|
+
text: JSON.stringify({
|
|
167
|
+
objective: contract.objective,
|
|
168
|
+
activeInstruction: state?.activeInstruction ?? contract.userIntent,
|
|
169
|
+
constraints: contract.constraints,
|
|
170
|
+
prohibitions: contract.prohibitions,
|
|
171
|
+
nonGoals: state?.nonGoals ?? contract.nonGoals ?? [],
|
|
172
|
+
openQuestions: state?.openQuestions ?? contract.openQuestions ?? [],
|
|
173
|
+
criteria: criterionStates ?? [],
|
|
174
|
+
}),
|
|
175
|
+
sourceRefs: uniqueStrings([
|
|
176
|
+
`contract:${contract.id}`,
|
|
177
|
+
...(criterionStates ?? []).map(criterion => criterion.id),
|
|
178
|
+
]),
|
|
179
|
+
taskEpoch,
|
|
180
|
+
}));
|
|
181
|
+
}
|
|
182
|
+
for (const ref of boundEvidenceRefs) {
|
|
183
|
+
const evidence = evidenceByRef.get(ref);
|
|
184
|
+
invariantItems.push(invariantItem({
|
|
185
|
+
kind: 'evidence',
|
|
186
|
+
text: evidence?.content ?? `Evidence reference: ${ref}`,
|
|
187
|
+
sourceRefs: [ref],
|
|
188
|
+
taskEpoch,
|
|
189
|
+
status: evidence?.status ?? 'unknown',
|
|
190
|
+
}));
|
|
191
|
+
}
|
|
192
|
+
if (capsule?.nextAction) {
|
|
193
|
+
invariantItems.push(invariantItem({
|
|
194
|
+
kind: 'next_action',
|
|
195
|
+
text: capsule.nextAction,
|
|
196
|
+
sourceRefs: ['harness:next-action'],
|
|
197
|
+
taskEpoch,
|
|
198
|
+
}));
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
...summary,
|
|
202
|
+
taskEpoch,
|
|
203
|
+
objective: options.goalObjective ?? state?.rootObjective ?? contract?.objective ?? summary.objective,
|
|
204
|
+
activeInstruction: state?.activeInstruction ?? contract?.userIntent ?? summary.latestUserInstruction,
|
|
205
|
+
scope: contract
|
|
206
|
+
? {
|
|
207
|
+
cwd: contract.allowedScope.cwd,
|
|
208
|
+
files: contract.allowedScope.files ? [...contract.allowedScope.files] : undefined,
|
|
209
|
+
commands: contract.allowedScope.commands
|
|
210
|
+
? [...contract.allowedScope.commands]
|
|
211
|
+
: undefined,
|
|
212
|
+
}
|
|
213
|
+
: undefined,
|
|
214
|
+
nonGoals: uniqueStrings([
|
|
215
|
+
...(summary.nonGoals ?? []),
|
|
216
|
+
...(state?.nonGoals ?? contract?.nonGoals ?? []),
|
|
217
|
+
]),
|
|
218
|
+
openQuestions: uniqueStrings([
|
|
219
|
+
...(summary.openQuestions ?? []),
|
|
220
|
+
...(state?.openQuestions ?? contract?.openQuestions ?? []),
|
|
221
|
+
]),
|
|
222
|
+
criterionStates,
|
|
223
|
+
files: uniqueStrings([...summary.files, ...(capsule?.changedFiles ?? [])]),
|
|
224
|
+
changedFiles: uniqueStrings(capsule?.changedFiles ?? []),
|
|
225
|
+
successfulVerifications: uniqueStrings(capsule?.verification.passed ?? []),
|
|
226
|
+
failedVerifications: uniqueStrings(capsule?.verification.failed ?? []),
|
|
227
|
+
blockers: uniqueStrings([...summary.blockers, ...(capsule?.verification.warnings ?? [])]),
|
|
228
|
+
nextAction: capsule?.nextAction,
|
|
229
|
+
evidenceRefs: uniqueStrings([...summary.evidenceRefs, ...boundEvidenceRefs]),
|
|
230
|
+
items: [...invariantItems, ...summary.items.map(item => ({ ...item, taskEpoch }))],
|
|
231
|
+
verification: [
|
|
232
|
+
...invariantItems.filter(item => item.kind === 'evidence'),
|
|
233
|
+
...summary.verification.map(item => ({ ...item, taskEpoch })),
|
|
234
|
+
],
|
|
235
|
+
capability: capability
|
|
236
|
+
? {
|
|
237
|
+
revision: capability.revision,
|
|
238
|
+
fingerprint: capability.fingerprint,
|
|
239
|
+
modelId: capability.model.id,
|
|
240
|
+
permissionMode: capability.permission.mode,
|
|
241
|
+
tools: [...capability.tools],
|
|
242
|
+
}
|
|
243
|
+
: undefined,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
function pinnedContextMessages(options) {
|
|
247
|
+
if (options.harnessState) {
|
|
248
|
+
return [
|
|
249
|
+
{
|
|
250
|
+
role: 'user',
|
|
251
|
+
content: (0, harness_1.renderHarnessStateForCompact)(options.harnessState, options.compactMode ?? 'manual'),
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
role: 'assistant',
|
|
255
|
+
content: 'I will continue from this Orion Code Context State and preserve its root objective, active instruction, constraints, and verification state.',
|
|
256
|
+
},
|
|
257
|
+
];
|
|
258
|
+
}
|
|
259
|
+
if (options.contextCapsule) {
|
|
260
|
+
return [
|
|
261
|
+
{ role: 'user', content: (0, harness_1.renderContextCapsule)(options.contextCapsule) },
|
|
262
|
+
{
|
|
263
|
+
role: 'assistant',
|
|
264
|
+
content: 'I will continue from this Context Capsule and preserve its open todos, constraints, and verification state.',
|
|
265
|
+
},
|
|
266
|
+
];
|
|
267
|
+
}
|
|
268
|
+
return [];
|
|
269
|
+
}
|
|
270
|
+
function stripSyntheticCompactMessages(messages) {
|
|
271
|
+
const priorSummary = [...messages]
|
|
55
272
|
.reverse()
|
|
56
|
-
.find(message => message.content?.startsWith(
|
|
57
|
-
const
|
|
273
|
+
.find(message => message.content?.startsWith(CONTEXT_SUMMARY_PREFIX));
|
|
274
|
+
const conversation = messages.filter(message => !message.content?.startsWith(CONTEXT_SUMMARY_PREFIX) &&
|
|
275
|
+
!(message.role === 'assistant' && message.content === SUMMARY_ACK) &&
|
|
276
|
+
!message.content?.startsWith('[Orion Code Context State v2]') &&
|
|
277
|
+
!message.content?.startsWith('## Context Capsule') &&
|
|
58
278
|
!(message.role === 'assistant' &&
|
|
59
|
-
message.content
|
|
60
|
-
'I
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
279
|
+
(message.content.startsWith('I will continue from this Orion Code Context State') ||
|
|
280
|
+
message.content.startsWith('I will continue from this Context Capsule'))));
|
|
281
|
+
return { priorSummary, conversation: cloneMessages(conversation) };
|
|
282
|
+
}
|
|
283
|
+
function withoutToolProtocol(messages) {
|
|
284
|
+
const callIds = new Set(messages.flatMap(message => message.tool_calls?.map(call => call.id) ?? []));
|
|
285
|
+
return messages
|
|
286
|
+
.filter(message => message.role !== 'tool' || !callIds.has(message.tool_call_id ?? ''))
|
|
287
|
+
.map(message => message.tool_calls?.length ? { ...message, tool_calls: undefined } : { ...message });
|
|
288
|
+
}
|
|
289
|
+
function emptyPlan(messages) {
|
|
290
|
+
return (0, planner_1.planCompactMessages)(messages, { maxMessages: messages.length });
|
|
291
|
+
}
|
|
292
|
+
function resultFromCandidate(candidate) {
|
|
293
|
+
return {
|
|
294
|
+
messages: cloneMessages(candidate.messages),
|
|
295
|
+
originalCount: candidate.originalCount,
|
|
296
|
+
compactedCount: candidate.messages.length,
|
|
297
|
+
ratio: candidate.originalCount === 0 ? 1 : candidate.messages.length / candidate.originalCount,
|
|
298
|
+
summary: candidate.summary,
|
|
299
|
+
summarySource: candidate.summarySource,
|
|
300
|
+
summaryGeneratedAt: candidate.summaryGeneratedAt,
|
|
301
|
+
semanticSummary: candidate.semanticSummary,
|
|
302
|
+
diagnostics: candidate.diagnostics.map(diagnostic => ({ ...diagnostic })),
|
|
303
|
+
fingerprint: candidate.fingerprint,
|
|
304
|
+
beforeTokens: candidate.beforeTokens,
|
|
305
|
+
afterTokens: candidate.afterTokens,
|
|
306
|
+
plan: candidate.plan,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
/** Prepare a model-context projection without mutating or persisting its source. */
|
|
310
|
+
async function prepareCompactCandidate(messages, options = {}) {
|
|
311
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
312
|
+
const source = cloneMessages(messages);
|
|
313
|
+
const systemMessages = opts.keepSystemMessage
|
|
314
|
+
? source.filter(message => message.role === 'system')
|
|
315
|
+
: [];
|
|
316
|
+
const nonSystem = opts.keepSystemMessage
|
|
317
|
+
? source.filter(message => message.role !== 'system')
|
|
318
|
+
: source;
|
|
319
|
+
const { priorSummary, conversation } = stripSyntheticCompactMessages(nonSystem);
|
|
320
|
+
const pinned = pinnedContextMessages(opts);
|
|
321
|
+
const framingTokens = (0, token_estimate_1.estimateMessagesTokens)([
|
|
322
|
+
{ role: 'user', content: CONTEXT_SUMMARY_PREFIX },
|
|
323
|
+
{ role: 'assistant', content: SUMMARY_ACK },
|
|
324
|
+
]);
|
|
325
|
+
const plan = (0, planner_1.planCompactMessages)(conversation, {
|
|
326
|
+
maxMessages: opts.maxMessages,
|
|
327
|
+
safeInputBudget: opts.safeInputBudget,
|
|
328
|
+
targetRatio: opts.targetRatio ?? planner_1.DEFAULT_COMPACT_TARGET_RATIO,
|
|
329
|
+
fixedTokens: (0, token_estimate_1.estimateMessagesTokens)([...systemMessages, ...pinned]) + framingTokens,
|
|
330
|
+
summaryReserveTokens: opts.summaryReserveTokens,
|
|
331
|
+
});
|
|
332
|
+
const evictedMessages = (0, planner_1.flattenCompactGroups)(plan.evictedGroups);
|
|
333
|
+
const oldMessages = priorSummary ? [{ ...priorSummary }, ...evictedMessages] : evictedMessages;
|
|
334
|
+
let semanticSummary = (0, semantic_summary_1.extractCompactSummary)(plan.evictedGroups, {
|
|
335
|
+
taskEpoch: opts.harnessState?.taskEpoch ?? opts.harnessState?.contract?.taskEpoch,
|
|
336
|
+
});
|
|
337
|
+
semanticSummary = {
|
|
338
|
+
...semanticSummary,
|
|
339
|
+
requestedFocus: (0, summary_generator_1.normalizeCompactFocus)(opts.summaryOptions?.focus),
|
|
340
|
+
projectInstructions: (0, summary_generator_1.normalizeCompactInstructions)(opts.summaryOptions?.instructions),
|
|
341
|
+
};
|
|
342
|
+
semanticSummary = enrichSemanticSummary(semanticSummary, opts);
|
|
343
|
+
let summary = '';
|
|
344
|
+
let summarySource = 'heuristic';
|
|
345
|
+
let diagnostics = [];
|
|
346
|
+
if (plan.evictedGroups.length > 0) {
|
|
347
|
+
if (opts.llm) {
|
|
348
|
+
const generated = await (0, summary_generator_1.generateSummaryWithSource)(oldMessages, opts.llm, opts.summaryOptions);
|
|
349
|
+
summary = generated.text;
|
|
350
|
+
summarySource = generated.source;
|
|
351
|
+
diagnostics = generated.diagnostics;
|
|
352
|
+
if (generated.source === 'heuristic') {
|
|
353
|
+
const projectionBudget = Math.max(256, Math.min(opts.summaryOptions?.maxLength ?? 2000, plan.summaryReserveTokens * 3 || 2000));
|
|
354
|
+
summary = renderDeterministicSemanticSummary(semanticSummary, projectionBudget);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
const projectionBudget = Math.max(256, Math.min(opts.summaryOptions?.maxLength ?? 2000, plan.summaryReserveTokens * 3 || 2000));
|
|
359
|
+
summary = renderDeterministicSemanticSummary(semanticSummary, projectionBudget);
|
|
360
|
+
diagnostics = [
|
|
361
|
+
{
|
|
362
|
+
code: 'deterministic_projection',
|
|
363
|
+
message: 'Rendered the typed semantic snapshot without a summary provider.',
|
|
364
|
+
fallbackUsed: true,
|
|
365
|
+
},
|
|
366
|
+
];
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
else if (priorSummary) {
|
|
370
|
+
summary = priorSummary.content.slice(CONTEXT_SUMMARY_PREFIX.length);
|
|
371
|
+
}
|
|
372
|
+
const candidateMessages = [...systemMessages];
|
|
373
|
+
if (plan.evictedGroups.length > 0)
|
|
374
|
+
candidateMessages.push(...pinned);
|
|
375
|
+
if (summary) {
|
|
376
|
+
candidateMessages.push({ role: 'user', content: `${CONTEXT_SUMMARY_PREFIX}${summary}` }, { role: 'assistant', content: SUMMARY_ACK });
|
|
377
|
+
}
|
|
378
|
+
candidateMessages.push(...(0, planner_1.flattenCompactGroups)(plan.recentGroups));
|
|
379
|
+
const visibleMessages = opts.keepToolCalls
|
|
380
|
+
? candidateMessages
|
|
381
|
+
: withoutToolProtocol(candidateMessages);
|
|
382
|
+
return {
|
|
383
|
+
status: 'prepared',
|
|
384
|
+
messages: visibleMessages,
|
|
385
|
+
originalCount: source.length,
|
|
386
|
+
summary,
|
|
387
|
+
summarySource,
|
|
388
|
+
summaryGeneratedAt: Date.now(),
|
|
389
|
+
semanticSummary,
|
|
390
|
+
diagnostics,
|
|
391
|
+
fingerprint: (0, fingerprint_1.canonicalCompactCandidateFingerprint)({
|
|
392
|
+
messages: visibleMessages,
|
|
393
|
+
sourceBoundary: {
|
|
394
|
+
firstGroupId: semanticSummary.sourceBoundary?.firstGroupId,
|
|
395
|
+
lastGroupId: semanticSummary.sourceBoundary?.lastGroupId,
|
|
396
|
+
groupCount: semanticSummary.sourceBoundary?.groupCount ?? semanticSummary.coverage.groupCount,
|
|
397
|
+
messageCount: semanticSummary.sourceBoundary?.messageCount ?? semanticSummary.coverage.messageCount,
|
|
398
|
+
groupIds: semanticSummary.coverage.groupIds,
|
|
399
|
+
},
|
|
400
|
+
}),
|
|
401
|
+
beforeTokens: (0, token_estimate_1.estimateMessagesTokens)(source),
|
|
402
|
+
afterTokens: (0, token_estimate_1.estimateMessagesTokens)(visibleMessages),
|
|
403
|
+
plan,
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
/** Validate semantic coverage, provider headroom, and tool protocol invariants. */
|
|
407
|
+
function validateCompactCandidate(candidate) {
|
|
408
|
+
const errors = [];
|
|
409
|
+
try {
|
|
410
|
+
(0, tool_call_groups_1.assertToolCallGroups)(candidate.messages);
|
|
411
|
+
}
|
|
412
|
+
catch (error) {
|
|
413
|
+
errors.push({
|
|
414
|
+
code: 'tool_group_invalid',
|
|
415
|
+
message: error instanceof Error ? error.message : String(error),
|
|
86
416
|
});
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
417
|
+
}
|
|
418
|
+
if (candidate.plan.targetTokens !== undefined &&
|
|
419
|
+
candidate.afterTokens > candidate.plan.targetTokens) {
|
|
420
|
+
errors.push({
|
|
421
|
+
code: 'target_headroom_exceeded',
|
|
422
|
+
message: `Candidate uses ${candidate.afterTokens} tokens; target is ${candidate.plan.targetTokens}.`,
|
|
90
423
|
});
|
|
91
424
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
425
|
+
const expectedCoverage = candidate.plan.evictedGroups.map(group => group.id);
|
|
426
|
+
if (expectedCoverage.length !== candidate.semanticSummary.coverage.groupIds.length ||
|
|
427
|
+
expectedCoverage.some((groupId, index) => candidate.semanticSummary.coverage.groupIds[index] !== groupId)) {
|
|
428
|
+
errors.push({
|
|
429
|
+
code: 'evicted_coverage_mismatch',
|
|
430
|
+
message: 'Semantic summary does not cover every evicted atomic group in order.',
|
|
96
431
|
});
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
432
|
+
}
|
|
433
|
+
const summary = candidate.semanticSummary;
|
|
434
|
+
const expectedMessageCount = candidate.plan.evictedGroups.reduce((total, group) => total + group.messages.length, 0);
|
|
435
|
+
if (summary.sourceBoundary?.firstGroupId !== expectedCoverage[0] ||
|
|
436
|
+
summary.sourceBoundary?.lastGroupId !== expectedCoverage.at(-1) ||
|
|
437
|
+
summary.sourceBoundary?.groupCount !== expectedCoverage.length ||
|
|
438
|
+
summary.sourceBoundary?.messageCount !== expectedMessageCount) {
|
|
439
|
+
errors.push({
|
|
440
|
+
code: 'source_boundary_mismatch',
|
|
441
|
+
message: 'Semantic source boundary does not match the evicted atomic groups.',
|
|
100
442
|
});
|
|
101
443
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
444
|
+
const validKinds = new Set([
|
|
445
|
+
'system',
|
|
446
|
+
'contract',
|
|
447
|
+
'decision',
|
|
448
|
+
'evidence',
|
|
449
|
+
'tool_group',
|
|
450
|
+
'turn',
|
|
451
|
+
'next_action',
|
|
452
|
+
]);
|
|
453
|
+
const validPriorities = new Set(['must_keep', 'high', 'normal', 'evictable']);
|
|
454
|
+
const schemaInvalid = !Number.isSafeInteger(summary.taskEpoch) ||
|
|
455
|
+
summary.taskEpoch < 1 ||
|
|
456
|
+
summary.items.some(item => !item.id ||
|
|
457
|
+
!item.groupId ||
|
|
458
|
+
!validKinds.has(item.kind) ||
|
|
459
|
+
!validPriorities.has(item.priority) ||
|
|
460
|
+
!Array.isArray(item.sourceRefs) ||
|
|
461
|
+
item.sourceRefs.length === 0 ||
|
|
462
|
+
!Number.isSafeInteger(item.tokenEstimate) ||
|
|
463
|
+
item.tokenEstimate < 0);
|
|
464
|
+
if (schemaInvalid) {
|
|
465
|
+
errors.push({
|
|
466
|
+
code: 'semantic_schema_invalid',
|
|
467
|
+
message: 'Semantic ContextItems do not satisfy the typed schema.',
|
|
107
468
|
});
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
469
|
+
}
|
|
470
|
+
if (summary.items.some(item => item.taskEpoch !== summary.taskEpoch)) {
|
|
471
|
+
errors.push({
|
|
472
|
+
code: 'task_epoch_mismatch',
|
|
473
|
+
message: 'Semantic ContextItems are not bound to the current task epoch.',
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
const conversationItems = summary.items.filter(item => item.messageIndexes.start >= 0);
|
|
477
|
+
if (conversationItems.length !== expectedCoverage.length ||
|
|
478
|
+
expectedCoverage.some((groupId, index) => conversationItems[index]?.groupId !== groupId ||
|
|
479
|
+
!conversationItems[index]?.sourceRefs.includes(`group:${groupId}`))) {
|
|
480
|
+
errors.push({
|
|
481
|
+
code: 'semantic_reference_invalid',
|
|
482
|
+
message: 'Conversation ContextItems do not bind every evicted group in order.',
|
|
111
483
|
});
|
|
112
484
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
485
|
+
const criterionIds = new Set();
|
|
486
|
+
let semanticReferenceInvalid = false;
|
|
487
|
+
for (const criterion of summary.criterionStates ?? []) {
|
|
488
|
+
if (!criterion.id || criterionIds.has(criterion.id))
|
|
489
|
+
semanticReferenceInvalid = true;
|
|
490
|
+
criterionIds.add(criterion.id);
|
|
491
|
+
if (!summary.items.some(item => item.kind === 'contract' && item.sourceRefs.includes(criterion.id))) {
|
|
492
|
+
semanticReferenceInvalid = true;
|
|
493
|
+
}
|
|
494
|
+
for (const evidenceRef of criterion.evidenceRefs) {
|
|
495
|
+
if (!summary.evidenceRefs.includes(evidenceRef) ||
|
|
496
|
+
!summary.items.some(item => item.kind === 'evidence' && item.sourceRefs.includes(evidenceRef))) {
|
|
497
|
+
semanticReferenceInvalid = true;
|
|
120
498
|
}
|
|
121
|
-
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (semanticReferenceInvalid) {
|
|
502
|
+
errors.push({
|
|
503
|
+
code: 'semantic_reference_invalid',
|
|
504
|
+
message: 'Criterion or evidence references are missing, duplicated, or dangling.',
|
|
122
505
|
});
|
|
123
506
|
}
|
|
124
|
-
|
|
125
|
-
const ratio = compactedCount / originalCount;
|
|
126
|
-
return {
|
|
127
|
-
messages: compactedMessages,
|
|
128
|
-
originalCount,
|
|
129
|
-
compactedCount,
|
|
130
|
-
ratio,
|
|
131
|
-
summary,
|
|
132
|
-
summarySource: generated.source,
|
|
133
|
-
summaryGeneratedAt: Date.now(),
|
|
134
|
-
};
|
|
507
|
+
return { valid: errors.length === 0, errors };
|
|
135
508
|
}
|
|
136
509
|
/**
|
|
137
|
-
*
|
|
510
|
+
* Commit the prepared in-memory projection. This intentionally does not write a
|
|
511
|
+
* session checkpoint; the runtime/session owner must perform that transaction.
|
|
138
512
|
*/
|
|
139
|
-
function
|
|
140
|
-
const
|
|
141
|
-
|
|
513
|
+
function commitCompactCandidate(candidate) {
|
|
514
|
+
const validation = validateCompactCandidate(candidate);
|
|
515
|
+
if (!validation.valid)
|
|
516
|
+
throw new CompactCandidateValidationError(validation);
|
|
517
|
+
return resultFromCandidate(candidate);
|
|
142
518
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
519
|
+
async function compactMessages(messages, options = {}) {
|
|
520
|
+
const threshold = options.threshold ?? DEFAULT_OPTIONS.threshold;
|
|
521
|
+
if (messages.length <= threshold) {
|
|
522
|
+
const cloned = cloneMessages(messages);
|
|
523
|
+
const tokens = (0, token_estimate_1.estimateMessagesTokens)(cloned);
|
|
524
|
+
return {
|
|
525
|
+
messages,
|
|
526
|
+
originalCount: messages.length,
|
|
527
|
+
compactedCount: messages.length,
|
|
528
|
+
ratio: 1,
|
|
529
|
+
summary: '',
|
|
530
|
+
summarySource: 'heuristic',
|
|
531
|
+
summaryGeneratedAt: Date.now(),
|
|
532
|
+
semanticSummary: (0, semantic_summary_1.emptyCompactSummary)(),
|
|
533
|
+
diagnostics: [],
|
|
534
|
+
fingerprint: (0, fingerprint_1.canonicalMessagesFingerprint)(cloned),
|
|
535
|
+
beforeTokens: tokens,
|
|
536
|
+
afterTokens: tokens,
|
|
537
|
+
plan: emptyPlan(cloned),
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
return commitCompactCandidate(await prepareCompactCandidate(messages, options));
|
|
541
|
+
}
|
|
542
|
+
function needsCompact(messages, threshold) {
|
|
543
|
+
return messages.length > (threshold ?? DEFAULT_OPTIONS.threshold);
|
|
159
544
|
}
|
|
160
545
|
//# sourceMappingURL=compact.js.map
|