@ai-sdk/harness-codex 1.0.165 → 1.0.167

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 CHANGED
@@ -1,5 +1,27 @@
1
1
  # @ai-sdk/harness-codex
2
2
 
3
+ ## 1.0.167
4
+
5
+ ### Patch Changes
6
+
7
+ - 39aae54: fix(harness): ensure harness adapters always resolve the model used
8
+ - Updated dependencies [e64ed82]
9
+ - @ai-sdk/provider-utils@5.0.69
10
+ - @ai-sdk/harness@1.0.165
11
+
12
+ ## 1.0.166
13
+
14
+ ### Patch Changes
15
+
16
+ - a9837eb: feat(harness): provide shared utils for bridge-backed adapters to manage web socket connection and bridge handshake
17
+ - e729d58: chore(docs): update `README.md` for consistent format and to avoid duplication
18
+ - Updated dependencies [5475347]
19
+ - Updated dependencies [a9837eb]
20
+ - Updated dependencies [e729d58]
21
+ - @ai-sdk/provider@4.0.34
22
+ - @ai-sdk/harness@1.0.164
23
+ - @ai-sdk/provider-utils@5.0.68
24
+
3
25
  ## 1.0.165
4
26
 
5
27
  ### Patch Changes
package/README.md CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  `HarnessV1` adapter backed by the [Codex CLI](https://www.npmjs.com/package/@openai/codex). The adapter runs Codex app-server inside a sandbox and communicates with it over JSON-RPC. A bridge process connects app-server to the host over a WebSocket on a sandbox-proxied loopback port.
4
4
 
5
+ -> **Note**: This package is experimental.
6
+
5
7
  ## Setup
6
8
 
7
9
  ```bash
8
- npm i @ai-sdk/harness-codex @ai-sdk/harness @ai-sdk/sandbox-vercel
10
+ npm i ai @ai-sdk/harness-codex @ai-sdk/harness @ai-sdk/sandbox-vercel zod
9
11
  ```
10
12
 
11
- The bridge installs the Codex CLI inside the sandbox the first time the session starts.
12
-
13
13
  ## Usage
14
14
 
15
15
  ```ts
@@ -39,43 +39,4 @@ const agent = new HarnessAgent({
39
39
  });
40
40
  ```
41
41
 
42
- `codexConfig` accepts additional native Codex configuration. Values pass
43
- through as provided, so use the snake_case keys from Codex's `config.toml`
44
- reference. The adapter's managed values take precedence over conflicting
45
- entries.
46
-
47
- > Codex does not auto-discover a skills directory the way the `claude` CLI
48
- > does, so when you supply `skills: [...]` on the factory the adapter
49
- > injects every skill inline into the user prompt on each turn. Use fewer,
50
- > larger skills rather than many tiny ones.
51
-
52
- ```ts
53
- const agent = new HarnessAgent({
54
- harness: createCodex({
55
- skills: [
56
- { name: 'haiku-mode', description: 'Answer in haikus.', content: '...' },
57
- ],
58
- }),
59
- });
60
-
61
- const sandboxSession = await createVercelNetworkSandboxSession({
62
- runtime: 'node24',
63
- ports: [4000],
64
- template: await agent.getSandboxTemplate(),
65
- });
66
- const session = await agent.createSession({ sandboxSession });
67
-
68
- try {
69
- const result = await agent.generate({
70
- session,
71
- prompt: 'List the files in this workspace and describe their purpose.',
72
- });
73
- console.log(result.text);
74
- } finally {
75
- await session.destroy();
76
- await sandboxSession.destroy();
77
- }
78
- ```
79
-
80
- The adapter needs a sandbox session with an exposed port. The caller ends the
81
- harness session and sandbox separately.
42
+ See the [Codex Harness documentation](https://ai-sdk.dev/providers/ai-sdk-harnesses/codex) for more information.
@@ -1342,12 +1342,14 @@ const CODEX_CLI_PATH = fileURLToPath(new URL("./node_modules/@openai/codex/bin/c
1342
1342
  function createCodexAppServerRuntime() {
1343
1343
  let client;
1344
1344
  let loadedThreadId;
1345
+ let loadedThreadModel;
1345
1346
  let loadedConfig;
1346
1347
  let activeTurn;
1347
1348
  const close = async () => {
1348
1349
  const previous = client;
1349
1350
  client = void 0;
1350
1351
  loadedThreadId = void 0;
1352
+ loadedThreadModel = void 0;
1351
1353
  loadedConfig = void 0;
1352
1354
  await previous?.close();
1353
1355
  };
@@ -1505,6 +1507,7 @@ function createCodexAppServerRuntime() {
1505
1507
  params: { threadId: loadedThreadId }
1506
1508
  }) });
1507
1509
  loadedThreadId = void 0;
1510
+ loadedThreadModel = void 0;
1508
1511
  }
1509
1512
  if (trustedHook != null) assertTrustedApplyPatchHook({
1510
1513
  response: await raceWithProcess({ operation: runningClient.request({
@@ -1547,9 +1550,18 @@ function createCodexAppServerRuntime() {
1547
1550
  method: threadMethod
1548
1551
  });
1549
1552
  loadedThreadId = currentTurn.threadId;
1553
+ loadedThreadModel = {
1554
+ requestedModel: codexModel,
1555
+ modelId: readOptionalString(asRecord(threadResponse)?.model)
1556
+ };
1550
1557
  }
1551
1558
  handler.announceThread(currentTurn.threadId);
1552
- emit({ type: "stream-start" });
1559
+ const threadModel = loadedThreadModel;
1560
+ const streamStartModelId = threadModel != null && threadModel.requestedModel === codexModel && threadModel.modelId != null ? threadModel.modelId : codexModel;
1561
+ emit({
1562
+ type: "stream-start",
1563
+ ...streamStartModelId ? { modelId: streamStartModelId } : {}
1564
+ });
1553
1565
  currentTurn.turnId = readNestedString({
1554
1566
  value: await raceWithProcess({ operation: runningClient.request({
1555
1567
  method: "turn/start",
@@ -1746,6 +1758,9 @@ function assertSuccessfulTurn(result) {
1746
1758
  function asRecord(value) {
1747
1759
  return value != null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
1748
1760
  }
1761
+ function readOptionalString(value) {
1762
+ return typeof value === "string" && value.length > 0 ? value : void 0;
1763
+ }
1749
1764
  //#endregion
1750
1765
  //#region src/bridge/codex-step-tracker.ts
1751
1766
  function createCodexStepTracker(input) {