@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,12 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { codexAppServerPendingUserMessageOwnership } from "./codexTurnState.js";
|
|
2
2
|
import {
|
|
3
3
|
codexAppServerNotificationItem,
|
|
4
4
|
codexAppServerUserMessageText,
|
|
5
5
|
codexAppServerNotificationTurnId
|
|
6
6
|
} from "./codexEvents.js";
|
|
7
|
+
import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
8
|
+
import { ignoreReceipt } from "./nativeCommandCallbacks.js";
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Request deduplication and authored receipt persistence. One instance and its two Maps belong to its run owner.
|
|
12
|
+
* @param {object} dependencies
|
|
13
|
+
* @param {import("./codexTurn.js").CodexSessionNamespace} dependencies.namespace
|
|
14
|
+
* @param {import("./codexTurn.js").CodexPublish} dependencies.publish
|
|
15
|
+
* @param {import("./codexTurn.js").CodexMessageMetadataHooks} dependencies.messageMetadata
|
|
16
|
+
* @param {import("./codexTurn.js").CodexCreateStore} dependencies.createStore
|
|
17
|
+
* @param {import("./codexTurn.js").CodexAgentRunTurnStateReader} dependencies.turnStateFromAgentRun
|
|
18
|
+
* @param {string} dependencies.deliveryStateMetadataKey
|
|
19
|
+
* @param {import("./codexOutput.js").CodexAppServerOutput} dependencies.output
|
|
20
|
+
* @param {import("./codexRunJournal.js").CodexRunJournal} dependencies.journal
|
|
21
|
+
* @param {import("./codexTurnRecovery.js").CodexTurnRecovery} dependencies.recovery
|
|
22
|
+
*/
|
|
10
23
|
export function createCodexAppServerMessageDelivery({
|
|
11
24
|
namespace,
|
|
12
25
|
publish,
|
|
@@ -18,12 +31,6 @@ export function createCodexAppServerMessageDelivery({
|
|
|
18
31
|
journal,
|
|
19
32
|
recovery
|
|
20
33
|
}) {
|
|
21
|
-
const {
|
|
22
|
-
readAgentRunForSession: readCodexAppServerAgentRunForSession,
|
|
23
|
-
writeMirroredTerminalMessage: writeMirroredCodexAppServerTerminalMessage
|
|
24
|
-
} = output;
|
|
25
|
-
const { writeUserMessageOwnership: writeCodexAppServerUserMessageOwnership } = journal;
|
|
26
|
-
const { markProviderTurnActive: markCodexAppServerProviderTurnActive } = recovery;
|
|
27
34
|
const codexAppServerMessageDeliveries = new Map();
|
|
28
35
|
const codexAppServerPendingUserMessages = new Map();
|
|
29
36
|
|
|
@@ -36,15 +43,18 @@ export function createCodexAppServerMessageDelivery({
|
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
async function withCodexAppServerMessageDelivery(sessionId, messageId, pendingMessage, operation) {
|
|
39
|
-
const normalizedMessageId =
|
|
46
|
+
const normalizedMessageId = normalizeText(messageId);
|
|
40
47
|
const deliveryKey = normalizedMessageId ? messageDeliveryKey(sessionId, normalizedMessageId) : "";
|
|
41
48
|
const existing = deliveryKey ? codexAppServerMessageDeliveries.get(deliveryKey) : null;
|
|
42
49
|
if (existing) {
|
|
43
50
|
return existing;
|
|
44
51
|
}
|
|
45
52
|
if (deliveryKey) {
|
|
53
|
+
const { onNativeReceipt = ignoreReceipt, onReceiptPersisted = ignoreReceipt } = pendingMessage;
|
|
46
54
|
codexAppServerPendingUserMessages.set(deliveryKey, {
|
|
47
55
|
...pendingMessage,
|
|
56
|
+
onNativeReceipt,
|
|
57
|
+
onReceiptPersisted,
|
|
48
58
|
receipt: Promise.withResolvers()
|
|
49
59
|
});
|
|
50
60
|
}
|
|
@@ -72,36 +82,33 @@ export function createCodexAppServerMessageDelivery({
|
|
|
72
82
|
nativeIdentity = null,
|
|
73
83
|
data
|
|
74
84
|
) {
|
|
75
|
-
const normalizedSessionId =
|
|
76
|
-
const message =
|
|
85
|
+
const normalizedSessionId = normalizeText(sessionId);
|
|
86
|
+
const message = normalizeText(text);
|
|
77
87
|
if (
|
|
78
88
|
!normalizedSessionId ||
|
|
79
|
-
(!message && !(Array.isArray(attachments) && attachments.length))
|
|
80
|
-
typeof runtime?.store?.writeConversationUserMessage !== "function"
|
|
89
|
+
(!message && !(Array.isArray(attachments) && attachments.length))
|
|
81
90
|
) {
|
|
82
91
|
return null;
|
|
83
92
|
}
|
|
84
|
-
const pendingMessage = pendingUserMessage(normalizedSessionId,
|
|
93
|
+
const pendingMessage = pendingUserMessage(normalizedSessionId, normalizeText(messageId));
|
|
85
94
|
if (pendingMessage?.recording) {
|
|
86
95
|
return pendingMessage.recording;
|
|
87
96
|
}
|
|
88
97
|
const authored = pendingMessage?.authoredInput;
|
|
89
|
-
const applicationData = authored?.messageId ===
|
|
98
|
+
const applicationData = authored?.messageId === normalizeText(messageId) ? authored.data : data;
|
|
90
99
|
const recording = (async () => {
|
|
91
100
|
const written = await runtime.store.writeConversationUserMessage(normalizedSessionId, {
|
|
92
101
|
attachments,
|
|
93
102
|
nativeIdentity,
|
|
94
|
-
messageId:
|
|
103
|
+
messageId: normalizeText(messageId),
|
|
95
104
|
text: message,
|
|
96
105
|
...(applicationData !== undefined ? { data: structuredClone(applicationData) } : {}),
|
|
97
|
-
turnMetadata: messageMetadata.delivered
|
|
98
|
-
? await messageMetadata.delivered(runtime.store, normalizedSessionId, turnMetadata)
|
|
99
|
-
: turnMetadata
|
|
106
|
+
turnMetadata: await messageMetadata.delivered(runtime.store, normalizedSessionId, turnMetadata)
|
|
100
107
|
});
|
|
101
108
|
if (!written) {
|
|
102
109
|
return null;
|
|
103
110
|
}
|
|
104
|
-
pendingMessage?.onReceiptPersisted
|
|
111
|
+
pendingMessage?.onReceiptPersisted();
|
|
105
112
|
await publish(normalizedSessionId, {
|
|
106
113
|
payload: {
|
|
107
114
|
conversationLogPatch: {
|
|
@@ -120,16 +127,16 @@ export function createCodexAppServerMessageDelivery({
|
|
|
120
127
|
}
|
|
121
128
|
|
|
122
129
|
async function mirrorCodexAppServerTerminalUserMessage(sessionId = "", threadId = "", notification = {}) {
|
|
123
|
-
const normalizedSessionId =
|
|
124
|
-
const normalizedThreadId =
|
|
130
|
+
const normalizedSessionId = normalizeText(sessionId);
|
|
131
|
+
const normalizedThreadId = normalizeText(threadId);
|
|
125
132
|
const item = codexAppServerNotificationItem(notification);
|
|
126
133
|
const text = codexAppServerUserMessageText(item);
|
|
127
|
-
const clientId =
|
|
128
|
-
if (!normalizedSessionId || (!text && (!clientId ||
|
|
134
|
+
const clientId = normalizeText(item?.clientId);
|
|
135
|
+
if (!normalizedSessionId || (!text && (!clientId || normalizeText(item?.type) !== "userMessage"))) {
|
|
129
136
|
return;
|
|
130
137
|
}
|
|
131
138
|
const store = await createStore(normalizedSessionId);
|
|
132
|
-
const run = await
|
|
139
|
+
const run = await output.readAgentRunForSession(store, normalizedSessionId);
|
|
133
140
|
let ownership = codexAppServerPendingUserMessageOwnership(run, clientId);
|
|
134
141
|
if (!ownership && clientId && await store.conversationMessageIdExists(normalizedSessionId, clientId)) return;
|
|
135
142
|
const receiptId = ownership?.clientId || clientId;
|
|
@@ -149,7 +156,7 @@ export function createCodexAppServerMessageDelivery({
|
|
|
149
156
|
Array.isArray(recoveredMessage?.displayAttachments) && recoveredMessage.displayAttachments.length
|
|
150
157
|
))) return;
|
|
151
158
|
if (ownership) {
|
|
152
|
-
pendingMessage?.onNativeReceipt
|
|
159
|
+
pendingMessage?.onNativeReceipt();
|
|
153
160
|
// The provider's user-message receipt precedes its answer notifications.
|
|
154
161
|
// Persist the authored message here so answers cannot overtake it while
|
|
155
162
|
// the original HTTP request is still finishing startup bookkeeping.
|
|
@@ -159,7 +166,7 @@ export function createCodexAppServerMessageDelivery({
|
|
|
159
166
|
normalizedSessionId,
|
|
160
167
|
pendingMessage.text,
|
|
161
168
|
ownership.clientId,
|
|
162
|
-
{ ...await messageMetadata.actor
|
|
169
|
+
{ ...await messageMetadata.actor(pendingMessage.actorContext), ...pendingMessage.turnMetadata },
|
|
163
170
|
pendingMessage.attachments,
|
|
164
171
|
{ threadId: normalizedThreadId, turnId: codexAppServerNotificationTurnId(notification) }
|
|
165
172
|
);
|
|
@@ -173,18 +180,18 @@ export function createCodexAppServerMessageDelivery({
|
|
|
173
180
|
}
|
|
174
181
|
const turn = turnStateFromAgentRun(run || {});
|
|
175
182
|
const providerTurnId = codexAppServerNotificationTurnId(notification);
|
|
176
|
-
const providerTurnAlreadyTracked =
|
|
177
|
-
(!normalizedThreadId ||
|
|
178
|
-
(!providerTurnId ||
|
|
183
|
+
const providerTurnAlreadyTracked = normalizeText(turn.state) === "active" &&
|
|
184
|
+
(!normalizedThreadId || normalizeText(turn.threadId) === normalizedThreadId) &&
|
|
185
|
+
(!providerTurnId || normalizeText(turn.turnId) === providerTurnId);
|
|
179
186
|
if (!providerTurnAlreadyTracked) {
|
|
180
|
-
await
|
|
187
|
+
await recovery.markProviderTurnActive(normalizedSessionId, {
|
|
181
188
|
inputSource: ownership.inputSource,
|
|
182
189
|
status: "inProgress",
|
|
183
190
|
threadId: normalizedThreadId,
|
|
184
191
|
turnId: providerTurnId
|
|
185
192
|
});
|
|
186
193
|
}
|
|
187
|
-
await
|
|
194
|
+
await journal.writeUserMessageOwnership(
|
|
188
195
|
store,
|
|
189
196
|
normalizedSessionId,
|
|
190
197
|
ownership.clientId,
|
|
@@ -198,12 +205,12 @@ export function createCodexAppServerMessageDelivery({
|
|
|
198
205
|
}
|
|
199
206
|
return;
|
|
200
207
|
}
|
|
201
|
-
await
|
|
208
|
+
await recovery.markProviderTurnActive(normalizedSessionId, {
|
|
202
209
|
status: "inProgress",
|
|
203
210
|
threadId: normalizedThreadId,
|
|
204
211
|
turnId: codexAppServerNotificationTurnId(notification)
|
|
205
212
|
});
|
|
206
|
-
await
|
|
213
|
+
await output.writeMirroredTerminalMessage({
|
|
207
214
|
notification,
|
|
208
215
|
role: "user",
|
|
209
216
|
sessionId: normalizedSessionId,
|
|
@@ -212,12 +219,14 @@ export function createCodexAppServerMessageDelivery({
|
|
|
212
219
|
});
|
|
213
220
|
}
|
|
214
221
|
|
|
215
|
-
return {
|
|
222
|
+
return Object.freeze({
|
|
216
223
|
messageDeliveries: codexAppServerMessageDeliveries,
|
|
217
224
|
pendingUserMessages: codexAppServerPendingUserMessages,
|
|
218
225
|
pendingUserMessage,
|
|
219
226
|
withMessageDelivery: withCodexAppServerMessageDelivery,
|
|
220
227
|
writeDeliveredUserMessage: writeCodexAppServerDeliveredUserMessage,
|
|
221
228
|
mirrorTerminalUserMessage: mirrorCodexAppServerTerminalUserMessage
|
|
222
|
-
};
|
|
229
|
+
});
|
|
223
230
|
}
|
|
231
|
+
|
|
232
|
+
/** @typedef {ReturnType<typeof createCodexAppServerMessageDelivery>} CodexAppServerMessageDelivery */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { normalizeNullableText as normalizeAgentText } from "./normalize.js";
|
|
2
|
+
import { codexAppServerOwnedRuntimeKey, codexAppServerOwnedRuntimes, withRuntimeLifecycle } from "./codexRuntimeInventory.js";
|
|
2
3
|
|
|
3
4
|
// Bounded live model catalog, cached per provider connection generation.
|
|
4
5
|
export function codexAppServerModelCatalogError(message = "", errorPrefix = "") {
|
|
@@ -7,13 +8,9 @@ export function codexAppServerModelCatalogError(message = "", errorPrefix = "")
|
|
|
7
8
|
return error;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
: typeof provider?.connectionGeneration === "function"
|
|
14
|
-
? provider.connectionGeneration()
|
|
15
|
-
: provider?.connectionGeneration;
|
|
16
|
-
return normalizeAgentText(generation || "");
|
|
11
|
+
/** @param {import("./codexProvider.js").CodexAppServerAgentProvider} provider */
|
|
12
|
+
export function codexAppServerProviderConnectionGeneration(provider) {
|
|
13
|
+
return normalizeAgentText(provider.currentConnectionGeneration() || "");
|
|
17
14
|
}
|
|
18
15
|
|
|
19
16
|
function codexAppServerModelCatalogSnapshot(value = null, errorPrefix = "") {
|
|
@@ -39,6 +36,7 @@ export function createCodexAppServerModelCatalogCache({
|
|
|
39
36
|
} = {}) {
|
|
40
37
|
const codexAppServerModelCatalogs = new WeakMap();
|
|
41
38
|
return async function readCodexAppServerModelCatalog(provider, { signal = null } = {}) {
|
|
39
|
+
// readable-check: allow method-probe - safety invariant: a provider without live model discovery is refused with codex_model_catalog_unavailable
|
|
42
40
|
if (typeof provider.listModels !== "function") {
|
|
43
41
|
const error = new Error("Codex live model discovery is unavailable.");
|
|
44
42
|
error.code = `${errorPrefix}codex_model_catalog_unavailable`;
|
|
@@ -95,3 +93,84 @@ export function createCodexAppServerModelCatalogCache({
|
|
|
95
93
|
}
|
|
96
94
|
};
|
|
97
95
|
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* The chat model catalogue an owner reads from its native runtime, cached per runtime identity. A runtime it
|
|
99
|
+
* starts only for the read stops again.
|
|
100
|
+
* @param {object} dependencies
|
|
101
|
+
* @param {<T>(operation: () => T) => Promise<Awaited<T>>} dependencies.withLifecycle
|
|
102
|
+
* @param {() => void} dependencies.assertOpen
|
|
103
|
+
* @param {(request: { operation: () => Promise<object>, provider: object, providerOptions: object }) => Promise<object>} dependencies.acquireRuntime
|
|
104
|
+
* @param {(record: object) => Promise<object>} dependencies.stopOwnedRuntime
|
|
105
|
+
* @param {(provider: object) => void} dependencies.forgetOwnedRuntime
|
|
106
|
+
*/
|
|
107
|
+
export function createCodexRuntimeModelCatalog({ withLifecycle, assertOpen, acquireRuntime, stopOwnedRuntime, forgetOwnedRuntime }) {
|
|
108
|
+
let codexAppServerChatModelCatalog = null;
|
|
109
|
+
|
|
110
|
+
function readModelCatalog({
|
|
111
|
+
prepareProviderOptions,
|
|
112
|
+
providerFactory,
|
|
113
|
+
resources = null,
|
|
114
|
+
signal = null,
|
|
115
|
+
cacheMs = 30_000
|
|
116
|
+
} = {}) {
|
|
117
|
+
return withLifecycle(async () => {
|
|
118
|
+
assertOpen();
|
|
119
|
+
signal?.throwIfAborted();
|
|
120
|
+
const providerOptions = await prepareProviderOptions();
|
|
121
|
+
return withRuntimeLifecycle(codexAppServerOwnedRuntimeKey("", providerOptions), async () => {
|
|
122
|
+
const existing = codexAppServerOwnedRuntimes.get(
|
|
123
|
+
codexAppServerOwnedRuntimeKey("", providerOptions)
|
|
124
|
+
);
|
|
125
|
+
const provider = existing?.provider || providerFactory(providerOptions);
|
|
126
|
+
let runtime = null;
|
|
127
|
+
let catalog = null;
|
|
128
|
+
let identity = "";
|
|
129
|
+
try {
|
|
130
|
+
assertOpen();
|
|
131
|
+
identity = JSON.stringify(await provider.currentRuntimeInfo());
|
|
132
|
+
signal?.throwIfAborted();
|
|
133
|
+
if (codexAppServerChatModelCatalog?.identity === identity &&
|
|
134
|
+
codexAppServerChatModelCatalog.expiresAt > Date.now()) {
|
|
135
|
+
return codexAppServerChatModelCatalog.value;
|
|
136
|
+
}
|
|
137
|
+
if (!existing?.provider) {
|
|
138
|
+
runtime = await acquireRuntime({
|
|
139
|
+
operation: () => provider.ensureRuntime(),
|
|
140
|
+
provider,
|
|
141
|
+
providerOptions
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
catalog = await provider.listModels({ includeHidden: false, limit: 100 }, { signal });
|
|
145
|
+
} finally {
|
|
146
|
+
if (!existing?.provider) {
|
|
147
|
+
try {
|
|
148
|
+
if ((runtime || provider.runtime)?.reused === false) {
|
|
149
|
+
await stopOwnedRuntime({ provider, resources });
|
|
150
|
+
} else {
|
|
151
|
+
forgetOwnedRuntime(provider);
|
|
152
|
+
}
|
|
153
|
+
} finally {
|
|
154
|
+
provider.close();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
codexAppServerChatModelCatalog = {
|
|
159
|
+
expiresAt: Date.now() + cacheMs,
|
|
160
|
+
identity,
|
|
161
|
+
value: catalog
|
|
162
|
+
};
|
|
163
|
+
return catalog;
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function forgetModelCatalog() {
|
|
169
|
+
codexAppServerChatModelCatalog = null;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return Object.freeze({
|
|
173
|
+
read: readModelCatalog,
|
|
174
|
+
forget: forgetModelCatalog
|
|
175
|
+
});
|
|
176
|
+
}
|