@adaptiqai/mcp 0.1.0 → 0.1.1

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adaptiqai",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "AdaptiqAI's knowledge and memory tools in Claude Code: search, use and save your collections in the conversation you are in.",
5
5
  "author": {
6
6
  "name": "AdaptiqAI",
package/lib/index.js CHANGED
@@ -100,7 +100,7 @@ function classifyFailure(status2, raw, headers, model2, options = {}) {
100
100
  if (effective === 503 && detail.code !== null && MODEL_OFFLINE_CODES.includes(detail.code)) {
101
101
  return make(CODES.server, `${model2 ?? "This model"} is offline right now. It will retry automatically.`, "retrying");
102
102
  }
103
- if (has(detail, "AdaptiqNativePreflightBusy", "session_route_unavailable", "conversation_preparing", "preparing", "upload_capacity_exhausted") || effective === 503 && !has(detail, "offline")) {
103
+ if (has(detail, "AdaptiqNativePreflightBusy", "session_route_unavailable", "conversation_preparing", "preparing", "upload_capacity_exhausted", "AdaptiqMemoryNotReady") || effective === 425 || effective === 503 && !has(detail, "offline")) {
104
104
  return make(CODES.preparing, "AdaptiqAI is getting your conversation ready. It will retry automatically.", "preparing");
105
105
  }
106
106
  if (effective === 409 && has(detail, "AdaptiqNativePreflight", "conversation")) {
@@ -317,6 +317,91 @@ function detailMessage(raw) {
317
317
  }
318
318
  return null;
319
319
  }
320
+ var EXPIRED = "The sign-in link expired. Start again.";
321
+ async function startDeviceCode(client, request) {
322
+ let response;
323
+ try {
324
+ response = await client.fetch(`${client.apiBase}/v1/cli-auth/device`, {
325
+ method: "POST",
326
+ headers: { "content-type": "application/json", accept: "application/json" },
327
+ body: JSON.stringify({
328
+ client_app: request.app,
329
+ client_name: request.app,
330
+ device_name: request.device,
331
+ client_binding: request.binding,
332
+ ...request.tokenLifetime === void 0 ? {} : { token_lifetime: request.tokenLifetime }
333
+ }),
334
+ signal: client.signal === void 0 ? AbortSignal.timeout(2e4) : AbortSignal.any([client.signal, AbortSignal.timeout(2e4)]),
335
+ redirect: "error"
336
+ });
337
+ } catch (error) {
338
+ if (client.signal?.aborted === true)
339
+ throw error;
340
+ throw new Error(UNREACHABLE, { cause: error });
341
+ }
342
+ if (!response.ok) {
343
+ const message = detailMessage(await readJson(response));
344
+ if (response.status >= 500)
345
+ throw new Error("AdaptiqAI isn't answering right now. Try again in a minute.");
346
+ throw new Error(message ?? `AdaptiqAI sign-in could not start (HTTP ${response.status}).`);
347
+ }
348
+ const body = await readJson(response);
349
+ const deviceCode = String(body?.device_code ?? "");
350
+ const userCode = String(body?.user_code ?? "");
351
+ const url = String(body?.verification_uri_complete ?? body?.verification_uri ?? "");
352
+ if (deviceCode === "" || userCode === "" || !/^https?:\/\//u.test(url))
353
+ throw new Error("AdaptiqAI returned an incomplete sign-in.");
354
+ return {
355
+ deviceCode,
356
+ userCode,
357
+ url,
358
+ expiresAt: client.now() + Math.min(DEVICE_TIMEOUT_MS, Math.max(60, Number(body?.expires_in ?? 600)) * 1e3),
359
+ interval: Math.max(1, Number(body?.interval ?? 2)) * 1e3
360
+ };
361
+ }
362
+ async function pollDeviceCode(client, code, extra = {}) {
363
+ let response;
364
+ try {
365
+ response = await client.fetch(`${client.apiBase}/v1/cli-auth/device/token`, {
366
+ method: "POST",
367
+ headers: { "content-type": "application/json", accept: "application/json" },
368
+ body: JSON.stringify({ ...extra, device_code: code.deviceCode }),
369
+ signal: client.signal === void 0 ? AbortSignal.timeout(2e4) : AbortSignal.any([client.signal, AbortSignal.timeout(2e4)]),
370
+ redirect: "error"
371
+ });
372
+ } catch {
373
+ return { state: "waiting", delayMs: code.interval * 2 };
374
+ }
375
+ if (response.status === 202)
376
+ return { state: "waiting", delayMs: code.interval };
377
+ if (response.status === 429) {
378
+ const retry = Number(response.headers.get("retry-after") ?? 0) * 1e3;
379
+ return { state: "waiting", delayMs: Math.max(code.interval, retry) + 250 };
380
+ }
381
+ if (response.status === 403) {
382
+ const raw = await readJson(response);
383
+ return { state: "denied", message: detailCode(raw) === "access_denied" ? "The connection was declined in the browser." : detailMessage(raw) ?? "The connection was declined." };
384
+ }
385
+ if (response.status === 410 || response.status === 404)
386
+ return { state: "expired", message: EXPIRED };
387
+ if (!response.ok) {
388
+ if (response.status >= 500)
389
+ return { state: "waiting", delayMs: code.interval * 2 };
390
+ return { state: "failed", message: detailMessage(await readJson(response)) ?? `Sign-in failed (HTTP ${response.status}).` };
391
+ }
392
+ const body = await readJson(response);
393
+ const access = String(body?.access_token ?? "");
394
+ const refresh = String(body?.refresh_token ?? "");
395
+ if (!access.startsWith("ak_") || refresh !== "" && !refresh.startsWith("akr_"))
396
+ return { state: "failed", message: "AdaptiqAI returned an invalid credential." };
397
+ return {
398
+ state: "approved",
399
+ access,
400
+ refresh: refresh === "" ? null : refresh,
401
+ expiresIn: Math.max(60, Number(body?.expires_in ?? 3600)),
402
+ workspaceLabel: typeof body?.workspace_label === "string" && body.workspace_label !== "" ? body.workspace_label : "Your workspace"
403
+ };
404
+ }
320
405
  var AuthManager = class {
321
406
  options;
322
407
  fetch;
@@ -359,6 +444,9 @@ var AuthManager = class {
359
444
  this.state = phase;
360
445
  this.options.onChange?.();
361
446
  }
447
+ client(signal) {
448
+ return { apiBase: this.options.apiBase, fetch: this.fetch, now: this.now, signal };
449
+ }
362
450
  /** Read the stored state once at startup. */
363
451
  async init() {
364
452
  const stored = await this.options.store.read();
@@ -492,39 +580,11 @@ var AuthManager = class {
492
580
  const clientProof = `${randomUUID()}${randomUUID()}`;
493
581
  const binding = createHash("sha256").update(clientProof).digest("hex");
494
582
  const app = this.options.appName ?? "DeepSeek Harness";
495
- let response;
496
- try {
497
- response = await this.fetch(`${this.options.apiBase}/v1/cli-auth/device`, {
498
- method: "POST",
499
- headers: { "content-type": "application/json", accept: "application/json" },
500
- body: JSON.stringify({
501
- client_app: app,
502
- client_name: app,
503
- device_name: deviceLabel(this.options.deviceName ?? hostname()),
504
- client_binding: binding
505
- }),
506
- signal: AbortSignal.any([flow.signal, AbortSignal.timeout(2e4)]),
507
- redirect: "error"
508
- });
509
- } catch (error) {
510
- if (flow.signal.aborted)
511
- throw error;
512
- throw new Error(UNREACHABLE, { cause: error });
513
- }
514
- if (!response.ok) {
515
- const message = detailMessage(await readJson(response));
516
- if (response.status >= 500)
517
- throw new Error("AdaptiqAI isn't answering right now. Try again in a minute.");
518
- throw new Error(message ?? `AdaptiqAI sign-in could not start (HTTP ${response.status}).`);
519
- }
520
- const body = await readJson(response);
521
- const deviceCode = String(body?.device_code ?? "");
522
- const userCode = String(body?.user_code ?? "");
523
- const url = String(body?.verification_uri_complete ?? body?.verification_uri ?? "");
524
- if (deviceCode === "" || userCode === "" || !/^https?:\/\//u.test(url))
525
- throw new Error("AdaptiqAI returned an incomplete sign-in.");
526
- const expiresAt = this.now() + Math.min(DEVICE_TIMEOUT_MS, Math.max(60, Number(body?.expires_in ?? 600)) * 1e3);
527
- const interval = Math.max(1, Number(body?.interval ?? 2)) * 1e3;
583
+ const { deviceCode, userCode, url, expiresAt, interval } = await startDeviceCode(this.client(flow.signal), {
584
+ app,
585
+ device: deviceLabel(this.options.deviceName ?? hostname()),
586
+ binding
587
+ });
528
588
  this.pendingSignIn = { url, userCode, expiresAt };
529
589
  this.set("signing-in");
530
590
  void this.poll(flow, deviceCode, clientProof, interval, expiresAt);
@@ -536,61 +596,27 @@ var AuthManager = class {
536
596
  while (this.now() < expiresAt) {
537
597
  await this.sleep(delay, flow.signal);
538
598
  delay = interval;
539
- let response;
540
- try {
541
- response = await this.fetch(`${this.options.apiBase}/v1/cli-auth/device/token`, {
542
- method: "POST",
543
- headers: { "content-type": "application/json", accept: "application/json" },
544
- body: JSON.stringify({ device_code: deviceCode }),
545
- signal: AbortSignal.any([flow.signal, AbortSignal.timeout(2e4)]),
546
- redirect: "error"
547
- });
548
- } catch {
549
- if (flow.signal.aborted)
550
- return;
551
- delay = interval * 2;
552
- continue;
553
- }
554
- if (response.status === 202)
555
- continue;
556
- if (response.status === 429) {
557
- const retry = Number(response.headers.get("retry-after") ?? 0) * 1e3;
558
- delay = Math.max(interval, retry) + 250;
599
+ const answer2 = await pollDeviceCode(this.client(flow.signal), { deviceCode, interval });
600
+ if (answer2.state === "waiting") {
601
+ delay = answer2.delayMs;
559
602
  continue;
560
603
  }
561
- if (response.status === 403) {
562
- const raw = await readJson(response);
563
- this.fail(flow, { code: "denied", message: detailCode(raw) === "access_denied" ? "The connection was declined in the browser." : detailMessage(raw) ?? "The connection was declined." });
604
+ if (answer2.state !== "approved") {
605
+ this.fail(flow, { code: answer2.state, message: answer2.message });
564
606
  return;
565
607
  }
566
- if (response.status === 410 || response.status === 404) {
567
- this.fail(flow, { code: "expired", message: "The sign-in link expired. Start again." });
568
- return;
569
- }
570
- if (!response.ok) {
571
- if (response.status >= 500) {
572
- delay = interval * 2;
573
- continue;
574
- }
575
- this.fail(flow, { code: "failed", message: detailMessage(await readJson(response)) ?? `Sign-in failed (HTTP ${response.status}).` });
576
- return;
577
- }
578
- const body = await readJson(response);
579
- const access = String(body?.access_token ?? "");
580
- const refresh = String(body?.refresh_token ?? "");
581
- if (!access.startsWith("ak_") || !refresh.startsWith("akr_")) {
608
+ if (answer2.refresh === null) {
582
609
  this.fail(flow, { code: "failed", message: "AdaptiqAI returned an invalid credential." });
583
610
  return;
584
611
  }
585
- const workspaceLabel = typeof body?.workspace_label === "string" && body.workspace_label !== "" ? body.workspace_label : "Your workspace";
586
612
  const grant = {
587
613
  schema: "adaptiq-dsh-grant-v1",
588
614
  apiBase: this.options.apiBase,
589
- access,
590
- refresh,
615
+ access: answer2.access,
616
+ refresh: answer2.refresh,
591
617
  clientProof,
592
- expiresAt: this.now() + Math.max(60, Number(body?.expires_in ?? 3600)) * 1e3,
593
- workspaceLabel,
618
+ expiresAt: this.now() + answer2.expiresIn * 1e3,
619
+ workspaceLabel: answer2.workspaceLabel,
594
620
  obtainedAt: this.now()
595
621
  };
596
622
  await this.options.store.modify(async () => grant);
@@ -599,12 +625,12 @@ var AuthManager = class {
599
625
  this.flow = null;
600
626
  this.pendingSignIn = null;
601
627
  this.source = "device";
602
- this.label = workspaceLabel;
628
+ this.label = answer2.workspaceLabel;
603
629
  this.set("connected");
604
- this.options.onSignedIn?.(workspaceLabel);
630
+ this.options.onSignedIn?.(answer2.workspaceLabel);
605
631
  return;
606
632
  }
607
- this.fail(flow, { code: "expired", message: "The sign-in link expired. Start again." });
633
+ this.fail(flow, { code: "expired", message: EXPIRED });
608
634
  } catch (error) {
609
635
  if (flow.signal.aborted)
610
636
  return;
@@ -729,6 +755,20 @@ var obj = (value) => typeof value === "object" && value !== null && !Array.isArr
729
755
  var str = (value) => typeof value === "string" && value.trim() !== "" ? value.trim() : null;
730
756
  var num = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : null;
731
757
  var count = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
758
+ function pricesFromRow(raw) {
759
+ const pricing = obj(raw);
760
+ const price = (value) => {
761
+ const parsed = typeof value === "string" && value.trim() !== "" ? Number(value) : typeof value === "number" ? value : Number.NaN;
762
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : null;
763
+ };
764
+ const input = price(pricing?.prompt);
765
+ const memoryWrite = price(pricing?.input_cache_write);
766
+ const memoryRead = price(pricing?.input_cache_read);
767
+ const output = price(pricing?.completion);
768
+ if (input === null || memoryWrite === null || memoryRead === null || output === null)
769
+ return null;
770
+ return { input, memoryWrite, memoryRead, output };
771
+ }
732
772
  var LEVEL_NAMES = {
733
773
  off: "Off",
734
774
  minimal: "Minimal",
@@ -817,17 +857,17 @@ function placementsFromRoutes(routes) {
817
857
  const model2 = str(route?.model);
818
858
  if (route === null || model2 === null || route.enabled !== true)
819
859
  continue;
820
- const add = (a, b) => a === null ? b : b === null ? a : a + b;
860
+ const add2 = (a, b) => a === null ? b : b === null ? a : a + b;
821
861
  const current = out.get(model2);
822
862
  const running = count(route.running);
823
863
  const waiting = count(route.waiting);
824
864
  out.set(model2, {
825
865
  name: current?.name ?? (str(route.name) !== null ? routeModelName(str(route.name)) : null),
826
866
  status: "running",
827
- lanes: add(current?.lanes ?? null, count(route.lanes)),
828
- maxParallel: add(current?.maxParallel ?? null, count(route.max_parallel_agents)),
829
- runningNow: add(current?.runningNow ?? null, running),
830
- waitingNow: add(current?.waitingNow ?? null, waiting),
867
+ lanes: add2(current?.lanes ?? null, count(route.lanes)),
868
+ maxParallel: add2(current?.maxParallel ?? null, count(route.max_parallel_agents)),
869
+ runningNow: add2(current?.runningNow ?? null, running),
870
+ waitingNow: add2(current?.waitingNow ?? null, waiting),
831
871
  region: current?.region ?? str(route.region),
832
872
  card: null,
833
873
  contextWindow: null,
@@ -888,7 +928,8 @@ function model(id, row, placement) {
888
928
  maxParallel: placement?.maxParallel ?? count(gateway?.max_parallel_agents),
889
929
  runningNow: placement?.runningNow ?? null,
890
930
  waitingNow: placement?.waitingNow ?? null,
891
- region: placement?.region ?? str(gateway?.region)
931
+ region: placement?.region ?? str(gateway?.region),
932
+ prices: pricesFromRow(row?.pricing)
892
933
  };
893
934
  }
894
935
  function selectableLevels(reasoning) {
@@ -948,6 +989,60 @@ function laneLimit(offer) {
948
989
  return free < offer.minLanes ? 0 : Math.min(offer.maxLanes, free);
949
990
  }
950
991
 
992
+ // ../core/lib/processed.js
993
+ var NOTHING_PROCESSED = { requests: 0, newInput: 0, fromMemory: 0, written: 0, output: 0, reasoning: 0, costUsd: 0 };
994
+ function stepCost(usage, prices) {
995
+ if (prices === null)
996
+ return null;
997
+ return usage.inputTokens * prices.input + (usage.cacheWriteTokens ?? 0) * prices.memoryWrite + (usage.cacheReadTokens ?? 0) * prices.memoryRead + usage.outputTokens * prices.output;
998
+ }
999
+ function add(view, step) {
1000
+ return {
1001
+ requests: view.requests + 1,
1002
+ newInput: view.newInput + step.usage.inputTokens,
1003
+ fromMemory: view.fromMemory + (step.usage.cacheReadTokens ?? 0),
1004
+ written: view.written + (step.usage.cacheWriteTokens ?? 0),
1005
+ output: view.output + step.usage.outputTokens,
1006
+ reasoning: view.reasoning + (step.usage.reasoningTokens ?? 0),
1007
+ costUsd: view.costUsd === null || step.costUsd === null ? null : view.costUsd + step.costUsd
1008
+ };
1009
+ }
1010
+ function addStep(record, step, now) {
1011
+ const turnKey = step.turn ?? record?.turnKey ?? null;
1012
+ const fresh = record == null || step.turn !== void 0 && step.turn !== record.turnKey;
1013
+ return {
1014
+ since: record?.since ?? now,
1015
+ at: now,
1016
+ turnKey,
1017
+ turn: add(fresh ? NOTHING_PROCESSED : record.turn, step),
1018
+ session: add(record?.session ?? NOTHING_PROCESSED, step)
1019
+ };
1020
+ }
1021
+ function readProcessed(raw) {
1022
+ const record = typeof raw === "object" && raw !== null ? raw : null;
1023
+ const view = (value) => {
1024
+ const fields = typeof value === "object" && value !== null ? value : null;
1025
+ if (fields === null)
1026
+ return null;
1027
+ const count3 = (name) => {
1028
+ const field = fields[name];
1029
+ return typeof field === "number" && Number.isFinite(field) && field >= 0 ? field : null;
1030
+ };
1031
+ const numbers = { requests: count3("requests"), newInput: count3("newInput"), fromMemory: count3("fromMemory"), written: count3("written"), output: count3("output"), reasoning: count3("reasoning") };
1032
+ if (Object.values(numbers).some((value2) => value2 === null))
1033
+ return null;
1034
+ return { ...numbers, costUsd: count3("costUsd") };
1035
+ };
1036
+ const turn = view(record?.turn);
1037
+ const session = view(record?.session);
1038
+ const since = record?.since;
1039
+ const at = record?.at;
1040
+ if (turn === null || session === null || typeof since !== "number" || typeof at !== "number")
1041
+ return null;
1042
+ const turnKey = typeof record?.turnKey === "number" ? record.turnKey : null;
1043
+ return { since, at, turnKey, turn, session };
1044
+ }
1045
+
951
1046
  // ../core/lib/strings.js
952
1047
  var en = {
953
1048
  brand: "AdaptiqAI",
@@ -1019,6 +1114,22 @@ var en = {
1019
1114
  popKnowledge: "Knowledge",
1020
1115
  addKnowledge: "Add knowledge",
1021
1116
  popWorkspace: "All memory on {model}",
1117
+ popSeesNow: "What the model sees now",
1118
+ procTitle: "Processed",
1119
+ procTurn: "Last turn",
1120
+ procSession: "This conversation",
1121
+ procSteps: "{count} steps",
1122
+ procStepsOne: "1 step",
1123
+ procNewInput: "New input",
1124
+ procFromMemory: "Read from memory",
1125
+ procWritten: "Saved to memory",
1126
+ procOutput: "Output",
1127
+ procThinking: "Thinking, part of output",
1128
+ procCost: "Cost",
1129
+ procExplain: "Each step reads the whole memory again. {percent} came from memory.",
1130
+ procExplainFree: "Each step reads the whole memory again. {percent} came from memory, which is free.",
1131
+ procExplainCheaper: "Each step reads the whole memory again. {percent} came from memory, at a fraction of the input price.",
1132
+ procSince: "Counted on this computer since {date}",
1022
1133
  openInKnowledge: "Open in Knowledge",
1023
1134
  kTitle: "Knowledge",
1024
1135
  kSearch: "Search your knowledge",
@@ -1503,6 +1614,21 @@ function button(id, label, extra = {}) {
1503
1614
  return { id, label: en[label], labelKey: label, ...extra };
1504
1615
  }
1505
1616
  var count2 = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
1617
+ var PROCESSED_SAVE_MS = 2e3;
1618
+ function savedProcessed(raw) {
1619
+ const out = {};
1620
+ if (typeof raw !== "object" || raw === null)
1621
+ return out;
1622
+ for (const [id, value] of Object.entries(raw)) {
1623
+ const record = readProcessed(value);
1624
+ if (record !== null)
1625
+ out[id] = record;
1626
+ }
1627
+ return out;
1628
+ }
1629
+ function processedSummary(record) {
1630
+ return record === void 0 ? null : { turn: record.turn, session: record.session, since: record.since };
1631
+ }
1506
1632
  var PRIVATE_HELD = "A private conversation is not kept on AdaptiqAI, so it can't use this before it exists there. Turn Remember on for this conversation to add it.";
1507
1633
  var ATTACH_TRIES = 3;
1508
1634
  function transient(error) {
@@ -1868,6 +1994,7 @@ var Workspace = class {
1868
1994
  listeners = /* @__PURE__ */ new Set();
1869
1995
  state = { preferences: DEFAULT_PREFERENCES, sessions: {} };
1870
1996
  saving = Promise.resolve();
1997
+ persistTimer;
1871
1998
  refreshing = null;
1872
1999
  timer;
1873
2000
  pendingAttach = /* @__PURE__ */ new Map();
@@ -1927,7 +2054,8 @@ var Workspace = class {
1927
2054
  preferences: { ...DEFAULT_PREFERENCES, ...saved.preferences },
1928
2055
  sessions: typeof saved.sessions === "object" && saved.sessions !== null ? saved.sessions : {},
1929
2056
  purchase: saved.purchase ?? null,
1930
- ...saved.defaultModel === "pending" || saved.defaultModel === "done" ? { defaultModel: saved.defaultModel } : {}
2057
+ ...saved.defaultModel === "pending" || saved.defaultModel === "done" ? { defaultModel: saved.defaultModel } : {},
2058
+ processed: savedProcessed(saved.processed)
1931
2059
  };
1932
2060
  this.purchases.restore(saved.purchase);
1933
2061
  }
@@ -1943,6 +2071,10 @@ var Workspace = class {
1943
2071
  this.purchases.dispose();
1944
2072
  clearTimeout(this.timer);
1945
2073
  clearTimeout(this.attachTimer);
2074
+ if (this.persistTimer !== void 0) {
2075
+ clearTimeout(this.persistTimer);
2076
+ void this.persist();
2077
+ }
1946
2078
  for (const session of this.sessions.values()) {
1947
2079
  clearTimeout(session.timer);
1948
2080
  clearTimeout(session.waitTimer);
@@ -2010,7 +2142,8 @@ var Workspace = class {
2010
2142
  region: model2.region,
2011
2143
  nativeMemory: model2.nativeMemory,
2012
2144
  tools: model2.tools,
2013
- memory: this.modelMemory.get(model2.id) ?? null
2145
+ memory: this.modelMemory.get(model2.id) ?? null,
2146
+ prices: model2.prices
2014
2147
  };
2015
2148
  }
2016
2149
  /**
@@ -2620,12 +2753,16 @@ var Workspace = class {
2620
2753
  return next;
2621
2754
  }
2622
2755
  async persist() {
2756
+ clearTimeout(this.persistTimer);
2757
+ this.persistTimer = void 0;
2623
2758
  const entries = Object.entries(this.state.sessions).sort((a, b) => b[1].at - a[1].at).slice(0, 500);
2759
+ const processed = Object.entries(this.state.processed ?? {}).sort((a, b) => b[1].at - a[1].at).slice(0, 500);
2624
2760
  const snapshot = {
2625
2761
  preferences: this.state.preferences,
2626
2762
  sessions: Object.fromEntries(entries),
2627
2763
  purchase: this.state.purchase ?? null,
2628
- ...this.state.defaultModel === void 0 ? {} : { defaultModel: this.state.defaultModel }
2764
+ ...this.state.defaultModel === void 0 ? {} : { defaultModel: this.state.defaultModel },
2765
+ ...processed.length === 0 ? {} : { processed: Object.fromEntries(processed) }
2629
2766
  };
2630
2767
  this.saving = this.saving.then(() => this.deps.store.save(snapshot)).catch((error) => {
2631
2768
  this.deps.log?.("warn", `adaptiq: could not save preferences: ${String(error)}`);
@@ -2736,6 +2873,7 @@ var Workspace = class {
2736
2873
  saved: session.saved,
2737
2874
  optimizing: session.optimizing,
2738
2875
  lastTurn: session.lastTurn,
2876
+ processed: processedSummary(this.state.processed?.[id]),
2739
2877
  knowledge: [...session.knowledge, ...[...session.pendingKnowledge.values()].filter((item) => !session.knowledge.some((entry) => entry.id === item.id))],
2740
2878
  conversations: [...session.conversations, ...[...session.pendingConversations.values()].filter((item) => !session.conversations.some((entry) => entry.id === item.id))],
2741
2879
  known: session.exists,
@@ -3115,10 +3253,19 @@ var Workspace = class {
3115
3253
  this.setPhase(session, "responding");
3116
3254
  this.clearNotices("busy", "preparing", "offline", "retrying");
3117
3255
  }
3118
- usage(sessionId, model2, usage) {
3256
+ usage(sessionId, model2, usage, step = {}) {
3119
3257
  if (sessionId === void 0)
3120
3258
  return;
3121
3259
  const session = this.session(sessionId);
3260
+ const costUsd = step.costUsd ?? stepCost(usage, this.catalog.find((entry) => entry.id === model2)?.prices ?? null);
3261
+ const counted = addStep(this.state.processed?.[sessionId], { usage, costUsd, ...step.turn === void 0 ? {} : { turn: step.turn } }, this.now());
3262
+ this.state = { ...this.state, processed: { ...this.state.processed, [sessionId]: counted } };
3263
+ if (this.persistTimer === void 0) {
3264
+ this.persistTimer = setTimeout(() => {
3265
+ void this.persist();
3266
+ }, PROCESSED_SAVE_MS);
3267
+ this.persistTimer.unref?.();
3268
+ }
3122
3269
  session.lastTurn = {
3123
3270
  fromMemory: usage.cacheReadTokens ?? 0,
3124
3271
  newInput: usage.inputTokens,
@@ -4877,7 +5024,7 @@ function claudeCode(options) {
4877
5024
  };
4878
5025
  const recent = async (at) => {
4879
5026
  const found = [];
4880
- const add = async (path, chat, agent) => {
5027
+ const add2 = async (path, chat, agent) => {
4881
5028
  const info = await stat2(path).catch(() => null);
4882
5029
  if (info !== null && Date.now() - info.mtimeMs < RECENT_MS) found.push({ path, chat, ...agent === void 0 ? {} : { agent }, mtime: info.mtimeMs });
4883
5030
  };
@@ -4885,11 +5032,11 @@ function claudeCode(options) {
4885
5032
  await Promise.all((await readdir(dir, { withFileTypes: true }).catch(() => [])).map(async (entry) => {
4886
5033
  const agent = /^agent-(.+)\.jsonl$/u.exec(entry.name)?.[1];
4887
5034
  if (entry.isDirectory() && depth < AGENT_DEPTH) await agents(join(dir, entry.name), chat, depth + 1);
4888
- else if (entry.isFile() && agent !== void 0) await add(join(dir, entry.name), chat, agent);
5035
+ else if (entry.isFile() && agent !== void 0) await add2(join(dir, entry.name), chat, agent);
4889
5036
  }));
4890
5037
  };
4891
5038
  await Promise.all((await readdir(at, { withFileTypes: true }).catch(() => [])).map(async (entry) => {
4892
- if (entry.isFile() && entry.name.endsWith(".jsonl")) await add(join(at, entry.name), entry.name.slice(0, -".jsonl".length));
5039
+ if (entry.isFile() && entry.name.endsWith(".jsonl")) await add2(join(at, entry.name), entry.name.slice(0, -".jsonl".length));
4893
5040
  else if (entry.isDirectory()) await agents(join(at, entry.name, "subagents"), entry.name, 0);
4894
5041
  }));
4895
5042
  return found.sort((a, b) => b.mtime - a.mtime);
@@ -5196,7 +5343,7 @@ function fileStateStore(dir) {
5196
5343
  }
5197
5344
 
5198
5345
  // src/index.ts
5199
- var VERSION = true ? "0.1.0" : "0.0.0";
5346
+ var VERSION = true ? "0.1.1" : "0.0.0";
5200
5347
  var PROTOCOLS = ["2025-11-25", "2025-06-18", "2025-03-26", "2024-11-05"];
5201
5348
  var WORDS = {
5202
5349
  signIn: "a terminal with `npx -y @adaptiqai/mcp login`",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptiqai/mcp",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "AdaptiqAI for Claude Code, Cline and any MCP app: your saved knowledge and this conversation's memory, as tools for the agent.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -37,7 +37,7 @@
37
37
  "esbuild": "~0.25.12",
38
38
  "typescript": "~5.9.3",
39
39
  "vitest": "~3.2.7",
40
- "@adaptiqai/core": "0.2.10"
40
+ "@adaptiqai/core": "0.2.11"
41
41
  },
42
42
  "scripts": {
43
43
  "build": "node scripts/build.mjs",