@wix/pathgrade 0.29.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/bin/pathgrade.js +2 -0
- package/dist/affected/anchor.d.ts +18 -0
- package/dist/affected/anchor.js +42 -0
- package/dist/affected/config.d.ts +25 -0
- package/dist/affected/config.js +98 -0
- package/dist/affected/format.d.ts +45 -0
- package/dist/affected/format.js +87 -0
- package/dist/affected/git.d.ts +33 -0
- package/dist/affected/git.js +68 -0
- package/dist/affected/glob.d.ts +17 -0
- package/dist/affected/glob.js +25 -0
- package/dist/affected/meta.d.ts +26 -0
- package/dist/affected/meta.js +158 -0
- package/dist/affected/select.d.ts +30 -0
- package/dist/affected/select.js +101 -0
- package/dist/affected/sidecar.d.ts +32 -0
- package/dist/affected/sidecar.js +86 -0
- package/dist/affected/types.d.ts +43 -0
- package/dist/affected/types.js +7 -0
- package/dist/agents/claude/ask-user-answer-store.d.ts +28 -0
- package/dist/agents/claude/ask-user-answer-store.js +29 -0
- package/dist/agents/claude/ask-user-bridge.d.ts +56 -0
- package/dist/agents/claude/ask-user-bridge.js +162 -0
- package/dist/agents/claude/sdk-message-projector.d.ts +43 -0
- package/dist/agents/claude/sdk-message-projector.js +208 -0
- package/dist/agents/claude/sdk-options.d.ts +52 -0
- package/dist/agents/claude/sdk-options.js +79 -0
- package/dist/agents/claude.d.ts +56 -0
- package/dist/agents/claude.js +143 -0
- package/dist/agents/codex-app-server/agent.d.ts +35 -0
- package/dist/agents/codex-app-server/agent.js +388 -0
- package/dist/agents/codex-app-server/fixtures/app-server-client.d.ts +19 -0
- package/dist/agents/codex-app-server/fixtures/app-server-client.js +104 -0
- package/dist/agents/codex-app-server/fixtures/run-gate.d.ts +25 -0
- package/dist/agents/codex-app-server/fixtures/run-gate.js +48 -0
- package/dist/agents/codex-app-server/protocol/ClientRequest.d.ts +27 -0
- package/dist/agents/codex-app-server/protocol/ClientRequest.js +7 -0
- package/dist/agents/codex-app-server/protocol/DynamicToolCallParams.d.ts +9 -0
- package/dist/agents/codex-app-server/protocol/DynamicToolCallParams.js +4 -0
- package/dist/agents/codex-app-server/protocol/GrantedPermissionProfile.d.ts +6 -0
- package/dist/agents/codex-app-server/protocol/GrantedPermissionProfile.js +7 -0
- package/dist/agents/codex-app-server/protocol/McpElicitationRequestParams.d.ts +23 -0
- package/dist/agents/codex-app-server/protocol/McpElicitationRequestParams.js +8 -0
- package/dist/agents/codex-app-server/protocol/Op.d.ts +11 -0
- package/dist/agents/codex-app-server/protocol/Op.js +5 -0
- package/dist/agents/codex-app-server/protocol/PermissionsRequestApprovalParams.d.ts +10 -0
- package/dist/agents/codex-app-server/protocol/PermissionsRequestApprovalParams.js +6 -0
- package/dist/agents/codex-app-server/protocol/PermissionsRequestApprovalResponse.d.ts +15 -0
- package/dist/agents/codex-app-server/protocol/PermissionsRequestApprovalResponse.js +4 -0
- package/dist/agents/codex-app-server/protocol/SandboxMode.d.ts +1 -0
- package/dist/agents/codex-app-server/protocol/SandboxMode.js +4 -0
- package/dist/agents/codex-app-server/protocol/ServerRequest.d.ts +42 -0
- package/dist/agents/codex-app-server/protocol/ServerRequest.js +7 -0
- package/dist/agents/codex-app-server/protocol/ThreadStartParams.d.ts +45 -0
- package/dist/agents/codex-app-server/protocol/ThreadStartParams.js +10 -0
- package/dist/agents/codex-app-server/protocol/ToolRequestUserInputAnswer.d.ts +6 -0
- package/dist/agents/codex-app-server/protocol/ToolRequestUserInputAnswer.js +4 -0
- package/dist/agents/codex-app-server/protocol/ToolRequestUserInputOption.d.ts +7 -0
- package/dist/agents/codex-app-server/protocol/ToolRequestUserInputOption.js +4 -0
- package/dist/agents/codex-app-server/protocol/ToolRequestUserInputParams.d.ts +10 -0
- package/dist/agents/codex-app-server/protocol/ToolRequestUserInputParams.js +4 -0
- package/dist/agents/codex-app-server/protocol/ToolRequestUserInputQuestion.d.ts +12 -0
- package/dist/agents/codex-app-server/protocol/ToolRequestUserInputQuestion.js +4 -0
- package/dist/agents/codex-app-server/protocol/ToolRequestUserInputResponse.d.ts +9 -0
- package/dist/agents/codex-app-server/protocol/ToolRequestUserInputResponse.js +4 -0
- package/dist/agents/codex-app-server/protocol/TurnCompletedNotification.d.ts +5 -0
- package/dist/agents/codex-app-server/protocol/TurnCompletedNotification.js +4 -0
- package/dist/agents/codex-app-server/protocol/index.d.ts +16 -0
- package/dist/agents/codex-app-server/protocol/index.js +11 -0
- package/dist/agents/codex-app-server/transport.d.ts +84 -0
- package/dist/agents/codex-app-server/transport.js +246 -0
- package/dist/agents/codex-app-server/wire-translators.d.ts +19 -0
- package/dist/agents/codex-app-server/wire-translators.js +52 -0
- package/dist/agents/codex.d.ts +7 -0
- package/dist/agents/codex.js +164 -0
- package/dist/agents/cursor.d.ts +39 -0
- package/dist/agents/cursor.js +233 -0
- package/dist/agents/registry.d.ts +17 -0
- package/dist/agents/registry.js +27 -0
- package/dist/agents/transcript-agent.d.ts +14 -0
- package/dist/agents/transcript-agent.js +59 -0
- package/dist/analytics/engine.d.ts +18 -0
- package/dist/analytics/engine.js +66 -0
- package/dist/commands/affected.d.ts +31 -0
- package/dist/commands/affected.js +150 -0
- package/dist/commands/analyze.d.ts +21 -0
- package/dist/commands/analyze.js +167 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.js +242 -0
- package/dist/commands/preview-reactions.d.ts +10 -0
- package/dist/commands/preview-reactions.js +88 -0
- package/dist/commands/preview.d.ts +5 -0
- package/dist/commands/preview.js +17 -0
- package/dist/commands/report.d.ts +39 -0
- package/dist/commands/report.js +108 -0
- package/dist/commands/run-args.d.ts +22 -0
- package/dist/commands/run-args.js +69 -0
- package/dist/commands/run-changed.d.ts +26 -0
- package/dist/commands/run-changed.js +138 -0
- package/dist/commands/validate.d.ts +13 -0
- package/dist/commands/validate.js +233 -0
- package/dist/core/mcp-mock.d.ts +3 -0
- package/dist/core/mcp-mock.js +23 -0
- package/dist/core/mcp-mock.types.d.ts +15 -0
- package/dist/core/mcp-mock.types.js +1 -0
- package/dist/core/skills.d.ts +15 -0
- package/dist/core/skills.js +76 -0
- package/dist/evals/discovery.d.ts +7 -0
- package/dist/evals/discovery.js +69 -0
- package/dist/mcp-mock-server.d.ts +1 -0
- package/dist/mcp-mock-server.js +116 -0
- package/dist/pathgrade.d.ts +10 -0
- package/dist/pathgrade.js +243 -0
- package/dist/plugin/index.d.ts +9 -0
- package/dist/plugin/index.js +81 -0
- package/dist/plugin/lifecycle.d.ts +45 -0
- package/dist/plugin/lifecycle.js +146 -0
- package/dist/plugin/reporter.d.ts +36 -0
- package/dist/plugin/reporter.js +275 -0
- package/dist/plugin/setup.d.ts +1 -0
- package/dist/plugin/setup.js +3 -0
- package/dist/providers/copy-filter.d.ts +18 -0
- package/dist/providers/copy-filter.js +66 -0
- package/dist/providers/credentials.d.ts +36 -0
- package/dist/providers/credentials.js +202 -0
- package/dist/providers/mcp-config.d.ts +34 -0
- package/dist/providers/mcp-config.js +55 -0
- package/dist/providers/sandbox-exec.d.ts +8 -0
- package/dist/providers/sandbox-exec.js +82 -0
- package/dist/providers/sandbox.d.ts +22 -0
- package/dist/providers/sandbox.js +158 -0
- package/dist/providers/sandboxed-claude-spawn.d.ts +24 -0
- package/dist/providers/sandboxed-claude-spawn.js +57 -0
- package/dist/providers/workspace.d.ts +15 -0
- package/dist/providers/workspace.js +73 -0
- package/dist/reporters/browser.d.ts +2 -0
- package/dist/reporters/browser.js +85 -0
- package/dist/reporters/cli.d.ts +2 -0
- package/dist/reporters/cli.js +131 -0
- package/dist/reporters/diagnostics.d.ts +46 -0
- package/dist/reporters/diagnostics.js +147 -0
- package/dist/reporters/github-comment.d.ts +67 -0
- package/dist/reporters/github-comment.js +252 -0
- package/dist/reporters/loader.d.ts +8 -0
- package/dist/reporters/loader.js +36 -0
- package/dist/reporters/results-path.d.ts +2 -0
- package/dist/reporters/results-path.js +10 -0
- package/dist/reporters/verbose-emitter.d.ts +69 -0
- package/dist/reporters/verbose-emitter.js +103 -0
- package/dist/sdk/agent-crash.d.ts +19 -0
- package/dist/sdk/agent-crash.js +20 -0
- package/dist/sdk/agent-resolution.d.ts +12 -0
- package/dist/sdk/agent-resolution.js +21 -0
- package/dist/sdk/agent-result-log.d.ts +19 -0
- package/dist/sdk/agent-result-log.js +45 -0
- package/dist/sdk/agent.d.ts +4 -0
- package/dist/sdk/agent.js +354 -0
- package/dist/sdk/ask-bus/bus.d.ts +21 -0
- package/dist/sdk/ask-bus/bus.js +129 -0
- package/dist/sdk/ask-bus/handler.d.ts +31 -0
- package/dist/sdk/ask-bus/handler.js +244 -0
- package/dist/sdk/ask-bus/parsers.d.ts +9 -0
- package/dist/sdk/ask-bus/parsers.js +30 -0
- package/dist/sdk/ask-bus/projection.d.ts +26 -0
- package/dist/sdk/ask-bus/projection.js +45 -0
- package/dist/sdk/ask-bus/types.d.ts +69 -0
- package/dist/sdk/ask-bus/types.js +1 -0
- package/dist/sdk/chat.d.ts +29 -0
- package/dist/sdk/chat.js +93 -0
- package/dist/sdk/conversation-window.d.ts +14 -0
- package/dist/sdk/conversation-window.js +38 -0
- package/dist/sdk/converse.d.ts +42 -0
- package/dist/sdk/converse.js +329 -0
- package/dist/sdk/eval-runtime.d.ts +10 -0
- package/dist/sdk/eval-runtime.js +17 -0
- package/dist/sdk/evaluate.d.ts +13 -0
- package/dist/sdk/evaluate.js +325 -0
- package/dist/sdk/index.d.ts +31 -0
- package/dist/sdk/index.js +20 -0
- package/dist/sdk/judge-pipeline.d.ts +7 -0
- package/dist/sdk/judge-pipeline.js +178 -0
- package/dist/sdk/judge-prompt-builder.d.ts +7 -0
- package/dist/sdk/judge-prompt-builder.js +76 -0
- package/dist/sdk/judge-tool-runner.d.ts +19 -0
- package/dist/sdk/judge-tool-runner.js +51 -0
- package/dist/sdk/judge-tool-session.d.ts +47 -0
- package/dist/sdk/judge-tool-session.js +213 -0
- package/dist/sdk/judge-tools.d.ts +29 -0
- package/dist/sdk/judge-tools.js +283 -0
- package/dist/sdk/managed-session.d.ts +50 -0
- package/dist/sdk/managed-session.js +110 -0
- package/dist/sdk/persona.d.ts +5 -0
- package/dist/sdk/persona.js +33 -0
- package/dist/sdk/reaction-loader.d.ts +4 -0
- package/dist/sdk/reaction-loader.js +119 -0
- package/dist/sdk/reaction-preview.d.ts +6 -0
- package/dist/sdk/reaction-preview.js +94 -0
- package/dist/sdk/run-scorer.d.ts +10 -0
- package/dist/sdk/run-scorer.js +124 -0
- package/dist/sdk/runtime-policy.d.ts +21 -0
- package/dist/sdk/runtime-policy.js +89 -0
- package/dist/sdk/scorer-utils.d.ts +6 -0
- package/dist/sdk/scorer-utils.js +39 -0
- package/dist/sdk/scorers.d.ts +64 -0
- package/dist/sdk/scorers.js +80 -0
- package/dist/sdk/snapshots.d.ts +41 -0
- package/dist/sdk/snapshots.js +148 -0
- package/dist/sdk/types.d.ts +416 -0
- package/dist/sdk/types.js +17 -0
- package/dist/sdk/visible-turn.d.ts +4 -0
- package/dist/sdk/visible-turn.js +23 -0
- package/dist/tool-events.d.ts +45 -0
- package/dist/tool-events.js +167 -0
- package/dist/types.d.ts +372 -0
- package/dist/types.js +37 -0
- package/dist/utils/cli.d.ts +55 -0
- package/dist/utils/cli.js +131 -0
- package/dist/utils/env.d.ts +8 -0
- package/dist/utils/env.js +26 -0
- package/dist/utils/llm-mocks.d.ts +43 -0
- package/dist/utils/llm-mocks.js +108 -0
- package/dist/utils/llm-providers/anthropic.d.ts +2 -0
- package/dist/utils/llm-providers/anthropic.js +132 -0
- package/dist/utils/llm-providers/cli.d.ts +20 -0
- package/dist/utils/llm-providers/cli.js +162 -0
- package/dist/utils/llm-providers/openai.d.ts +2 -0
- package/dist/utils/llm-providers/openai.js +56 -0
- package/dist/utils/llm-types.d.ts +107 -0
- package/dist/utils/llm-types.js +1 -0
- package/dist/utils/llm.d.ts +36 -0
- package/dist/utils/llm.js +209 -0
- package/dist/utils/shutdown.d.ts +15 -0
- package/dist/utils/shutdown.js +41 -0
- package/dist/utils/timeout.d.ts +8 -0
- package/dist/utils/timeout.js +32 -0
- package/dist/viewer.html +1178 -0
- package/package.json +88 -0
- package/templates/eval.ts.template +28 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { CheckScorer, CodeJudgeToolName, ScorerContext, JudgeScorer, ScoreScorer, ScoreResult, ToolExpectation, ToolUsageScorer } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Create a check scorer — a boolean gate that passes (1.0) or fails (0.0).
|
|
4
|
+
*/
|
|
5
|
+
export declare function check(name: string, fn: (ctx: ScorerContext) => boolean | Promise<boolean>, opts?: {
|
|
6
|
+
weight?: number;
|
|
7
|
+
}): CheckScorer;
|
|
8
|
+
/**
|
|
9
|
+
* Create a score scorer — returns a number (0-1) or { score, details } for partial credit.
|
|
10
|
+
*/
|
|
11
|
+
export declare function score(name: string, fn: (ctx: ScorerContext) => number | ScoreResult | Promise<number | ScoreResult>, opts?: {
|
|
12
|
+
weight?: number;
|
|
13
|
+
}): ScoreScorer;
|
|
14
|
+
/**
|
|
15
|
+
* Create a judge scorer — uses an LLM to evaluate against a rubric.
|
|
16
|
+
* Transcript is auto-included. Tool events opt-in via includeToolEvents.
|
|
17
|
+
*
|
|
18
|
+
* @param opts.input - Additional context to include in the judge prompt alongside
|
|
19
|
+
* the transcript. Each key becomes a section heading; string values are rendered
|
|
20
|
+
* as-is, objects are JSON-stringified. Use this to pass file contents, command
|
|
21
|
+
* output, or other artifacts that the agent produced but may not appear in the
|
|
22
|
+
* transcript. The judge LLM only sees the conversation transcript by default —
|
|
23
|
+
* if the agent wrote a file, the judge cannot verify its contents unless you read
|
|
24
|
+
* the file and pass it here.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Read the file the agent created and pass it to the judge
|
|
28
|
+
* const content = await agent.exec('cat output.md');
|
|
29
|
+
* judge('file quality', {
|
|
30
|
+
* rubric: 'The output file should contain a valid markdown document...',
|
|
31
|
+
* input: { 'output.md contents': content.stdout },
|
|
32
|
+
* })
|
|
33
|
+
* // Or derive the judge input from scorer context
|
|
34
|
+
* judge('file quality', {
|
|
35
|
+
* rubric: 'The output file should contain a valid markdown document...',
|
|
36
|
+
* input: async (ctx) => ({ 'output.md contents': await ctx.artifacts.read('output.md') }),
|
|
37
|
+
* })
|
|
38
|
+
*/
|
|
39
|
+
export declare function judge(name: string, opts: {
|
|
40
|
+
rubric: string;
|
|
41
|
+
weight?: number;
|
|
42
|
+
model?: string;
|
|
43
|
+
retry?: boolean | number;
|
|
44
|
+
includeToolEvents?: boolean;
|
|
45
|
+
/** Additional context for the judge. See function docs for usage pattern. */
|
|
46
|
+
input?: import('./types.js').JudgeInput;
|
|
47
|
+
/**
|
|
48
|
+
* Opt-in allowlist of tools the judge LLM may call during a multi-turn
|
|
49
|
+
* tool-use loop. When set to a non-empty array, the judge runs in a
|
|
50
|
+
* tool-use loop against a provider that supports callWithTools. When
|
|
51
|
+
* omitted, behavior is byte-for-byte unchanged.
|
|
52
|
+
*/
|
|
53
|
+
tools?: CodeJudgeToolName[];
|
|
54
|
+
/** Cap on LLM calls per tool-use judge; default 10. */
|
|
55
|
+
maxRounds?: number;
|
|
56
|
+
/** Anthropic prompt caching. Default: true when tools is set, unchanged otherwise. */
|
|
57
|
+
cacheControl?: boolean;
|
|
58
|
+
}): JudgeScorer;
|
|
59
|
+
/**
|
|
60
|
+
* Create a tool usage scorer — matches tool events against expectations.
|
|
61
|
+
*/
|
|
62
|
+
export declare function toolUsage(name: string, expectations: ToolExpectation[], opts?: {
|
|
63
|
+
weight?: number;
|
|
64
|
+
}): ToolUsageScorer;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a check scorer — a boolean gate that passes (1.0) or fails (0.0).
|
|
3
|
+
*/
|
|
4
|
+
export function check(name, fn, opts) {
|
|
5
|
+
return {
|
|
6
|
+
type: 'check',
|
|
7
|
+
name,
|
|
8
|
+
weight: opts?.weight ?? 1,
|
|
9
|
+
fn,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Create a score scorer — returns a number (0-1) or { score, details } for partial credit.
|
|
14
|
+
*/
|
|
15
|
+
export function score(name, fn, opts) {
|
|
16
|
+
return {
|
|
17
|
+
type: 'score',
|
|
18
|
+
name,
|
|
19
|
+
weight: opts?.weight ?? 1,
|
|
20
|
+
fn,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create a judge scorer — uses an LLM to evaluate against a rubric.
|
|
25
|
+
* Transcript is auto-included. Tool events opt-in via includeToolEvents.
|
|
26
|
+
*
|
|
27
|
+
* @param opts.input - Additional context to include in the judge prompt alongside
|
|
28
|
+
* the transcript. Each key becomes a section heading; string values are rendered
|
|
29
|
+
* as-is, objects are JSON-stringified. Use this to pass file contents, command
|
|
30
|
+
* output, or other artifacts that the agent produced but may not appear in the
|
|
31
|
+
* transcript. The judge LLM only sees the conversation transcript by default —
|
|
32
|
+
* if the agent wrote a file, the judge cannot verify its contents unless you read
|
|
33
|
+
* the file and pass it here.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* // Read the file the agent created and pass it to the judge
|
|
37
|
+
* const content = await agent.exec('cat output.md');
|
|
38
|
+
* judge('file quality', {
|
|
39
|
+
* rubric: 'The output file should contain a valid markdown document...',
|
|
40
|
+
* input: { 'output.md contents': content.stdout },
|
|
41
|
+
* })
|
|
42
|
+
* // Or derive the judge input from scorer context
|
|
43
|
+
* judge('file quality', {
|
|
44
|
+
* rubric: 'The output file should contain a valid markdown document...',
|
|
45
|
+
* input: async (ctx) => ({ 'output.md contents': await ctx.artifacts.read('output.md') }),
|
|
46
|
+
* })
|
|
47
|
+
*/
|
|
48
|
+
export function judge(name, opts) {
|
|
49
|
+
const tools = opts.tools && opts.tools.length > 0 ? [...opts.tools] : undefined;
|
|
50
|
+
const includeToolEvents = opts.includeToolEvents
|
|
51
|
+
?? (tools?.includes('getToolEvents') ? true : undefined);
|
|
52
|
+
// When tools is set, default cacheControl to true (mitigates the
|
|
53
|
+
// 10–70× input-token inflation measured in the spike). Explicit
|
|
54
|
+
// false opts out; explicit true is a no-op.
|
|
55
|
+
const cacheControl = opts.cacheControl ?? (tools ? true : undefined);
|
|
56
|
+
return {
|
|
57
|
+
type: 'judge',
|
|
58
|
+
name,
|
|
59
|
+
weight: opts.weight ?? 1,
|
|
60
|
+
rubric: opts.rubric,
|
|
61
|
+
model: opts.model,
|
|
62
|
+
retry: opts.retry,
|
|
63
|
+
includeToolEvents,
|
|
64
|
+
input: opts.input,
|
|
65
|
+
tools,
|
|
66
|
+
maxRounds: opts.maxRounds,
|
|
67
|
+
cacheControl,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Create a tool usage scorer — matches tool events against expectations.
|
|
72
|
+
*/
|
|
73
|
+
export function toolUsage(name, expectations, opts) {
|
|
74
|
+
return {
|
|
75
|
+
type: 'tool_usage',
|
|
76
|
+
name,
|
|
77
|
+
weight: opts?.weight ?? 1,
|
|
78
|
+
expectations,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { LogEntry } from '../types.js';
|
|
2
|
+
import type { ToolEvent } from '../tool-events.js';
|
|
3
|
+
import type { AgentName, ConversationResult, Message, TurnTiming } from './types.js';
|
|
4
|
+
export declare const RUN_SNAPSHOT_VERSION = 1;
|
|
5
|
+
export interface RunSnapshot {
|
|
6
|
+
version: 1;
|
|
7
|
+
timestamp: string;
|
|
8
|
+
agent: AgentName;
|
|
9
|
+
messages: Message[];
|
|
10
|
+
log: LogEntry[];
|
|
11
|
+
toolEvents: ToolEvent[];
|
|
12
|
+
turnTimings: TurnTiming[];
|
|
13
|
+
conversationResult: {
|
|
14
|
+
turns: number;
|
|
15
|
+
completionReason: ConversationResult['completionReason'];
|
|
16
|
+
completionDetail?: string;
|
|
17
|
+
turnTimings: TurnTiming[];
|
|
18
|
+
};
|
|
19
|
+
workspace: string | null;
|
|
20
|
+
}
|
|
21
|
+
export declare function buildRunSnapshot(params: {
|
|
22
|
+
agent: AgentName;
|
|
23
|
+
messages: Message[];
|
|
24
|
+
log: LogEntry[];
|
|
25
|
+
conversationResult: ConversationResult;
|
|
26
|
+
workspace: string | null;
|
|
27
|
+
timestamp?: string;
|
|
28
|
+
}): RunSnapshot;
|
|
29
|
+
export declare class SnapshotParseError extends Error {
|
|
30
|
+
constructor(message: string, options?: {
|
|
31
|
+
cause?: unknown;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export declare class SnapshotVersionError extends Error {
|
|
35
|
+
constructor(version: number);
|
|
36
|
+
}
|
|
37
|
+
export declare class WorkspaceMissingError extends Error {
|
|
38
|
+
constructor(message: string);
|
|
39
|
+
}
|
|
40
|
+
export declare function buildTranscript(messages: Message[]): string;
|
|
41
|
+
export declare function loadRunSnapshot(snapshotPath: string): Promise<RunSnapshot>;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
export const RUN_SNAPSHOT_VERSION = 1;
|
|
3
|
+
export function buildRunSnapshot(params) {
|
|
4
|
+
const { agent, messages, log, conversationResult, workspace, timestamp } = params;
|
|
5
|
+
const toolEvents = log
|
|
6
|
+
.filter((entry) => entry.type === 'tool_event' && entry.tool_event)
|
|
7
|
+
.map((entry) => entry.tool_event);
|
|
8
|
+
return {
|
|
9
|
+
version: RUN_SNAPSHOT_VERSION,
|
|
10
|
+
timestamp: timestamp ?? new Date().toISOString(),
|
|
11
|
+
agent,
|
|
12
|
+
messages: [...messages],
|
|
13
|
+
log: [...log],
|
|
14
|
+
toolEvents,
|
|
15
|
+
turnTimings: [...conversationResult.turnTimings],
|
|
16
|
+
conversationResult: {
|
|
17
|
+
turns: conversationResult.turns,
|
|
18
|
+
completionReason: conversationResult.completionReason,
|
|
19
|
+
...(conversationResult.completionDetail ? { completionDetail: conversationResult.completionDetail } : {}),
|
|
20
|
+
turnTimings: [...conversationResult.turnTimings],
|
|
21
|
+
},
|
|
22
|
+
workspace,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export class SnapshotParseError extends Error {
|
|
26
|
+
constructor(message, options) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = 'SnapshotParseError';
|
|
29
|
+
if (options?.cause !== undefined) {
|
|
30
|
+
this.cause = options.cause;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export class SnapshotVersionError extends Error {
|
|
35
|
+
constructor(version) {
|
|
36
|
+
super(`Unsupported snapshot version: ${version}`);
|
|
37
|
+
this.name = 'SnapshotVersionError';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export class WorkspaceMissingError extends Error {
|
|
41
|
+
constructor(message) {
|
|
42
|
+
super(message);
|
|
43
|
+
this.name = 'WorkspaceMissingError';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const ASK_SOURCE_VALUES = new Set(['claude', 'codex-app-server', 'cursor']);
|
|
47
|
+
const ASK_LIFECYCLE_VALUES = new Set(['live', 'post-hoc']);
|
|
48
|
+
function validateLogEntries(entries) {
|
|
49
|
+
for (let i = 0; i < entries.length; i++) {
|
|
50
|
+
const entry = entries[i];
|
|
51
|
+
if (!entry || typeof entry !== 'object') {
|
|
52
|
+
throw new SnapshotParseError(`Snapshot log entry ${i} must be an object`);
|
|
53
|
+
}
|
|
54
|
+
const record = entry;
|
|
55
|
+
if (record.type === 'ask_batch') {
|
|
56
|
+
if (typeof record.batch_id !== 'string') {
|
|
57
|
+
throw new SnapshotParseError(`ask_batch log entry ${i} is missing required field: batch_id`);
|
|
58
|
+
}
|
|
59
|
+
if (typeof record.turn_number !== 'number') {
|
|
60
|
+
throw new SnapshotParseError(`ask_batch log entry ${i} is missing required field: turn_number`);
|
|
61
|
+
}
|
|
62
|
+
if (typeof record.source !== 'string' || !ASK_SOURCE_VALUES.has(record.source)) {
|
|
63
|
+
throw new SnapshotParseError(`ask_batch log entry ${i} has invalid source: ${String(record.source)}`);
|
|
64
|
+
}
|
|
65
|
+
if (typeof record.lifecycle !== 'string' || !ASK_LIFECYCLE_VALUES.has(record.lifecycle)) {
|
|
66
|
+
throw new SnapshotParseError(`ask_batch log entry ${i} has invalid lifecycle: ${String(record.lifecycle)}`);
|
|
67
|
+
}
|
|
68
|
+
if (typeof record.source_tool !== 'string') {
|
|
69
|
+
throw new SnapshotParseError(`ask_batch log entry ${i} is missing required field: source_tool`);
|
|
70
|
+
}
|
|
71
|
+
if (typeof record.question_count !== 'number') {
|
|
72
|
+
throw new SnapshotParseError(`ask_batch log entry ${i} is missing required field: question_count`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Legacy blocked_prompt_* fields on agent_result entries remain accepted
|
|
76
|
+
// without additional validation — their schema is owned by the writer.
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export function buildTranscript(messages) {
|
|
80
|
+
return messages
|
|
81
|
+
.map((msg) => `[${msg.role === 'user' ? 'User' : 'Agent'}]\n${msg.content}`)
|
|
82
|
+
.join('\n\n');
|
|
83
|
+
}
|
|
84
|
+
export async function loadRunSnapshot(snapshotPath) {
|
|
85
|
+
let parsed;
|
|
86
|
+
try {
|
|
87
|
+
parsed = await fs.readJSON(snapshotPath);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
throw new SnapshotParseError(`Failed to read snapshot JSON from ${snapshotPath}`, { cause: error });
|
|
91
|
+
}
|
|
92
|
+
return validateRunSnapshot(parsed);
|
|
93
|
+
}
|
|
94
|
+
function validateRunSnapshot(input) {
|
|
95
|
+
if (!input || typeof input !== 'object') {
|
|
96
|
+
throw new SnapshotParseError('Snapshot must be a JSON object');
|
|
97
|
+
}
|
|
98
|
+
const snapshot = input;
|
|
99
|
+
if (typeof snapshot.version !== 'number') {
|
|
100
|
+
throw new SnapshotParseError('Snapshot is missing required field: version');
|
|
101
|
+
}
|
|
102
|
+
if (snapshot.version > RUN_SNAPSHOT_VERSION) {
|
|
103
|
+
throw new SnapshotVersionError(snapshot.version);
|
|
104
|
+
}
|
|
105
|
+
if (!Array.isArray(snapshot.messages)) {
|
|
106
|
+
throw new SnapshotParseError('Snapshot is missing required field: messages');
|
|
107
|
+
}
|
|
108
|
+
if (!Array.isArray(snapshot.log)) {
|
|
109
|
+
throw new SnapshotParseError('Snapshot is missing required field: log');
|
|
110
|
+
}
|
|
111
|
+
validateLogEntries(snapshot.log);
|
|
112
|
+
if (!Array.isArray(snapshot.toolEvents)) {
|
|
113
|
+
throw new SnapshotParseError('Snapshot is missing required field: toolEvents');
|
|
114
|
+
}
|
|
115
|
+
if (!snapshot.conversationResult || typeof snapshot.conversationResult !== 'object') {
|
|
116
|
+
throw new SnapshotParseError('Snapshot is missing required field: conversationResult');
|
|
117
|
+
}
|
|
118
|
+
if (!Array.isArray(snapshot.conversationResult.turnTimings)) {
|
|
119
|
+
throw new SnapshotParseError('Snapshot conversationResult is missing required field: turnTimings');
|
|
120
|
+
}
|
|
121
|
+
if (typeof snapshot.conversationResult.turns !== 'number') {
|
|
122
|
+
throw new SnapshotParseError('Snapshot conversationResult is missing required field: turns');
|
|
123
|
+
}
|
|
124
|
+
if (typeof snapshot.conversationResult.completionReason !== 'string') {
|
|
125
|
+
throw new SnapshotParseError('Snapshot conversationResult is missing required field: completionReason');
|
|
126
|
+
}
|
|
127
|
+
const turnTimings = Array.isArray(snapshot.turnTimings)
|
|
128
|
+
? snapshot.turnTimings
|
|
129
|
+
: snapshot.conversationResult.turnTimings;
|
|
130
|
+
return {
|
|
131
|
+
version: RUN_SNAPSHOT_VERSION,
|
|
132
|
+
timestamp: typeof snapshot.timestamp === 'string' ? snapshot.timestamp : new Date(0).toISOString(),
|
|
133
|
+
agent: snapshot.agent === 'claude' || snapshot.agent === 'codex' || snapshot.agent === 'cursor' ? snapshot.agent : 'claude',
|
|
134
|
+
messages: snapshot.messages,
|
|
135
|
+
log: snapshot.log,
|
|
136
|
+
toolEvents: snapshot.toolEvents,
|
|
137
|
+
turnTimings,
|
|
138
|
+
conversationResult: {
|
|
139
|
+
turns: snapshot.conversationResult.turns,
|
|
140
|
+
completionReason: snapshot.conversationResult.completionReason,
|
|
141
|
+
...(snapshot.conversationResult.completionDetail
|
|
142
|
+
? { completionDetail: snapshot.conversationResult.completionDetail }
|
|
143
|
+
: {}),
|
|
144
|
+
turnTimings: snapshot.conversationResult.turnTimings,
|
|
145
|
+
},
|
|
146
|
+
workspace: typeof snapshot.workspace === 'string' ? snapshot.workspace : null,
|
|
147
|
+
};
|
|
148
|
+
}
|