@jskit-ai/assistant-core 0.2.6 → 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 +18 -12
- 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
|
@@ -11,7 +11,7 @@ function nonNegativeInteger(value) {
|
|
|
11
11
|
return Number.isSafeInteger(number) && number >= 0 ? number : null;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
function codexContextUsageFromNotification(notification
|
|
14
|
+
function codexContextUsageFromNotification(notification) {
|
|
15
15
|
if (normalizeNullableText(notification?.method) !== CODEX_TOKEN_USAGE_METHOD) {
|
|
16
16
|
return null;
|
|
17
17
|
}
|
|
@@ -104,7 +104,7 @@ function codexAppServerStatusFromValue(status = null) {
|
|
|
104
104
|
return type;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
function codexAppServerNotificationParams(notification
|
|
107
|
+
function codexAppServerNotificationParams(notification) {
|
|
108
108
|
return isRecord(notification?.params) ? notification.params : {};
|
|
109
109
|
}
|
|
110
110
|
|
|
@@ -604,74 +604,6 @@ function codexAppServerContextRefreshReason(notification = {}) {
|
|
|
604
604
|
return "";
|
|
605
605
|
}
|
|
606
606
|
|
|
607
|
-
// Like codexAppServerThreadRawValue, but provider results may also wrap the
|
|
608
|
-
// thread once more under `thread`, checked after raw and response.thread.
|
|
609
|
-
function codexAppServerProviderThread(value = {}) {
|
|
610
|
-
if (!isRecord(value?.raw) && !isRecord(value?.response?.thread) && isRecord(value?.thread)) {
|
|
611
|
-
return value.thread;
|
|
612
|
-
}
|
|
613
|
-
return codexAppServerThreadRawValue(value || {});
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
function codexAppServerProviderTurnId(turn = {}) {
|
|
617
|
-
return normalizeNullableText(turn.id || turn.turnId || turn.turn_id || turn.turn?.id || "");
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
function codexAppServerProviderTurnItems(turn = {}) {
|
|
621
|
-
return [
|
|
622
|
-
...(Array.isArray(turn.items) ? turn.items : []),
|
|
623
|
-
...(Array.isArray(turn.itemsView) ? turn.itemsView : [])
|
|
624
|
-
].filter(isRecord);
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
function codexAppServerProviderThreadTurn(value = {}, turnId = "") {
|
|
628
|
-
const normalizedTurnId = normalizeNullableText(turnId);
|
|
629
|
-
if (!normalizedTurnId) {
|
|
630
|
-
return null;
|
|
631
|
-
}
|
|
632
|
-
const thread = codexAppServerProviderThread(value);
|
|
633
|
-
return (Array.isArray(thread.turns) ? thread.turns : [])
|
|
634
|
-
.find((turn) => codexAppServerProviderTurnId(turn) === normalizedTurnId) || null;
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
function codexAppServerProviderTurnAssistantSegments(turn = {}) {
|
|
638
|
-
const seenItemIds = new Set();
|
|
639
|
-
const items = codexAppServerProviderTurnItems(turn);
|
|
640
|
-
// Providers without phases emit progress as ordinary assistant messages.
|
|
641
|
-
// Only the trailing response can be a final; reasoning/tools separate it
|
|
642
|
-
// from earlier updates. Explicit finals retain their native attribution.
|
|
643
|
-
let responseStart = items.length;
|
|
644
|
-
while (responseStart > 0 && codexAppServerAssistantItemText(items[responseStart - 1])) responseStart -= 1;
|
|
645
|
-
const active = ["inProgress", "starting"].includes(codexAppServerStatusFromValue(turn.status));
|
|
646
|
-
return items
|
|
647
|
-
.filter((item, index) => {
|
|
648
|
-
const phase = normalizeNullableText(item.phase);
|
|
649
|
-
return phase === "final_answer" || (!phase && !active && index >= responseStart);
|
|
650
|
-
})
|
|
651
|
-
.map((item) => {
|
|
652
|
-
const itemId = normalizeNullableText(item.id);
|
|
653
|
-
const text = codexAppServerAssistantItemText(item);
|
|
654
|
-
if (
|
|
655
|
-
!itemId ||
|
|
656
|
-
!text ||
|
|
657
|
-
seenItemIds.has(itemId)
|
|
658
|
-
) {
|
|
659
|
-
return null;
|
|
660
|
-
}
|
|
661
|
-
seenItemIds.add(itemId);
|
|
662
|
-
return {
|
|
663
|
-
itemId,
|
|
664
|
-
text
|
|
665
|
-
};
|
|
666
|
-
})
|
|
667
|
-
.filter(Boolean);
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
function codexAppServerProviderThreadAssistantSegments(value = {}, turnId = "") {
|
|
671
|
-
const turn = codexAppServerProviderThreadTurn(value, turnId);
|
|
672
|
-
return turn ? codexAppServerProviderTurnAssistantSegments(turn) : [];
|
|
673
|
-
}
|
|
674
|
-
|
|
675
607
|
function codexAppServerOutputOwnerTurnId({
|
|
676
608
|
notificationThreadId = "",
|
|
677
609
|
notificationTurnId = "",
|
|
@@ -693,139 +625,12 @@ function codexAppServerOutputOwnerTurnId({
|
|
|
693
625
|
: normalizeNullableText(notificationTurnId);
|
|
694
626
|
}
|
|
695
627
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
return thread.raw;
|
|
699
|
-
}
|
|
700
|
-
if (isRecord(thread.response?.thread)) {
|
|
701
|
-
return thread.response.thread;
|
|
702
|
-
}
|
|
703
|
-
return isRecord(thread) ? thread : {};
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
function codexAppServerThreadTurnId(thread = {}) {
|
|
707
|
-
const observedTurnId = normalizeNullableText(thread.observedTurn?.id || "");
|
|
708
|
-
if (observedTurnId) {
|
|
709
|
-
return observedTurnId;
|
|
710
|
-
}
|
|
711
|
-
const rawThread = codexAppServerThreadRawValue(thread);
|
|
712
|
-
const status = isRecord(rawThread.status) ? rawThread.status : {};
|
|
713
|
-
return normalizeNullableText(
|
|
714
|
-
thread.turnId ||
|
|
715
|
-
thread.turn_id ||
|
|
716
|
-
thread.turn?.id ||
|
|
717
|
-
rawThread.turnId ||
|
|
718
|
-
rawThread.turn_id ||
|
|
719
|
-
rawThread.turn?.id ||
|
|
720
|
-
rawThread.currentTurnId ||
|
|
721
|
-
rawThread.current_turn_id ||
|
|
722
|
-
rawThread.activeTurnId ||
|
|
723
|
-
rawThread.active_turn_id ||
|
|
724
|
-
status.turnId ||
|
|
725
|
-
status.turn_id ||
|
|
726
|
-
status.turn?.id ||
|
|
727
|
-
status.currentTurnId ||
|
|
728
|
-
status.current_turn_id ||
|
|
729
|
-
status.activeTurnId ||
|
|
730
|
-
status.active_turn_id ||
|
|
731
|
-
""
|
|
732
|
-
);
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
function codexAppServerThreadError(thread = {}) {
|
|
736
|
-
const rawThread = codexAppServerThreadRawValue(thread);
|
|
737
|
-
const status = isRecord(rawThread.status) ? rawThread.status : {};
|
|
738
|
-
return codexAppServerErrorText(rawThread.error || status.error);
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
function codexAppServerProviderThreadTurns(thread = null) {
|
|
742
|
-
const rawThread = codexAppServerThreadRawValue(thread || {});
|
|
743
|
-
return (Array.isArray(rawThread.turns) ? rawThread.turns : [])
|
|
744
|
-
.filter((turn) => isRecord(turn));
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
function codexAppServerProviderTurnStatus(turn = {}) {
|
|
748
|
-
return codexAppServerStatusFromValue(turn.status || turn.state);
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
function codexAppServerProviderTurnClientIds(turn = {}) {
|
|
752
|
-
return codexAppServerProviderTurnItems(turn)
|
|
753
|
-
.map((item) => normalizeNullableText(
|
|
754
|
-
item.clientId ||
|
|
755
|
-
item.client_id ||
|
|
756
|
-
item.clientUserMessageId ||
|
|
757
|
-
item.client_user_message_id ||
|
|
758
|
-
""
|
|
759
|
-
))
|
|
760
|
-
.filter(Boolean);
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
function codexAppServerProviderTurnForOperation(thread = null, {
|
|
764
|
-
clientMessageId = "",
|
|
765
|
-
turnId = ""
|
|
766
|
-
} = {}) {
|
|
767
|
-
const normalizedTurnId = normalizeNullableText(turnId || "");
|
|
768
|
-
const normalizedClientMessageId = normalizeNullableText(clientMessageId || "");
|
|
769
|
-
const turns = codexAppServerProviderThreadTurns(thread);
|
|
770
|
-
if (normalizedTurnId) {
|
|
771
|
-
return turns.find((turn) => (
|
|
772
|
-
codexAppServerProviderTurnId(turn) === normalizedTurnId
|
|
773
|
-
)) || null;
|
|
774
|
-
}
|
|
775
|
-
if (!normalizedClientMessageId) {
|
|
776
|
-
return null;
|
|
777
|
-
}
|
|
778
|
-
return [...turns].reverse().find((turn) => (
|
|
779
|
-
codexAppServerProviderTurnClientIds(turn).includes(normalizedClientMessageId)
|
|
780
|
-
)) || null;
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
// Native snapshot matching for renewal handover and seeding.
|
|
784
|
-
// The application projects these classifications into its approval/error policy.
|
|
785
|
-
function inspectCodexAppServerRenewalThread(thread = null, {
|
|
786
|
-
clientMessageId = "",
|
|
787
|
-
turnId: expectedTurnId = "",
|
|
788
|
-
requireFresh = false
|
|
789
|
-
} = {}) {
|
|
790
|
-
const snapshotTurns = codexAppServerProviderThreadTurns(thread);
|
|
791
|
-
const targetTurn = codexAppServerProviderTurnForOperation(thread, {
|
|
792
|
-
clientMessageId,
|
|
793
|
-
turnId: expectedTurnId
|
|
794
|
-
});
|
|
795
|
-
if (expectedTurnId && !targetTurn) return { targetTurn, failure: "turn_missing" };
|
|
796
|
-
if (!requireFresh && !targetTurn && snapshotTurns.length === 0) return { targetTurn, failure: "history_missing" };
|
|
797
|
-
if (requireFresh && snapshotTurns.some((turn) => (
|
|
798
|
-
!targetTurn || codexAppServerProviderTurnId(turn) !== codexAppServerProviderTurnId(targetTurn)
|
|
799
|
-
))) return { targetTurn, failure: "unrelated_history" };
|
|
800
|
-
return { targetTurn, failure: "" };
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
function codexAppServerProviderTurnText(thread = null, turnId = "") {
|
|
804
|
-
return codexAppServerProviderThreadAssistantSegments(thread || {}, turnId)
|
|
805
|
-
.map((segment) => segment.text)
|
|
806
|
-
.join("\n\n")
|
|
807
|
-
.trim();
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
function codexAppServerProviderTurnError(turn = {}) {
|
|
811
|
-
return codexAppServerSignedOutText(codexAppServerErrorText(turn.error || turn.status?.error || turn.state?.error));
|
|
812
|
-
}
|
|
628
|
+
// The `./server/codex-events` contract forwards this snapshot reader from here.
|
|
629
|
+
export { codexAppServerProviderThreadAssistantSegments } from "./codexThreadSnapshot.js";
|
|
813
630
|
|
|
814
631
|
export {
|
|
815
632
|
codexContextUsageFromNotification,
|
|
816
633
|
classifyCodexAppServerEvent,
|
|
817
|
-
codexAppServerThreadRawValue,
|
|
818
|
-
codexAppServerThreadTurnId,
|
|
819
|
-
codexAppServerThreadError,
|
|
820
|
-
codexAppServerProviderThreadTurns,
|
|
821
|
-
codexAppServerProviderTurnId,
|
|
822
|
-
codexAppServerProviderTurnStatus,
|
|
823
|
-
codexAppServerProviderTurnItems,
|
|
824
|
-
codexAppServerProviderTurnClientIds,
|
|
825
|
-
codexAppServerProviderTurnForOperation,
|
|
826
|
-
inspectCodexAppServerRenewalThread,
|
|
827
|
-
codexAppServerProviderTurnText,
|
|
828
|
-
codexAppServerProviderTurnError,
|
|
829
634
|
codexAppServerAgentMessageText,
|
|
830
635
|
codexAppServerAssistantItemText,
|
|
831
636
|
codexAppServerContentText,
|
|
@@ -842,8 +647,8 @@ export {
|
|
|
842
647
|
codexAppServerNotificationTurnId,
|
|
843
648
|
codexAppServerNotificationTurnStatus,
|
|
844
649
|
codexAppServerNotificationUsageLimitExceeded,
|
|
845
|
-
codexAppServerProviderThreadAssistantSegments,
|
|
846
650
|
codexAppServerOutputOwnerTurnId,
|
|
651
|
+
codexAppServerSignedOutText,
|
|
847
652
|
codexAppServerStatusFromValue,
|
|
848
653
|
codexAppServerUserMessageText
|
|
849
654
|
};
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { CODEX_APP_SERVER_AGENT_RUN_ID } from "./codexTurnState.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* The run owner's native goal commands: preparing a goal's context, validating its input and updating it.
|
|
5
|
+
* @param {object} dependencies
|
|
6
|
+
* @param {import("./codexConversations.js").CodexConversationCommands["codexAppServerConversationContext"]} dependencies.conversationContext
|
|
7
|
+
* @param {import("./codexThreadReadiness.js").CodexThreadReadiness["ensureThreadReady"]} dependencies.ensureThreadReady
|
|
8
|
+
* @param {import("./codexTurn.js").CodexPublish} dependencies.publish
|
|
9
|
+
* @param {import("./codexOutput.js").CodexAppServerOutput["readAgentRunForSession"]} dependencies.readCodexAppServerAgentRunForSession
|
|
10
|
+
* @param {import("./codexNotificationObserver.js").CodexNotificationObserver["reconcileGoalUpdated"]} dependencies.reconcileCodexAppServerGoalUpdated
|
|
11
|
+
* @param {import("./codexOutput.js").CodexAppServerOutput["submitAssistantResult"]} dependencies.submitCodexAppServerAssistantResult
|
|
12
|
+
* @param {import("./codexNotificationObserver.js").CodexNotificationObserver["subscribeEvents"]} dependencies.subscribeCodexAppServerEvents
|
|
13
|
+
* @param {import("./codexTurn.js").CodexTurnStateReader} dependencies.turnState
|
|
14
|
+
*/
|
|
4
15
|
export function createCodexGoalCommands({
|
|
5
16
|
conversationContext,
|
|
6
17
|
ensureThreadReady,
|
|
@@ -120,10 +131,9 @@ export function createCodexGoalCommands({
|
|
|
120
131
|
return { ok: true, status: "available", threadId, goal: result.goal || null };
|
|
121
132
|
}
|
|
122
133
|
|
|
123
|
-
|
|
124
|
-
return {
|
|
134
|
+
return Object.freeze({
|
|
125
135
|
prepareCodexAppServerGoalContext,
|
|
126
136
|
validateCodexAppServerGoalInput,
|
|
127
137
|
updateCodexAppServerGoal
|
|
128
|
-
};
|
|
138
|
+
});
|
|
129
139
|
}
|
|
@@ -1,34 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { AppError } from "@jskit-ai/kernel/server/runtime/errors";
|
|
2
|
+
import { codexAppServerDeliveredTurn } from "./codexProviderTurns.js";
|
|
3
|
+
import { deleteCodexAppServerThread } from "./codexProviderThreads.js";
|
|
4
|
+
import { CODEX_HELPER_THREAD_LIFECYCLES } from "./codexHelperThreadRecord.js";
|
|
5
|
+
import { codexAppServerErrorMessage as errorMessage } from "./codexTurnState.js";
|
|
6
|
+
import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
4
7
|
|
|
5
8
|
export function createCodexHelperOwnershipError({ applicationName = "Application", errorPrefix = "" } = {}) {
|
|
6
9
|
return function codexAppServerHelperOwnershipError(message = "", details = {}) {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
`${applicationName} could not prove ownership of a persisted low-cost assistant thread
|
|
10
|
+
const retryable = details.retryable !== false;
|
|
11
|
+
const error = new AppError(409,
|
|
12
|
+
normalizeText(message) || `${applicationName} could not prove ownership of a persisted low-cost assistant thread.`,
|
|
13
|
+
{
|
|
14
|
+
code: `${errorPrefix}codex_helper_ownership_blocked`,
|
|
15
|
+
details: { ...details, retryable },
|
|
16
|
+
...(normalizeText(message) ? {} : { messageCode: "assistant.codex.helperOwnershipBlocked", messageParams: { applicationName } })
|
|
17
|
+
}
|
|
10
18
|
);
|
|
11
|
-
error.
|
|
12
|
-
error.statusCode = 409;
|
|
13
|
-
if (!normalizeText(message)) {
|
|
14
|
-
error.messageCode = "assistant.codex.helperOwnershipBlocked";
|
|
15
|
-
error.messageParams = { applicationName };
|
|
16
|
-
}
|
|
17
|
-
error.retryable = details.retryable !== false;
|
|
18
|
-
error.details = {
|
|
19
|
-
...details,
|
|
20
|
-
retryable: error.retryable
|
|
21
|
-
};
|
|
19
|
+
error.retryable = retryable;
|
|
22
20
|
return error;
|
|
23
21
|
};
|
|
24
22
|
}
|
|
25
23
|
|
|
24
|
+
/**
|
|
25
|
+
* @param {import("./codexProvider.js").CodexAppServerAgentProvider} provider
|
|
26
|
+
* @param {ReturnType<typeof createCodexHelperOwnershipError>} codexAppServerHelperOwnershipError
|
|
27
|
+
*/
|
|
26
28
|
export async function readCodexAppServerAccountIdentity(provider, codexAppServerHelperOwnershipError) {
|
|
27
|
-
if (typeof provider.currentRuntimeInfo !== "function") {
|
|
28
|
-
throw codexAppServerHelperOwnershipError(
|
|
29
|
-
"The Codex provider cannot identify the selected account."
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
29
|
const runtimeInfo = await provider.currentRuntimeInfo();
|
|
33
30
|
const accountIdentitySignature = normalizeText(runtimeInfo?.accountIdentitySignature);
|
|
34
31
|
if (!/^sha256:[a-f0-9]{64}$/u.test(accountIdentitySignature)) {
|
|
@@ -39,12 +36,17 @@ export async function readCodexAppServerAccountIdentity(provider, codexAppServer
|
|
|
39
36
|
return accountIdentitySignature;
|
|
40
37
|
}
|
|
41
38
|
|
|
39
|
+
/**
|
|
40
|
+
* @param {import("./codexProvider.js").CodexAppServerAgentProvider | null} provider
|
|
41
|
+
* @param {string} expectedSignature
|
|
42
|
+
* @param {ReturnType<typeof createCodexHelperOwnershipError>} codexAppServerHelperOwnershipError
|
|
43
|
+
*/
|
|
42
44
|
export async function assertCodexAppServerHelperAccountIdentity(provider, expectedSignature = "", codexAppServerHelperOwnershipError) {
|
|
43
45
|
const expected = normalizeText(expectedSignature);
|
|
44
46
|
if (!expected) {
|
|
45
47
|
return;
|
|
46
48
|
}
|
|
47
|
-
if (!/^sha256:[a-f0-9]{64}$/u.test(expected) ||
|
|
49
|
+
if (!/^sha256:[a-f0-9]{64}$/u.test(expected) || !provider) {
|
|
48
50
|
throw codexAppServerHelperOwnershipError(
|
|
49
51
|
"The requested low-cost assistant account identity is invalid. Refresh the task and retry."
|
|
50
52
|
);
|
|
@@ -65,25 +67,18 @@ export async function sendPreparedCodexAppServerHelperTurn(provider, prepared, h
|
|
|
65
67
|
prepared.input,
|
|
66
68
|
prepared.turnSettings((await helperIsolation.executionContext(provider)).cwd)
|
|
67
69
|
);
|
|
68
|
-
return Object.freeze({
|
|
70
|
+
return Object.freeze({
|
|
71
|
+
executionProfile: prepared.executionProfile,
|
|
72
|
+
input: prepared.input,
|
|
73
|
+
turn
|
|
74
|
+
});
|
|
69
75
|
}
|
|
70
76
|
|
|
71
|
-
// One invocation
|
|
72
|
-
//
|
|
77
|
+
// One invocation holds its own mutable record; the shared owner holds all
|
|
78
|
+
// durable state, locks and cross-operation coordination.
|
|
73
79
|
export async function prepareDetachedCodexHelperThread(owner, scope, preparation, {
|
|
74
80
|
applicationName = "Application"
|
|
75
81
|
} = {}) {
|
|
76
|
-
const {
|
|
77
|
-
withProjectOperation: withCodexAppServerHelperProjectOperation,
|
|
78
|
-
remember: rememberCodexAppServerHelperThread,
|
|
79
|
-
update: updateCodexAppServerHelperThread,
|
|
80
|
-
remove: removeCodexAppServerHelperThread,
|
|
81
|
-
retire: retireCodexAppServerHelperThread,
|
|
82
|
-
ownershipError: codexAppServerHelperOwnershipError,
|
|
83
|
-
cleanupError: codexAppServerHelperThreadCleanupError,
|
|
84
|
-
key: codexAppServerHelperThreadKey,
|
|
85
|
-
turnStarts: codexAppServerHelperTurnStarts
|
|
86
|
-
} = owner;
|
|
87
82
|
const {
|
|
88
83
|
executionProfile, onRetired, projectRuntimeRoot, provider, sessionId,
|
|
89
84
|
requestedThreadId, workdir
|
|
@@ -100,7 +95,7 @@ export async function prepareDetachedCodexHelperThread(owner, scope, preparation
|
|
|
100
95
|
sessionId = "",
|
|
101
96
|
workdir = ""
|
|
102
97
|
} = {}) {
|
|
103
|
-
return
|
|
98
|
+
return owner.withProjectOperation(projectRuntimeRoot, async () => {
|
|
104
99
|
const projectContextRoot = normalizeText(scope.projectContextRoot);
|
|
105
100
|
let thread = null;
|
|
106
101
|
try {
|
|
@@ -116,7 +111,7 @@ export async function prepareDetachedCodexHelperThread(owner, scope, preparation
|
|
|
116
111
|
error?.codexAppServerHelperThreadCleanupRequired === true &&
|
|
117
112
|
failedThreadId
|
|
118
113
|
) {
|
|
119
|
-
await
|
|
114
|
+
await owner.remember({
|
|
120
115
|
executionProfile,
|
|
121
116
|
lifecycle: CODEX_HELPER_THREAD_LIFECYCLES.CLEANUP_REQUIRED,
|
|
122
117
|
projectContextRoot,
|
|
@@ -134,7 +129,7 @@ export async function prepareDetachedCodexHelperThread(owner, scope, preparation
|
|
|
134
129
|
throw new Error("Codex app-server did not return a helper thread id.");
|
|
135
130
|
}
|
|
136
131
|
try {
|
|
137
|
-
const record = await
|
|
132
|
+
const record = await owner.remember({
|
|
138
133
|
executionProfile,
|
|
139
134
|
lifecycle: CODEX_HELPER_THREAD_LIFECYCLES.STARTING_TURN,
|
|
140
135
|
onRetired,
|
|
@@ -150,7 +145,7 @@ export async function prepareDetachedCodexHelperThread(owner, scope, preparation
|
|
|
150
145
|
try {
|
|
151
146
|
await deleteCodexAppServerThread({ provider, threadId });
|
|
152
147
|
} catch (cleanupError) {
|
|
153
|
-
const failure =
|
|
148
|
+
const failure = owner.ownershipError(
|
|
154
149
|
`${applicationName} could not persist or retire a newly created low-cost assistant thread.`,
|
|
155
150
|
{
|
|
156
151
|
cleanupError: errorMessage(cleanupError),
|
|
@@ -169,7 +164,7 @@ export async function prepareDetachedCodexHelperThread(owner, scope, preparation
|
|
|
169
164
|
|
|
170
165
|
if (requestedThreadId) {
|
|
171
166
|
try {
|
|
172
|
-
helperThreadRecord = await
|
|
167
|
+
helperThreadRecord = await owner.update(
|
|
173
168
|
helperThreadRecord,
|
|
174
169
|
{
|
|
175
170
|
lifecycle: CODEX_HELPER_THREAD_LIFECYCLES.STARTING_TURN,
|
|
@@ -186,30 +181,30 @@ export async function prepareDetachedCodexHelperThread(owner, scope, preparation
|
|
|
186
181
|
} catch (error) {
|
|
187
182
|
if (error?.codexAppServerHelperThreadRetired === true) {
|
|
188
183
|
try {
|
|
189
|
-
await
|
|
184
|
+
await owner.remove(helperThreadRecord);
|
|
190
185
|
} catch (ledgerError) {
|
|
191
|
-
throw
|
|
186
|
+
throw owner.cleanupError(
|
|
192
187
|
helperThreadRecord,
|
|
193
188
|
ledgerError
|
|
194
189
|
);
|
|
195
190
|
}
|
|
196
191
|
} else if (error?.codexAppServerHelperThreadCleanupRequired === true) {
|
|
197
192
|
try {
|
|
198
|
-
helperThreadRecord = await
|
|
193
|
+
helperThreadRecord = await owner.update(
|
|
199
194
|
helperThreadRecord,
|
|
200
195
|
{
|
|
201
196
|
lifecycle: CODEX_HELPER_THREAD_LIFECYCLES.CLEANUP_REQUIRED
|
|
202
197
|
}
|
|
203
198
|
);
|
|
204
199
|
} catch (ledgerError) {
|
|
205
|
-
throw
|
|
200
|
+
throw owner.cleanupError(
|
|
206
201
|
helperThreadRecord,
|
|
207
202
|
ledgerError
|
|
208
203
|
);
|
|
209
204
|
}
|
|
210
205
|
} else {
|
|
211
206
|
try {
|
|
212
|
-
await
|
|
207
|
+
await owner.retire(helperThreadRecord);
|
|
213
208
|
} catch (cleanupError) {
|
|
214
209
|
cleanupError.cause = error;
|
|
215
210
|
throw cleanupError;
|
|
@@ -236,7 +231,7 @@ export async function prepareDetachedCodexHelperThread(owner, scope, preparation
|
|
|
236
231
|
if (!helperThreadRecord) {
|
|
237
232
|
return;
|
|
238
233
|
}
|
|
239
|
-
await
|
|
234
|
+
await owner.retire(helperThreadRecord);
|
|
240
235
|
};
|
|
241
236
|
|
|
242
237
|
async function dispatch(threadId, failDispatch) {
|
|
@@ -245,13 +240,13 @@ export async function prepareDetachedCodexHelperThread(owner, scope, preparation
|
|
|
245
240
|
let status = "";
|
|
246
241
|
let helperTurnStart = null;
|
|
247
242
|
try {
|
|
248
|
-
const helperThreadKey =
|
|
243
|
+
const helperThreadKey = owner.key(helperThreadRecord);
|
|
249
244
|
helperTurnStart = (async () => {
|
|
250
245
|
const currentDelivery = await sendPreparedCodexAppServerHelperTurn(
|
|
251
246
|
provider, preparation.turn(threadId), preparation.isolation
|
|
252
247
|
);
|
|
253
248
|
const { turnId: currentTurnId, status: currentStatus } = codexAppServerDeliveredTurn(currentDelivery);
|
|
254
|
-
helperThreadRecord = await
|
|
249
|
+
helperThreadRecord = await owner.update(
|
|
255
250
|
helperThreadRecord,
|
|
256
251
|
{
|
|
257
252
|
lifecycle: CODEX_HELPER_THREAD_LIFECYCLES.ACTIVE,
|
|
@@ -264,15 +259,15 @@ export async function prepareDetachedCodexHelperThread(owner, scope, preparation
|
|
|
264
259
|
turnId: currentTurnId
|
|
265
260
|
};
|
|
266
261
|
})();
|
|
267
|
-
|
|
262
|
+
owner.turnStarts.set(helperThreadKey, helperTurnStart);
|
|
268
263
|
({ delivery, status, turnId } = await helperTurnStart);
|
|
269
264
|
} catch (error) {
|
|
270
265
|
await failDispatch(error);
|
|
271
266
|
} finally {
|
|
272
267
|
if (helperTurnStart) {
|
|
273
|
-
const helperThreadKey =
|
|
274
|
-
if (
|
|
275
|
-
|
|
268
|
+
const helperThreadKey = owner.key(helperThreadRecord);
|
|
269
|
+
if (owner.turnStarts.get(helperThreadKey) === helperTurnStart) {
|
|
270
|
+
owner.turnStarts.delete(helperThreadKey);
|
|
276
271
|
}
|
|
277
272
|
}
|
|
278
273
|
}
|
|
@@ -281,13 +276,13 @@ export async function prepareDetachedCodexHelperThread(owner, scope, preparation
|
|
|
281
276
|
|
|
282
277
|
async function complete() {
|
|
283
278
|
try {
|
|
284
|
-
helperThreadRecord = await
|
|
279
|
+
helperThreadRecord = await owner.update(helperThreadRecord, {
|
|
285
280
|
lifecycle: CODEX_HELPER_THREAD_LIFECYCLES.READY,
|
|
286
281
|
turnId: ""
|
|
287
282
|
});
|
|
288
283
|
} catch (error) {
|
|
289
284
|
try {
|
|
290
|
-
await
|
|
285
|
+
await owner.retire(helperThreadRecord);
|
|
291
286
|
} catch (cleanupError) {
|
|
292
287
|
cleanupError.cause = error;
|
|
293
288
|
throw cleanupError;
|
|
@@ -296,5 +291,10 @@ export async function prepareDetachedCodexHelperThread(owner, scope, preparation
|
|
|
296
291
|
}
|
|
297
292
|
}
|
|
298
293
|
|
|
299
|
-
return Object.freeze({
|
|
294
|
+
return Object.freeze({
|
|
295
|
+
thread,
|
|
296
|
+
dispatch,
|
|
297
|
+
discard: discardHelperThread,
|
|
298
|
+
complete
|
|
299
|
+
});
|
|
300
300
|
}
|