@wix/pathgrade 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/codex-app-server/agent.js +2 -2
- package/dist/agents/codex-model.d.ts +1 -0
- package/dist/agents/codex-model.js +4 -0
- package/dist/agents/codex.js +17 -6
- package/dist/sdk/agent-resolution.d.ts +2 -1
- package/dist/sdk/agent-resolution.js +7 -0
- package/dist/sdk/agent.js +2 -2
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/types.d.ts +4 -2
- package/dist/utils/llm-providers/anthropic.js +39 -6
- package/package.json +3 -2
|
@@ -8,7 +8,7 @@ import { decideMcpToolCall, redactMcpSecrets, } from '../../sdk/mcp-safety.js';
|
|
|
8
8
|
import { spawnAppServerTransport, } from './transport.js';
|
|
9
9
|
import { normalizeUpstreamQuestion, toWireAnswerMap, } from './wire-translators.js';
|
|
10
10
|
import { extractTurnCompletionFailure } from './turn-completion.js';
|
|
11
|
-
|
|
11
|
+
import { resolveCodexModel } from '../codex-model.js';
|
|
12
12
|
const TURN_COMPLETED_METHOD = 'turn/completed';
|
|
13
13
|
function recordFromUnknown(value) {
|
|
14
14
|
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
@@ -212,7 +212,7 @@ export class CodexAppServerAgent extends BaseAgent {
|
|
|
212
212
|
const askBus = requireAskBusForLiveBatches(options, 'CodexAppServerAgent');
|
|
213
213
|
const workspacePath = getWorkspacePath(runtime);
|
|
214
214
|
const runtimeEnv = getRuntimeEnv(runtime);
|
|
215
|
-
const model = options?.model
|
|
215
|
+
const model = resolveCodexModel(options?.model);
|
|
216
216
|
const sandboxMode = this.deps.sandboxMode ?? 'workspace-write';
|
|
217
217
|
let handle = null;
|
|
218
218
|
let threadId = null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function resolveCodexModel(explicitModel?: string): string;
|
package/dist/agents/codex.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { TOOL_NAME_MAP, buildSummary, inferCodexExecAction, enrichSkillEvents } from '../tool-events.js';
|
|
2
2
|
import { TranscriptAgent } from './transcript-agent.js';
|
|
3
3
|
import { assertMcpRuntimeMountingSupportedForCodexExec } from '../providers/mcp-runtime-mounting.js';
|
|
4
|
+
import { resolveCodexModel } from './codex-model.js';
|
|
4
5
|
export class CodexAgent extends TranscriptAgent {
|
|
5
6
|
async runTurn(instruction, runCommand, options) {
|
|
6
7
|
await assertMcpRuntimeMountingSupportedForCodexExec({
|
|
7
8
|
mcpConfigPath: options?.mcpConfigPath,
|
|
8
9
|
});
|
|
10
|
+
await assertVerifiedCodexCli(runCommand);
|
|
9
11
|
const promptPath = await this.writePromptFile(instruction, runCommand);
|
|
10
12
|
const command = buildCodexExecCommand(promptPath, options?.model);
|
|
11
13
|
const result = await runCommand(command);
|
|
@@ -26,17 +28,26 @@ export class CodexAgent extends TranscriptAgent {
|
|
|
26
28
|
};
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
|
-
const
|
|
31
|
+
const VERIFIED_CODEX_CLI_VERSION = '0.148.0-alpha.9';
|
|
32
|
+
async function assertVerifiedCodexCli(runCommand) {
|
|
33
|
+
const result = await runCommand('codex --version');
|
|
34
|
+
const reportedVersion = (result.stdout || result.stderr).trim();
|
|
35
|
+
const expected = `codex-cli ${VERIFIED_CODEX_CLI_VERSION}`;
|
|
36
|
+
if (result.exitCode !== 0 || reportedVersion !== expected) {
|
|
37
|
+
throw new Error(`Codex CLI ${VERIFIED_CODEX_CLI_VERSION} required for PathGrade exec; received ${reportedVersion || `exit code ${result.exitCode}`}. Install @openai/codex@${VERIFIED_CODEX_CLI_VERSION}.`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
30
40
|
const CODEX_PROXY_PROVIDER_ID = 'pathgrade_openai_proxy';
|
|
31
|
-
function buildCodexExecCommand(promptPath, model
|
|
41
|
+
function buildCodexExecCommand(promptPath, model) {
|
|
32
42
|
const quotedPromptPath = JSON.stringify(promptPath);
|
|
33
|
-
const quotedModel = JSON.stringify(model);
|
|
34
|
-
const
|
|
43
|
+
const quotedModel = JSON.stringify(resolveCodexModel(model));
|
|
44
|
+
const globalArgs = '-a never -s workspace-write';
|
|
45
|
+
const execArgs = `--skip-git-repo-check -m ${quotedModel} - < ${quotedPromptPath}`;
|
|
35
46
|
return [
|
|
36
47
|
'if [ -n "${OPENAI_BASE_URL:-}" ]; then',
|
|
37
|
-
`codex exec ${buildCodexProxyConfigArgs()} ${execArgs};`,
|
|
48
|
+
`codex ${globalArgs} exec ${buildCodexProxyConfigArgs()} ${execArgs};`,
|
|
38
49
|
'else',
|
|
39
|
-
`codex exec ${execArgs};`,
|
|
50
|
+
`codex ${globalArgs} exec ${execArgs};`,
|
|
40
51
|
'fi',
|
|
41
52
|
].join(' ');
|
|
42
53
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentName, AgentTransport, AgentOptions } from './types.js';
|
|
1
|
+
import type { AgentExecutionTransport, AgentName, AgentTransport, AgentOptions } from './types.js';
|
|
2
2
|
export declare class InvalidTransportEnvError extends Error {
|
|
3
3
|
constructor(value: string);
|
|
4
4
|
}
|
|
@@ -10,3 +10,4 @@ export declare function resolveCodexTransport(opts: {
|
|
|
10
10
|
}, env: {
|
|
11
11
|
PATHGRADE_CODEX_TRANSPORT?: string;
|
|
12
12
|
}): AgentTransport;
|
|
13
|
+
export declare function resolveExecutionTransport(agentName: AgentName, codexTransport?: AgentTransport): AgentExecutionTransport;
|
|
@@ -19,3 +19,10 @@ export function resolveCodexTransport(opts, env) {
|
|
|
19
19
|
}
|
|
20
20
|
return 'app-server';
|
|
21
21
|
}
|
|
22
|
+
export function resolveExecutionTransport(agentName, codexTransport) {
|
|
23
|
+
if (agentName === 'claude')
|
|
24
|
+
return 'claude-agent-sdk';
|
|
25
|
+
if (agentName === 'cursor')
|
|
26
|
+
return 'cursor-agent';
|
|
27
|
+
return codexTransport ?? 'app-server';
|
|
28
|
+
}
|
package/dist/sdk/agent.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { prepareWorkspace } from '../providers/workspace.js';
|
|
2
|
-
import { resolveAgentName, resolveCodexTransport } from './agent-resolution.js';
|
|
2
|
+
import { resolveAgentName, resolveCodexTransport, resolveExecutionTransport, } from './agent-resolution.js';
|
|
3
3
|
import { lifecycleCore } from './lifecycle.js';
|
|
4
4
|
import { ChatSessionImpl } from './chat.js';
|
|
5
5
|
import { runConversation } from './converse.js';
|
|
@@ -73,7 +73,7 @@ class AgentImpl {
|
|
|
73
73
|
return {
|
|
74
74
|
name: this.agentName,
|
|
75
75
|
...(this.modelOpt ? { requestedModel: this.modelOpt } : {}),
|
|
76
|
-
|
|
76
|
+
transport: resolveExecutionTransport(this.agentName, this.transport),
|
|
77
77
|
...(interactionMode ? { interactionMode } : {}),
|
|
78
78
|
};
|
|
79
79
|
}
|
package/dist/sdk/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export { emitEvalResult, resetAllResultObserversForTests, resetUserResultObserve
|
|
|
21
21
|
export { getAgentCapabilities } from './types.js';
|
|
22
22
|
export type { AgentTransport, AgentCapabilities, AgentName, McpRunMode, McpSafetyOptions, McpToolPolicy, McpToolPolicyRule, } from './types.js';
|
|
23
23
|
export type { AskBus, AskBatch, AskQuestion, AskOption, AskAnswer, AskResolution, AskBatchSnapshot, AskAnswerSnapshot, AskResolutionSnapshot, AskHandle, AskHandler, AskSource, AskLifecycle, AskAnswerSource, Unsubscribe as AskBusUnsubscribe, } from './ask-bus/types.js';
|
|
24
|
-
export type { Agent, AgentOptions, Message, Scorer, CheckScorer, ScoreScorer, JudgeScorer, ToolUsageScorer, ScorerContext, EvalResult, ScorerResultEntry, ScorerStatus, ChatSession, ConversationResult, ConverseOptions, UntilPredicate, UntilContext, Reaction, TextReaction, AskUserReaction, AskUserQuestion, AskUserOption, ReactionPreviewEntry, TextReactionPreviewEntry, AskUserReactionPreviewEntry, ReactionPreviewResult, ReactionPreviewTurn, StepScorer, Persona, PersonaConfig, ConversationWindowConfig, TurnDetail, ReactionFiredEntry, PathgradePluginOptions, PathgradeMeta, TurnTiming, TokenUsage, EvaluateOptions, ReactionPreviewStatus, ScoreResult, JudgeInput, CodeJudgeToolName, ToolExpectation, SessionArtifactMatchOptions, SessionArtifactContent, SessionArtifacts, RecordedEvalResult, PathgradeTestMeta, EvaluationResultKind, AgentExecutionMetadata, AgentInteractionMode, } from './types.js';
|
|
24
|
+
export type { Agent, AgentOptions, Message, Scorer, CheckScorer, ScoreScorer, JudgeScorer, ToolUsageScorer, ScorerContext, EvalResult, ScorerResultEntry, ScorerStatus, ChatSession, ConversationResult, ConverseOptions, UntilPredicate, UntilContext, Reaction, TextReaction, AskUserReaction, AskUserQuestion, AskUserOption, ReactionPreviewEntry, TextReactionPreviewEntry, AskUserReactionPreviewEntry, ReactionPreviewResult, ReactionPreviewTurn, StepScorer, Persona, PersonaConfig, ConversationWindowConfig, TurnDetail, ReactionFiredEntry, PathgradePluginOptions, PathgradeMeta, TurnTiming, TokenUsage, EvaluateOptions, ReactionPreviewStatus, ScoreResult, JudgeInput, CodeJudgeToolName, ToolExpectation, SessionArtifactMatchOptions, SessionArtifactContent, SessionArtifacts, RecordedEvalResult, PathgradeTestMeta, EvaluationResultKind, AgentExecutionMetadata, AgentExecutionTransport, AgentInteractionMode, } from './types.js';
|
|
25
25
|
export type { ConversationWindow, ConversationWindowOptions } from './conversation-window.js';
|
|
26
26
|
export type { JudgePipelineOptions } from './judge-pipeline.js';
|
|
27
27
|
export type { RunScorerOptions } from './run-scorer.js';
|
package/dist/sdk/types.d.ts
CHANGED
|
@@ -7,12 +7,14 @@ import type { LLMPort } from '../utils/llm-types.js';
|
|
|
7
7
|
import type { McpSafetyOptions } from './mcp-safety.js';
|
|
8
8
|
export type AgentName = 'claude' | 'codex' | 'cursor';
|
|
9
9
|
export type AgentInteractionMode = 'prompt' | 'start_chat' | 'conversation';
|
|
10
|
+
/** Runtime channel that actually executed the agent. */
|
|
11
|
+
export type AgentExecutionTransport = AgentTransport | 'claude-agent-sdk' | 'cursor-agent';
|
|
10
12
|
/** Privacy-safe execution dimensions exposed to result observers. */
|
|
11
13
|
export interface AgentExecutionMetadata {
|
|
12
14
|
name: AgentName;
|
|
13
15
|
/** Model override requested by the caller; not necessarily the provider-resolved model. */
|
|
14
16
|
requestedModel?: string;
|
|
15
|
-
transport?:
|
|
17
|
+
transport?: AgentExecutionTransport;
|
|
16
18
|
interactionMode?: AgentInteractionMode;
|
|
17
19
|
}
|
|
18
20
|
export interface AgentOptions {
|
|
@@ -70,7 +72,7 @@ export interface Agent {
|
|
|
70
72
|
readonly messages: Message[];
|
|
71
73
|
readonly log: LogEntry[];
|
|
72
74
|
readonly workspace: string;
|
|
73
|
-
/** Provider/
|
|
75
|
+
/** Provider/runtime metadata only; never contains prompts or paths. */
|
|
74
76
|
readonly executionMetadata?: AgentExecutionMetadata;
|
|
75
77
|
dispose(): Promise<void>;
|
|
76
78
|
}
|
|
@@ -27,6 +27,35 @@ function sumInputTokens(usage) {
|
|
|
27
27
|
+ (usage?.cache_creation_input_tokens ?? 0)
|
|
28
28
|
+ (usage?.cache_read_input_tokens ?? 0);
|
|
29
29
|
}
|
|
30
|
+
const DEFAULT_ANTHROPIC_MODEL = 'claude-sonnet-5';
|
|
31
|
+
const DEFAULT_ANTHROPIC_MODEL_CONFIG = {
|
|
32
|
+
transport: 'raw-messages',
|
|
33
|
+
temperature: 'default-zero',
|
|
34
|
+
};
|
|
35
|
+
const ANTHROPIC_MODEL_CONFIGS = {
|
|
36
|
+
'claude-haiku-4-5-20251001': { transport: 'raw-messages', temperature: 'default-zero' },
|
|
37
|
+
'claude-opus-4-7': { transport: 'raw-messages', temperature: 'unsupported' },
|
|
38
|
+
'claude-opus-5': { transport: 'raw-messages', temperature: 'unsupported' },
|
|
39
|
+
'claude-sonnet-5': { transport: 'raw-messages', temperature: 'unsupported' },
|
|
40
|
+
'claude-opus-5[1m]': { transport: 'claude-agent-sdk' },
|
|
41
|
+
};
|
|
42
|
+
function getAnthropicModelConfig(model) {
|
|
43
|
+
return ANTHROPIC_MODEL_CONFIGS[model] ?? DEFAULT_ANTHROPIC_MODEL_CONFIG;
|
|
44
|
+
}
|
|
45
|
+
function assertRawAnthropicModel(model, config) {
|
|
46
|
+
if (config.transport !== 'raw-messages') {
|
|
47
|
+
throw new Error(`Anthropic model ${model} uses Claude Agent SDK transport syntax and cannot be sent to the raw Messages API`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function resolveTemperature(model, config, temperature) {
|
|
51
|
+
if (config.temperature === 'unsupported') {
|
|
52
|
+
if (temperature !== undefined) {
|
|
53
|
+
throw new Error(`Anthropic model ${model} does not accept temperature; omit the option`);
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
return temperature ?? 0;
|
|
58
|
+
}
|
|
30
59
|
async function postAnthropic(apiKey, useCache, body, env) {
|
|
31
60
|
const response = await fetch(`${resolveBaseUrl(env)}/v1/messages`, {
|
|
32
61
|
method: 'POST',
|
|
@@ -52,8 +81,10 @@ export const anthropicProvider = {
|
|
|
52
81
|
if (!apiKey) {
|
|
53
82
|
throw new Error('No ANTHROPIC_API_KEY available');
|
|
54
83
|
}
|
|
55
|
-
const model = opts.model ||
|
|
56
|
-
const
|
|
84
|
+
const model = opts.model || DEFAULT_ANTHROPIC_MODEL;
|
|
85
|
+
const modelConfig = getAnthropicModelConfig(model);
|
|
86
|
+
assertRawAnthropicModel(model, modelConfig);
|
|
87
|
+
const temperature = resolveTemperature(model, modelConfig, opts.temperature);
|
|
57
88
|
const useCache = opts.cacheControl ?? false;
|
|
58
89
|
const content = useCache
|
|
59
90
|
? [{ type: 'text', text: prompt, cache_control: { type: 'ephemeral' } }]
|
|
@@ -62,7 +93,7 @@ export const anthropicProvider = {
|
|
|
62
93
|
const data = await postAnthropic(apiKey, useCache, {
|
|
63
94
|
model,
|
|
64
95
|
max_tokens: 4096,
|
|
65
|
-
temperature,
|
|
96
|
+
...(temperature === undefined ? {} : { temperature }),
|
|
66
97
|
messages: [{ role: 'user', content }],
|
|
67
98
|
}, opts.env);
|
|
68
99
|
const inputTokens = sumInputTokens(data?.usage);
|
|
@@ -84,8 +115,10 @@ export const anthropicProvider = {
|
|
|
84
115
|
if (!apiKey) {
|
|
85
116
|
throw new Error('No ANTHROPIC_API_KEY available');
|
|
86
117
|
}
|
|
87
|
-
const model = opts.model ||
|
|
88
|
-
const
|
|
118
|
+
const model = opts.model || DEFAULT_ANTHROPIC_MODEL;
|
|
119
|
+
const modelConfig = getAnthropicModelConfig(model);
|
|
120
|
+
assertRawAnthropicModel(model, modelConfig);
|
|
121
|
+
const temperature = resolveTemperature(model, modelConfig, opts.temperature);
|
|
89
122
|
const maxTokens = opts.maxTokens ?? 4096;
|
|
90
123
|
const useCache = opts.cacheControl === true;
|
|
91
124
|
// Tool schemas: only the last gets cache_control, serving as a cache
|
|
@@ -96,7 +129,7 @@ export const anthropicProvider = {
|
|
|
96
129
|
const body = {
|
|
97
130
|
model,
|
|
98
131
|
max_tokens: maxTokens,
|
|
99
|
-
temperature,
|
|
132
|
+
...(temperature === undefined ? {} : { temperature }),
|
|
100
133
|
messages,
|
|
101
134
|
tools,
|
|
102
135
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/pathgrade",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"packageManager": "yarn@4.12.0",
|
|
5
5
|
"description": "Evaluate whether AI agents discover and use your skills correctly",
|
|
6
6
|
"exports": {
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"test": "yarn build && vitest run && yarn test:runner-cli-smoke",
|
|
63
63
|
"test:runner-cli-smoke": "node tests/runner-cli-smoke/run-smokes.mjs",
|
|
64
64
|
"test:evals": "vitest run --config evals/vitest.config.mts",
|
|
65
|
+
"smoke:models": "tsx scripts/model-smoke.ts",
|
|
65
66
|
"test:coverage": "vitest run --coverage",
|
|
66
67
|
"dev": "tsx src/pathgrade.ts",
|
|
67
68
|
"build": "tsc -p tsconfig.build.json && cp src/viewer.html dist/viewer.html && cp src/adapters/jest/reporter.cjs dist/adapters/jest/reporter.cjs"
|
|
@@ -126,5 +127,5 @@
|
|
|
126
127
|
"typescript": "^5.9.3",
|
|
127
128
|
"zod": "4.3.6"
|
|
128
129
|
},
|
|
129
|
-
"falconPackageHash": "
|
|
130
|
+
"falconPackageHash": "b61abd1d02054fc169ad426379b1be872d282675641bfd6012d5bbe7"
|
|
130
131
|
}
|