@ai-sdk/harness-codex 1.0.152 → 1.0.154
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 +18 -0
- package/dist/bridge/index.mjs +117 -5
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/bridge/codex-app-server-driver.ts +28 -2
- package/src/bridge/codex-step-tracker.ts +40 -0
- package/src/codex-harness.ts +1 -0
|
@@ -17,6 +17,8 @@ export type CodexStepTracker = {
|
|
|
17
17
|
itemId: string | undefined;
|
|
18
18
|
}): void;
|
|
19
19
|
finishTurn(): void;
|
|
20
|
+
awaitHostInput(input: { itemId: string }): void;
|
|
21
|
+
resolveHostInput(input: { itemId: string }): void;
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
export function createCodexStepTracker(input: {
|
|
@@ -24,6 +26,14 @@ export function createCodexStepTracker(input: {
|
|
|
24
26
|
}): CodexStepTracker {
|
|
25
27
|
let stepOpen = false;
|
|
26
28
|
const pendingToolItemIds = new Set<string>();
|
|
29
|
+
/*
|
|
30
|
+
* Dynamic tool calls waiting for the host to return their result. When
|
|
31
|
+
* every pending tool item waits on the host, Codex cannot make progress, so
|
|
32
|
+
* the tracker emits an early `finish-step` that lets the host pause the
|
|
33
|
+
* turn. The step stays open until the regular `finish-step`.
|
|
34
|
+
*/
|
|
35
|
+
const hostInputWaitingItemIds = new Set<string>();
|
|
36
|
+
const earlyFinishStepItemIds = new Set<string>();
|
|
27
37
|
|
|
28
38
|
const finishStep = (): void => {
|
|
29
39
|
if (!stepOpen || pendingToolItemIds.size > 0) return;
|
|
@@ -34,6 +44,25 @@ export function createCodexStepTracker(input: {
|
|
|
34
44
|
harnessMetadata: { codex: { inferredStep: true } },
|
|
35
45
|
});
|
|
36
46
|
stepOpen = false;
|
|
47
|
+
earlyFinishStepItemIds.clear();
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const emitEarlyFinishStepIfReady = (): void => {
|
|
51
|
+
if (!stepOpen || pendingToolItemIds.size === 0) return;
|
|
52
|
+
for (const itemId of pendingToolItemIds) {
|
|
53
|
+
if (!hostInputWaitingItemIds.has(itemId)) return;
|
|
54
|
+
}
|
|
55
|
+
const uncovered = [...pendingToolItemIds].filter(
|
|
56
|
+
itemId => !earlyFinishStepItemIds.has(itemId),
|
|
57
|
+
);
|
|
58
|
+
if (uncovered.length === 0) return;
|
|
59
|
+
for (const itemId of uncovered) earlyFinishStepItemIds.add(itemId);
|
|
60
|
+
input.send({
|
|
61
|
+
type: 'finish-step',
|
|
62
|
+
finishReason: { unified: 'tool-calls', raw: 'host-input' },
|
|
63
|
+
usage: defaultUsage(),
|
|
64
|
+
harnessMetadata: { codex: { inferredStep: true } },
|
|
65
|
+
});
|
|
37
66
|
};
|
|
38
67
|
|
|
39
68
|
return {
|
|
@@ -46,6 +75,7 @@ export function createCodexStepTracker(input: {
|
|
|
46
75
|
if (isToolStepItem(item)) {
|
|
47
76
|
if (event.type === 'item.started' && itemId) {
|
|
48
77
|
pendingToolItemIds.add(itemId);
|
|
78
|
+
emitEarlyFinishStepIfReady();
|
|
49
79
|
} else if (event.type === 'item.completed') {
|
|
50
80
|
if (itemId) pendingToolItemIds.delete(itemId);
|
|
51
81
|
finishStep();
|
|
@@ -54,8 +84,18 @@ export function createCodexStepTracker(input: {
|
|
|
54
84
|
},
|
|
55
85
|
finishTurn() {
|
|
56
86
|
pendingToolItemIds.clear();
|
|
87
|
+
hostInputWaitingItemIds.clear();
|
|
57
88
|
finishStep();
|
|
58
89
|
},
|
|
90
|
+
awaitHostInput({ itemId }) {
|
|
91
|
+
stepOpen = true;
|
|
92
|
+
pendingToolItemIds.add(itemId);
|
|
93
|
+
hostInputWaitingItemIds.add(itemId);
|
|
94
|
+
emitEarlyFinishStepIfReady();
|
|
95
|
+
},
|
|
96
|
+
resolveHostInput({ itemId }) {
|
|
97
|
+
hostInputWaitingItemIds.delete(itemId);
|
|
98
|
+
},
|
|
59
99
|
};
|
|
60
100
|
}
|
|
61
101
|
|
package/src/codex-harness.ts
CHANGED