@jskit-ai/assistant-core 0.1.219 → 0.1.220
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.
|
@@ -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.220",
|
|
12
|
+
"@jskit-ai/http-runtime": "0.1.240",
|
|
13
|
+
"@jskit-ai/kernel": "0.1.242",
|
|
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.59",
|
|
18
|
+
"@jskit-ai/connectors-catalog": "0.1.59"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@vitejs/plugin-vue": "^6.0.7",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/assistant-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.220",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test --test-concurrency=1"
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"@ai-sdk/perplexity": "^4.0.43",
|
|
48
48
|
"@ai-sdk/togetherai": "^3.0.49",
|
|
49
49
|
"@ai-sdk/xai": "^4.0.58",
|
|
50
|
-
"@jskit-ai/resource-core": "0.1.
|
|
51
|
-
"@jskit-ai/resource-crud-core": "0.1.
|
|
50
|
+
"@jskit-ai/resource-core": "0.1.184",
|
|
51
|
+
"@jskit-ai/resource-crud-core": "0.1.184",
|
|
52
52
|
"@mdi/js": "^7.4.47",
|
|
53
53
|
"@openrouter/ai-sdk-provider": "^3.0.0",
|
|
54
54
|
"ai": "^7.0.101",
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
"ws": "^8.20.1"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
61
|
-
"@jskit-ai/kernel": "0.1.
|
|
60
|
+
"@jskit-ai/http-runtime": "0.1.240",
|
|
61
|
+
"@jskit-ai/kernel": "0.1.242",
|
|
62
62
|
"vue": "^3.5.13",
|
|
63
63
|
"vuetify": "^4.0.0"
|
|
64
64
|
},
|
|
@@ -1634,7 +1634,9 @@ export function createOpenCodeSharedRuntime({ onStop = () => {}, scope } = {}) {
|
|
|
1634
1634
|
|
|
1635
1635
|
async function interruptTurn(key, target, { threadId = "", writeRun } = {}) {
|
|
1636
1636
|
const turn = turns.get(key);
|
|
1637
|
-
|
|
1637
|
+
// Helpers can acquire the shared process before a main conversation exists.
|
|
1638
|
+
// Their cleanup is owned by closeSession, not a native main-turn interrupt.
|
|
1639
|
+
if (!target || (!text(target.upstreamSessionId) && !turn?.active)) {
|
|
1638
1640
|
return {
|
|
1639
1641
|
interrupted: false,
|
|
1640
1642
|
ok: true,
|
|
@@ -241,7 +241,8 @@ export function createConversationRuntime({ engine: defaultEngine = "api", defau
|
|
|
241
241
|
await emit(entry, { type: "message", turnId: turn.turnId, messageId: message.messageId,
|
|
242
242
|
...(message.outputId ? { outputId: message.outputId } : {}),
|
|
243
243
|
...(["user", "application"].includes(turn.metadata?.runtime?.origin) ? { origin: turn.metadata.runtime.origin } : {}),
|
|
244
|
-
role: message.role, text: message.text, status: "complete",
|
|
244
|
+
role: message.role, text: message.text, at: message.at, status: "complete", persisted: true,
|
|
245
|
+
streaming: payload.conversationStream || streams.read(entry.id) });
|
|
245
246
|
}
|
|
246
247
|
}
|
|
247
248
|
if (payload.conversationStream) {
|
|
@@ -3108,6 +3108,8 @@ test("default Codex commentary publishes its saved output identity rather than a
|
|
|
3108
3108
|
assert.equal(completed.every(event => event.messageId === progress[0].messageId), true,
|
|
3109
3109
|
"The existing canonical publication owns this exact output; its native stream must not complete a second identity");
|
|
3110
3110
|
assert.equal(completed.every(event => event.outputId === progress[0].outputId && event.text === progress[0].text), true);
|
|
3111
|
+
assert.equal(completed.every(event => event.persisted === true && event.at === progress[0].at), true,
|
|
3112
|
+
"Saved output notifications retain their timestamp and cannot masquerade as transient output outside a loaded history page");
|
|
3111
3113
|
assert.equal((await f.conversation.read()).streaming.completedMessages, undefined);
|
|
3112
3114
|
assert.equal((await f.trace()).filter(row => row.method === "turn/start").length, 1);
|
|
3113
3115
|
});
|
|
@@ -4,6 +4,7 @@ import os from "node:os";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import test from "node:test";
|
|
6
6
|
import { createOpenCodeSharedRuntime, ensureOpenCodeSession, openCodeServerForDirectory, readOpenCodeEnvironments } from "../src/server/conversation/openCodeRuntime.js";
|
|
7
|
+
import { createOpenCodeServerClient } from "../src/server/conversation/openCodeClient.js";
|
|
7
8
|
|
|
8
9
|
function fixture(options = {}) {
|
|
9
10
|
const runtime = createOpenCodeSharedRuntime();
|
|
@@ -186,6 +187,54 @@ test("OpenCode shares one lazy server across open sessions and stops it after th
|
|
|
186
187
|
assert.equal(f.stops.length, 2);
|
|
187
188
|
});
|
|
188
189
|
|
|
190
|
+
test("an acquired OpenCode process without a main conversation can close without interrupting a peer", async () => {
|
|
191
|
+
const interrupted = [];
|
|
192
|
+
const f = fixture({ interrupt: id => { interrupted.push(id); return true; } });
|
|
193
|
+
const target = await f.acquire("empty");
|
|
194
|
+
target.sessionId = "empty";
|
|
195
|
+
const peer = await f.acquire("peer");
|
|
196
|
+
peer.upstreamSessionId = "peer-native";
|
|
197
|
+
const nativeClient = createOpenCodeServerClient({ baseUrl: "http://127.0.0.1:1",
|
|
198
|
+
fetchImpl: async () => assert.fail("No native main conversation exists to interrupt.") });
|
|
199
|
+
target.server = { ...target.server, client: nativeClient };
|
|
200
|
+
const stopped = await f.runtime.interruptPreparedTurn({
|
|
201
|
+
key: "empty", threadId: "", failure: error => { throw error; }
|
|
202
|
+
});
|
|
203
|
+
assert.equal(stopped.ok, true);
|
|
204
|
+
assert.equal(stopped.interrupted, false);
|
|
205
|
+
const calls = [];
|
|
206
|
+
const closed = await f.runtime.closeSession("empty", {}, {
|
|
207
|
+
closeTerminals: async () => { calls.push("terminals"); return { ok: true, closed: 0 }; },
|
|
208
|
+
beforeRelease: async () => { calls.push("helpers"); },
|
|
209
|
+
onRemoved: async () => { calls.push("removed"); },
|
|
210
|
+
afterRelease: async () => { calls.push("history"); },
|
|
211
|
+
failure: error => { throw error; }
|
|
212
|
+
});
|
|
213
|
+
assert.equal(closed.ok, true);
|
|
214
|
+
assert.equal(closed.closed, 1);
|
|
215
|
+
assert.deepEqual(calls, ["terminals", "helpers", "removed", "history"]);
|
|
216
|
+
assert.equal(target.abortController.signal.aborted, true);
|
|
217
|
+
assert.equal(peer.abortController.signal.aborted, false);
|
|
218
|
+
assert.equal(f.stops.length, 0);
|
|
219
|
+
assert.deepEqual(interrupted, []);
|
|
220
|
+
await f.runtime.interruptTurn("peer", peer);
|
|
221
|
+
assert.deepEqual(interrupted, ["peer-native"]);
|
|
222
|
+
await f.runtime.release(peer);
|
|
223
|
+
assert.equal(f.stops.length, 1);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
test("an active OpenCode turn with missing native identity still fails instead of claiming Stop", async () => {
|
|
227
|
+
const runtime = createOpenCodeSharedRuntime();
|
|
228
|
+
const client = createOpenCodeServerClient({ baseUrl: "http://127.0.0.1:1",
|
|
229
|
+
fetchImpl: async () => assert.fail("Invalid identity must fail before transport.") });
|
|
230
|
+
const turn = { active: true, state: "inProgress" };
|
|
231
|
+
runtime.turns.set("invalid", turn);
|
|
232
|
+
await assert.rejects(runtime.interruptTurn("invalid", { upstreamSessionId: "", server: { client } }),
|
|
233
|
+
/OpenCode session requests require a session id/u);
|
|
234
|
+
assert.equal(turn.active, true);
|
|
235
|
+
assert.equal(turn.interruptRequested, false);
|
|
236
|
+
});
|
|
237
|
+
|
|
189
238
|
test("a pending OpenCode session start retains the shared server while another session closes", async () => {
|
|
190
239
|
const f = fixture();
|
|
191
240
|
const first = await f.acquire("session-1");
|