@jskit-ai/assistant-core 0.1.238 → 0.1.239

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.238",
12
- "@jskit-ai/http-runtime": "0.1.242",
13
- "@jskit-ai/kernel": "0.1.244",
11
+ "@jskit-ai/assistant-core": "0.1.239",
12
+ "@jskit-ai/http-runtime": "0.1.243",
13
+ "@jskit-ai/kernel": "0.1.245",
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.61",
18
- "@jskit-ai/connectors-catalog": "0.1.62"
17
+ "@jskit-ai/connectors-core": "0.1.62",
18
+ "@jskit-ai/connectors-catalog": "0.1.63"
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.238",
3
+ "version": "0.1.239",
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.186",
51
- "@jskit-ai/resource-crud-core": "0.1.186",
50
+ "@jskit-ai/resource-core": "0.1.187",
51
+ "@jskit-ai/resource-crud-core": "0.1.187",
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.242",
61
- "@jskit-ai/kernel": "0.1.244",
60
+ "@jskit-ai/http-runtime": "0.1.243",
61
+ "@jskit-ai/kernel": "0.1.245",
62
62
  "vue": "^3.5.13",
63
63
  "vuetify": "^4.0.0"
64
64
  },
@@ -175,7 +175,7 @@
175
175
  class="assistant-transcript__message-footer assistant-transcript__message-footer--user"
176
176
  >
177
177
  <time v-if="entry.message.displayAt">{{ entry.message.displayAt }}</time>
178
- <span v-if="entry.turn.optimistic?.status === 'pending'" role="status">Pending</span>
178
+ <span v-if="entry.turn.optimistic?.status === 'pending'" role="status">{{ entry.turn.optimistic.waiting ? `Pending: ${entry.turn.optimistic.waiting}` : "Pending" }}</span>
179
179
  </div>
180
180
  <slot name="user-message-actions" :message="entry.message" :turn="entry.turn" />
181
181
  <div
@@ -96,7 +96,8 @@ function createAssistantMessageDelivery({ deliver: defaultDeliver } = {}) {
96
96
  delivery: { messageId: message.id, error: message.error, checking: message.checking === true }
97
97
  } : null;
98
98
  return {
99
- optimistic: { error: message.error, id: message.id, status: message.status },
99
+ optimistic: { error: message.error, id: message.id, status: message.status,
100
+ ...(message.status === "pending" && message.waiting ? { waiting: message.waiting } : {}) },
100
101
  turnId: message.id,
101
102
  [role]: authored,
102
103
  ...(status ? { system: role === "system" ? { ...authored, ...status, text: `${authored.text}\n\n${status.text}` } : status } : {})
@@ -201,6 +202,12 @@ function createAssistantMessageDelivery({ deliver: defaultDeliver } = {}) {
201
202
  }
202
203
  }
203
204
 
205
+ // Explains why a pending message is held locally, or clears that reason.
206
+ function wait(messageId, reason = "") {
207
+ const message = find(messageId);
208
+ if (message?.status === "pending") message.waiting = String(reason || "").trim();
209
+ }
210
+
204
211
  function rejectUnsent(messageId, error) {
205
212
  if (find(messageId)?.status !== "uncertain") return false;
206
213
  fail(messageId, error);
@@ -253,7 +260,7 @@ function createAssistantMessageDelivery({ deliver: defaultDeliver } = {}) {
253
260
  state.sending = false;
254
261
  }
255
262
 
256
- return { accept, cancel, edit, find, reconcile, remove, resend, reset, restoreUncertain, rejectUnsent, send, state, turns };
263
+ return { accept, cancel, edit, find, reconcile, remove, resend, reset, restoreUncertain, rejectUnsent, send, state, turns, wait };
257
264
  }
258
265
 
259
266
  export { createAssistantMessageDelivery, unmatchedOptimisticMessages };
@@ -10,7 +10,7 @@ const NATIVE_AI_PROVIDERS = Object.freeze([
10
10
  claudeAutoCompactWindow: 786432, webSearch: false,
11
11
  models: Object.freeze([
12
12
  model("deepseek-flash", 1048576, ["low", "high", "max"], { images: true, freeformPatch: true, codexHistoryRouting: true }),
13
- model("deepseek-v4-pro", 1048576, ["low", "high", "max"], { freeformPatch: true })
13
+ model("deepseek-v4-pro", 1048576, ["low", "high", "max"], { freeformPatch: true, codexHistoryRouting: true })
14
14
  ])
15
15
  }),
16
16
  Object.freeze({
@@ -267,7 +267,7 @@ async function compactedFixture(t, { maxRequestBytes } = {}) {
267
267
  test("mixed Codex recovery keeps exact text and tool facts without changing native history or current instructions", async (t) => {
268
268
  const fixture = await compactedFixture(t);
269
269
  const native = await readFile(fixture.historyPath);
270
- for (const [destination, model] of [["deepseek", "deepseek-flash"], ["zai-coding-plan", "glm-5.3"]]) {
270
+ for (const [destination, model] of [["deepseek", "deepseek-flash"], ["deepseek", "deepseek-v4-pro"], ["zai-coding-plan", "glm-5.3"]]) {
271
271
  const current = { type: "message", role: "developer", content: [{ type: "input_text", text: "CURRENT_INSTRUCTIONS" }] };
272
272
  const body = { model, input: [current, fixture.compacted, foreign], tools: [{ type: "function", name: "exec_command" }] };
273
273
  const original = structuredClone(body);
@@ -289,7 +289,7 @@ test("mixed Codex recovery keeps exact text and tool facts without changing nati
289
289
  assert.deepEqual(body, original);
290
290
  }
291
291
  assert.deepEqual(await readFile(fixture.historyPath), native);
292
- assert.equal(fixture.calls.length, 2, "one upstream request per user request");
292
+ assert.equal(fixture.calls.length, 3, "one upstream request per user request");
293
293
  });
294
294
 
295
295
  test("compacted native agent messages retain attribution, readable content and explicit opaque-content markers", async (t) => {
@@ -358,9 +358,11 @@ test("compacted screenshots stay visible and associated with their original mess
358
358
  assert.match(content[3].text, /Archived image 2/);
359
359
  assert.equal(content.at(-1).text, "[/Archived conversation]");
360
360
  assert.deepEqual(await readFile(fixture.historyPath), native);
361
- const unsupported = await fixture.send({ model: "glm-5.3", input: [fixture.compacted] }, "zai-coding-plan");
362
- assert.equal(unsupported.status, 422);
363
- assert.match((await unsupported.json()).error.message, /does not support images/);
361
+ for (const [model, destination] of [["glm-5.3", "zai-coding-plan"], ["deepseek-v4-pro", "deepseek"]]) {
362
+ const unsupported = await fixture.send({ model, input: [fixture.compacted] }, destination);
363
+ assert.equal(unsupported.status, 422);
364
+ assert.match((await unsupported.json()).error.message, /does not support images/);
365
+ }
364
366
  assert.equal(fixture.calls.length, 1);
365
367
  });
366
368