@jskit-ai/assistant-core 0.1.199 → 0.1.201
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/README.md +8 -1
- package/examples/conversation/package.json +5 -5
- package/fixtures/responsive-assistant/App.vue +4 -1
- package/package.json +99 -36
- package/src/client/conversation/AssistantConversationElement.vue +27 -4
- package/src/client/conversation/AssistantConversationStatus.vue +24 -0
- package/src/client/conversation/AssistantGoalControl.vue +8 -5
- package/src/client/conversation/AssistantTranscript.vue +10 -3
- package/src/client/conversation/index.js +2 -0
- package/src/client/conversation/messageDelivery.js +115 -32
- package/src/client/conversation/retainedConversation.js +32 -0
- package/src/client/conversation/useAssistantQuestions.js +76 -0
- package/src/client/lib/assistantApi.js +72 -2
- package/src/server/conversation/agentRun.js +222 -0
- package/src/server/conversation/attachments.js +93 -0
- package/src/server/conversation/claudeClient.js +221 -0
- package/src/server/conversation/claudeHistory.js +256 -0
- package/src/server/conversation/claudeProcess.js +327 -0
- package/src/server/conversation/claudeTools.js +42 -0
- package/src/server/conversation/claudeTurn.js +1082 -0
- package/src/server/conversation/codexConfiguration.js +1183 -0
- package/src/server/conversation/codexConversations.js +1082 -0
- package/src/server/conversation/codexDetachedTurn.js +332 -0
- package/src/server/conversation/codexEvents.js +194 -1
- package/src/server/conversation/codexGoalCommands.js +124 -0
- package/src/server/conversation/codexHelperExecution.js +306 -0
- package/src/server/conversation/codexHelperThreadLedger.js +804 -0
- package/src/server/conversation/codexHelperThreadRecovery.js +395 -0
- package/src/server/conversation/codexHelperThreads.js +638 -0
- package/src/server/conversation/codexHistoryAdapter.js +369 -0
- package/src/server/conversation/codexMessageCommands.js +663 -0
- package/src/server/conversation/codexMessageDelivery.js +211 -0
- package/src/server/conversation/codexNativeHistoryExport.js +95 -0
- package/src/server/conversation/codexNotificationObserver.js +482 -0
- package/src/server/conversation/codexNotificationQueue.js +103 -0
- package/src/server/conversation/codexObservationControl.js +174 -0
- package/src/server/conversation/codexOutput.js +931 -0
- package/src/server/conversation/codexProcess.js +1559 -0
- package/src/server/conversation/codexProcessLeader.js +14 -0
- package/src/server/conversation/codexProvider.js +2710 -0
- package/src/server/conversation/codexProviderOwner.js +1058 -0
- package/src/server/conversation/codexProviderSelection.js +218 -0
- package/src/server/conversation/codexReasoning.js +314 -0
- package/src/server/conversation/codexRenewalCommands.js +290 -0
- package/src/server/conversation/codexResultSettlement.js +409 -0
- package/src/server/conversation/codexRunJournal.js +658 -0
- package/src/server/conversation/codexRuntimeLifecycle.js +288 -0
- package/src/server/conversation/codexSessionCleanup.js +96 -0
- package/src/server/conversation/codexSessionReconciliation.js +284 -0
- package/src/server/conversation/codexThreadReadiness.js +397 -0
- package/src/server/conversation/codexThreadStatus.js +354 -0
- package/src/server/conversation/codexTurn.js +701 -255
- package/src/server/conversation/codexTurnControl.js +317 -0
- package/src/server/conversation/codexTurnRecovery.js +990 -0
- package/src/server/conversation/codexTurnState.js +549 -0
- package/src/server/conversation/commandHook.js +18 -0
- package/src/server/conversation/commandWrapper.js +37 -0
- package/src/server/conversation/configuration.js +43 -0
- package/src/server/conversation/continuity.js +289 -0
- package/src/server/conversation/fileStorage.js +55 -0
- package/src/server/conversation/hookBridge.js +19 -0
- package/src/server/conversation/index.js +13 -0
- package/src/server/conversation/localExecution.js +665 -0
- package/src/server/conversation/memoryStorage.js +7 -72
- package/src/server/conversation/nativeHistoryExport.js +90 -0
- package/src/server/conversation/nativeStorage.js +23 -0
- package/src/server/conversation/openCodeClient.js +209 -19
- package/src/server/conversation/openCodePlugin.js +84 -0
- package/src/server/conversation/openCodeProcess.js +476 -0
- package/src/server/conversation/openCodeRuntime.js +1578 -0
- package/src/server/conversation/openCodeTools.js +60 -0
- package/src/server/conversation/openCodeTurn.js +557 -0
- package/src/server/conversation/provider.js +30 -0
- package/src/server/conversation/providers/api.js +136 -0
- package/src/server/conversation/providers/claude.js +63 -0
- package/src/server/conversation/providers/claudeDriver.js +425 -0
- package/src/server/conversation/providers/codex.js +248 -0
- package/src/server/conversation/providers/codexDriver.js +1078 -0
- package/src/server/conversation/providers/opencode.js +49 -0
- package/src/server/conversation/providers/opencodeDriver.js +650 -0
- package/src/server/conversation/providers/scoped.js +312 -0
- package/src/server/conversation/runtime.js +2220 -0
- package/src/server/conversation/runtimeStateUpgrade.js +125 -0
- package/src/server/conversation/storage.js +184 -0
- package/src/server/conversation/streams.js +7 -2
- package/src/server/conversation/structuredOutput.js +240 -0
- package/src/server/conversation/systemPrompt.js +54 -0
- package/src/server/conversation/tools.js +84 -0
- package/src/server/conversation/transcript.js +5 -4
- package/src/server/hosts/claudeHistory.js +5 -0
- package/src/server/hosts/claudeProcess.js +11 -0
- package/src/server/hosts/claudeTurn.js +4 -0
- package/src/server/hosts/codexConfiguration.js +20 -0
- package/src/server/hosts/codexEvents.js +13 -0
- package/src/server/hosts/codexProcess.js +12 -0
- package/src/server/hosts/codexProvider.js +23 -0
- package/src/server/hosts/codexTurn.js +20 -0
- package/src/server/hosts/nativeHistory.js +3 -0
- package/src/server/hosts/openCodeClient.js +3 -0
- package/src/server/hosts/openCodeProcess.js +23 -0
- package/src/server/hosts/openCodeTurn.js +7 -0
- package/src/server/index.js +2 -0
- package/src/server/lib/aiConnectionClient.js +13 -6
- package/src/server/lib/assistantCompletion.js +190 -0
- package/src/server/lib/assistantToolLoop.js +314 -0
- package/src/server/lib/serviceToolCatalog.js +25 -10
- package/src/shared/assistantResponseText.js +29 -0
- package/src/shared/conversation/attachments.js +19 -0
- package/src/shared/conversation/index.js +3 -0
- package/src/shared/conversation/pagination.js +78 -0
- package/src/shared/conversation/patches.js +150 -0
- package/src/shared/conversation/questions.js +48 -0
- package/src/shared/conversation/streaming.js +7 -4
- package/src/shared/index.js +2 -0
- package/src/shared/nativeProviders.js +45 -0
- package/src/testing/conversationStorageContract.js +31 -1
- package/src/testing/nativeCodex.js +11 -0
- package/src/testing/nativeOpenCode.js +3 -0
- package/test/aiConnectionClient.test.js +2 -0
- package/test/apiConversationDriver.test.js +73 -0
- package/test/assistantApiSurfaceHeader.test.js +85 -0
- package/test/assistantBoundedToolLoop.test.js +285 -0
- package/test/assistantScroll.browser.test.js +16 -0
- package/test/claudeClient.test.js +189 -0
- package/test/claudeConversationSession.test.js +1173 -0
- package/test/claudeInstructionResume.test.js +82 -0
- package/test/claudeProcess.test.js +204 -0
- package/test/claudeTurn.test.js +253 -0
- package/test/codexConversationSession.test.js +2122 -0
- package/test/codexGoal.test.js +37 -0
- package/test/codexHelperDeletion.test.js +163 -0
- package/test/codexHelperThreadLedger.test.js +494 -0
- package/test/codexHistoryAdapter.test.js +541 -0
- package/test/codexInteractiveArguments.test.js +30 -0
- package/test/codexIsolation.test.js +756 -0
- package/test/codexModelCatalog.test.js +362 -0
- package/test/codexNativeHistoryExport.test.js +81 -0
- package/test/codexThreadSelection.test.js +136 -0
- package/test/codexTurn.test.js +2158 -0
- package/test/conversation.test.js +110 -0
- package/test/conversationAgentRun.test.js +326 -0
- package/test/conversationApiFacilities.test.js +90 -0
- package/test/conversationAttachments.test.js +238 -0
- package/test/conversationCommandWrapper.test.js +48 -0
- package/test/conversationConfiguration.test.js +174 -0
- package/test/conversationNativeStorage.test.js +25 -0
- package/test/conversationReplacement.test.js +172 -0
- package/test/conversationRuntime.test.js +241 -0
- package/test/conversationRuntimeStateUpgrade.test.js +144 -0
- package/test/conversationSession.test.js +1080 -0
- package/test/conversationStreaming.test.js +68 -0
- package/test/conversationSystemPrompt.test.js +84 -0
- package/test/conversationTools.test.js +416 -0
- package/test/fileConversationStorage.test.js +73 -0
- package/test/fixtures/codexHelperThreadLedger.js +39 -0
- package/test/localConversationExecution.test.js +90 -0
- package/test/messageDelivery.test.js +234 -1
- package/test/nativeConversationRetirement.test.js +215 -0
- package/test/openCodeClient.test.js +515 -0
- package/test/openCodeProcess.test.js +177 -0
- package/test/openCodeRuntime.test.js +322 -0
- package/test/openCodeTools.test.js +287 -0
- package/test/opencodeConversationSession.test.js +789 -0
- package/test/serviceToolCatalog.test.js +24 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import {
|
|
2
|
+
codexAppServerTurnStatusIsSuccessfulComplete,
|
|
3
|
+
codexAppServerThreadStatus,
|
|
4
|
+
codexAppServerAgentRun,
|
|
5
|
+
codexAppServerTurnOwnsActiveGoal,
|
|
6
|
+
codexAppServerConversationTurnIsActive,
|
|
7
|
+
CODEX_APP_SERVER_AGENT_RUN_ID,
|
|
8
|
+
CODEX_APP_SERVER_RUN_STATE
|
|
9
|
+
} from "./codexTurnState.js";
|
|
10
|
+
|
|
11
|
+
// Original observation-loss barriers, stop settlement and saved-stop inspection.
|
|
12
|
+
// The shared conversation registry and journal remain their existing owners.
|
|
13
|
+
export function createCodexObservationControl({
|
|
14
|
+
conversations,
|
|
15
|
+
output,
|
|
16
|
+
journal,
|
|
17
|
+
namespace,
|
|
18
|
+
createRuntime,
|
|
19
|
+
publish,
|
|
20
|
+
runInContext,
|
|
21
|
+
turnState,
|
|
22
|
+
errorPrefix
|
|
23
|
+
}) {
|
|
24
|
+
const { codexAppServerConversations } = conversations;
|
|
25
|
+
const { readAgentRunForSession: readCodexAppServerAgentRunForSession } = output;
|
|
26
|
+
const {
|
|
27
|
+
agentRunRealtimePayload: codexAppServerAgentRunRealtimePayload,
|
|
28
|
+
clearActiveTimer: clearCodexAppServerActiveTimer
|
|
29
|
+
} = journal;
|
|
30
|
+
|
|
31
|
+
function assertCodexAppServerThreadCanResume(run, threadId) {
|
|
32
|
+
if (run?.providerThreadId === threadId && run.providerStatus === "observation_lost") {
|
|
33
|
+
throw Object.assign(new Error(run.error || "Codex is stopped. Use Resume or Send to continue."), {
|
|
34
|
+
code: `${errorPrefix}codex_observation_lost`
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function createCodexAppServerObservation(sessionId, context = {}) {
|
|
40
|
+
const { projectContext, target, retireProvider } = context;
|
|
41
|
+
return {
|
|
42
|
+
prepare({ provider, error }) {
|
|
43
|
+
return runInContext(projectContext, async () => {
|
|
44
|
+
const managed = target(error);
|
|
45
|
+
const threads = new Map();
|
|
46
|
+
for (const entry of codexAppServerConversations.get(namespace(sessionId))?.values() || []) {
|
|
47
|
+
if (entry.provider !== provider) continue;
|
|
48
|
+
threads.set(entry.conversationId, entry.runId);
|
|
49
|
+
if (codexAppServerConversationTurnIsActive(entry.status) || entry.goal?.status === "active") {
|
|
50
|
+
entry.error = managed.pendingMessage;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// A helper owns only its own threads. Main chat belongs to its managed provider.
|
|
54
|
+
if (managed.threadId) {
|
|
55
|
+
const runtime = await createRuntime();
|
|
56
|
+
const turn = turnState(await runtime.getSession(sessionId));
|
|
57
|
+
threads.set(managed.threadId, turn.turnId);
|
|
58
|
+
if (turn.active || codexAppServerTurnOwnsActiveGoal(turn, managed.threadId)) {
|
|
59
|
+
await runtime.store.writeAgentRunEvent(sessionId, CODEX_APP_SERVER_AGENT_RUN_ID, {
|
|
60
|
+
event: { kind: "observation-lost", message: error.message },
|
|
61
|
+
patch: { providerStatus: "observation_lost", error: managed.pendingMessage }
|
|
62
|
+
});
|
|
63
|
+
await publish(sessionId, { reason: "codex-observation-lost" });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return threads;
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
barrier({ error }) {
|
|
70
|
+
return runInContext(projectContext, async () => {
|
|
71
|
+
const managed = target(error);
|
|
72
|
+
if (!managed.threadId) return;
|
|
73
|
+
const runtime = await createRuntime();
|
|
74
|
+
const turn = turnState(await runtime.getSession(sessionId));
|
|
75
|
+
if (!turn.active && !codexAppServerTurnOwnsActiveGoal(turn, managed.threadId)) return;
|
|
76
|
+
await runtime.store.writeAgentRunEvent(sessionId, CODEX_APP_SERVER_AGENT_RUN_ID, {
|
|
77
|
+
event: { kind: "observation-lost", message: error.message },
|
|
78
|
+
patch: { providerStatus: "observation_lost", error: managed.pendingMessage }
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
},
|
|
82
|
+
complete({ provider, error, sharedStop }) {
|
|
83
|
+
return runInContext(projectContext, async () => {
|
|
84
|
+
const managed = target(error);
|
|
85
|
+
let stoppedRun = null;
|
|
86
|
+
let conversationStream = null;
|
|
87
|
+
if (managed.threadId) {
|
|
88
|
+
const runtime = await createRuntime();
|
|
89
|
+
stoppedRun = await runtime.store.mutateSession(sessionId, async () => {
|
|
90
|
+
const run = await readCodexAppServerAgentRunForSession(runtime.store, sessionId);
|
|
91
|
+
if (run?.providerThreadId !== managed.threadId || run.providerStatus !== "observation_lost") return null;
|
|
92
|
+
const stopped = await runtime.store.writeAgentRunEvent(sessionId, CODEX_APP_SERVER_AGENT_RUN_ID, {
|
|
93
|
+
event: { kind: "codex-observation-stopped", state: CODEX_APP_SERVER_RUN_STATE.INTERRUPTED },
|
|
94
|
+
patch: {
|
|
95
|
+
error: sharedStop ? `${managed.message} Its shared service was stopped, affecting other sessions using it.` : managed.message,
|
|
96
|
+
providerStatus: "observation_lost", state: CODEX_APP_SERVER_RUN_STATE.INTERRUPTED
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
conversationStream = runtime.store.clearConversationStream(sessionId);
|
|
100
|
+
return stopped;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// Retain the stop owner until the stopped state is durable. Make the
|
|
104
|
+
// provider ready for explicit control before publishing that state.
|
|
105
|
+
if (sharedStop) await retireProvider(provider);
|
|
106
|
+
else provider.observationFailure = null;
|
|
107
|
+
for (const entry of codexAppServerConversations.get(namespace(sessionId))?.values() || []) {
|
|
108
|
+
if (entry.provider === provider && (
|
|
109
|
+
codexAppServerConversationTurnIsActive(entry.status) || entry.goal?.status === "active"
|
|
110
|
+
)) {
|
|
111
|
+
entry.status = "interrupted";
|
|
112
|
+
entry.error = managed.message;
|
|
113
|
+
entry.watcher?.failNow(error);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (stoppedRun) {
|
|
117
|
+
await publish(sessionId, {
|
|
118
|
+
payload: { ...codexAppServerAgentRunRealtimePayload(stoppedRun), conversationStream },
|
|
119
|
+
reason: "codex-observation-stopped"
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function recoverCodexAppServerObservationLoss(runtime, session, context = {}) {
|
|
128
|
+
const sessionId = session.sessionId;
|
|
129
|
+
const current = await runtime.getSession(sessionId);
|
|
130
|
+
const turn = turnState(current);
|
|
131
|
+
if (turn.status !== "observation_lost" || !turn.active) return current;
|
|
132
|
+
const threadId = context.threadId(current);
|
|
133
|
+
if (!threadId || (turn.threadId && turn.threadId !== threadId)) return current;
|
|
134
|
+
|
|
135
|
+
// Reconnect only to inspect. Resuming a thread could restart its goal.
|
|
136
|
+
const provider = await context.acquireProvider(current);
|
|
137
|
+
const { goal } = await provider.readGoal(threadId);
|
|
138
|
+
if (goal !== null && !["paused", "complete"].includes(goal?.status)) return current;
|
|
139
|
+
const status = codexAppServerThreadStatus(await provider.readThreadStatus(threadId));
|
|
140
|
+
if (!codexAppServerTurnStatusIsSuccessfulComplete(status)) return current;
|
|
141
|
+
|
|
142
|
+
const stoppedRun = await runtime.store.mutateSession(sessionId, async () => {
|
|
143
|
+
const latest = await readCodexAppServerAgentRunForSession(runtime.store, sessionId);
|
|
144
|
+
if (JSON.stringify(latest) !== JSON.stringify(codexAppServerAgentRun(current))) return null;
|
|
145
|
+
return runtime.store.writeAgentRunEvent(sessionId, CODEX_APP_SERVER_AGENT_RUN_ID, {
|
|
146
|
+
event: { kind: "codex-observation-stop-recovered", message: "Codex confirmed that the conversation is stopped." },
|
|
147
|
+
patch: {
|
|
148
|
+
error: "",
|
|
149
|
+
providerThreadId: threadId,
|
|
150
|
+
providerGoalThreadId: threadId,
|
|
151
|
+
providerGoalStatus: goal?.status || "",
|
|
152
|
+
state: CODEX_APP_SERVER_RUN_STATE.INTERRUPTED
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
if (stoppedRun) {
|
|
157
|
+
clearCodexAppServerActiveTimer(sessionId);
|
|
158
|
+
await publish(sessionId, {
|
|
159
|
+
payload: {
|
|
160
|
+
...codexAppServerAgentRunRealtimePayload(stoppedRun),
|
|
161
|
+
conversationStream: runtime.store.clearConversationStream(sessionId)
|
|
162
|
+
},
|
|
163
|
+
reason: "codex-observation-stop-recovered"
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
return runtime.getSession(sessionId);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
assertThreadCanResume: assertCodexAppServerThreadCanResume,
|
|
171
|
+
createObservation: createCodexAppServerObservation,
|
|
172
|
+
recoverObservationLoss: recoverCodexAppServerObservationLoss
|
|
173
|
+
};
|
|
174
|
+
}
|