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
|
@@ -14,8 +14,9 @@ import { CompiledContextError } from "./compiled-context-validator";
|
|
|
14
14
|
import type { SwapOnlyPolicyV1 } from "./context-policy";
|
|
15
15
|
import { ContextProtocolError } from "./context-protocol-validator";
|
|
16
16
|
import type {
|
|
17
|
+
BuiltContextRequest,
|
|
17
18
|
CompiledRevisionContext,
|
|
18
|
-
|
|
19
|
+
StoredContextRevisionV8,
|
|
19
20
|
SwapOverride,
|
|
20
21
|
} from "./context-revision";
|
|
21
22
|
import {
|
|
@@ -48,13 +49,14 @@ export type SwapRevisionPlan = {
|
|
|
48
49
|
readonly policyVersion: "swap-only-v1";
|
|
49
50
|
readonly baseRevisionId: CompiledRevisionContext["revisionId"];
|
|
50
51
|
readonly baseRevisionNumber: number;
|
|
52
|
+
readonly baseKeepFromOrdinal: number;
|
|
51
53
|
readonly baseCanonicalThroughOrdinal: number;
|
|
52
|
-
readonly
|
|
54
|
+
readonly baseActiveOverrideManifestSha256: string;
|
|
53
55
|
readonly basePrefixHash: string;
|
|
54
56
|
readonly requestConfigHash: string;
|
|
55
57
|
readonly toolSchemaHash: string;
|
|
56
58
|
readonly addedOverrides: readonly SwapOverride[];
|
|
57
|
-
readonly
|
|
59
|
+
readonly nextActiveOverrideManifestSha256: string;
|
|
58
60
|
readonly targetTokens: number;
|
|
59
61
|
readonly rawTokensBefore: number;
|
|
60
62
|
readonly rawTokensAfter: number;
|
|
@@ -66,7 +68,8 @@ export type SwapRevisionPlan = {
|
|
|
66
68
|
|
|
67
69
|
export type SwapPlanningInput = {
|
|
68
70
|
readonly active: CompiledRevisionContext;
|
|
69
|
-
readonly revision:
|
|
71
|
+
readonly revision: StoredContextRevisionV8;
|
|
72
|
+
readonly surface: BuiltContextRequest["surface"];
|
|
70
73
|
readonly activeOverrides: readonly SwapOverride[];
|
|
71
74
|
readonly canonical: ProtocolContextView;
|
|
72
75
|
readonly activePrepared: PreparedModelRequest;
|
|
@@ -176,6 +179,7 @@ export class SwapPlanner {
|
|
|
176
179
|
input.canonical,
|
|
177
180
|
input.activeOverrides,
|
|
178
181
|
input.policy,
|
|
182
|
+
input.revision.keepFromOrdinal,
|
|
179
183
|
);
|
|
180
184
|
if (scan.eligible.length === 0) {
|
|
181
185
|
return {
|
|
@@ -206,10 +210,12 @@ export class SwapPlanner {
|
|
|
206
210
|
canonical: input.canonical,
|
|
207
211
|
activeOverrides: input.activeOverrides,
|
|
208
212
|
addedOverrides,
|
|
213
|
+
activeSurface: input.surface,
|
|
209
214
|
});
|
|
210
215
|
const built = this.requestBuilder.build({
|
|
211
216
|
canonical: input.canonical,
|
|
212
217
|
revision: input.revision,
|
|
218
|
+
surface: input.surface,
|
|
213
219
|
activeOverrides: [...input.activeOverrides, ...addedOverrides],
|
|
214
220
|
compiled,
|
|
215
221
|
tools: input.tools,
|
|
@@ -344,6 +350,7 @@ export class SwapPlanner {
|
|
|
344
350
|
canonical: ProtocolContextView,
|
|
345
351
|
activeOverrides: readonly SwapOverride[],
|
|
346
352
|
policy: SwapOnlyPolicyV1,
|
|
353
|
+
keepFromOrdinal: number,
|
|
347
354
|
): CandidateScan {
|
|
348
355
|
const alreadySwapped = new Set(
|
|
349
356
|
activeOverrides.map((override) => override.messageId),
|
|
@@ -367,6 +374,10 @@ export class SwapPlanner {
|
|
|
367
374
|
if (message.role !== "tool") {
|
|
368
375
|
continue;
|
|
369
376
|
}
|
|
377
|
+
if (message.ordinal < keepFromOrdinal) {
|
|
378
|
+
increment(exclusions, "retired_prefix");
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
370
381
|
if (alreadySwapped.has(message.messageId)) {
|
|
371
382
|
increment(exclusions, "already_swapped");
|
|
372
383
|
continue;
|
|
@@ -428,7 +439,7 @@ export function assertPlanBaseCurrent(
|
|
|
428
439
|
plan: SwapRevisionPlan,
|
|
429
440
|
current: {
|
|
430
441
|
readonly active: CompiledRevisionContext;
|
|
431
|
-
readonly revision:
|
|
442
|
+
readonly revision: StoredContextRevisionV8;
|
|
432
443
|
readonly activeOverrides: readonly SwapOverride[];
|
|
433
444
|
readonly activePrepared: PreparedModelRequest;
|
|
434
445
|
},
|
|
@@ -438,8 +449,9 @@ export function assertPlanBaseCurrent(
|
|
|
438
449
|
plan.baseRevisionId !== current.active.revisionId ||
|
|
439
450
|
plan.baseRevisionId !== current.revision.revisionId ||
|
|
440
451
|
plan.baseRevisionNumber !== current.revision.revisionNumber ||
|
|
452
|
+
plan.baseKeepFromOrdinal !== current.revision.keepFromOrdinal ||
|
|
441
453
|
plan.baseCanonicalThroughOrdinal !== current.active.canonicalThroughOrdinal ||
|
|
442
|
-
plan.
|
|
454
|
+
plan.baseActiveOverrideManifestSha256 !==
|
|
443
455
|
activeOverrideManifestHash(current.activeOverrides) ||
|
|
444
456
|
plan.basePrefixHash !== fingerprint.prefixHash ||
|
|
445
457
|
plan.requestConfigHash !== fingerprint.requestConfigHash ||
|
|
@@ -463,14 +475,24 @@ function validatePlanningInput(input: SwapPlanningInput): void {
|
|
|
463
475
|
input.active.sessionId !== input.canonical.sessionId ||
|
|
464
476
|
input.revision.sessionId !== input.canonical.sessionId ||
|
|
465
477
|
input.revision.revisionId !== input.active.revisionId ||
|
|
478
|
+
input.revision.keepFromOrdinal !== input.active.manifest.keepFromOrdinal ||
|
|
466
479
|
input.active.canonicalThroughOrdinal !== input.canonical.messages.length ||
|
|
467
|
-
input.revision.
|
|
480
|
+
input.revision.activeOverrideManifestSha256 !==
|
|
468
481
|
activeOverrideManifestHash(input.activeOverrides)
|
|
469
482
|
) {
|
|
470
483
|
throw new ContextRevisionError(
|
|
471
484
|
"Active revision does not match canonical planning input.",
|
|
472
485
|
);
|
|
473
486
|
}
|
|
487
|
+
if (
|
|
488
|
+
input.activeOverrides.some(
|
|
489
|
+
(override) => override.ordinal < input.revision.keepFromOrdinal,
|
|
490
|
+
)
|
|
491
|
+
) {
|
|
492
|
+
throw new ContextRevisionError(
|
|
493
|
+
"Active swap planning input contains a retired override.",
|
|
494
|
+
);
|
|
495
|
+
}
|
|
474
496
|
if (
|
|
475
497
|
input.forcedTargetTokens !== undefined &&
|
|
476
498
|
(!Number.isSafeInteger(input.forcedTargetTokens) || input.forcedTargetTokens < 0)
|
|
@@ -654,7 +676,7 @@ function createPlan(input: {
|
|
|
654
676
|
guardedTokensAfter: number;
|
|
655
677
|
}): SwapRevisionPlan {
|
|
656
678
|
const planningInput = input.input;
|
|
657
|
-
const
|
|
679
|
+
const nextActiveOverrideManifestSha256 = activeOverrideManifestHash([
|
|
658
680
|
...planningInput.activeOverrides,
|
|
659
681
|
...input.addedOverrides,
|
|
660
682
|
]);
|
|
@@ -663,8 +685,10 @@ function createPlan(input: {
|
|
|
663
685
|
policyVersion: "swap-only-v1",
|
|
664
686
|
baseRevisionId: planningInput.active.revisionId,
|
|
665
687
|
baseRevisionNumber: planningInput.revision.revisionNumber,
|
|
688
|
+
baseKeepFromOrdinal: planningInput.revision.keepFromOrdinal,
|
|
666
689
|
baseCanonicalThroughOrdinal: planningInput.active.canonicalThroughOrdinal,
|
|
667
|
-
|
|
690
|
+
baseActiveOverrideManifestSha256:
|
|
691
|
+
planningInput.revision.activeOverrideManifestSha256,
|
|
668
692
|
basePrefixHash: input.activeFingerprint.prefixHash,
|
|
669
693
|
requestConfigHash: input.activeFingerprint.requestConfigHash,
|
|
670
694
|
toolSchemaHash: input.activeFingerprint.toolSchemaHash,
|
|
@@ -673,7 +697,7 @@ function createPlan(input: {
|
|
|
673
697
|
originalContentSha256: override.originalContentSha256,
|
|
674
698
|
renderedContentSha256: override.renderedContentSha256,
|
|
675
699
|
})),
|
|
676
|
-
|
|
700
|
+
nextActiveOverrideManifestSha256,
|
|
677
701
|
targetTokens: input.targetTokens,
|
|
678
702
|
projectedPrefixHash: input.projectedFingerprint.prefixHash,
|
|
679
703
|
} as const;
|
|
@@ -10,7 +10,7 @@ export class ObservationTextLog implements EventSink {
|
|
|
10
10
|
constructor(private readonly filePath: string) {}
|
|
11
11
|
|
|
12
12
|
async append(event: AgentEvent): Promise<void> {
|
|
13
|
-
const text =
|
|
13
|
+
const text = renderObservationLogEvent(event);
|
|
14
14
|
if (text === undefined) {
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
@@ -19,7 +19,7 @@ export class ObservationTextLog implements EventSink {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
function
|
|
22
|
+
export function renderObservationLogEvent(event: AgentEvent): string | undefined {
|
|
23
23
|
switch (event.type) {
|
|
24
24
|
case "session.started":
|
|
25
25
|
return renderSessionStarted(event);
|
|
@@ -72,7 +72,7 @@ function renderTurnStarted(
|
|
|
72
72
|
return [
|
|
73
73
|
`## Turn ${event.turnNumber ?? ""} - Prompt`,
|
|
74
74
|
"",
|
|
75
|
-
event.data.userPrompt,
|
|
75
|
+
event.data.userPrompt.text,
|
|
76
76
|
"",
|
|
77
77
|
"---",
|
|
78
78
|
"",
|
|
@@ -24,7 +24,7 @@ export class StdoutEventPrinter implements EventSink {
|
|
|
24
24
|
break;
|
|
25
25
|
case "session.resumed":
|
|
26
26
|
this.stdout.write(
|
|
27
|
-
`session.resumed sessionId=${event.sessionId} openCount=${event.data.openCount} recallIndexRebuilt=${event.data.recallIndexRebuilt}\n`,
|
|
27
|
+
`session.resumed sessionId=${event.sessionId} openCount=${event.data.openCount} recallIndexRebuilt=${event.data.recallIndexRebuilt}${event.data.contextRefresh === undefined ? "" : ` contextRevision=${event.data.contextRefresh.revisionNumber}`}\n`,
|
|
28
28
|
);
|
|
29
29
|
break;
|
|
30
30
|
case "session.interrupted_frame_recovered":
|
|
@@ -67,12 +67,24 @@ export class StdoutEventPrinter implements EventSink {
|
|
|
67
67
|
break;
|
|
68
68
|
case "context.revision.started":
|
|
69
69
|
this.stdout.write(
|
|
70
|
-
|
|
70
|
+
event.data.strategy === "swap"
|
|
71
|
+
? `context.revision.started reason=${event.data.reason} policy=${event.data.policyVersion}\n`
|
|
72
|
+
: event.data.strategy === "surface_refresh"
|
|
73
|
+
? `context.revision.started reason=${event.data.reason} strategy=surface_refresh changed=${event.data.changed.join(",")}\n`
|
|
74
|
+
: event.data.strategy === "skills_update"
|
|
75
|
+
? `context.revision.started reason=${event.data.reason} strategy=skills_update names=${event.data.names.join(",")}\n`
|
|
76
|
+
: `context.revision.started reason=${event.data.reason} strategy=retire_prefix policy=${event.data.policyVersion}\n`,
|
|
71
77
|
);
|
|
72
78
|
break;
|
|
73
79
|
case "context.revision.finished":
|
|
74
80
|
this.stdout.write(
|
|
75
|
-
|
|
81
|
+
event.data.strategy === "swap"
|
|
82
|
+
? `context.revision.finished outcome=${event.data.outcome} revision=${event.data.revisionNumber ?? event.data.baseRevisionNumber} added=${event.data.addedOverrideCount} before=${event.data.guardedTokensBefore} after=${event.data.guardedTokensAfter ?? "n/a"}\n`
|
|
83
|
+
: event.data.strategy === "surface_refresh"
|
|
84
|
+
? `context.revision.finished strategy=surface_refresh revision=${event.data.revisionNumber} changed=${event.data.changed.join(",")} tools=${event.data.toolCountBefore}->${event.data.toolCountAfter}\n`
|
|
85
|
+
: event.data.strategy === "skills_update"
|
|
86
|
+
? `context.revision.finished strategy=skills_update revision=${event.data.revisionNumber} activated=${event.data.activated.join(",")} refreshed=${event.data.refreshed.join(",")} deactivated=${event.data.deactivated.join(",")} unavailable=${event.data.unavailable.join(",")}\n`
|
|
87
|
+
: `context.revision.finished strategy=retire_prefix outcome=${event.data.outcome} revision=${event.data.revisionNumber ?? event.data.baseRevisionNumber} retired_turns=${event.data.retiredTurnCount} before=${event.data.guardedTokensBefore} after=${event.data.guardedTokensAfter ?? "n/a"}\n`,
|
|
76
88
|
);
|
|
77
89
|
break;
|
|
78
90
|
case "context.revision.failed":
|
|
@@ -151,6 +163,16 @@ export class StdoutEventPrinter implements EventSink {
|
|
|
151
163
|
case "session.finished":
|
|
152
164
|
this.stdout.write(`session.finished reason=${event.data.reason}\n`);
|
|
153
165
|
break;
|
|
166
|
+
case "skills.catalog.loaded":
|
|
167
|
+
this.stdout.write(
|
|
168
|
+
`skills.catalog.loaded available=${event.data.availableCount} active=${event.data.activeNames.join(",")} shadowed=${event.data.shadowedNames.join(",")}\n`,
|
|
169
|
+
);
|
|
170
|
+
break;
|
|
171
|
+
case "skills.updated":
|
|
172
|
+
this.stdout.write(
|
|
173
|
+
`skills.updated reason=${event.data.reason} activated=${event.data.activated.join(",")} refreshed=${event.data.refreshed.join(",")} deactivated=${event.data.deactivated.join(",")} unavailable=${event.data.unavailable.join(",")}\n`,
|
|
174
|
+
);
|
|
175
|
+
break;
|
|
154
176
|
default:
|
|
155
177
|
break;
|
|
156
178
|
}
|
|
@@ -168,6 +190,8 @@ function formatToolRawResult(call: ToolCall, raw: ToolRawResult): string[] {
|
|
|
168
190
|
case "task_list":
|
|
169
191
|
case "task_stop":
|
|
170
192
|
return optionalLine(formatTaskResult(call, raw));
|
|
193
|
+
case "skill":
|
|
194
|
+
return [formatSkillResult(raw)];
|
|
171
195
|
case "read":
|
|
172
196
|
case "glob":
|
|
173
197
|
case "grep":
|
|
@@ -182,6 +206,18 @@ function formatToolRawResult(call: ToolCall, raw: ToolRawResult): string[] {
|
|
|
182
206
|
}
|
|
183
207
|
}
|
|
184
208
|
|
|
209
|
+
function formatSkillResult(raw: Extract<ToolRawResult, { kind: "skill" }>): string {
|
|
210
|
+
if (!raw.ok) {
|
|
211
|
+
return `skill ${raw.name || "(unknown)"} failed -> ${boundedToolError(raw.error)}\n`;
|
|
212
|
+
}
|
|
213
|
+
return `skill ${raw.name} ${raw.status.replaceAll("_", " ")}\n`;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function boundedToolError(error: string): string {
|
|
217
|
+
const limit = 1_000;
|
|
218
|
+
return error.length <= limit ? error : `${error.slice(0, limit)}…`;
|
|
219
|
+
}
|
|
220
|
+
|
|
185
221
|
function optionalLine(line: string | undefined): string[] {
|
|
186
222
|
return line === undefined ? [] : [line];
|
|
187
223
|
}
|
package/src/events/types.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
TurnCancellation,
|
|
6
6
|
TurnIdentity,
|
|
7
7
|
} from "../agent/types";
|
|
8
|
+
import type { UserPromptProjection } from "../agent/user-prompt-projection";
|
|
8
9
|
import type {
|
|
9
10
|
IterationId,
|
|
10
11
|
ProtocolFrameId,
|
|
@@ -25,6 +26,7 @@ import type {
|
|
|
25
26
|
ProjectInstructionFileName,
|
|
26
27
|
ProjectInstructionManifest,
|
|
27
28
|
} from "../instructions/project-instructions";
|
|
29
|
+
import type { ContextSurfaceComponent } from "../context/context-surface";
|
|
28
30
|
|
|
29
31
|
export type SessionStartedData = {
|
|
30
32
|
workspaceRoot: string;
|
|
@@ -44,43 +46,165 @@ export type ContextUsageUpdatedData = {
|
|
|
44
46
|
snapshot: ContextUsageSnapshot;
|
|
45
47
|
};
|
|
46
48
|
|
|
47
|
-
export type ContextRevisionStartedData =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
export type ContextRevisionStartedData =
|
|
50
|
+
| {
|
|
51
|
+
strategy: "swap";
|
|
52
|
+
reason: "manual" | "runtime_pressure";
|
|
53
|
+
policyVersion: "swap-only-v1";
|
|
54
|
+
rendererFormat: "swap-observation-v1";
|
|
55
|
+
qualificationId?: string;
|
|
56
|
+
}
|
|
57
|
+
| {
|
|
58
|
+
strategy: "surface_refresh";
|
|
59
|
+
reason: "resume";
|
|
60
|
+
baseRevisionNumber: number;
|
|
61
|
+
changed: readonly ContextSurfaceComponent[];
|
|
62
|
+
}
|
|
63
|
+
| {
|
|
64
|
+
strategy: "retire_prefix";
|
|
65
|
+
reason: "manual" | "runtime_pressure";
|
|
66
|
+
policyVersion: "recall-first-retirement-v1";
|
|
67
|
+
baseRevisionNumber: number;
|
|
68
|
+
qualificationId?: string;
|
|
69
|
+
}
|
|
70
|
+
| {
|
|
71
|
+
strategy: "skills_update";
|
|
72
|
+
reason: "activation" | "resume";
|
|
73
|
+
baseRevisionNumber: number;
|
|
74
|
+
names: readonly string[];
|
|
75
|
+
};
|
|
53
76
|
|
|
54
|
-
export type ContextRevisionFinishedData =
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
export type ContextRevisionFinishedData =
|
|
78
|
+
| {
|
|
79
|
+
strategy: "swap";
|
|
80
|
+
reason: "manual" | "runtime_pressure";
|
|
81
|
+
policyVersion: "swap-only-v1";
|
|
82
|
+
outcome:
|
|
83
|
+
| "below_trigger"
|
|
84
|
+
| "below_target"
|
|
85
|
+
| "no_eligible_candidates"
|
|
86
|
+
| "target_reached"
|
|
87
|
+
| "insufficient_candidates";
|
|
88
|
+
baseRevisionNumber: number;
|
|
89
|
+
revisionNumber?: number;
|
|
90
|
+
addedOverrideCount: number;
|
|
91
|
+
activeOverrideCount: number;
|
|
92
|
+
originalObservationBytes: number;
|
|
93
|
+
projectedObservationBytes: number;
|
|
94
|
+
rawTokensBefore: number;
|
|
95
|
+
rawTokensAfter?: number;
|
|
96
|
+
guardedTokensBefore: number;
|
|
97
|
+
guardedTokensAfter?: number;
|
|
98
|
+
targetTokens: number;
|
|
99
|
+
planHash?: string;
|
|
100
|
+
durationMs: number;
|
|
101
|
+
qualificationId?: string;
|
|
102
|
+
}
|
|
103
|
+
| {
|
|
104
|
+
strategy: "surface_refresh";
|
|
105
|
+
reason: "resume";
|
|
106
|
+
baseRevisionNumber: number;
|
|
107
|
+
revisionNumber: number;
|
|
108
|
+
changed: readonly ContextSurfaceComponent[];
|
|
109
|
+
toolCountBefore: number;
|
|
110
|
+
toolCountAfter: number;
|
|
111
|
+
measuredAnchorCleared: true;
|
|
112
|
+
durationMs: number;
|
|
113
|
+
}
|
|
114
|
+
| {
|
|
115
|
+
strategy: "retire_prefix";
|
|
116
|
+
reason: "manual" | "runtime_pressure";
|
|
117
|
+
policyVersion: "recall-first-retirement-v1";
|
|
118
|
+
outcome:
|
|
119
|
+
| "below_target"
|
|
120
|
+
| "no_complete_prefix"
|
|
121
|
+
| "target_reached"
|
|
122
|
+
| "retirement_floor";
|
|
123
|
+
baseRevisionNumber: number;
|
|
124
|
+
revisionNumber?: number;
|
|
125
|
+
previousKeepFromOrdinal: number;
|
|
126
|
+
keepFromOrdinal: number;
|
|
127
|
+
retiredTurnCount: number;
|
|
128
|
+
retiredFrameCount: number;
|
|
129
|
+
retiredMessageCount: number;
|
|
130
|
+
activeOverrideCount: number;
|
|
131
|
+
rawTokensBefore?: number;
|
|
132
|
+
rawTokensAfter?: number;
|
|
133
|
+
guardedTokensBefore: number;
|
|
134
|
+
guardedTokensAfter?: number;
|
|
135
|
+
targetTokens: number;
|
|
136
|
+
planHash?: string;
|
|
137
|
+
planningDurationMs: number;
|
|
138
|
+
validationDurationMs?: number;
|
|
139
|
+
transactionDurationMs?: number;
|
|
140
|
+
activationDurationMs?: number;
|
|
141
|
+
durationMs: number;
|
|
142
|
+
qualificationId?: string;
|
|
143
|
+
}
|
|
144
|
+
| {
|
|
145
|
+
strategy: "skills_update";
|
|
146
|
+
reason: "activation" | "resume";
|
|
147
|
+
baseRevisionNumber: number;
|
|
148
|
+
revisionNumber: number;
|
|
149
|
+
activated: readonly string[];
|
|
150
|
+
refreshed: readonly string[];
|
|
151
|
+
deactivated: readonly string[];
|
|
152
|
+
unavailable: readonly string[];
|
|
153
|
+
addedOverrideCount: number;
|
|
154
|
+
measuredAnchorCleared: true;
|
|
155
|
+
durationMs: number;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export type ContextRevisionFailedData =
|
|
159
|
+
| {
|
|
160
|
+
strategy: "swap";
|
|
161
|
+
reason: "manual" | "runtime_pressure";
|
|
162
|
+
stage: "snapshot" | "plan" | "validate" | "commit" | "activate";
|
|
163
|
+
errorCode: string;
|
|
164
|
+
error: string;
|
|
165
|
+
qualificationId?: string;
|
|
166
|
+
}
|
|
167
|
+
| {
|
|
168
|
+
strategy: "surface_refresh";
|
|
169
|
+
reason: "resume";
|
|
170
|
+
stage: "prepare" | "commit" | "activate";
|
|
171
|
+
errorCode: string;
|
|
172
|
+
error: string;
|
|
173
|
+
committed: boolean;
|
|
174
|
+
}
|
|
175
|
+
| {
|
|
176
|
+
strategy: "retire_prefix";
|
|
177
|
+
reason: "manual" | "runtime_pressure";
|
|
178
|
+
stage: "snapshot" | "plan" | "validate" | "commit" | "activate";
|
|
179
|
+
errorCode: string;
|
|
180
|
+
error: string;
|
|
181
|
+
committed: boolean;
|
|
182
|
+
qualificationId?: string;
|
|
183
|
+
}
|
|
184
|
+
| {
|
|
185
|
+
strategy: "skills_update";
|
|
186
|
+
reason: "activation" | "resume";
|
|
187
|
+
stage: "prepare" | "commit" | "activate";
|
|
188
|
+
errorCode: string;
|
|
189
|
+
error: string;
|
|
190
|
+
committed: boolean;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
export type SkillsCatalogLoadedData = {
|
|
194
|
+
availableCount: number;
|
|
195
|
+
projectCount: number;
|
|
196
|
+
userCount: number;
|
|
197
|
+
activeNames: readonly string[];
|
|
198
|
+
shadowedNames: readonly string[];
|
|
76
199
|
};
|
|
77
200
|
|
|
78
|
-
export type
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
201
|
+
export type SkillsUpdatedData = {
|
|
202
|
+
reason: "activation" | "resume";
|
|
203
|
+
activated: readonly string[];
|
|
204
|
+
refreshed: readonly string[];
|
|
205
|
+
deactivated: readonly string[];
|
|
206
|
+
unavailable: readonly string[];
|
|
207
|
+
revisionNumber?: number;
|
|
84
208
|
};
|
|
85
209
|
|
|
86
210
|
export type ContextShadowPlannedData = {
|
|
@@ -131,7 +255,16 @@ export type SessionResumedData = {
|
|
|
131
255
|
recoveredFrameId?: ProtocolFrameId;
|
|
132
256
|
syntheticCompletionCount: number;
|
|
133
257
|
recallIndexRebuilt: boolean;
|
|
258
|
+
contextProfile: ModelContextProfile;
|
|
259
|
+
contextBudget: ModelContextBudget;
|
|
134
260
|
projectInstructionFile?: ProjectInstructionFileName;
|
|
261
|
+
contextRefresh?: {
|
|
262
|
+
previousRevisionNumber: number;
|
|
263
|
+
revisionNumber: number;
|
|
264
|
+
changed: readonly ContextSurfaceComponent[];
|
|
265
|
+
toolCountBefore: number;
|
|
266
|
+
toolCountAfter: number;
|
|
267
|
+
};
|
|
135
268
|
};
|
|
136
269
|
|
|
137
270
|
export type InterruptedFrameRecoveredData = {
|
|
@@ -152,7 +285,7 @@ export type AgentEventDataMap = {
|
|
|
152
285
|
"session.resumed": SessionResumedData;
|
|
153
286
|
"session.interrupted_frame_recovered": InterruptedFrameRecoveredData;
|
|
154
287
|
"session.finished": SessionFinishedData;
|
|
155
|
-
"turn.started": { userPrompt:
|
|
288
|
+
"turn.started": { userPrompt: UserPromptProjection };
|
|
156
289
|
"turn.finished": TurnFinishedData;
|
|
157
290
|
"turn.failed": { error: string };
|
|
158
291
|
"turn.cancelled": { cancellation: TurnCancellation };
|
|
@@ -165,6 +298,8 @@ export type AgentEventDataMap = {
|
|
|
165
298
|
"context.revision.failed": ContextRevisionFailedData;
|
|
166
299
|
"context.shadow.planned": ContextShadowPlannedData;
|
|
167
300
|
"context.shadow.failed": ContextShadowFailedData;
|
|
301
|
+
"skills.catalog.loaded": SkillsCatalogLoadedData;
|
|
302
|
+
"skills.updated": SkillsUpdatedData;
|
|
168
303
|
"assistant.progress": { content: string };
|
|
169
304
|
"tool.started": { call: ToolCall };
|
|
170
305
|
"tool.raw_result": { call: ToolCall; raw: ToolRawResult };
|
|
@@ -237,6 +372,8 @@ export type AgentEventInput =
|
|
|
237
372
|
| "context.revision.started"
|
|
238
373
|
| "context.revision.finished"
|
|
239
374
|
| "context.revision.failed"
|
|
375
|
+
| "skills.catalog.loaded"
|
|
376
|
+
| "skills.updated"
|
|
240
377
|
>
|
|
241
378
|
| SessionEventInput<"mcp.server.connected" | "mcp.server.failed">
|
|
242
379
|
| SessionEventInput<"diagnostic.sink_failed">
|
package/src/ids/runtime-id.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createUuidV7 } from "./uuid-v7";
|
|
2
|
+
import type { ImageAttachmentId } from "../image/image-types";
|
|
2
3
|
|
|
3
4
|
export type RuntimeId<Name extends string> = string & {
|
|
4
5
|
readonly __runtimeId: Name;
|
|
@@ -11,6 +12,7 @@ export type ToolCallId = RuntimeId<"tool-call">;
|
|
|
11
12
|
export type MessageId = RuntimeId<"message">;
|
|
12
13
|
export type ProtocolFrameId = RuntimeId<"protocol-frame">;
|
|
13
14
|
export type ContextRevisionId = RuntimeId<"context-revision">;
|
|
15
|
+
export type ContextSurfaceId = RuntimeId<"context-surface">;
|
|
14
16
|
|
|
15
17
|
export type RuntimeIdFactory = {
|
|
16
18
|
createSessionId(): SessionId;
|
|
@@ -20,6 +22,8 @@ export type RuntimeIdFactory = {
|
|
|
20
22
|
createMessageId(): MessageId;
|
|
21
23
|
createProtocolFrameId(): ProtocolFrameId;
|
|
22
24
|
createContextRevisionId(): ContextRevisionId;
|
|
25
|
+
createContextSurfaceId(): ContextSurfaceId;
|
|
26
|
+
createImageAttachmentId(): ImageAttachmentId;
|
|
23
27
|
};
|
|
24
28
|
|
|
25
29
|
export const runtimeIdFactory: RuntimeIdFactory = {
|
|
@@ -30,6 +34,8 @@ export const runtimeIdFactory: RuntimeIdFactory = {
|
|
|
30
34
|
createMessageId: () => createUuidV7() as MessageId,
|
|
31
35
|
createProtocolFrameId: () => createUuidV7() as ProtocolFrameId,
|
|
32
36
|
createContextRevisionId: () => createUuidV7() as ContextRevisionId,
|
|
37
|
+
createContextSurfaceId: () => createUuidV7() as ContextSurfaceId,
|
|
38
|
+
createImageAttachmentId: () => createUuidV7() as ImageAttachmentId,
|
|
33
39
|
};
|
|
34
40
|
|
|
35
41
|
const canonicalUuidV7Pattern =
|
package/src/ids/uuid-v7.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { v7 as uuidv7 } from "uuid";
|
|
2
2
|
|
|
3
|
+
const CANONICAL_UUID_V7_PATTERN =
|
|
4
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
5
|
+
|
|
3
6
|
export function createUuidV7(): string {
|
|
4
7
|
return uuidv7();
|
|
5
8
|
}
|
|
9
|
+
|
|
10
|
+
export function isCanonicalUuidV7(value: string): boolean {
|
|
11
|
+
return CANONICAL_UUID_V7_PATTERN.test(value);
|
|
12
|
+
}
|