tinker-agent 1.0.65 → 1.2.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/CHANGELOG.md +36 -0
- package/LICENSE +201 -0
- package/NOTICE +6 -0
- package/README.md +90 -9
- package/bin/tinker.js +39 -0
- package/node_modules/ansi-regex/index.d.ts +33 -0
- package/node_modules/ansi-regex/index.js +14 -0
- package/node_modules/ansi-regex/license +9 -0
- package/node_modules/ansi-regex/package.json +61 -0
- package/node_modules/ansi-regex/readme.md +66 -0
- package/node_modules/ansi-styles/index.d.ts +236 -0
- package/node_modules/ansi-styles/index.js +223 -0
- package/node_modules/ansi-styles/license +9 -0
- package/node_modules/ansi-styles/package.json +54 -0
- package/node_modules/ansi-styles/readme.md +173 -0
- package/node_modules/chalk/license +9 -0
- package/node_modules/chalk/package.json +83 -0
- package/node_modules/chalk/readme.md +297 -0
- package/node_modules/chalk/source/index.d.ts +325 -0
- package/node_modules/chalk/source/index.js +225 -0
- package/node_modules/chalk/source/utilities.js +33 -0
- package/node_modules/chalk/source/vendor/ansi-styles/index.d.ts +236 -0
- package/node_modules/chalk/source/vendor/ansi-styles/index.js +223 -0
- package/node_modules/chalk/source/vendor/supports-color/browser.d.ts +1 -0
- package/node_modules/chalk/source/vendor/supports-color/browser.js +34 -0
- package/node_modules/chalk/source/vendor/supports-color/index.d.ts +55 -0
- package/node_modules/chalk/source/vendor/supports-color/index.js +190 -0
- package/node_modules/character-entities/index.d.ts +6 -0
- package/node_modules/character-entities/index.js +2132 -0
- package/node_modules/character-entities/license +22 -0
- package/node_modules/character-entities/package.json +78 -0
- package/node_modules/character-entities/readme.md +152 -0
- package/node_modules/decode-named-character-reference/index.d.ts +13 -0
- package/node_modules/decode-named-character-reference/index.d.ts.map +1 -0
- package/node_modules/decode-named-character-reference/index.dom.d.ts +6 -0
- package/node_modules/decode-named-character-reference/index.dom.d.ts.map +1 -0
- package/node_modules/decode-named-character-reference/index.dom.js +32 -0
- package/node_modules/decode-named-character-reference/index.js +19 -0
- package/node_modules/decode-named-character-reference/license +22 -0
- package/node_modules/decode-named-character-reference/package.json +90 -0
- package/node_modules/decode-named-character-reference/readme.md +136 -0
- package/node_modules/get-east-asian-width/index.d.ts +60 -0
- package/node_modules/get-east-asian-width/index.js +30 -0
- package/node_modules/get-east-asian-width/license +9 -0
- package/node_modules/get-east-asian-width/lookup-data.js +21 -0
- package/node_modules/get-east-asian-width/lookup.js +138 -0
- package/node_modules/get-east-asian-width/package.json +71 -0
- package/node_modules/get-east-asian-width/readme.md +65 -0
- package/node_modules/get-east-asian-width/utilities.js +24 -0
- package/node_modules/has-flag/index.d.ts +39 -0
- package/node_modules/has-flag/index.js +8 -0
- package/node_modules/has-flag/license +9 -0
- package/node_modules/has-flag/package.json +49 -0
- package/node_modules/has-flag/readme.md +74 -0
- package/node_modules/is-fullwidth-code-point/index.d.ts +17 -0
- package/node_modules/is-fullwidth-code-point/index.js +12 -0
- package/node_modules/is-fullwidth-code-point/license +9 -0
- package/node_modules/is-fullwidth-code-point/package.json +53 -0
- package/node_modules/is-fullwidth-code-point/readme.md +31 -0
- package/node_modules/markdansi/LICENSE +21 -0
- package/node_modules/markdansi/README.md +167 -0
- package/node_modules/markdansi/dist/ast.d.ts +99 -0
- package/node_modules/markdansi/dist/ast.js +1 -0
- package/node_modules/markdansi/dist/cli.d.ts +17 -0
- package/node_modules/markdansi/dist/cli.js +208 -0
- package/node_modules/markdansi/dist/hyperlink.d.ts +9 -0
- package/node_modules/markdansi/dist/hyperlink.js +26 -0
- package/node_modules/markdansi/dist/index.d.ts +10 -0
- package/node_modules/markdansi/dist/index.js +16 -0
- package/node_modules/markdansi/dist/parser.d.ts +2 -0
- package/node_modules/markdansi/dist/parser.js +205 -0
- package/node_modules/markdansi/dist/render.d.ts +9 -0
- package/node_modules/markdansi/dist/render.js +680 -0
- package/node_modules/markdansi/dist/stream.d.ts +39 -0
- package/node_modules/markdansi/dist/stream.js +192 -0
- package/node_modules/markdansi/dist/theme.d.ts +18 -0
- package/node_modules/markdansi/dist/theme.js +105 -0
- package/node_modules/markdansi/dist/types.d.ts +58 -0
- package/node_modules/markdansi/dist/types.js +1 -0
- package/node_modules/markdansi/dist/wrap.d.ts +10 -0
- package/node_modules/markdansi/dist/wrap.js +73 -0
- package/node_modules/markdansi/docs/spec.md +110 -0
- package/node_modules/markdansi/package.json +78 -0
- package/node_modules/markdansi/tsconfig.json +18 -0
- package/node_modules/marked/LICENSE +44 -0
- package/node_modules/marked/README.md +115 -0
- package/node_modules/marked/bin/main.js +284 -0
- package/node_modules/marked/bin/marked.js +16 -0
- package/node_modules/marked/lib/marked.d.ts +760 -0
- package/node_modules/marked/lib/marked.esm.js +77 -0
- package/node_modules/marked/lib/marked.esm.js.map +7 -0
- package/node_modules/marked/lib/marked.umd.js +79 -0
- package/node_modules/marked/lib/marked.umd.js.map +7 -0
- package/node_modules/marked/man/marked.1 +113 -0
- package/node_modules/marked/man/marked.1.md +93 -0
- package/node_modules/marked/package.json +103 -0
- package/node_modules/slice-ansi/index.d.ts +19 -0
- package/node_modules/slice-ansi/index.js +317 -0
- package/node_modules/slice-ansi/license +10 -0
- package/node_modules/slice-ansi/package.json +59 -0
- package/node_modules/slice-ansi/readme.md +55 -0
- package/node_modules/slice-ansi/tokenize-ansi.js +752 -0
- package/node_modules/string-width/index.d.ts +39 -0
- package/node_modules/string-width/index.js +203 -0
- package/node_modules/string-width/license +9 -0
- package/node_modules/string-width/package.json +65 -0
- package/node_modules/string-width/readme.md +66 -0
- package/node_modules/strip-ansi/index.d.ts +15 -0
- package/node_modules/strip-ansi/index.js +19 -0
- package/node_modules/strip-ansi/license +9 -0
- package/node_modules/strip-ansi/package.json +59 -0
- package/node_modules/strip-ansi/readme.md +37 -0
- package/node_modules/supports-color/browser.d.ts +1 -0
- package/node_modules/supports-color/browser.js +35 -0
- package/node_modules/supports-color/index.d.ts +55 -0
- package/node_modules/supports-color/index.js +202 -0
- package/node_modules/supports-color/license +9 -0
- package/node_modules/supports-color/package.json +64 -0
- package/node_modules/supports-color/readme.md +75 -0
- package/node_modules/supports-hyperlinks/browser.js +10 -0
- package/node_modules/supports-hyperlinks/index.d.ts +25 -0
- package/node_modules/supports-hyperlinks/index.js +163 -0
- package/node_modules/supports-hyperlinks/license +10 -0
- package/node_modules/supports-hyperlinks/package.json +47 -0
- package/node_modules/supports-hyperlinks/readme.md +45 -0
- package/package.json +41 -10
- package/patches/markdansi@0.3.2.patch +22 -2
- package/src/agent/context-builder.ts +24 -10
- package/src/agent/context-meter.ts +89 -5
- package/src/agent/loop.ts +107 -10
- package/src/agent/runtime-session.ts +1437 -82
- package/src/agent/session-ledger.ts +169 -29
- package/src/agent/types.ts +12 -1
- package/src/agent/user-prompt-projection.ts +62 -0
- package/src/cli/config.ts +57 -14
- package/src/cli/model-profiles.ts +124 -0
- package/src/cli/run-runner.ts +4 -1
- package/src/cli/tui-runner.tsx +68 -30
- package/src/context/compiled-context-hash.ts +1 -1
- package/src/context/compiled-context-validator.ts +92 -15
- package/src/context/context-automation-policy.ts +121 -0
- package/src/context/context-manager.ts +390 -11
- package/src/context/context-policy.ts +8 -0
- package/src/context/context-protocol-validator.ts +11 -1
- package/src/context/context-revision-compiler.ts +190 -27
- package/src/context/context-revision.ts +105 -19
- package/src/context/context-surface.ts +329 -0
- package/src/context/prefix-retirement-planner.ts +570 -0
- package/src/context/protocol-frame.ts +30 -3
- package/src/context/recall-retirement-contract.ts +27 -0
- package/src/context/swap-planner.ts +34 -10
- package/src/events/observation-text-log.ts +3 -3
- package/src/events/stdout-event-printer.ts +39 -3
- package/src/events/types.ts +172 -35
- package/src/ids/runtime-id.ts +6 -0
- package/src/ids/uuid-v7.ts +7 -0
- package/src/image/image-asset-store.ts +319 -0
- package/src/image/image-input-policy.ts +14 -0
- package/src/image/image-probe.ts +233 -0
- package/src/image/image-types.ts +262 -0
- package/src/instructions/project-instructions.ts +4 -1
- package/src/mcp/mcp-manager.ts +83 -19
- package/src/model/fake-model-client.ts +9 -1
- package/src/model/input-token-estimator.ts +25 -0
- package/src/model/model-client.ts +60 -0
- package/src/model/model-request-preflight.ts +1 -0
- package/src/model/moonshot-input-token-estimator.ts +107 -0
- package/src/model/openai-chat-mapping.ts +77 -1
- package/src/model/openai-chat-model-client.ts +389 -59
- package/src/model/openai-chat-stream.ts +272 -0
- package/src/model/prompt-prefix-hash.ts +2 -4
- package/src/model/token-estimator.ts +4 -0
- package/src/observation/observation-builder.ts +29 -0
- package/src/session/resume-projection.ts +94 -34
- package/src/session/session-catalog.ts +4 -4
- package/src/session/session-errors.ts +1 -1
- package/src/session/session-history-reader.ts +151 -4
- package/src/session/session-last-response-reader.ts +189 -0
- package/src/session/session-schema.ts +349 -35
- package/src/session/session-store.ts +3266 -255
- package/src/session/sqlite-session-ledger.ts +9 -4
- package/src/skills/skill-catalog.ts +182 -0
- package/src/skills/skill-context.ts +364 -0
- package/src/skills/skill-loader.ts +779 -0
- package/src/skills/skill-tool.ts +297 -0
- package/src/tools/edit.ts +51 -64
- package/src/tools/ensure-parent-directory.ts +6 -0
- package/src/tools/read.ts +2 -2
- package/src/tools/recall.ts +43 -40
- package/src/tools/registry.ts +24 -3
- package/src/tools/ripgrep.ts +3 -2
- package/src/tools/types.ts +43 -4
- package/src/tools/write.ts +20 -31
- package/src/tui/app.tsx +333 -96
- package/src/tui/clipboard.ts +5 -0
- package/src/tui/components/mcp-panel.tsx +28 -0
- package/src/tui/components/prompt-input.tsx +790 -257
- package/src/tui/components/skills-panel.tsx +31 -0
- package/src/tui/components/timeline.tsx +30 -1
- package/src/tui/event-store.ts +85 -2
- package/src/tui/file-mention.ts +234 -0
- package/src/tui/line-editor.ts +1 -0
- package/src/tui/project-slash-commands.ts +229 -0
- package/src/tui/prompt-draft.ts +510 -0
- package/src/tui/prompt-history.ts +294 -22
- package/src/tui/slash-commands.ts +46 -2
- package/src/tui/tui-session-controller.ts +110 -48
- package/src/tui/workspace-file-search.ts +94 -0
|
@@ -11,10 +11,11 @@ import { ContextProtocolValidator } from "./context-protocol-validator";
|
|
|
11
11
|
import type {
|
|
12
12
|
CompiledContextEntry,
|
|
13
13
|
CompiledRevisionContext,
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
StoredContextSnapshotV8,
|
|
15
|
+
StoredInitialContextRevisionV8,
|
|
16
16
|
SwapOverride,
|
|
17
17
|
} from "./context-revision";
|
|
18
|
+
import type { StoredContextSurfaceV8 } from "./context-surface";
|
|
18
19
|
import {
|
|
19
20
|
immutableRecord,
|
|
20
21
|
materializeAgentMessages,
|
|
@@ -34,7 +35,7 @@ export class ContextRevisionCompiler {
|
|
|
34
35
|
private readonly compiledValidator = new CompiledContextValidator(),
|
|
35
36
|
) {}
|
|
36
37
|
|
|
37
|
-
compileActive(snapshot:
|
|
38
|
+
compileActive(snapshot: StoredContextSnapshotV8): CompiledRevisionContext {
|
|
38
39
|
validateSnapshotIdentity(snapshot);
|
|
39
40
|
this.protocolValidator.validate(snapshot.canonical);
|
|
40
41
|
const overrides = overrideMap(snapshot.activeOverrides);
|
|
@@ -42,11 +43,15 @@ export class ContextRevisionCompiler {
|
|
|
42
43
|
canonical: snapshot.canonical,
|
|
43
44
|
revisionId: snapshot.revision.revisionId,
|
|
44
45
|
overrides,
|
|
46
|
+
keepFromOrdinal: snapshot.revision.keepFromOrdinal,
|
|
47
|
+
systemPrompt: snapshot.surface.systemPrompt,
|
|
48
|
+
surfaceSha256: snapshot.surface.surfaceSha256,
|
|
45
49
|
});
|
|
46
50
|
this.compiledValidator.validateActive(
|
|
47
51
|
compiled,
|
|
48
52
|
snapshot.canonical,
|
|
49
53
|
snapshot.activeOverrides,
|
|
54
|
+
snapshot.surface,
|
|
50
55
|
);
|
|
51
56
|
if (
|
|
52
57
|
compiled.manifest.canonicalSequenceHash !==
|
|
@@ -65,11 +70,40 @@ export class ContextRevisionCompiler {
|
|
|
65
70
|
return compiled;
|
|
66
71
|
}
|
|
67
72
|
|
|
73
|
+
compileForIdentityRekey(input: {
|
|
74
|
+
canonical: ProtocolContextView;
|
|
75
|
+
revisionId: ContextRevisionId;
|
|
76
|
+
activeOverrides: readonly SwapOverride[];
|
|
77
|
+
keepFromOrdinal: number;
|
|
78
|
+
surface: StoredContextSurfaceV8;
|
|
79
|
+
}): CompiledRevisionContext {
|
|
80
|
+
this.protocolValidator.validate(input.canonical);
|
|
81
|
+
const compiled = compileEntries({
|
|
82
|
+
canonical: input.canonical,
|
|
83
|
+
revisionId: input.revisionId,
|
|
84
|
+
overrides: overrideMap(input.activeOverrides),
|
|
85
|
+
keepFromOrdinal: input.keepFromOrdinal,
|
|
86
|
+
systemPrompt: input.surface.systemPrompt,
|
|
87
|
+
surfaceSha256: input.surface.surfaceSha256,
|
|
88
|
+
});
|
|
89
|
+
this.compiledValidator.validateActive(
|
|
90
|
+
compiled,
|
|
91
|
+
input.canonical,
|
|
92
|
+
input.activeOverrides,
|
|
93
|
+
input.surface,
|
|
94
|
+
);
|
|
95
|
+
return compiled;
|
|
96
|
+
}
|
|
97
|
+
|
|
68
98
|
compileProspective(input: {
|
|
69
99
|
active: CompiledRevisionContext;
|
|
70
100
|
canonical: ProtocolContextView;
|
|
71
101
|
activeOverrides: readonly SwapOverride[];
|
|
72
102
|
addedOverrides: readonly SwapOverride[];
|
|
103
|
+
activeSurface: StoredContextSurfaceV8;
|
|
104
|
+
surface?: StoredContextSurfaceV8;
|
|
105
|
+
keepFromOrdinal?: number;
|
|
106
|
+
allowCombinedSurfaceAndOverrides?: boolean;
|
|
73
107
|
}): CompiledRevisionContext {
|
|
74
108
|
this.protocolValidator.validate(input.canonical);
|
|
75
109
|
if (
|
|
@@ -86,21 +120,53 @@ export class ContextRevisionCompiler {
|
|
|
86
120
|
input.active,
|
|
87
121
|
input.canonical,
|
|
88
122
|
input.activeOverrides,
|
|
123
|
+
input.activeSurface,
|
|
89
124
|
);
|
|
90
|
-
const
|
|
125
|
+
const keepFromOrdinal =
|
|
126
|
+
input.keepFromOrdinal ?? input.active.manifest.keepFromOrdinal;
|
|
127
|
+
if (
|
|
128
|
+
!Number.isSafeInteger(keepFromOrdinal) ||
|
|
129
|
+
keepFromOrdinal < input.active.manifest.keepFromOrdinal
|
|
130
|
+
) {
|
|
131
|
+
throw new ContextRevisionError(
|
|
132
|
+
"Prospective keep boundary must move monotonically forward.",
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
const changes = [
|
|
136
|
+
input.addedOverrides.length > 0,
|
|
137
|
+
input.surface !== undefined &&
|
|
138
|
+
input.surface.surfaceSha256 !== input.activeSurface.surfaceSha256,
|
|
139
|
+
keepFromOrdinal > input.active.manifest.keepFromOrdinal,
|
|
140
|
+
].filter(Boolean).length;
|
|
141
|
+
if (changes > 1 && input.allowCombinedSurfaceAndOverrides !== true) {
|
|
142
|
+
throw new ContextRevisionError(
|
|
143
|
+
"A prospective context revision cannot combine revision semantics.",
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
const candidateOverrides =
|
|
147
|
+
keepFromOrdinal > input.active.manifest.keepFromOrdinal
|
|
148
|
+
? input.activeOverrides.filter(
|
|
149
|
+
(override) => override.ordinal >= keepFromOrdinal,
|
|
150
|
+
)
|
|
151
|
+
: [...input.activeOverrides, ...input.addedOverrides];
|
|
91
152
|
const overrides = overrideMap(candidateOverrides);
|
|
92
153
|
if (overrides.size !== candidateOverrides.length) {
|
|
93
154
|
throw new ContextRevisionError("Prospective overrides contain duplicate IDs.");
|
|
94
155
|
}
|
|
156
|
+
const surface = input.surface ?? input.activeSurface;
|
|
95
157
|
const compiled = compileEntries({
|
|
96
158
|
canonical: input.canonical,
|
|
97
159
|
revisionId: input.active.revisionId,
|
|
98
160
|
overrides,
|
|
161
|
+
keepFromOrdinal,
|
|
162
|
+
systemPrompt: surface.systemPrompt,
|
|
163
|
+
surfaceSha256: surface.surfaceSha256,
|
|
99
164
|
});
|
|
100
165
|
this.compiledValidator.validateProspective(
|
|
101
166
|
compiled,
|
|
102
167
|
input.canonical,
|
|
103
168
|
candidateOverrides,
|
|
169
|
+
surface,
|
|
104
170
|
);
|
|
105
171
|
return compiled;
|
|
106
172
|
}
|
|
@@ -110,29 +176,59 @@ function compileEntries(input: {
|
|
|
110
176
|
canonical: ProtocolContextView;
|
|
111
177
|
revisionId: CompiledRevisionContext["revisionId"];
|
|
112
178
|
overrides: ReadonlyMap<string, SwapOverride>;
|
|
179
|
+
keepFromOrdinal: number;
|
|
180
|
+
systemPrompt: string;
|
|
181
|
+
surfaceSha256: string;
|
|
113
182
|
}): CompiledRevisionContext {
|
|
114
|
-
const
|
|
115
|
-
|
|
183
|
+
const records =
|
|
184
|
+
input.keepFromOrdinal === 1
|
|
185
|
+
? input.canonical.messages
|
|
186
|
+
: [
|
|
187
|
+
requireItem(input.canonical.messages, 0, "canonical system message"),
|
|
188
|
+
...input.canonical.messages.slice(input.keepFromOrdinal - 1),
|
|
189
|
+
];
|
|
190
|
+
const materialized = materializeAgentMessages(records);
|
|
191
|
+
const entries = records.map((record, index) => {
|
|
116
192
|
const canonicalMessage = requireItem(materialized, index, "canonical message");
|
|
117
193
|
const override = input.overrides.get(record.messageId);
|
|
194
|
+
const surfacedMessage =
|
|
195
|
+
record.ordinal === 1
|
|
196
|
+
? surfacedSystemMessage(canonicalMessage, input.systemPrompt)
|
|
197
|
+
: canonicalMessage;
|
|
118
198
|
const message =
|
|
119
199
|
override === undefined
|
|
120
|
-
?
|
|
121
|
-
: swappedToolMessage(
|
|
200
|
+
? surfacedMessage
|
|
201
|
+
: swappedToolMessage(surfacedMessage, override);
|
|
202
|
+
const representation =
|
|
203
|
+
override !== undefined
|
|
204
|
+
? "swapped"
|
|
205
|
+
: record.ordinal === 1 && input.systemPrompt !== record.content
|
|
206
|
+
? "surface"
|
|
207
|
+
: "canonical";
|
|
122
208
|
return Object.freeze<CompiledContextEntry>({
|
|
123
209
|
frameId: record.frameId,
|
|
124
210
|
messageId: record.messageId,
|
|
125
211
|
ordinal: record.ordinal,
|
|
126
|
-
representation
|
|
212
|
+
representation,
|
|
127
213
|
sourceContentSha256: record.contentSha256,
|
|
128
214
|
message: immutableRecord(message),
|
|
129
215
|
});
|
|
130
216
|
});
|
|
131
217
|
const manifest = Object.freeze({
|
|
132
|
-
|
|
133
|
-
|
|
218
|
+
canonicalFrameCount: input.canonical.frames.length,
|
|
219
|
+
canonicalMessageCount: input.canonical.messages.length,
|
|
220
|
+
activeFrameCount:
|
|
221
|
+
input.keepFromOrdinal === 1
|
|
222
|
+
? input.canonical.frames.length
|
|
223
|
+
: 1 +
|
|
224
|
+
input.canonical.frames.filter(
|
|
225
|
+
(frame) => frame.firstOrdinal >= input.keepFromOrdinal,
|
|
226
|
+
).length,
|
|
227
|
+
activeMessageCount: entries.length,
|
|
228
|
+
keepFromOrdinal: input.keepFromOrdinal,
|
|
134
229
|
canonicalSequenceHash: canonicalSequenceHash(input.canonical),
|
|
135
230
|
renderedMessageHash: renderedMessageHash(entries),
|
|
231
|
+
surfaceSha256: input.surfaceSha256,
|
|
136
232
|
});
|
|
137
233
|
return Object.freeze({
|
|
138
234
|
sessionId: input.canonical.sessionId,
|
|
@@ -143,6 +239,19 @@ function compileEntries(input: {
|
|
|
143
239
|
});
|
|
144
240
|
}
|
|
145
241
|
|
|
242
|
+
function surfacedSystemMessage(
|
|
243
|
+
message: AgentMessage,
|
|
244
|
+
systemPrompt: string,
|
|
245
|
+
): AgentMessage {
|
|
246
|
+
if (message.role !== "system") {
|
|
247
|
+
throw new ContextRevisionError("Canonical ordinal 1 is not a system message.");
|
|
248
|
+
}
|
|
249
|
+
if (systemPrompt.trim() === "") {
|
|
250
|
+
throw new ContextRevisionError("Active context surface prompt is empty.");
|
|
251
|
+
}
|
|
252
|
+
return { role: "system", content: systemPrompt };
|
|
253
|
+
}
|
|
254
|
+
|
|
146
255
|
function swappedToolMessage(
|
|
147
256
|
message: AgentMessage,
|
|
148
257
|
override: SwapOverride,
|
|
@@ -158,18 +267,25 @@ function swappedToolMessage(
|
|
|
158
267
|
};
|
|
159
268
|
}
|
|
160
269
|
|
|
161
|
-
function validateSnapshotIdentity(snapshot:
|
|
270
|
+
function validateSnapshotIdentity(snapshot: StoredContextSnapshotV8): void {
|
|
162
271
|
if (
|
|
163
272
|
snapshot.meta.sessionId !== snapshot.canonical.sessionId ||
|
|
164
273
|
snapshot.revision.sessionId !== snapshot.canonical.sessionId ||
|
|
165
|
-
snapshot.meta.activeRevisionId !== snapshot.revision.revisionId
|
|
274
|
+
snapshot.meta.activeRevisionId !== snapshot.revision.revisionId ||
|
|
275
|
+
snapshot.surface.sessionId !== snapshot.canonical.sessionId ||
|
|
276
|
+
snapshot.surface.surfaceId !== snapshot.revision.surfaceId ||
|
|
277
|
+
snapshot.surface.surfaceSha256 !== snapshot.revision.surfaceSha256
|
|
166
278
|
) {
|
|
167
279
|
throw new ContextRevisionError(
|
|
168
280
|
"Active context revision identity does not match canonical history.",
|
|
169
281
|
);
|
|
170
282
|
}
|
|
171
|
-
if (
|
|
172
|
-
|
|
283
|
+
if (
|
|
284
|
+
!Number.isSafeInteger(snapshot.revision.keepFromOrdinal) ||
|
|
285
|
+
snapshot.revision.keepFromOrdinal < 1 ||
|
|
286
|
+
snapshot.revision.keepFromOrdinal > snapshot.revision.sourceThroughOrdinal
|
|
287
|
+
) {
|
|
288
|
+
throw new ContextRevisionError("Active context revision boundary is invalid.");
|
|
173
289
|
}
|
|
174
290
|
const firstFrame = snapshot.canonical.frames[0];
|
|
175
291
|
const firstMessage = snapshot.canonical.messages[0];
|
|
@@ -202,25 +318,67 @@ function validateSnapshotIdentity(snapshot: StoredContextSnapshotV5): void {
|
|
|
202
318
|
snapshot.revision.parentRevisionId !== null ||
|
|
203
319
|
snapshot.revision.sourceThroughOrdinal !== 1 ||
|
|
204
320
|
snapshot.revision.addedOverrideCount !== 0 ||
|
|
205
|
-
snapshot.revision.
|
|
321
|
+
snapshot.revision.keepFromOrdinal !== 1 ||
|
|
322
|
+
snapshot.revision.activeOverrideCount !== 0 ||
|
|
206
323
|
snapshot.activeOverrides.length !== 0
|
|
207
324
|
) {
|
|
208
325
|
throw new ContextRevisionError("Initial context revision invariant failed.");
|
|
209
326
|
}
|
|
210
327
|
} else if (
|
|
211
|
-
snapshot.revision.
|
|
212
|
-
snapshot.revision.
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
328
|
+
snapshot.revision.kind === "swap_only" &&
|
|
329
|
+
(snapshot.revision.revisionNumber < 2 ||
|
|
330
|
+
snapshot.revision.addedOverrideCount < 1 ||
|
|
331
|
+
snapshot.revision.activeOverrideCount < snapshot.revision.addedOverrideCount ||
|
|
332
|
+
snapshot.revision.policyVersion !== "swap-only-v1" ||
|
|
333
|
+
snapshot.revision.rendererFormat !== "swap-observation-v1" ||
|
|
334
|
+
snapshot.activeOverrides.length !== snapshot.revision.activeOverrideCount)
|
|
217
335
|
) {
|
|
218
336
|
throw new ContextRevisionError("Swap context revision invariant failed.");
|
|
337
|
+
} else if (
|
|
338
|
+
snapshot.revision.kind === "surface_refresh" &&
|
|
339
|
+
(snapshot.revision.revisionNumber < 2 ||
|
|
340
|
+
snapshot.revision.addedOverrideCount !== 0 ||
|
|
341
|
+
snapshot.activeOverrides.length !== snapshot.revision.activeOverrideCount)
|
|
342
|
+
) {
|
|
343
|
+
throw new ContextRevisionError("Surface context revision invariant failed.");
|
|
344
|
+
} else if (
|
|
345
|
+
snapshot.revision.kind === "prefix_retirement" &&
|
|
346
|
+
(snapshot.revision.revisionNumber < 2 ||
|
|
347
|
+
snapshot.revision.keepFromOrdinal <= 1 ||
|
|
348
|
+
snapshot.revision.addedOverrideCount !== 0 ||
|
|
349
|
+
snapshot.revision.retiredThroughOrdinal !==
|
|
350
|
+
snapshot.revision.keepFromOrdinal - 1 ||
|
|
351
|
+
snapshot.revision.retiredTurnCount < 1 ||
|
|
352
|
+
snapshot.revision.retiredFrameCount < 1 ||
|
|
353
|
+
snapshot.revision.retiredMessageCount < 1 ||
|
|
354
|
+
snapshot.activeOverrides.length !== snapshot.revision.activeOverrideCount)
|
|
355
|
+
) {
|
|
356
|
+
throw new ContextRevisionError("Prefix retirement revision invariant failed.");
|
|
357
|
+
} else if (
|
|
358
|
+
snapshot.revision.kind === "skills_update" &&
|
|
359
|
+
(snapshot.revision.revisionNumber < 2 ||
|
|
360
|
+
snapshot.revision.addedOverrideCount < 1 ||
|
|
361
|
+
snapshot.revision.activeOverrideCount < snapshot.revision.addedOverrideCount ||
|
|
362
|
+
snapshot.revision.policyVersion !== "agent-skills-v1" ||
|
|
363
|
+
snapshot.revision.rendererFormat !== "skill-activation-receipt-v1" ||
|
|
364
|
+
snapshot.activeOverrides.length !== snapshot.revision.activeOverrideCount)
|
|
365
|
+
) {
|
|
366
|
+
throw new ContextRevisionError("Agent Skills context revision invariant failed.");
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (
|
|
370
|
+
snapshot.activeOverrides.some(
|
|
371
|
+
(override) => override.ordinal < snapshot.revision.keepFromOrdinal,
|
|
372
|
+
)
|
|
373
|
+
) {
|
|
374
|
+
throw new ContextRevisionError(
|
|
375
|
+
"Active context revision contains an override before its keep boundary.",
|
|
376
|
+
);
|
|
219
377
|
}
|
|
220
378
|
|
|
221
379
|
if (
|
|
222
380
|
activeOverrideManifestHash(snapshot.activeOverrides) !==
|
|
223
|
-
snapshot.revision.
|
|
381
|
+
snapshot.revision.activeOverrideManifestSha256
|
|
224
382
|
) {
|
|
225
383
|
throw new ContextRevisionError(
|
|
226
384
|
"Active context revision override manifest does not match stored overrides.",
|
|
@@ -231,8 +389,9 @@ function validateSnapshotIdentity(snapshot: StoredContextSnapshotV5): void {
|
|
|
231
389
|
export function createInitialContextRevision(input: {
|
|
232
390
|
revisionId: ContextRevisionId;
|
|
233
391
|
canonical: ProtocolContextView;
|
|
392
|
+
surface: StoredContextSurfaceV8;
|
|
234
393
|
createdAt: string;
|
|
235
|
-
}):
|
|
394
|
+
}): StoredInitialContextRevisionV8 {
|
|
236
395
|
const firstFrame = input.canonical.frames[0];
|
|
237
396
|
const firstMessage = input.canonical.messages[0];
|
|
238
397
|
if (
|
|
@@ -243,7 +402,9 @@ export function createInitialContextRevision(input: {
|
|
|
243
402
|
firstFrame.firstOrdinal !== 1 ||
|
|
244
403
|
firstFrame.lastOrdinal !== 1 ||
|
|
245
404
|
firstMessage?.role !== "system" ||
|
|
246
|
-
firstMessage.ordinal !== 1
|
|
405
|
+
firstMessage.ordinal !== 1 ||
|
|
406
|
+
input.surface.sessionId !== input.canonical.sessionId ||
|
|
407
|
+
input.surface.systemPrompt !== firstMessage.content
|
|
247
408
|
) {
|
|
248
409
|
throw new ContextRevisionError(
|
|
249
410
|
"Initial context revision requires exactly one closed system frame.",
|
|
@@ -255,11 +416,13 @@ export function createInitialContextRevision(input: {
|
|
|
255
416
|
revisionNumber: 1,
|
|
256
417
|
parentRevisionId: null,
|
|
257
418
|
kind: "initial_full",
|
|
419
|
+
surfaceId: input.surface.surfaceId,
|
|
420
|
+
surfaceSha256: input.surface.surfaceSha256,
|
|
258
421
|
keepFromOrdinal: 1,
|
|
259
422
|
sourceThroughOrdinal: 1,
|
|
260
423
|
addedOverrideCount: 0,
|
|
261
|
-
|
|
262
|
-
|
|
424
|
+
activeOverrideCount: 0,
|
|
425
|
+
activeOverrideManifestSha256: activeOverrideManifestHash([]),
|
|
263
426
|
canonicalSequenceSha256: canonicalSequenceHash(input.canonical, 1),
|
|
264
427
|
renderedMessageSha256: canonicalRenderedMessageHash(input.canonical, 1),
|
|
265
428
|
createdAt: input.createdAt,
|
|
@@ -1,41 +1,47 @@
|
|
|
1
1
|
import type { AgentMessage } from "../agent/types";
|
|
2
2
|
import type {
|
|
3
3
|
ContextRevisionId,
|
|
4
|
+
ContextSurfaceId,
|
|
4
5
|
MessageId,
|
|
5
6
|
ProtocolFrameId,
|
|
6
7
|
SessionId,
|
|
7
8
|
} from "../ids/runtime-id";
|
|
8
9
|
import type { ModelRequestInput } from "../model/model-client";
|
|
9
10
|
import type { MessageSource } from "./context-source";
|
|
11
|
+
import type { ContextSurfaceChanges, StoredContextSurfaceV8 } from "./context-surface";
|
|
10
12
|
import type { ProtocolContextView } from "./protocol-frame";
|
|
11
13
|
|
|
12
|
-
export type
|
|
14
|
+
export type StoredInitialContextRevisionV8 = {
|
|
13
15
|
readonly revisionId: ContextRevisionId;
|
|
14
16
|
readonly sessionId: SessionId;
|
|
15
17
|
readonly revisionNumber: 1;
|
|
16
18
|
readonly parentRevisionId: null;
|
|
17
19
|
readonly kind: "initial_full";
|
|
20
|
+
readonly surfaceId: ContextSurfaceId;
|
|
21
|
+
readonly surfaceSha256: string;
|
|
18
22
|
readonly keepFromOrdinal: 1;
|
|
19
23
|
readonly sourceThroughOrdinal: 1;
|
|
20
24
|
readonly addedOverrideCount: 0;
|
|
21
|
-
readonly
|
|
22
|
-
readonly
|
|
25
|
+
readonly activeOverrideCount: 0;
|
|
26
|
+
readonly activeOverrideManifestSha256: string;
|
|
23
27
|
readonly canonicalSequenceSha256: string;
|
|
24
28
|
readonly renderedMessageSha256: string;
|
|
25
29
|
readonly createdAt: string;
|
|
26
30
|
};
|
|
27
31
|
|
|
28
|
-
export type
|
|
32
|
+
export type StoredSwapContextRevisionV8 = {
|
|
29
33
|
readonly revisionId: ContextRevisionId;
|
|
30
34
|
readonly sessionId: SessionId;
|
|
31
35
|
readonly revisionNumber: number;
|
|
32
36
|
readonly parentRevisionId: ContextRevisionId;
|
|
33
37
|
readonly kind: "swap_only";
|
|
34
|
-
readonly
|
|
38
|
+
readonly surfaceId: ContextSurfaceId;
|
|
39
|
+
readonly surfaceSha256: string;
|
|
40
|
+
readonly keepFromOrdinal: number;
|
|
35
41
|
readonly sourceThroughOrdinal: number;
|
|
36
42
|
readonly addedOverrideCount: number;
|
|
37
|
-
readonly
|
|
38
|
-
readonly
|
|
43
|
+
readonly activeOverrideCount: number;
|
|
44
|
+
readonly activeOverrideManifestSha256: string;
|
|
39
45
|
readonly canonicalSequenceSha256: string;
|
|
40
46
|
readonly renderedMessageSha256: string;
|
|
41
47
|
readonly policyVersion: "swap-only-v1";
|
|
@@ -44,9 +50,77 @@ export type StoredSwapContextRevisionV5 = {
|
|
|
44
50
|
readonly createdAt: string;
|
|
45
51
|
};
|
|
46
52
|
|
|
47
|
-
export type
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
export type StoredSurfaceRefreshContextRevisionV8 = {
|
|
54
|
+
readonly revisionId: ContextRevisionId;
|
|
55
|
+
readonly sessionId: SessionId;
|
|
56
|
+
readonly revisionNumber: number;
|
|
57
|
+
readonly parentRevisionId: ContextRevisionId;
|
|
58
|
+
readonly kind: "surface_refresh";
|
|
59
|
+
readonly surfaceId: ContextSurfaceId;
|
|
60
|
+
readonly surfaceSha256: string;
|
|
61
|
+
readonly keepFromOrdinal: number;
|
|
62
|
+
readonly sourceThroughOrdinal: number;
|
|
63
|
+
readonly addedOverrideCount: 0;
|
|
64
|
+
readonly activeOverrideCount: number;
|
|
65
|
+
readonly activeOverrideManifestSha256: string;
|
|
66
|
+
readonly canonicalSequenceSha256: string;
|
|
67
|
+
readonly renderedMessageSha256: string;
|
|
68
|
+
readonly changeManifestSha256: string;
|
|
69
|
+
readonly createdAt: string;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export type StoredPrefixRetirementContextRevisionV8 = {
|
|
73
|
+
readonly revisionId: ContextRevisionId;
|
|
74
|
+
readonly sessionId: SessionId;
|
|
75
|
+
readonly revisionNumber: number;
|
|
76
|
+
readonly parentRevisionId: ContextRevisionId;
|
|
77
|
+
readonly kind: "prefix_retirement";
|
|
78
|
+
readonly surfaceId: ContextSurfaceId;
|
|
79
|
+
readonly surfaceSha256: string;
|
|
80
|
+
readonly keepFromOrdinal: number;
|
|
81
|
+
readonly sourceThroughOrdinal: number;
|
|
82
|
+
readonly addedOverrideCount: 0;
|
|
83
|
+
readonly activeOverrideCount: number;
|
|
84
|
+
readonly activeOverrideManifestSha256: string;
|
|
85
|
+
readonly canonicalSequenceSha256: string;
|
|
86
|
+
readonly renderedMessageSha256: string;
|
|
87
|
+
readonly policyVersion: "recall-first-retirement-v1";
|
|
88
|
+
readonly planSha256: string;
|
|
89
|
+
readonly retiredThroughOrdinal: number;
|
|
90
|
+
readonly retiredTurnCount: number;
|
|
91
|
+
readonly retiredFrameCount: number;
|
|
92
|
+
readonly retiredMessageCount: number;
|
|
93
|
+
readonly createdAt: string;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export type StoredSkillsUpdateContextRevisionV8 = {
|
|
97
|
+
readonly revisionId: ContextRevisionId;
|
|
98
|
+
readonly sessionId: SessionId;
|
|
99
|
+
readonly revisionNumber: number;
|
|
100
|
+
readonly parentRevisionId: ContextRevisionId;
|
|
101
|
+
readonly kind: "skills_update";
|
|
102
|
+
readonly surfaceId: ContextSurfaceId;
|
|
103
|
+
readonly surfaceSha256: string;
|
|
104
|
+
readonly keepFromOrdinal: number;
|
|
105
|
+
readonly sourceThroughOrdinal: number;
|
|
106
|
+
readonly addedOverrideCount: number;
|
|
107
|
+
readonly activeOverrideCount: number;
|
|
108
|
+
readonly activeOverrideManifestSha256: string;
|
|
109
|
+
readonly canonicalSequenceSha256: string;
|
|
110
|
+
readonly renderedMessageSha256: string;
|
|
111
|
+
readonly policyVersion: "agent-skills-v1";
|
|
112
|
+
readonly rendererFormat: "skill-activation-receipt-v1";
|
|
113
|
+
readonly changeManifestSha256: string;
|
|
114
|
+
readonly activationManifestSha256: string;
|
|
115
|
+
readonly createdAt: string;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export type StoredContextRevisionV8 =
|
|
119
|
+
| StoredInitialContextRevisionV8
|
|
120
|
+
| StoredSwapContextRevisionV8
|
|
121
|
+
| StoredSurfaceRefreshContextRevisionV8
|
|
122
|
+
| StoredPrefixRetirementContextRevisionV8
|
|
123
|
+
| StoredSkillsUpdateContextRevisionV8;
|
|
50
124
|
|
|
51
125
|
export type SwapOverride = {
|
|
52
126
|
readonly frameId: ProtocolFrameId;
|
|
@@ -59,21 +133,23 @@ export type SwapOverride = {
|
|
|
59
133
|
readonly originalBytes: number;
|
|
60
134
|
readonly renderedBytes: number;
|
|
61
135
|
readonly byteSavings: number;
|
|
136
|
+
readonly rendererFormat?: "swap-observation-v1" | "skill-activation-receipt-v1";
|
|
62
137
|
};
|
|
63
138
|
|
|
64
|
-
export type
|
|
139
|
+
export type StoredContextOverrideV8 = SwapOverride & {
|
|
65
140
|
readonly introducedRevisionId: ContextRevisionId;
|
|
66
|
-
readonly rendererFormat: "swap-observation-v1";
|
|
141
|
+
readonly rendererFormat: "swap-observation-v1" | "skill-activation-receipt-v1";
|
|
67
142
|
readonly createdAt: string;
|
|
68
143
|
};
|
|
69
144
|
|
|
70
|
-
export type
|
|
145
|
+
export type StoredContextSnapshotV8 = {
|
|
71
146
|
readonly meta: {
|
|
72
147
|
readonly sessionId: SessionId;
|
|
73
148
|
readonly activeRevisionId: ContextRevisionId;
|
|
74
149
|
};
|
|
75
|
-
readonly revision:
|
|
76
|
-
readonly
|
|
150
|
+
readonly revision: StoredContextRevisionV8;
|
|
151
|
+
readonly surface: StoredContextSurfaceV8;
|
|
152
|
+
readonly activeOverrides: readonly StoredContextOverrideV8[];
|
|
77
153
|
readonly canonical: ProtocolContextView;
|
|
78
154
|
};
|
|
79
155
|
|
|
@@ -81,16 +157,20 @@ export type CompiledContextEntry = {
|
|
|
81
157
|
readonly frameId: ProtocolFrameId;
|
|
82
158
|
readonly messageId: MessageId;
|
|
83
159
|
readonly ordinal: number;
|
|
84
|
-
readonly representation: "canonical" | "swapped";
|
|
160
|
+
readonly representation: "canonical" | "surface" | "swapped";
|
|
85
161
|
readonly sourceContentSha256: string;
|
|
86
162
|
readonly message: AgentMessage;
|
|
87
163
|
};
|
|
88
164
|
|
|
89
165
|
export type CompiledContextManifest = {
|
|
90
|
-
readonly
|
|
91
|
-
readonly
|
|
166
|
+
readonly canonicalFrameCount: number;
|
|
167
|
+
readonly canonicalMessageCount: number;
|
|
168
|
+
readonly activeFrameCount: number;
|
|
169
|
+
readonly activeMessageCount: number;
|
|
170
|
+
readonly keepFromOrdinal: number;
|
|
92
171
|
readonly canonicalSequenceHash: string;
|
|
93
172
|
readonly renderedMessageHash: string;
|
|
173
|
+
readonly surfaceSha256: string;
|
|
94
174
|
};
|
|
95
175
|
|
|
96
176
|
export type CompiledRevisionContext = {
|
|
@@ -103,9 +183,15 @@ export type CompiledRevisionContext = {
|
|
|
103
183
|
|
|
104
184
|
export type BuiltContextRequest = {
|
|
105
185
|
readonly canonical: ProtocolContextView;
|
|
106
|
-
readonly revision:
|
|
186
|
+
readonly revision: StoredContextRevisionV8;
|
|
187
|
+
readonly surface: StoredContextSurfaceV8;
|
|
107
188
|
readonly activeOverrides: readonly SwapOverride[];
|
|
108
189
|
readonly compiled: CompiledRevisionContext;
|
|
109
190
|
readonly request: ModelRequestInput;
|
|
110
191
|
readonly candidateUserPromptIncluded: boolean;
|
|
111
192
|
};
|
|
193
|
+
|
|
194
|
+
export type SurfaceRefreshPlan = {
|
|
195
|
+
readonly surface: StoredContextSurfaceV8;
|
|
196
|
+
readonly changes: ContextSurfaceChanges;
|
|
197
|
+
};
|