@adaptiqai/deepseek-harness 0.2.13 → 0.2.14

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/lib/host.js CHANGED
@@ -124,30 +124,30 @@ function classifyFailure(status, raw, headers, model2, options = {}) {
124
124
  }
125
125
  if (detail.code === "plan_usage_exhausted") {
126
126
  const renewsAt = envelope.detail?.renews_at;
127
- const failure = make(CODES.noLanes, detail.message ?? "Your plan's usage is used up for now. Rent extra lanes in the meantime.", "no-lanes");
127
+ const failure = make(CODES.noLanes, detail.message ?? "Your plan's usage is used up for now. Pay per token from your balance in the meantime.", "no-lanes");
128
128
  return typeof renewsAt === "number" ? { ...failure, planRenewsAt: renewsAt } : failure;
129
129
  }
130
130
  if (effective === 402 || detail.code === "rental_paused") {
131
131
  const releaseAt = envelope.detail?.release_at;
132
132
  const minutes = typeof releaseAt === "number" ? Math.max(1, Math.ceil((releaseAt * 1e3 - Date.now()) / 6e4)) : null;
133
- const keep = minutes === null ? "to continue" : `within ${minutes} minute${minutes === 1 ? "" : "s"} to keep them`;
134
- const failure = make(CODES.outOfCredit, `Your balance ran out, so your lanes are paused. Add funds ${keep}.`, "out-of-credit");
133
+ const keep = minutes === null ? "to continue" : `within ${minutes} minute${minutes === 1 ? "" : "s"} to keep your models running`;
134
+ const failure = make(CODES.outOfCredit, `Your balance ran out. Add funds ${keep}.`, "out-of-credit");
135
135
  return minutes === null ? failure : { ...failure, minutesLeft: minutes };
136
136
  }
137
137
  if (effective === 401) {
138
138
  return make(CODES.signIn, "Your AdaptiqAI sign-in has expired. Open Settings \u2192 AdaptiqAI and sign in again.", "sign-in");
139
139
  }
140
140
  if (detail.code === "rental_stopped_unused") {
141
- return make(CODES.noLanes, "Your lane stopped because it went unused, so nothing more was charged. Get access to start it again.", "no-lanes");
141
+ return make(CODES.noLanes, "The model stopped after going unused. Get access to start it again.", "no-lanes");
142
142
  }
143
143
  if (has(detail, "AdaptiqLaneAccessRequired", "inference_entitlement_required", "instance_access_required", "lane_access") || effective === 403 && has(detail, "lane", "entitle", "model access")) {
144
- return make(CODES.noLanes, "You need to rent a lane or subscribe to AdaptiqAI to continue.", "no-lanes");
144
+ return make(CODES.noLanes, "This model isn't in your workspace yet. Get access to continue; you pay per token from your balance.", "no-lanes");
145
145
  }
146
146
  if (effective === 403) {
147
147
  return make(CODES.signIn, "This AdaptiqAI connection isn't allowed to do that. Sign in again from Settings \u2192 AdaptiqAI.", "sign-in");
148
148
  }
149
149
  if (effective === 429 || has(detail, "AdaptiqLaneQueueTimeout", "InflightLimit", "rate_limit")) {
150
- return make(CODES.busy, `All of your lanes on ${name2} are busy. Your request will retry automatically in a moment.`, "busy");
150
+ return make(CODES.busy, `${name2} is busy. Your request will retry automatically in a moment.`, "busy");
151
151
  }
152
152
  if (effective === 503 && detail.code !== null && MODEL_OFFLINE_CODES.includes(detail.code)) {
153
153
  return make(CODES.server, `${model2 ?? "This model"} is offline right now. It will retry automatically.`, "retrying");
@@ -159,7 +159,7 @@ function classifyFailure(status, raw, headers, model2, options = {}) {
159
159
  return make(CODES.conversationUnavailable, "This conversation couldn't be opened on AdaptiqAI right now. Try again shortly; your saved memory is unchanged.", null);
160
160
  }
161
161
  if (effective === 404 && (has(detail, "model", "not_found", "does not exist") || detail.message === null)) {
162
- return make(CODES.modelNotFound, `${name2} isn't available to your workspace right now. Pick another AdaptiqAI model, or check your lanes in the console.`, "model-unavailable");
162
+ return make(CODES.modelNotFound, `${name2} isn't available to your workspace right now. Pick another AdaptiqAI model, or check your models in the console.`, "model-unavailable");
163
163
  }
164
164
  if (effective === 400 || effective === 413 || effective === 422) {
165
165
  const said = detail.message !== null ? ` (${detail.message.slice(0, 200)})` : "";
@@ -1066,13 +1066,11 @@ var en = {
1066
1066
  expiredTitle: "Your sign-in expired",
1067
1067
  signInAgain: "Sign in again",
1068
1068
  tryAgain: "Try again",
1069
- models: "Models & lanes",
1069
+ models: "Models",
1070
1070
  status_running: "Running",
1071
1071
  status_offline: "Offline",
1072
1072
  status_disabled: "Paused",
1073
1073
  status_unknown: "Available",
1074
- lanesOne: "{count} lane",
1075
- lanesMany: "{count} lanes",
1076
1074
  thinkingLevels: "Thinking {levels}",
1077
1075
  noModels: "Pick your first model",
1078
1076
  getAccess: "Get access",
@@ -1098,10 +1096,10 @@ var en = {
1098
1096
  routeConflictTitle: "AdaptiqAI models are hidden",
1099
1097
  pillMemory: "Memory",
1100
1098
  pillPreparing: "Preparing memory",
1101
- pillQueued: "Waiting for a free lane",
1099
+ pillQueued: "Waiting in line",
1102
1100
  pillStarting: "Starting\u2026",
1103
1101
  pillSignIn: "Sign in to AdaptiqAI",
1104
- pillFromMemory: "{tokens} from memory",
1102
+ pillFromMemory: "{tokens} from memory \xB7 free",
1105
1103
  pillTooltip: "AdaptiqAI memory for this conversation",
1106
1104
  popTitle: "Memory",
1107
1105
  popSaving: "Saving",
@@ -1177,22 +1175,22 @@ var en = {
1177
1175
  accessTitle: "Get a model",
1178
1176
  offerSpeed: "{speed} tokens/s",
1179
1177
  offerMemory: "{tokens} memory",
1180
- offerPrice: "{price} per lane per {period}",
1178
+ offerPrice: "{price} per {period}",
1181
1179
  offerOwned: "In your workspace",
1182
1180
  offerFull: "Full right now",
1183
1181
  period_hour: "hour",
1184
1182
  period_month: "month",
1185
1183
  period_once: "purchase",
1186
- lanesLabel: "Lanes",
1187
- lanesHint: "Each lane runs one conversation at a time.",
1184
+ lanesLabel: "At once",
1185
+ lanesHint: "How many conversations can run at the same time.",
1188
1186
  totalPrice: "{price} per {period}",
1189
1187
  noOffers: "No models are on offer right now. Check back soon.",
1190
- manualNote: "Our team activates new lanes after you confirm.",
1191
- balanceNote: "Runs from your balance and stops by itself after 15 minutes without requests, or when you stop it.",
1188
+ manualNote: "Our team turns it on after you confirm.",
1189
+ balanceNote: "You pay per token from your balance. Reads from memory are free.",
1192
1190
  cardNote: "You pay by card in your browser.",
1193
- addLanes: "Add lanes",
1191
+ addLanes: "Run more at once",
1194
1192
  purchase_approving: "Confirm in your browser",
1195
- purchase_approving_body: "We opened a page to confirm {lanes} on {model}. This updates by itself.",
1193
+ purchase_approving_body: "We opened a page to confirm {model}. This updates by itself.",
1196
1194
  purchase_console_body: "Finish on the page we opened. {model} appears here as soon as it's active.",
1197
1195
  purchase_requested: "Requested. We'll activate it shortly",
1198
1196
  purchase_requested_body: "You'll get an email too. {model} appears here by itself.",
@@ -1202,10 +1200,8 @@ var en = {
1202
1200
  purchase_ready_body: "Pick it in the model picker and start.",
1203
1201
  purchase_denied: "The purchase was declined in the browser.",
1204
1202
  purchase_expired: "The confirmation page expired.",
1205
- purchase_stopped: "The lanes have stopped.",
1203
+ purchase_stopped: "The model has stopped.",
1206
1204
  purchase_failed: "The purchase didn't go through.",
1207
- lanesCount: "{count} lanes",
1208
- laneCount: "1 lane",
1209
1205
  openPage: "Open the page again",
1210
1206
  stopWaiting: "Stop waiting",
1211
1207
  startChatting: "Start a conversation",
@@ -1284,16 +1280,16 @@ var en = {
1284
1280
  n_signIn_title: "Sign in to keep going",
1285
1281
  n_signIn_body: "Your AdaptiqAI connection needs a fresh sign-in.",
1286
1282
  n_connect_body: "Connect your AdaptiqAI account to use this model.",
1287
- n_noLanes_title: "Rent a lane to continue",
1288
- n_noLanes_body: "You need to rent a lane or subscribe to AdaptiqAI to continue.",
1289
- n_laneStopped_body: "Your lane stopped because it went unused, so nothing more was charged.",
1290
- n_planUsedUp_body: "Your plan's usage is used up until {until}. Rent extra lanes in the meantime.",
1291
- n_planUsedUpNoDate_body: "Your plan's usage is used up for now. Rent extra lanes in the meantime.",
1283
+ n_noLanes_title: "Get access to continue",
1284
+ n_noLanes_body: "This model isn't in your workspace yet. You pay per token from your balance; reads from memory are free.",
1285
+ n_laneStopped_body: "The model stopped after going unused. Start it again to continue.",
1286
+ n_planUsedUp_body: "Your plan's usage is used up until {until}. Pay per token from your balance in the meantime.",
1287
+ n_planUsedUpNoDate_body: "Your plan's usage is used up for now. Pay per token from your balance in the meantime.",
1292
1288
  n_credit_title: "Add funds to continue",
1293
- n_credit_body: "Your balance ran out, so your lanes are paused.",
1294
- n_creditMinutes_body: "Your balance ran out, so your lanes are paused. Add funds within {minutes} min to keep them.",
1295
- n_busy_title: "All lanes are busy",
1296
- n_busy_body: "Your request on {model} is waiting for a free lane and will retry by itself.",
1289
+ n_credit_body: "Your balance ran out. Add funds to keep going.",
1290
+ n_creditMinutes_body: "Your balance ran out. Add funds within {minutes} min to keep your models running.",
1291
+ n_busy_title: "{model} is busy",
1292
+ n_busy_body: "Your request is waiting in line and retries by itself.",
1297
1293
  n_preparing_title: "Getting your conversation ready",
1298
1294
  n_preparing_body: "AdaptiqAI is loading this conversation's memory. It retries by itself.",
1299
1295
  n_unavailable_title: "{model} isn't available",
@@ -1332,122 +1328,6 @@ function fill(template, params = {}) {
1332
1328
  return template.replace(/\{(\w+)\}/gu, (whole, name2) => name2 in params ? String(params[name2]) : whole);
1333
1329
  }
1334
1330
 
1335
- // ../core/lib/update.js
1336
- var RELEASE_AGE_MS = 24 * 36e5;
1337
- var RELEASE_VERSION = /^\d+\.\d+\.\d+$/u;
1338
- function semverGreater(a, b) {
1339
- const parse = (value) => value.replace(/^v/u, "").split(/[.-]/u).slice(0, 3).map((part) => Number.parseInt(part, 10) || 0);
1340
- const [x, y] = [parse(a), parse(b)];
1341
- for (let i = 0; i < 3; i++)
1342
- if ((x[i] ?? 0) !== (y[i] ?? 0))
1343
- return (x[i] ?? 0) > (y[i] ?? 0);
1344
- return false;
1345
- }
1346
- var UpdateFailure = class extends Error {
1347
- code;
1348
- constructor(code, message) {
1349
- super(message);
1350
- this.code = code;
1351
- this.name = "UpdateFailure";
1352
- }
1353
- };
1354
-
1355
- // ../core/lib/usage.js
1356
- async function* parseSse(body, activity) {
1357
- const decoder = new TextDecoder();
1358
- const reader = body.getReader();
1359
- let buffer = "";
1360
- try {
1361
- while (true) {
1362
- const { value, done } = await reader.read();
1363
- if (done)
1364
- break;
1365
- activity();
1366
- buffer += decoder.decode(value, { stream: true });
1367
- let boundary = nextBoundary(buffer);
1368
- while (boundary !== null) {
1369
- const block = buffer.slice(0, boundary.index);
1370
- buffer = buffer.slice(boundary.index + boundary.length);
1371
- const event = parseBlock(block);
1372
- if (event !== null)
1373
- yield event;
1374
- boundary = nextBoundary(buffer);
1375
- }
1376
- }
1377
- buffer += decoder.decode();
1378
- const tail = parseBlock(buffer);
1379
- if (tail !== null)
1380
- yield tail;
1381
- } finally {
1382
- reader.releaseLock();
1383
- }
1384
- }
1385
- function nextBoundary(buffer) {
1386
- const match = /\r?\n\r?\n/u.exec(buffer);
1387
- return match === null ? null : { index: match.index, length: match[0].length };
1388
- }
1389
- function parseBlock(block) {
1390
- let event = null;
1391
- const data = [];
1392
- for (const line of block.split(/\r?\n/u)) {
1393
- const notice = /^: ?adaptiq-memory (.*)$/u.exec(line);
1394
- if (notice !== null) {
1395
- event = "adaptiq.memory";
1396
- data.push(notice[1]);
1397
- continue;
1398
- }
1399
- if (line === "" || line.startsWith(":"))
1400
- continue;
1401
- const colon = line.indexOf(":");
1402
- const field = colon === -1 ? line : line.slice(0, colon);
1403
- const value = colon === -1 ? "" : line.slice(colon + 1).replace(/^ /u, "");
1404
- if (field === "event")
1405
- event = value;
1406
- else if (field === "data")
1407
- data.push(value);
1408
- }
1409
- return data.length === 0 ? null : { event, data: data.join("\n") };
1410
- }
1411
- function mapUsage(raw) {
1412
- const n = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.round(value) : 0;
1413
- const details = typeof raw.prompt_tokens_details === "object" && raw.prompt_tokens_details !== null ? raw.prompt_tokens_details : {};
1414
- const completion = typeof raw.completion_tokens_details === "object" && raw.completion_tokens_details !== null ? raw.completion_tokens_details : {};
1415
- const prompt = n(raw.prompt_tokens);
1416
- const output = n(raw.completion_tokens);
1417
- const cached = Math.min(prompt, n(details.cached_tokens) || n(raw.prompt_cache_hit_tokens));
1418
- const written = Math.min(prompt - cached, n(details.cache_write_tokens) || n(raw.cache_write_tokens) || n(raw.cache_creation_input_tokens));
1419
- const reasoning2 = n(completion.reasoning_tokens);
1420
- const total = n(raw.total_tokens);
1421
- return {
1422
- inputTokens: Math.max(0, prompt - cached - written),
1423
- outputTokens: output,
1424
- ...cached > 0 ? { cacheReadTokens: cached } : {},
1425
- ...written > 0 ? { cacheWriteTokens: written } : {},
1426
- ...reasoning2 > 0 ? { reasoningTokens: reasoning2 } : {},
1427
- ...total > 0 ? { totalTokens: total } : prompt + output > 0 ? { totalTokens: prompt + output } : {}
1428
- };
1429
- }
1430
- function memoryNotice(raw) {
1431
- let value = raw;
1432
- if (typeof raw === "string") {
1433
- try {
1434
- value = JSON.parse(raw);
1435
- } catch {
1436
- return null;
1437
- }
1438
- }
1439
- if (typeof value !== "object" || value === null)
1440
- return null;
1441
- const notice = value;
1442
- if (notice.kind !== "hibernated" && notice.kind !== "suggestion")
1443
- return null;
1444
- const sessions = Array.isArray(notice.sessions) ? notice.sessions.length : 0;
1445
- if (sessions === 0)
1446
- return null;
1447
- const number = (field) => typeof field === "number" && Number.isFinite(field) && field >= 0 ? field : null;
1448
- return { kind: notice.kind, sessions, tokens: number(notice.tokens), usageRatio: number(notice.usage_ratio) };
1449
- }
1450
-
1451
1331
  // ../core/lib/workspace.js
1452
1332
  import { randomUUID as randomUUID3 } from "node:crypto";
1453
1333
 
@@ -1554,9 +1434,9 @@ var PurchaseFlow = class {
1554
1434
  }
1555
1435
  const limit = laneLimit(offer);
1556
1436
  if (limit === 0)
1557
- throw new Error(`${offer.name} has no free lanes right now. Try again later, or pick another model.`);
1437
+ throw new Error(`${offer.name} is full right now. Try again later, or pick another model.`);
1558
1438
  if (!Number.isInteger(lanes) || lanes < offer.minLanes || lanes > limit) {
1559
- throw new Error(`Choose between ${offer.minLanes} and ${limit} lanes.`);
1439
+ throw new Error(`Choose between ${offer.minLanes} and ${limit} conversations at once.`);
1560
1440
  }
1561
1441
  const base = {
1562
1442
  offerId: offer.id,
@@ -1677,6 +1557,26 @@ var PurchaseFlow = class {
1677
1557
  }
1678
1558
  };
1679
1559
 
1560
+ // ../core/lib/update.js
1561
+ var RELEASE_AGE_MS = 24 * 36e5;
1562
+ var RELEASE_VERSION = /^\d+\.\d+\.\d+$/u;
1563
+ function semverGreater(a, b) {
1564
+ const parse = (value) => value.replace(/^v/u, "").split(/[.-]/u).slice(0, 3).map((part) => Number.parseInt(part, 10) || 0);
1565
+ const [x, y] = [parse(a), parse(b)];
1566
+ for (let i = 0; i < 3; i++)
1567
+ if ((x[i] ?? 0) !== (y[i] ?? 0))
1568
+ return (x[i] ?? 0) > (y[i] ?? 0);
1569
+ return false;
1570
+ }
1571
+ var UpdateFailure = class extends Error {
1572
+ code;
1573
+ constructor(code, message) {
1574
+ super(message);
1575
+ this.code = code;
1576
+ this.name = "UpdateFailure";
1577
+ }
1578
+ };
1579
+
1680
1580
  // ../core/lib/workspace.js
1681
1581
  var obj4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
1682
1582
  var str4 = (value) => typeof value === "string" && value.trim() !== "" ? value.trim() : null;
@@ -1851,7 +1751,7 @@ function copyFailure(error, model2) {
1851
1751
  case "model_mismatch":
1852
1752
  return str4(detail.message) ?? `This collection can't be made available for ${model2}.`;
1853
1753
  case "inference_entitlement_required":
1854
- return "You need to rent a lane or subscribe to AdaptiqAI to continue.";
1754
+ return "This model isn't in your workspace yet. Get access to continue; you pay per token from your balance.";
1855
1755
  case "collection_not_found":
1856
1756
  return "This collection no longer exists.";
1857
1757
  case "sources_not_exportable":
@@ -2830,7 +2730,9 @@ var Workspace = class {
2830
2730
  /**
2831
2731
  * Whether this conversation is known to be stored on AdaptiqAI. A private
2832
2732
  * turn of a conversation that is not stored yet runs ephemeral: there is
2833
- * nothing to read back and nothing may be saved.
2733
+ * nothing to read back and nothing may be saved. While the last answer was
2734
+ * "not stored", the server is asked again: a remembered turn since may have
2735
+ * stored it, and a plugin that reports no turns would not hear of it.
2834
2736
  * @param sessionId - harness session id.
2835
2737
  * @returns true when the server has the conversation.
2836
2738
  */
@@ -2838,7 +2740,7 @@ var Workspace = class {
2838
2740
  if (sessionId2 === void 0)
2839
2741
  return false;
2840
2742
  const session = this.session(sessionId2);
2841
- if (session.remoteAt === 0 && this.deps.auth.phase() === "connected") {
2743
+ if ((session.remoteAt === 0 || !session.exists) && this.deps.auth.phase() === "connected") {
2842
2744
  await Promise.race([this.loadSession(session).catch(() => {
2843
2745
  }), new Promise((resolve2) => setTimeout(resolve2, 2500))]);
2844
2746
  }
@@ -4562,6 +4464,105 @@ var Workspace = class {
4562
4464
  }
4563
4465
  };
4564
4466
 
4467
+ // ../core/lib/tools.js
4468
+ var SOURCE_LIMIT = 6 * 1024 * 1024;
4469
+
4470
+ // ../core/lib/usage.js
4471
+ async function* parseSse(body, activity) {
4472
+ const decoder = new TextDecoder();
4473
+ const reader = body.getReader();
4474
+ let buffer = "";
4475
+ try {
4476
+ while (true) {
4477
+ const { value, done } = await reader.read();
4478
+ if (done)
4479
+ break;
4480
+ activity();
4481
+ buffer += decoder.decode(value, { stream: true });
4482
+ let boundary = nextBoundary(buffer);
4483
+ while (boundary !== null) {
4484
+ const block = buffer.slice(0, boundary.index);
4485
+ buffer = buffer.slice(boundary.index + boundary.length);
4486
+ const event = parseBlock(block);
4487
+ if (event !== null)
4488
+ yield event;
4489
+ boundary = nextBoundary(buffer);
4490
+ }
4491
+ }
4492
+ buffer += decoder.decode();
4493
+ const tail = parseBlock(buffer);
4494
+ if (tail !== null)
4495
+ yield tail;
4496
+ } finally {
4497
+ reader.releaseLock();
4498
+ }
4499
+ }
4500
+ function nextBoundary(buffer) {
4501
+ const match = /\r?\n\r?\n/u.exec(buffer);
4502
+ return match === null ? null : { index: match.index, length: match[0].length };
4503
+ }
4504
+ function parseBlock(block) {
4505
+ let event = null;
4506
+ const data = [];
4507
+ for (const line of block.split(/\r?\n/u)) {
4508
+ const notice = /^: ?adaptiq-memory (.*)$/u.exec(line);
4509
+ if (notice !== null) {
4510
+ event = "adaptiq.memory";
4511
+ data.push(notice[1]);
4512
+ continue;
4513
+ }
4514
+ if (line === "" || line.startsWith(":"))
4515
+ continue;
4516
+ const colon = line.indexOf(":");
4517
+ const field = colon === -1 ? line : line.slice(0, colon);
4518
+ const value = colon === -1 ? "" : line.slice(colon + 1).replace(/^ /u, "");
4519
+ if (field === "event")
4520
+ event = value;
4521
+ else if (field === "data")
4522
+ data.push(value);
4523
+ }
4524
+ return data.length === 0 ? null : { event, data: data.join("\n") };
4525
+ }
4526
+ function mapUsage(raw) {
4527
+ const n = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.round(value) : 0;
4528
+ const details = typeof raw.prompt_tokens_details === "object" && raw.prompt_tokens_details !== null ? raw.prompt_tokens_details : {};
4529
+ const completion = typeof raw.completion_tokens_details === "object" && raw.completion_tokens_details !== null ? raw.completion_tokens_details : {};
4530
+ const prompt = n(raw.prompt_tokens);
4531
+ const output = n(raw.completion_tokens);
4532
+ const cached = Math.min(prompt, n(details.cached_tokens) || n(raw.prompt_cache_hit_tokens));
4533
+ const written = Math.min(prompt - cached, n(details.cache_write_tokens) || n(raw.cache_write_tokens) || n(raw.cache_creation_input_tokens));
4534
+ const reasoning2 = n(completion.reasoning_tokens);
4535
+ const total = n(raw.total_tokens);
4536
+ return {
4537
+ inputTokens: Math.max(0, prompt - cached - written),
4538
+ outputTokens: output,
4539
+ ...cached > 0 ? { cacheReadTokens: cached } : {},
4540
+ ...written > 0 ? { cacheWriteTokens: written } : {},
4541
+ ...reasoning2 > 0 ? { reasoningTokens: reasoning2 } : {},
4542
+ ...total > 0 ? { totalTokens: total } : prompt + output > 0 ? { totalTokens: prompt + output } : {}
4543
+ };
4544
+ }
4545
+ function memoryNotice(raw) {
4546
+ let value = raw;
4547
+ if (typeof raw === "string") {
4548
+ try {
4549
+ value = JSON.parse(raw);
4550
+ } catch {
4551
+ return null;
4552
+ }
4553
+ }
4554
+ if (typeof value !== "object" || value === null)
4555
+ return null;
4556
+ const notice = value;
4557
+ if (notice.kind !== "hibernated" && notice.kind !== "suggestion")
4558
+ return null;
4559
+ const sessions = Array.isArray(notice.sessions) ? notice.sessions.length : 0;
4560
+ if (sessions === 0)
4561
+ return null;
4562
+ const number = (field) => typeof field === "number" && Number.isFinite(field) && field >= 0 ? field : null;
4563
+ return { kind: notice.kind, sessions, tokens: number(notice.tokens), usageRatio: number(notice.usage_ratio) };
4564
+ }
4565
+
4565
4566
  // src/host/stream.ts
4566
4567
  var REASONING_FIELDS = ["reasoning_content", "reasoning", "reasoning_text"];
4567
4568
  async function* translate(events, hooks) {
@@ -5056,7 +5057,6 @@ function resolvedInfo(route, model2) {
5056
5057
  function describe(model2) {
5057
5058
  const parts = [];
5058
5059
  if (model2.nativeMemory || (model2.contextWindow ?? 0) >= 1e6) parts.push("Native memory");
5059
- if (model2.lanes !== null) parts.push(`${model2.lanes} ${model2.lanes === 1 ? "lane" : "lanes"}`);
5060
5060
  return parts.join(" \xB7 ");
5061
5061
  }
5062
5062
  function toLlmError(failure, cause) {
@@ -5327,7 +5327,7 @@ var AdaptiqAdapter = class extends LlmAdapter {
5327
5327
 
5328
5328
  // src/host/commands.ts
5329
5329
  var HELP = [
5330
- "/adaptiq \u2014 workspace, models, lanes and memory",
5330
+ "/adaptiq \u2014 workspace, models and memory",
5331
5331
  "/adaptiq signin \u2014 connect your AdaptiqAI account in the browser",
5332
5332
  "/adaptiq private \u2014 stop saving new messages of this conversation",
5333
5333
  "/adaptiq remember \u2014 save this conversation to memory again",
@@ -5433,10 +5433,9 @@ ${HELP}`;
5433
5433
  lines.push("No models yet. Pick one in Settings \u2192 AdaptiqAI.");
5434
5434
  } else {
5435
5435
  for (const model2 of snapshot.models) {
5436
- const lanes = model2.lanes === null ? "" : ` \xB7 ${model2.lanes} ${model2.lanes === 1 ? "lane" : "lanes"}`;
5437
5436
  const live = model2.runningNow === null ? "" : ` (${model2.runningNow} running, ${model2.waitingNow ?? 0} waiting)`;
5438
5437
  const window = model2.contextWindow === null ? "" : ` \xB7 ${formatTokens(model2.contextWindow)} context`;
5439
- lines.push(`\u2022 ${model2.name}${window}${lanes}${live}${model2.status === "offline" ? " \xB7 offline" : ""}`);
5438
+ lines.push(`\u2022 ${model2.name}${window}${live}${model2.status === "offline" ? " \xB7 offline" : ""}`);
5440
5439
  }
5441
5440
  }
5442
5441
  if (memory?.available === true && memory.conversationsTokens !== null) {
@@ -5770,7 +5769,7 @@ var render = (_args, value) => {
5770
5769
  return [{ type: "text", text: typeof text2 === "string" ? text2 : JSON.stringify(value) }];
5771
5770
  };
5772
5771
  var say2 = (result) => ({ result });
5773
- var SOURCE_LIMIT = 6 * 1024 * 1024;
5772
+ var SOURCE_LIMIT2 = 6 * 1024 * 1024;
5774
5773
  var MEDIA = {
5775
5774
  ".pdf": "application/pdf",
5776
5775
  ".txt": "text/plain",
@@ -6027,7 +6026,7 @@ ${content}`);
6027
6026
  const info = await stat(path);
6028
6027
  if (!info.isFile()) fail(`${raw} is not a file.`);
6029
6028
  bytes += info.size;
6030
- if (bytes > SOURCE_LIMIT) fail("These files are too large for one request. Use fewer or smaller files, or a repository link.");
6029
+ if (bytes > SOURCE_LIMIT2) fail("These files are too large for one request. Use fewer or smaller files, or a repository link.");
6031
6030
  const content = await readFile2(path);
6032
6031
  files.push({ name: source.name ?? basename(path), mediaType: mediaTypeOf(path), contentBase64: content.toString("base64") });
6033
6032
  } else {
@@ -6273,7 +6272,7 @@ Open **Settings \u2192 AdaptiqAI** to connect, or run \`/adaptiq signin\`.
6273
6272
  var ENTRY_PROTOCOL = 1;
6274
6273
  var RELOAD_SIGNATURE = true ? "ada3dfffa1b3d7b1" : "source";
6275
6274
  function pluginVersion() {
6276
- if (true) return "0.2.13";
6275
+ if (true) return "0.2.14";
6277
6276
  try {
6278
6277
  return createRequire(import.meta.url)("../package.json").version;
6279
6278
  } catch {
@@ -30,7 +30,7 @@ export declare function MemoryCallout({ store, t }: {
30
30
  * memory, thinking levels, region. A field is left out only when unknown.
31
31
  */
32
32
  export declare function modelFacts(model: ModelView, t: T): string;
33
- /** One model row: name, facts, lanes, status. */
33
+ /** One model row: name, facts, status. */
34
34
  export declare function ModelRow({ model, t }: {
35
35
  model: ModelView;
36
36
  t: T;
@@ -9,7 +9,7 @@ export declare const COUNT_UP_MS = 900;
9
9
  * The pill's words while a request waits.
10
10
  * @param t - translate.
11
11
  * @param kind - what the request waits for.
12
- * @returns e.g. "Waiting for a free lane".
12
+ * @returns e.g. "Waiting in line".
13
13
  */
14
14
  export declare function waitText(t: T, kind: WaitKind): string;
15
15
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptiqai/deepseek-harness",
3
- "version": "0.2.13",
3
+ "version": "0.2.14",
4
4
  "description": "AdaptiqAI for DeepSeek Harness: models with 5M-token native memory and Knowledge. Sign up, get a model and work without leaving the harness",
5
5
  "keywords": [
6
6
  "dsh-plugin",
@@ -90,7 +90,7 @@
90
90
  "react-dom": "~18.3.1",
91
91
  "typescript": "~5.9.3",
92
92
  "vitest": "~3.2.7",
93
- "@adaptiqai/core": "0.2.9"
93
+ "@adaptiqai/core": "0.2.10"
94
94
  },
95
95
  "repository": {
96
96
  "type": "git",