@jskit-ai/assistant-core 0.2.7 → 0.2.8
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/examples/conversation/package.json +5 -5
- package/package.json +18 -7
- package/src/client/browser.js +21 -0
- package/src/client/conversation/AssistantAttachmentQueue.vue +25 -108
- package/src/client/conversation/AssistantComposerActions.vue +1 -1
- package/src/client/conversation/AssistantConversationElement.vue +14 -52
- package/src/client/conversation/AssistantGoalControl.vue +13 -10
- package/src/client/conversation/AssistantPromptInput.vue +6 -91
- package/src/client/conversation/AssistantTranscript.css +505 -0
- package/src/client/conversation/AssistantTranscript.vue +24 -1197
- package/src/client/conversation/attachmentFiles.js +158 -0
- package/src/client/conversation/attachmentQueueItems.js +121 -0
- package/src/client/conversation/attachmentUploadRows.js +265 -0
- package/src/client/conversation/conversationDisplay.js +54 -0
- package/src/client/conversation/messageDelivery.js +13 -9
- package/src/client/conversation/retainedConversation.js +14 -3
- package/src/client/conversation/submitText.js +13 -2
- package/src/client/conversation/transcriptEntries.js +225 -0
- package/src/client/conversation/useAssistantAttachments.js +86 -388
- package/src/client/conversation/useAssistantQuestions.js +16 -3
- package/src/client/conversation/useAssistantSuggestions.js +16 -2
- package/src/client/conversation/useScrollToBottom.js +17 -19
- package/src/client/conversation/useTextareaAutoGrow.js +115 -0
- package/src/client/conversation/useTranscriptScrollFollow.js +525 -0
- package/src/client/lib/assistantApi.js +192 -161
- package/src/client/types.js +110 -0
- package/src/server/conversation/attachments.js +21 -6
- package/src/server/conversation/boundedToolLoop.js +1 -0
- package/src/server/conversation/claudeClient.js +71 -20
- package/src/server/conversation/claudeCommandRun.js +191 -0
- package/src/server/conversation/claudeHistory.js +7 -0
- package/src/server/conversation/claudeNativeTurn.js +708 -0
- package/src/server/conversation/claudeProcess.js +186 -112
- package/src/server/conversation/claudeProcessStart.js +214 -0
- package/src/server/conversation/claudePromptDelivery.js +183 -0
- package/src/server/conversation/claudeSessionCleanup.js +248 -0
- package/src/server/conversation/claudeTools.js +15 -3
- package/src/server/conversation/claudeTurn.js +212 -1388
- package/src/server/conversation/codexAccountReader.js +168 -0
- package/src/server/conversation/codexAuthPreflight.js +5 -4
- package/src/server/conversation/codexClient.js +18 -6
- package/src/server/conversation/codexConfiguration.js +8 -844
- package/src/server/conversation/codexConversationStops.js +377 -0
- package/src/server/conversation/codexConversationStore.js +119 -85
- package/src/server/conversation/codexConversationTurns.js +378 -0
- package/src/server/conversation/codexConversations.js +134 -866
- package/src/server/conversation/codexDetachedConversation.js +203 -0
- package/src/server/conversation/codexDetachedTurn.js +145 -104
- package/src/server/conversation/codexEvents.js +5 -200
- package/src/server/conversation/codexGoalCommands.js +14 -4
- package/src/server/conversation/codexHelperExecution.js +57 -57
- package/src/server/conversation/codexHelperThreadLedger.js +30 -288
- package/src/server/conversation/codexHelperThreadRecord.js +304 -0
- package/src/server/conversation/codexHelperThreadRecovery.js +54 -76
- package/src/server/conversation/codexHelperThreads.js +94 -93
- package/src/server/conversation/codexHistoryAdapter.js +13 -8
- package/src/server/conversation/codexIsolation.js +672 -0
- package/src/server/conversation/codexLiveItems.js +379 -0
- package/src/server/conversation/codexMessageCommands.js +68 -286
- package/src/server/conversation/codexMessageDelivery.js +46 -37
- package/src/server/conversation/codexModelCatalog.js +86 -7
- package/src/server/conversation/codexNotificationObserver.js +81 -88
- package/src/server/conversation/codexNotificationQueue.js +21 -10
- package/src/server/conversation/codexObservationControl.js +105 -89
- package/src/server/conversation/codexOutput.js +84 -419
- package/src/server/conversation/codexProcess.js +29 -1053
- package/src/server/conversation/codexProcessLeader.js +1 -0
- package/src/server/conversation/codexPromptDispatch.js +241 -0
- package/src/server/conversation/codexProvider.js +147 -1807
- package/src/server/conversation/codexProviderAuth.js +348 -0
- package/src/server/conversation/codexProviderInvalidation.js +371 -0
- package/src/server/conversation/codexProviderInventories.js +437 -0
- package/src/server/conversation/codexProviderOwner.js +149 -957
- package/src/server/conversation/codexProviderRelease.js +465 -0
- package/src/server/conversation/codexProviderSelection.js +26 -15
- package/src/server/conversation/codexProviderThreads.js +698 -0
- package/src/server/conversation/codexProviderTurns.js +453 -0
- package/src/server/conversation/codexReasoning.js +32 -23
- package/src/server/conversation/codexRenewalCommands.js +18 -6
- package/src/server/conversation/codexRenewalThreads.js +7 -22
- package/src/server/conversation/codexResultSettlement.js +70 -88
- package/src/server/conversation/codexRunJournal.js +91 -97
- package/src/server/conversation/codexRuntime.js +426 -0
- package/src/server/conversation/codexRuntimeInventory.js +113 -0
- package/src/server/conversation/codexRuntimeLifecycle.js +39 -13
- package/src/server/conversation/codexRuntimeStart.js +431 -0
- package/src/server/conversation/codexRuntimeStop.js +324 -0
- package/src/server/conversation/codexSessionCleanup.js +25 -10
- package/src/server/conversation/codexSessionReconciliation.js +21 -7
- package/src/server/conversation/codexThreadReadiness.js +49 -52
- package/src/server/conversation/codexThreadSnapshot.js +210 -0
- package/src/server/conversation/codexThreadStatus.js +48 -62
- package/src/server/conversation/codexTurn.js +171 -55
- package/src/server/conversation/codexTurnActivity.js +210 -0
- package/src/server/conversation/codexTurnControl.js +44 -48
- package/src/server/conversation/codexTurnEndings.js +610 -0
- package/src/server/conversation/codexTurnRecovery.js +97 -848
- package/src/server/conversation/codexTurnState.js +138 -111
- package/src/server/conversation/completedResponses.js +227 -0
- package/src/server/conversation/configuration.js +2 -2
- package/src/server/conversation/continuity.js +43 -6
- package/src/server/conversation/conversationDelivery.js +394 -0
- package/src/server/conversation/conversationEntries.js +365 -0
- package/src/server/conversation/conversationEvents.js +192 -0
- package/src/server/conversation/conversationGoals.js +187 -0
- package/src/server/conversation/conversationHandles.js +237 -0
- package/src/server/conversation/conversationReads.js +206 -0
- package/src/server/conversation/conversationRefusals.js +58 -0
- package/src/server/conversation/conversationReplacement.js +254 -0
- package/src/server/conversation/conversationSending.js +273 -0
- package/src/server/conversation/conversationStopping.js +121 -0
- package/src/server/conversation/conversationTurnDelivery.js +413 -0
- package/src/server/conversation/conversationTurns.js +511 -0
- package/src/server/conversation/deliveryTiming.js +25 -3
- package/src/server/conversation/fileStorage.js +11 -6
- package/src/server/conversation/hookBridge.js +14 -3
- package/src/server/conversation/index.js +1 -1
- package/src/server/conversation/localExecution.js +82 -625
- package/src/server/conversation/nativeCommandCallbacks.js +10 -0
- package/src/server/conversation/nativeConversationLifecycle.js +379 -0
- package/src/server/conversation/nativeHistoryExport.js +27 -18
- package/src/server/conversation/normalize.js +9 -0
- package/src/server/conversation/openCodeClient.js +295 -366
- package/src/server/conversation/openCodeNativeHistory.js +141 -0
- package/src/server/conversation/openCodeNativeSession.js +79 -0
- package/src/server/conversation/openCodeProcess.js +109 -53
- package/src/server/conversation/openCodeProcessOwner.js +565 -0
- package/src/server/conversation/openCodeRuntime.js +111 -1814
- package/src/server/conversation/openCodeSessionTurns.js +547 -0
- package/src/server/conversation/openCodeTemporaryConversations.js +394 -0
- package/src/server/conversation/openCodeTools.js +28 -14
- package/src/server/conversation/openCodeTurn.js +80 -74
- package/src/server/conversation/openCodeTurnMonitor.js +388 -0
- package/src/server/conversation/processIdentity.js +582 -0
- package/src/server/conversation/provider.js +21 -6
- package/src/server/conversation/providers/api.js +268 -107
- package/src/server/conversation/providers/claude.js +29 -6
- package/src/server/conversation/providers/claudeDriver.js +325 -250
- package/src/server/conversation/providers/codex.js +69 -33
- package/src/server/conversation/providers/codexDriver.js +503 -1081
- package/src/server/conversation/providers/codexDriverConnection.js +331 -0
- package/src/server/conversation/providers/codexDriverTurns.js +464 -0
- package/src/server/conversation/providers/opencode.js +30 -4
- package/src/server/conversation/providers/opencodeDriver.js +321 -659
- package/src/server/conversation/providers/opencodeStandalone.js +475 -0
- package/src/server/conversation/providers/scoped.js +64 -19
- package/src/server/conversation/runtime.js +171 -2863
- package/src/server/conversation/storage.js +91 -50
- package/src/server/conversation/streams.js +15 -2
- package/src/server/conversation/structuredOutput.js +7 -11
- package/src/server/conversation/systemPrompt.js +13 -1
- package/src/server/conversation/tools.js +47 -15
- package/src/server/conversation/transcript.js +49 -20
- package/src/server/hosts/claudeTurn.js +2 -4
- package/src/server/hosts/codexConfiguration.js +6 -8
- package/src/server/hosts/codexEvents.js +4 -2
- package/src/server/hosts/codexProcess.js +1 -1
- package/src/server/hosts/codexProvider.js +11 -9
- package/src/server/hosts/codexTurn.js +3 -3
- package/src/server/hosts/openCodeClient.js +4 -2
- package/src/server/index.js +0 -2
- package/src/server/lib/aiConnectionClient.js +35 -25
- package/src/server/lib/ndjson.js +1 -0
- package/src/server/lib/providers/anthropicClient.js +15 -6
- package/src/server/lib/providers/common.js +10 -6
- package/src/server/lib/providers/openAiCompatibleClient.js +40 -23
- package/src/server/lib/serviceToolCatalog.js +29 -283
- package/src/server/lib/serviceToolEntries.js +270 -0
- package/src/server/types.js +78 -0
- package/src/shared/assistantResource.js +0 -23
- package/src/shared/conversation/answerChoiceSugar.js +2 -14
- package/src/shared/conversation/messageInputSugar.js +18 -0
- package/src/shared/conversation/numberedQuestionSugar.js +6 -16
- package/src/shared/conversation/pagination.js +1 -1
- package/src/shared/conversation/questions.js +1 -0
- package/src/shared/conversation/streaming.js +1 -0
- package/src/shared/index.js +0 -1
- package/src/testing/conversationStorageContract.js +20 -0
- package/test/aiConnectionClient.test.js +42 -1
- package/test/apiConversationDriver.test.js +217 -38
- package/test/assistantBoundedToolLoop.test.js +1 -1
- package/test/claudeConversationSession.test.js +15 -11
- package/test/claudeInstructionResume.test.js +1 -1
- package/test/claudeProcess.test.js +9 -9
- package/test/claudeTurn.test.js +21 -8
- package/test/codexAccountChange.test.js +5 -3
- package/test/codexConversationSession.test.js +22 -21
- package/test/codexEvents.test.js +3 -1
- package/test/codexHelperDeletion.test.js +3 -7
- package/test/codexIsolation.test.js +6 -6
- package/test/codexModelCatalog.test.js +6 -7
- package/test/codexProcess.test.js +3 -3
- package/test/codexThreadSelection.test.js +4 -1
- package/test/codexTurn.test.js +29 -20
- package/test/conversationApiFacilities.test.js +11 -9
- package/test/conversationAttachments.test.js +3 -3
- package/test/conversationConfiguration.test.js +4 -4
- package/test/conversationNativeStorage.test.js +11 -10
- package/test/conversationReplacement.test.js +13 -13
- package/test/conversationRuntime.test.js +9 -5
- package/test/conversationSession.test.js +78 -22
- package/test/conversationTools.test.js +47 -26
- package/test/fileConversationStorage.test.js +10 -3
- package/test/fixtures/codexHelperThreadLedger.js +3 -3
- package/test/frameworkActions.test.js +33 -18
- package/test/localConversationExecution.test.js +4 -4
- package/test/localExecution.test.js +1 -1
- package/test/openCodeConnectionChange.test.js +3 -2
- package/test/openCodeRuntime.test.js +8 -7
- package/test/openCodeTools.test.js +1 -1
- package/test/opencodeConversationSession.test.js +4 -3
- package/test/serviceToolCatalog.test.js +3 -8
- package/src/server/lib/assistantCompletion.js +0 -190
- package/src/server/lib/assistantToolLoop.js +0 -259
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import { isRecord, normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
2
3
|
import { normalizeNullableText } from "./normalize.js";
|
|
3
|
-
import { codexAppServerStatusFromValue
|
|
4
|
+
import { codexAppServerStatusFromValue } from "./codexEvents.js";
|
|
5
|
+
import { codexAppServerThreadRawValue } from "./codexThreadSnapshot.js";
|
|
4
6
|
|
|
5
7
|
function codexAppServerTurnStatusIsActive(status = "") {
|
|
6
8
|
return normalizeNullableText(status) === "inProgress";
|
|
@@ -36,6 +38,12 @@ function codexAppServerThreadStatus(thread = {}) {
|
|
|
36
38
|
return liveStatus;
|
|
37
39
|
}
|
|
38
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Reads a native thread's status, and with observeLatestTurn its latest turn too.
|
|
43
|
+
* @param {import("./codexProvider.js").CodexAppServerAgentProvider | null} provider
|
|
44
|
+
* @param {string} threadId
|
|
45
|
+
* @param {{ observeLatestTurn?: boolean }} [options]
|
|
46
|
+
*/
|
|
39
47
|
async function codexAppServerReadThreadStatus(provider = null, threadId = "", {
|
|
40
48
|
observeLatestTurn = false
|
|
41
49
|
} = {}) {
|
|
@@ -43,9 +51,9 @@ async function codexAppServerReadThreadStatus(provider = null, threadId = "", {
|
|
|
43
51
|
if (!normalizedThreadId) {
|
|
44
52
|
return null;
|
|
45
53
|
}
|
|
46
|
-
if (
|
|
54
|
+
if (provider) {
|
|
47
55
|
const thread = await provider.readThreadStatus(normalizedThreadId);
|
|
48
|
-
if (!observeLatestTurn
|
|
56
|
+
if (!observeLatestTurn) {
|
|
49
57
|
return thread;
|
|
50
58
|
}
|
|
51
59
|
const response = await provider.listThreadTurns(normalizedThreadId, {
|
|
@@ -54,7 +62,7 @@ async function codexAppServerReadThreadStatus(provider = null, threadId = "", {
|
|
|
54
62
|
sortDirection: "desc"
|
|
55
63
|
});
|
|
56
64
|
const observedTurn = Array.isArray(response?.data) ? response.data[0] : null;
|
|
57
|
-
if (provider.isControlProbeTurn
|
|
65
|
+
if (provider.isControlProbeTurn(normalizedThreadId, observedTurn?.id)) return thread;
|
|
58
66
|
return isRecord(observedTurn)
|
|
59
67
|
? {
|
|
60
68
|
...thread,
|
|
@@ -65,9 +73,9 @@ async function codexAppServerReadThreadStatus(provider = null, threadId = "", {
|
|
|
65
73
|
return null;
|
|
66
74
|
}
|
|
67
75
|
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
// request journal
|
|
76
|
+
// The native run projection and its guarded mutation sequence. The caller's
|
|
77
|
+
// runtime store owns persistence and its mutation lock; there is no second
|
|
78
|
+
// request journal and no ownership derived from the transcript.
|
|
71
79
|
const CODEX_APP_SERVER_AGENT_RUN_ID = "codex_app_server";
|
|
72
80
|
const CODEX_APP_SERVER_RESULT_PROCESSED_EVENT = "codex-app-server-result-processed";
|
|
73
81
|
const CODEX_AGENT_PROVIDER = "codex";
|
|
@@ -95,16 +103,12 @@ const CODEX_APP_SERVER_ACTIVE_RUN_STATES = new Set([
|
|
|
95
103
|
CODEX_APP_SERVER_RUN_STATE.STARTING
|
|
96
104
|
]);
|
|
97
105
|
|
|
98
|
-
function
|
|
99
|
-
return
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function codexAppServerRunInputSource(run = {}) {
|
|
103
|
-
return normalizeCodexRunText(run?.inputSource);
|
|
106
|
+
function codexAppServerRunInputSource(run) {
|
|
107
|
+
return normalizeText(run?.inputSource);
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
export function normalizeCodexAppServerRunState(state) {
|
|
107
|
-
const normalizedState =
|
|
111
|
+
const normalizedState = normalizeText(state) || CODEX_APP_SERVER_RUN_STATE.STARTING;
|
|
108
112
|
if (!CODEX_APP_SERVER_RUN_STATES.has(normalizedState)) {
|
|
109
113
|
throw Object.assign(new Error(`Invalid Codex app-server run state: ${normalizedState}`), {
|
|
110
114
|
code: "codex_app_server_invalid_run_state"
|
|
@@ -123,19 +127,19 @@ export function codexAppServerRunStateIsTerminal(state) {
|
|
|
123
127
|
|
|
124
128
|
export function codexAppServerAgentRun(session = {}) {
|
|
125
129
|
const runs = Array.isArray(session.agentRuns) ? session.agentRuns : [];
|
|
126
|
-
return runs.find((run) =>
|
|
130
|
+
return runs.find((run) => normalizeText(run?.id) === CODEX_APP_SERVER_AGENT_RUN_ID) || null;
|
|
127
131
|
}
|
|
128
132
|
|
|
129
|
-
export function codexAppServerPendingUserMessageClientIds(run
|
|
133
|
+
export function codexAppServerPendingUserMessageClientIds(run) {
|
|
130
134
|
const ids = run?.pendingUserMessageClientIds;
|
|
131
135
|
return (Array.isArray(ids) ? ids : [])
|
|
132
|
-
.map((id) =>
|
|
136
|
+
.map((id) => normalizeText(id))
|
|
133
137
|
.filter(Boolean);
|
|
134
138
|
}
|
|
135
139
|
|
|
136
|
-
export function codexAppServerPendingUserMessageOwnership(run
|
|
140
|
+
export function codexAppServerPendingUserMessageOwnership(run, clientId = "") {
|
|
137
141
|
const pendingClientIds = codexAppServerPendingUserMessageClientIds(run);
|
|
138
|
-
const normalizedClientId =
|
|
142
|
+
const normalizedClientId = normalizeText(clientId);
|
|
139
143
|
const ownedClientId = normalizedClientId
|
|
140
144
|
? pendingClientIds.find((id) => id === normalizedClientId)
|
|
141
145
|
: pendingClientIds[0];
|
|
@@ -144,18 +148,18 @@ export function codexAppServerPendingUserMessageOwnership(run = {}, clientId = "
|
|
|
144
148
|
}
|
|
145
149
|
return {
|
|
146
150
|
clientId: ownedClientId,
|
|
147
|
-
inputSource:
|
|
151
|
+
inputSource: normalizeText(run?.inputSource)
|
|
148
152
|
};
|
|
149
153
|
}
|
|
150
154
|
|
|
151
155
|
export function codexAppServerProcessedResultEvent(session = {}, threadId = "", turnId = "") {
|
|
152
|
-
const normalizedThreadId =
|
|
153
|
-
const normalizedTurnId =
|
|
156
|
+
const normalizedThreadId = normalizeText(threadId);
|
|
157
|
+
const normalizedTurnId = normalizeText(turnId);
|
|
154
158
|
const events = codexAppServerAgentRun(session)?.events;
|
|
155
159
|
return (Array.isArray(events) ? events : []).findLast((event) => (
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
160
|
+
normalizeText(event?.kind) === CODEX_APP_SERVER_RESULT_PROCESSED_EVENT &&
|
|
161
|
+
normalizeText(event?.providerThreadId) === normalizedThreadId &&
|
|
162
|
+
normalizeText(event?.providerTurnId) === normalizedTurnId
|
|
159
163
|
)) || null;
|
|
160
164
|
}
|
|
161
165
|
|
|
@@ -171,21 +175,21 @@ export function codexAppServerTurnStateFromAgentRun(run = {}, normalizeRunState
|
|
|
171
175
|
: "idle";
|
|
172
176
|
return {
|
|
173
177
|
active,
|
|
174
|
-
completedAt:
|
|
175
|
-
error:
|
|
176
|
-
goalStatus:
|
|
177
|
-
goalThreadId:
|
|
178
|
-
inputSource:
|
|
179
|
-
outerTurnId:
|
|
180
|
-
phase: active && run.providerStatus !== "observation_lost" ?
|
|
181
|
-
runId:
|
|
178
|
+
completedAt: normalizeText(run.finishedAt),
|
|
179
|
+
error: normalizeText(run.error),
|
|
180
|
+
goalStatus: normalizeText(run.providerGoalStatus),
|
|
181
|
+
goalThreadId: normalizeText(run.providerGoalThreadId),
|
|
182
|
+
inputSource: normalizeText(run.inputSource),
|
|
183
|
+
outerTurnId: normalizeText(run.outerTurnId),
|
|
184
|
+
phase: active && run.providerStatus !== "observation_lost" ? normalizeText(run.providerPhase) : "",
|
|
185
|
+
runId: normalizeText(run.id),
|
|
182
186
|
runState,
|
|
183
|
-
startedAt:
|
|
187
|
+
startedAt: normalizeText(run.startedAt),
|
|
184
188
|
state,
|
|
185
|
-
status:
|
|
186
|
-
threadId:
|
|
187
|
-
turnId:
|
|
188
|
-
updatedAt:
|
|
189
|
+
status: normalizeText(run.providerStatus || run.status || runState),
|
|
190
|
+
threadId: normalizeText(run.providerThreadId),
|
|
191
|
+
turnId: normalizeText(run.providerTurnId),
|
|
192
|
+
updatedAt: normalizeText(run.updatedAt)
|
|
189
193
|
};
|
|
190
194
|
}
|
|
191
195
|
|
|
@@ -215,23 +219,23 @@ export function codexAppServerTurnState(session = {}, normalizeRunState = normal
|
|
|
215
219
|
}
|
|
216
220
|
|
|
217
221
|
export function codexAppServerTurnOwnsActiveGoal(turn = {}, threadId = "") {
|
|
218
|
-
const normalizedThreadId =
|
|
219
|
-
const goalThreadId =
|
|
220
|
-
const inputSource =
|
|
221
|
-
return
|
|
222
|
+
const normalizedThreadId = normalizeText(threadId);
|
|
223
|
+
const goalThreadId = normalizeText(turn.goalThreadId);
|
|
224
|
+
const inputSource = normalizeText(turn.inputSource);
|
|
225
|
+
return normalizeText(turn.goalStatus) === "active" &&
|
|
222
226
|
Boolean(normalizedThreadId) &&
|
|
223
227
|
goalThreadId === normalizedThreadId &&
|
|
224
|
-
Boolean(
|
|
228
|
+
Boolean(normalizeText(turn.outerTurnId)) &&
|
|
225
229
|
Boolean(inputSource) &&
|
|
226
230
|
inputSource !== "terminal";
|
|
227
231
|
}
|
|
228
232
|
|
|
229
233
|
export function codexAppServerTurnMatches(turn = {}, threadId = "", turnId = "") {
|
|
230
|
-
const normalizedThreadId =
|
|
231
|
-
const normalizedTurnId =
|
|
232
|
-
const currentThreadId =
|
|
233
|
-
const currentTurnId =
|
|
234
|
-
if (normalizedThreadId &&
|
|
234
|
+
const normalizedThreadId = normalizeText(threadId);
|
|
235
|
+
const normalizedTurnId = normalizeText(turnId);
|
|
236
|
+
const currentThreadId = normalizeText(turn.threadId);
|
|
237
|
+
const currentTurnId = normalizeText(turn.turnId);
|
|
238
|
+
if (normalizedThreadId && normalizeText(turn.threadId) !== normalizedThreadId) {
|
|
235
239
|
return false;
|
|
236
240
|
}
|
|
237
241
|
if (normalizedTurnId && currentTurnId && currentTurnId !== normalizedTurnId) {
|
|
@@ -248,26 +252,26 @@ export function codexAppServerTurnMatches(turn = {}, threadId = "", turnId = "")
|
|
|
248
252
|
|
|
249
253
|
export function codexAppServerTurnCanReceiveProviderCompletion(turn = {}, threadId = "", turnId = "") {
|
|
250
254
|
return codexAppServerTurnMatches(turn, threadId, turnId) &&
|
|
251
|
-
["active", "finalizing"].includes(
|
|
255
|
+
["active", "finalizing"].includes(normalizeText(turn.state));
|
|
252
256
|
}
|
|
253
257
|
|
|
254
258
|
export function codexAppServerTurnAwaitsProviderIdentity(turn = {}, threadId = "", turnId = "") {
|
|
255
|
-
const normalizedThreadId =
|
|
256
|
-
const normalizedTurnId =
|
|
257
|
-
const currentThreadId =
|
|
258
|
-
return
|
|
259
|
+
const normalizedThreadId = normalizeText(threadId);
|
|
260
|
+
const normalizedTurnId = normalizeText(turnId);
|
|
261
|
+
const currentThreadId = normalizeText(turn.threadId);
|
|
262
|
+
return normalizeText(turn.state) === "starting" &&
|
|
259
263
|
Boolean(normalizedTurnId) &&
|
|
260
|
-
!
|
|
264
|
+
!normalizeText(turn.turnId) &&
|
|
261
265
|
(!normalizedThreadId || !currentThreadId || normalizedThreadId === currentThreadId);
|
|
262
266
|
}
|
|
263
267
|
|
|
264
268
|
export function codexAppServerTurnCanReceiveProviderActivity(turn = {}, threadId = "", turnId = "") {
|
|
265
269
|
if (turn.status === "observation_lost") return false;
|
|
266
|
-
const normalizedThreadId =
|
|
267
|
-
const normalizedTurnId =
|
|
268
|
-
const currentThreadId =
|
|
269
|
-
const currentTurnId =
|
|
270
|
-
if (!["starting", "active"].includes(
|
|
270
|
+
const normalizedThreadId = normalizeText(threadId);
|
|
271
|
+
const normalizedTurnId = normalizeText(turnId);
|
|
272
|
+
const currentThreadId = normalizeText(turn.threadId);
|
|
273
|
+
const currentTurnId = normalizeText(turn.turnId);
|
|
274
|
+
if (!["starting", "active"].includes(normalizeText(turn.state))) {
|
|
271
275
|
return false;
|
|
272
276
|
}
|
|
273
277
|
if (normalizedThreadId && currentThreadId && currentThreadId !== normalizedThreadId) {
|
|
@@ -284,12 +288,12 @@ export function codexAppServerTurnCanReceiveProviderActivity(turn = {}, threadId
|
|
|
284
288
|
|
|
285
289
|
export function codexAppServerTurnCanAdoptSuccessor(turn = {}, threadId = "", turnId = "") {
|
|
286
290
|
if (turn.status === "observation_lost") return false;
|
|
287
|
-
const normalizedThreadId =
|
|
288
|
-
const normalizedTurnId =
|
|
289
|
-
const currentThreadId =
|
|
290
|
-
const currentTurnId =
|
|
291
|
+
const normalizedThreadId = normalizeText(threadId);
|
|
292
|
+
const normalizedTurnId = normalizeText(turnId);
|
|
293
|
+
const currentThreadId = normalizeText(turn.threadId);
|
|
294
|
+
const currentTurnId = normalizeText(turn.turnId);
|
|
291
295
|
return turn.active === true &&
|
|
292
|
-
["active", "finalizing"].includes(
|
|
296
|
+
["active", "finalizing"].includes(normalizeText(turn.state)) &&
|
|
293
297
|
Boolean(normalizedThreadId) &&
|
|
294
298
|
normalizedThreadId === currentThreadId &&
|
|
295
299
|
Boolean(normalizedTurnId) &&
|
|
@@ -298,7 +302,30 @@ export function codexAppServerTurnCanAdoptSuccessor(turn = {}, threadId = "", tu
|
|
|
298
302
|
}
|
|
299
303
|
|
|
300
304
|
export function codexAppServerTurnKey(threadId = "", turnId = "") {
|
|
301
|
-
return `${
|
|
305
|
+
return `${normalizeText(threadId)}:${normalizeText(turnId)}`;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Identity of a native conversation message, derived from its thread, turn, role and text.
|
|
309
|
+
export function codexAppServerConversationMessageId(
|
|
310
|
+
threadId = "",
|
|
311
|
+
turnId = "",
|
|
312
|
+
role = "",
|
|
313
|
+
text = ""
|
|
314
|
+
) {
|
|
315
|
+
const normalizedText = normalizeText(text);
|
|
316
|
+
const normalizedThreadId = normalizeText(threadId);
|
|
317
|
+
if (!normalizedText || !normalizedThreadId) {
|
|
318
|
+
return "";
|
|
319
|
+
}
|
|
320
|
+
const digest = crypto.createHash("sha256")
|
|
321
|
+
.update([
|
|
322
|
+
normalizedThreadId,
|
|
323
|
+
normalizeText(turnId) || "*",
|
|
324
|
+
normalizeText(role),
|
|
325
|
+
normalizedText
|
|
326
|
+
].join("\u0000"))
|
|
327
|
+
.digest("hex");
|
|
328
|
+
return `codex-${digest}`;
|
|
302
329
|
}
|
|
303
330
|
|
|
304
331
|
// Identity of a native outer turn. Terminal turns and persistent-conversation
|
|
@@ -322,31 +349,31 @@ export function codexAppServerAgentRunPatch({
|
|
|
322
349
|
const normalizedRunState = normalizeRunState(runState);
|
|
323
350
|
const currentRun = codexAppServerAgentRun(session);
|
|
324
351
|
const sameActiveTurn = normalizedRunState === CODEX_APP_SERVER_RUN_STATE.ACTIVE &&
|
|
325
|
-
currentRun?.providerThreadId ===
|
|
326
|
-
currentRun?.providerTurnId ===
|
|
352
|
+
currentRun?.providerThreadId === normalizeText(threadId) &&
|
|
353
|
+
currentRun?.providerTurnId === normalizeText(turnId);
|
|
327
354
|
const patch = {
|
|
328
|
-
error:
|
|
355
|
+
error: normalizeText(error),
|
|
329
356
|
provider: CODEX_AGENT_PROVIDER,
|
|
330
357
|
providerInterface: "codex_app_server",
|
|
331
358
|
providerPhase: normalizedRunState === CODEX_APP_SERVER_RUN_STATE.ACTIVE && status !== "observation_lost"
|
|
332
|
-
?
|
|
359
|
+
? normalizeText(phase === undefined && sameActiveTurn ? currentRun?.providerPhase : phase)
|
|
333
360
|
: "",
|
|
334
|
-
providerStatus:
|
|
335
|
-
providerThreadId:
|
|
336
|
-
providerTurnId:
|
|
361
|
+
providerStatus: normalizeText(status),
|
|
362
|
+
providerThreadId: normalizeText(threadId),
|
|
363
|
+
providerTurnId: normalizeText(turnId),
|
|
337
364
|
state: normalizedRunState,
|
|
338
|
-
updatedAt:
|
|
365
|
+
updatedAt: normalizeText(updatedAt)
|
|
339
366
|
};
|
|
340
|
-
const normalizedInputSource =
|
|
367
|
+
const normalizedInputSource = normalizeText(inputSource);
|
|
341
368
|
if (normalizedInputSource) {
|
|
342
369
|
patch.inputSource = normalizedInputSource;
|
|
343
370
|
}
|
|
344
371
|
// A native terminal turn starts its own chat owner. Reusing the previous
|
|
345
372
|
// owner's id would checkpoint two different turns with one identity.
|
|
346
|
-
const normalizedOuterTurnId =
|
|
373
|
+
const normalizedOuterTurnId = normalizeText(outerTurnId) ||
|
|
347
374
|
(normalizedInputSource === "terminal" && normalizedRunState === CODEX_APP_SERVER_RUN_STATE.ACTIVE && !sameActiveTurn
|
|
348
|
-
? codexAppServerNativeOuterTurnId(
|
|
349
|
-
:
|
|
375
|
+
? codexAppServerNativeOuterTurnId(normalizeText(threadId), normalizeText(turnId))
|
|
376
|
+
: normalizeText(currentRun?.outerTurnId));
|
|
350
377
|
if (normalizedOuterTurnId) {
|
|
351
378
|
patch.outerTurnId = normalizedOuterTurnId;
|
|
352
379
|
}
|
|
@@ -358,10 +385,10 @@ export function codexAppServerAgentRunPatch({
|
|
|
358
385
|
patch.pendingUserMessageClientIds = [];
|
|
359
386
|
}
|
|
360
387
|
if ([CODEX_APP_SERVER_RUN_STATE.ACTIVE, CODEX_APP_SERVER_RUN_STATE.STARTING].includes(normalizedRunState)) {
|
|
361
|
-
patch.startedAt =
|
|
388
|
+
patch.startedAt = normalizeText(updatedAt);
|
|
362
389
|
}
|
|
363
390
|
if (!codexAppServerRunStateIsActive(normalizedRunState)) {
|
|
364
|
-
patch.finishedAt =
|
|
391
|
+
patch.finishedAt = normalizeText(updatedAt);
|
|
365
392
|
}
|
|
366
393
|
return patch;
|
|
367
394
|
}
|
|
@@ -370,8 +397,8 @@ export function codexAppServerRunIdentityForPatch(session = {}, {
|
|
|
370
397
|
threadId = "",
|
|
371
398
|
turnId = ""
|
|
372
399
|
} = {}, normalizeRunState = normalizeCodexAppServerRunState) {
|
|
373
|
-
const normalizedThreadId =
|
|
374
|
-
const normalizedTurnId =
|
|
400
|
+
const normalizedThreadId = normalizeText(threadId);
|
|
401
|
+
const normalizedTurnId = normalizeText(turnId);
|
|
375
402
|
if (normalizedTurnId) {
|
|
376
403
|
return {
|
|
377
404
|
threadId: normalizedThreadId,
|
|
@@ -379,10 +406,10 @@ export function codexAppServerRunIdentityForPatch(session = {}, {
|
|
|
379
406
|
};
|
|
380
407
|
}
|
|
381
408
|
const currentTurn = codexAppServerTurnState(session, normalizeRunState);
|
|
382
|
-
const currentThreadId =
|
|
409
|
+
const currentThreadId = normalizeText(currentTurn.threadId);
|
|
383
410
|
if (
|
|
384
|
-
|
|
385
|
-
["active", "finalizing"].includes(
|
|
411
|
+
normalizeText(currentTurn.turnId) &&
|
|
412
|
+
["active", "finalizing"].includes(normalizeText(currentTurn.state)) &&
|
|
386
413
|
(!normalizedThreadId || !currentThreadId || normalizedThreadId === currentThreadId)
|
|
387
414
|
) {
|
|
388
415
|
return {
|
|
@@ -399,8 +426,8 @@ export function codexAppServerRunIdentityForPatch(session = {}, {
|
|
|
399
426
|
// A settling writer names the turn it settles. While another turn owns the
|
|
400
427
|
// active run, that write belongs to a predecessor and must not end the run.
|
|
401
428
|
export function codexAppServerRunPatchSettlesOtherActiveTurn(currentTurn = {}, patch = {}) {
|
|
402
|
-
const currentTurnId =
|
|
403
|
-
const patchTurnId =
|
|
429
|
+
const currentTurnId = normalizeText(currentTurn.turnId);
|
|
430
|
+
const patchTurnId = normalizeText(patch.providerTurnId);
|
|
404
431
|
return currentTurn.active === true &&
|
|
405
432
|
!codexAppServerRunStateIsActive(patch.state) &&
|
|
406
433
|
Boolean(currentTurnId) &&
|
|
@@ -417,10 +444,10 @@ export function codexAppServerRunPatchIsStaleAfterTerminalState(currentTurn = {}
|
|
|
417
444
|
if (patchRunState === CODEX_APP_SERVER_RUN_STATE.STARTING) {
|
|
418
445
|
return false;
|
|
419
446
|
}
|
|
420
|
-
const currentThreadId =
|
|
421
|
-
const patchThreadId =
|
|
422
|
-
const currentTurnId =
|
|
423
|
-
const patchTurnId =
|
|
447
|
+
const currentThreadId = normalizeText(currentTurn.threadId);
|
|
448
|
+
const patchThreadId = normalizeText(patch.providerThreadId);
|
|
449
|
+
const currentTurnId = normalizeText(currentTurn.turnId);
|
|
450
|
+
const patchTurnId = normalizeText(patch.providerTurnId);
|
|
424
451
|
const threadMatches = !patchThreadId || !currentThreadId || patchThreadId === currentThreadId;
|
|
425
452
|
const turnMatches = !patchTurnId || (
|
|
426
453
|
Boolean(currentTurnId) &&
|
|
@@ -430,7 +457,7 @@ export function codexAppServerRunPatchIsStaleAfterTerminalState(currentTurn = {}
|
|
|
430
457
|
}
|
|
431
458
|
|
|
432
459
|
function codexAppServerErrorMessage(value, fallback = "Codex could not be prepared.") {
|
|
433
|
-
return
|
|
460
|
+
return normalizeText(value?.error || value?.message || value) || fallback;
|
|
434
461
|
}
|
|
435
462
|
|
|
436
463
|
export function codexAppServerSteerFailure(result = {}, steerFailedCode = "codex_turn_steer_failed") {
|
|
@@ -441,10 +468,10 @@ export function codexAppServerSteerFailure(result = {}, steerFailedCode = "codex
|
|
|
441
468
|
return null;
|
|
442
469
|
}
|
|
443
470
|
return {
|
|
444
|
-
code:
|
|
471
|
+
code: normalizeText(result.code) || steerFailedCode,
|
|
445
472
|
error: codexAppServerErrorMessage(result, "Codex app-server turn could not be steered."),
|
|
446
473
|
ok: false,
|
|
447
|
-
operationOutcome:
|
|
474
|
+
operationOutcome: normalizeText(result.operationOutcome) || "steer_failed",
|
|
448
475
|
refreshRecommended: true,
|
|
449
476
|
retryable: result.retryable === true
|
|
450
477
|
};
|
|
@@ -461,9 +488,9 @@ export function codexAppServerMessageRequiresNewTurn({
|
|
|
461
488
|
newTurnRequired: true,
|
|
462
489
|
ok: true,
|
|
463
490
|
operationOutcome: "new_turn_required",
|
|
464
|
-
reason:
|
|
465
|
-
threadId:
|
|
466
|
-
turnId:
|
|
491
|
+
reason: normalizeText(reason),
|
|
492
|
+
threadId: normalizeText(threadId),
|
|
493
|
+
turnId: normalizeText(turnId)
|
|
467
494
|
};
|
|
468
495
|
}
|
|
469
496
|
|
|
@@ -494,10 +521,10 @@ export function codexAppServerInterruptFailure(result = {}, interruptFailedCode
|
|
|
494
521
|
return null;
|
|
495
522
|
}
|
|
496
523
|
return {
|
|
497
|
-
code:
|
|
524
|
+
code: normalizeText(result.code) || interruptFailedCode,
|
|
498
525
|
error: codexAppServerErrorMessage(result, "Codex app-server turn could not be interrupted."),
|
|
499
526
|
ok: false,
|
|
500
|
-
operationOutcome:
|
|
527
|
+
operationOutcome: normalizeText(result.operationOutcome) || "interrupt_failed",
|
|
501
528
|
refreshRecommended: true,
|
|
502
529
|
retryable: result.retryable === true
|
|
503
530
|
};
|
|
@@ -518,8 +545,8 @@ export function codexAppServerInterruptUnavailableResponse({
|
|
|
518
545
|
operationOutcome: "interrupt_unavailable",
|
|
519
546
|
refreshRecommended: true,
|
|
520
547
|
retryable: active === true,
|
|
521
|
-
threadId:
|
|
522
|
-
turnId:
|
|
548
|
+
threadId: normalizeText(threadId),
|
|
549
|
+
turnId: normalizeText(turnId)
|
|
523
550
|
};
|
|
524
551
|
}
|
|
525
552
|
|
|
@@ -532,41 +559,41 @@ export function codexAppServerFrozenTurnInterruptResponse({
|
|
|
532
559
|
ok: true,
|
|
533
560
|
operationOutcome: "already_idle",
|
|
534
561
|
status: "interrupted",
|
|
535
|
-
threadId:
|
|
536
|
-
turnId:
|
|
562
|
+
threadId: normalizeText(threadId),
|
|
563
|
+
turnId: normalizeText(turnId)
|
|
537
564
|
};
|
|
538
565
|
}
|
|
539
566
|
|
|
540
567
|
export function codexAppServerConversationTurnIsActive(status = "") {
|
|
541
|
-
return ["starting", "inProgress"].includes(
|
|
568
|
+
return ["starting", "inProgress"].includes(normalizeText(status));
|
|
542
569
|
}
|
|
543
570
|
|
|
544
571
|
export function codexAppServerMessageText(input = {}) {
|
|
545
572
|
if (typeof input === "string") {
|
|
546
|
-
return
|
|
573
|
+
return normalizeText(input);
|
|
547
574
|
}
|
|
548
575
|
if (!isRecord(input)) {
|
|
549
576
|
return "";
|
|
550
577
|
}
|
|
551
|
-
return
|
|
578
|
+
return normalizeText(input.message);
|
|
552
579
|
}
|
|
553
580
|
|
|
554
581
|
export function codexAppServerMessageDisplayText(input = {}, fallback = "") {
|
|
555
582
|
if (!isRecord(input)) {
|
|
556
|
-
return
|
|
583
|
+
return normalizeText(fallback || input);
|
|
557
584
|
}
|
|
558
|
-
return
|
|
585
|
+
return normalizeText(input.displayMessage || input.message || fallback);
|
|
559
586
|
}
|
|
560
587
|
|
|
561
588
|
function codexPromptInputFromRequest(input = {}) {
|
|
562
589
|
if (typeof input === "string") {
|
|
563
|
-
return
|
|
590
|
+
return normalizeText(input);
|
|
564
591
|
}
|
|
565
|
-
const terminalInput =
|
|
592
|
+
const terminalInput = normalizeText(input.terminalInput);
|
|
566
593
|
if (terminalInput) {
|
|
567
594
|
return terminalInput;
|
|
568
595
|
}
|
|
569
596
|
return codexAppServerMessageText(input);
|
|
570
597
|
}
|
|
571
598
|
|
|
572
|
-
export { codexAppServerRunInputSource, codexAppServerThreadStatus, codexAppServerReadThreadStatus, codexAppServerTurnStatusIsActive, codexAppServerTurnStatusIsComplete, codexAppServerTurnStatusIsSuccessfulComplete, codexAppServerTurnStatusIsProviderFailure,
|
|
599
|
+
export { codexAppServerRunInputSource, codexAppServerThreadStatus, codexAppServerReadThreadStatus, codexAppServerTurnStatusIsActive, codexAppServerTurnStatusIsComplete, codexAppServerTurnStatusIsSuccessfulComplete, codexAppServerTurnStatusIsProviderFailure, codexAppServerErrorMessage, codexAppServerMessageDeferred, codexPromptInputFromRequest, CODEX_APP_SERVER_AGENT_RUN_ID, CODEX_APP_SERVER_RESULT_PROCESSED_EVENT, CODEX_AGENT_PROVIDER, CODEX_APP_SERVER_ACTIVE_RUN_STATES };
|