@jskit-ai/assistant-core 0.2.7 → 0.2.9

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.
Files changed (214) hide show
  1. package/examples/conversation/package.json +5 -5
  2. package/package.json +18 -7
  3. package/src/client/browser.js +21 -0
  4. package/src/client/conversation/AssistantAttachmentQueue.vue +25 -108
  5. package/src/client/conversation/AssistantComposerActions.vue +1 -1
  6. package/src/client/conversation/AssistantConversationElement.vue +14 -52
  7. package/src/client/conversation/AssistantGoalControl.vue +13 -10
  8. package/src/client/conversation/AssistantPromptInput.vue +6 -91
  9. package/src/client/conversation/AssistantTranscript.css +505 -0
  10. package/src/client/conversation/AssistantTranscript.vue +24 -1197
  11. package/src/client/conversation/attachmentFiles.js +158 -0
  12. package/src/client/conversation/attachmentQueueItems.js +121 -0
  13. package/src/client/conversation/attachmentUploadRows.js +265 -0
  14. package/src/client/conversation/conversationDisplay.js +54 -0
  15. package/src/client/conversation/messageDelivery.js +13 -9
  16. package/src/client/conversation/retainedConversation.js +14 -3
  17. package/src/client/conversation/submitText.js +13 -2
  18. package/src/client/conversation/transcriptEntries.js +225 -0
  19. package/src/client/conversation/useAssistantAttachments.js +86 -388
  20. package/src/client/conversation/useAssistantQuestions.js +16 -3
  21. package/src/client/conversation/useAssistantSuggestions.js +16 -2
  22. package/src/client/conversation/useScrollToBottom.js +17 -19
  23. package/src/client/conversation/useTextareaAutoGrow.js +115 -0
  24. package/src/client/conversation/useTranscriptScrollFollow.js +525 -0
  25. package/src/client/lib/assistantApi.js +192 -161
  26. package/src/client/types.js +110 -0
  27. package/src/server/conversation/attachments.js +21 -6
  28. package/src/server/conversation/boundedToolLoop.js +1 -0
  29. package/src/server/conversation/claudeClient.js +71 -20
  30. package/src/server/conversation/claudeCommandRun.js +191 -0
  31. package/src/server/conversation/claudeHistory.js +7 -0
  32. package/src/server/conversation/claudeNativeTurn.js +708 -0
  33. package/src/server/conversation/claudeProcess.js +186 -112
  34. package/src/server/conversation/claudeProcessStart.js +214 -0
  35. package/src/server/conversation/claudePromptDelivery.js +183 -0
  36. package/src/server/conversation/claudeSessionCleanup.js +248 -0
  37. package/src/server/conversation/claudeTools.js +15 -3
  38. package/src/server/conversation/claudeTurn.js +212 -1388
  39. package/src/server/conversation/codexAccountReader.js +168 -0
  40. package/src/server/conversation/codexAuthPreflight.js +5 -4
  41. package/src/server/conversation/codexClient.js +18 -6
  42. package/src/server/conversation/codexConfiguration.js +8 -844
  43. package/src/server/conversation/codexConversationStops.js +377 -0
  44. package/src/server/conversation/codexConversationStore.js +119 -85
  45. package/src/server/conversation/codexConversationTurns.js +378 -0
  46. package/src/server/conversation/codexConversations.js +134 -866
  47. package/src/server/conversation/codexDetachedConversation.js +203 -0
  48. package/src/server/conversation/codexDetachedTurn.js +145 -104
  49. package/src/server/conversation/codexEvents.js +5 -200
  50. package/src/server/conversation/codexGoalCommands.js +14 -4
  51. package/src/server/conversation/codexHelperExecution.js +57 -57
  52. package/src/server/conversation/codexHelperThreadLedger.js +30 -288
  53. package/src/server/conversation/codexHelperThreadRecord.js +304 -0
  54. package/src/server/conversation/codexHelperThreadRecovery.js +54 -76
  55. package/src/server/conversation/codexHelperThreads.js +94 -93
  56. package/src/server/conversation/codexHistoryAdapter.js +13 -8
  57. package/src/server/conversation/codexIsolation.js +672 -0
  58. package/src/server/conversation/codexLiveItems.js +379 -0
  59. package/src/server/conversation/codexMessageCommands.js +68 -286
  60. package/src/server/conversation/codexMessageDelivery.js +46 -37
  61. package/src/server/conversation/codexModelCatalog.js +86 -7
  62. package/src/server/conversation/codexNotificationObserver.js +81 -88
  63. package/src/server/conversation/codexNotificationQueue.js +21 -10
  64. package/src/server/conversation/codexObservationControl.js +105 -89
  65. package/src/server/conversation/codexOutput.js +84 -419
  66. package/src/server/conversation/codexProcess.js +29 -1053
  67. package/src/server/conversation/codexProcessLeader.js +1 -0
  68. package/src/server/conversation/codexPromptDispatch.js +241 -0
  69. package/src/server/conversation/codexProvider.js +147 -1807
  70. package/src/server/conversation/codexProviderAuth.js +348 -0
  71. package/src/server/conversation/codexProviderInvalidation.js +371 -0
  72. package/src/server/conversation/codexProviderInventories.js +437 -0
  73. package/src/server/conversation/codexProviderOwner.js +149 -957
  74. package/src/server/conversation/codexProviderRelease.js +465 -0
  75. package/src/server/conversation/codexProviderSelection.js +26 -15
  76. package/src/server/conversation/codexProviderThreads.js +698 -0
  77. package/src/server/conversation/codexProviderTurns.js +453 -0
  78. package/src/server/conversation/codexReasoning.js +32 -23
  79. package/src/server/conversation/codexRenewalCommands.js +18 -6
  80. package/src/server/conversation/codexRenewalThreads.js +7 -22
  81. package/src/server/conversation/codexResultSettlement.js +70 -88
  82. package/src/server/conversation/codexRunJournal.js +91 -97
  83. package/src/server/conversation/codexRuntime.js +426 -0
  84. package/src/server/conversation/codexRuntimeInventory.js +113 -0
  85. package/src/server/conversation/codexRuntimeLifecycle.js +39 -13
  86. package/src/server/conversation/codexRuntimeStart.js +431 -0
  87. package/src/server/conversation/codexRuntimeStop.js +324 -0
  88. package/src/server/conversation/codexSessionCleanup.js +25 -10
  89. package/src/server/conversation/codexSessionReconciliation.js +21 -7
  90. package/src/server/conversation/codexThreadReadiness.js +49 -52
  91. package/src/server/conversation/codexThreadSnapshot.js +210 -0
  92. package/src/server/conversation/codexThreadStatus.js +48 -62
  93. package/src/server/conversation/codexTurn.js +171 -55
  94. package/src/server/conversation/codexTurnActivity.js +210 -0
  95. package/src/server/conversation/codexTurnControl.js +44 -48
  96. package/src/server/conversation/codexTurnEndings.js +610 -0
  97. package/src/server/conversation/codexTurnRecovery.js +97 -848
  98. package/src/server/conversation/codexTurnState.js +138 -111
  99. package/src/server/conversation/completedResponses.js +227 -0
  100. package/src/server/conversation/configuration.js +2 -2
  101. package/src/server/conversation/continuity.js +43 -6
  102. package/src/server/conversation/conversationDelivery.js +394 -0
  103. package/src/server/conversation/conversationEntries.js +365 -0
  104. package/src/server/conversation/conversationEvents.js +192 -0
  105. package/src/server/conversation/conversationGoals.js +187 -0
  106. package/src/server/conversation/conversationHandles.js +237 -0
  107. package/src/server/conversation/conversationReads.js +206 -0
  108. package/src/server/conversation/conversationRefusals.js +58 -0
  109. package/src/server/conversation/conversationReplacement.js +254 -0
  110. package/src/server/conversation/conversationSending.js +273 -0
  111. package/src/server/conversation/conversationStopping.js +121 -0
  112. package/src/server/conversation/conversationTurnDelivery.js +413 -0
  113. package/src/server/conversation/conversationTurns.js +511 -0
  114. package/src/server/conversation/deliveryTiming.js +25 -3
  115. package/src/server/conversation/fileStorage.js +11 -6
  116. package/src/server/conversation/hookBridge.js +14 -3
  117. package/src/server/conversation/index.js +1 -1
  118. package/src/server/conversation/localExecution.js +82 -625
  119. package/src/server/conversation/nativeCommandCallbacks.js +10 -0
  120. package/src/server/conversation/nativeConversationLifecycle.js +379 -0
  121. package/src/server/conversation/nativeHistoryExport.js +27 -18
  122. package/src/server/conversation/normalize.js +9 -0
  123. package/src/server/conversation/openCodeClient.js +295 -366
  124. package/src/server/conversation/openCodeNativeHistory.js +141 -0
  125. package/src/server/conversation/openCodeNativeSession.js +79 -0
  126. package/src/server/conversation/openCodeProcess.js +109 -53
  127. package/src/server/conversation/openCodeProcessOwner.js +565 -0
  128. package/src/server/conversation/openCodeRuntime.js +111 -1814
  129. package/src/server/conversation/openCodeSessionTurns.js +547 -0
  130. package/src/server/conversation/openCodeTemporaryConversations.js +394 -0
  131. package/src/server/conversation/openCodeTools.js +28 -14
  132. package/src/server/conversation/openCodeTurn.js +80 -74
  133. package/src/server/conversation/openCodeTurnMonitor.js +388 -0
  134. package/src/server/conversation/processIdentity.js +582 -0
  135. package/src/server/conversation/provider.js +21 -6
  136. package/src/server/conversation/providers/api.js +268 -107
  137. package/src/server/conversation/providers/claude.js +29 -6
  138. package/src/server/conversation/providers/claudeDriver.js +325 -250
  139. package/src/server/conversation/providers/codex.js +69 -33
  140. package/src/server/conversation/providers/codexDriver.js +503 -1081
  141. package/src/server/conversation/providers/codexDriverConnection.js +331 -0
  142. package/src/server/conversation/providers/codexDriverTurns.js +464 -0
  143. package/src/server/conversation/providers/opencode.js +30 -4
  144. package/src/server/conversation/providers/opencodeDriver.js +321 -659
  145. package/src/server/conversation/providers/opencodeStandalone.js +475 -0
  146. package/src/server/conversation/providers/scoped.js +64 -19
  147. package/src/server/conversation/runtime.js +171 -2863
  148. package/src/server/conversation/storage.js +91 -50
  149. package/src/server/conversation/streams.js +15 -2
  150. package/src/server/conversation/structuredOutput.js +7 -11
  151. package/src/server/conversation/systemPrompt.js +13 -1
  152. package/src/server/conversation/tools.js +47 -15
  153. package/src/server/conversation/transcript.js +49 -20
  154. package/src/server/hosts/claudeTurn.js +2 -4
  155. package/src/server/hosts/codexConfiguration.js +6 -8
  156. package/src/server/hosts/codexEvents.js +4 -2
  157. package/src/server/hosts/codexProcess.js +1 -1
  158. package/src/server/hosts/codexProvider.js +11 -9
  159. package/src/server/hosts/codexTurn.js +3 -3
  160. package/src/server/hosts/openCodeClient.js +4 -2
  161. package/src/server/index.js +0 -2
  162. package/src/server/lib/aiConnectionClient.js +35 -25
  163. package/src/server/lib/ndjson.js +1 -0
  164. package/src/server/lib/providers/anthropicClient.js +15 -6
  165. package/src/server/lib/providers/common.js +10 -6
  166. package/src/server/lib/providers/openAiCompatibleClient.js +40 -23
  167. package/src/server/lib/serviceToolCatalog.js +29 -283
  168. package/src/server/lib/serviceToolEntries.js +270 -0
  169. package/src/server/types.js +78 -0
  170. package/src/shared/assistantResource.js +0 -23
  171. package/src/shared/conversation/answerChoiceSugar.js +2 -14
  172. package/src/shared/conversation/messageInputSugar.js +18 -0
  173. package/src/shared/conversation/numberedQuestionSugar.js +6 -16
  174. package/src/shared/conversation/pagination.js +1 -1
  175. package/src/shared/conversation/questions.js +1 -0
  176. package/src/shared/conversation/streaming.js +1 -0
  177. package/src/shared/index.js +0 -1
  178. package/src/testing/conversationStorageContract.js +20 -0
  179. package/test/aiConnectionClient.test.js +42 -1
  180. package/test/apiConversationDriver.test.js +217 -38
  181. package/test/assistantBoundedToolLoop.test.js +1 -1
  182. package/test/claudeConversationSession.test.js +15 -11
  183. package/test/claudeInstructionResume.test.js +1 -1
  184. package/test/claudeProcess.test.js +9 -9
  185. package/test/claudeTurn.test.js +21 -8
  186. package/test/codexAccountChange.test.js +5 -3
  187. package/test/codexConversationSession.test.js +22 -21
  188. package/test/codexEvents.test.js +3 -1
  189. package/test/codexHelperDeletion.test.js +3 -7
  190. package/test/codexIsolation.test.js +6 -6
  191. package/test/codexModelCatalog.test.js +6 -7
  192. package/test/codexProcess.test.js +3 -3
  193. package/test/codexThreadSelection.test.js +4 -1
  194. package/test/codexTurn.test.js +29 -20
  195. package/test/conversationApiFacilities.test.js +11 -9
  196. package/test/conversationAttachments.test.js +3 -3
  197. package/test/conversationConfiguration.test.js +4 -4
  198. package/test/conversationNativeStorage.test.js +11 -10
  199. package/test/conversationReplacement.test.js +13 -13
  200. package/test/conversationRuntime.test.js +9 -5
  201. package/test/conversationSession.test.js +78 -22
  202. package/test/conversationTools.test.js +47 -26
  203. package/test/fileConversationStorage.test.js +10 -3
  204. package/test/fixtures/codexHelperThreadLedger.js +3 -3
  205. package/test/frameworkActions.test.js +33 -18
  206. package/test/localConversationExecution.test.js +4 -4
  207. package/test/localExecution.test.js +1 -1
  208. package/test/openCodeConnectionChange.test.js +3 -2
  209. package/test/openCodeRuntime.test.js +8 -7
  210. package/test/openCodeTools.test.js +1 -1
  211. package/test/opencodeConversationSession.test.js +4 -3
  212. package/test/serviceToolCatalog.test.js +3 -8
  213. package/src/server/lib/assistantCompletion.js +0 -190
  214. package/src/server/lib/assistantToolLoop.js +0 -259
@@ -1,28 +1,46 @@
1
- import {
2
- normalizeCodexRunText,
3
- codexAppServerRunStateIsActive,
4
- codexAppServerAgentRun,
5
- codexAppServerPendingUserMessageClientIds,
6
- codexAppServerProcessedResultEvent,
7
- codexAppServerTurnCanReceiveProviderActivity,
8
- codexAppServerTurnKey,
9
- codexAppServerAgentRunPatch,
10
- codexAppServerRunIdentityForPatch,
11
- codexAppServerRunPatchIsStaleAfterTerminalState,
12
- codexAppServerRunPatchSettlesOtherActiveTurn,
13
- CODEX_APP_SERVER_AGENT_RUN_ID,
14
- CODEX_AGENT_PROVIDER,
15
- CODEX_APP_SERVER_RUN_STATE,
16
- codexAppServerRunInputSource,
17
- codexAppServerTurnStateFromAgentRun
18
- } from "./codexTurnState.js";
1
+ import { codexAppServerRunStateIsActive, codexAppServerAgentRun, codexAppServerPendingUserMessageClientIds, codexAppServerProcessedResultEvent, codexAppServerTurnCanReceiveProviderActivity, codexAppServerTurnKey, codexAppServerAgentRunPatch, codexAppServerRunIdentityForPatch, codexAppServerRunPatchIsStaleAfterTerminalState, codexAppServerRunPatchSettlesOtherActiveTurn, CODEX_APP_SERVER_AGENT_RUN_ID, CODEX_AGENT_PROVIDER, CODEX_APP_SERVER_RUN_STATE, codexAppServerRunInputSource, codexAppServerTurnStateFromAgentRun } from "./codexTurnState.js";
19
2
  import crypto from "node:crypto";
20
- import { isRecord } from "@jskit-ai/kernel/shared/support/normalize";
3
+ import { isRecord, normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
21
4
 
22
5
  const CODEX_APP_SERVER_PROMPT_CLAIM_GRACE_MS = 15000;
23
6
 
24
- // Original native run claims, guarded journal writes and status retirement.
25
- // The containing run owner shares these exact Sets and Maps by reference.
7
+ function terminalCodexAppServerAgentRunState(status = "") {
8
+ const normalizedStatus = normalizeText(status);
9
+ if (normalizedStatus === "interrupted") {
10
+ return CODEX_APP_SERVER_RUN_STATE.INTERRUPTED;
11
+ }
12
+ if (normalizedStatus === "failed") {
13
+ return CODEX_APP_SERVER_RUN_STATE.FAILED;
14
+ }
15
+ return CODEX_APP_SERVER_RUN_STATE.COMPLETED;
16
+ }
17
+
18
+ function codexAppServerDateValueMs(value = "") {
19
+ const parsed = Date.parse(normalizeText(value));
20
+ return Number.isFinite(parsed) ? parsed : 0;
21
+ }
22
+
23
+ /**
24
+ * Native run claims, guarded journal writes and status retirement. The containing run owner shares these exact Sets
25
+ * and Maps by reference.
26
+ * @param {object} dependencies
27
+ * @param {import("./codexTurn.js").CodexSessionNamespace} dependencies.namespace
28
+ * @param {(state: unknown) => string} dependencies.normalizeRunState
29
+ * @param {import("./codexTurn.js").CodexTurnStateReader} dependencies.turnState
30
+ * @param {import("./codexTurn.js").CodexCreateRuntime} dependencies.createRuntime
31
+ * @param {import("./codexTurn.js").CodexPublish} dependencies.publish
32
+ * @param {(sessionId: string, input: object) => Promise<unknown>} dependencies.checkpoint
33
+ * @param {import("./codexTurn.js").CodexDebugLog} dependencies.debugLog
34
+ * @param {import("./codexOutput.js").CodexAppServerOutput} dependencies.output
35
+ * @param {string} dependencies.messageIdPrefix
36
+ * @param {string} dependencies.sessionIdRequiredError
37
+ * @param {string} dependencies.turnAlreadyRunningError
38
+ * @param {string} dependencies.errorPrefix
39
+ * @param {object} [dependencies.idlePublishPayload]
40
+ * @param {number} dependencies.finalizingGraceMs
41
+ * @param {(session: object, run: object) => boolean} dependencies.admissionTaskFinished
42
+ * @param {string} dependencies.orphanedPromptMessage
43
+ */
26
44
  export function createCodexRunJournal({
27
45
  namespace,
28
46
  normalizeRunState,
@@ -34,7 +52,6 @@ export function createCodexRunJournal({
34
52
  output,
35
53
  messageIdPrefix,
36
54
  sessionIdRequiredError,
37
- turnClaimsUnsupportedError,
38
55
  turnAlreadyRunningError,
39
56
  errorPrefix,
40
57
  idlePublishPayload,
@@ -49,18 +66,14 @@ export function createCodexRunJournal({
49
66
  const agentRunPatch = input => codexAppServerAgentRunPatch(input, normalizeRunState);
50
67
  const runIdentityForPatch = (session, input) => codexAppServerRunIdentityForPatch(session, input, normalizeRunState);
51
68
  const runPatchIsStaleAfterTerminalState = (turn, patch) => codexAppServerRunPatchIsStaleAfterTerminalState(turn, patch, normalizeRunState);
52
- const {
53
- resultFinalizationKey: codexAppServerResultFinalizationKey,
54
- readAgentRunForSession: readCodexAppServerAgentRunForSession
55
- } = output;
56
69
 
57
70
  function codexAppServerTurnResultWasProcessed(session = {}, threadId = "", turnId = "") {
58
- const normalizedThreadId = normalizeCodexRunText(threadId);
59
- const normalizedTurnId = normalizeCodexRunText(turnId);
71
+ const normalizedThreadId = normalizeText(threadId);
72
+ const normalizedTurnId = normalizeText(turnId);
60
73
  if (!normalizedThreadId || !normalizedTurnId) {
61
74
  return false;
62
75
  }
63
- return codexAppServerProcessedTurns.has(codexAppServerResultFinalizationKey(
76
+ return codexAppServerProcessedTurns.has(output.resultFinalizationKey(
64
77
  session.sessionId,
65
78
  normalizedThreadId,
66
79
  normalizedTurnId
@@ -70,8 +83,8 @@ export function createCodexRunJournal({
70
83
  async function claimCodexAppServerTurnStart(runtime, sessionId = "", outerTurnId = "", {
71
84
  inputSource = "chat"
72
85
  } = {}) {
73
- const normalizedSessionId = normalizeCodexRunText(sessionId);
74
- const normalizedOuterTurnId = normalizeCodexRunText(outerTurnId);
86
+ const normalizedSessionId = normalizeText(sessionId);
87
+ const normalizedOuterTurnId = normalizeText(outerTurnId);
75
88
  let claimResult = null;
76
89
  const mutationResult = await runtime.store.mutateSession(normalizedSessionId, async () => {
77
90
  const currentSession = await runtime.getSession(normalizedSessionId);
@@ -85,7 +98,7 @@ export function createCodexRunJournal({
85
98
  }
86
99
  const updatedAt = new Date().toISOString();
87
100
  const runPatch = agentRunPatch({
88
- inputSource: normalizeCodexRunText(inputSource) || "chat",
101
+ inputSource: normalizeText(inputSource) || "chat",
89
102
  outerTurnId: normalizedOuterTurnId,
90
103
  runState: CODEX_APP_SERVER_RUN_STATE.STARTING,
91
104
  session: currentSession,
@@ -115,8 +128,8 @@ export function createCodexRunJournal({
115
128
  async function claimCodexAppServerMessageStart(runtime, sessionId = "", outerTurnId = "", {
116
129
  inputSource = "chat"
117
130
  } = {}) {
118
- const normalizedSessionId = normalizeCodexRunText(sessionId);
119
- const normalizedOuterTurnId = normalizeCodexRunText(outerTurnId) ||
131
+ const normalizedSessionId = normalizeText(sessionId);
132
+ const normalizedOuterTurnId = normalizeText(outerTurnId) ||
120
133
  `${messageIdPrefix}${crypto.randomUUID()}`;
121
134
  if (!normalizedSessionId) {
122
135
  return {
@@ -127,9 +140,6 @@ export function createCodexRunJournal({
127
140
  } }
128
141
  };
129
142
  }
130
- if (typeof runtime?.store?.mutateSession !== "function" || typeof runtime?.getSession !== "function") {
131
- throw new Error(turnClaimsUnsupportedError);
132
- }
133
143
  const result = await claimCodexAppServerTurnStart(runtime, normalizedSessionId, normalizedOuterTurnId, { inputSource });
134
144
  if (result?.claimed === false && result.session) {
135
145
  const turn = turnState(result.session);
@@ -139,8 +149,8 @@ export function createCodexRunJournal({
139
149
  error: turnAlreadyRunningError,
140
150
  operationOutcome: "agent_already_running",
141
151
  refreshRecommended: true,
142
- threadId: normalizeCodexRunText(turn.threadId),
143
- turnId: normalizeCodexRunText(turn.turnId)
152
+ threadId: normalizeText(turn.threadId),
153
+ turnId: normalizeText(turn.turnId)
144
154
  }, session: result.session } };
145
155
  }
146
156
  if (result?.claimed) {
@@ -165,15 +175,13 @@ export function createCodexRunJournal({
165
175
  turnId = "",
166
176
  updatedAt = ""
167
177
  } = {}) {
168
- const normalizedSessionId = normalizeCodexRunText(sessionId);
178
+ const normalizedSessionId = normalizeText(sessionId);
169
179
  let runPatch = null;
170
180
  let conversationStream = null;
171
181
  let wrote = false;
172
182
  let stale = null;
173
183
  const updatedSession = await runtime.store.mutateSession(normalizedSessionId, async () => {
174
- const currentSession = typeof runtime?.getSession === "function"
175
- ? await runtime.getSession(normalizedSessionId).catch(() => null)
176
- : null;
184
+ const currentSession = await runtime.getSession(normalizedSessionId).catch(() => null);
177
185
  const identity = runIdentityForPatch(currentSession || {}, {
178
186
  threadId,
179
187
  turnId
@@ -187,13 +195,13 @@ export function createCodexRunJournal({
187
195
  status,
188
196
  threadId: identity.threadId,
189
197
  turnId: identity.turnId,
190
- updatedAt: normalizeCodexRunText(updatedAt) || new Date().toISOString()
198
+ updatedAt: normalizeText(updatedAt) || new Date().toISOString()
191
199
  });
192
200
  const currentTurn = turnState(currentSession || {});
193
201
  if (
194
202
  codexAppServerRunStateIsActive(runPatch.state) &&
195
- currentTurn.threadId === normalizeCodexRunText(runPatch.providerThreadId) &&
196
- currentTurn.turnId === normalizeCodexRunText(runPatch.providerTurnId) &&
203
+ currentTurn.threadId === normalizeText(runPatch.providerThreadId) &&
204
+ currentTurn.turnId === normalizeText(runPatch.providerTurnId) &&
197
205
  currentTurn.startedAt
198
206
  ) {
199
207
  runPatch.startedAt = currentTurn.startedAt;
@@ -209,7 +217,7 @@ export function createCodexRunJournal({
209
217
  currentTurn.turnId === runPatch.providerTurnId &&
210
218
  runPatch.state === CODEX_APP_SERVER_RUN_STATE.ACTIVE;
211
219
  const observationLostBlocks = currentTurn.status === "observation_lost" && status !== "observation_lost";
212
- const phaseTargetsOtherTurn = phase !== undefined && (!normalizeCodexRunText(turnId) ||
220
+ const phaseTargetsOtherTurn = phase !== undefined && (!normalizeText(turnId) ||
213
221
  !codexAppServerTurnCanReceiveProviderActivity(currentTurn, threadId, turnId));
214
222
  const observationExpired = Boolean(observedRun) && !canRecoverStoppedTurn;
215
223
  const terminalAlreadyRecorded = !canRecoverStoppedTurn && runPatchIsStaleAfterTerminalState(currentTurn, runPatch);
@@ -241,7 +249,7 @@ export function createCodexRunJournal({
241
249
  await runtime.store.writeAgentRunEvent(normalizedSessionId, CODEX_APP_SERVER_AGENT_RUN_ID, {
242
250
  event: {
243
251
  kind: publishReason || "codex-app-server-turn-state",
244
- message: normalizeCodexRunText(error),
252
+ message: normalizeText(error),
245
253
  state: runPatch.state
246
254
  },
247
255
  patch: runPatch
@@ -256,7 +264,7 @@ export function createCodexRunJournal({
256
264
  }
257
265
 
258
266
  function clearCodexAppServerActiveTimer(sessionId = "") {
259
- const normalizedSessionId = normalizeCodexRunText(sessionId);
267
+ const normalizedSessionId = normalizeText(sessionId);
260
268
  const sessionKey = namespace(normalizedSessionId);
261
269
  const timer = codexAppServerActiveTimers.get(sessionKey);
262
270
  if (timer) {
@@ -266,7 +274,7 @@ export function createCodexRunJournal({
266
274
  }
267
275
 
268
276
  function clearCodexAppServerFinalizingTimer(sessionId = "", threadId = "", turnId = "") {
269
- const key = codexAppServerResultFinalizationKey(sessionId, threadId, turnId);
277
+ const key = output.resultFinalizationKey(sessionId, threadId, turnId);
270
278
  const entry = codexAppServerFinalizingTimers.get(key);
271
279
  if (entry) {
272
280
  clearTimeout(entry.timer);
@@ -275,7 +283,7 @@ export function createCodexRunJournal({
275
283
  }
276
284
 
277
285
  function clearCodexAppServerSessionRecoveryTimers(sessionId = "") {
278
- const normalizedSessionId = normalizeCodexRunText(sessionId);
286
+ const normalizedSessionId = normalizeText(sessionId);
279
287
  clearCodexAppServerActiveTimer(normalizedSessionId);
280
288
  const finalizingKeyPrefix = `${namespace(normalizedSessionId)}:`;
281
289
  for (const [key, entry] of codexAppServerFinalizingTimers.entries()) {
@@ -286,17 +294,6 @@ export function createCodexRunJournal({
286
294
  }
287
295
  }
288
296
 
289
- function terminalCodexAppServerAgentRunState(status = "") {
290
- const normalizedStatus = normalizeCodexRunText(status);
291
- if (normalizedStatus === "interrupted") {
292
- return CODEX_APP_SERVER_RUN_STATE.INTERRUPTED;
293
- }
294
- if (normalizedStatus === "failed") {
295
- return CODEX_APP_SERVER_RUN_STATE.FAILED;
296
- }
297
- return CODEX_APP_SERVER_RUN_STATE.COMPLETED;
298
- }
299
-
300
297
  function codexAppServerAgentRunRealtimePayload(runPatch = {}) {
301
298
  const turn = codexAppServerTurnStateFromAgentRun({ ...runPatch, id: CODEX_APP_SERVER_AGENT_RUN_ID }, normalizeRunState);
302
299
  return {
@@ -350,7 +347,7 @@ export function createCodexRunJournal({
350
347
  turnId = "",
351
348
  updatedAt = ""
352
349
  } = {}) {
353
- const normalizedSessionId = normalizeCodexRunText(sessionId);
350
+ const normalizedSessionId = normalizeText(sessionId);
354
351
  if (!normalizedSessionId) {
355
352
  return {
356
353
  ok: false,
@@ -385,27 +382,27 @@ export function createCodexRunJournal({
385
382
 
386
383
  async function markCodexAppServerTurnFinalizing(sessionId = "", input = {}) {
387
384
  const result = await publishCodexAppServerAgentRun(sessionId, {
388
- error: normalizeCodexRunText(input.error),
385
+ error: normalizeText(input.error),
389
386
  publishReason: "codex-app-server-turn-finalizing",
390
387
  runState: CODEX_APP_SERVER_RUN_STATE.FINALIZING,
391
- status: normalizeCodexRunText(input.status) || "completed",
392
- threadId: normalizeCodexRunText(input.threadId),
393
- turnId: normalizeCodexRunText(input.turnId)
388
+ status: normalizeText(input.status) || "completed",
389
+ threadId: normalizeText(input.threadId),
390
+ turnId: normalizeText(input.turnId)
394
391
  });
395
392
  clearCodexAppServerActiveTimer(sessionId);
396
393
  return result;
397
394
  }
398
395
 
399
396
  async function markCodexAppServerTurnIdle(sessionId = "", input = {}) {
400
- const status = normalizeCodexRunText(input.status) || "completed";
397
+ const status = normalizeText(input.status) || "completed";
401
398
  const result = await publishCodexAppServerAgentRun(sessionId, {
402
- error: normalizeCodexRunText(input.error),
399
+ error: normalizeText(input.error),
403
400
  publishPayload: idlePublishPayload,
404
401
  publishReason: "codex-app-server-turn-idle",
405
402
  runState: terminalCodexAppServerAgentRunState(status),
406
403
  status,
407
- threadId: normalizeCodexRunText(input.threadId),
408
- turnId: normalizeCodexRunText(input.turnId)
404
+ threadId: normalizeText(input.threadId),
405
+ turnId: normalizeText(input.turnId)
409
406
  });
410
407
  clearCodexAppServerActiveTimer(sessionId);
411
408
  clearCodexAppServerFinalizingTimer(sessionId, input.threadId, input.turnId);
@@ -416,16 +413,16 @@ export function createCodexRunJournal({
416
413
  ...result,
417
414
  checkpoint: await checkpoint(sessionId, {
418
415
  status,
419
- turnOutcome: normalizeCodexRunText(input.turnOutcome),
420
- threadId: normalizeCodexRunText(input.threadId),
421
- turnId: normalizeCodexRunText(input.turnId)
416
+ turnOutcome: normalizeText(input.turnOutcome),
417
+ threadId: normalizeText(input.threadId),
418
+ turnId: normalizeText(input.turnId)
422
419
  })
423
420
  };
424
421
  }
425
422
 
426
423
  async function currentCodexAppServerTurnId(sessionId = "", threadId = "") {
427
- const normalizedSessionId = normalizeCodexRunText(sessionId);
428
- const normalizedThreadId = normalizeCodexRunText(threadId);
424
+ const normalizedSessionId = normalizeText(sessionId);
425
+ const normalizedThreadId = normalizeText(threadId);
429
426
  if (!normalizedSessionId) {
430
427
  return "";
431
428
  }
@@ -442,16 +439,11 @@ export function createCodexRunJournal({
442
439
  }
443
440
 
444
441
  async function resolveCodexAppServerTurnId(sessionId = "", threadId = "", turnId = "") {
445
- return normalizeCodexRunText(turnId) || await currentCodexAppServerTurnId(sessionId, threadId);
446
- }
447
-
448
- function codexAppServerDateValueMs(value = "") {
449
- const parsed = Date.parse(normalizeCodexRunText(value));
450
- return Number.isFinite(parsed) ? parsed : 0;
442
+ return normalizeText(turnId) || await currentCodexAppServerTurnId(sessionId, threadId);
451
443
  }
452
444
 
453
445
  function codexAppServerFinalizingExpired(turn = {}, nowMs = Date.now()) {
454
- if (normalizeCodexRunText(turn.state) !== "finalizing") {
446
+ if (normalizeText(turn.state) !== "finalizing") {
455
447
  return false;
456
448
  }
457
449
  const referenceMs = codexAppServerDateValueMs(turn.completedAt) || codexAppServerDateValueMs(turn.updatedAt);
@@ -467,8 +459,8 @@ export function createCodexRunJournal({
467
459
  }
468
460
 
469
461
  function codexAppServerTurnWasCompleted(session = {}, threadId = "", turnId = "") {
470
- const normalizedThreadId = normalizeCodexRunText(threadId);
471
- const normalizedTurnId = normalizeCodexRunText(turnId);
462
+ const normalizedThreadId = normalizeText(threadId);
463
+ const normalizedTurnId = normalizeText(turnId);
472
464
  if (!normalizedThreadId || !normalizedTurnId) {
473
465
  return false;
474
466
  }
@@ -479,7 +471,7 @@ export function createCodexRunJournal({
479
471
  }
480
472
 
481
473
  async function failOrphanedCodexAppServerPromptDelivery(runtime, session = {}, turn = {}) {
482
- const sessionId = normalizeCodexRunText(session.sessionId);
474
+ const sessionId = normalizeText(session.sessionId);
483
475
  if (!sessionId) {
484
476
  return session;
485
477
  }
@@ -523,14 +515,14 @@ export function createCodexRunJournal({
523
515
  eventKind = "codex-app-server-user-message-ownership-updated",
524
516
  owned = false
525
517
  } = {}) {
526
- const normalizedSessionId = normalizeCodexRunText(sessionId);
527
- const normalizedClientId = normalizeCodexRunText(clientId);
518
+ const normalizedSessionId = normalizeText(sessionId);
519
+ const normalizedClientId = normalizeText(clientId);
528
520
  if (!normalizedSessionId || !normalizedClientId) {
529
521
  return false;
530
522
  }
531
523
  let wasOwned = false;
532
524
  await store.mutateSession(normalizedSessionId, async () => {
533
- const run = await readCodexAppServerAgentRunForSession(store, normalizedSessionId);
525
+ const run = await output.readAgentRunForSession(store, normalizedSessionId);
534
526
  const currentIds = codexAppServerPendingUserMessageClientIds(run);
535
527
  wasOwned = currentIds.indexOf(normalizedClientId) >= 0;
536
528
  if (wasOwned === owned) {
@@ -567,9 +559,9 @@ export function createCodexRunJournal({
567
559
  nowMs - runUpdatedMs >= CODEX_APP_SERVER_PROMPT_CLAIM_GRACE_MS
568
560
  );
569
561
  return (
570
- normalizeCodexRunText(run.state) === CODEX_APP_SERVER_RUN_STATE.STARTING &&
571
- !normalizeCodexRunText(run.providerThreadId) &&
572
- !normalizeCodexRunText(run.providerTurnId) &&
562
+ normalizeText(run.state) === CODEX_APP_SERVER_RUN_STATE.STARTING &&
563
+ !normalizeText(run.providerThreadId) &&
564
+ !normalizeText(run.providerTurnId) &&
573
565
  promptDeliveryActive !== true &&
574
566
  (admissionTaskFinished(session, run) || claimExpired)
575
567
  ) ? run : null;
@@ -577,7 +569,7 @@ export function createCodexRunJournal({
577
569
 
578
570
  async function recoverAbandonedCodexAppServerPromptClaim(runtime, session = {}, options = {}) {
579
571
  const run = abandonedCodexAppServerPromptClaim(session, options);
580
- if (!run || !session?.sessionId || typeof runtime?.store?.writeAgentRunEvent !== "function") {
572
+ if (!run || !session.sessionId) {
581
573
  return {
582
574
  recovered: false,
583
575
  session
@@ -602,7 +594,7 @@ export function createCodexRunJournal({
602
594
  }
603
595
  });
604
596
  debugLog("appServerPrompt.abandoned", {
605
- runUpdatedAt: normalizeCodexRunText(run.updatedAt),
597
+ runUpdatedAt: normalizeText(run.updatedAt),
606
598
  sessionId: session.sessionId
607
599
  });
608
600
  return {
@@ -611,7 +603,7 @@ export function createCodexRunJournal({
611
603
  };
612
604
  }
613
605
 
614
- return {
606
+ return Object.freeze({
615
607
  completedTurns: codexAppServerCompletedTurns,
616
608
  processedTurns: codexAppServerProcessedTurns,
617
609
  activeTimers: codexAppServerActiveTimers,
@@ -619,7 +611,7 @@ export function createCodexRunJournal({
619
611
  agentRunPatch,
620
612
  turnResultWasProcessed: codexAppServerTurnResultWasProcessed,
621
613
  claimTurnStart: claimCodexAppServerTurnStart,
622
- claimMessageStart: claimCodexAppServerMessageStart,
614
+ claimCodexAppServerMessageStart,
623
615
  writeAgentRun: writeCodexAppServerAgentRun,
624
616
  clearActiveTimer: clearCodexAppServerActiveTimer,
625
617
  clearFinalizingTimer: clearCodexAppServerFinalizingTimer,
@@ -636,5 +628,7 @@ export function createCodexRunJournal({
636
628
  writeUserMessageOwnership: writeCodexAppServerUserMessageOwnership,
637
629
  recoverAbandonedPromptClaim: recoverAbandonedCodexAppServerPromptClaim,
638
630
  failOrphanedPromptDelivery: failOrphanedCodexAppServerPromptDelivery
639
- };
631
+ });
640
632
  }
633
+
634
+ /** @typedef {ReturnType<typeof createCodexRunJournal>} CodexRunJournal */