@jskit-ai/assistant-core 0.1.200 → 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
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Conversation primitives example
|
|
2
|
+
|
|
3
|
+
This lower-level example assembles UI, delivery and HTTP primitives. For a new
|
|
4
|
+
application, start with `@jskit-ai/assistant-voice/examples/conversation`; speech
|
|
5
|
+
is optional, and its five chats plus headless task use the supplied conversation
|
|
6
|
+
runtime, server integration and retained client binding. Native engines use that
|
|
7
|
+
same ordinary integration. This example remains useful for custom primitive
|
|
8
|
+
composition and its existing storage/attachment contract.
|
|
2
9
|
|
|
3
10
|
Copy this directory into a new application, then run:
|
|
4
11
|
|
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
"build": "vite build"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@jskit-ai/assistant-core": "0.1.
|
|
12
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
13
|
-
"@jskit-ai/kernel": "0.1.
|
|
11
|
+
"@jskit-ai/assistant-core": "0.1.201",
|
|
12
|
+
"@jskit-ai/http-runtime": "0.1.221",
|
|
13
|
+
"@jskit-ai/kernel": "0.1.223",
|
|
14
14
|
"@mdi/js": "^7.4.47",
|
|
15
15
|
"vue": "^3.5.13",
|
|
16
16
|
"vuetify": "^4.0.0",
|
|
17
|
-
"@jskit-ai/connectors-core": "0.1.
|
|
18
|
-
"@jskit-ai/connectors-catalog": "0.1.
|
|
17
|
+
"@jskit-ai/connectors-core": "0.1.40",
|
|
18
|
+
"@jskit-ai/connectors-catalog": "0.1.40"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@vitejs/plugin-vue": "^6.0.7",
|
|
@@ -4,6 +4,7 @@ import AssistantConversationElement from "../../src/client/conversation/Assistan
|
|
|
4
4
|
import { conversationTurnsFromMessages } from "../../src/shared/conversation/turns.js";
|
|
5
5
|
import { mergeConversationStream } from "../../src/shared/conversation/streaming.js";
|
|
6
6
|
const draft = ref("");
|
|
7
|
+
const visible = ref(true);
|
|
7
8
|
const query = new URLSearchParams(location.search);
|
|
8
9
|
const controls = query.has("controls");
|
|
9
10
|
const deferredHistory = query.has("history");
|
|
@@ -50,6 +51,7 @@ function finishHistory(error = "") {
|
|
|
50
51
|
}
|
|
51
52
|
const adapter = computed(() => ({
|
|
52
53
|
conversation: {
|
|
54
|
+
visible: visible.value,
|
|
53
55
|
turns: mergeConversationStream(conversationTurnsFromMessages(messages.value), { messages: [liveMessage.value] }), scrollKey: scope.value,
|
|
54
56
|
hasMoreBefore: hasMoreBefore.value, loadingMore: loadingMore.value, loadMoreError: loadMoreError.value
|
|
55
57
|
},
|
|
@@ -76,6 +78,7 @@ const adapter = computed(() => ({
|
|
|
76
78
|
<button @click="finishStream">Finish answer</button>
|
|
77
79
|
</nav>
|
|
78
80
|
<nav v-if="controls">
|
|
81
|
+
<button @click="visible = !visible">Toggle visibility</button>
|
|
79
82
|
<button @click="scope = scope === 'one' ? 'two' : 'one'">Change conversation</button>
|
|
80
83
|
<button @click="messages.push({ id: `added-${messages.length}`, role: 'assistant', text: 'New reply. '.repeat(30), status: 'completed' })">Append reply</button>
|
|
81
84
|
</nav>
|
|
@@ -85,7 +88,7 @@ const adapter = computed(() => ({
|
|
|
85
88
|
<button @click="hasMoreBefore = false">Exhaust history</button>
|
|
86
89
|
<output>History requests: {{ historyRequests }}</output>
|
|
87
90
|
</nav>
|
|
88
|
-
<AssistantConversationElement :adapter="adapter" class="assistant-responsive-fixture__conversation" />
|
|
91
|
+
<AssistantConversationElement v-show="visible" :adapter="adapter" class="assistant-responsive-fixture__conversation" />
|
|
89
92
|
</main>
|
|
90
93
|
</v-main>
|
|
91
94
|
</v-app>
|
package/package.json
CHANGED
|
@@ -1,27 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/assistant-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.201",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"test": "node --test"
|
|
6
|
+
"test": "node --test --test-concurrency=1"
|
|
7
7
|
},
|
|
8
8
|
"exports": {
|
|
9
9
|
"./client": "./src/client/index.js",
|
|
10
10
|
"./server": "./src/server/index.js",
|
|
11
11
|
"./shared": "./src/shared/index.js",
|
|
12
12
|
"./client/conversation": "./src/client/conversation/index.js",
|
|
13
|
-
"./server/codex-events": "./src/server/
|
|
14
|
-
"./server/codex-turn": "./src/server/
|
|
15
|
-
"./server/
|
|
16
|
-
"./server/opencode-client": "./src/server/conversation/openCodeClient.js",
|
|
13
|
+
"./server/codex-events": "./src/server/hosts/codexEvents.js",
|
|
14
|
+
"./server/codex-turn": "./src/server/hosts/codexTurn.js",
|
|
15
|
+
"./server/opencode-client": "./src/server/hosts/openCodeClient.js",
|
|
17
16
|
"./server/conversation": "./src/server/conversation/index.js",
|
|
18
17
|
"./shared/conversation": "./src/shared/conversation/index.js",
|
|
19
|
-
"./client/conversation-submit": "./src/client/conversation/submitText.js",
|
|
20
18
|
"./client/conversation-scroll": "./src/client/conversation/useScrollToBottom.js",
|
|
21
19
|
"./testing/conversation-storage": "./src/testing/conversationStorageContract.js",
|
|
22
20
|
"./client/conversation-suggestions": "./src/client/conversation/useAssistantSuggestions.js",
|
|
21
|
+
"./client/conversation-questions": "./src/client/conversation/useAssistantQuestions.js",
|
|
23
22
|
"./client/conversation-attachments": "./src/client/conversation/useAssistantAttachments.js",
|
|
24
|
-
"./client/conversation-delivery": "./src/client/conversation/messageDelivery.js"
|
|
23
|
+
"./client/conversation-delivery": "./src/client/conversation/messageDelivery.js",
|
|
24
|
+
"./server/claude-history": "./src/server/hosts/claudeHistory.js",
|
|
25
|
+
"./server/claude-process": "./src/server/hosts/claudeProcess.js",
|
|
26
|
+
"./server/claude-turn": "./src/server/hosts/claudeTurn.js",
|
|
27
|
+
"./server/codex-configuration": "./src/server/hosts/codexConfiguration.js",
|
|
28
|
+
"./server/codex-process": "./src/server/hosts/codexProcess.js",
|
|
29
|
+
"./server/opencode-turn": "./src/server/hosts/openCodeTurn.js",
|
|
30
|
+
"./server/opencode-process": "./src/server/hosts/openCodeProcess.js",
|
|
31
|
+
"./shared/native-providers": "./src/shared/nativeProviders.js",
|
|
32
|
+
"./server/codex-provider": "./src/server/hosts/codexProvider.js",
|
|
33
|
+
"./server/native-history": "./src/server/hosts/nativeHistory.js",
|
|
34
|
+
"./testing/native-codex": "./src/testing/nativeCodex.js",
|
|
35
|
+
"./testing/native-opencode": "./src/testing/nativeOpenCode.js"
|
|
25
36
|
},
|
|
26
37
|
"dependencies": {
|
|
27
38
|
"@ai-sdk/anthropic": "^4.0.53",
|
|
@@ -34,8 +45,8 @@
|
|
|
34
45
|
"@ai-sdk/perplexity": "^4.0.43",
|
|
35
46
|
"@ai-sdk/togetherai": "^3.0.49",
|
|
36
47
|
"@ai-sdk/xai": "^4.0.58",
|
|
37
|
-
"@jskit-ai/resource-core": "0.1.
|
|
38
|
-
"@jskit-ai/resource-crud-core": "0.1.
|
|
48
|
+
"@jskit-ai/resource-core": "0.1.165",
|
|
49
|
+
"@jskit-ai/resource-crud-core": "0.1.165",
|
|
39
50
|
"@mdi/js": "^7.4.47",
|
|
40
51
|
"@openrouter/ai-sdk-provider": "^3.0.0",
|
|
41
52
|
"ai": "^7.0.101",
|
|
@@ -44,8 +55,8 @@
|
|
|
44
55
|
"ws": "^8.20.1"
|
|
45
56
|
},
|
|
46
57
|
"peerDependencies": {
|
|
47
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
48
|
-
"@jskit-ai/kernel": "0.1.
|
|
58
|
+
"@jskit-ai/http-runtime": "0.1.221",
|
|
59
|
+
"@jskit-ai/kernel": "0.1.223",
|
|
49
60
|
"vue": "^3.5.13",
|
|
50
61
|
"vuetify": "^4.0.0"
|
|
51
62
|
},
|
|
@@ -69,61 +80,113 @@
|
|
|
69
80
|
"metadata": {
|
|
70
81
|
"apiSummary": {
|
|
71
82
|
"surfaces": [
|
|
83
|
+
{
|
|
84
|
+
"subpath": "./server/conversation",
|
|
85
|
+
"summary": "Conversation runtime: createConversationRuntime and file or application-owned storage; advanced storage and host contracts are documented separately."
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"subpath": "./client/conversation",
|
|
89
|
+
"summary": "Optional UI: Embeddable conversation element, transcript, composer and progress presentation with application-owned state and actions."
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"subpath": "./shared/conversation",
|
|
93
|
+
"summary": "Optional UI: Turn mapping, rich-text parsing, question helpers and scroll-follow state."
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"subpath": "./client/conversation-scroll",
|
|
97
|
+
"summary": "Optional UI: Layout-aware scroll-follow operations."
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"subpath": "./client/conversation-suggestions",
|
|
101
|
+
"summary": "Optional UI: Suggestion state and configuration for an application-supplied, separately authorized generator."
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"subpath": "./client/conversation-questions",
|
|
105
|
+
"summary": "Optional UI: Question extraction and answer selection used by the supplied binding and custom presentation."
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"subpath": "./client/conversation-attachments",
|
|
109
|
+
"summary": "Optional UI: Attachment upload and selection state; applications retain storage and authorization."
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"subpath": "./client/conversation-delivery",
|
|
113
|
+
"summary": "Optional UI: Optimistic message delivery, immutable retry payloads, failure actions and canonical receipt reconciliation."
|
|
114
|
+
},
|
|
72
115
|
{
|
|
73
116
|
"subpath": "./client",
|
|
74
|
-
"summary": "Exports reusable assistant UI primitives, HTTP helpers, and client API builders."
|
|
117
|
+
"summary": "Framework integration: Exports reusable assistant UI primitives, HTTP helpers, and client API builders."
|
|
75
118
|
},
|
|
76
119
|
{
|
|
77
120
|
"subpath": "./server",
|
|
78
|
-
"summary": "Exports reusable assistant AI/provider and NDJSON streaming helpers."
|
|
121
|
+
"summary": "Framework integration: Exports reusable assistant AI/provider and NDJSON streaming helpers."
|
|
79
122
|
},
|
|
80
123
|
{
|
|
81
124
|
"subpath": "./shared",
|
|
82
|
-
"summary": "Exports reusable assistant validators, path helpers, query keys, and stream/settings events."
|
|
125
|
+
"summary": "Framework integration: Exports reusable assistant validators, path helpers, query keys, and stream/settings events."
|
|
83
126
|
},
|
|
84
127
|
{
|
|
85
|
-
"subpath": "./
|
|
86
|
-
"summary": "
|
|
128
|
+
"subpath": "./server/codex-events",
|
|
129
|
+
"summary": "Advanced native host: Codex event identities, thread-history projections and context-refresh facts for native hosts."
|
|
87
130
|
},
|
|
88
131
|
{
|
|
89
|
-
"subpath": "./server/
|
|
90
|
-
"summary": "
|
|
132
|
+
"subpath": "./server/codex-turn",
|
|
133
|
+
"summary": "Advanced native host: Original Codex run, receipt, observation, goal, steering, control, scoped-turn and renewal coordination."
|
|
91
134
|
},
|
|
92
135
|
{
|
|
93
|
-
"subpath": "./
|
|
94
|
-
"summary": "
|
|
136
|
+
"subpath": "./server/opencode-client",
|
|
137
|
+
"summary": "Advanced native host: OpenCode native history retirement for existing hosts."
|
|
95
138
|
},
|
|
96
139
|
{
|
|
97
|
-
"subpath": "./server/
|
|
98
|
-
"summary": "
|
|
140
|
+
"subpath": "./server/claude-history",
|
|
141
|
+
"summary": "Advanced native host: Claude native transcript reading, storage inventory and authorized history retirement."
|
|
99
142
|
},
|
|
100
143
|
{
|
|
101
|
-
"subpath": "./server/
|
|
102
|
-
"summary": "
|
|
144
|
+
"subpath": "./server/claude-process",
|
|
145
|
+
"summary": "Advanced native host: Claude command and account-query configuration, owned process startup and verified cleanup."
|
|
103
146
|
},
|
|
104
147
|
{
|
|
105
|
-
"subpath": "./server/
|
|
106
|
-
"summary": "
|
|
148
|
+
"subpath": "./server/claude-turn",
|
|
149
|
+
"summary": "Advanced native host: Original Claude admission, streaming, background-task completion, goals, steering and private renewal execution."
|
|
107
150
|
},
|
|
108
151
|
{
|
|
109
|
-
"subpath": "./server/
|
|
110
|
-
"summary": "
|
|
152
|
+
"subpath": "./server/codex-configuration",
|
|
153
|
+
"summary": "Advanced native host: Codex model and account configuration with verified Helper isolation for existing native hosts."
|
|
111
154
|
},
|
|
112
155
|
{
|
|
113
|
-
"subpath": "./
|
|
114
|
-
"summary": "
|
|
156
|
+
"subpath": "./server/codex-process",
|
|
157
|
+
"summary": "Advanced native host: Codex shared runtime acquisition, process leadership, verified retirement and recovery for managed execution hosts."
|
|
115
158
|
},
|
|
116
159
|
{
|
|
117
|
-
"subpath": "./
|
|
118
|
-
"summary": "
|
|
160
|
+
"subpath": "./server/opencode-turn",
|
|
161
|
+
"summary": "Advanced native host: OpenCode authorized history projections, structured results and bounded renewal for existing hosts."
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"subpath": "./server/opencode-process",
|
|
165
|
+
"summary": "Advanced native host: OpenCode shared runtime selection, native plugin environment, owned server lifecycle, credential-free catalogue reads and bounded API-key verification for existing hosts."
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"subpath": "./shared/native-providers",
|
|
169
|
+
"summary": "Advanced native host: Exact native provider routes, engine configuration facts and qualified model capabilities; applications choose which models to offer."
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"subpath": "./server/codex-provider",
|
|
173
|
+
"summary": "Advanced native host: Original Codex provider acquisition, thread selection, control, recovery, native history retirement and private renewal identity operations."
|
|
119
174
|
},
|
|
120
175
|
{
|
|
121
176
|
"subpath": "./testing/conversation-storage",
|
|
122
|
-
"summary": "Reusable checks for application conversation storage adapters."
|
|
177
|
+
"summary": "Testing: Reusable checks for application conversation storage adapters."
|
|
123
178
|
},
|
|
124
179
|
{
|
|
125
|
-
"subpath": "./
|
|
126
|
-
"summary": "
|
|
180
|
+
"subpath": "./server/native-history",
|
|
181
|
+
"summary": "Testing: Shared native retirement sequence retained for isolated archive and deletion-contract fixtures; native host integrations normally call their engine-specific retirement owner."
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"subpath": "./testing/native-codex",
|
|
185
|
+
"summary": "Testing: Original Codex client, history-adapter, event and model-catalogue probes for isolated host tests; tests own endpoints, authorization and cleanup."
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"subpath": "./testing/native-opencode",
|
|
189
|
+
"summary": "Testing: Original OpenCode loopback client for isolated host integration tests; tests own endpoints, authorization and cleanup."
|
|
127
190
|
}
|
|
128
191
|
],
|
|
129
192
|
"capabilities": []
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
v-bind="conversation" :working="working" class="assistant-conversation__transcript"
|
|
5
5
|
@load-more="adapter.actions?.loadMore?.($event)" @reload="adapter.actions?.reload?.()"
|
|
6
6
|
@resend-turn="resend($event)" @cancel-turn="cancel($event)"
|
|
7
|
+
@check-delivery="adapter.actions?.checkDelivery?.($event)"
|
|
7
8
|
@edit-turn="edit($event)" @link-click="adapter.actions?.openLink?.($event)"
|
|
8
9
|
>
|
|
9
10
|
<template v-for="name in transcriptSlots" #[name]="scope"><slot :name="name" v-bind="scope" /></template>
|
|
@@ -117,11 +118,33 @@ const delivery = ref(null);
|
|
|
117
118
|
const statusId = `assistant-status-${useId()}`;
|
|
118
119
|
const conversation = computed(() => {
|
|
119
120
|
const saved = props.adapter.conversation;
|
|
120
|
-
if (!props.adapter.delivery) return saved;
|
|
121
|
-
const
|
|
122
|
-
|
|
121
|
+
if (!props.adapter.delivery && !saved.previewMessage && !saved.interimReply) return saved;
|
|
122
|
+
const { previewMessage, interimReply, ...display } = saved;
|
|
123
|
+
let turns = props.adapter.delivery ? props.adapter.delivery.turns(saved.turns || []) : saved.turns || [];
|
|
124
|
+
if (interimReply?.text && interimReply.turnId) {
|
|
125
|
+
const assistant = { ...interimReply, messageId: interimReply.id, role: "assistant" };
|
|
126
|
+
turns = turns.map(turn => turn.turnId !== interimReply.turnId ? turn : {
|
|
127
|
+
...turn, assistant,
|
|
128
|
+
commentary: (turn.commentary || []).filter(message =>
|
|
129
|
+
(message.outputId || message.messageId) !== (interimReply.outputId || interimReply.id)),
|
|
130
|
+
...(Array.isArray(turn.messages) ? { messages: turn.messages.filter(message =>
|
|
131
|
+
message.role !== "assistant" &&
|
|
132
|
+
(message.outputId || message.messageId) !== (interimReply.outputId || interimReply.id)).concat(assistant) } : {})
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
const messageId = String(previewMessage?.messageId || previewMessage?.id || "").trim();
|
|
136
|
+
const alreadyShown = messageId && (props.adapter.delivery?.find?.(messageId) || turns.some(turn => [
|
|
137
|
+
turn.system, turn.user, turn.assistant, ...(turn.thinking || []), ...(turn.commentary || []), ...(turn.messages || [])
|
|
138
|
+
].some(message => String(message?.messageId || message?.id || "") === messageId)));
|
|
139
|
+
if (messageId && previewMessage?.text && !alreadyShown) {
|
|
140
|
+
const user = { messageId, role: "user", text: String(previewMessage.text) };
|
|
141
|
+
turns = [...turns, { turnId: messageId, user, messages: [user], optimistic: { id: messageId, status: "pending" } }];
|
|
142
|
+
}
|
|
143
|
+
// Transcription and interim replies are display only. The receipt watcher
|
|
144
|
+
// receives canonical turns, never these presentation or delivery overlays.
|
|
145
|
+
return { ...display, turns, welcomeMessage: turns.length ? "" : saved.welcomeMessage };
|
|
123
146
|
});
|
|
124
|
-
watch(() =>
|
|
147
|
+
watch([() => props.adapter.delivery, () => props.adapter.conversation.turns], ([controller, turns]) => {
|
|
125
148
|
controller?.reconcile(turns || []);
|
|
126
149
|
}, { immediate: true });
|
|
127
150
|
const pending = computed(() => Boolean(props.adapter.delivery?.state.sending || props.adapter.composer?.pending));
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div v-if="message.delivery" role="status">
|
|
3
|
+
<p>{{ message.text }}</p>
|
|
4
|
+
<p v-if="message.delivery.error" class="text-body-small">{{ message.delivery.error }}</p>
|
|
5
|
+
<v-btn
|
|
6
|
+
variant="tonal"
|
|
7
|
+
min-height="48"
|
|
8
|
+
:disabled="message.delivery.checking"
|
|
9
|
+
@click="$emit('check-delivery', message.delivery.messageId)"
|
|
10
|
+
>
|
|
11
|
+
{{ message.delivery.checking ? 'Checking delivery…' : 'Check delivery' }}
|
|
12
|
+
</v-btn>
|
|
13
|
+
</div>
|
|
14
|
+
<slot v-else>
|
|
15
|
+
<LongTextPreviewBlocks compact :blocks="message.blocks" @link-click="$emit('link-click', $event)" />
|
|
16
|
+
</slot>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script setup>
|
|
20
|
+
import LongTextPreviewBlocks from "./LongTextPreviewBlocks.vue";
|
|
21
|
+
|
|
22
|
+
defineProps({ message: { type: Object, required: true } });
|
|
23
|
+
defineEmits(["check-delivery", "link-click"]);
|
|
24
|
+
</script>
|
|
@@ -22,7 +22,7 @@ const elapsed = computed(() => {
|
|
|
22
22
|
return minutes < 60 ? `${minutes}:${seconds}` : `${Math.floor(minutes / 60)}:${String(minutes % 60).padStart(2, "0")}:${seconds}`;
|
|
23
23
|
});
|
|
24
24
|
const canSet = computed(() => typeof props.state?.set === "function" && (!goal.value || goal.value.status === "complete"));
|
|
25
|
-
const validBudget = computed(() => tokenBudget.value === "" || (Number.isSafeInteger(Number(tokenBudget.value)) && Number(tokenBudget.value) > 0));
|
|
25
|
+
const validBudget = computed(() => props.state?.tokenBudgetSupported === false || tokenBudget.value === "" || (Number.isSafeInteger(Number(tokenBudget.value)) && Number(tokenBudget.value) > 0));
|
|
26
26
|
let timer;
|
|
27
27
|
onMounted(() => watch(() => [props.state?.enabled, running.value, goal.value?.elapsedSeconds, goal.value?.sampledAt], () => {
|
|
28
28
|
clearInterval(timer);
|
|
@@ -35,7 +35,7 @@ onScopeDispose(() => clearInterval(timer));
|
|
|
35
35
|
watch(() => props.state?.enabled, enabled => { if (enabled === false) open.value = false; });
|
|
36
36
|
async function setGoal() {
|
|
37
37
|
if (!canSet.value || props.state.pending || !objective.value.trim() || !validBudget.value) return;
|
|
38
|
-
const result = await props.state.set({ objective: objective.value.trim(), ...(tokenBudget.value === "" ? {} : { tokenBudget: Number(tokenBudget.value) }) });
|
|
38
|
+
const result = await props.state.set({ objective: objective.value.trim(), ...(props.state.tokenBudgetSupported === false || tokenBudget.value === "" ? {} : { tokenBudget: Number(tokenBudget.value) }) });
|
|
39
39
|
if (result !== false && !props.state.error) { objective.value = ""; tokenBudget.value = ""; }
|
|
40
40
|
}
|
|
41
41
|
</script>
|
|
@@ -52,13 +52,16 @@ async function setGoal() {
|
|
|
52
52
|
<v-card class="assistant-goal__details pa-3" max-width="360">
|
|
53
53
|
<strong role="status">{{ label }}</strong>
|
|
54
54
|
<p v-if="goal" class="my-2">{{ goal.objective }}</p>
|
|
55
|
+
<p v-if="goal?.reason" class="text-body-small my-2">{{ goal.reason }}</p>
|
|
55
56
|
<p v-if="elapsed" class="text-body-small my-2">Running time: {{ elapsed }}</p>
|
|
56
57
|
<v-btn v-if="running && state.pause" size="small" :disabled="state.pending" @click="state.pause()">{{ state.pending ? 'Pausing…' : 'Pause goal' }}</v-btn>
|
|
57
58
|
<v-btn v-else-if="['paused', 'blocked', 'usageLimited'].includes(goal?.status) && state.resume" size="small" :disabled="state.pending" @click="state.resume()">{{ state.pending ? 'Resuming…' : 'Resume goal' }}</v-btn>
|
|
58
|
-
<
|
|
59
|
+
<v-btn v-if="goal && goal.status !== 'complete' && state.cancel" color="error" size="small" variant="text" :disabled="state.pending" @click="state.cancel()">Cancel goal</v-btn>
|
|
60
|
+
<p v-if="running || goal?.status === 'paused'" class="text-body-small mt-2">{{ state.pauseInterruptsTurn ? 'Pause stops the current turn and keeps the goal for later.' : 'Pausing prevents further automatic turns. Use Stop to interrupt the current turn.' }}</p>
|
|
61
|
+
<p v-if="goal && goal.status !== 'complete' && state.cancel" class="text-body-small mt-2">{{ state.cancelInterruptsTurn ? 'Cancel stops the current turn and clears the goal.' : 'Cancel removes this goal. Use Stop to interrupt a turn already running.' }}</p>
|
|
59
62
|
<form v-if="canSet" class="assistant-goal__form mt-2" @submit.prevent="setGoal">
|
|
60
|
-
<v-textarea v-model="objective" label="Goal objective" rows="2" auto-grow :disabled="state.pending" hide-details />
|
|
61
|
-
<v-text-field v-model="tokenBudget" label="Token budget (optional)" type="number" min="1" step="1" :disabled="state.pending" :error="!validBudget" hide-details />
|
|
63
|
+
<v-textarea v-model="objective" label="Goal objective" rows="2" maxlength="4000" auto-grow :disabled="state.pending" hide-details />
|
|
64
|
+
<v-text-field v-if="state.tokenBudgetSupported !== false" v-model="tokenBudget" label="Token budget (optional)" type="number" min="1" step="1" :disabled="state.pending" :error="!validBudget" hide-details />
|
|
62
65
|
<v-btn type="submit" size="small" :disabled="state.pending || !objective.trim() || !validBudget">{{ state.pending ? 'Starting…' : 'Start goal' }}</v-btn>
|
|
63
66
|
</form>
|
|
64
67
|
<p v-if="state.error" role="alert" class="text-error text-body-small mt-2">{{ state.error }}</p>
|
|
@@ -116,7 +116,9 @@
|
|
|
116
116
|
<span>{{ systemLabel }}</span>
|
|
117
117
|
<time v-if="entry.message.displayAt">{{ entry.message.displayAt }}</time>
|
|
118
118
|
</div>
|
|
119
|
-
<slot name="system-message" :message="entry.message"
|
|
119
|
+
<slot name="system-message" :message="entry.message">
|
|
120
|
+
<AssistantConversationStatus :message="entry.message" @check-delivery="emit('check-delivery', $event)" @link-click="handleLongTextLinkClick" />
|
|
121
|
+
</slot>
|
|
120
122
|
</div>
|
|
121
123
|
</div>
|
|
122
124
|
|
|
@@ -288,6 +290,7 @@
|
|
|
288
290
|
|
|
289
291
|
<script setup>
|
|
290
292
|
import AssistantMessageAttachments from "./AssistantMessageAttachments.vue";
|
|
293
|
+
import AssistantConversationStatus from "./AssistantConversationStatus.vue";
|
|
291
294
|
import { computed, nextTick, onBeforeUnmount, ref, watch } from "vue";
|
|
292
295
|
import {
|
|
293
296
|
mdiAccountOutline,
|
|
@@ -372,7 +375,7 @@ const props = defineProps({
|
|
|
372
375
|
}
|
|
373
376
|
});
|
|
374
377
|
|
|
375
|
-
const emit = defineEmits(["cancel-turn", "edit-turn", "load-more", "link-click", "reload", "resend-turn"]);
|
|
378
|
+
const emit = defineEmits(["cancel-turn", "check-delivery", "edit-turn", "load-more", "link-click", "reload", "resend-turn"]);
|
|
376
379
|
|
|
377
380
|
const USER_MESSAGE_COLLAPSE_MIN_CHARACTERS = 360;
|
|
378
381
|
const USER_MESSAGE_PREVIEW_MAX_CHARACTERS = 280;
|
|
@@ -633,7 +636,6 @@ function messageScrollKey(message = null) {
|
|
|
633
636
|
}
|
|
634
637
|
|
|
635
638
|
const timelineScrollTrigger = computed(() => [
|
|
636
|
-
props.visible ? "visible" : "hidden",
|
|
637
639
|
props.error ? "error" : "body",
|
|
638
640
|
loadingIndicatorVisible.value ? "loading" : "ready",
|
|
639
641
|
displayEntries.value.length ? "has-messages" : "empty",
|
|
@@ -927,6 +929,11 @@ watch(timelineScrollTrigger, () => {
|
|
|
927
929
|
flush: "post",
|
|
928
930
|
immediate: true
|
|
929
931
|
});
|
|
932
|
+
|
|
933
|
+
watch(() => props.visible, (visible) => {
|
|
934
|
+
clearLoadMoreScrollSnapshot();
|
|
935
|
+
if (visible) queueLiveBottomScroll({ force: true });
|
|
936
|
+
}, { flush: "post" });
|
|
930
937
|
</script>
|
|
931
938
|
|
|
932
939
|
<style scoped>
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
export { default as AssistantConversationElement } from "./AssistantConversationElement.vue";
|
|
2
2
|
export { default as AssistantTranscript } from "./AssistantTranscript.vue";
|
|
3
|
+
export { default as AssistantConversationStatus } from "./AssistantConversationStatus.vue";
|
|
3
4
|
export { default as AssistantPromptInput } from "./AssistantPromptInput.vue";
|
|
4
5
|
export { default as AssistantComposerActions } from "./AssistantComposerActions.vue";
|
|
5
6
|
export { default as AssistantProgress } from "./AssistantProgress.vue";
|
|
6
7
|
export { default as AssistantComposerSupport } from "./AssistantComposerSupport.vue";
|
|
7
8
|
export { default as AssistantGoalControl } from "./AssistantGoalControl.vue";
|
|
8
9
|
export { useAssistantSuggestions } from "./useAssistantSuggestions.js";
|
|
10
|
+
export { useAssistantQuestions } from "./useAssistantQuestions.js";
|
|
9
11
|
export { default as LongTextPreviewBlocks } from "./LongTextPreviewBlocks.vue";
|
|
10
12
|
export { default as LongTextInlineParts } from "./LongTextInlineParts.vue";
|
|
11
13
|
export { useScrollToBottom } from "./useScrollToBottom.js";
|