@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
@@ -7,6 +7,7 @@ await runCodexAppServerProcess({
7
7
  runtimeDir,
8
8
  command,
9
9
  args,
10
+ env: process.env,
10
11
  runtimeToken: process.env[CODEX_APP_SERVER_DEFAULT_ENVIRONMENT.runtimeToken],
11
12
  bundled: process.env[CODEX_APP_SERVER_DEFAULT_ENVIRONMENT.modelCatalogSource] === "bundled",
12
13
  additionalModels: codexProviderModelCatalog({ models: NATIVE_AI_PROVIDERS.flatMap(provider =>
@@ -0,0 +1,241 @@
1
+ import { codexAppServerTurnStatusIsSuccessfulComplete, codexAppServerTurnStatusIsProviderFailure, codexAppServerErrorMessage, codexAppServerSteerFailure, codexAppServerMessageRequiresNewTurn, codexAppServerMessageDeferred } from "./codexTurnState.js";
2
+ import { codexAppServerRequestIsInvalid } from "./codexProviderThreads.js";
3
+ import { codexLocalImageInput, codexAppServerDeliveredTurn, sendCodexAppServerPrompt } from "./codexProviderTurns.js";
4
+ import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
5
+ import { ignorePromptRejection, ignorePromptSending } from "./nativeCommandCallbacks.js";
6
+
7
+ /**
8
+ * Delivers one prompt to the native thread: it starts a new turn, or steers the active one. Each delivery owns its
9
+ * user message until the native receipt arrives, and releases it when the provider refuses.
10
+ * @param {object} dependencies
11
+ * @param {import("./codexOutput.js").CodexAppServerOutput} dependencies.output
12
+ * @param {import("./codexRunJournal.js").CodexRunJournal} dependencies.journal
13
+ * @param {import("./codexTurnRecovery.js").CodexTurnRecovery} dependencies.recovery
14
+ * @param {import("./codexThreadStatus.js").CodexThreadStatus} dependencies.threadStatus
15
+ * @param {import("./codexMessageDelivery.js").CodexAppServerMessageDelivery} dependencies.delivery
16
+ * @param {import("./codexTurn.js").CodexDebugError} dependencies.debugError
17
+ * @param {import("./codexTurn.js").CodexDebugLog} dependencies.debugLog
18
+ * @param {string} dependencies.steerFailedCode
19
+ * @param {import("./codexTurn.js").CodexTurnStateReader} dependencies.turnState
20
+ */
21
+ export function createCodexPromptDispatch({
22
+ output,
23
+ journal,
24
+ recovery,
25
+ threadStatus,
26
+ delivery,
27
+ debugError,
28
+ debugLog,
29
+ steerFailedCode,
30
+ turnState
31
+ }) {
32
+
33
+ async function startCodexAppServerTurn(sessionId, input = {}, context = {}) {
34
+ const { runtime, provider, threadId, messageId, renderedPrompt, turnMetadata } = context;
35
+ const { onPromptSending = ignorePromptSending, onPromptRejected = ignorePromptRejection } = input;
36
+ let providerFailure = "";
37
+ let nativeDelivery = null;
38
+ const promptSessionId = normalizeText(sessionId);
39
+ const clientUserMessageId = messageId;
40
+ await journal.writeUserMessageOwnership(runtime.store, sessionId, clientUserMessageId, {
41
+ eventKind: "codex-app-server-user-message-owned",
42
+ owned: true
43
+ });
44
+ try {
45
+ await onPromptSending({ threadId: threadId, displayAttachments: input.displayAttachments, turnMetadata });
46
+ const response = sendCodexAppServerPrompt({
47
+ clientUserMessageId,
48
+ prompt: renderedPrompt,
49
+ attachments: input.attachments,
50
+ provider,
51
+ threadId
52
+ }, context);
53
+ const receipt = delivery.pendingUserMessage(promptSessionId, clientUserMessageId)?.receipt;
54
+ // An exact, persisted user-message receipt confirms delivery too.
55
+ // Finish bookkeeping once; a late RPC reply must not hold admission
56
+ // or change a turn that has already continued or completed.
57
+ nativeDelivery = receipt
58
+ ? await Promise.race([response, receipt.promise.then((turn) => ({ turn }))])
59
+ : await response;
60
+ } catch (error) {
61
+ if (Number.isInteger(error?.code) && error.code < 0) await onPromptRejected();
62
+ await journal.writeUserMessageOwnership(runtime.store, sessionId, clientUserMessageId, {
63
+ eventKind: "codex-app-server-user-message-released",
64
+ owned: false
65
+ });
66
+ await journal.markTurnIdle(sessionId, {
67
+ error: codexAppServerErrorMessage(error, "Codex app-server prompt delivery failed."),
68
+ status: "failed",
69
+ threadId: threadId
70
+ });
71
+ return { error, turnFailureHandled: true };
72
+ }
73
+ const { turnId: deliveredTurnId, status: deliveredTurnStatus } = codexAppServerDeliveredTurn(nativeDelivery);
74
+ if (!deliveredTurnId) {
75
+ throw new Error("Codex app-server accepted the prompt without returning a turn id.");
76
+ }
77
+ delivery.pendingUserMessage(promptSessionId, clientUserMessageId)?.onNativeReceipt();
78
+ await recovery.markTurnActive(sessionId, {
79
+ requireTrackedTurn: true,
80
+ status: "inProgress",
81
+ threadId: threadId,
82
+ turnId: deliveredTurnId
83
+ });
84
+ if (codexAppServerTurnStatusIsProviderFailure(deliveredTurnStatus)) {
85
+ providerFailure = `Codex turn ${deliveredTurnStatus}.`;
86
+ await recovery.stopTurnWithProviderFailure(sessionId, threadId, deliveredTurnId, {
87
+ provider,
88
+ status: deliveredTurnStatus
89
+ });
90
+ } else if (codexAppServerTurnStatusIsSuccessfulComplete(deliveredTurnStatus)) {
91
+ const completion = await recovery.completeTurn(sessionId, threadId, deliveredTurnId, {
92
+ provider,
93
+ status: deliveredTurnStatus
94
+ });
95
+ if (completion?.ok === false) {
96
+ providerFailure = normalizeText(completion.error) || "Codex completed, but its response could not be processed.";
97
+ }
98
+ }
99
+ return { delivery: nativeDelivery, deliveredTurnId, providerFailure };
100
+ }
101
+
102
+ async function steerCodexAppServerTurn(sessionId, input = {}, context = {}) {
103
+ const { runtime, provider, threadId, turnId, message, displayMessage, messageId, clientUserMessageId, turnMetadata } = context;
104
+ const { onPromptSending = ignorePromptSending, onPromptRejected = ignorePromptRejection } = input;
105
+ let currentSession;
106
+ await journal.writeUserMessageOwnership(runtime.store, sessionId, clientUserMessageId, {
107
+ eventKind: "codex-app-server-user-message-owned",
108
+ owned: true
109
+ });
110
+ debugLog("appServerMessage.activeTurn.start", {
111
+ messageId,
112
+ sessionId,
113
+ threadId,
114
+ turnId
115
+ });
116
+ async function recoverAfterSteerFailure(error = null) {
117
+ await journal.writeUserMessageOwnership(runtime.store, sessionId, clientUserMessageId, {
118
+ eventKind: "codex-app-server-user-message-released",
119
+ owned: false
120
+ });
121
+ await threadStatus.reconcileThreadStatus(sessionId, provider, threadId, {
122
+ source: "message_delivery_steer_race"
123
+ }).catch(() => null);
124
+ currentSession = await runtime.getSession(sessionId);
125
+ const currentTurn = turnState(currentSession);
126
+ const sameTurnIsActive = currentTurn.active === true &&
127
+ normalizeText(currentTurn.threadId) === threadId &&
128
+ normalizeText(currentTurn.turnId) === turnId &&
129
+ currentTurn.state !== "finalizing";
130
+ if (sameTurnIsActive) {
131
+ return codexAppServerRequestIsInvalid(error, "turn/steer")
132
+ ? { value: codexAppServerMessageDeferred({ threadId, turnId }, steerFailedCode), session: currentSession }
133
+ : null;
134
+ }
135
+ debugLog("appServerMessage.newTurn", {
136
+ error: debugError(error),
137
+ messageId,
138
+ reason: "active_turn_completed_before_delivery",
139
+ sessionId,
140
+ threadId,
141
+ turnId
142
+ });
143
+ return { value: codexAppServerMessageRequiresNewTurn({
144
+ reason: "active_turn_completed_before_delivery",
145
+ threadId,
146
+ turnId
147
+ }), session: currentSession };
148
+ }
149
+ let result;
150
+ try {
151
+ await onPromptSending({ threadId, displayAttachments: input.displayAttachments, turnMetadata });
152
+ const response = provider.steerTurn(
153
+ threadId,
154
+ turnId,
155
+ context.preparedInput === undefined
156
+ ? input.attachments?.some((attachment) => attachment.contentType?.startsWith("image/"))
157
+ ? [message, ...codexLocalImageInput(input.attachments)]
158
+ : message
159
+ : context.preparedInput,
160
+ {
161
+ clientUserMessageId
162
+ }
163
+ );
164
+ const receipt = delivery.pendingUserMessage(sessionId, clientUserMessageId)?.receipt;
165
+ result = receipt ? await Promise.race([response, receipt.promise]) : await response;
166
+ } catch (error) {
167
+ if (Number.isInteger(error?.code) && error.code < 0) await onPromptRejected();
168
+ const recovered = await recoverAfterSteerFailure(error);
169
+ if (recovered) {
170
+ return recovered;
171
+ }
172
+ debugLog("appServerMessage.activeTurn.error", {
173
+ error: debugError(error),
174
+ messageId,
175
+ sessionId,
176
+ threadId,
177
+ turnId
178
+ });
179
+ throw error;
180
+ }
181
+ const steerFailure = codexAppServerSteerFailure(result, steerFailedCode);
182
+ if (steerFailure) {
183
+ const recovered = await recoverAfterSteerFailure(result);
184
+ if (recovered) {
185
+ return recovered;
186
+ }
187
+ debugLog("appServerMessage.activeTurn.failed", {
188
+ error: steerFailure.error,
189
+ messageId,
190
+ operationOutcome: steerFailure.operationOutcome,
191
+ sessionId,
192
+ threadId,
193
+ turnId
194
+ });
195
+ return { value: {
196
+ ...steerFailure,
197
+ result,
198
+ threadId,
199
+ turnId
200
+ } };
201
+ }
202
+ delivery.pendingUserMessage(sessionId, clientUserMessageId)?.onNativeReceipt();
203
+ const conversationTurn = await delivery.writeDeliveredUserMessage(
204
+ runtime,
205
+ sessionId,
206
+ displayMessage || message,
207
+ messageId,
208
+ turnMetadata,
209
+ input.displayAttachments,
210
+ { threadId, turnId }
211
+ );
212
+ output.splitReasoningTurn(threadId, turnId);
213
+ currentSession = await runtime.getSession(sessionId);
214
+ debugLog("appServerMessage.activeTurn.done", {
215
+ conversationTurnId: normalizeText(conversationTurn?.turnId || conversationTurn?.id),
216
+ messageId,
217
+ sessionId,
218
+ threadId,
219
+ turnId
220
+ });
221
+ return { value: {
222
+ conversationTurn,
223
+ conversationTurns: [conversationTurn],
224
+ delivered: true,
225
+ deliveryMode: "active_turn",
226
+ newTurnRequired: false,
227
+ ok: true,
228
+ operationOutcome: "delivered_to_active_turn",
229
+ result,
230
+ threadId,
231
+ turnId
232
+ }, session: currentSession };
233
+ }
234
+
235
+ return Object.freeze({
236
+ startTurn: startCodexAppServerTurn,
237
+ steerTurn: steerCodexAppServerTurn
238
+ });
239
+ }
240
+
241
+ /** @typedef {ReturnType<typeof createCodexPromptDispatch>} CodexPromptDispatch */