@wix/pathgrade 1.0.4 → 1.0.5

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.
@@ -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
- const DEFAULT_MODEL = 'gpt-5.4';
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 ?? DEFAULT_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;
@@ -0,0 +1,4 @@
1
+ const DEFAULT_CODEX_MODEL = 'gpt-5.6-luna';
2
+ export function resolveCodexModel(explicitModel) {
3
+ return explicitModel ?? DEFAULT_CODEX_MODEL;
4
+ }
@@ -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 DEFAULT_CODEX_MODEL = 'gpt-5.4';
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 = DEFAULT_CODEX_MODEL) {
41
+ function buildCodexExecCommand(promptPath, model) {
32
42
  const quotedPromptPath = JSON.stringify(promptPath);
33
- const quotedModel = JSON.stringify(model);
34
- const execArgs = `--full-auto --skip-git-repo-check -m ${quotedModel} - < ${quotedPromptPath}`;
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
  }
@@ -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 || 'claude-sonnet-4-20250514';
56
- const temperature = opts.temperature ?? 0;
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 || 'claude-sonnet-4-20250514';
88
- const temperature = opts.temperature ?? 0;
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.4",
3
+ "version": "1.0.5",
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": "112cde138733c678a01778b225c1b3891d22417d98bbf2c479f8734c"
130
+ "falconPackageHash": "0d0bd8f233a4d538524961fc02c50f608b46cb42353be3b9ad1c4cde"
130
131
  }