@jskit-ai/assistant-core 0.1.200 → 0.1.202

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 (164) hide show
  1. package/examples/conversation/README.md +8 -1
  2. package/examples/conversation/package.json +5 -5
  3. package/fixtures/responsive-assistant/App.vue +4 -1
  4. package/package.json +99 -36
  5. package/src/client/conversation/AssistantConversationElement.vue +27 -4
  6. package/src/client/conversation/AssistantConversationStatus.vue +24 -0
  7. package/src/client/conversation/AssistantGoalControl.vue +8 -5
  8. package/src/client/conversation/AssistantTranscript.vue +10 -3
  9. package/src/client/conversation/index.js +2 -0
  10. package/src/client/conversation/messageDelivery.js +115 -32
  11. package/src/client/conversation/retainedConversation.js +32 -0
  12. package/src/client/conversation/useAssistantQuestions.js +76 -0
  13. package/src/client/lib/assistantApi.js +72 -2
  14. package/src/server/conversation/agentRun.js +222 -0
  15. package/src/server/conversation/attachments.js +93 -0
  16. package/src/server/conversation/claudeClient.js +221 -0
  17. package/src/server/conversation/claudeHistory.js +256 -0
  18. package/src/server/conversation/claudeProcess.js +327 -0
  19. package/src/server/conversation/claudeTools.js +42 -0
  20. package/src/server/conversation/claudeTurn.js +1082 -0
  21. package/src/server/conversation/codexConfiguration.js +1183 -0
  22. package/src/server/conversation/codexConversations.js +1082 -0
  23. package/src/server/conversation/codexDetachedTurn.js +332 -0
  24. package/src/server/conversation/codexEvents.js +194 -1
  25. package/src/server/conversation/codexGoalCommands.js +124 -0
  26. package/src/server/conversation/codexHelperExecution.js +306 -0
  27. package/src/server/conversation/codexHelperThreadLedger.js +804 -0
  28. package/src/server/conversation/codexHelperThreadRecovery.js +395 -0
  29. package/src/server/conversation/codexHelperThreads.js +638 -0
  30. package/src/server/conversation/codexHistoryAdapter.js +369 -0
  31. package/src/server/conversation/codexMessageCommands.js +663 -0
  32. package/src/server/conversation/codexMessageDelivery.js +211 -0
  33. package/src/server/conversation/codexNativeHistoryExport.js +95 -0
  34. package/src/server/conversation/codexNotificationObserver.js +482 -0
  35. package/src/server/conversation/codexNotificationQueue.js +103 -0
  36. package/src/server/conversation/codexObservationControl.js +174 -0
  37. package/src/server/conversation/codexOutput.js +931 -0
  38. package/src/server/conversation/codexProcess.js +1559 -0
  39. package/src/server/conversation/codexProcessLeader.js +14 -0
  40. package/src/server/conversation/codexProvider.js +2710 -0
  41. package/src/server/conversation/codexProviderOwner.js +1058 -0
  42. package/src/server/conversation/codexProviderSelection.js +218 -0
  43. package/src/server/conversation/codexReasoning.js +314 -0
  44. package/src/server/conversation/codexRenewalCommands.js +290 -0
  45. package/src/server/conversation/codexResultSettlement.js +409 -0
  46. package/src/server/conversation/codexRunJournal.js +658 -0
  47. package/src/server/conversation/codexRuntimeLifecycle.js +288 -0
  48. package/src/server/conversation/codexSessionCleanup.js +96 -0
  49. package/src/server/conversation/codexSessionReconciliation.js +284 -0
  50. package/src/server/conversation/codexThreadReadiness.js +397 -0
  51. package/src/server/conversation/codexThreadStatus.js +354 -0
  52. package/src/server/conversation/codexTurn.js +701 -255
  53. package/src/server/conversation/codexTurnControl.js +317 -0
  54. package/src/server/conversation/codexTurnRecovery.js +990 -0
  55. package/src/server/conversation/codexTurnState.js +549 -0
  56. package/src/server/conversation/commandHook.js +18 -0
  57. package/src/server/conversation/commandWrapper.js +37 -0
  58. package/src/server/conversation/configuration.js +43 -0
  59. package/src/server/conversation/continuity.js +289 -0
  60. package/src/server/conversation/fileStorage.js +55 -0
  61. package/src/server/conversation/hookBridge.js +19 -0
  62. package/src/server/conversation/index.js +13 -0
  63. package/src/server/conversation/localExecution.js +665 -0
  64. package/src/server/conversation/memoryStorage.js +7 -72
  65. package/src/server/conversation/nativeHistoryExport.js +90 -0
  66. package/src/server/conversation/nativeStorage.js +23 -0
  67. package/src/server/conversation/openCodeClient.js +209 -19
  68. package/src/server/conversation/openCodePlugin.js +84 -0
  69. package/src/server/conversation/openCodeProcess.js +476 -0
  70. package/src/server/conversation/openCodeRuntime.js +1578 -0
  71. package/src/server/conversation/openCodeTools.js +60 -0
  72. package/src/server/conversation/openCodeTurn.js +557 -0
  73. package/src/server/conversation/provider.js +30 -0
  74. package/src/server/conversation/providers/api.js +136 -0
  75. package/src/server/conversation/providers/claude.js +63 -0
  76. package/src/server/conversation/providers/claudeDriver.js +425 -0
  77. package/src/server/conversation/providers/codex.js +248 -0
  78. package/src/server/conversation/providers/codexDriver.js +1078 -0
  79. package/src/server/conversation/providers/opencode.js +49 -0
  80. package/src/server/conversation/providers/opencodeDriver.js +650 -0
  81. package/src/server/conversation/providers/scoped.js +312 -0
  82. package/src/server/conversation/runtime.js +2220 -0
  83. package/src/server/conversation/runtimeStateUpgrade.js +125 -0
  84. package/src/server/conversation/storage.js +184 -0
  85. package/src/server/conversation/streams.js +7 -2
  86. package/src/server/conversation/structuredOutput.js +240 -0
  87. package/src/server/conversation/systemPrompt.js +54 -0
  88. package/src/server/conversation/tools.js +84 -0
  89. package/src/server/conversation/transcript.js +5 -4
  90. package/src/server/hosts/claudeHistory.js +5 -0
  91. package/src/server/hosts/claudeProcess.js +11 -0
  92. package/src/server/hosts/claudeTurn.js +4 -0
  93. package/src/server/hosts/codexConfiguration.js +20 -0
  94. package/src/server/hosts/codexEvents.js +13 -0
  95. package/src/server/hosts/codexProcess.js +12 -0
  96. package/src/server/hosts/codexProvider.js +23 -0
  97. package/src/server/hosts/codexTurn.js +20 -0
  98. package/src/server/hosts/nativeHistory.js +3 -0
  99. package/src/server/hosts/openCodeClient.js +3 -0
  100. package/src/server/hosts/openCodeProcess.js +23 -0
  101. package/src/server/hosts/openCodeTurn.js +7 -0
  102. package/src/server/index.js +2 -0
  103. package/src/server/lib/aiConnectionClient.js +13 -6
  104. package/src/server/lib/assistantCompletion.js +190 -0
  105. package/src/server/lib/assistantToolLoop.js +314 -0
  106. package/src/server/lib/serviceToolCatalog.js +25 -10
  107. package/src/shared/assistantResponseText.js +29 -0
  108. package/src/shared/conversation/attachments.js +19 -0
  109. package/src/shared/conversation/index.js +3 -0
  110. package/src/shared/conversation/pagination.js +78 -0
  111. package/src/shared/conversation/patches.js +150 -0
  112. package/src/shared/conversation/questions.js +48 -0
  113. package/src/shared/conversation/streaming.js +7 -4
  114. package/src/shared/index.js +2 -0
  115. package/src/shared/nativeProviders.js +45 -0
  116. package/src/testing/conversationStorageContract.js +31 -1
  117. package/src/testing/nativeCodex.js +11 -0
  118. package/src/testing/nativeOpenCode.js +3 -0
  119. package/test/aiConnectionClient.test.js +2 -0
  120. package/test/apiConversationDriver.test.js +73 -0
  121. package/test/assistantApiSurfaceHeader.test.js +85 -0
  122. package/test/assistantBoundedToolLoop.test.js +285 -0
  123. package/test/assistantScroll.browser.test.js +16 -0
  124. package/test/claudeClient.test.js +189 -0
  125. package/test/claudeConversationSession.test.js +1173 -0
  126. package/test/claudeInstructionResume.test.js +82 -0
  127. package/test/claudeProcess.test.js +204 -0
  128. package/test/claudeTurn.test.js +253 -0
  129. package/test/codexConversationSession.test.js +2122 -0
  130. package/test/codexGoal.test.js +37 -0
  131. package/test/codexHelperDeletion.test.js +163 -0
  132. package/test/codexHelperThreadLedger.test.js +494 -0
  133. package/test/codexHistoryAdapter.test.js +541 -0
  134. package/test/codexInteractiveArguments.test.js +30 -0
  135. package/test/codexIsolation.test.js +756 -0
  136. package/test/codexModelCatalog.test.js +362 -0
  137. package/test/codexNativeHistoryExport.test.js +81 -0
  138. package/test/codexThreadSelection.test.js +136 -0
  139. package/test/codexTurn.test.js +2158 -0
  140. package/test/conversation.test.js +110 -0
  141. package/test/conversationAgentRun.test.js +326 -0
  142. package/test/conversationApiFacilities.test.js +90 -0
  143. package/test/conversationAttachments.test.js +238 -0
  144. package/test/conversationCommandWrapper.test.js +48 -0
  145. package/test/conversationConfiguration.test.js +174 -0
  146. package/test/conversationNativeStorage.test.js +25 -0
  147. package/test/conversationReplacement.test.js +172 -0
  148. package/test/conversationRuntime.test.js +241 -0
  149. package/test/conversationRuntimeStateUpgrade.test.js +144 -0
  150. package/test/conversationSession.test.js +1080 -0
  151. package/test/conversationStreaming.test.js +68 -0
  152. package/test/conversationSystemPrompt.test.js +84 -0
  153. package/test/conversationTools.test.js +416 -0
  154. package/test/fileConversationStorage.test.js +73 -0
  155. package/test/fixtures/codexHelperThreadLedger.js +39 -0
  156. package/test/localConversationExecution.test.js +90 -0
  157. package/test/messageDelivery.test.js +234 -1
  158. package/test/nativeConversationRetirement.test.js +215 -0
  159. package/test/openCodeClient.test.js +515 -0
  160. package/test/openCodeProcess.test.js +177 -0
  161. package/test/openCodeRuntime.test.js +322 -0
  162. package/test/openCodeTools.test.js +287 -0
  163. package/test/opencodeConversationSession.test.js +789 -0
  164. package/test/serviceToolCatalog.test.js +24 -0
@@ -0,0 +1,354 @@
1
+ import {
2
+ codexAppServerTurnStatusIsActive,
3
+ codexAppServerTurnStatusIsComplete,
4
+ codexAppServerTurnStatusIsSuccessfulComplete,
5
+ codexAppServerTurnStatusIsProviderFailure,
6
+ codexAppServerThreadStatus,
7
+ codexAppServerReadThreadStatus,
8
+ normalizeCodexRunText,
9
+ codexAppServerAgentRun,
10
+ codexAppServerTurnCanReceiveProviderCompletion,
11
+ codexAppServerTurnCanAdoptSuccessor,
12
+ codexAppServerErrorMessage
13
+ } from "./codexTurnState.js";
14
+ import { isPlainObject } from "./normalize.js";
15
+ import {
16
+ codexAppServerStatusFromValue,
17
+ codexAppServerThreadRawValue,
18
+ codexAppServerThreadTurnId,
19
+ codexAppServerThreadError
20
+ } from "./codexEvents.js";
21
+
22
+ // Original native snapshot reconciliation; existing owners retain all state.
23
+ export function createCodexThreadStatus({ journal, settlement, recovery, output, createRuntime, turnState, turnOutcomes, debugLog, debugError }) {
24
+ const { turnResultWasProcessed: codexAppServerTurnResultWasProcessed } = journal;
25
+ const {
26
+ finalizeAssistantResult: finalizeCodexAppServerAssistantResult,
27
+ adoptSuccessorTurn: adoptCodexAppServerSuccessorTurn
28
+ } = settlement;
29
+ const {
30
+ stopTurnWithProviderFailure: stopCodexAppServerTurnWithProviderFailure,
31
+ markProviderTurnActive: markCodexAppServerProviderTurnActive,
32
+ completeTurn: completeCodexAppServerTurn
33
+ } = recovery;
34
+ const { reconcileObservedTurnItems: reconcileCodexAppServerObservedTurnItems } = output;
35
+
36
+ function codexAppServerReadyTurnFailureMessage(reason = "", error = "") {
37
+ const detail = normalizeCodexRunText(error);
38
+ if (detail) {
39
+ return detail;
40
+ }
41
+ switch (normalizeCodexRunText(reason)) {
42
+ case "thread_replaced":
43
+ return "Codex app-server resumed a different thread before this turn completed.";
44
+ case "provider_unreadable":
45
+ return "Codex app-server could not confirm the active turn after restart.";
46
+ case "missing_status":
47
+ return "Codex app-server did not report the active turn status after restart.";
48
+ case "missing_turn":
49
+ return "Codex app-server did not report the active turn after restart.";
50
+ case "turn_mismatch":
51
+ return "Codex app-server reported a different active turn after restart.";
52
+ default:
53
+ return "Codex app-server could not recover the active turn after restart.";
54
+ }
55
+ }
56
+
57
+ async function failCodexAppServerTrackedReadyTurn(sessionId = "", turn = {}, {
58
+ error = "",
59
+ reason = "",
60
+ status = "failed",
61
+ threadId = "",
62
+ turnId = ""
63
+ } = {}) {
64
+ const normalizedSessionId = normalizeCodexRunText(sessionId);
65
+ const normalizedThreadId = normalizeCodexRunText(threadId) || normalizeCodexRunText(turn.threadId);
66
+ const normalizedTurnId = normalizeCodexRunText(turnId) || normalizeCodexRunText(turn.turnId);
67
+ if (!normalizedSessionId || !normalizedThreadId) {
68
+ return {
69
+ ok: false,
70
+ processed: false,
71
+ reason: "missing_tracked_turn"
72
+ };
73
+ }
74
+ return stopCodexAppServerTurnWithProviderFailure(
75
+ normalizedSessionId,
76
+ normalizedThreadId,
77
+ normalizedTurnId,
78
+ {
79
+ error: codexAppServerReadyTurnFailureMessage(reason, error),
80
+ outcome: turnOutcomes.SERVICE_RESTART,
81
+ status
82
+ }
83
+ );
84
+ }
85
+
86
+ async function reconcileCodexAppServerThreadStatus(sessionId = "", provider = null, threadId = "", {
87
+ failUnconfirmedTrackedTurn = false,
88
+ observeLatestTurn = false,
89
+ requireTrackedTurn = false,
90
+ source = ""
91
+ } = {}) {
92
+ const normalizedSessionId = normalizeCodexRunText(sessionId);
93
+ const normalizedThreadId = normalizeCodexRunText(threadId);
94
+ const runtime = normalizedSessionId
95
+ ? await createRuntime()
96
+ : null;
97
+ const session = runtime
98
+ ? await runtime.getSession(normalizedSessionId)
99
+ : {};
100
+ const trackedTurn = turnState(session);
101
+ if (trackedTurn.status === "observation_lost") return { ok: true, status: "observation_lost" };
102
+ const trackedStartingTurn = trackedTurn.active && trackedTurn.state === "starting"
103
+ ? trackedTurn
104
+ : null;
105
+ const trackedProviderTurn = ["active", "finalizing"].includes(trackedTurn.state) &&
106
+ trackedTurn.active &&
107
+ trackedTurn.threadId
108
+ ? trackedTurn
109
+ : null;
110
+ const statusThreadId = normalizeCodexRunText(trackedProviderTurn?.threadId) || normalizedThreadId;
111
+ const shouldFailUnconfirmed = failUnconfirmedTrackedTurn && trackedProviderTurn;
112
+ if (!normalizedSessionId || !normalizedThreadId) {
113
+ return {
114
+ ok: true,
115
+ status: "notRead"
116
+ };
117
+ }
118
+ if (requireTrackedTurn && !trackedProviderTurn) {
119
+ return {
120
+ ok: true,
121
+ status: "notTracked"
122
+ };
123
+ }
124
+ if (
125
+ trackedProviderTurn?.state === "finalizing" &&
126
+ codexAppServerTurnResultWasProcessed(
127
+ session,
128
+ trackedProviderTurn.threadId,
129
+ trackedProviderTurn.turnId
130
+ )
131
+ ) {
132
+ await finalizeCodexAppServerAssistantResult(
133
+ normalizedSessionId,
134
+ trackedProviderTurn.threadId,
135
+ trackedProviderTurn.turnId,
136
+ {
137
+ status: trackedProviderTurn.status || "completed"
138
+ }
139
+ );
140
+ return {
141
+ ok: true,
142
+ status: trackedProviderTurn.status || "completed",
143
+ turnId: trackedProviderTurn.turnId
144
+ };
145
+ }
146
+
147
+ if (shouldFailUnconfirmed && statusThreadId !== normalizedThreadId) {
148
+ debugLog("appServerThread.reconcile.trackedThreadReplaced", {
149
+ currentThreadId: normalizedThreadId,
150
+ sessionId: normalizedSessionId,
151
+ source: normalizeCodexRunText(source),
152
+ trackedThreadId: statusThreadId,
153
+ trackedTurnId: trackedProviderTurn.turnId
154
+ });
155
+ return failCodexAppServerTrackedReadyTurn(normalizedSessionId, trackedProviderTurn, {
156
+ reason: "thread_replaced"
157
+ });
158
+ }
159
+
160
+ if (typeof provider?.readThreadStatus !== "function") {
161
+ if (shouldFailUnconfirmed) {
162
+ return failCodexAppServerTrackedReadyTurn(normalizedSessionId, trackedProviderTurn, {
163
+ reason: "provider_unreadable"
164
+ });
165
+ }
166
+ return {
167
+ ok: true,
168
+ status: "notRead"
169
+ };
170
+ }
171
+
172
+ let thread = null;
173
+ try {
174
+ thread = await codexAppServerReadThreadStatus(provider, statusThreadId, {
175
+ observeLatestTurn
176
+ });
177
+ } catch (error) {
178
+ if (shouldFailUnconfirmed) {
179
+ debugLog("appServerThread.reconcile.readFailed", {
180
+ error: debugError(error),
181
+ sessionId: normalizedSessionId,
182
+ source: normalizeCodexRunText(source),
183
+ threadId: statusThreadId,
184
+ turnId: trackedProviderTurn.turnId
185
+ });
186
+ return failCodexAppServerTrackedReadyTurn(normalizedSessionId, trackedProviderTurn, {
187
+ error: codexAppServerErrorMessage(error, "Codex app-server could not confirm the active turn after restart."),
188
+ reason: "provider_unreadable"
189
+ });
190
+ }
191
+ throw error;
192
+ }
193
+
194
+ const status = codexAppServerThreadStatus(thread);
195
+ const turnId = codexAppServerThreadTurnId(thread);
196
+ if (!status) {
197
+ if (shouldFailUnconfirmed) {
198
+ return failCodexAppServerTrackedReadyTurn(normalizedSessionId, trackedProviderTurn, {
199
+ reason: "missing_status"
200
+ });
201
+ }
202
+ return {
203
+ ok: true,
204
+ status: "unknown"
205
+ };
206
+ }
207
+ // A STARTING run has durable application ownership but no provider identity yet.
208
+ // A thread snapshot may describe the predecessor (or an unrelated terminal
209
+ // turn), so only the active-turn recovery path may bind it after matching
210
+ // the provider's client message id.
211
+ if (trackedStartingTurn) {
212
+ return {
213
+ ok: true,
214
+ status,
215
+ turnId
216
+ };
217
+ }
218
+ if (
219
+ trackedProviderTurn &&
220
+ turnId &&
221
+ codexAppServerTurnCanAdoptSuccessor(trackedProviderTurn, statusThreadId, turnId)
222
+ ) {
223
+ const adoption = await adoptCodexAppServerSuccessorTurn(normalizedSessionId, {
224
+ previousTurnId: trackedProviderTurn.turnId,
225
+ source: normalizeCodexRunText(source) || "thread_status",
226
+ status: "inProgress",
227
+ threadId: statusThreadId,
228
+ turnId
229
+ });
230
+ if (!adoption.processed && adoption.reason !== "already_current") {
231
+ if (shouldFailUnconfirmed) {
232
+ return failCodexAppServerTrackedReadyTurn(normalizedSessionId, trackedProviderTurn, {
233
+ reason: "turn_mismatch"
234
+ });
235
+ }
236
+ return {
237
+ ok: true,
238
+ reason: adoption.reason,
239
+ status,
240
+ turnId
241
+ };
242
+ }
243
+ }
244
+ if (codexAppServerTurnStatusIsActive(status)) {
245
+ if (!turnId) {
246
+ debugLog("appServerThread.reconcile.activeWithoutTurn", {
247
+ sessionId: normalizedSessionId,
248
+ status,
249
+ source: normalizeCodexRunText(source),
250
+ threadId: statusThreadId,
251
+ trackedTurnId: trackedProviderTurn?.turnId || ""
252
+ });
253
+ return {
254
+ ok: true,
255
+ status
256
+ };
257
+ }
258
+ await markCodexAppServerProviderTurnActive(normalizedSessionId, {
259
+ observedRun: codexAppServerTurnStatusIsActive(codexAppServerStatusFromValue(
260
+ codexAppServerThreadRawValue(thread).status || thread.status
261
+ )) ? codexAppServerAgentRun(session) : null,
262
+ source: normalizeCodexRunText(source) || "thread_status",
263
+ status,
264
+ threadId: statusThreadId,
265
+ turnId
266
+ });
267
+ await reconcileCodexAppServerObservedTurnItems(
268
+ normalizedSessionId,
269
+ statusThreadId,
270
+ thread?.observedTurn,
271
+ provider
272
+ );
273
+ return {
274
+ ok: true,
275
+ status,
276
+ turnId
277
+ };
278
+ }
279
+ if (
280
+ codexAppServerTurnStatusIsComplete(status) &&
281
+ isPlainObject(thread?.observedTurn) &&
282
+ turnId
283
+ ) {
284
+ const currentSession = await runtime.getSession(normalizedSessionId);
285
+ const currentTurn = turnState(currentSession);
286
+ if (!currentTurn.active && normalizeCodexRunText(currentTurn.turnId) !== turnId) {
287
+ await markCodexAppServerProviderTurnActive(normalizedSessionId, {
288
+ inputSource: "terminal",
289
+ source: normalizeCodexRunText(source) || "thread_snapshot",
290
+ status: "inProgress",
291
+ threadId: statusThreadId,
292
+ turnId
293
+ });
294
+ }
295
+ const recoverableSession = await runtime.getSession(normalizedSessionId);
296
+ if (codexAppServerTurnCanReceiveProviderCompletion(
297
+ turnState(recoverableSession),
298
+ statusThreadId,
299
+ turnId
300
+ )) {
301
+ await reconcileCodexAppServerObservedTurnItems(
302
+ normalizedSessionId,
303
+ statusThreadId,
304
+ thread.observedTurn,
305
+ provider
306
+ );
307
+ }
308
+ }
309
+ const completedTurnId = turnId || normalizeCodexRunText(trackedProviderTurn?.turnId);
310
+ if (!completedTurnId) {
311
+ return {
312
+ ok: true,
313
+ status
314
+ };
315
+ }
316
+ if (codexAppServerTurnStatusIsProviderFailure(status)) {
317
+ await stopCodexAppServerTurnWithProviderFailure(normalizedSessionId, statusThreadId, completedTurnId, {
318
+ error: codexAppServerThreadError(thread),
319
+ provider,
320
+ status
321
+ });
322
+ } else if (codexAppServerTurnStatusIsSuccessfulComplete(status)) {
323
+ await completeCodexAppServerTurn(normalizedSessionId, statusThreadId, completedTurnId, {
324
+ status,
325
+ verifyInactive: false
326
+ });
327
+ }
328
+ return {
329
+ ok: true,
330
+ status,
331
+ turnId: completedTurnId
332
+ };
333
+ }
334
+
335
+ async function reconcileCodexAppServerLoadedThreadStatus(
336
+ sessionId = "",
337
+ provider = null,
338
+ threadId = "",
339
+ {
340
+ observeLatestTurn = false
341
+ } = {}
342
+ ) {
343
+ return reconcileCodexAppServerThreadStatus(sessionId, provider, threadId, {
344
+ observeLatestTurn,
345
+ source: "loaded_thread"
346
+ });
347
+ }
348
+
349
+
350
+ return {
351
+ reconcileThreadStatus: reconcileCodexAppServerThreadStatus,
352
+ reconcileLoadedThreadStatus: reconcileCodexAppServerLoadedThreadStatus
353
+ };
354
+ }