blun-king-cli 9.1.611 → 9.1.613

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/blun.mjs CHANGED
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
- // BLUN_BUILD_INPUT_SHA256:0533ca113dc07cc119988be5e76555dec986b6881903f8e2b537f5adf96cc2c5
2
+ // BLUN_BUILD_INPUT_SHA256:5c7277a864ffcc0a6909494ad5ada6956f900fe23735200c5aca26b1e7d78834
3
3
  import { fileURLToPath as __cjsShimFileURLToPath } from 'node:url';
4
4
  import { dirname as __cjsShimDirname } from 'node:path';
5
5
  const __filename = __cjsShimFileURLToPath(import.meta.url);
6
6
  const __dirname = __cjsShimDirname(__filename);
7
7
  import { createRequire } from "node:module";
8
- import crypto$1, { createHash, randomBytes, randomInt, randomUUID, timingSafeEqual } from "node:crypto";
9
- import * as fs$16 from "node:fs";
8
+ import crypto$1, { createHash, createHmac, randomBytes, randomInt, randomUUID, timingSafeEqual } from "node:crypto";
9
+ import * as fs$17 from "node:fs";
10
10
  import Kt, { accessSync, appendFileSync, chmodSync, closeSync, constants, copyFileSync, createReadStream, createWriteStream, existsSync, fstatSync, fsyncSync, linkSync, lstatSync, mkdirSync, openSync, opendirSync, promises, readFileSync, readSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
11
11
  import * as path$17 from "node:path";
12
12
  import path, { basename, dirname, extname, isAbsolute, join, normalize, parse, posix, relative, resolve, sep, win32 } from "node:path";
13
13
  import { Blob as Blob$1, Buffer as Buffer$1, File as File$1 } from "node:buffer";
14
- import ro, { access, appendFile, chmod, constants as constants$1, copyFile, cp, link, lstat, mkdir, mkdtemp, open, readFile, readdir, readlink, realpath, rename, rm, rmdir, stat, unlink, writeFile } from "node:fs/promises";
14
+ import fs, { access, appendFile, chmod, constants as constants$1, copyFile, cp, link, lstat, mkdir, mkdtemp, open, readFile, readdir, readlink, realpath, rename, rm, rmdir, stat, unlink, writeFile } from "node:fs/promises";
15
15
  import * as nodeOs from "node:os";
16
16
  import os, { arch, homedir, hostname, networkInterfaces, platform, release, tmpdir, type, userInfo } from "node:os";
17
17
  import { execFile, execFileSync, execSync, spawn, spawnSync } from "node:child_process";
@@ -1211,7 +1211,7 @@ function normalizeBlunToolSchema(schema) {
1211
1211
  }
1212
1212
  function ensureBlunPropertyTypes(schema) {
1213
1213
  const normalized = cloneJsonValue(schema);
1214
- if (!isRecord$29(normalized)) throw new Error("JSON Schema root must normalize to an object.");
1214
+ if (!isRecord$33(normalized)) throw new Error("JSON Schema root must normalize to an object.");
1215
1215
  recurseSchema(normalized);
1216
1216
  return normalized;
1217
1217
  }
@@ -1272,7 +1272,7 @@ function resolveLocalJsonPointer(root, ref) {
1272
1272
  let current = root;
1273
1273
  for (const rawPart of ref.slice(2).split("/")) {
1274
1274
  const part = unescapeJsonPointerPart(rawPart);
1275
- if (isRecord$29(current)) {
1275
+ if (isRecord$33(current)) {
1276
1276
  if (!hasOwn(current, part)) return { found: false };
1277
1277
  current = current[part];
1278
1278
  } else if (Array.isArray(current)) {
@@ -1294,20 +1294,20 @@ function parseJsonPointerArrayIndex(part) {
1294
1294
  return Number(part);
1295
1295
  }
1296
1296
  function recurseSchema(node) {
1297
- if (!isRecord$29(node)) return;
1297
+ if (!isRecord$33(node)) return;
1298
1298
  visitChildSchemas(node, normalizeProperty);
1299
1299
  }
1300
1300
  function visitChildSchemas(node, visit) {
1301
1301
  for (const { key, kind } of CHILD_SCHEMA_SLOTS) {
1302
1302
  const value = node[key];
1303
1303
  if (kind === "single") {
1304
- if (isRecord$29(value)) visit(value);
1304
+ if (isRecord$33(value)) visit(value);
1305
1305
  } else if (kind === "array") {
1306
1306
  if (Array.isArray(value)) for (const item of value) visit(item);
1307
1307
  } else if (kind === "map") {
1308
- if (isRecord$29(value)) for (const item of Object.values(value)) visit(item);
1308
+ if (isRecord$33(value)) for (const item of Object.values(value)) visit(item);
1309
1309
  } else if (kind === "schema-or-array") {
1310
- if (isRecord$29(value)) visit(value);
1310
+ if (isRecord$33(value)) visit(value);
1311
1311
  else if (Array.isArray(value)) for (const item of value) visit(item);
1312
1312
  }
1313
1313
  }
@@ -1319,7 +1319,7 @@ function childSchemaKeysForParentType(parentType) {
1319
1319
  });
1320
1320
  }
1321
1321
  function normalizeProperty(node) {
1322
- if (!isRecord$29(node)) return;
1322
+ if (!isRecord$33(node)) return;
1323
1323
  if (!hasOwn(node, "type") && !hasAnyKey(node, TYPE_COMPLETION_SKIP_KEYS)) {
1324
1324
  const enumValues = node["enum"];
1325
1325
  if (Array.isArray(enumValues) && enumValues.length > 0) node["type"] = inferTypeFromValues(enumValues);
@@ -1403,14 +1403,14 @@ function hasAnyKey(obj, keys) {
1403
1403
  }
1404
1404
  function cloneJsonValue(value) {
1405
1405
  if (Array.isArray(value)) return value.map((item) => cloneJsonValue(item));
1406
- if (isRecord$29(value)) {
1406
+ if (isRecord$33(value)) {
1407
1407
  const cloned = {};
1408
1408
  for (const [key, child] of Object.entries(value)) cloned[key] = cloneJsonValue(child);
1409
1409
  return cloned;
1410
1410
  }
1411
1411
  return value;
1412
1412
  }
1413
- function isRecord$29(value) {
1413
+ function isRecord$33(value) {
1414
1414
  return typeof value === "object" && value !== null && !Array.isArray(value);
1415
1415
  }
1416
1416
  function hasOwn(obj, key) {
@@ -1819,16 +1819,6 @@ function measureSerializedRequest(body, requestBytes) {
1819
1819
  const payload = parsed;
1820
1820
  const messages = Array.isArray(payload["messages"]) ? payload["messages"] : [];
1821
1821
  const tools = Array.isArray(payload["tools"]) ? payload["tools"] : void 0;
1822
- let systemMessageBytes = 0;
1823
- let conversationMessageBytes = 0;
1824
- let toolResultMessageBytes = 0;
1825
- for (const message of messages) {
1826
- const size = Buffer.byteLength(JSON.stringify(message), "utf8");
1827
- const role = message !== null && typeof message === "object" ? message["role"] : void 0;
1828
- if (role === "system" || role === "developer") systemMessageBytes += size;
1829
- else if (role === "tool") toolResultMessageBytes += size;
1830
- else conversationMessageBytes += size;
1831
- }
1832
1822
  const toolDefinitions = Object.freeze((tools ?? []).map((tool, index) => {
1833
1823
  const entry = tool !== null && typeof tool === "object" ? tool : void 0;
1834
1824
  const fn = entry?.["function"];
@@ -1839,6 +1829,44 @@ function measureSerializedRequest(body, requestBytes) {
1839
1829
  ...typeof name === "string" && name.length > 0 && name.length <= 128 ? { name } : {}
1840
1830
  });
1841
1831
  }));
1832
+ const declaredNames = new Set(toolDefinitions.flatMap((tool) => tool.name === void 0 ? [] : [tool.name]));
1833
+ const callNames = /* @__PURE__ */ new Map();
1834
+ for (const message of messages) {
1835
+ if (message === null || typeof message !== "object" || message["role"] !== "assistant") continue;
1836
+ const calls = message["tool_calls"];
1837
+ if (!Array.isArray(calls)) continue;
1838
+ for (const call of calls) {
1839
+ if (call === null || typeof call !== "object") continue;
1840
+ const entry = call;
1841
+ const fn = entry["function"];
1842
+ const name = fn !== null && typeof fn === "object" ? fn["name"] : void 0;
1843
+ const id = entry["id"];
1844
+ if (typeof id !== "string" || id.length === 0) continue;
1845
+ callNames.set(id, callNames.has(id) ? void 0 : typeof name === "string" && declaredNames.has(name) ? name : void 0);
1846
+ }
1847
+ }
1848
+ let systemMessageBytes = 0;
1849
+ let conversationMessageBytes = 0;
1850
+ let toolResultMessageBytes = 0;
1851
+ const results = /* @__PURE__ */ new Map();
1852
+ for (const message of messages) {
1853
+ const size = Buffer.byteLength(JSON.stringify(message), "utf8");
1854
+ const role = message !== null && typeof message === "object" ? message["role"] : void 0;
1855
+ if (role === "system" || role === "developer") systemMessageBytes += size;
1856
+ else if (role === "tool") {
1857
+ toolResultMessageBytes += size;
1858
+ const id = message["tool_call_id"];
1859
+ const name = typeof id === "string" ? callNames.get(id) : void 0;
1860
+ const key = name ?? "";
1861
+ const previous = results.get(key);
1862
+ results.set(key, {
1863
+ ...name === void 0 ? {} : { name },
1864
+ count: (previous?.count ?? 0) + 1,
1865
+ bytes: (previous?.bytes ?? 0) + size
1866
+ });
1867
+ } else conversationMessageBytes += size;
1868
+ }
1869
+ const toolResultByTool = Object.freeze(Array.from(results.values(), (entry) => Object.freeze(entry)));
1842
1870
  const toolArrayOverheadBytes = tools === void 0 ? 0 : 2 + Math.max(0, tools.length - 1);
1843
1871
  const toolSchemaBytes = toolDefinitions.reduce((sum, tool) => sum + tool.bytes, toolArrayOverheadBytes);
1844
1872
  return Object.freeze({
@@ -1848,6 +1876,7 @@ function measureSerializedRequest(body, requestBytes) {
1848
1876
  systemMessageBytes,
1849
1877
  conversationMessageBytes,
1850
1878
  toolResultMessageBytes,
1879
+ ...toolResultByTool.length === 0 ? {} : { toolResultByTool },
1851
1880
  toolSchemaBytes,
1852
1881
  toolDefinitions,
1853
1882
  toolArrayOverheadBytes,
@@ -2077,6 +2106,9 @@ var init_fetch_http_client = __esmMin((() => {
2077
2106
  const maxRetries = normalizeMaxRetries(requestOptions?.maxRetries);
2078
2107
  const requestBytes = exactBodyBytes(init.body);
2079
2108
  const requestBreakdown = pathname === "/chat/completions" && requestOptions?.onTransportAttempt !== void 0 && typeof init.body === "string" && requestBytes !== void 0 ? measureSerializedRequest(init.body, requestBytes) : void 0;
2109
+ if (pathname === "/chat/completions" && typeof init.body === "string") try {
2110
+ requestOptions?.onSerializedRequest?.(init.body);
2111
+ } catch {}
2080
2112
  let attempt = 0;
2081
2113
  while (true) {
2082
2114
  const headers = new Headers(init.headers);
@@ -2085,6 +2117,9 @@ var init_fetch_http_client = __esmMin((() => {
2085
2117
  const startedAt = performance.now();
2086
2118
  const startedAtMs = Date.now();
2087
2119
  try {
2120
+ try {
2121
+ requestOptions?.onRequestSent?.();
2122
+ } catch {}
2088
2123
  const response = await this.fetch(`${this.baseUrl}${pathname}`, {
2089
2124
  ...init,
2090
2125
  headers
@@ -2236,11 +2271,11 @@ var init_blun_files = __esmMin((() => {
2236
2271
  async uploadVideo(input, options) {
2237
2272
  let file;
2238
2273
  if (typeof input === "string") {
2239
- if (!fs$16.existsSync(input)) throw new ChatProviderError(`Video file not found: ${input}`);
2274
+ if (!fs$17.existsSync(input)) throw new ChatProviderError(`Video file not found: ${input}`);
2240
2275
  const filename = path$17.basename(input);
2241
2276
  const mimeType = guessMimeTypeFromExt(filename);
2242
2277
  if (mimeType === void 0 || !mimeType.startsWith("video/")) throw new ChatProviderError(`BlunFiles.uploadVideo: file extension does not indicate a video type: ${filename}`);
2243
- const data = await fs$16.promises.readFile(input);
2278
+ const data = await fs$17.promises.readFile(input);
2244
2279
  file = new File$1([new Blob$1([new Uint8Array(data)], { type: mimeType })], filename, { type: mimeType });
2245
2280
  } else {
2246
2281
  if (!input.mimeType.startsWith("video/")) throw new ChatProviderError(`Expected a video mime type, got ${input.mimeType}`);
@@ -2344,6 +2379,9 @@ function extractChatCompletionUsage(usage) {
2344
2379
  const value = usage;
2345
2380
  const promptTokens = typeof value["prompt_tokens"] === "number" ? value["prompt_tokens"] : 0;
2346
2381
  const completionTokens = typeof value["completion_tokens"] === "number" ? value["completion_tokens"] : 0;
2382
+ const completionDetails = value["completion_tokens_details"];
2383
+ const reportedReasoning = completionDetails !== null && typeof completionDetails === "object" ? completionDetails["reasoning_tokens"] : void 0;
2384
+ const outputReasoning = typeof reportedReasoning === "number" && Number.isSafeInteger(reportedReasoning) && reportedReasoning >= 0 && reportedReasoning <= completionTokens ? reportedReasoning : void 0;
2347
2385
  let cachedTokens = 0;
2348
2386
  if (typeof value["cached_tokens"] === "number") cachedTokens = value["cached_tokens"];
2349
2387
  else if (value["prompt_tokens_details"] !== null && typeof value["prompt_tokens_details"] === "object") {
@@ -2353,6 +2391,7 @@ function extractChatCompletionUsage(usage) {
2353
2391
  return {
2354
2392
  inputOther: promptTokens - cachedTokens,
2355
2393
  output: completionTokens,
2394
+ ...outputReasoning === void 0 ? {} : { outputReasoning },
2356
2395
  inputCacheRead: cachedTokens,
2357
2396
  inputCacheCreation: 0
2358
2397
  };
@@ -2619,6 +2658,13 @@ function collectBlunVisionAttachments(messages) {
2619
2658
  }
2620
2659
  return attachments;
2621
2660
  }
2661
+ function estimateBlunRequestExtraBytes(tools, messages) {
2662
+ const attachments = collectBlunVisionAttachments(messages);
2663
+ return {
2664
+ toolsBytes: tools.length === 0 ? 0 : Buffer.byteLength(JSON.stringify({ tools: tools.map(convertTool) }), "utf8"),
2665
+ visionBytes: attachments.length === 0 ? 0 : Buffer.byteLength(JSON.stringify({ visionAttachments: attachments }), "utf8")
2666
+ };
2667
+ }
2622
2668
  function convertMessage(message) {
2623
2669
  let reasoningContent = "";
2624
2670
  const nonThinkParts = [];
@@ -2950,12 +2996,13 @@ var init_blun = __esmMin((() => {
2950
2996
  if (this._stream) createParams["stream_options"] = { include_usage: true };
2951
2997
  try {
2952
2998
  const client = this._createClient(options?.auth);
2953
- const requestOptions = options?.signal !== void 0 || options?.transportMaxRetries !== void 0 || options?.onTransportAttempt !== void 0 ? {
2999
+ const requestOptions = options?.signal !== void 0 || options?.transportMaxRetries !== void 0 || options?.onRequestSent !== void 0 || options?.onSerializedRequest !== void 0 || options?.onTransportAttempt !== void 0 ? {
2954
3000
  ...options.signal !== void 0 ? { signal: options.signal } : {},
2955
3001
  ...options.transportMaxRetries !== void 0 ? { maxRetries: options.transportMaxRetries } : {},
3002
+ ...options.onRequestSent !== void 0 ? { onRequestSent: options.onRequestSent } : {},
3003
+ ...options.onSerializedRequest !== void 0 ? { onSerializedRequest: options.onSerializedRequest } : {},
2956
3004
  ...options.onTransportAttempt !== void 0 ? { onTransportAttempt: options.onTransportAttempt } : {}
2957
3005
  } : void 0;
2958
- options?.onRequestSent?.();
2959
3006
  let response;
2960
3007
  try {
2961
3008
  response = await client.chat.completions.create(createParams, requestOptions);
@@ -2964,7 +3011,6 @@ var init_blun = __esmMin((() => {
2964
3011
  const cap = rejection instanceof APIContextOverflowError ? contextOverflowOutputCap(rejection, createParams["max_completion_tokens"]) : void 0;
2965
3012
  if (cap === void 0) throw rejection;
2966
3013
  options?.signal?.throwIfAborted();
2967
- options?.onRequestSent?.();
2968
3014
  response = await client.chat.completions.create({
2969
3015
  ...createParams,
2970
3016
  max_completion_tokens: cap
@@ -3360,9 +3406,11 @@ function emptyUsage() {
3360
3406
  * Sum two TokenUsage values.
3361
3407
  */
3362
3408
  function addUsage$1(a, b) {
3409
+ const outputReasoning = a.outputReasoning !== void 0 && b.outputReasoning !== void 0 ? a.outputReasoning + b.outputReasoning : a.output === 0 ? b.outputReasoning : b.output === 0 ? a.outputReasoning : void 0;
3363
3410
  return {
3364
3411
  inputOther: a.inputOther + b.inputOther,
3365
3412
  output: a.output + b.output,
3413
+ ...outputReasoning === void 0 ? {} : { outputReasoning },
3366
3414
  inputCacheRead: a.inputCacheRead + b.inputCacheRead,
3367
3415
  inputCacheCreation: a.inputCacheCreation + b.inputCacheCreation
3368
3416
  };
@@ -10140,6 +10188,8 @@ var init_schema = __esmMin((() => {
10140
10188
  ProviderConfigSchema = object$1({
10141
10189
  type: ProviderTypeSchema,
10142
10190
  apiKey: string().optional(),
10191
+ memoryWorkspaceId: string().regex(/^blun-[0-9a-f]{64}$/u).optional(),
10192
+ memoryApiKeyHash: string().regex(/^[0-9a-f]{64}$/u).optional(),
10143
10193
  baseUrl: string().optional(),
10144
10194
  defaultModel: string().optional(),
10145
10195
  oauth: OAuthRefSchema.optional(),
@@ -10630,7 +10680,8 @@ function tokenToWire(token) {
10630
10680
  expires_at: token.expiresAt,
10631
10681
  scope: token.scope,
10632
10682
  token_type: token.tokenType,
10633
- expires_in: token.expiresIn
10683
+ expires_in: token.expiresIn,
10684
+ ...token.memoryWorkspaceId === void 0 ? {} : { memory_workspace_id: token.memoryWorkspaceId }
10634
10685
  };
10635
10686
  }
10636
10687
  function tokenFromWire(wire) {
@@ -10640,13 +10691,14 @@ function tokenFromWire(wire) {
10640
10691
  expiresAt: typeof wire.expires_at === "number" ? wire.expires_at : 0,
10641
10692
  scope: wire.scope ?? "",
10642
10693
  tokenType: wire.token_type ?? "",
10643
- expiresIn: typeof wire.expires_in === "number" ? wire.expires_in : 0
10694
+ expiresIn: typeof wire.expires_in === "number" ? wire.expires_in : 0,
10695
+ ...typeof wire.memory_workspace_id === "string" && wire.memory_workspace_id.length > 0 ? { memoryWorkspaceId: wire.memory_workspace_id } : {}
10644
10696
  };
10645
10697
  }
10646
10698
  var init_types$17 = __esmMin((() => {}));
10647
10699
  //#endregion
10648
10700
  //#region ../../packages/oauth/src/utils.ts
10649
- function isRecord$28(value) {
10701
+ function isRecord$32(value) {
10650
10702
  return typeof value === "object" && value !== null && !Array.isArray(value);
10651
10703
  }
10652
10704
  var init_utils$1 = __esmMin((() => {}));
@@ -11229,7 +11281,7 @@ var init_storage = __esmMin((() => {
11229
11281
  } catch {
11230
11282
  return;
11231
11283
  }
11232
- if (!isRecord$28(parsed)) return void 0;
11284
+ if (!isRecord$32(parsed)) return void 0;
11233
11285
  return tokenFromWire(parsed);
11234
11286
  }
11235
11287
  async save(name, token) {
@@ -11323,7 +11375,7 @@ function extractApiErrorMessage(value) {
11323
11375
  }
11324
11376
  return;
11325
11377
  }
11326
- if (!isRecord$28(value)) return void 0;
11378
+ if (!isRecord$32(value)) return void 0;
11327
11379
  for (const key of DIRECT_ERROR_KEYS) {
11328
11380
  const message = stringField$4(value, key);
11329
11381
  if (message !== void 0) return message;
@@ -11331,7 +11383,7 @@ function extractApiErrorMessage(value) {
11331
11383
  const error = value["error"];
11332
11384
  const errorString = nonEmptyString$7(error);
11333
11385
  if (errorString !== void 0) return errorString;
11334
- if (isRecord$28(error)) for (const key of NESTED_ERROR_KEYS) {
11386
+ if (isRecord$32(error)) for (const key of NESTED_ERROR_KEYS) {
11335
11387
  const message = stringField$4(error, key);
11336
11388
  if (message !== void 0) return message;
11337
11389
  }
@@ -11421,7 +11473,7 @@ async function postForm(url, params, deviceHeaders, options) {
11421
11473
  let data = {};
11422
11474
  try {
11423
11475
  const parsed = await response.json();
11424
- if (isRecord$28(parsed)) data = parsed;
11476
+ if (isRecord$32(parsed)) data = parsed;
11425
11477
  } catch {}
11426
11478
  return {
11427
11479
  status,
@@ -11897,7 +11949,7 @@ var require_clone$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
11897
11949
  //#endregion
11898
11950
  //#region ../../node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/graceful-fs.js
11899
11951
  var require_graceful_fs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
11900
- var fs$15 = __require("fs");
11952
+ var fs$16 = __require("fs");
11901
11953
  var polyfills = require_polyfills();
11902
11954
  var legacy = require_legacy_streams();
11903
11955
  var clone = require_clone$1();
@@ -11926,36 +11978,36 @@ var require_graceful_fs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
11926
11978
  m = "GFS4: " + m.split(/\n/).join("\nGFS4: ");
11927
11979
  console.error(m);
11928
11980
  };
11929
- if (!fs$15[gracefulQueue]) {
11930
- publishQueue(fs$15, global[gracefulQueue] || []);
11931
- fs$15.close = (function(fs$close) {
11981
+ if (!fs$16[gracefulQueue]) {
11982
+ publishQueue(fs$16, global[gracefulQueue] || []);
11983
+ fs$16.close = (function(fs$close) {
11932
11984
  function close(fd, cb) {
11933
- return fs$close.call(fs$15, fd, function(err) {
11985
+ return fs$close.call(fs$16, fd, function(err) {
11934
11986
  if (!err) resetQueue();
11935
11987
  if (typeof cb === "function") cb.apply(this, arguments);
11936
11988
  });
11937
11989
  }
11938
11990
  Object.defineProperty(close, previousSymbol, { value: fs$close });
11939
11991
  return close;
11940
- })(fs$15.close);
11941
- fs$15.closeSync = (function(fs$closeSync) {
11992
+ })(fs$16.close);
11993
+ fs$16.closeSync = (function(fs$closeSync) {
11942
11994
  function closeSync(fd) {
11943
- fs$closeSync.apply(fs$15, arguments);
11995
+ fs$closeSync.apply(fs$16, arguments);
11944
11996
  resetQueue();
11945
11997
  }
11946
11998
  Object.defineProperty(closeSync, previousSymbol, { value: fs$closeSync });
11947
11999
  return closeSync;
11948
- })(fs$15.closeSync);
12000
+ })(fs$16.closeSync);
11949
12001
  if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) process.on("exit", function() {
11950
- debug(fs$15[gracefulQueue]);
11951
- __require("assert").equal(fs$15[gracefulQueue].length, 0);
12002
+ debug(fs$16[gracefulQueue]);
12003
+ __require("assert").equal(fs$16[gracefulQueue].length, 0);
11952
12004
  });
11953
12005
  }
11954
- if (!global[gracefulQueue]) publishQueue(global, fs$15[gracefulQueue]);
11955
- module.exports = patch(clone(fs$15));
11956
- if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs$15.__patched) {
11957
- module.exports = patch(fs$15);
11958
- fs$15.__patched = true;
12006
+ if (!global[gracefulQueue]) publishQueue(global, fs$16[gracefulQueue]);
12007
+ module.exports = patch(clone(fs$16));
12008
+ if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs$16.__patched) {
12009
+ module.exports = patch(fs$16);
12010
+ fs$16.__patched = true;
11959
12011
  }
11960
12012
  function patch(fs) {
11961
12013
  polyfills(fs);
@@ -12210,23 +12262,23 @@ var require_graceful_fs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
12210
12262
  }
12211
12263
  function enqueue(elem) {
12212
12264
  debug("ENQUEUE", elem[0].name, elem[1]);
12213
- fs$15[gracefulQueue].push(elem);
12265
+ fs$16[gracefulQueue].push(elem);
12214
12266
  retry();
12215
12267
  }
12216
12268
  var retryTimer;
12217
12269
  function resetQueue() {
12218
12270
  var now = Date.now();
12219
- for (var i = 0; i < fs$15[gracefulQueue].length; ++i) if (fs$15[gracefulQueue][i].length > 2) {
12220
- fs$15[gracefulQueue][i][3] = now;
12221
- fs$15[gracefulQueue][i][4] = now;
12271
+ for (var i = 0; i < fs$16[gracefulQueue].length; ++i) if (fs$16[gracefulQueue][i].length > 2) {
12272
+ fs$16[gracefulQueue][i][3] = now;
12273
+ fs$16[gracefulQueue][i][4] = now;
12222
12274
  }
12223
12275
  retry();
12224
12276
  }
12225
12277
  function retry() {
12226
12278
  clearTimeout(retryTimer);
12227
12279
  retryTimer = void 0;
12228
- if (fs$15[gracefulQueue].length === 0) return;
12229
- var elem = fs$15[gracefulQueue].shift();
12280
+ if (fs$16[gracefulQueue].length === 0) return;
12281
+ var elem = fs$16[gracefulQueue].shift();
12230
12282
  var fn = elem[0];
12231
12283
  var args = elem[1];
12232
12284
  var err = elem[2];
@@ -12245,7 +12297,7 @@ var require_graceful_fs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
12245
12297
  if (sinceAttempt >= Math.min(sinceStart * 1.2, 100)) {
12246
12298
  debug("RETRY", fn.name, args);
12247
12299
  fn.apply(null, args.concat([startTime]));
12248
- } else fs$15[gracefulQueue].push(elem);
12300
+ } else fs$16[gracefulQueue].push(elem);
12249
12301
  }
12250
12302
  if (retryTimer === void 0) retryTimer = setTimeout(retry, 0);
12251
12303
  }
@@ -13051,6 +13103,27 @@ var init_oauth_manager = __esmMin((() => {
13051
13103
  const state = await this.loadState();
13052
13104
  return state.kind === "valid" ? state.token.accessToken : void 0;
13053
13105
  }
13106
+ async getCachedMemoryWorkspaceId() {
13107
+ const state = await this.loadState();
13108
+ return state.kind === "valid" && state.token.expiresAt > this.now() ? state.token.memoryWorkspaceId : void 0;
13109
+ }
13110
+ async cacheMemoryWorkspaceId(workspaceId) {
13111
+ if (workspaceId.length === 0) return false;
13112
+ const release = await this.acquireRefreshLock();
13113
+ try {
13114
+ const state = await this.loadState();
13115
+ if (state.kind !== "valid" || state.token.expiresAt <= this.now()) return false;
13116
+ if (state.token.memoryWorkspaceId === workspaceId) return true;
13117
+ if (state.token.memoryWorkspaceId !== void 0) return false;
13118
+ await this.storage.save(this.config.name, {
13119
+ ...state.token,
13120
+ memoryWorkspaceId: workspaceId
13121
+ });
13122
+ return true;
13123
+ } finally {
13124
+ await release();
13125
+ }
13126
+ }
13054
13127
  async logout() {
13055
13128
  await this.inFlightRefresh?.promise.catch(() => void 0);
13056
13129
  const release = await this.acquireRefreshLock();
@@ -13118,7 +13191,10 @@ var init_oauth_manager = __esmMin((() => {
13118
13191
  if (activeToken.refreshToken.length === 0) throw new OAuthUnauthorizedError(`Token for "${this.config.name}" has no refresh_token; re-login required.`);
13119
13192
  try {
13120
13193
  const refreshed = await this.refreshImpl(this.config, activeToken.refreshToken);
13121
- await this.storage.save(this.config.name, refreshed);
13194
+ await this.storage.save(this.config.name, {
13195
+ ...refreshed,
13196
+ memoryWorkspaceId: activeToken.memoryWorkspaceId
13197
+ });
13122
13198
  this.notifyRefresh({ success: true });
13123
13199
  return refreshed.accessToken;
13124
13200
  } catch (error) {
@@ -13333,9 +13409,9 @@ function blunContextWindowsUrl(oauthHost) {
13333
13409
  return `${(oauthHost ?? process.env["BLUN_OAUTH_HOST"] ?? "https://account.blun.ai").replace(/\/+$/, "")}/api/verbrauch/tarife`;
13334
13410
  }
13335
13411
  function parseManagedContextWindow(payload, plan) {
13336
- if (!isRecord$28(payload)) return void 0;
13412
+ if (!isRecord$32(payload)) return void 0;
13337
13413
  const contextWindows = payload["kontext"];
13338
- if (!isRecord$28(contextWindows)) return void 0;
13414
+ if (!isRecord$32(contextWindows)) return void 0;
13339
13415
  const value = contextWindows[plan];
13340
13416
  return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : void 0;
13341
13417
  }
@@ -13370,7 +13446,7 @@ function parseManagedUsagePayload(payload) {
13370
13446
  const plan = typeof rec["plan"] === "string" && rec["plan"].trim().length > 0 ? rec["plan"].trim() : void 0;
13371
13447
  const contextWindowTokens = managedContextWindowFrom(rec);
13372
13448
  const unlimited = rec["unlimited"] === true;
13373
- const stand = isRecord$28(rec["stand"]) ? rec["stand"] : void 0;
13449
+ const stand = isRecord$32(rec["stand"]) ? rec["stand"] : void 0;
13374
13450
  if (stand !== void 0) for (const [sourceKey, id, label] of ACCOUNT_USAGE_WINDOWS) {
13375
13451
  const row = toAccountUsageRow(stand[sourceKey], id, label, unlimited);
13376
13452
  if (row !== null) limits.push(row);
@@ -13380,9 +13456,9 @@ function parseManagedUsagePayload(payload) {
13380
13456
  const item = rawLimits[idx];
13381
13457
  if (!item || typeof item !== "object") continue;
13382
13458
  const detailRaw = item["detail"];
13383
- const detail = isRecord$28(detailRaw) ? detailRaw : item;
13459
+ const detail = isRecord$32(detailRaw) ? detailRaw : item;
13384
13460
  const windowRaw = item["window"];
13385
- const row = toUsageRow(detail, limitLabel(item, detail, isRecord$28(windowRaw) ? windowRaw : {}, idx));
13461
+ const row = toUsageRow(detail, limitLabel(item, detail, isRecord$32(windowRaw) ? windowRaw : {}, idx));
13386
13462
  if (row !== null) limits.push(row);
13387
13463
  }
13388
13464
  return {
@@ -13406,7 +13482,7 @@ function managedContextWindowFrom(payload) {
13406
13482
  return values.every((value) => value === first) ? first : void 0;
13407
13483
  }
13408
13484
  function toAccountUsageRow(raw, id, label, accountUnlimited) {
13409
- if (!isRecord$28(raw)) return null;
13485
+ if (!isRecord$32(raw)) return null;
13410
13486
  const used = toInt(raw["verbraucht"]);
13411
13487
  const unlimited = accountUnlimited || raw["unlimited"] === true;
13412
13488
  const fraction = raw["anteil"];
@@ -13439,7 +13515,7 @@ function toAccountUsageRow(raw, id, label, accountUnlimited) {
13439
13515
  };
13440
13516
  }
13441
13517
  function toUsageRow(raw, defaultLabel) {
13442
- if (!isRecord$28(raw)) return null;
13518
+ if (!isRecord$32(raw)) return null;
13443
13519
  const unlimited = raw["unlimited"] === true;
13444
13520
  const limit = toInt(raw["limit"]);
13445
13521
  let used = toInt(raw["used"]);
@@ -13560,7 +13636,7 @@ function isManagedQuotaErrorMessage(message) {
13560
13636
  return /you(?:'|’)?ve reached your usage limit/.test(normalized) && /billing cycle|quota will be (?:refreshed|reset)|purchase extra usage/.test(normalized);
13561
13637
  }
13562
13638
  function hasManagedUsageShape(payload) {
13563
- if (!isRecord$28(payload)) return false;
13639
+ if (!isRecord$32(payload)) return false;
13564
13640
  let recognized = false;
13565
13641
  if ("context_window_tokens" in payload || "contextWindowTokens" in payload) {
13566
13642
  recognized = true;
@@ -13576,15 +13652,15 @@ function hasManagedUsageShape(payload) {
13576
13652
  if (!Array.isArray(limits)) return false;
13577
13653
  for (let index = 0; index < limits.length; index++) {
13578
13654
  const item = limits[index];
13579
- if (!isRecord$28(item)) return false;
13580
- const detail = isRecord$28(item["detail"]) ? item["detail"] : item;
13581
- if (toUsageRow(detail, limitLabel(item, detail, isRecord$28(item["window"]) ? item["window"] : {}, index)) === null) return false;
13655
+ if (!isRecord$32(item)) return false;
13656
+ const detail = isRecord$32(item["detail"]) ? item["detail"] : item;
13657
+ if (toUsageRow(detail, limitLabel(item, detail, isRecord$32(item["window"]) ? item["window"] : {}, index)) === null) return false;
13582
13658
  }
13583
13659
  }
13584
13660
  if ("stand" in payload) {
13585
13661
  recognized = true;
13586
13662
  const stand = payload["stand"];
13587
- if (!isRecord$28(stand)) return false;
13663
+ if (!isRecord$32(stand)) return false;
13588
13664
  const windows = ACCOUNT_USAGE_WINDOWS.filter(([sourceKey]) => sourceKey in stand);
13589
13665
  if (windows.length === 0) return false;
13590
13666
  const unlimited = payload["unlimited"] === true;
@@ -13680,8 +13756,8 @@ function userExtras(existing, remoteOwnedFields) {
13680
13756
  return out;
13681
13757
  }
13682
13758
  function mergeRefreshedModelAlias(existing, remote, remoteOwnedFields) {
13683
- const current = isRecord$28(existing) ? existing : {};
13684
- const overrides = cloneOverrides(isRecord$28(current["overrides"]) ? current["overrides"] : void 0);
13759
+ const current = isRecord$32(existing) ? existing : {};
13760
+ const overrides = cloneOverrides(isRecord$32(current["overrides"]) ? current["overrides"] : void 0);
13685
13761
  return {
13686
13762
  ...userExtras(current, remoteOwnedFields),
13687
13763
  ...remote,
@@ -13870,7 +13946,7 @@ function parseModelContextLength(item, modelId) {
13870
13946
  return values[0];
13871
13947
  }
13872
13948
  function toModelInfo(item) {
13873
- if (!isRecord$28(item) || typeof item["id"] !== "string" || item["id"].length === 0) return;
13949
+ if (!isRecord$32(item) || typeof item["id"] !== "string" || item["id"].length === 0) return;
13874
13950
  const contextLength = parseModelContextLength(item, item["id"]);
13875
13951
  const displayName = item["display_name"];
13876
13952
  const normalizedDisplayName = typeof displayName === "string" && displayName.length > 0 ? displayName : void 0;
@@ -13957,7 +14033,7 @@ async function fetchManagedBlunCodeModels(options) {
13957
14033
  throw new Error(message);
13958
14034
  }
13959
14035
  const payload = await response.json();
13960
- if (!isRecord$28(payload) || !Array.isArray(payload["data"])) throw new Error(`Unexpected models response for ${baseUrl}.`);
14036
+ if (!isRecord$32(payload) || !Array.isArray(payload["data"])) throw new Error(`Unexpected models response for ${baseUrl}.`);
13961
14037
  return payload["data"].map((item) => toModelInfo(item)).filter((item) => item !== void 0);
13962
14038
  }
13963
14039
  throw new Error(`Failed to list BLUN models for ${baseUrl}.`);
@@ -14000,11 +14076,11 @@ function applyManagedBlunCodeConfig(config, options) {
14000
14076
  apiKey
14001
14077
  };
14002
14078
  const upstreamKeys = new Set(options.models.map((m) => managedModelKey(m.id)));
14003
- for (const [key, model] of Object.entries(existingModels)) if (RETIRED_BLUN_MODEL_KEYS.has(key) || isRecord$28(model) && model["provider"] === "managed:blun" && !upstreamKeys.has(key)) delete existingModels[key];
14079
+ for (const [key, model] of Object.entries(existingModels)) if (RETIRED_BLUN_MODEL_KEYS.has(key) || isRecord$32(model) && model["provider"] === "managed:blun" && !upstreamKeys.has(key)) delete existingModels[key];
14004
14080
  for (const model of options.models) {
14005
14081
  const capabilities = capabilitiesForModel(model);
14006
14082
  const key = managedModelKey(model.id);
14007
- const existing = isRecord$28(existingModels[key]) ? existingModels[key] : {};
14083
+ const existing = isRecord$32(existingModels[key]) ? existingModels[key] : {};
14008
14084
  const supportsAdaptiveThinking = capabilities?.includes("thinking") === true || capabilities?.includes("always_thinking") === true;
14009
14085
  existingModels[key] = mergeRefreshedModelAlias(existing, {
14010
14086
  provider: BLUN_PROVIDER_NAME$1,
@@ -14052,7 +14128,7 @@ function applyManagedBlunCodeLogoutConfig(config) {
14052
14128
  let removedDefaultModel = false;
14053
14129
  const existingModels = config.models ?? {};
14054
14130
  for (const [key, model] of Object.entries(existingModels)) {
14055
- if (!isRecord$28(model) || model["provider"] !== "managed:blun") continue;
14131
+ if (!isRecord$32(model) || model["provider"] !== "managed:blun") continue;
14056
14132
  delete existingModels[key];
14057
14133
  if (config.defaultModel === key) removedDefaultModel = true;
14058
14134
  }
@@ -14092,7 +14168,7 @@ function selectDefaultModel(config, models, options) {
14092
14168
  function canPreserveDefaultModel(existingModels, defaultModel, managedModels) {
14093
14169
  if (managedModels.has(defaultModel)) return true;
14094
14170
  const existing = existingModels[defaultModel];
14095
- return isRecord$28(existing) && existing["provider"] !== "managed:blun";
14171
+ return isRecord$32(existing) && existing["provider"] !== "managed:blun";
14096
14172
  }
14097
14173
  function assertPositiveContextLength(model) {
14098
14174
  if (!Number.isInteger(model.contextLength) || model.contextLength <= 0) throw new Error(`BLUN model "${model.id}" must include a positive context_length.`);
@@ -14168,13 +14244,13 @@ function blunManagedQuotaUrl(oauthHost) {
14168
14244
  return `${(oauthHost ?? process.env["BLUN_OAUTH_HOST"] ?? "https://account.blun.ai").replace(/\/+$/, "")}${MANAGED_QUOTA_PATH}`;
14169
14245
  }
14170
14246
  function parseManagedQuotaPayload(payload) {
14171
- if (!isRecord$28(payload)) return void 0;
14247
+ if (!isRecord$32(payload)) return void 0;
14172
14248
  const plan = nonEmptyString$6(payload["plan"]);
14173
14249
  const paid = payload["bezahlt"];
14174
14250
  const creditCents = payload["guthaben_cent"];
14175
14251
  const billingKind = nonEmptyString$6(payload["art"]);
14176
14252
  const globalUnlimited = payload["unlimited"];
14177
- if (plan === void 0 || typeof paid !== "boolean" || !Number.isSafeInteger(creditCents) || creditCents < 0 || billingKind === void 0 || globalUnlimited !== void 0 && typeof globalUnlimited !== "boolean" || !isRecord$28(payload["stand"])) return;
14253
+ if (plan === void 0 || typeof paid !== "boolean" || !Number.isSafeInteger(creditCents) || creditCents < 0 || billingKind === void 0 || globalUnlimited !== void 0 && typeof globalUnlimited !== "boolean" || !isRecord$32(payload["stand"])) return;
14178
14254
  if (!hasStrictQuotaStand(payload["stand"], globalUnlimited === true)) return void 0;
14179
14255
  const limits = parseManagedUsagePayload(payload).limits;
14180
14256
  if (limits.length !== REQUIRED_WINDOWS.length || REQUIRED_WINDOWS.some(([, id]) => limits.filter((row) => row.id === id).length !== 1)) return;
@@ -14244,7 +14320,7 @@ function nonEmptyString$6(value) {
14244
14320
  function hasStrictQuotaStand(stand, globalUnlimited) {
14245
14321
  return REQUIRED_WINDOWS.every(([sourceKey]) => {
14246
14322
  const row = stand[sourceKey];
14247
- if (!isRecord$28(row)) return false;
14323
+ if (!isRecord$32(row)) return false;
14248
14324
  const used = row["verbraucht"];
14249
14325
  const rowUnlimited = row["unlimited"];
14250
14326
  if (rowUnlimited !== void 0 && typeof rowUnlimited !== "boolean") return false;
@@ -14534,6 +14610,16 @@ var init_toolkit = __esmMin((() => {
14534
14610
  hasToken: await this.managerFor(name, oauthKey, oauthHost).hasToken()
14535
14611
  }] };
14536
14612
  }
14613
+ async getCachedMemoryWorkspaceId(oauthRef) {
14614
+ const oauthHost = this.oauthHostFor(oauthRef);
14615
+ const oauthKey = oauthRef?.key ?? this.defaultOAuthKey(void 0, oauthHost);
14616
+ return this.managerFor(BLUN_PROVIDER_NAME$1, oauthKey, oauthHost).getCachedMemoryWorkspaceId();
14617
+ }
14618
+ async cacheMemoryWorkspaceId(workspaceId, oauthRef) {
14619
+ const oauthHost = this.oauthHostFor(oauthRef);
14620
+ const oauthKey = oauthRef?.key ?? this.defaultOAuthKey(void 0, oauthHost);
14621
+ return this.managerFor(BLUN_PROVIDER_NAME$1, oauthKey, oauthHost).cacheMemoryWorkspaceId(workspaceId);
14622
+ }
14537
14623
  async login(providerName, options = {}) {
14538
14624
  const name = providerName ?? "managed:blun";
14539
14625
  const oauthHost = this.oauthHostFor(options.oauthRef, options.oauthHost);
@@ -15089,7 +15175,7 @@ async function syncDir(dirPath) {
15089
15175
  */
15090
15176
  function syncFd(fd) {
15091
15177
  return new Promise((resolve, reject) => {
15092
- fs$16.fsync(fd, (err) => {
15178
+ fs$17.fsync(fd, (err) => {
15093
15179
  if (err) {
15094
15180
  reject(err);
15095
15181
  return;
@@ -16674,6 +16760,8 @@ function providerToToml(provider, rawProvider) {
16674
16760
  for (const key of [
16675
16761
  "type",
16676
16762
  "apiKey",
16763
+ "memoryWorkspaceId",
16764
+ "memoryApiKeyHash",
16677
16765
  "baseUrl",
16678
16766
  "defaultModel",
16679
16767
  "oauth",
@@ -21759,7 +21847,7 @@ function parseSkillText(options) {
21759
21847
  throw error;
21760
21848
  }
21761
21849
  const frontmatter = parsed.data ?? {};
21762
- if (!isRecord$27(frontmatter)) throw new SkillParseError(`Frontmatter in ${options.skillMdPath} must be a mapping at the top level`);
21850
+ if (!isRecord$31(frontmatter)) throw new SkillParseError(`Frontmatter in ${options.skillMdPath} must be a mapping at the top level`);
21763
21851
  const metadata = normalizeMetadata(frontmatter);
21764
21852
  if (!isSupportedSkillType(metadata.type)) throw new UnsupportedSkillTypeError(metadata.type ?? String(frontmatter["type"]));
21765
21853
  const name = nonEmptyString$4(metadata.name);
@@ -21872,7 +21960,7 @@ function tokenizeArgs(raw) {
21872
21960
  function nonEmptyString$4(value) {
21873
21961
  return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
21874
21962
  }
21875
- function isRecord$27(value) {
21963
+ function isRecord$31(value) {
21876
21964
  return typeof value === "object" && value !== null && !Array.isArray(value);
21877
21965
  }
21878
21966
  var import_regexp_escape, FrontmatterError, SkillParseError, UnsupportedSkillTypeError, FENCE, METADATA_ALIASES;
@@ -21921,7 +22009,7 @@ var init_parser$1 = __esmMin((() => {
21921
22009
  function parseCommandText(input) {
21922
22010
  const { text, commandPath, pluginId } = input;
21923
22011
  const parsed = parseFrontmatter(text);
21924
- const frontmatter = isRecord$26(parsed.data) ? parsed.data : {};
22012
+ const frontmatter = isRecord$30(parsed.data) ? parsed.data : {};
21925
22013
  const baseName = input.fallbackName ?? path.basename(commandPath).replace(/\.md$/i, "");
21926
22014
  const name = nonEmptyString$3(frontmatter["name"]) ?? baseName;
21927
22015
  const body = parsed.body.trim();
@@ -21963,7 +22051,7 @@ function descriptionFromBody(body) {
21963
22051
  if (firstLine === void 0) return "No description provided.";
21964
22052
  return firstLine.length > 240 ? `${firstLine.slice(0, 239)}…` : firstLine;
21965
22053
  }
21966
- function isRecord$26(value) {
22054
+ function isRecord$30(value) {
21967
22055
  return typeof value === "object" && value !== null && !Array.isArray(value);
21968
22056
  }
21969
22057
  var init_commands = __esmMin((() => {
@@ -22273,10 +22361,15 @@ async function loadAgentsMdForRoots(kaos, brandHome, workDirs) {
22273
22361
  const discovered = [];
22274
22362
  const emptySources = /* @__PURE__ */ new Map();
22275
22363
  const seen = /* @__PURE__ */ new Set();
22364
+ const notLoadedCandidates = /* @__PURE__ */ new Set();
22276
22365
  const collect = async (path) => {
22277
22366
  const file = await readAgentFile(kaos, path);
22278
- if (file === void 0) return false;
22367
+ if (file === void 0) {
22368
+ notLoadedCandidates.add(kaos.normpath(path));
22369
+ return false;
22370
+ }
22279
22371
  const key = kaos.normpath(file.path);
22372
+ notLoadedCandidates.delete(key);
22280
22373
  if (file.content.length === 0) {
22281
22374
  emptySources.set(key, InstructionText.file(file.path, "", file.sourceTextBytes));
22282
22375
  return false;
@@ -22312,7 +22405,10 @@ async function loadAgentsMdForRoots(kaos, brandHome, workDirs) {
22312
22405
  return {
22313
22406
  content,
22314
22407
  warning: totalBytes > AGENTS_MD_RECOMMENDED_MAX_BYTES ? `AGENTS.md total ${formatKB(totalBytes)} KB exceeds the recommended ${formatKB(AGENTS_MD_RECOMMENDED_MAX_BYTES)} KB. Large instruction files increase cost and may impact performance; consider trimming.` : void 0,
22315
- sources: rendered.measure()
22408
+ sources: {
22409
+ ...rendered.measure(),
22410
+ ...notLoadedCandidates.size === 0 ? {} : { notLoadedCandidates: [...notLoadedCandidates] }
22411
+ }
22316
22412
  };
22317
22413
  }
22318
22414
  async function loadAdditionalDirsInfo(kaos, additionalDirs) {
@@ -27708,7 +27804,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
27708
27804
  };
27709
27805
  return _setPrototypeOf(o, p);
27710
27806
  }
27711
- var fs$14 = __require("fs");
27807
+ var fs$15 = __require("fs");
27712
27808
  var path$14 = __require("path");
27713
27809
  var Loader = require_loader();
27714
27810
  var PrecompiledLoader = require_precompiled_loader().PrecompiledLoader;
@@ -27732,7 +27828,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
27732
27828
  } catch (e) {
27733
27829
  throw new Error("watch requires chokidar to be installed");
27734
27830
  }
27735
- var paths = _this.searchPaths.filter(fs$14.existsSync);
27831
+ var paths = _this.searchPaths.filter(fs$15.existsSync);
27736
27832
  var watcher = chokidar.watch(paths);
27737
27833
  watcher.on("all", function(event, fullname) {
27738
27834
  fullname = path$14.resolve(fullname);
@@ -27751,7 +27847,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
27751
27847
  for (var i = 0; i < paths.length; i++) {
27752
27848
  var basePath = path$14.resolve(paths[i]);
27753
27849
  var p = path$14.resolve(paths[i], name);
27754
- if (p.indexOf(basePath) === 0 && fs$14.existsSync(p)) {
27850
+ if (p.indexOf(basePath) === 0 && fs$15.existsSync(p)) {
27755
27851
  fullpath = p;
27756
27852
  break;
27757
27853
  }
@@ -27759,7 +27855,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
27759
27855
  if (!fullpath) return null;
27760
27856
  this.pathsToNames[fullpath] = name;
27761
27857
  var source = {
27762
- src: fs$14.readFileSync(fullpath, "utf-8"),
27858
+ src: fs$15.readFileSync(fullpath, "utf-8"),
27763
27859
  path: fullpath,
27764
27860
  noCache: this.noCache
27765
27861
  };
@@ -27807,7 +27903,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
27807
27903
  }
27808
27904
  this.pathsToNames[fullpath] = name;
27809
27905
  var source = {
27810
- src: fs$14.readFileSync(fullpath, "utf-8"),
27906
+ src: fs$15.readFileSync(fullpath, "utf-8"),
27811
27907
  path: fullpath,
27812
27908
  noCache: this.noCache
27813
27909
  };
@@ -28551,7 +28647,7 @@ var require_precompile_global = /* @__PURE__ */ __commonJSMin(((exports, module)
28551
28647
  //#endregion
28552
28648
  //#region ../../node_modules/.pnpm/nunjucks@3.2.4_chokidar@4.0.3/node_modules/nunjucks/src/precompile.js
28553
28649
  var require_precompile = /* @__PURE__ */ __commonJSMin(((exports, module) => {
28554
- var fs$13 = __require("fs");
28650
+ var fs$14 = __require("fs");
28555
28651
  var path$12 = __require("path");
28556
28652
  var _prettifyError = require_lib$8()._prettifyError;
28557
28653
  var compiler = require_compiler();
@@ -28576,27 +28672,27 @@ var require_precompile = /* @__PURE__ */ __commonJSMin(((exports, module) => {
28576
28672
  var env = opts.env || new Environment([]);
28577
28673
  var wrapper = opts.wrapper || precompileGlobal;
28578
28674
  if (opts.isString) return precompileString(input, opts);
28579
- var pathStats = fs$13.existsSync(input) && fs$13.statSync(input);
28675
+ var pathStats = fs$14.existsSync(input) && fs$14.statSync(input);
28580
28676
  var precompiled = [];
28581
28677
  var templates = [];
28582
28678
  function addTemplates(dir) {
28583
- fs$13.readdirSync(dir).forEach(function(file) {
28679
+ fs$14.readdirSync(dir).forEach(function(file) {
28584
28680
  var filepath = path$12.join(dir, file);
28585
28681
  var subpath = filepath.substr(path$12.join(input, "/").length);
28586
- var stat = fs$13.statSync(filepath);
28682
+ var stat = fs$14.statSync(filepath);
28587
28683
  if (stat && stat.isDirectory()) {
28588
28684
  subpath += "/";
28589
28685
  if (!match(subpath, opts.exclude)) addTemplates(filepath);
28590
28686
  } else if (match(subpath, opts.include)) templates.push(filepath);
28591
28687
  });
28592
28688
  }
28593
- if (pathStats.isFile()) precompiled.push(_precompile(fs$13.readFileSync(input, "utf-8"), opts.name || input, env));
28689
+ if (pathStats.isFile()) precompiled.push(_precompile(fs$14.readFileSync(input, "utf-8"), opts.name || input, env));
28594
28690
  else if (pathStats.isDirectory()) {
28595
28691
  addTemplates(input);
28596
28692
  for (var i = 0; i < templates.length; i++) {
28597
28693
  var name = templates[i].replace(path$12.join(input, "/"), "");
28598
28694
  try {
28599
- precompiled.push(_precompile(fs$13.readFileSync(templates[i], "utf-8"), name, env));
28695
+ precompiled.push(_precompile(fs$14.readFileSync(templates[i], "utf-8"), name, env));
28600
28696
  } catch (e) {
28601
28697
  if (opts.force) console.error(e);
28602
28698
  else throw e;
@@ -29312,17 +29408,20 @@ function createSystemPromptRenderer(merged) {
29312
29408
  const counts = renderPromptContributions(merged.systemPromptTemplate, vars, rendered, true) ?? renderPromptContributions(merged.systemPromptTemplate, vars, rendered);
29313
29409
  const sources = context.agentsMdSources;
29314
29410
  const copies = counts?.instructionCopies ?? 0;
29315
- const sourceMatches = sources !== void 0 && sources.version === 1 && Number.isSafeInteger(sources.generatedBytes) && sources.generatedBytes >= 0 && sources.files.every((file) => typeof file.path === "string" && Number.isSafeInteger(file.bytes) && file.bytes >= 0) && sources.totalBytes === Buffer.byteLength(vars["BLUN_AGENTS_MD"] ?? "", "utf8") && sources.generatedBytes + sources.files.reduce((sum, file) => sum + file.bytes, 0) === sources.totalBytes;
29411
+ const sourceMatches = sources !== void 0 && sources.version === 1 && Number.isSafeInteger(sources.generatedBytes) && sources.generatedBytes >= 0 && sources.files.every((file) => typeof file.path === "string" && Number.isSafeInteger(file.bytes) && file.bytes >= 0) && (sources.notLoadedCandidates?.every((path) => typeof path === "string") ?? true) && sources.totalBytes === Buffer.byteLength(vars["BLUN_AGENTS_MD"] ?? "", "utf8") && sources.generatedBytes + sources.files.reduce((sum, file) => sum + file.bytes, 0) === sources.totalBytes;
29412
+ const notLoadedCandidates = sourceMatches && sources.notLoadedCandidates !== void 0 ? { notLoadedCandidates: [...sources.notLoadedCandidates] } : {};
29316
29413
  const instructionSources = copies === 0 ? {
29317
29414
  version: 1,
29318
29415
  totalBytes: 0,
29319
29416
  generatedBytes: 0,
29320
- files: sourceMatches ? sources.files.map((file) => copyInstructionFileBytes(file, 0)) : []
29417
+ files: sourceMatches ? sources.files.map((file) => copyInstructionFileBytes(file, 0)) : [],
29418
+ ...notLoadedCandidates
29321
29419
  } : !sourceMatches ? void 0 : {
29322
29420
  version: 1,
29323
29421
  totalBytes: sources.totalBytes * copies,
29324
29422
  generatedBytes: sources.generatedBytes * copies,
29325
- files: sources.files.map((file) => copyInstructionFileBytes(file, copies))
29423
+ files: sources.files.map((file) => copyInstructionFileBytes(file, copies)),
29424
+ ...notLoadedCandidates
29326
29425
  };
29327
29426
  const skillListingSources = counts === void 0 ? void 0 : scaleSkillListingSources(skillSources, vars["BLUN_SKILLS"] ?? "", counts.skillListingBytes);
29328
29427
  context.onContributions(counts === void 0 ? void 0 : {
@@ -29811,7 +29910,7 @@ var init_per_id_json_store = __esmMin((() => {
29811
29910
  }));
29812
29911
  //#endregion
29813
29912
  //#region ../../packages/agent-core/src/agent/background/resume-store.ts
29814
- var BACKGROUND_TASK_ID, id, digest$2, timestamp$2, ResumeIntentSchema, hash$3, isRecord$25, TaskResumeStore;
29913
+ var BACKGROUND_TASK_ID, id, digest$2, timestamp$2, ResumeIntentSchema, hash$3, isRecord$29, TaskResumeStore;
29815
29914
  var init_resume_store = __esmMin((() => {
29816
29915
  init_zod$1();
29817
29916
  BACKGROUND_TASK_ID = /^[a-z0-9]+(?:-[a-z0-9]+)*-[0-9a-z]{8}$/;
@@ -29836,7 +29935,7 @@ var init_resume_store = __esmMin((() => {
29836
29935
  startedAt: timestamp$2.nullable()
29837
29936
  }).strict();
29838
29937
  hash$3 = (value) => createHash("sha256").update(value).digest("hex");
29839
- isRecord$25 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
29938
+ isRecord$29 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
29840
29939
  TaskResumeStore = class {
29841
29940
  home;
29842
29941
  constructor(home) {
@@ -29891,9 +29990,9 @@ var init_resume_store = __esmMin((() => {
29891
29990
  }
29892
29991
  async readOwnedTask(taskId) {
29893
29992
  const task = await this.read("tasks", taskId);
29894
- if (!isRecord$25(task)) throw new Error("Task has no persisted local record.");
29993
+ if (!isRecord$29(task)) throw new Error("Task has no persisted local record.");
29895
29994
  const owner = task["resumeOwnership"];
29896
- if (!isRecord$25(owner) || owner["version"] !== 1 || owner["scope"] !== hash$3(await this.root()) || owner["taskId"] !== taskId || task["taskId"] !== taskId || task["kind"] !== "agent" || owner["agentId"] !== task["agentId"] || owner["startedAt"] !== task["startedAt"]) throw new Error("Task ownership is unverified; historical or foreign records cannot be resumed automatically.");
29995
+ if (!isRecord$29(owner) || owner["version"] !== 1 || owner["scope"] !== hash$3(await this.root()) || owner["taskId"] !== taskId || task["taskId"] !== taskId || task["kind"] !== "agent" || owner["agentId"] !== task["agentId"] || owner["startedAt"] !== task["startedAt"]) throw new Error("Task ownership is unverified; historical or foreign records cannot be resumed automatically.");
29897
29996
  const { resumeOwnership: _ownership, ...info } = task;
29898
29997
  return info;
29899
29998
  }
@@ -30014,12 +30113,12 @@ function legacyStatusToCurrent$1(task) {
30014
30113
  return task.status;
30015
30114
  }
30016
30115
  function isReadablePersistedTask$1(obj) {
30017
- return isRecord$24(obj) && (typeof obj["taskId"] === "string" || typeof obj["task_id"] === "string");
30116
+ return isRecord$28(obj) && (typeof obj["taskId"] === "string" || typeof obj["task_id"] === "string");
30018
30117
  }
30019
30118
  function isLegacyPersistedTask$1(task) {
30020
30119
  return "task_id" in task;
30021
30120
  }
30022
- function isRecord$24(value) {
30121
+ function isRecord$28(value) {
30023
30122
  return typeof value === "object" && value !== null;
30024
30123
  }
30025
30124
  function optionalNonEmptyString$2(value) {
@@ -191962,7 +192061,7 @@ var require_gifframe = /* @__PURE__ */ __commonJSMin(((exports) => {
191962
192061
  //#region ../../node_modules/.pnpm/gifwrap@0.10.1/node_modules/gifwrap/src/gifutil.js
191963
192062
  var require_gifutil = /* @__PURE__ */ __commonJSMin(((exports) => {
191964
192063
  /** @namespace GifUtil */
191965
- const fs$12 = __require("fs");
192064
+ const fs$13 = __require("fs");
191966
192065
  const ImageQ = require_image_q();
191967
192066
  const BitmapImage = require_bitmapimage();
191968
192067
  const { GifFrame } = require_gifframe();
@@ -192229,7 +192328,7 @@ var require_gifutil = /* @__PURE__ */ __commonJSMin(((exports) => {
192229
192328
  }
192230
192329
  function _readBinary(path) {
192231
192330
  return new Promise((resolve, reject) => {
192232
- fs$12.readFile(path, (err, buffer) => {
192331
+ fs$13.readFile(path, (err, buffer) => {
192233
192332
  if (err) return reject(err);
192234
192333
  return resolve(buffer);
192235
192334
  });
@@ -192237,7 +192336,7 @@ var require_gifutil = /* @__PURE__ */ __commonJSMin(((exports) => {
192237
192336
  }
192238
192337
  function _writeBinary(path, buffer) {
192239
192338
  return new Promise((resolve, reject) => {
192240
- fs$12.writeFile(path, buffer, (err) => {
192339
+ fs$13.writeFile(path, buffer, (err) => {
192241
192340
  if (err) return reject(err);
192242
192341
  return resolve();
192243
192342
  });
@@ -218055,7 +218154,7 @@ var init_file_type = __esmMin((() => {
218055
218154
  }
218056
218155
  async fromFile(path) {
218057
218156
  this.options.signal?.throwIfAborted();
218058
- const fileHandle = await ro.open(path, constants.O_RDONLY | constants.O_NONBLOCK);
218157
+ const fileHandle = await fs.open(path, constants.O_RDONLY | constants.O_NONBLOCK);
218059
218158
  const fileStat = await fileHandle.stat();
218060
218159
  if (!fileStat.isFile()) {
218061
218160
  await fileHandle.close();
@@ -229617,7 +229716,7 @@ function escapeXml(value) {
229617
229716
  function locationKey(messageIndex, partIndex) {
229618
229717
  return `${String(messageIndex)}:${String(partIndex)}`;
229619
229718
  }
229620
- function isRecord$23(value) {
229719
+ function isRecord$27(value) {
229621
229720
  return value !== null && typeof value === "object" && !Array.isArray(value);
229622
229721
  }
229623
229722
  function isNonNegativeInteger$1(value) {
@@ -229818,7 +229917,7 @@ var init_vision_reader = __esmMin((() => {
229818
229917
  reason: "malformed"
229819
229918
  };
229820
229919
  }
229821
- if (!isRecord$23(payload) || payload["done"] !== true || typeof payload["response"] !== "string" || !isNonNegativeInteger$1(payload["prompt_eval_count"]) || !isNonNegativeInteger$1(payload["eval_count"])) return {
229920
+ if (!isRecord$27(payload) || payload["done"] !== true || typeof payload["response"] !== "string" || !isNonNegativeInteger$1(payload["prompt_eval_count"]) || !isNonNegativeInteger$1(payload["eval_count"])) return {
229822
229921
  ok: false,
229823
229922
  reason: "malformed"
229824
229923
  };
@@ -231014,16 +231113,19 @@ var init_full = __esmMin((() => {
231014
231113
  const projected = context.additionalMessages === void 0 ? messages : [...messages, ...context.additionalMessages];
231015
231114
  const historyBudget = this.requestHistoryByteBudget(projected);
231016
231115
  const historyThresholdReached = historyBudget !== void 0 && historyBudget.usedHistoryBytes >= historyBudget.thresholdHistoryBytes;
231116
+ const requestBudget = this.requestBodyByteBudget(projected, context);
231117
+ const requestThresholdReached = requestBudget !== void 0 && requestBudget.usedRequestBytesEstimate >= requestBudget.thresholdRequestBytes;
231017
231118
  if (this.sessionCompactionFailures >= MAX_SESSION_COMPACTION_FAILURES) reason = "session_stopped";
231018
231119
  else if (this.isCompacting) reason = "already_compacting";
231019
- else if (thresholdTokens === void 0 && historyBudget === void 0) reason = "no_budget";
231020
- else if (!historyThresholdReached && (thresholdTokens === void 0 || !Number.isFinite(usedTokens) || usedTokens < thresholdTokens)) reason = "below_threshold";
231120
+ else if (thresholdTokens === void 0 && historyBudget === void 0 && requestBudget === void 0) reason = "no_budget";
231121
+ else if (!historyThresholdReached && !requestThresholdReached && (thresholdTokens === void 0 || !Number.isFinite(usedTokens) || usedTokens < thresholdTokens)) reason = "below_threshold";
231021
231122
  else if (!this.hasShrinkableHistory(projected)) reason = "nothing_to_compact";
231022
231123
  return {
231023
231124
  eligible: reason === "eligible",
231024
231125
  usedTokens,
231025
231126
  thresholdTokens,
231026
231127
  ...historyBudget,
231128
+ ...requestBudget,
231027
231129
  reason
231028
231130
  };
231029
231131
  }
@@ -231045,6 +231147,35 @@ var init_full = __esmMin((() => {
231045
231147
  thresholdHistoryBytes: limit
231046
231148
  };
231047
231149
  }
231150
+ requestBodyByteBudget(messages, context) {
231151
+ const limit = this.agent.blunConfig?.loopControl?.maxRequestHistoryBytes;
231152
+ if (!this.agent.config.hasProvider || this.strategy.compactionBudgetTokens === void 0 || limit !== void 0 && (!Number.isSafeInteger(limit) || limit <= 0)) return void 0;
231153
+ const model = this.agent.activeResponderModel ?? this.agent.config.modelAlias;
231154
+ if (model === void 0 || this.agent.config.runtimeModel(model).provider.name !== "blun") return void 0;
231155
+ const systemPrompt = context.systemPrompt ?? this.agent.effectiveSystemPrompt;
231156
+ const tools = (context.tools ?? this.agent.tools.loopTools).map((tool) => ({
231157
+ name: tool.name,
231158
+ description: tool.description,
231159
+ parameters: tool.parameters
231160
+ }));
231161
+ let extraBytes;
231162
+ try {
231163
+ extraBytes = estimateBlunRequestExtraBytes(tools, messages);
231164
+ } catch {
231165
+ return;
231166
+ }
231167
+ if (Buffer.byteLength(JSON.stringify({
231168
+ systemPrompt,
231169
+ messages: []
231170
+ }), "utf8") >= BLUN_COMPACTION_REQUEST_BUDGET_BYTES) return void 0;
231171
+ return {
231172
+ usedRequestBytesEstimate: Buffer.byteLength(JSON.stringify({
231173
+ systemPrompt,
231174
+ messages
231175
+ }), "utf8") + extraBytes.toolsBytes + extraBytes.visionBytes,
231176
+ thresholdRequestBytes: BLUN_COMPACTION_REQUEST_BUDGET_BYTES
231177
+ };
231178
+ }
231048
231179
  requestProactiveCompaction(context = {}) {
231049
231180
  const status = this.proactiveCompactionStatus(context);
231050
231181
  if (status.eligible && !this.proactiveCompactionRequested) {
@@ -231053,7 +231184,9 @@ var init_full = __esmMin((() => {
231053
231184
  used_tokens: status.usedTokens,
231054
231185
  threshold_tokens: status.thresholdTokens,
231055
231186
  used_history_bytes: status.usedHistoryBytes,
231056
- threshold_history_bytes: status.thresholdHistoryBytes
231187
+ threshold_history_bytes: status.thresholdHistoryBytes,
231188
+ used_request_bytes_estimate: status.usedRequestBytesEstimate,
231189
+ threshold_request_bytes: status.thresholdRequestBytes
231057
231190
  });
231058
231191
  }
231059
231192
  return status;
@@ -231182,7 +231315,9 @@ var init_full = __esmMin((() => {
231182
231315
  const requestTokens = this.estimateCurrentRequestTokens(requestContext);
231183
231316
  const budget = this.getCompactionBudgetTokens();
231184
231317
  const historyBudget = this.requestHistoryByteBudget(projectedMessages);
231185
- const proactive = (historyBudget !== void 0 && historyBudget.usedHistoryBytes >= historyBudget.thresholdHistoryBytes || !this.isCompacting && budget !== void 0 && Number.isFinite(requestTokens) && requestTokens >= Math.max(1, Math.floor(budget * .9))) && this.hasShrinkableHistory(projectedMessages);
231318
+ const historyThresholdReached = historyBudget !== void 0 && historyBudget.usedHistoryBytes >= historyBudget.thresholdHistoryBytes;
231319
+ const requestBudget = this.requestBodyByteBudget(projectedMessages, requestContext);
231320
+ const proactive = (requestBudget !== void 0 && requestBudget.usedRequestBytesEstimate >= requestBudget.thresholdRequestBytes || historyThresholdReached || !this.isCompacting && budget !== void 0 && Number.isFinite(requestTokens) && requestTokens >= Math.max(1, Math.floor(budget * .9))) && this.hasShrinkableHistory(projectedMessages);
231186
231321
  if (this.checkAutoCompaction(true, requestTokens, projectedMessages, proactive) && (proactive || this.strategy.shouldBlock(requestTokens))) await this.block(signal);
231187
231322
  signal.throwIfAborted();
231188
231323
  const compacted = this.agent.context.history !== historyBefore;
@@ -231392,7 +231527,10 @@ var init_full = __esmMin((() => {
231392
231527
  dropOrphanResults: true
231393
231528
  }), createUserMessage(requestInstruction)], capability));
231394
231529
  };
231395
- const estimateRequestBytes = (messages) => Buffer.byteLength(JSON.stringify(messages), "utf8") + Buffer.byteLength(this.agent.config.systemPrompt, "utf8");
231530
+ const estimateRequestBytes = (messages) => Buffer.byteLength(JSON.stringify({
231531
+ systemPrompt: this.agent.effectiveSystemPrompt,
231532
+ messages
231533
+ }), "utf8");
231396
231534
  while (true) {
231397
231535
  signal.throwIfAborted();
231398
231536
  if (hierarchicalPassCount >= MAX_HIERARCHICAL_COMPACTION_PASSES) throw new BlunError(ErrorCodes.COMPACTION_FAILED, `Compaction stopped after ${String(MAX_HIERARCHICAL_COMPACTION_PASSES)} staged requests without reaching a final summary. The conversation history was not changed.`, { details: {
@@ -236113,7 +236251,7 @@ function structuredOutput(stdout, input) {
236113
236251
  return {
236114
236252
  ...result,
236115
236253
  additionalContext: input["hook_event_name"] === "UserPromptSubmit" && hookSpecificOutput?.hookEventName === "UserPromptSubmit" ? hookSpecificOutput.additionalContext : void 0,
236116
- updatedInput: input["hook_event_name"] === "PreToolUse" && hookSpecificOutput?.hookEventName === "PreToolUse" && isRecord$22(hookSpecificOutput.updatedInput) ? hookSpecificOutput.updatedInput : void 0
236254
+ updatedInput: input["hook_event_name"] === "PreToolUse" && hookSpecificOutput?.hookEventName === "PreToolUse" && isRecord$26(hookSpecificOutput.updatedInput) ? hookSpecificOutput.updatedInput : void 0
236117
236255
  };
236118
236256
  }
236119
236257
  return {
@@ -236182,7 +236320,7 @@ function killProcessTreeWindows(child, force) {
236182
236320
  } catch {}
236183
236321
  }
236184
236322
  }
236185
- function isRecord$22(value) {
236323
+ function isRecord$26(value) {
236186
236324
  return typeof value === "object" && value !== null && !Array.isArray(value);
236187
236325
  }
236188
236326
  function errorMessage$12(error) {
@@ -236199,7 +236337,7 @@ var init_runner = __esmMin((() => {
236199
236337
  if (typeof value === "string") return value;
236200
236338
  if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value);
236201
236339
  }, string().optional());
236202
- HookSpecificOutputSchema = preprocess((value) => isRecord$22(value) ? value : void 0, looseObject({
236340
+ HookSpecificOutputSchema = preprocess((value) => isRecord$26(value) ? value : void 0, looseObject({
236203
236341
  message: OptionalStringSchema,
236204
236342
  additionalContext: OptionalStringSchema,
236205
236343
  permissionDecision: unknown().optional(),
@@ -237487,7 +237625,7 @@ function parsePersonalMemoryRecall(output) {
237487
237625
  } catch {
237488
237626
  return { kind: "invalid" };
237489
237627
  }
237490
- if (!isRecord$21(parsed) || !isRecord$21(parsed["personal_memory"])) return { kind: "invalid" };
237628
+ if (!isRecord$25(parsed) || !isRecord$25(parsed["personal_memory"])) return { kind: "invalid" };
237491
237629
  const memory = parsed["personal_memory"];
237492
237630
  const savedRaw = memory["saved"];
237493
237631
  const threadsRaw = memory["threads"];
@@ -237496,7 +237634,7 @@ function parsePersonalMemoryRecall(output) {
237496
237634
  if (savedRaw.length > MAX_SAVED_MEMORIES || threadsRaw.length > MAX_THREADS || historyRaw.length > 0) return { kind: "invalid" };
237497
237635
  const saved = [];
237498
237636
  for (const value of savedRaw) {
237499
- if (!isRecord$21(value)) return { kind: "invalid" };
237637
+ if (!isRecord$25(value)) return { kind: "invalid" };
237500
237638
  const text = boundedTrimmedString(value["text"], MAX_MEMORY_TEXT_CHARS);
237501
237639
  const confidence = value["confidence"];
237502
237640
  if (text === void 0 || typeof confidence !== "string" || !CONFIDENCE_VALUES.has(confidence)) return { kind: "invalid" };
@@ -237507,7 +237645,7 @@ function parsePersonalMemoryRecall(output) {
237507
237645
  }
237508
237646
  const threads = [];
237509
237647
  for (const value of threadsRaw) {
237510
- if (!isRecord$21(value)) return { kind: "invalid" };
237648
+ if (!isRecord$25(value)) return { kind: "invalid" };
237511
237649
  const title = boundedTrimmedString(value["title"], MAX_THREAD_TITLE_CHARS);
237512
237650
  const summary = boundedTrimmedString(value["summary"], MAX_THREAD_SUMMARY_CHARS);
237513
237651
  if (title === void 0 || summary === void 0) return { kind: "invalid" };
@@ -237561,7 +237699,7 @@ function boundedTrimmedString(value, maxChars) {
237561
237699
  const trimmed = value.trim();
237562
237700
  return trimmed.length > 0 ? trimmed : void 0;
237563
237701
  }
237564
- function isRecord$21(value) {
237702
+ function isRecord$25(value) {
237565
237703
  return typeof value === "object" && value !== null && !Array.isArray(value);
237566
237704
  }
237567
237705
  var PERSONAL_MEMORY_HOST_RECALL_HANDLER$1, RECALL_LIMIT, RECALL_TIMEOUT_MS, MAX_QUERY_CHARS, MAX_WIRE_CHARS, MAX_SAVED_MEMORIES, MAX_THREADS, MAX_MEMORY_TEXT_CHARS, MAX_THREAD_TITLE_CHARS, MAX_THREAD_SUMMARY_CHARS, CONFIDENCE_VALUES, TELEGRAM_GROUP_MARKER_RE, TELEGRAM_MARKER_RE, TELEGRAM_CHANNEL_RE, TELEGRAM_SOURCE_RE, TELEGRAM_CHAT_ID_RE, TELEGRAM_SENDER_LINE_RE, TELEGRAM_ATTACHMENT_BLOCK_RE, TELEGRAM_ATTACHMENT_NOTICE_RE, TELEGRAM_IMAGE_ATTACHMENT_RE, GENERIC_IMAGE_QUERY, GENERIC_FILE_QUERY, GENERIC_EMPTY_QUERY, PERSONAL_MEMORY_RECALL_VARIANT, PersonalMemoryRecallInjector;
@@ -239793,6 +239931,32 @@ var require_turn_tool_performance_policy = /* @__PURE__ */ __commonJSMin(((expor
239793
239931
  "suchen"
239794
239932
  ]);
239795
239933
  const TOOL_SEARCH_RELATED_TERM_GROUPS = Object.freeze([
239934
+ Object.freeze([
239935
+ "persist",
239936
+ "save",
239937
+ "speichere",
239938
+ "speichern",
239939
+ "store"
239940
+ ]),
239941
+ Object.freeze([
239942
+ "erinnerung",
239943
+ "erinnerungen",
239944
+ "fact",
239945
+ "facts",
239946
+ "fakt",
239947
+ "fakten",
239948
+ "memory",
239949
+ "memories",
239950
+ "merk",
239951
+ "merken",
239952
+ "remember"
239953
+ ]),
239954
+ Object.freeze([
239955
+ "note",
239956
+ "notes",
239957
+ "notiz",
239958
+ "notizen"
239959
+ ]),
239796
239960
  Object.freeze([
239797
239961
  "checklist",
239798
239962
  "list",
@@ -239990,10 +240154,27 @@ var require_turn_tool_performance_policy = /* @__PURE__ */ __commonJSMin(((expor
239990
240154
  function relatedSearchTerms(token) {
239991
240155
  return TOOL_SEARCH_RELATED_TERM_GROUPS.find((terms) => terms.includes(token)) || [token];
239992
240156
  }
240157
+ function withoutFencedCode(value) {
240158
+ const visibleLines = [];
240159
+ let fence = null;
240160
+ for (const line of String(value || "").split(/\r?\n/)) {
240161
+ const marker = line.match(/^ {0,3}(`{3,}|~{3,})/u)?.[1];
240162
+ if (fence) {
240163
+ if (marker?.[0] === fence[0] && marker.length >= fence.length && /^ {0,3}(?:`{3,}|~{3,})[ \t]*$/u.test(line)) fence = null;
240164
+ continue;
240165
+ }
240166
+ if (marker) {
240167
+ fence = marker;
240168
+ continue;
240169
+ }
240170
+ visibleLines.push(line);
240171
+ }
240172
+ return visibleLines.join("\n");
240173
+ }
239993
240174
  function rankingIntentTexts(value) {
239994
240175
  const text = String(value || "");
239995
240176
  const channelBodies = [...text.matchAll(/(?:^|\r?\n)<channel\b[^>]*>\r?\n([\s\S]*?)\r?\n<\/channel>(?=\r?\n|$)/giu)].map((match) => match[1]);
239996
- return (channelBodies.length > 0 ? channelBodies : [text]).map((intentText) => normalizeDeferredToolQuery(intentText.replace(TOOL_RANK_EMBEDDED_CONTENT_RE, " ")));
240177
+ return (channelBodies.length > 0 ? channelBodies : [text]).map((intentText) => normalizeDeferredToolQuery(withoutFencedCode(intentText.replace(TOOL_RANK_EMBEDDED_CONTENT_RE, " "))));
239997
240178
  }
239998
240179
  function rankingTokens(value) {
239999
240180
  return [...new Set(String(value || "").normalize("NFKC").toLowerCase().match(/[\p{L}\p{N}]{3,}/gu) || [])].filter((token) => !TOOL_RANK_STOP_WORDS.has(token));
@@ -240051,7 +240232,7 @@ var require_turn_tool_performance_policy = /* @__PURE__ */ __commonJSMin(((expor
240051
240232
  if (document.nameTokens.has(token)) exactNameMatches += 1;
240052
240233
  else if (relatedSearchTerms(token).some((term) => document.nameTokens.has(term))) relatedNameMatches += 1;
240053
240234
  }
240054
- return matchedTokens >= 2 || exactNameMatches >= 1 && score >= 10 || relatedNameMatches >= 1 && score >= 5 ? {
240235
+ return matchedTokens >= 2 || exactNameMatches >= 1 && score >= 10 || queryTokens.length === 1 && relatedNameMatches >= 1 && score >= 5 ? {
240055
240236
  name: document.name,
240056
240237
  score,
240057
240238
  matchedTokens,
@@ -240072,11 +240253,11 @@ var require_turn_tool_performance_policy = /* @__PURE__ */ __commonJSMin(((expor
240072
240253
  function searchRelatedDeferredTools(tools, query, options = {}) {
240073
240254
  const normalized = normalizeDeferredToolQuery(query).toLowerCase();
240074
240255
  if (!normalized || normalized.startsWith("select:")) return [];
240075
- const tokens = normalized.split(/\s+/).filter(Boolean);
240256
+ const tokens = normalized.match(/\+?[\p{L}\p{N}_-]+/gu) || [];
240076
240257
  const requestedNameTokens = tokens.filter((token) => token.startsWith("+")).map((token) => token.slice(1)).filter(Boolean);
240077
240258
  const relaxRequiredNameTokens = options.relaxRequiredNameTokens === true && requestedNameTokens.length > 0;
240078
240259
  const requiredNameTokens = relaxRequiredNameTokens ? [] : requestedNameTokens;
240079
- const searchTokens = [...tokens.filter((token) => !token.startsWith("+")), ...relaxRequiredNameTokens ? requestedNameTokens : []].filter((token) => !TOOL_SEARCH_INTENT_WORDS.has(token));
240260
+ const searchTokens = [...tokens.filter((token) => !token.startsWith("+")), ...relaxRequiredNameTokens ? requestedNameTokens : []].filter((token) => !TOOL_SEARCH_INTENT_WORDS.has(token) && !TOOL_RANK_STOP_WORDS.has(token));
240080
240261
  if (searchTokens.length < 2 && !TOOL_SEARCH_SINGLE_TERM_RELATED_FALLBACKS.has(searchTokens[0])) return [];
240081
240262
  const minimumMatchedTokens = searchTokens.length === 1 ? 1 : Math.max(2, Math.ceil(searchTokens.length * .75));
240082
240263
  const ranked = tools.map((tool) => {
@@ -251089,7 +251270,8 @@ function logStepTiming(log, turnId, step, response) {
251089
251270
  inputOtherTokens: response.usage.inputOther,
251090
251271
  cacheReadTokens: response.usage.inputCacheRead,
251091
251272
  cacheCreationTokens: response.usage.inputCacheCreation,
251092
- outputTokens: response.usage.output
251273
+ outputTokens: response.usage.output,
251274
+ ...response.usage.outputReasoning === void 0 ? {} : { outputReasoningTokens: response.usage.outputReasoning }
251093
251275
  });
251094
251276
  }
251095
251277
  function deriveStepStopReason(response) {
@@ -252163,6 +252345,7 @@ var init_events$1 = __esmMin((() => {
252163
252345
  tokenUsageSchema = object$1({
252164
252346
  inputOther: number$1(),
252165
252347
  output: number$1(),
252348
+ outputReasoning: number$1().optional(),
252166
252349
  inputCacheRead: number$1(),
252167
252350
  inputCacheCreation: number$1()
252168
252351
  });
@@ -253343,7 +253526,7 @@ function createAsyncApiDocument(options = {}) {
253343
253526
  function buildMessages() {
253344
253527
  const messages = {};
253345
253528
  for (const operation of ASYNCAPI_OPERATIONS) {
253346
- const id = messageId$1(operation.type);
253529
+ const id = messageId$2(operation.type);
253347
253530
  messages[id] = asyncApiMessage(operation.type, operation.description, operation.messageSchema);
253348
253531
  if (operation.ackSchema !== void 0) {
253349
253532
  const ackId = `${id}_ack`;
@@ -253353,10 +253536,10 @@ function buildMessages() {
253353
253536
  return messages;
253354
253537
  }
253355
253538
  function operationMessageRefs(direction) {
253356
- return ASYNCAPI_OPERATIONS.filter((operation) => operation.direction === direction).map((operation) => ({ $ref: `#/components/messages/${messageId$1(operation.type)}` }));
253539
+ return ASYNCAPI_OPERATIONS.filter((operation) => operation.direction === direction).map((operation) => ({ $ref: `#/components/messages/${messageId$2(operation.type)}` }));
253357
253540
  }
253358
253541
  function ackMessageRefs() {
253359
- return ASYNCAPI_OPERATIONS.filter((operation) => operation.ackSchema !== void 0).map((operation) => ({ $ref: `#/components/messages/${messageId$1(operation.type)}_ack` }));
253542
+ return ASYNCAPI_OPERATIONS.filter((operation) => operation.ackSchema !== void 0).map((operation) => ({ $ref: `#/components/messages/${messageId$2(operation.type)}_ack` }));
253360
253543
  }
253361
253544
  function asyncApiMessage(name, summary, schema) {
253362
253545
  return {
@@ -253376,7 +253559,7 @@ function jsonSchema$1(schema) {
253376
253559
  delete converted["$schema"];
253377
253560
  return converted;
253378
253561
  }
253379
- function messageId$1(type) {
253562
+ function messageId$2(type) {
253380
253563
  return type.replace(/[^A-Za-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
253381
253564
  }
253382
253565
  function titleFromName(name) {
@@ -259155,7 +259338,7 @@ function Yn(s, t) {
259155
259338
  function Kn(s, t) {
259156
259339
  s.head = new ue$1(t, void 0, s.head, s), s.tail || (s.tail = s.head), s.length++;
259157
259340
  }
259158
- var zr, Ur, Ds, Wr, Gr, Zr, Q$1, J$1, nt$1, De$1, qt, Ne$1, Ns, Ae$1, As, z$1, Mt, g$1, Qt, Bt, b$1, N$1, _$1, bi, Ie$1, L$1, S, _i, Oi, Is, Ti, Z$1, xi, Ce$1, Jt$1, Rt, C, jt, Yr, Kr, Vr, $r, Fe$1, Li, Xr, qr, A$1, Jr, ht, H$1, te, m$1, Ni, tt$1, Ai, ki, vi, ie$1, ke$1, Ut$1, Ht, Ii, Pt, at, U$1, ot, Y$1, zt, Ci, j$1, ee$1, Fi, ve$1, gt$2, Me, bt, _t, Be$1, et$1, Wt$1, jr, Fs, ks, vs, Ms, Bs, tn, se$1, K$1, sn, M$1, rn, zs, nn, Bi, Tt, Gt, Pi, re, Pe$1, ze$1, Ue, He$1, We$1, Ge$1, Ze$1, Ye$1, Ke$1, Us, hn, an, Hs, ln, cn, Ws, Gs, Hi, ne, dn, Ui, oe$1, Ve$1, un, F$1, mn, xt, Wi, pn, lt, En, wn, Sn, ct, yn, Rn, gn, Gi, bn, Lt, ft, On, Tn, xn, f, $e$1, Dt, Nn, Xi, qi, An, B$1, Nt, it, Zi, Zs, V$1, he$1, dt, Ys, p, st$1, ut, Yi, At, w$1, Xe$1, qe$1, Ki, Ks, Vs, ae$1, Vi, Qe$1, Yt$1, $$1, Je$1, It, je$1, ti, $s, In, le$1, $i, Xs, Cn, rt$1, mt, vn, Qi, Mn, Bn, Ct, Ji, zn, qs, ce$1, ei, ji, Un, Hn, ts, Qs, rr, Wn, tr, er, ir, is$2, sr, fe$1, ii, ss, si, rs, ns, os$6, hs, pt, ri, as, es, q$1, de$1, ni, oi, Gn, hi, ue$1, pi, nr, li, me$1, W$1, pe$2, Et, Ft$1, Ee$1, ai, G, ls, ci, or, ds, us, fi, di, hr, cs, ui, lr, fs$11, wt, kt, Vn, $n, fr, dr, Xn, qn, Er, wr, ur, Sr, yr, Rr, jn, to, eo, mr, ms, ps, Ei, io, Es, so, ws, Se$1, St, no, gr, Ss, br, oo, _r, ys, Or, Vt$1, Tr, ao, lo, yi, Lr, Dr, _s, Nr, Os, P$1, Ts, xs, gi, Ar, Ir, Re, Cr, Fr, Rs, yt, O$1, Ri, kr, $t, gs, bs, Ls, ge$1, be, _e$1, Oe$1, Te$1, uo, mo, po, vr, Xt$1, ye$1, xe$1, Eo, wo, So, yo, Ro, go, bo, _o, vt, To;
259341
+ var zr, Ur, Ds, Wr, Gr, Zr, Q$1, J$1, nt$1, De$1, qt, Ne$1, Ns, Ae$1, As, z$1, Mt, g$1, Qt, Bt, b$1, N$1, _$1, bi, Ie$1, L$1, S, _i, Oi, Is, Ti, Z$1, xi, Ce$1, Jt$1, Rt, C, jt, Yr, Kr, Vr, $r, Fe$1, Li, Xr, qr, A$1, Jr, ht, H$1, te, m$1, Ni, tt$1, Ai, ki, vi, ie$1, ke$1, Ut$1, Ht, Ii, Pt, at, U$1, ot, Y$1, zt, Ci, j$1, ee$1, Fi, ve$1, gt$2, Me, bt, _t, Be$1, et$1, Wt$1, jr, Fs, ks, vs, Ms, Bs, tn, se$1, K$1, sn, M$1, rn, zs, nn, Bi, Tt, Gt, Pi, re, Pe$1, ze$1, Ue, He$1, We$1, Ge$1, Ze$1, Ye$1, Ke$1, Us, hn, an, Hs, ln, cn, Ws, Gs, Hi, ne, dn, Ui, oe$1, Ve$1, un, F$1, mn, xt, Wi, pn, lt, En, wn, Sn, ct, yn, Rn, gn, Gi, bn, Lt, ft, On, Tn, xn, f, $e$1, Dt, Nn, Xi, qi, An, B$1, Nt, it, Zi, Zs, V$1, he$1, dt, Ys, p, st$1, ut, Yi, At, w$1, Xe$1, qe$1, Ki, Ks, Vs, ae$1, Vi, Qe$1, Yt$1, $$1, Je$1, It, je$1, ti, $s, In, le$1, $i, Xs, Cn, rt$1, mt, vn, Qi, Mn, Bn, Ct, Ji, zn, qs, ce$1, ei, ji, Un, Hn, ts, Qs, rr, Wn, tr, er, ir, is$2, sr, fe$1, ii, ss, si, rs, ns, os$6, hs, pt, ri, as, es, q$1, de$1, ni, oi, Gn, hi, ue$1, pi, nr, li, me$1, W$1, pe$2, Et, Ft$1, Ee$1, ai, G, ls, ci, or, ds, us, fi, di, hr, cs, ui, lr, fs$12, wt, kt, Vn, $n, fr, dr, Xn, qn, Er, wr, ur, Sr, yr, Rr, jn, to, eo, mr, ms, ps, Ei, io, Es, so, ws, Se$1, St, no, gr, Ss, br, oo, _r, ys, Or, Vt$1, Tr, ao, lo, yi, Lr, Dr, _s, Nr, Os, P$1, Ts, xs, gi, Ar, Ir, Re, Cr, Fr, Rs, yt, O$1, Ri, kr, $t, gs, bs, Ls, ge$1, be, _e$1, Oe$1, Te$1, uo, mo, po, vr, Xt$1, ye$1, xe$1, Eo, wo, So, yo, Ro, go, bo, _o, vt, To;
259159
259342
  var init_index_min = __esmMin((() => {
259160
259343
  zr = Object.defineProperty;
259161
259344
  Ur = (s, t) => {
@@ -261125,7 +261308,7 @@ while (this[Zs](this[st$1].shift()));
261125
261308
  constructor(t, e) {
261126
261309
  this.path = t || "./", this.absolute = e;
261127
261310
  }
261128
- }, nr = Buffer.alloc(1024), li = Symbol("onStat"), me$1 = Symbol("ended"), W$1 = Symbol("queue"), pe$2 = Symbol("pendingLinks"), Et = Symbol("current"), Ft$1 = Symbol("process"), Ee$1 = Symbol("processing"), ai = Symbol("processJob"), G = Symbol("jobs"), ls = Symbol("jobDone"), ci = Symbol("addFSEntry"), or = Symbol("addTarEntry"), ds = Symbol("stat"), us = Symbol("readdir"), fi = Symbol("onreaddir"), di = Symbol("pipe"), hr = Symbol("entry"), cs = Symbol("entryOpt"), ui = Symbol("writeEntryClass"), lr = Symbol("write"), fs$11 = Symbol("ondrain"), wt = class extends A$1 {
261311
+ }, nr = Buffer.alloc(1024), li = Symbol("onStat"), me$1 = Symbol("ended"), W$1 = Symbol("queue"), pe$2 = Symbol("pendingLinks"), Et = Symbol("current"), Ft$1 = Symbol("process"), Ee$1 = Symbol("processing"), ai = Symbol("processJob"), G = Symbol("jobs"), ls = Symbol("jobDone"), ci = Symbol("addFSEntry"), or = Symbol("addTarEntry"), ds = Symbol("stat"), us = Symbol("readdir"), fi = Symbol("onreaddir"), di = Symbol("pipe"), hr = Symbol("entry"), cs = Symbol("entryOpt"), ui = Symbol("writeEntryClass"), lr = Symbol("write"), fs$12 = Symbol("ondrain"), wt = class extends A$1 {
261129
261312
  sync = !1;
261130
261313
  opt;
261131
261314
  cwd;
@@ -261158,8 +261341,8 @@ while (this[Zs](this[st$1].shift()));
261158
261341
  if ((t.gzip ? 1 : 0) + (t.brotli ? 1 : 0) + (t.zstd ? 1 : 0) > 1) throw new TypeError("gzip, brotli, zstd are mutually exclusive");
261159
261342
  if (t.gzip && (typeof t.gzip != "object" && (t.gzip = {}), this.portable && (t.gzip.portable = !0), this.zip = new ze$1(t.gzip)), t.brotli && (typeof t.brotli != "object" && (t.brotli = {}), this.zip = new We$1(t.brotli)), t.zstd && (typeof t.zstd != "object" && (t.zstd = {}), this.zip = new Ye$1(t.zstd)), !this.zip) throw new Error("impossible");
261160
261343
  let e = this.zip;
261161
- e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[fs$11]()), this.on("resume", () => e.resume());
261162
- } else this.on("drain", this[fs$11]);
261344
+ e.on("data", (i) => super.write(i)), e.on("end", () => super.end()), e.on("drain", () => this[fs$12]()), this.on("resume", () => e.resume());
261345
+ } else this.on("drain", this[fs$12]);
261163
261346
  this.noDirRecurse = !!t.noDirRecurse, this.follow = !!t.follow, this.noMtime = !!t.noMtime, t.mtime && (this.mtime = t.mtime), this.filter = typeof t.filter == "function" ? t.filter : () => !0, this[W$1] = new hi(), this[G] = 0, this.jobs = Number(t.jobs) || 4, this[Ee$1] = !1, this[me$1] = !1;
261164
261347
  }
261165
261348
  [lr](t) {
@@ -261286,7 +261469,7 @@ while (this[Zs](this[st$1].shift()));
261286
261469
  this.emit("error", e);
261287
261470
  }
261288
261471
  }
261289
- [fs$11]() {
261472
+ [fs$12]() {
261290
261473
  this[Et] && this[Et].entry && this[Et].entry.resume();
261291
261474
  }
261292
261475
  [di](t) {
@@ -261452,7 +261635,7 @@ while (this[Zs](this[st$1].shift()));
261452
261635
  E ? e(E) : x && a ? Es(x, o, h, (Le) => y(Le)) : n ? Kt.chmod(s, r, e) : e();
261453
261636
  };
261454
261637
  if (s === d) return no(s, y);
261455
- if (l) return ro.mkdir(s, {
261638
+ if (l) return fs.mkdir(s, {
261456
261639
  mode: r,
261457
261640
  recursive: !0
261458
261641
  }).then((E) => y(null, E ?? void 0), y);
@@ -262211,7 +262394,7 @@ var require_pend = /* @__PURE__ */ __commonJSMin(((exports, module) => {
262211
262394
  //#endregion
262212
262395
  //#region ../../node_modules/.pnpm/yauzl@3.3.0/node_modules/yauzl/fd-slicer.js
262213
262396
  var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
262214
- var fs$10 = __require("fs");
262397
+ var fs$11 = __require("fs");
262215
262398
  var util$6 = __require("util");
262216
262399
  var stream$2 = __require("stream");
262217
262400
  var Readable = stream$2.Readable;
@@ -262236,7 +262419,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
262236
262419
  FdSlicer.prototype.read = function(buffer, offset, length, position, callback) {
262237
262420
  var self = this;
262238
262421
  self.pend.go(function(cb) {
262239
- fs$10.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer) {
262422
+ fs$11.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer) {
262240
262423
  cb();
262241
262424
  callback(err, bytesRead, buffer);
262242
262425
  });
@@ -262245,7 +262428,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
262245
262428
  FdSlicer.prototype.write = function(buffer, offset, length, position, callback) {
262246
262429
  var self = this;
262247
262430
  self.pend.go(function(cb) {
262248
- fs$10.write(self.fd, buffer, offset, length, position, function(err, written, buffer) {
262431
+ fs$11.write(self.fd, buffer, offset, length, position, function(err, written, buffer) {
262249
262432
  cb();
262250
262433
  callback(err, written, buffer);
262251
262434
  });
@@ -262265,7 +262448,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
262265
262448
  self.refCount -= 1;
262266
262449
  if (self.refCount > 0) return;
262267
262450
  if (self.refCount < 0) throw new Error("invalid unref");
262268
- if (self.autoClose) fs$10.close(self.fd, onCloseDone);
262451
+ if (self.autoClose) fs$11.close(self.fd, onCloseDone);
262269
262452
  function onCloseDone(err) {
262270
262453
  if (err) self.emit("error", err);
262271
262454
  else self.emit("close");
@@ -262296,7 +262479,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
262296
262479
  self.context.pend.go(function(cb) {
262297
262480
  if (self.destroyed) return cb();
262298
262481
  var buffer = Buffer.allocUnsafe(toRead);
262299
- fs$10.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) {
262482
+ fs$11.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) {
262300
262483
  if (err) self.destroy(err);
262301
262484
  else if (bytesRead === 0) {
262302
262485
  self.destroyed = true;
@@ -262342,7 +262525,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
262342
262525
  }
262343
262526
  self.context.pend.go(function(cb) {
262344
262527
  if (self.destroyed) return cb();
262345
- fs$10.write(self.context.fd, buffer, 0, buffer.length, self.pos, function(err, bytes) {
262528
+ fs$11.write(self.context.fd, buffer, 0, buffer.length, self.pos, function(err, bytes) {
262346
262529
  if (err) {
262347
262530
  self.destroy();
262348
262531
  cb();
@@ -268826,6 +269009,7 @@ var init_turn = __esmMin((() => {
268826
269009
  const appendedMessage = this.agent.context.history.at(-1);
268827
269010
  const turnAnchor = appendedMessage !== previousLastMessage && appendedMessage?.role === "user" && appendedMessage.origin === origin ? appendedMessage : void 0;
268828
269011
  const startedAt = Date.now();
269012
+ const preRequestHookStartedAt = performance.now();
268829
269013
  let ended;
268830
269014
  let blockedByUserPromptHook = false;
268831
269015
  let completedStopReason;
@@ -268851,6 +269035,13 @@ var init_turn = __esmMin((() => {
268851
269035
  this.agent.log.warn("Turn-start observation failed");
268852
269036
  }
268853
269037
  signal.throwIfAborted();
269038
+ if (this.agent.type === "main" && process.env["BLUN_DIAG_PRE_REQUEST_PHASES"] === "1") try {
269039
+ this.agent.log.info("turn pre-request phase", {
269040
+ turnId,
269041
+ phase: "turn-hooks",
269042
+ durationMs: Math.max(0, Math.round(performance.now() - preRequestHookStartedAt))
269043
+ });
269044
+ } catch {}
268854
269045
  const stopReason = await this.runStepLoop(turnId, signal, input, origin, turnAnchor, (response) => {
268855
269046
  completedResponse = response;
268856
269047
  });
@@ -268962,6 +269153,10 @@ var init_turn = __esmMin((() => {
268962
269153
  signal.throwIfAborted();
268963
269154
  const blockResult = renderUserPromptHookBlockResult(promptHookResults);
268964
269155
  if (blockResult !== void 0) {
269156
+ this.agent.log.warn("turn blocked by UserPromptSubmit hook", {
269157
+ turnId,
269158
+ reason: blockResult.message
269159
+ });
268965
269160
  this.agent.context.appendMessage({
268966
269161
  role: "assistant",
268967
269162
  content: [{
@@ -269020,9 +269215,26 @@ var init_turn = __esmMin((() => {
269020
269215
  let stopHookContinuationUsed = false;
269021
269216
  let goalOutcomeMessageContinuationUsed = false;
269022
269217
  const deduper = new ToolCallDeduplicator({ telemetry: this.agent.telemetry });
269218
+ const diagnosePreRequest = this.agent.type === "main" && process.env["BLUN_DIAG_PRE_REQUEST_PHASES"] === "1";
269219
+ const recordPreRequestPhase = (phase, startedAt) => {
269220
+ if (!diagnosePreRequest) return;
269221
+ try {
269222
+ this.agent.log.info("turn pre-request phase", {
269223
+ turnId,
269224
+ phase,
269225
+ durationMs: Math.max(0, Math.round(performance.now() - startedAt))
269226
+ });
269227
+ } catch {}
269228
+ };
269229
+ let phaseStartedAt = performance.now();
269023
269230
  await this.agent.mcp?.waitForInitialLoad(signal);
269231
+ recordPreRequestPhase("mcp-initial-load", phaseStartedAt);
269232
+ phaseStartedAt = performance.now();
269024
269233
  const personalMemoryRecall = await this.agent.injection.injectPersonalMemoryForTurn(turnId, input, origin, signal);
269234
+ recordPreRequestPhase("personal-memory-recall", phaseStartedAt);
269235
+ phaseStartedAt = performance.now();
269025
269236
  await this.agent.injection.injectGoal();
269237
+ recordPreRequestPhase("goal-injection", phaseStartedAt);
269026
269238
  this.setActiveSteerAcceptance(turnId, true);
269027
269239
  const turnNeedsThinking = blunTurnNeedsTools(blunThinkingIntentInput(input), origin);
269028
269240
  let toolInput = input;
@@ -269033,12 +269245,14 @@ var init_turn = __esmMin((() => {
269033
269245
  const raw = [...this.agent.context.history];
269034
269246
  const history = personalMemoryRecall === void 0 ? raw : [...raw, personalMemoryRecall];
269035
269247
  const selected = taskToolsNeeded ? history : greetingHistory(history, greetingAnchor);
269248
+ const projectionStartedAt = performance.now();
269036
269249
  const projected = await this.historicalToolProjection.project(selected, turnAnchor, tools, {
269037
269250
  turnId: String(turnId),
269038
269251
  stepNumber: this.currentStep,
269039
269252
  signal,
269040
269253
  llm: turnLLM
269041
269254
  });
269255
+ recordPreRequestPhase("historical-tool-projection", projectionStartedAt);
269042
269256
  const current = this.agent.context.history;
269043
269257
  if (current.length !== raw.length || current.some((message, index) => message !== raw[index])) {
269044
269258
  const latest = personalMemoryRecall === void 0 ? current : [...current, personalMemoryRecall];
@@ -269049,7 +269263,7 @@ var init_turn = __esmMin((() => {
269049
269263
  partialContext = selected.length < history.length || projected.changed;
269050
269264
  return projected.history;
269051
269265
  };
269052
- const turnLLM = this.agent.llmForTurn(turnNeedsThinking ? void 0 : "off");
269266
+ const turnLLM = this.agent.llmForTurn(turnNeedsThinking ? void 0 : "off", turnId);
269053
269267
  const turnTools = this.agent.tools.captureTurnTools();
269054
269268
  while (true) {
269055
269269
  signal.throwIfAborted();
@@ -269059,6 +269273,7 @@ var init_turn = __esmMin((() => {
269059
269273
  try {
269060
269274
  const selectedTools = [];
269061
269275
  this.refreshSelectedTools = (snapshot) => {
269276
+ const selectionStartedAt = performance.now();
269062
269277
  if (snapshot.messages.length > 0) toolInput = snapshot.messages.flatMap((message) => message.content);
269063
269278
  const eligibleTools = blunToolsForOrigin(this.agent.injection.filterPersonalMemoryToolsForTurn(turnId, input, origin, turnTools()), origin);
269064
269279
  const intent = blunThinkingIntentInput(toolInput);
@@ -269071,6 +269286,7 @@ var init_turn = __esmMin((() => {
269071
269286
  if (tool !== void 0 && !selectedTools.some((candidate) => candidate.name === name) && estimateTokensForTools([...selectedTools, tool]) <= (0, import_turn_tool_performance_policy.toolSchemaBudgetTokens)(this.agent.config.modelCapabilities?.max_context_tokens)) selectedTools.push(tool);
269072
269287
  }
269073
269288
  } else selectedTools.splice(0, selectedTools.length, ...eligibleTools.filter((tool) => BLUN_LANGUAGE_REVIEW_TOOL_NAMES.has(tool.name) || BLUN_TELEGRAM_OUTBOUND_TOOL_RE.test(tool.name)));
269289
+ recordPreRequestPhase("tool-selection", selectionStartedAt);
269074
269290
  return selectedTools;
269075
269291
  };
269076
269292
  return (await runTurn({
@@ -269083,14 +269299,24 @@ var init_turn = __esmMin((() => {
269083
269299
  }, completion);
269084
269300
  },
269085
269301
  llm: turnLLM,
269086
- buildMessages: async () => this.agent.context.project(await turnHistory(selectedTools), { dropOrphanResults: true }),
269087
- buildMessagesStrict: async () => this.agent.context.project(await turnHistory(selectedTools), {
269088
- synthesizeMissing: true,
269089
- dropOrphanResults: true,
269090
- dedupeDuplicateToolCalls: true,
269091
- dropLeadingNonUser: true,
269092
- mergeConsecutiveAssistants: true
269093
- }),
269302
+ buildMessages: async () => {
269303
+ const startedAt = performance.now();
269304
+ const messages = this.agent.context.project(await turnHistory(selectedTools), { dropOrphanResults: true });
269305
+ recordPreRequestPhase("message-build", startedAt);
269306
+ return messages;
269307
+ },
269308
+ buildMessagesStrict: async () => {
269309
+ const startedAt = performance.now();
269310
+ const messages = this.agent.context.project(await turnHistory(selectedTools), {
269311
+ synthesizeMissing: true,
269312
+ dropOrphanResults: true,
269313
+ dedupeDuplicateToolCalls: true,
269314
+ dropLeadingNonUser: true,
269315
+ mergeConsecutiveAssistants: true
269316
+ });
269317
+ recordPreRequestPhase("message-build-strict", startedAt);
269318
+ return messages;
269319
+ },
269094
269320
  dispatchEvent: this.buildDispatchEvent(turnId, signal, onFinalResponse, () => partialContext),
269095
269321
  tools: selectedTools,
269096
269322
  log: this.agent.log,
@@ -269107,8 +269333,10 @@ var init_turn = __esmMin((() => {
269107
269333
  },
269108
269334
  hooks: {
269109
269335
  beforeStep: async ({ signal: stepSignal, llm }) => {
269336
+ const injectionStartedAt = performance.now();
269110
269337
  this.agent.microCompaction.detect();
269111
269338
  await this.agent.injection.inject();
269339
+ recordPreRequestPhase("step-injection", injectionStartedAt);
269112
269340
  stepSignal.throwIfAborted();
269113
269341
  deduper.beginStep();
269114
269342
  },
@@ -269146,6 +269374,17 @@ var init_turn = __esmMin((() => {
269146
269374
  signal.throwIfAborted();
269147
269375
  if (stopBlock !== void 0) {
269148
269376
  stopHookContinuationUsed = true;
269377
+ this.agent.log.warn("turn continuation blocked by Stop hook", {
269378
+ turnId,
269379
+ reason: stopBlock.reason
269380
+ });
269381
+ this.agent.emitEvent({
269382
+ type: "hook.result",
269383
+ turnId,
269384
+ hookEvent: "Stop",
269385
+ content: stopBlock.reason,
269386
+ blocked: true
269387
+ });
269149
269388
  this.agent.context.appendUserMessage([{
269150
269389
  type: "text",
269151
269390
  text: stopBlock.reason
@@ -272612,6 +272851,7 @@ var init_fallback_llm = __esmMin((() => {
272612
272851
  throw new Error("Fallback request preparation requires a fresh request boundary.");
272613
272852
  }
272614
272853
  let requestParams = params;
272854
+ let messagesReady = false;
272615
272855
  const rebuildRequestMessages = async () => {
272616
272856
  const messages = await rebuildMessages();
272617
272857
  const suffix = requestParams.boundaryMessageSuffix;
@@ -272620,7 +272860,14 @@ var init_fallback_llm = __esmMin((() => {
272620
272860
  while (true) {
272621
272861
  const candidate = this.current;
272622
272862
  try {
272623
- requestParams = await this.prepareRequest?.(candidate, requestParams, rebuildRequestMessages) ?? requestParams;
272863
+ const prepared = await this.prepareRequest?.(candidate, requestParams, rebuildRequestMessages);
272864
+ if (prepared !== void 0) if ("messagesReady" in prepared) {
272865
+ requestParams = prepared.params;
272866
+ messagesReady = true;
272867
+ } else {
272868
+ requestParams = prepared;
272869
+ messagesReady = false;
272870
+ }
272624
272871
  } catch (error) {
272625
272872
  if (!isFallbackCandidateError(error) && !isUnavailableFallbackCandidate(error)) throw error;
272626
272873
  const nextIndex = this.findNextCandidateIndex();
@@ -272630,13 +272877,14 @@ var init_fallback_llm = __esmMin((() => {
272630
272877
  ...requestParams,
272631
272878
  messages: await rebuildRequestMessages()
272632
272879
  };
272880
+ messagesReady = false;
272633
272881
  requestParams.signal.throwIfAborted();
272634
272882
  this.currentIndex = nextIndex;
272635
272883
  this.onModelChanged(this.current.alias);
272636
272884
  continue;
272637
272885
  }
272638
272886
  requestParams.signal.throwIfAborted();
272639
- const messages = await rebuildRequestMessages();
272887
+ const messages = messagesReady ? requestParams.messages : await rebuildRequestMessages();
272640
272888
  requestParams.signal.throwIfAborted();
272641
272889
  return {
272642
272890
  ...requestParams,
@@ -272760,7 +273008,8 @@ function copyContributions(value) {
272760
273008
  version: source.version,
272761
273009
  totalBytes: source.totalBytes,
272762
273010
  generatedBytes: source.generatedBytes,
272763
- files: source.files.map((file) => copyInstructionFileBytes(file))
273011
+ files: source.files.map((file) => copyInstructionFileBytes(file)),
273012
+ ...source.notLoadedCandidates === void 0 ? {} : { notLoadedCandidates: [...source.notLoadedCandidates] }
272764
273013
  } }
272765
273014
  };
272766
273015
  }
@@ -272799,8 +273048,13 @@ var init_llm_request_logger = __esmMin((() => {
272799
273048
  toolsEstimatedTokens = 0;
272800
273049
  requestSequence = 0;
272801
273050
  lastTurnRequest;
272802
- constructor(log) {
273051
+ serializedPrefixKey;
273052
+ requestSignatures = /* @__PURE__ */ new Map();
273053
+ prefixComparisons = /* @__PURE__ */ new Map();
273054
+ lastSerializedRequest;
273055
+ constructor(log, serializedPrefixDiagnostic = process.env["BLUN_DIAG_SERIALIZED_PREFIX"] === "1") {
272803
273056
  this.log = log;
273057
+ this.serializedPrefixKey = serializedPrefixDiagnostic ? randomBytes(32) : void 0;
272804
273058
  }
272805
273059
  logRequest(input) {
272806
273060
  const sequence = ++this.requestSequence;
@@ -272817,6 +273071,10 @@ var init_llm_request_logger = __esmMin((() => {
272817
273071
  toolsHash: fingerprint(JSON.stringify(toolSignature(tools)))
272818
273072
  };
272819
273073
  const signature = JSON.stringify(config);
273074
+ if (this.serializedPrefixKey !== void 0) {
273075
+ this.requestSignatures.set(sequence, signature);
273076
+ if (this.requestSignatures.size > 32) this.requestSignatures.delete(this.requestSignatures.keys().next().value);
273077
+ }
272820
273078
  if (signature !== this.lastConfigLogSignature) {
272821
273079
  this.lastConfigLogSignature = signature;
272822
273080
  this.configRevision++;
@@ -272846,6 +273104,20 @@ var init_llm_request_logger = __esmMin((() => {
272846
273104
  }
272847
273105
  };
272848
273106
  if (partialMessageCount > 0) requestFields.partialMessageCount = partialMessageCount;
273107
+ const source = input.systemPromptContributions;
273108
+ if (source?.version === 1 && [
273109
+ source.totalBytes,
273110
+ source.instructionBytes,
273111
+ source.skillListingBytes,
273112
+ source.runtimeMemoryBytes,
273113
+ source.otherBytes
273114
+ ].every((value) => Number.isSafeInteger(value) && value >= 0) && source.instructionBytes + source.skillListingBytes + source.runtimeMemoryBytes + source.otherBytes === source.totalBytes && source.totalBytes === Buffer.byteLength(systemPrompt, "utf8")) requestFields.systemPromptSourceBytes = {
273115
+ totalBytes: source.totalBytes,
273116
+ instructionBytes: source.instructionBytes,
273117
+ skillListingBytes: source.skillListingBytes,
273118
+ runtimeMemoryBytes: source.runtimeMemoryBytes,
273119
+ otherBytes: source.otherBytes
273120
+ };
272849
273121
  this.log.info("llm request", requestFields);
272850
273122
  if (fields?.turnStep !== void 0 && /^\d+\.\d+$/.test(fields.turnStep)) {
272851
273123
  const historyTextOrigins = summarizeRequestTextOrigins(messages);
@@ -272871,10 +273143,51 @@ var init_llm_request_logger = __esmMin((() => {
272871
273143
  getLastTurnRequest() {
272872
273144
  return this.lastTurnRequest === void 0 ? void 0 : structuredClone(this.lastTurnRequest);
272873
273145
  }
273146
+ get serializedPrefixDiagnosticEnabled() {
273147
+ return this.serializedPrefixKey !== void 0;
273148
+ }
273149
+ observeSerializedRequest(body, fields, sequence) {
273150
+ const key = this.serializedPrefixKey;
273151
+ if (key === void 0 || !/^\d+\.\d+$/.test(fields?.turnStep ?? "")) return;
273152
+ const signature = this.requestSignatures.get(sequence);
273153
+ if (signature === void 0) return;
273154
+ try {
273155
+ const bytes = Buffer.from(body, "utf8");
273156
+ const granularityBytes = 1024;
273157
+ const chunks = [];
273158
+ for (let start = 0; start + granularityBytes <= bytes.length; start += granularityBytes) chunks.push(createHmac("sha256", key).update(bytes.subarray(start, start + granularityBytes)).digest("hex"));
273159
+ const previous = this.lastSerializedRequest;
273160
+ if (previous !== void 0 && previous.signature === signature) {
273161
+ let common = 0;
273162
+ while (common < previous.chunks.length && common < chunks.length && previous.chunks[common] === chunks[common]) common++;
273163
+ this.prefixComparisons.set(sequence, {
273164
+ version: 1,
273165
+ granularityBytes,
273166
+ previousBytes: previous.bytes,
273167
+ currentBytes: bytes.length,
273168
+ commonPrefixBytesLowerBound: common * granularityBytes,
273169
+ previousSequence: previous.sequence,
273170
+ currentSequence: sequence
273171
+ });
273172
+ if (this.prefixComparisons.size > 32) this.prefixComparisons.delete(this.prefixComparisons.keys().next().value);
273173
+ }
273174
+ this.lastSerializedRequest = {
273175
+ sequence,
273176
+ signature,
273177
+ bytes: bytes.length,
273178
+ chunks
273179
+ };
273180
+ } catch {
273181
+ this.lastSerializedRequest = void 0;
273182
+ }
273183
+ }
272874
273184
  logTransportAttempt(stats, fields, sequence) {
273185
+ const serializedPrefix = sequence === void 0 ? void 0 : this.prefixComparisons.get(sequence);
272875
273186
  this.log.info("llm transport attempt", {
272876
273187
  ...fields,
272877
- ...stats
273188
+ ...stats,
273189
+ ...this.serializedPrefixKey === void 0 || sequence === void 0 ? {} : { requestSequence: sequence },
273190
+ ...serializedPrefix === void 0 ? {} : { serializedPrefix }
272878
273191
  });
272879
273192
  if (sequence === void 0 || this.lastTurnRequest?.sequence !== sequence) return;
272880
273193
  const breakdown = stats.requestBreakdown;
@@ -272896,6 +273209,11 @@ var init_llm_request_logger = __esmMin((() => {
272896
273209
  systemMessageBytes: breakdown.systemMessageBytes,
272897
273210
  conversationMessageBytes: breakdown.conversationMessageBytes,
272898
273211
  toolResultMessageBytes: breakdown.toolResultMessageBytes,
273212
+ ...breakdown.toolResultByTool === void 0 ? {} : { toolResultByTool: breakdown.toolResultByTool.map((tool) => ({
273213
+ count: tool.count,
273214
+ bytes: tool.bytes,
273215
+ ...tool.name === void 0 ? {} : { name: tool.name }
273216
+ })) },
272899
273217
  toolSchemaBytes: breakdown.toolSchemaBytes,
272900
273218
  otherBytes: breakdown.otherBytes,
272901
273219
  ...breakdown.toolArrayOverheadBytes === void 0 ? {} : { toolArrayOverheadBytes: breakdown.toolArrayOverheadBytes },
@@ -273022,6 +273340,7 @@ var init_agent = __esmMin((() => {
273022
273340
  errorMemory;
273023
273341
  replayBuilder;
273024
273342
  additionalDirs;
273343
+ systemPromptStartedAt = /* @__PURE__ */ new Date();
273025
273344
  activeProfile;
273026
273345
  brandHome;
273027
273346
  _activeResponderModel;
@@ -273109,6 +273428,7 @@ var init_agent = __esmMin((() => {
273109
273428
  const retryScope = providerRetryScope(modelAlias, provider);
273110
273429
  await this.providerRetryWait.wait(retryScope, generateOptions?.signal);
273111
273430
  const callerTransportAttempt = generateOptions?.onTransportAttempt;
273431
+ const callerSerializedRequest = generateOptions?.onSerializedRequest;
273112
273432
  const ownedGenerateOptions = {
273113
273433
  ...generateOptions,
273114
273434
  transportMaxRetries: 0
@@ -273131,6 +273451,12 @@ var init_agent = __esmMin((() => {
273131
273451
  callerTransportAttempt?.(stats);
273132
273452
  this.llmRequestLogger.logTransportAttempt(stats, requestLogFields, requestSequence);
273133
273453
  },
273454
+ ...callerSerializedRequest !== void 0 || this.llmRequestLogger.serializedPrefixDiagnosticEnabled ? { onSerializedRequest: (body) => {
273455
+ try {
273456
+ callerSerializedRequest?.(body);
273457
+ } catch {}
273458
+ this.llmRequestLogger.observeSerializedRequest(body, requestLogFields, requestSequence);
273459
+ } } : {},
273134
273460
  onRequestStart: () => {
273135
273461
  requestOptions?.onRequestStart?.();
273136
273462
  requestStarted = true;
@@ -273156,7 +273482,7 @@ var init_agent = __esmMin((() => {
273156
273482
  get llm() {
273157
273483
  return this.llmForTurn();
273158
273484
  }
273159
- llmForTurn(thinkingEffort) {
273485
+ llmForTurn(thinkingEffort, diagnosticTurnId) {
273160
273486
  const selectedAlias = this.config.model;
273161
273487
  const modelProvider = this.modelProvider;
273162
273488
  if (modelProvider === void 0) throw new BlunError(ErrorCodes.MODEL_NOT_CONFIGURED, "Provider not set");
@@ -273171,6 +273497,7 @@ var init_agent = __esmMin((() => {
273171
273497
  messages: await rebuildMessages()
273172
273498
  };
273173
273499
  let systemPrompt = this.effectiveSystemPrompt;
273500
+ const preflightStartedAt = performance.now();
273174
273501
  const compacted = await this.fullCompaction.beforeStep(params.signal, {
273175
273502
  messages: params.messages,
273176
273503
  additionalMessages: steers.messages,
@@ -273179,17 +273506,31 @@ var init_agent = __esmMin((() => {
273179
273506
  rebuildSystemPrompt: () => systemPrompt = this.effectiveSystemPrompt,
273180
273507
  tools: params.tools
273181
273508
  });
273509
+ if (this.type === "main" && diagnosticTurnId !== void 0 && process.env["BLUN_DIAG_PRE_REQUEST_PHASES"] === "1") try {
273510
+ this.log.info("turn pre-request phase", {
273511
+ turnId: diagnosticTurnId,
273512
+ phase: "compaction-preflight",
273513
+ durationMs: Math.max(0, Math.round(performance.now() - preflightStartedAt))
273514
+ });
273515
+ } catch {}
273182
273516
  const tools = params.tools.some((tool) => tool.name === "CompactConversation") && !this.fullCompaction.proactiveCompactionStatus({
273183
273517
  messages: compacted ? await rebuildMessages() : params.messages,
273184
273518
  additionalMessages: steers.messages,
273185
273519
  systemPrompt,
273186
273520
  tools: params.tools
273187
273521
  }).eligible ? params.tools.filter((tool) => tool.name !== "CompactConversation") : params.tools;
273188
- this.turn.commitPendingSteers(steers);
273189
- return {
273522
+ const steersCommitted = this.turn.commitPendingSteers(steers);
273523
+ if (compacted || steersCommitted) params = {
273190
273524
  ...params,
273191
- systemPrompt,
273192
- tools
273525
+ messages: await rebuildMessages()
273526
+ };
273527
+ return {
273528
+ params: {
273529
+ ...params,
273530
+ systemPrompt,
273531
+ tools
273532
+ },
273533
+ messagesReady: true
273193
273534
  };
273194
273535
  }, (candidate, _params, error) => {
273195
273536
  this.fullCompaction.observeContextOverflow(error, candidate.alias);
@@ -273283,6 +273624,7 @@ var init_agent = __esmMin((() => {
273283
273624
  let contributions;
273284
273625
  const systemPrompt = profile.systemPrompt({
273285
273626
  osEnv: this.kaos.osEnv,
273627
+ now: this.systemPromptStartedAt,
273286
273628
  cwd: this.config.cwd,
273287
273629
  skills: this.skills?.registry,
273288
273630
  cwdListing: context?.cwdListing,
@@ -303200,7 +303542,7 @@ var init_proxy = __esmMin((() => {
303200
303542
  var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303201
303543
  module.exports = isexe;
303202
303544
  isexe.sync = sync;
303203
- var fs$8 = __require("fs");
303545
+ var fs$9 = __require("fs");
303204
303546
  function checkPathExt(path, options) {
303205
303547
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
303206
303548
  if (!pathext) return true;
@@ -303217,12 +303559,12 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303217
303559
  return checkPathExt(path, options);
303218
303560
  }
303219
303561
  function isexe(path, options, cb) {
303220
- fs$8.stat(path, function(er, stat) {
303562
+ fs$9.stat(path, function(er, stat) {
303221
303563
  cb(er, er ? false : checkStat(stat, path, options));
303222
303564
  });
303223
303565
  }
303224
303566
  function sync(path, options) {
303225
- return checkStat(fs$8.statSync(path), path, options);
303567
+ return checkStat(fs$9.statSync(path), path, options);
303226
303568
  }
303227
303569
  }));
303228
303570
  //#endregion
@@ -303230,14 +303572,14 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303230
303572
  var require_mode = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303231
303573
  module.exports = isexe;
303232
303574
  isexe.sync = sync;
303233
- var fs$7 = __require("fs");
303575
+ var fs$8 = __require("fs");
303234
303576
  function isexe(path, options, cb) {
303235
- fs$7.stat(path, function(er, stat) {
303577
+ fs$8.stat(path, function(er, stat) {
303236
303578
  cb(er, er ? false : checkStat(stat, options));
303237
303579
  });
303238
303580
  }
303239
303581
  function sync(path, options) {
303240
- return checkStat(fs$7.statSync(path), options);
303582
+ return checkStat(fs$8.statSync(path), options);
303241
303583
  }
303242
303584
  function checkStat(stat, options) {
303243
303585
  return stat.isFile() && checkMode(stat, options);
@@ -303452,16 +303794,16 @@ var require_shebang_command = /* @__PURE__ */ __commonJSMin(((exports, module) =
303452
303794
  //#endregion
303453
303795
  //#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js
303454
303796
  var require_readShebang = /* @__PURE__ */ __commonJSMin(((exports, module) => {
303455
- const fs$6 = __require("fs");
303797
+ const fs$7 = __require("fs");
303456
303798
  const shebangCommand = require_shebang_command();
303457
303799
  function readShebang(command) {
303458
303800
  const size = 150;
303459
303801
  const buffer = Buffer.alloc(size);
303460
303802
  let fd;
303461
303803
  try {
303462
- fd = fs$6.openSync(command, "r");
303463
- fs$6.readSync(fd, buffer, 0, size, 0);
303464
- fs$6.closeSync(fd);
303804
+ fd = fs$7.openSync(command, "r");
303805
+ fs$7.readSync(fd, buffer, 0, size, 0);
303806
+ fs$7.closeSync(fd);
303465
303807
  } catch (e) {}
303466
303808
  return shebangCommand(buffer.toString());
303467
303809
  }
@@ -304569,9 +304911,9 @@ function projectAgentSpinePrompt(input) {
304569
304911
  if (typeof input["hook_event_name"] !== "string" || !PROMPT_EVENTS.has(input["hook_event_name"]) || !Array.isArray(input["prompt"])) return input;
304570
304912
  let changed = false;
304571
304913
  const prompt = input["prompt"].map((part) => {
304572
- if (!isRecord$20(part)) return part;
304914
+ if (!isRecord$24(part)) return part;
304573
304915
  const field = part["type"] === "image_url" ? "imageUrl" : part["type"] === "audio_url" ? "audioUrl" : part["type"] === "video_url" ? "videoUrl" : void 0;
304574
- if (field === void 0 || !isRecord$20(part[field]) || typeof part[field]["url"] !== "string") return part;
304916
+ if (field === void 0 || !isRecord$24(part[field]) || typeof part[field]["url"] !== "string") return part;
304575
304917
  const serialized = JSON.stringify(part);
304576
304918
  changed = true;
304577
304919
  return {
@@ -304586,7 +304928,7 @@ function projectAgentSpinePrompt(input) {
304586
304928
  prompt
304587
304929
  } : input;
304588
304930
  }
304589
- function isRecord$20(value) {
304931
+ function isRecord$24(value) {
304590
304932
  return typeof value === "object" && value !== null && !Array.isArray(value);
304591
304933
  }
304592
304934
  var PROMPT_EVENTS, EMPTY_RUNTIME, AgentSpineSessionRuntime;
@@ -337623,7 +337965,7 @@ var require_dist$5 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
337623
337965
  //#endregion
337624
337966
  //#region ../../node_modules/.pnpm/yazl@3.3.1/node_modules/yazl/index.js
337625
337967
  var require_yazl = /* @__PURE__ */ __commonJSMin(((exports) => {
337626
- var fs$5 = __require("fs");
337968
+ var fs$6 = __require("fs");
337627
337969
  var Transform$2 = __require("stream").Transform;
337628
337970
  var PassThrough$2 = __require("stream").PassThrough;
337629
337971
  var zlib$1 = __require("zlib");
@@ -337652,14 +337994,14 @@ var require_yazl = /* @__PURE__ */ __commonJSMin(((exports) => {
337652
337994
  if (shouldIgnoreAdding(self)) return;
337653
337995
  var entry = new Entry(metadataPath, false, options);
337654
337996
  self.entries.push(entry);
337655
- fs$5.stat(realPath, function(err, stats) {
337997
+ fs$6.stat(realPath, function(err, stats) {
337656
337998
  if (err) return self.emit("error", err);
337657
337999
  if (!stats.isFile()) return self.emit("error", /* @__PURE__ */ new Error("not a file: " + realPath));
337658
338000
  entry.uncompressedSize = stats.size;
337659
338001
  if (options.mtime == null) entry.setLastModDate(stats.mtime);
337660
338002
  if (options.mode == null) entry.setFileAttributesMode(stats.mode);
337661
338003
  entry.setFileDataPumpFunction(function() {
337662
- var readStream = fs$5.createReadStream(realPath);
338004
+ var readStream = fs$6.createReadStream(realPath);
337663
338005
  entry.state = Entry.FILE_DATA_IN_PROGRESS;
337664
338006
  readStream.on("error", function(err) {
337665
338007
  self.emit("error", err);
@@ -339004,10 +339346,10 @@ async function appendForkedMarkers(state) {
339004
339346
  time: Date.now()
339005
339347
  };
339006
339348
  const agents = state["agents"];
339007
- if (!isRecord$19(agents)) return;
339349
+ if (!isRecord$23(agents)) return;
339008
339350
  const paths = /* @__PURE__ */ new Set();
339009
339351
  for (const agentMeta of Object.values(agents)) {
339010
- if (!isRecord$19(agentMeta)) continue;
339352
+ if (!isRecord$23(agentMeta)) continue;
339011
339353
  const homedir = agentMeta["homedir"];
339012
339354
  if (typeof homedir !== "string") continue;
339013
339355
  paths.add(join$4(homedir, "wire.jsonl"));
@@ -339019,7 +339361,7 @@ async function appendForkedMarkers(state) {
339019
339361
  }));
339020
339362
  }
339021
339363
  function customMetadataForFork(value) {
339022
- if (!isRecord$19(value)) return {};
339364
+ if (!isRecord$23(value)) return {};
339023
339365
  const custom = {};
339024
339366
  for (const [key, entry] of Object.entries(value)) {
339025
339367
  if (key === "goal" || key === "managedQuotaWarningThreshold") continue;
@@ -339074,10 +339416,10 @@ function normalizeForkTitle(title, fallback) {
339074
339416
  return typeof fallback === "string" && fallback.trim().length > 0 ? fallback : "New Session";
339075
339417
  }
339076
339418
  function rewriteAgentHomedirs(value, sourceDir, targetDir) {
339077
- if (!isRecord$19(value)) return {};
339419
+ if (!isRecord$23(value)) return {};
339078
339420
  const agents = {};
339079
339421
  for (const [agentId, agentMeta] of Object.entries(value)) {
339080
- if (!isRecord$19(agentMeta)) {
339422
+ if (!isRecord$23(agentMeta)) {
339081
339423
  agents[agentId] = agentMeta;
339082
339424
  continue;
339083
339425
  }
@@ -339095,7 +339437,7 @@ function remapSessionPath(value, sourceDir, targetDir) {
339095
339437
  if (rel.startsWith("..") || isAbsolute$2(rel)) return value;
339096
339438
  return join$4(targetDir, rel);
339097
339439
  }
339098
- function isRecord$19(value) {
339440
+ function isRecord$23(value) {
339099
339441
  return typeof value === "object" && value !== null && !Array.isArray(value);
339100
339442
  }
339101
339443
  async function statIfExists(path) {
@@ -339359,7 +339701,7 @@ var init_session_store$1 = __esmMin((() => {
339359
339701
  } catch (error) {
339360
339702
  throw new BlunError(ErrorCodes.SESSION_STATE_NOT_FOUND, `Session "${input.sourceId}" state.json was not found`, { cause: error });
339361
339703
  }
339362
- if (!isRecord$19(parsed)) throw new BlunError(ErrorCodes.SESSION_STATE_INVALID, `Session "${input.sourceId}" state.json is invalid`);
339704
+ if (!isRecord$23(parsed)) throw new BlunError(ErrorCodes.SESSION_STATE_INVALID, `Session "${input.sourceId}" state.json is invalid`);
339363
339705
  const title = normalizeForkTitle(input.title, parsed["title"]);
339364
339706
  const now = (/* @__PURE__ */ new Date()).toISOString();
339365
339707
  const next = {
@@ -350684,6 +351026,39 @@ var BlunAuthFacade = class {
350684
351026
  }
350685
351027
  return this.toolkit.status(providerName, this.resolveRuntimeManagedAuth(providerName).oauthRef);
350686
351028
  }
351029
+ async getCachedMemoryWorkspaceId() {
351030
+ const apiKey = nonEmpty(this.resolveManagedAuth(BLUN_PROVIDER_NAME$1).apiKey);
351031
+ if (apiKey !== void 0) {
351032
+ const provider = readConfigFileForUpdate(this.options.configPath).providers[BLUN_PROVIDER_NAME$1];
351033
+ if (provider?.apiKey !== apiKey || provider.memoryApiKeyHash !== memoryApiKeyHash(apiKey)) return;
351034
+ return provider.memoryWorkspaceId;
351035
+ }
351036
+ return this.toolkit.getCachedMemoryWorkspaceId(this.resolveRuntimeManagedAuth(BLUN_PROVIDER_NAME$1).oauthRef);
351037
+ }
351038
+ async cacheMemoryWorkspaceId(workspaceId) {
351039
+ const apiKey = nonEmpty(this.resolveManagedAuth(BLUN_PROVIDER_NAME$1).apiKey);
351040
+ if (apiKey !== void 0) {
351041
+ const hash = memoryApiKeyHash(apiKey);
351042
+ return mutateConfigFile(this.options.configPath, (config) => {
351043
+ const provider = config.providers[BLUN_PROVIDER_NAME$1];
351044
+ if (provider?.apiKey !== apiKey) return {
351045
+ config,
351046
+ result: false
351047
+ };
351048
+ if (provider.memoryApiKeyHash === hash && provider.memoryWorkspaceId !== void 0 && provider.memoryWorkspaceId !== workspaceId) return {
351049
+ config,
351050
+ result: false
351051
+ };
351052
+ provider.memoryApiKeyHash = hash;
351053
+ provider.memoryWorkspaceId = workspaceId;
351054
+ return {
351055
+ config,
351056
+ result: true
351057
+ };
351058
+ });
351059
+ }
351060
+ return this.toolkit.cacheMemoryWorkspaceId(workspaceId, this.resolveRuntimeManagedAuth(BLUN_PROVIDER_NAME$1).oauthRef);
351061
+ }
350687
351062
  async login(providerName = BLUN_PROVIDER_NAME$1, options = {}) {
350688
351063
  const auth = this.resolveManagedAuth(providerName);
350689
351064
  const loginAuth = resolveBlunCodeLoginAuth({
@@ -350989,6 +351364,9 @@ function nonEmpty(value) {
350989
351364
  const normalized = value?.trim();
350990
351365
  return normalized === void 0 || normalized.length === 0 ? void 0 : normalized;
350991
351366
  }
351367
+ function memoryApiKeyHash(apiKey) {
351368
+ return createHash("sha256").update(apiKey).digest("hex");
351369
+ }
350992
351370
  function transitionAggregateError(message, primary, secondary) {
350993
351371
  return new AggregateError([primary, secondary], message, { cause: primary });
350994
351372
  }
@@ -353525,7 +353903,7 @@ var require_command = /* @__PURE__ */ __commonJSMin(((exports) => {
353525
353903
  const EventEmitter$12 = __require("node:events").EventEmitter;
353526
353904
  const childProcess = __require("node:child_process");
353527
353905
  const path$7 = __require("node:path");
353528
- const fs$4 = __require("node:fs");
353906
+ const fs$5 = __require("node:fs");
353529
353907
  const process$2 = __require("node:process");
353530
353908
  const { Argument, humanReadableArgName } = require_argument();
353531
353909
  const { CommanderError } = require_error$2();
@@ -354408,7 +354786,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
354408
354786
  * @param {string} subcommandName
354409
354787
  */
354410
354788
  _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
354411
- if (fs$4.existsSync(executableFile)) return;
354789
+ if (fs$5.existsSync(executableFile)) return;
354412
354790
  const executableMissing = `'${executableFile}' does not exist
354413
354791
  - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
354414
354792
  - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
@@ -354432,9 +354810,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
354432
354810
  ];
354433
354811
  function findFile(baseDir, baseName) {
354434
354812
  const localBin = path$7.resolve(baseDir, baseName);
354435
- if (fs$4.existsSync(localBin)) return localBin;
354813
+ if (fs$5.existsSync(localBin)) return localBin;
354436
354814
  if (sourceExt.includes(path$7.extname(baseName))) return void 0;
354437
- const foundExt = sourceExt.find((ext) => fs$4.existsSync(`${localBin}${ext}`));
354815
+ const foundExt = sourceExt.find((ext) => fs$5.existsSync(`${localBin}${ext}`));
354438
354816
  if (foundExt) return `${localBin}${foundExt}`;
354439
354817
  }
354440
354818
  this._checkForMissingMandatoryOptions();
@@ -354444,7 +354822,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
354444
354822
  if (this._scriptPath) {
354445
354823
  let resolvedScriptPath;
354446
354824
  try {
354447
- resolvedScriptPath = fs$4.realpathSync(this._scriptPath);
354825
+ resolvedScriptPath = fs$5.realpathSync(this._scriptPath);
354448
354826
  } catch {
354449
354827
  resolvedScriptPath = this._scriptPath;
354450
354828
  }
@@ -361354,6 +361732,30 @@ var AcpSession = class {
361354
361732
  }, event.message));
361355
361733
  return;
361356
361734
  }
361735
+ if (event.type === "hook.result") {
361736
+ if (!isFromMainAgent(event) || event.content.trim().length === 0) return;
361737
+ if (event.blocked === true) log.warn("acp: turn blocked by hook", {
361738
+ sessionId,
361739
+ hookEvent: event.hookEvent,
361740
+ reason: event.content
361741
+ });
361742
+ conn.sessionUpdate({
361743
+ sessionId,
361744
+ update: {
361745
+ sessionUpdate: "agent_message_chunk",
361746
+ content: {
361747
+ type: "text",
361748
+ text: `${event.content}\n`
361749
+ }
361750
+ }
361751
+ }).catch((err) => {
361752
+ log.warn("acp: failed to push hook result", {
361753
+ sessionId,
361754
+ error: err instanceof Error ? err.message : String(err)
361755
+ });
361756
+ });
361757
+ return;
361758
+ }
361357
361759
  if (event.type === "assistant.delta") {
361358
361760
  if (!isFromMainAgent(event)) return;
361359
361761
  conn.sessionUpdate(assistantDeltaToSessionUpdate(sessionId, event)).catch((err) => {
@@ -364122,8 +364524,8 @@ function createAccountMemoryClient(auth, options = {}) {
364122
364524
  }
364123
364525
  function readAccountMemoryConsentStatus(payload) {
364124
364526
  const settings = unwrapPayload(payload)?.["settings"];
364125
- const dataControls = isRecord$18(settings) ? settings["data_controls"] : void 0;
364126
- if (!isRecord$18(dataControls)) throw new Error("Account memory returned an invalid response.");
364527
+ const dataControls = isRecord$22(settings) ? settings["data_controls"] : void 0;
364528
+ if (!isRecord$22(dataControls)) throw new Error("Account memory returned an invalid response.");
364127
364529
  if (dataControls["memory_consent_asked"] !== true) return "never_asked";
364128
364530
  if (dataControls["allow_memory"] === true) return "enabled";
364129
364531
  if (dataControls["allow_memory"] === false) return "disabled";
@@ -364246,8 +364648,8 @@ function memoryContextSummary(facts, included) {
364246
364648
  })}`;
364247
364649
  }
364248
364650
  function unwrapPayload(value) {
364249
- if (!isRecord$18(value)) return void 0;
364250
- return isRecord$18(value["data"]) ? value["data"] : value;
364651
+ if (!isRecord$22(value)) return void 0;
364652
+ return isRecord$22(value["data"]) ? value["data"] : value;
364251
364653
  }
364252
364654
  function readFacts(root) {
364253
364655
  let rawFacts = [];
@@ -364255,7 +364657,7 @@ function readFacts(root) {
364255
364657
  else {
364256
364658
  const factsJson = parseFactsJson(root["facts_json"]);
364257
364659
  if (Array.isArray(factsJson)) rawFacts = factsJson;
364258
- else if (isRecord$18(factsJson) && Array.isArray(factsJson["facts"])) rawFacts = factsJson["facts"];
364660
+ else if (isRecord$22(factsJson) && Array.isArray(factsJson["facts"])) rawFacts = factsJson["facts"];
364259
364661
  }
364260
364662
  const facts = [];
364261
364663
  const seen = /* @__PURE__ */ new Set();
@@ -364284,7 +364686,7 @@ function parseFactsJson(value) {
364284
364686
  }
364285
364687
  }
364286
364688
  function normalizeFact(value) {
364287
- const raw = typeof value === "string" ? value : isRecord$18(value) && typeof value["text"] === "string" ? value["text"] : void 0;
364689
+ const raw = typeof value === "string" ? value : isRecord$22(value) && typeof value["text"] === "string" ? value["text"] : void 0;
364288
364690
  if (raw === void 0) return void 0;
364289
364691
  const normalized = raw.replaceAll(/\s+/gu, " ").trim();
364290
364692
  if (normalized.length === 0) return void 0;
@@ -364295,7 +364697,7 @@ function normalizeFact(value) {
364295
364697
  truncated: normalized.length > ACCOUNT_MEMORY_MAX_FACT_CHARS
364296
364698
  };
364297
364699
  }
364298
- function isRecord$18(value) {
364700
+ function isRecord$22(value) {
364299
364701
  return typeof value === "object" && value !== null && !Array.isArray(value);
364300
364702
  }
364301
364703
  //#endregion
@@ -364522,6 +364924,8 @@ registerUiCatalogFragment({
364522
364924
  "auth.logout.selectTitle": "Select a provider to log out",
364523
364925
  "auth.logout.none": "Nothing to log out.",
364524
364926
  "auth.logout.complete": "Logged out from {provider}.",
364927
+ "auth.warning.memoryRetractionOAuthPending": "Deletion has not been sent yet. It will be sent at your next sign-in.",
364928
+ "auth.warning.memoryRetractionApiKeyPending": "Deletion has not been sent yet. It will be sent once you reconnect.",
364525
364929
  "auth.warning.remoteRevokeFailed": "The local OAuth credentials were removed, but remote revocation could not be confirmed.",
364526
364930
  "auth.warning.oauthCleanupFailed": "The API key is active, but the previous OAuth credentials could not be fully removed."
364527
364931
  },
@@ -364554,6 +364958,8 @@ registerUiCatalogFragment({
364554
364958
  "auth.logout.selectTitle": "Anbieter zum Abmelden auswählen",
364555
364959
  "auth.logout.none": "Es gibt keine aktive Anmeldung.",
364556
364960
  "auth.logout.complete": "Von {provider} abgemeldet.",
364961
+ "auth.warning.memoryRetractionOAuthPending": "Löschen noch nicht übertragen – folgt bei deiner nächsten Anmeldung.",
364962
+ "auth.warning.memoryRetractionApiKeyPending": "Löschen noch nicht übertragen – folgt, sobald du wieder verbunden bist.",
364557
364963
  "auth.warning.remoteRevokeFailed": "Die lokalen OAuth-Zugangsdaten wurden entfernt, aber der Widerruf auf dem Server konnte nicht bestätigt werden.",
364558
364964
  "auth.warning.oauthCleanupFailed": "Der API-Schlüssel ist aktiv, aber die vorherigen OAuth-Zugangsdaten konnten nicht vollständig entfernt werden."
364559
364965
  },
@@ -364586,6 +364992,8 @@ registerUiCatalogFragment({
364586
364992
  "auth.logout.selectTitle": "Selecciona el proveedor cuya sesión quieres cerrar",
364587
364993
  "auth.logout.none": "No hay ninguna sesión que cerrar.",
364588
364994
  "auth.logout.complete": "Sesión cerrada en {provider}.",
364995
+ "auth.warning.memoryRetractionOAuthPending": "La eliminación aún no se ha enviado: se enviará en tu próximo inicio de sesión.",
364996
+ "auth.warning.memoryRetractionApiKeyPending": "La eliminación aún no se ha enviado: se enviará cuando se restablezca la conexión.",
364589
364997
  "auth.warning.remoteRevokeFailed": "Las credenciales OAuth locales se han eliminado, pero no se pudo confirmar su revocación en el servidor.",
364590
364998
  "auth.warning.oauthCleanupFailed": "La clave de API está activa, pero no se pudieron eliminar por completo las credenciales OAuth anteriores."
364591
364999
  },
@@ -364618,6 +365026,8 @@ registerUiCatalogFragment({
364618
365026
  "auth.logout.selectTitle": "Sélectionnez le fournisseur dont vous souhaitez vous déconnecter",
364619
365027
  "auth.logout.none": "Aucune session à fermer.",
364620
365028
  "auth.logout.complete": "Déconnexion de {provider} effectuée.",
365029
+ "auth.warning.memoryRetractionOAuthPending": "Suppression pas encore transmise – elle le sera à ta prochaine connexion.",
365030
+ "auth.warning.memoryRetractionApiKeyPending": "Suppression pas encore transmise – elle le sera dès que la connexion sera rétablie.",
364621
365031
  "auth.warning.remoteRevokeFailed": "Les identifiants OAuth locaux ont été supprimés, mais leur révocation sur le serveur n’a pas pu être confirmée.",
364622
365032
  "auth.warning.oauthCleanupFailed": "La clé API est active, mais les identifiants OAuth précédents n’ont pas pu être entièrement supprimés."
364623
365033
  },
@@ -364650,6 +365060,8 @@ registerUiCatalogFragment({
364650
365060
  "auth.logout.selectTitle": "Välj en leverantör att logga ut från",
364651
365061
  "auth.logout.none": "Det finns inget att logga ut från.",
364652
365062
  "auth.logout.complete": "Utloggad från {provider}.",
365063
+ "auth.warning.memoryRetractionOAuthPending": "Raderingen har inte överförts än – sker vid din nästa inloggning.",
365064
+ "auth.warning.memoryRetractionApiKeyPending": "Raderingen har inte överförts än – sker så snart du är ansluten igen.",
364653
365065
  "auth.warning.remoteRevokeFailed": "De lokala OAuth-uppgifterna har tagits bort, men det gick inte att bekräfta återkallelsen på servern.",
364654
365066
  "auth.warning.oauthCleanupFailed": "API-nyckeln är aktiv, men de tidigare OAuth-uppgifterna kunde inte tas bort helt."
364655
365067
  },
@@ -364682,6 +365094,8 @@ registerUiCatalogFragment({
364682
365094
  "auth.logout.selectTitle": "Vyberte poskytovatele, od kterého se chcete odhlásit",
364683
365095
  "auth.logout.none": "Nic k odhlášení.",
364684
365096
  "auth.logout.complete": "Odhlášeno od {provider}.",
365097
+ "auth.warning.memoryRetractionOAuthPending": "Smazání zatím nebylo přeneseno – proběhne při tvém příštím přihlášení.",
365098
+ "auth.warning.memoryRetractionApiKeyPending": "Smazání zatím nebylo přeneseno – proběhne, jakmile se obnoví připojení.",
364685
365099
  "auth.warning.remoteRevokeFailed": "Místní přihlašovací údaje OAuth byly odstraněny, ale jejich zneplatnění na serveru se nepodařilo potvrdit.",
364686
365100
  "auth.warning.oauthCleanupFailed": "Klíč API je aktivní, ale předchozí přihlašovací údaje OAuth nebyly zcela odstraněny."
364687
365101
  }
@@ -365813,7 +366227,7 @@ function formatErrorMessage$4(error, filePath) {
365813
366227
  function findValidationIssues(error) {
365814
366228
  if (!(error instanceof Error)) return void 0;
365815
366229
  const details = "details" in error ? error.details : void 0;
365816
- if (!isRecord$17(details)) return void 0;
366230
+ if (!isRecord$21(details)) return void 0;
365817
366231
  const validationIssues = details["validationIssues"];
365818
366232
  return isValidationIssueArray(validationIssues) ? validationIssues : void 0;
365819
366233
  }
@@ -365821,11 +366235,11 @@ function isValidationIssueArray(value) {
365821
366235
  return Array.isArray(value) && value.every(isValidationIssue);
365822
366236
  }
365823
366237
  function isValidationIssue(value) {
365824
- if (!isRecord$17(value) || typeof value["message"] !== "string") return false;
366238
+ if (!isRecord$21(value) || typeof value["message"] !== "string") return false;
365825
366239
  const path = value["path"];
365826
366240
  return Array.isArray(path) && path.every((segment) => typeof segment === "string" || typeof segment === "number");
365827
366241
  }
365828
- function isRecord$17(value) {
366242
+ function isRecord$21(value) {
365829
366243
  return typeof value === "object" && value !== null;
365830
366244
  }
365831
366245
  function findZodError(error) {
@@ -366320,7 +366734,7 @@ function assertEntryCount(value) {
366320
366734
  return value;
366321
366735
  }
366322
366736
  function parseMistakeRecordDeclarations(value, sourceId, declaredRecordTypes) {
366323
- if (!isRecord$16(value) || !hasOnlyKeys(value, [
366737
+ if (!isRecord$20(value) || !hasOnlyKeys(value, [
366324
366738
  "version",
366325
366739
  "records",
366326
366740
  "relations"
@@ -366333,7 +366747,7 @@ function parseMistakeRecordDeclarations(value, sourceId, declaredRecordTypes) {
366333
366747
  return {
366334
366748
  version: 1,
366335
366749
  records: value["records"].map((candidate, index) => {
366336
- if (!isRecord$16(candidate) || !hasOnlyKeys(candidate, [
366750
+ if (!isRecord$20(candidate) || !hasOnlyKeys(candidate, [
366337
366751
  "source_record_id",
366338
366752
  "type",
366339
366753
  "raw_locator"
@@ -366353,7 +366767,7 @@ function parseMistakeRecordDeclarations(value, sourceId, declaredRecordTypes) {
366353
366767
  };
366354
366768
  }),
366355
366769
  relations: value["relations"].map((candidate, index) => {
366356
- if (!isRecord$16(candidate) || !hasOnlyKeys(candidate, [
366770
+ if (!isRecord$20(candidate) || !hasOnlyKeys(candidate, [
366357
366771
  "from_source_record_id",
366358
366772
  "type",
366359
366773
  "to"
@@ -366363,7 +366777,7 @@ function parseMistakeRecordDeclarations(value, sourceId, declaredRecordTypes) {
366363
366777
  const target = candidate["to"];
366364
366778
  if (typeof fromRecordId !== "string" || !isValidRecordId(fromRecordId) || !recordIds.has(fromRecordId)) throw new Error(`record relation ${index} must start at a declared local record`);
366365
366779
  if (typeof type !== "string" || !MISTAKE_RELATION_TYPES.includes(type)) throw new Error(`record relation ${index} has an invalid relation type`);
366366
- if (!isRecord$16(target) || !hasOnlyKeys(target, ["source_id", "source_record_id"])) throw new Error(`record relation ${index} has an invalid target`);
366780
+ if (!isRecord$20(target) || !hasOnlyKeys(target, ["source_id", "source_record_id"])) throw new Error(`record relation ${index} has an invalid target`);
366367
366781
  const targetSourceId = target["source_id"];
366368
366782
  const targetRecordId = target["source_record_id"];
366369
366783
  if (typeof targetSourceId !== "string" || !isNormalizedSourceId(targetSourceId)) throw new Error(`record relation ${index} has an invalid target source id`);
@@ -366633,7 +367047,7 @@ function receiptsEqual(left, right) {
366633
367047
  return left.version === right.version && left.accepted === right.accepted && left.event_id === right.event_id && left.client_event_id === right.client_event_id && left.source_id === right.source_id && left.canonical_agent_id === right.canonical_agent_id && left.received_at === right.received_at && left.raw_count === right.raw_count && left.accepted_count === right.accepted_count && left.rejected_count === right.rejected_count && left.raw_bytes === right.raw_bytes && left.raw_sha256 === right.raw_sha256 && left.declared_entry_count === right.declared_entry_count;
366634
367048
  }
366635
367049
  function isStateActionReceipt(value) {
366636
- if (!isRecord$16(value) || !hasOnlyKeys(value, STATE_ACTION_KEYS)) return false;
367050
+ if (!isRecord$20(value) || !hasOnlyKeys(value, STATE_ACTION_KEYS)) return false;
366637
367051
  const reason = value["reason"];
366638
367052
  return value["version"] === 1 && typeof value["action_id"] === "string" && UUID_RE$1.test(value["action_id"]) && (value["action"] === "remove" || value["action"] === "restore") && typeof value["target_event_id"] === "string" && UUID_RE$1.test(value["target_event_id"]) && typeof value["acted_at"] === "string" && isIsoTimestamp(value["acted_at"]) && Number.isSafeInteger(value["server_sequence"]) && value["server_sequence"] >= 1 && typeof value["principal_id"] === "string" && isNormalizedSourceId(value["principal_id"]) && typeof reason === "string" && reason.trim() === reason && reason.length >= 3 && reason.length <= 500;
366639
367053
  }
@@ -366736,7 +367150,7 @@ function assertInventoryInvariants(bestandsstatus, aktualitaetsstatus, declaredE
366736
367150
  if (aktualitaetsstatus === "fresh" && lastRawObservedAt === null) throw new Error("fresh inventory requires a last raw observed timestamp");
366737
367151
  if (capturedAt !== void 0 && lastRawObservedAt !== null && Date.parse(lastRawObservedAt) > Date.parse(capturedAt)) throw new Error("last raw observed timestamp must not be later than captured at");
366738
367152
  }
366739
- function isRecord$16(value) {
367153
+ function isRecord$20(value) {
366740
367154
  return typeof value === "object" && value !== null && !Array.isArray(value);
366741
367155
  }
366742
367156
  function hasOnlyKeys(value, allowedKeys) {
@@ -367680,12 +368094,14 @@ const PERSONAL_MEMORY_EXPLICIT_CATEGORY = "user_explicit";
367680
368094
  const SAFE_BROKER_ERROR_CODES = new Set([
367681
368095
  "AUTHENTICATION_REQUIRED",
367682
368096
  "EXPLICIT_CONSENT_REQUIRED",
368097
+ "FORGET_GENERATION_CHANGED",
367683
368098
  "INTERNAL_ERROR",
367684
368099
  "INTERACTIVE_CONFIRMATION_REQUIRED",
367685
368100
  "INSUFFICIENT_SCOPE",
367686
368101
  "INVALID_PAYLOAD",
367687
368102
  "MEMORY_NOT_FOUND",
367688
368103
  "MEMORY_WRITE_DISABLED",
368104
+ "PAYLOAD_TOO_LARGE",
367689
368105
  "SECRET_REJECTED",
367690
368106
  "UNAVAILABLE"
367691
368107
  ]);
@@ -367700,7 +368116,7 @@ var PersonalMemoryBrokerError = class extends Error {
367700
368116
  }
367701
368117
  };
367702
368118
  function parsePersonalMemorySettings(payload) {
367703
- if (!isRecord$15(payload)) return void 0;
368119
+ if (!isRecord$19(payload)) return void 0;
367704
368120
  const status = payload["status"];
367705
368121
  if (status !== "configured" && status !== "never_asked") return void 0;
367706
368122
  const memoryEnabled = payload["memory_enabled"];
@@ -367809,21 +368225,23 @@ async function brokerHttpError(response) {
367809
368225
  const responseCode = await safeBrokerResponseCode(response);
367810
368226
  if (responseCode !== void 0) return new PersonalMemoryBrokerError(responseCode, status);
367811
368227
  if (status === 401) return new PersonalMemoryBrokerError("AUTHENTICATION_REQUIRED", status);
368228
+ if (status === 409) return new PersonalMemoryBrokerError("FORGET_GENERATION_CHANGED", status);
368229
+ if (status === 413) return new PersonalMemoryBrokerError("PAYLOAD_TOO_LARGE", status);
367812
368230
  if (status === 403) return new PersonalMemoryBrokerError("INSUFFICIENT_SCOPE", status);
367813
368231
  return new PersonalMemoryBrokerError("UNAVAILABLE", status);
367814
368232
  }
367815
368233
  async function safeBrokerResponseCode(response) {
367816
368234
  try {
367817
368235
  const payload = await response.json();
367818
- if (!isRecord$15(payload)) return void 0;
367819
- const nested = isRecord$15(payload["error"]) ? payload["error"]["code"] : void 0;
368236
+ if (!isRecord$19(payload)) return void 0;
368237
+ const nested = isRecord$19(payload["error"]) ? payload["error"]["code"] : void 0;
367820
368238
  const candidate = payload["code"] ?? payload["error_code"] ?? nested;
367821
368239
  return typeof candidate === "string" && SAFE_BROKER_ERROR_CODES.has(candidate) ? candidate : void 0;
367822
368240
  } catch {
367823
368241
  return;
367824
368242
  }
367825
368243
  }
367826
- function isRecord$15(value) {
368244
+ function isRecord$19(value) {
367827
368245
  return typeof value === "object" && value !== null && !Array.isArray(value);
367828
368246
  }
367829
368247
  function isAllowedBrokerRequest(method, path) {
@@ -367834,13 +368252,17 @@ function isAllowedBrokerRequest(method, path) {
367834
368252
  return false;
367835
368253
  }
367836
368254
  if (url.origin !== "https://personal-memory.invalid") return false;
367837
- if (url.search.length > 0 || url.hash.length > 0) return false;
368255
+ if (url.hash.length > 0) return false;
368256
+ if (url.pathname === "/api/memory/workspace" && url.search.length > 0) return method === "GET" && url.searchParams.size === 2 && url.searchParams.get("source") === "tui" && url.searchParams.has("sessionId") && (url.searchParams.get("sessionId")?.length ?? 0) > 0 && (url.searchParams.get("sessionId")?.length ?? 0) <= 200;
368257
+ if (url.search.length > 0) return false;
367838
368258
  const pathname = url.pathname;
367839
368259
  if (pathname === PERSONAL_MEMORY_SETTINGS_PATH) return method === "GET" || method === "PUT";
367840
368260
  if (pathname === "/api/account/consent") return method === "POST";
367841
368261
  if (pathname === PERSONAL_MEMORY_MEMORIES_PATH) return method === "GET" || method === "POST";
367842
368262
  if (/^\/v1\/me\/memories\/[0-9a-f-]{36}$/i.test(pathname)) return false;
367843
368263
  if (pathname === PERSONAL_MEMORY_RECALL_PATH) return method === PERSONAL_MEMORY_RECALL_METHOD;
368264
+ if (pathname === "/api/memory/workspace") return method === "GET";
368265
+ if (pathname === "/api/memory/capture" || pathname === "/api/memory/recall" || pathname === "/api/memory/search" || pathname === "/api/memory/retract") return method === "POST";
367844
368266
  return false;
367845
368267
  }
367846
368268
  //#endregion
@@ -368530,7 +368952,7 @@ function createAttestation(value, createdAt) {
368530
368952
  };
368531
368953
  }
368532
368954
  function parseProof(value) {
368533
- if (!isRecord$14(value) || value["schema"] !== "blun.proof" || value["schemaVersion"] !== 1) throw new Error("Unsupported proof document.");
368955
+ if (!isRecord$18(value) || value["schema"] !== "blun.proof" || value["schemaVersion"] !== 1) throw new Error("Unsupported proof document.");
368534
368956
  assertObjectKeys(value, [
368535
368957
  "schema",
368536
368958
  "schemaVersion",
@@ -368550,12 +368972,12 @@ function parseProof(value) {
368550
368972
  "incomplete",
368551
368973
  "failed"
368552
368974
  ].includes(proof.outcome)) throw new Error("Invalid proof outcome.");
368553
- if (!isRecord$14(proof.source) || proof.source.kind !== "workspace") throw new Error("Invalid proof source.");
368975
+ if (!isRecord$18(proof.source) || proof.source.kind !== "workspace") throw new Error("Invalid proof source.");
368554
368976
  assertObjectKeys(proof.source, ["kind"], ["git"], "proof source");
368555
368977
  if (proof.source.git !== void 0) validateGitSnapshot(proof.source.git);
368556
368978
  if (!Array.isArray(proof.checks) || !Array.isArray(proof.artifacts)) throw new TypeError("Invalid proof collections.");
368557
368979
  if (proof.checks.length > MAX_COMMANDS || proof.artifacts.length > MAX_ARTIFACTS) throw new Error("Proof collections exceed their limits.");
368558
- if (!isRecord$14(proof.attestation) || proof.attestation.algorithm !== "SHA-256" || proof.attestation.scope !== "content-integrity-only" || !SHA256_PATTERN.test(proof.attestation.hash)) throw new Error("Invalid proof attestation.");
368980
+ if (!isRecord$18(proof.attestation) || proof.attestation.algorithm !== "SHA-256" || proof.attestation.scope !== "content-integrity-only" || !SHA256_PATTERN.test(proof.attestation.hash)) throw new Error("Invalid proof attestation.");
368559
368981
  assertObjectKeys(proof.attestation, [
368560
368982
  "algorithm",
368561
368983
  "scope",
@@ -368570,7 +368992,7 @@ function parseProof(value) {
368570
368992
  screenshot: 0
368571
368993
  };
368572
368994
  for (const artifact of proof.artifacts) {
368573
- if (!isRecord$14(artifact) || artifact.kind !== "file" && artifact.kind !== "screenshot" || typeof artifact.id !== "string" || typeof artifact.size !== "number" || !Number.isSafeInteger(artifact.size) || artifact.size < 0 || typeof artifact.sha256 !== "string" || !SHA256_PATTERN.test(artifact.sha256)) throw new Error("Invalid proof artifact.");
368995
+ if (!isRecord$18(artifact) || artifact.kind !== "file" && artifact.kind !== "screenshot" || typeof artifact.id !== "string" || typeof artifact.size !== "number" || !Number.isSafeInteger(artifact.size) || artifact.size < 0 || typeof artifact.sha256 !== "string" || !SHA256_PATTERN.test(artifact.sha256)) throw new Error("Invalid proof artifact.");
368574
368996
  assertObjectKeys(artifact, [
368575
368997
  "id",
368576
368998
  "kind",
@@ -368587,14 +369009,14 @@ function parseProof(value) {
368587
369009
  return proof;
368588
369010
  }
368589
369011
  function validateGitSnapshot(value) {
368590
- if (!isRecord$14(value)) throw new Error("Invalid proof git snapshot.");
369012
+ if (!isRecord$18(value)) throw new Error("Invalid proof git snapshot.");
368591
369013
  assertObjectKeys(value, ["dirty", "changedCount"], [], "proof git snapshot");
368592
369014
  if (typeof value["dirty"] !== "boolean") throw new TypeError("Invalid proof git dirty flag.");
368593
369015
  if (typeof value["changedCount"] !== "number" || !Number.isSafeInteger(value["changedCount"]) || value["changedCount"] < 0) throw new Error("Invalid proof git changed count.");
368594
369016
  if (value["dirty"] !== value["changedCount"] > 0) throw new Error("Inconsistent proof git state.");
368595
369017
  }
368596
369018
  function validateProofCheck(value, index) {
368597
- if (!isRecord$14(value)) throw new Error("Invalid proof check.");
369019
+ if (!isRecord$18(value)) throw new Error("Invalid proof check.");
368598
369020
  assertObjectKeys(value, [
368599
369021
  "id",
368600
369022
  "outcome",
@@ -368606,13 +369028,13 @@ function validateProofCheck(value, index) {
368606
369028
  if (value["outcome"] !== expectedOutcome) throw new Error("Invalid proof check outcome.");
368607
369029
  }
368608
369030
  function attestedContent(value) {
368609
- if (!isRecord$14(value)) return value;
369031
+ if (!isRecord$18(value)) return value;
368610
369032
  const { attestation: _attestation, createdAt: _createdAt, ...content } = value;
368611
369033
  return content;
368612
369034
  }
368613
369035
  function canonicalize(value) {
368614
369036
  if (Array.isArray(value)) return value.map(canonicalize);
368615
- if (!isRecord$14(value)) return value;
369037
+ if (!isRecord$18(value)) return value;
368616
369038
  return Object.keys(value).toSorted().reduce((result, key) => {
368617
369039
  result[key] = canonicalize(value[key]);
368618
369040
  return result;
@@ -368689,7 +369111,7 @@ function sameFileIdentity$1(left, right) {
368689
369111
  function sameFileSnapshot(left, right) {
368690
369112
  return sameFileIdentity$1(left, right) && left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs;
368691
369113
  }
368692
- function isRecord$14(value) {
369114
+ function isRecord$18(value) {
368693
369115
  return typeof value === "object" && value !== null && !Array.isArray(value);
368694
369116
  }
368695
369117
  //#endregion
@@ -372961,7 +373383,7 @@ var require_atomic_sleep = /* @__PURE__ */ __commonJSMin(((exports, module) => {
372961
373383
  //#endregion
372962
373384
  //#region ../../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js
372963
373385
  var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
372964
- const fs$3 = __require("fs");
373386
+ const fs$4 = __require("fs");
372965
373387
  const EventEmitter$10 = __require("events");
372966
373388
  const inherits$6 = __require("util").inherits;
372967
373389
  const path$6 = __require("path");
@@ -373004,17 +373426,17 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373004
373426
  const flags = sonic.append ? "a" : "w";
373005
373427
  const mode = sonic.mode;
373006
373428
  if (sonic.sync) try {
373007
- if (sonic.mkdir) fs$3.mkdirSync(path$6.dirname(file), { recursive: true });
373008
- fileOpened(null, fs$3.openSync(file, flags, mode));
373429
+ if (sonic.mkdir) fs$4.mkdirSync(path$6.dirname(file), { recursive: true });
373430
+ fileOpened(null, fs$4.openSync(file, flags, mode));
373009
373431
  } catch (err) {
373010
373432
  fileOpened(err);
373011
373433
  throw err;
373012
373434
  }
373013
- else if (sonic.mkdir) fs$3.mkdir(path$6.dirname(file), { recursive: true }, (err) => {
373435
+ else if (sonic.mkdir) fs$4.mkdir(path$6.dirname(file), { recursive: true }, (err) => {
373014
373436
  if (err) return fileOpened(err);
373015
- fs$3.open(file, flags, mode, fileOpened);
373437
+ fs$4.open(file, flags, mode, fileOpened);
373016
373438
  });
373017
- else fs$3.open(file, flags, mode, fileOpened);
373439
+ else fs$4.open(file, flags, mode, fileOpened);
373018
373440
  }
373019
373441
  function SonicBoom(opts) {
373020
373442
  if (!(this instanceof SonicBoom)) return new SonicBoom(opts);
@@ -373052,8 +373474,8 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373052
373474
  this.flush = flushBuffer;
373053
373475
  this.flushSync = flushBufferSync;
373054
373476
  this._actualWrite = actualWriteBuffer;
373055
- fsWriteSync = () => fs$3.writeSync(this.fd, this._writingBuf);
373056
- fsWrite = () => fs$3.write(this.fd, this._writingBuf, this.release);
373477
+ fsWriteSync = () => fs$4.writeSync(this.fd, this._writingBuf);
373478
+ fsWrite = () => fs$4.write(this.fd, this._writingBuf, this.release);
373057
373479
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
373058
373480
  this._writingBuf = "";
373059
373481
  this.write = write;
@@ -373061,12 +373483,12 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373061
373483
  this.flushSync = flushSync;
373062
373484
  this._actualWrite = actualWrite;
373063
373485
  fsWriteSync = () => {
373064
- if (Buffer.isBuffer(this._writingBuf)) return fs$3.writeSync(this.fd, this._writingBuf);
373065
- return fs$3.writeSync(this.fd, this._writingBuf, "utf8");
373486
+ if (Buffer.isBuffer(this._writingBuf)) return fs$4.writeSync(this.fd, this._writingBuf);
373487
+ return fs$4.writeSync(this.fd, this._writingBuf, "utf8");
373066
373488
  };
373067
373489
  fsWrite = () => {
373068
- if (Buffer.isBuffer(this._writingBuf)) return fs$3.write(this.fd, this._writingBuf, this.release);
373069
- return fs$3.write(this.fd, this._writingBuf, "utf8", this.release);
373490
+ if (Buffer.isBuffer(this._writingBuf)) return fs$4.write(this.fd, this._writingBuf, this.release);
373491
+ return fs$4.write(this.fd, this._writingBuf, "utf8", this.release);
373070
373492
  };
373071
373493
  } else throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
373072
373494
  if (typeof fd === "number") {
@@ -373111,7 +373533,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373111
373533
  return;
373112
373534
  }
373113
373535
  }
373114
- if (this._fsync) fs$3.fsyncSync(this.fd);
373536
+ if (this._fsync) fs$4.fsyncSync(this.fd);
373115
373537
  const len = this._len;
373116
373538
  if (this._reopening) {
373117
373539
  this._writing = false;
@@ -373208,7 +373630,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373208
373630
  this._flushPending = true;
373209
373631
  const onDrain = () => {
373210
373632
  if (!this._fsync) try {
373211
- fs$3.fsync(this.fd, (err) => {
373633
+ fs$4.fsync(this.fd, (err) => {
373212
373634
  this._flushPending = false;
373213
373635
  cb(err);
373214
373636
  });
@@ -373285,7 +373707,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373285
373707
  if (this._writing) return;
373286
373708
  const fd = this.fd;
373287
373709
  this.once("ready", () => {
373288
- if (fd !== this.fd) fs$3.close(fd, (err) => {
373710
+ if (fd !== this.fd) fs$4.close(fd, (err) => {
373289
373711
  if (err) return this.emit("error", err);
373290
373712
  });
373291
373713
  });
@@ -373316,7 +373738,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373316
373738
  while (this._bufs.length || buf.length) {
373317
373739
  if (buf.length <= 0) buf = this._bufs[0];
373318
373740
  try {
373319
- const n = Buffer.isBuffer(buf) ? fs$3.writeSync(this.fd, buf) : fs$3.writeSync(this.fd, buf, "utf8");
373741
+ const n = Buffer.isBuffer(buf) ? fs$4.writeSync(this.fd, buf) : fs$4.writeSync(this.fd, buf, "utf8");
373320
373742
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
373321
373743
  buf = releasedBufObj.writingBuf;
373322
373744
  this._len = releasedBufObj.len;
@@ -373327,7 +373749,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373327
373749
  }
373328
373750
  }
373329
373751
  try {
373330
- fs$3.fsyncSync(this.fd);
373752
+ fs$4.fsyncSync(this.fd);
373331
373753
  } catch {}
373332
373754
  }
373333
373755
  function flushBufferSync() {
@@ -373341,7 +373763,7 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373341
373763
  while (this._bufs.length || buf.length) {
373342
373764
  if (buf.length <= 0) buf = mergeBuf(this._bufs[0], this._lens[0]);
373343
373765
  try {
373344
- const n = fs$3.writeSync(this.fd, buf);
373766
+ const n = fs$4.writeSync(this.fd, buf);
373345
373767
  buf = buf.subarray(n);
373346
373768
  this._len = Math.max(this._len - n, 0);
373347
373769
  if (buf.length <= 0) {
@@ -373363,24 +373785,24 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373363
373785
  this._writing = true;
373364
373786
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
373365
373787
  if (this.sync) try {
373366
- release(null, Buffer.isBuffer(this._writingBuf) ? fs$3.writeSync(this.fd, this._writingBuf) : fs$3.writeSync(this.fd, this._writingBuf, "utf8"));
373788
+ release(null, Buffer.isBuffer(this._writingBuf) ? fs$4.writeSync(this.fd, this._writingBuf) : fs$4.writeSync(this.fd, this._writingBuf, "utf8"));
373367
373789
  } catch (err) {
373368
373790
  release(err);
373369
373791
  }
373370
- else fs$3.write(this.fd, this._writingBuf, release);
373792
+ else fs$4.write(this.fd, this._writingBuf, release);
373371
373793
  }
373372
373794
  function actualWriteBuffer() {
373373
373795
  const release = this.release;
373374
373796
  this._writing = true;
373375
373797
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
373376
373798
  if (this.sync) try {
373377
- release(null, fs$3.writeSync(this.fd, this._writingBuf));
373799
+ release(null, fs$4.writeSync(this.fd, this._writingBuf));
373378
373800
  } catch (err) {
373379
373801
  release(err);
373380
373802
  }
373381
373803
  else {
373382
373804
  if (kCopyBuffer) this._writingBuf = Buffer.from(this._writingBuf);
373383
- fs$3.write(this.fd, this._writingBuf, release);
373805
+ fs$4.write(this.fd, this._writingBuf, release);
373384
373806
  }
373385
373807
  }
373386
373808
  function actualClose(sonic) {
@@ -373394,10 +373816,10 @@ var require_sonic_boom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
373394
373816
  sonic._lens = [];
373395
373817
  assert$8(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
373396
373818
  try {
373397
- fs$3.fsync(sonic.fd, closeWrapped);
373819
+ fs$4.fsync(sonic.fd, closeWrapped);
373398
373820
  } catch {}
373399
373821
  function closeWrapped() {
373400
- if (sonic.fd !== 1 && sonic.fd !== 2) fs$3.close(sonic.fd, done);
373822
+ if (sonic.fd !== 1 && sonic.fd !== 2) fs$4.close(sonic.fd, done);
373401
373823
  else done();
373402
373824
  }
373403
373825
  function done(err) {
@@ -416074,7 +416496,7 @@ var require_dist$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
416074
416496
  //#region ../../node_modules/.pnpm/@fastify+swagger@9.7.0/node_modules/@fastify/swagger/lib/mode/static.js
416075
416497
  var require_static = /* @__PURE__ */ __commonJSMin(((exports, module) => {
416076
416498
  const path$4 = __require("node:path");
416077
- const fs$2 = __require("node:fs");
416499
+ const fs$3 = __require("node:fs");
416078
416500
  const yaml = require_dist$1();
416079
416501
  module.exports = function(fastify, opts, done) {
416080
416502
  if (!opts.specification) return done(/* @__PURE__ */ new Error("specification is missing in the module options"));
@@ -416083,14 +416505,14 @@ var require_static = /* @__PURE__ */ __commonJSMin(((exports, module) => {
416083
416505
  if (!opts.specification.path && !opts.specification.document) return done(/* @__PURE__ */ new Error("both specification.path and specification.document are missing, should be path to the file or swagger document spec"));
416084
416506
  else if (opts.specification.path) {
416085
416507
  if (typeof opts.specification.path !== "string") return done(/* @__PURE__ */ new Error("specification.path is not a string"));
416086
- if (!fs$2.existsSync(path$4.resolve(opts.specification.path))) return done(/* @__PURE__ */ new Error(`${opts.specification.path} does not exist`));
416508
+ if (!fs$3.existsSync(path$4.resolve(opts.specification.path))) return done(/* @__PURE__ */ new Error(`${opts.specification.path} does not exist`));
416087
416509
  const extName = path$4.extname(opts.specification.path).toLowerCase();
416088
416510
  if ([".yaml", ".json"].indexOf(extName) === -1) return done(/* @__PURE__ */ new Error("specification.path extension name is not supported, should be one from ['.yaml', '.json']"));
416089
416511
  if (opts.specification.postProcessor && typeof opts.specification.postProcessor !== "function") return done(/* @__PURE__ */ new Error("specification.postProcessor should be a function"));
416090
416512
  if (opts.specification.baseDir && typeof opts.specification.baseDir !== "string") return done(/* @__PURE__ */ new Error("specification.baseDir should be string"));
416091
416513
  if (!opts.specification.baseDir) opts.specification.baseDir = path$4.resolve(path$4.dirname(opts.specification.path));
416092
416514
  else while (opts.specification.baseDir.endsWith("/")) opts.specification.baseDir = opts.specification.baseDir.slice(0, -1);
416093
- const source = fs$2.readFileSync(path$4.resolve(opts.specification.path), "utf8");
416515
+ const source = fs$3.readFileSync(path$4.resolve(opts.specification.path), "utf8");
416094
416516
  switch (extName) {
416095
416517
  case ".yaml":
416096
416518
  swaggerObject = yaml.parse(source);
@@ -416357,11 +416779,11 @@ var require_should_route_hide = /* @__PURE__ */ __commonJSMin(((exports, module)
416357
416779
  //#endregion
416358
416780
  //#region ../../node_modules/.pnpm/@fastify+swagger@9.7.0/node_modules/@fastify/swagger/lib/util/read-package-json.js
416359
416781
  var require_read_package_json = /* @__PURE__ */ __commonJSMin(((exports, module) => {
416360
- const fs$1 = __require("node:fs");
416782
+ const fs$2 = __require("node:fs");
416361
416783
  const path$3 = __require("node:path");
416362
416784
  function readPackageJson() {
416363
416785
  try {
416364
- return JSON.parse(fs$1.readFileSync(path$3.join(__dirname, "..", "..", "package.json")));
416786
+ return JSON.parse(fs$2.readFileSync(path$3.join(__dirname, "..", "..", "package.json")));
416365
416787
  } catch {
416366
416788
  return {};
416367
416789
  }
@@ -423564,12 +423986,12 @@ function legacyStatusToCurrent(task) {
423564
423986
  return task.status;
423565
423987
  }
423566
423988
  function isReadablePersistedTask(obj) {
423567
- return isRecord$13(obj) && (typeof obj["taskId"] === "string" || typeof obj["task_id"] === "string");
423989
+ return isRecord$17(obj) && (typeof obj["taskId"] === "string" || typeof obj["task_id"] === "string");
423568
423990
  }
423569
423991
  function isLegacyPersistedTask(task) {
423570
423992
  return "task_id" in task;
423571
423993
  }
423572
- function isRecord$13(value) {
423994
+ function isRecord$17(value) {
423573
423995
  return typeof value === "object" && value !== null;
423574
423996
  }
423575
423997
  function optionalNonEmptyString(value) {
@@ -423978,11 +424400,11 @@ const WINDOWS_RESERVED_NAMES = new Set([
423978
424400
  ...Array.from({ length: 9 }, (_value, index) => `COM${String(index + 1)}`),
423979
424401
  ...Array.from({ length: 9 }, (_value, index) => `LPT${String(index + 1)}`)
423980
424402
  ]);
423981
- function isRecord$12(value) {
424403
+ function isRecord$16(value) {
423982
424404
  return typeof value === "object" && value !== null && !Array.isArray(value);
423983
424405
  }
423984
424406
  function assertRecord(value, label) {
423985
- if (!isRecord$12(value)) throw new Error(`${label} must be an object.`);
424407
+ if (!isRecord$16(value)) throw new Error(`${label} must be an object.`);
423986
424408
  }
423987
424409
  function assertExactKeys(value, required, optional, label) {
423988
424410
  const allowed = new Set([...required, ...optional]);
@@ -424273,7 +424695,7 @@ function currentArtifactRecord(artifacts) {
424273
424695
  return result;
424274
424696
  }
424275
424697
  function readAttestationHash(value) {
424276
- if (!isRecord$12(value) || !isRecord$12(value["attestation"])) return null;
424698
+ if (!isRecord$16(value) || !isRecord$16(value["attestation"])) return null;
424277
424699
  const hash = value["attestation"]["hash"];
424278
424700
  return typeof hash === "string" && /^[a-f0-9]{64}$/.test(hash) ? hash : null;
424279
424701
  }
@@ -425045,21 +425467,21 @@ async function ensureSafeDirectory(path, create, recursive) {
425045
425467
  return true;
425046
425468
  }
425047
425469
  function validateRegistry(value, context) {
425048
- if (!isRecord$11(value) || value["version"] !== 1) throw new WorkspaceError("registry_invalid", "Unsupported workspace registry version.");
425470
+ if (!isRecord$15(value) || value["version"] !== 1) throw new WorkspaceError("registry_invalid", "Unsupported workspace registry version.");
425049
425471
  if (!hasExactKeys(value, REGISTRY_KEYS)) throw new WorkspaceError("registry_invalid", "Workspace registry contains unknown fields.");
425050
- if (value["repoFingerprint"] !== context.repoFingerprint || value["primaryRoot"] !== context.primaryRoot || !isRecord$11(value["workspaces"])) throw new WorkspaceError("registry_invalid", "Workspace registry does not match this repository.");
425472
+ if (value["repoFingerprint"] !== context.repoFingerprint || value["primaryRoot"] !== context.primaryRoot || !isRecord$15(value["workspaces"])) throw new WorkspaceError("registry_invalid", "Workspace registry does not match this repository.");
425051
425473
  for (const [name, record] of Object.entries(value["workspaces"])) if (!isWorkspaceRecord(record) || record.name !== name) throw new WorkspaceError("registry_invalid", "Workspace registry contains an invalid entry.");
425052
425474
  return value;
425053
425475
  }
425054
425476
  function isWorkspaceRecord(value) {
425055
- if (!isRecord$11(value) || !hasExactKeys(value, WORKSPACE_RECORD_KEYS)) return false;
425477
+ if (!isRecord$15(value) || !hasExactKeys(value, WORKSPACE_RECORD_KEYS)) return false;
425056
425478
  return typeof value["name"] === "string" && typeof value["path"] === "string" && typeof value["branch"] === "string" && typeof value["baseCommit"] === "string" && typeof value["repoFingerprint"] === "string" && isCanonicalIsoTimestamp(value["createdAt"]);
425057
425479
  }
425058
425480
  function isCanonicalIsoTimestamp(value) {
425059
425481
  if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(value)) return false;
425060
425482
  return new Date(value).toISOString() === value;
425061
425483
  }
425062
- function isRecord$11(value) {
425484
+ function isRecord$15(value) {
425063
425485
  if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
425064
425486
  const prototype = Object.getPrototypeOf(value);
425065
425487
  return prototype === Object.prototype || prototype === null;
@@ -425150,7 +425572,7 @@ async function readRegistryLockMetadata(lockPath) {
425150
425572
  if (error.code !== void 0) throw error;
425151
425573
  return;
425152
425574
  }
425153
- if (!isRecord$11(value) || !hasExactKeys(value, [
425575
+ if (!isRecord$15(value) || !hasExactKeys(value, [
425154
425576
  "version",
425155
425577
  "pid",
425156
425578
  "createdAt",
@@ -425859,7 +426281,7 @@ async function searchLocalWorkHistory(homeDir, sessions, query, limit = 8) {
425859
426281
  let skippedRecords = 0;
425860
426282
  for (const session of sessions) {
425861
426283
  const sessionDir = await realpath(session.sessionDir).catch(() => void 0);
425862
- if (sessionDir === void 0 || path.basename(sessionDir) !== session.id || !isInside(sessionsRoot, sessionDir)) {
426284
+ if (sessionDir === void 0 || path.basename(sessionDir) !== session.id || !isInside$1(sessionsRoot, sessionDir)) {
425863
426285
  skippedSessions++;
425864
426286
  continue;
425865
426287
  }
@@ -425881,7 +426303,7 @@ async function searchLocalWorkHistory(homeDir, sessions, query, limit = 8) {
425881
426303
  continue;
425882
426304
  }
425883
426305
  const canonicalWire = await realpath(wirePath).catch(() => void 0);
425884
- if (canonicalWire === void 0 || !isInside(sessionDir, canonicalWire)) {
426306
+ if (canonicalWire === void 0 || !isInside$1(sessionDir, canonicalWire)) {
425885
426307
  skippedSessions++;
425886
426308
  continue;
425887
426309
  }
@@ -425899,7 +426321,7 @@ async function searchLocalWorkHistory(homeDir, sessions, query, limit = 8) {
425899
426321
  skippedRecords++;
425900
426322
  continue;
425901
426323
  }
425902
- const event = isRecord$10(record) && record["type"] === "context.append_loop_event" && isRecord$10(record["event"]) ? record["event"] : void 0;
426324
+ const event = isRecord$14(record) && record["type"] === "context.append_loop_event" && isRecord$14(record["event"]) ? record["event"] : void 0;
425903
426325
  if (event?.["type"] === "step.end" && typeof event["uuid"] === "string") assistantSteps.delete(event["uuid"]);
425904
426326
  else if (event?.["type"] === "content.part" && typeof event["stepUuid"] === "string" && isTextPart(event["part"])) {
425905
426327
  const stepId = event["stepUuid"];
@@ -425976,11 +426398,11 @@ async function* boundedWireLines(wirePath, size) {
425976
426398
  }
425977
426399
  }
425978
426400
  function searchableText(record) {
425979
- if (!isRecord$10(record)) return void 0;
425980
- if (record["type"] === "context.append_message" && isRecord$10(record["message"])) {
426401
+ if (!isRecord$14(record)) return void 0;
426402
+ if (record["type"] === "context.append_message" && isRecord$14(record["message"])) {
425981
426403
  const message = record["message"];
425982
426404
  const origin = message["origin"];
425983
- if (message["role"] !== "user" && message["role"] !== "assistant" || message["role"] === "assistant" && origin !== void 0 || message["role"] === "user" && origin !== void 0 && (!isRecord$10(origin) || origin["kind"] !== "user")) return;
426405
+ if (message["role"] !== "user" && message["role"] !== "assistant" || message["role"] === "assistant" && origin !== void 0 || message["role"] === "user" && origin !== void 0 && (!isRecord$14(origin) || origin["kind"] !== "user")) return;
425984
426406
  const content = message["content"];
425985
426407
  if (!Array.isArray(content)) return void 0;
425986
426408
  const text = content.filter(isTextPart).map((part) => part.text).join(" ");
@@ -426002,12 +426424,12 @@ function snippet(text, firstTerm) {
426002
426424
  return `${start > 0 ? "..." : ""}${flattened.slice(start, end)}${end < flattened.length ? "..." : ""}`;
426003
426425
  }
426004
426426
  function isTextPart(value) {
426005
- return isRecord$10(value) && value["type"] === "text" && typeof value["text"] === "string";
426427
+ return isRecord$14(value) && value["type"] === "text" && typeof value["text"] === "string";
426006
426428
  }
426007
- function isRecord$10(value) {
426429
+ function isRecord$14(value) {
426008
426430
  return typeof value === "object" && value !== null && !Array.isArray(value);
426009
426431
  }
426010
- function isInside(parent, child) {
426432
+ function isInside$1(parent, child) {
426011
426433
  const relative = path.relative(parent, child);
426012
426434
  return relative !== "" && relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
426013
426435
  }
@@ -426100,7 +426522,7 @@ async function searchLocalToolEvents(homeDir, sessions, query, limit = 8) {
426100
426522
  };
426101
426523
  }
426102
426524
  function parseSavedEvent(value, sessionId) {
426103
- if (!isRecord$9(value) || value["version"] !== 1 || value["sessionId"] !== sessionId || typeof value["agentId"] !== "string" || !TOOL_NAME.test(value["agentId"]) || typeof value["tool"] !== "string" || !TOOL_NAME.test(value["tool"]) || typeof value["at"] !== "number" || !Number.isSafeInteger(value["at"]) || value["at"] < 0 || value["status"] !== "ok" && value["status"] !== "error" && value["status"] !== "synthetic") return;
426525
+ if (!isRecord$13(value) || value["version"] !== 1 || value["sessionId"] !== sessionId || typeof value["agentId"] !== "string" || !TOOL_NAME.test(value["agentId"]) || typeof value["tool"] !== "string" || !TOOL_NAME.test(value["tool"]) || typeof value["at"] !== "number" || !Number.isSafeInteger(value["at"]) || value["at"] < 0 || value["status"] !== "ok" && value["status"] !== "error" && value["status"] !== "synthetic") return;
426104
426526
  const filePath = value["filePath"];
426105
426527
  if (filePath !== void 0 && (typeof filePath !== "string" || filePath.length > 1024 || /[\u0000-\u001F\u007F]/u.test(filePath))) return void 0;
426106
426528
  return {
@@ -426132,7 +426554,7 @@ function localToolEventRecordingEnabled(homeDir) {
426132
426554
  }
426133
426555
  if (!info.isFile() || info.isSymbolicLink() || info.size > 1024) return false;
426134
426556
  const parsed = JSON.parse(readFileSync(settingsPath, "utf8"));
426135
- return isRecord$9(parsed) && parsed["version"] === 1 && parsed["enabled"] === true;
426557
+ return isRecord$13(parsed) && parsed["version"] === 1 && parsed["enabled"] === true;
426136
426558
  } catch {
426137
426559
  return false;
426138
426560
  }
@@ -426195,7 +426617,11 @@ function createLocalToolEventRecorder(homeDir, sessionId, enabled = localToolEve
426195
426617
  if (event.type === "tool.call.started") {
426196
426618
  if (!TOOL_NAME.test(event.name) || !TOOL_NAME.test(event.agentId)) return;
426197
426619
  if (pending.size >= MAX_PENDING_CALLS) pending.delete(pending.keys().next().value);
426198
- pending.set(event.toolCallId, {
426620
+ pending.set(JSON.stringify([
426621
+ event.agentId,
426622
+ event.turnId,
426623
+ event.toolCallId
426624
+ ]), {
426199
426625
  agentId: event.agentId,
426200
426626
  turnId: event.turnId,
426201
426627
  tool: event.name,
@@ -426204,9 +426630,14 @@ function createLocalToolEventRecorder(homeDir, sessionId, enabled = localToolEve
426204
426630
  return;
426205
426631
  }
426206
426632
  if (event.type !== "tool.result") return;
426207
- const started = pending.get(event.toolCallId);
426633
+ const key = JSON.stringify([
426634
+ event.agentId,
426635
+ event.turnId,
426636
+ event.toolCallId
426637
+ ]);
426638
+ const started = pending.get(key);
426208
426639
  if (started === void 0 || started.agentId !== event.agentId || started.turnId !== event.turnId) return;
426209
- pending.delete(event.toolCallId);
426640
+ pending.delete(key);
426210
426641
  const record = {
426211
426642
  version: 1,
426212
426643
  sessionId,
@@ -426234,7 +426665,7 @@ function createLocalToolEventRecorder(homeDir, sessionId, enabled = localToolEve
426234
426665
  };
426235
426666
  }
426236
426667
  function filePathFor(tool, args) {
426237
- if (!FILE_TOOLS.has(tool) || !isRecord$9(args)) return {};
426668
+ if (!FILE_TOOLS.has(tool) || !isRecord$13(args)) return {};
426238
426669
  const value = args["path"];
426239
426670
  if (typeof value !== "string" || value.length === 0 || value.length > 1024 || /[\u0000-\u001F\u007F]/u.test(value)) return {};
426240
426671
  return { filePath: value };
@@ -426277,11 +426708,11 @@ async function assertPlainDirectory(directory) {
426277
426708
  function samePath(a, b) {
426278
426709
  return process.platform === "win32" ? path.resolve(a).toLocaleLowerCase() === path.resolve(b).toLocaleLowerCase() : path.resolve(a) === path.resolve(b);
426279
426710
  }
426280
- function isRecord$9(value) {
426711
+ function isRecord$13(value) {
426281
426712
  return typeof value === "object" && value !== null && !Array.isArray(value);
426282
426713
  }
426283
426714
  function isErrno$1(error, code) {
426284
- return isRecord$9(error) && error["code"] === code;
426715
+ return isRecord$13(error) && error["code"] === code;
426285
426716
  }
426286
426717
  //#endregion
426287
426718
  //#region src/personal-memory/session-mcp.ts
@@ -426463,12 +426894,12 @@ function isPersonalMemoryToolName(name) {
426463
426894
  return PERSONAL_MEMORY_TOOL_NAMES.includes(name);
426464
426895
  }
426465
426896
  function normalizePhaseOneRecall(payload, limit) {
426466
- if (!isRecord$8(payload) || !Array.isArray(payload["ergebnis"])) throw new PersonalMemoryBrokerError("INVALID_PAYLOAD");
426897
+ if (!isRecord$12(payload) || !Array.isArray(payload["ergebnis"])) throw new PersonalMemoryBrokerError("INVALID_PAYLOAD");
426467
426898
  const results = payload["ergebnis"];
426468
426899
  if (results.length > 100) throw new PersonalMemoryBrokerError("INVALID_PAYLOAD");
426469
426900
  return { personal_memory: {
426470
426901
  saved: results.map((entry) => {
426471
- if (!isRecord$8(entry)) throw new PersonalMemoryBrokerError("INVALID_PAYLOAD");
426902
+ if (!isRecord$12(entry)) throw new PersonalMemoryBrokerError("INVALID_PAYLOAD");
426472
426903
  const text = entry["inhalt"];
426473
426904
  if (typeof text !== "string" || text.trim().length === 0 || text.length > 4e3) throw new PersonalMemoryBrokerError("INVALID_PAYLOAD");
426474
426905
  return {
@@ -426480,7 +426911,46 @@ function normalizePhaseOneRecall(payload, limit) {
426480
426911
  chat_history_context: []
426481
426912
  } };
426482
426913
  }
426483
- function isRecord$8(value) {
426914
+ function isRecord$12(value) {
426915
+ return typeof value === "object" && value !== null && !Array.isArray(value);
426916
+ }
426917
+ //#endregion
426918
+ //#region src/personal-memory/account-memory-recall.ts
426919
+ function mergeAccountMemoryRecall(phaseOne, account) {
426920
+ const existing = parsePhaseOne(phaseOne);
426921
+ if (existing === void 0 && account === void 0) throw new PersonalMemoryBrokerError("UNAVAILABLE");
426922
+ const saved = [...(existing?.personal_memory.saved ?? []).slice(0, 4), ...(account?.profile.card ?? []).slice(0, 4).map((text) => ({
426923
+ text: text.slice(0, 1e3),
426924
+ confidence: "medium"
426925
+ }))];
426926
+ const threads = (existing?.personal_memory.threads ?? []).slice(0, 4);
426927
+ if (account?.profile.representation.trim()) threads.push({
426928
+ title: "Account memory profile",
426929
+ summary: account.profile.representation.slice(0, 1e3)
426930
+ });
426931
+ for (const item of account?.items ?? []) {
426932
+ if (threads.length >= 8) break;
426933
+ threads.push({
426934
+ title: `${item.source} / ${item.sessionId}`.slice(0, 200),
426935
+ summary: item.text.slice(0, 1e3)
426936
+ });
426937
+ }
426938
+ return { personal_memory: {
426939
+ saved,
426940
+ threads,
426941
+ chat_history_context: []
426942
+ } };
426943
+ }
426944
+ function parsePhaseOne(value) {
426945
+ if (!isRecord$11(value) || !isRecord$11(value["personal_memory"])) return void 0;
426946
+ const memory = value["personal_memory"];
426947
+ if (!Array.isArray(memory["saved"]) || !Array.isArray(memory["threads"]) || !Array.isArray(memory["chat_history_context"]) || memory["chat_history_context"].length > 0) return void 0;
426948
+ const saved = memory["saved"];
426949
+ const threads = memory["threads"];
426950
+ if (saved.length > 8 || threads.length > 8 || !saved.every((item) => isRecord$11(item) && typeof item["text"] === "string" && item["text"].length <= 1e3 && item["confidence"] === "medium") || !threads.every((item) => isRecord$11(item) && typeof item["title"] === "string" && item["title"].length <= 200 && typeof item["summary"] === "string" && item["summary"].length <= 1e3)) return void 0;
426951
+ return value;
426952
+ }
426953
+ function isRecord$11(value) {
426484
426954
  return typeof value === "object" && value !== null && !Array.isArray(value);
426485
426955
  }
426486
426956
  //#endregion
@@ -426591,9 +427061,22 @@ const savedSearchResultSchema = object$1({ personal_memory: object$1({ saved: ar
426591
427061
  async function bindPersonalMemoryHostTools(session, harness, options = {}) {
426592
427062
  if (!supportsPersonalMemoryHostTools(session)) return;
426593
427063
  const binding = Object.prototype.hasOwnProperty.call(options, "binding") ? options.binding : personalMemoryHostBinding();
426594
- await clearPersonalMemoryHostTools(session);
426595
427064
  const localHistory = options.localHistory;
426596
427065
  const localOnlyEnabled = localHistory !== void 0 && localToolEventRecordingEnabled(localHistory.homeDir);
427066
+ const savedSearchEnabled = binding?.mode === "full" && binding.capabilities.recallEnabled;
427067
+ if (options.searchOnly) {
427068
+ await session.unregisterToolAndWait(PERSONAL_MEMORY_SEARCH_TOOL);
427069
+ if (localHistory === void 0 || !savedSearchEnabled && !localOnlyEnabled) return;
427070
+ const searchClient = savedSearchEnabled ? options.client ?? createPersonalMemoryBrokerClient(harness) : void 0;
427071
+ try {
427072
+ await registerPersonalMemorySearchTool(session, localHistory, searchClient, binding, savedSearchEnabled, localOnlyEnabled, savedSearchEnabled ? options.accountMemory : void 0);
427073
+ } catch (error) {
427074
+ await session.unregisterToolAndWait(PERSONAL_MEMORY_SEARCH_TOOL).catch(() => {});
427075
+ throw error;
427076
+ }
427077
+ return;
427078
+ }
427079
+ await clearPersonalMemoryHostTools(session);
426597
427080
  if (binding === void 0 && !localOnlyEnabled) return;
426598
427081
  const client = binding === void 0 ? void 0 : options.client ?? createPersonalMemoryBrokerClient(harness);
426599
427082
  const context = binding === void 0 ? void 0 : {
@@ -426604,45 +427087,10 @@ async function bindPersonalMemoryHostTools(session, harness, options = {}) {
426604
427087
  for (const name of binding === void 0 ? [] : personalMemoryToolNames(binding.mode, binding.capabilities)) {
426605
427088
  if (name === "memory_recall") continue;
426606
427089
  const definition = personalMemoryToolDefinition(name);
426607
- await session.registerToolAndWait(qualifiedPersonalMemoryToolName(name), definition.description, definition.parameters, createHostHandler(client, name, context, name === "memory_settings_update" ? () => refreshPersonalMemoryBinding(session, harness, client, localHistory) : void 0));
426608
- }
426609
- const savedSearchEnabled = binding?.mode === "full" && binding.capabilities.recallEnabled;
426610
- if (savedSearchEnabled) session.setHostToolCallHandler(PERSONAL_MEMORY_HOST_RECALL_HANDLER, createHostHandler(client, "memory_recall", context));
426611
- if (localHistory !== void 0 && (savedSearchEnabled || localOnlyEnabled)) await session.registerToolAndWait(PERSONAL_MEMORY_SEARCH_TOOL, "Search saved memories when enabled and this local profile's past work only when the user asks about prior work. Never use for routine recall.", toJSONSchema(searchInputSchema, { target: "draft-7" }), async (request) => {
426612
- const parsed = searchInputSchema.safeParse(request.args);
426613
- if (!parsed.success || !consumeWorkHistorySearchIntent(request)) return {
426614
- output: "EXPLICIT_HISTORY_REQUEST_REQUIRED",
426615
- isError: true
426616
- };
426617
- try {
426618
- const sessions = localHistory.listSessions({ includeArchive: true });
426619
- const [savedResult, workHistoryResult, toolEventsResult] = await Promise.allSettled([
426620
- savedSearchEnabled ? invokePersonalMemoryTool(client, "memory_recall", parsed.data, context) : Promise.resolve(void 0),
426621
- sessions.then((list) => searchLocalWorkHistory(localHistory.homeDir, list, parsed.data.query, parsed.data.limit)),
426622
- sessions.then((list) => searchLocalToolEvents(localHistory.homeDir, list, parsed.data.query, parsed.data.limit))
426623
- ]);
426624
- const saved = savedSearchEnabled && savedResult.status === "fulfilled" ? savedSearchResultSchema.safeParse(savedResult.value) : void 0;
426625
- const savedAvailable = saved?.success === true;
426626
- if (!savedAvailable && workHistoryResult.status === "rejected" && toolEventsResult.status === "rejected") return {
426627
- output: "MEMORY_SEARCH_UNAVAILABLE",
426628
- isError: true
426629
- };
426630
- return { output: JSON.stringify({
426631
- saved: savedAvailable ? previewSavedSearchResult(saved.data) : null,
426632
- savedAvailable,
426633
- workHistory: workHistoryResult.status === "fulfilled" ? workHistoryResult.value : null,
426634
- workHistoryAvailable: workHistoryResult.status === "fulfilled",
426635
- toolEvents: toolEventsResult.status === "fulfilled" ? toolEventsResult.value : null,
426636
- toolEventsAvailable: toolEventsResult.status === "fulfilled",
426637
- toolEventRecordingEnabled: localOnlyEnabled
426638
- }) };
426639
- } catch {
426640
- return {
426641
- output: "MEMORY_SEARCH_UNAVAILABLE",
426642
- isError: true
426643
- };
426644
- }
426645
- });
427090
+ await session.registerToolAndWait(qualifiedPersonalMemoryToolName(name), definition.description, definition.parameters, createHostHandler(client, name, context, name === "memory_settings_update" ? () => refreshPersonalMemoryBinding(session, harness, client, localHistory, options.accountMemory) : void 0));
427091
+ }
427092
+ if (savedSearchEnabled) session.setHostToolCallHandler(PERSONAL_MEMORY_HOST_RECALL_HANDLER, createHostHandler(client, "memory_recall", context, void 0, options.accountMemory));
427093
+ if (localHistory !== void 0 && (savedSearchEnabled || localOnlyEnabled)) await registerPersonalMemorySearchTool(session, localHistory, client, binding, savedSearchEnabled, localOnlyEnabled, savedSearchEnabled ? options.accountMemory : void 0);
426646
427094
  if (binding !== void 0) await session.setPersonalMemoryHostCapability(true);
426647
427095
  } catch (error) {
426648
427096
  resetPersonalMemorySession();
@@ -426650,6 +427098,55 @@ async function bindPersonalMemoryHostTools(session, harness, options = {}) {
426650
427098
  throw error;
426651
427099
  }
426652
427100
  }
427101
+ async function registerPersonalMemorySearchTool(session, localHistory, client, binding, savedSearchEnabled, localOnlyEnabled, accountMemory) {
427102
+ const context = binding === void 0 ? void 0 : {
427103
+ mode: binding.mode,
427104
+ capabilities: binding.capabilities
427105
+ };
427106
+ await session.registerToolAndWait(PERSONAL_MEMORY_SEARCH_TOOL, "Search saved memories when enabled and this local profile's past work only when the user asks about prior work. Never use for routine recall.", toJSONSchema(searchInputSchema, { target: "draft-7" }), async (request) => {
427107
+ const parsed = searchInputSchema.safeParse(request.args);
427108
+ if (!parsed.success || !consumeWorkHistorySearchIntent(request)) return {
427109
+ output: "EXPLICIT_HISTORY_REQUEST_REQUIRED",
427110
+ isError: true
427111
+ };
427112
+ try {
427113
+ const sessions = localHistory.listSessions({ includeArchive: true });
427114
+ const [savedResult, workHistoryResult, toolEventsResult, accountResult] = await Promise.allSettled([
427115
+ savedSearchEnabled ? invokePersonalMemoryTool(client, "memory_recall", parsed.data, context) : Promise.resolve(void 0),
427116
+ sessions.then((list) => searchLocalWorkHistory(localHistory.homeDir, list, parsed.data.query, parsed.data.limit)),
427117
+ sessions.then((list) => searchLocalToolEvents(localHistory.homeDir, list, parsed.data.query, parsed.data.limit)),
427118
+ accountMemory?.search(parsed.data.query, Math.min(20, parsed.data.limit)) ?? Promise.resolve(void 0)
427119
+ ]);
427120
+ const saved = savedSearchEnabled && savedResult.status === "fulfilled" ? savedSearchResultSchema.safeParse(savedResult.value) : void 0;
427121
+ const savedAvailable = saved?.success === true;
427122
+ if (!savedAvailable && workHistoryResult.status === "rejected" && toolEventsResult.status === "rejected" && (accountResult.status === "rejected" || accountResult.value === void 0)) return {
427123
+ output: "MEMORY_SEARCH_UNAVAILABLE",
427124
+ isError: true
427125
+ };
427126
+ return { output: JSON.stringify({
427127
+ saved: savedAvailable ? previewSavedSearchResult(saved.data) : null,
427128
+ savedAvailable,
427129
+ workHistory: workHistoryResult.status === "fulfilled" ? workHistoryResult.value : null,
427130
+ workHistoryAvailable: workHistoryResult.status === "fulfilled",
427131
+ toolEvents: toolEventsResult.status === "fulfilled" ? toolEventsResult.value : null,
427132
+ toolEventsAvailable: toolEventsResult.status === "fulfilled",
427133
+ accountHistory: accountResult.status === "fulfilled" ? accountResult.value?.items.slice(0, 8).map((item) => ({
427134
+ source: item.source,
427135
+ sessionId: item.sessionId,
427136
+ at: item.at,
427137
+ text: item.text.slice(0, 600)
427138
+ })) ?? null : null,
427139
+ accountHistoryAvailable: accountResult.status === "fulfilled" && accountResult.value !== void 0,
427140
+ toolEventRecordingEnabled: localOnlyEnabled
427141
+ }) };
427142
+ } catch {
427143
+ return {
427144
+ output: "MEMORY_SEARCH_UNAVAILABLE",
427145
+ isError: true
427146
+ };
427147
+ }
427148
+ });
427149
+ }
426653
427150
  function previewSavedSearchResult(result) {
426654
427151
  return { personal_memory: {
426655
427152
  saved: result.personal_memory.saved.map(({ text, confidence }) => {
@@ -426709,13 +427206,20 @@ function supportsPersonalMemoryHostTools(session) {
426709
427206
  function qualifiedPersonalMemoryToolName(name) {
426710
427207
  return `${PERSONAL_MEMORY_QUALIFIED_PREFIX}${name}`;
426711
427208
  }
426712
- function createHostHandler(client, name, context, afterSettingsUpdate) {
427209
+ function createHostHandler(client, name, context, afterSettingsUpdate, accountMemory) {
426713
427210
  return async (request) => {
426714
427211
  try {
426715
- const result = await invokePersonalMemoryTool(client, name, request.args, {
427212
+ const original = () => invokePersonalMemoryTool(client, name, request.args, {
426716
427213
  ...context,
426717
427214
  explicitRememberAttested: name === "memory_remember" ? consumePersonalMemoryRememberIntent(request) : void 0
426718
427215
  });
427216
+ let result;
427217
+ if (name === "memory_recall" && accountMemory !== void 0) {
427218
+ const parsed = searchInputSchema.safeParse(request.args);
427219
+ if (!parsed.success) throw new PersonalMemoryBrokerError("INVALID_PAYLOAD");
427220
+ const [phaseOne, account] = await Promise.all([original().catch(() => void 0), accountMemory.recall(parsed.data.query)]);
427221
+ result = mergeAccountMemoryRecall(phaseOne, account);
427222
+ } else result = await original();
426719
427223
  if (name === "memory_settings_update") await afterSettingsUpdate?.();
426720
427224
  return { output: JSON.stringify(result ?? null) };
426721
427225
  } catch (error) {
@@ -426726,7 +427230,7 @@ function createHostHandler(client, name, context, afterSettingsUpdate) {
426726
427230
  }
426727
427231
  };
426728
427232
  }
426729
- async function refreshPersonalMemoryBinding(session, harness, client, localHistory) {
427233
+ async function refreshPersonalMemoryBinding(session, harness, client, localHistory, accountMemory) {
426730
427234
  resetPersonalMemorySession();
426731
427235
  await clearPersonalMemoryHostTools(session);
426732
427236
  try {
@@ -426738,7 +427242,8 @@ async function refreshPersonalMemoryBinding(session, harness, client, localHisto
426738
427242
  await bindPersonalMemoryHostTools(session, harness, {
426739
427243
  binding,
426740
427244
  client,
426741
- localHistory
427245
+ localHistory,
427246
+ accountMemory
426742
427247
  });
426743
427248
  } catch (error) {
426744
427249
  resetPersonalMemorySession();
@@ -433263,7 +433768,7 @@ var TUI = class TUI extends Container {
433263
433768
  if (!debugRedraw) return;
433264
433769
  const logPath = path$17.join(nodeOs.homedir(), ".pi", "agent", "pi-debug.log");
433265
433770
  const msg = `[${(/* @__PURE__ */ new Date()).toISOString()}] fullRender: ${reason} (prev=${this.previousLines.length}, new=${newLines.length}, height=${height})\n`;
433266
- fs$16.appendFileSync(logPath, msg);
433771
+ fs$17.appendFileSync(logPath, msg);
433267
433772
  };
433268
433773
  if (this.previousLines.length === 0 && !widthChanged && !heightChanged) {
433269
433774
  logRedraw("first render");
@@ -433410,7 +433915,7 @@ var TUI = class TUI extends Container {
433410
433915
  buffer += "\x1B[?2026l";
433411
433916
  if (process.env["PI_TUI_DEBUG"] === "1") {
433412
433917
  const debugDir = "/tmp/tui";
433413
- fs$16.mkdirSync(debugDir, { recursive: true });
433918
+ fs$17.mkdirSync(debugDir, { recursive: true });
433414
433919
  const debugPath = path$17.join(debugDir, `render-${Date.now()}-${Math.random().toString(36).slice(2)}.log`);
433415
433920
  const debugData = [
433416
433921
  `firstChanged: ${firstChanged}`,
@@ -433434,7 +433939,7 @@ var TUI = class TUI extends Container {
433434
433939
  "=== buffer ===",
433435
433940
  JSON.stringify(buffer)
433436
433941
  ].join("\n");
433437
- fs$16.writeFileSync(debugPath, debugData);
433942
+ fs$17.writeFileSync(debugPath, debugData);
433438
433943
  }
433439
433944
  this.terminal.write(buffer);
433440
433945
  this.cursorRow = Math.max(0, newLines.length - 1);
@@ -438098,7 +438603,7 @@ var ProcessTerminal = class {
438098
438603
  const env = process.env["PI_TUI_WRITE_LOG"] || "";
438099
438604
  if (!env) return "";
438100
438605
  try {
438101
- if (fs$16.statSync(env).isDirectory()) {
438606
+ if (fs$17.statSync(env).isDirectory()) {
438102
438607
  const now = /* @__PURE__ */ new Date();
438103
438608
  const ts = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}_${String(now.getHours()).padStart(2, "0")}-${String(now.getMinutes()).padStart(2, "0")}-${String(now.getSeconds()).padStart(2, "0")}`;
438104
438609
  return path$17.join(env, `tui-${ts}-${process.pid}.log`);
@@ -438381,7 +438886,7 @@ var ProcessTerminal = class {
438381
438886
  write(data) {
438382
438887
  process.stdout.write(data);
438383
438888
  if (this.writeLogPath) try {
438384
- fs$16.appendFileSync(this.writeLogPath, data, { encoding: "utf8" });
438889
+ fs$17.appendFileSync(this.writeLogPath, data, { encoding: "utf8" });
438385
438890
  } catch {}
438386
438891
  }
438387
438892
  get columns() {
@@ -438469,6 +438974,148 @@ function sanitizeTerminalText(value) {
438469
438974
  return value.replaceAll(OSC_SEQUENCE$1, "").replaceAll(CSI_SEQUENCE$1, "").replaceAll(ESC_SEQUENCE$1, "").replaceAll(CONTROL_CHARACTERS$1, " ");
438470
438975
  }
438471
438976
  //#endregion
438977
+ //#region src/tui/utils/export-markdown.copy.ts
438978
+ registerUiCatalogFragment({
438979
+ en: {
438980
+ "export.thinking": "Thinking",
438981
+ "export.image": "image",
438982
+ "export.audio": "audio",
438983
+ "export.video": "video",
438984
+ "export.toolCall": "Tool Call: {name}",
438985
+ "export.toolResult": "Tool Result: {name}",
438986
+ "export.turn": "Turn {number}",
438987
+ "export.user": "User",
438988
+ "export.assistant": "Assistant",
438989
+ "export.system": "System",
438990
+ "export.unknownTool": "unknown",
438991
+ "export.overview": "Overview",
438992
+ "export.topic": "Topic",
438993
+ "export.labelSeparator": ":",
438994
+ "export.empty": "empty",
438995
+ "export.conversation": "Conversation",
438996
+ "export.turnCount.one": "{count} turn",
438997
+ "export.turnCount.other": "{count} turns",
438998
+ "export.toolCallCount.one": "{count} tool call",
438999
+ "export.toolCallCount.other": "{count} tool calls",
439000
+ "export.title": "King Session Export"
439001
+ },
439002
+ de: {
439003
+ "export.thinking": "Denken",
439004
+ "export.image": "Bild",
439005
+ "export.audio": "Audio",
439006
+ "export.video": "Video",
439007
+ "export.toolCall": "Werkzeugaufruf: {name}",
439008
+ "export.toolResult": "Werkzeugergebnis: {name}",
439009
+ "export.turn": "Durchlauf {number}",
439010
+ "export.user": "Benutzer",
439011
+ "export.assistant": "Assistent",
439012
+ "export.system": "System",
439013
+ "export.unknownTool": "unbekannt",
439014
+ "export.overview": "Übersicht",
439015
+ "export.topic": "Thema",
439016
+ "export.labelSeparator": ":",
439017
+ "export.empty": "leer",
439018
+ "export.conversation": "Gespräch",
439019
+ "export.turnCount.one": "{count} Durchlauf",
439020
+ "export.turnCount.other": "{count} Durchläufe",
439021
+ "export.toolCallCount.one": "{count} Werkzeugaufruf",
439022
+ "export.toolCallCount.other": "{count} Werkzeugaufrufe",
439023
+ "export.title": "King-Sitzungsexport"
439024
+ },
439025
+ es: {
439026
+ "export.thinking": "Razonamiento",
439027
+ "export.image": "imagen",
439028
+ "export.audio": "audio",
439029
+ "export.video": "vídeo",
439030
+ "export.toolCall": "Llamada a herramienta: {name}",
439031
+ "export.toolResult": "Resultado de la herramienta: {name}",
439032
+ "export.turn": "Turno {number}",
439033
+ "export.user": "Usuario",
439034
+ "export.assistant": "Asistente",
439035
+ "export.system": "Sistema",
439036
+ "export.unknownTool": "desconocida",
439037
+ "export.overview": "Resumen",
439038
+ "export.topic": "Tema",
439039
+ "export.labelSeparator": ":",
439040
+ "export.empty": "vacío",
439041
+ "export.conversation": "Conversación",
439042
+ "export.turnCount.one": "{count} turno",
439043
+ "export.turnCount.other": "{count} turnos",
439044
+ "export.toolCallCount.one": "{count} llamada a herramienta",
439045
+ "export.toolCallCount.other": "{count} llamadas a herramientas",
439046
+ "export.title": "Exportación de la sesión de King"
439047
+ },
439048
+ fr: {
439049
+ "export.thinking": "Réflexion",
439050
+ "export.image": "image",
439051
+ "export.audio": "audio",
439052
+ "export.video": "vidéo",
439053
+ "export.toolCall": "Appel d’outil\xA0: {name}",
439054
+ "export.toolResult": "Résultat de l’outil\xA0: {name}",
439055
+ "export.turn": "Tour {number}",
439056
+ "export.user": "Utilisateur",
439057
+ "export.assistant": "Assistant",
439058
+ "export.system": "Système",
439059
+ "export.unknownTool": "inconnu",
439060
+ "export.overview": "Vue d’ensemble",
439061
+ "export.topic": "Sujet",
439062
+ "export.labelSeparator": "\xA0:",
439063
+ "export.empty": "vide",
439064
+ "export.conversation": "Conversation",
439065
+ "export.turnCount.one": "{count} tour",
439066
+ "export.turnCount.other": "{count} tours",
439067
+ "export.toolCallCount.one": "{count} appel d’outil",
439068
+ "export.toolCallCount.other": "{count} appels d’outil",
439069
+ "export.title": "Export de la session King"
439070
+ },
439071
+ sv: {
439072
+ "export.thinking": "Resonemang",
439073
+ "export.image": "bild",
439074
+ "export.audio": "ljud",
439075
+ "export.video": "video",
439076
+ "export.toolCall": "Verktygsanrop: {name}",
439077
+ "export.toolResult": "Verktygsresultat: {name}",
439078
+ "export.turn": "Omgång {number}",
439079
+ "export.user": "Användare",
439080
+ "export.assistant": "Assistent",
439081
+ "export.system": "System",
439082
+ "export.unknownTool": "okänt",
439083
+ "export.overview": "Översikt",
439084
+ "export.topic": "Ämne",
439085
+ "export.labelSeparator": ":",
439086
+ "export.empty": "tomt",
439087
+ "export.conversation": "Konversation",
439088
+ "export.turnCount.one": "{count} omgång",
439089
+ "export.turnCount.other": "{count} omgångar",
439090
+ "export.toolCallCount.one": "{count} verktygsanrop",
439091
+ "export.toolCallCount.other": "{count} verktygsanrop",
439092
+ "export.title": "Export av King-session"
439093
+ },
439094
+ cs: {
439095
+ "export.thinking": "Uvažování",
439096
+ "export.image": "obrázek",
439097
+ "export.audio": "zvuk",
439098
+ "export.video": "video",
439099
+ "export.toolCall": "Volání nástroje: {name}",
439100
+ "export.toolResult": "Výsledek nástroje: {name}",
439101
+ "export.turn": "Kolo {number}",
439102
+ "export.user": "Uživatel",
439103
+ "export.assistant": "Asistent",
439104
+ "export.system": "Systém",
439105
+ "export.unknownTool": "neznámý",
439106
+ "export.overview": "Přehled",
439107
+ "export.topic": "Téma",
439108
+ "export.labelSeparator": ":",
439109
+ "export.empty": "prázdné",
439110
+ "export.conversation": "Konverzace",
439111
+ "export.turnCount.one": "Kola: {count}",
439112
+ "export.turnCount.other": "Kola: {count}",
439113
+ "export.toolCallCount.one": "{count} volání nástroje",
439114
+ "export.toolCallCount.other": "{count} volání nástrojů",
439115
+ "export.title": "Export relace King"
439116
+ }
439117
+ });
439118
+ //#endregion
438472
439119
  //#region src/tui/components/messages/usage-panel.ts
438473
439120
  registerUiCatalogFragment({
438474
439121
  en: {
@@ -438637,6 +439284,11 @@ function usageNumber(value) {
438637
439284
  function usageInputTotal$2(usage) {
438638
439285
  return usageNumber(usage.inputOther) + usageNumber(usage.inputCacheRead) + usageNumber(usage.inputCacheCreation);
438639
439286
  }
439287
+ function knownReasoningTokens(usage) {
439288
+ const value = usage.outputReasoning;
439289
+ const output = usageNumber(usage.output);
439290
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && value <= output ? value : void 0;
439291
+ }
438640
439292
  function managedUsageLabel(row) {
438641
439293
  switch (row.id) {
438642
439294
  case "five_hours": return uiText("usage.plan.window.fiveHours");
@@ -438685,14 +439337,23 @@ function buildSessionUsageSection(usage, error, value, muted, errorStyle) {
438685
439337
  const locale = getCurrentUiLocale();
438686
439338
  let totalInput = 0;
438687
439339
  let totalOutput = 0;
439340
+ let totalReasoning = 0;
439341
+ let reasoningComplete = true;
438688
439342
  for (const [model, row] of entries) {
438689
439343
  const input = usageInputTotal$2(row);
438690
439344
  const output = usageNumber(row.output);
439345
+ const reasoning = knownReasoningTokens(row);
438691
439346
  totalInput += input;
438692
439347
  totalOutput += output;
438693
- lines.push(` ${muted(sanitizeTerminalText(model))} ${uiText("usage.input")} ${value(formatExactTokenCount(input, locale))} ${uiText("usage.output")} ${value(formatExactTokenCount(output, locale))} ${uiText("usage.total")} ${value(formatExactTokenCount(input + output, locale))}`);
439348
+ if (reasoning !== void 0) totalReasoning += reasoning;
439349
+ else if (output > 0) reasoningComplete = false;
439350
+ const reasoningPart = reasoning === void 0 ? "" : ` ${uiText("export.thinking")} ${value(formatExactTokenCount(reasoning, locale))}`;
439351
+ lines.push(` ${muted(sanitizeTerminalText(model))} ${uiText("usage.input")} ${value(formatExactTokenCount(input, locale))} ${uiText("usage.output")} ${value(formatExactTokenCount(output, locale))}${reasoningPart} ${uiText("usage.total")} ${value(formatExactTokenCount(input + output, locale))}`);
439352
+ }
439353
+ if (entries.length > 1) {
439354
+ const reasoningPart = reasoningComplete && totalOutput > 0 ? ` ${uiText("export.thinking")} ${value(formatExactTokenCount(totalReasoning, locale))}` : "";
439355
+ lines.push(` ${muted(uiText("usage.total"))} ${uiText("usage.input")} ${value(formatExactTokenCount(totalInput, locale))} ${uiText("usage.output")} ${value(formatExactTokenCount(totalOutput, locale))}${reasoningPart} ${uiText("usage.total")} ${value(formatExactTokenCount(totalInput + totalOutput, locale))}`);
438694
439356
  }
438695
- if (entries.length > 1) lines.push(` ${muted(uiText("usage.total"))} ${uiText("usage.input")} ${value(formatExactTokenCount(totalInput, locale))} ${uiText("usage.output")} ${value(formatExactTokenCount(totalOutput, locale))} ${uiText("usage.total")} ${value(formatExactTokenCount(totalInput + totalOutput, locale))}`);
438696
439357
  return lines;
438697
439358
  }
438698
439359
  function buildManagedUsageSection(usage, error, accent, value, muted, errorStyle) {
@@ -502741,7 +503402,7 @@ function parsePluginMarketplace(raw, location) {
502741
503402
  } catch (error) {
502742
503403
  throw new Error(`Plugin marketplace is not valid JSON: ${formatParseError(error)}`, { cause: error });
502743
503404
  }
502744
- if (!isRecord$7(parsed)) throw new TypeError("Plugin marketplace must be an object.");
503405
+ if (!isRecord$10(parsed)) throw new TypeError("Plugin marketplace must be an object.");
502745
503406
  const rawPlugins = parsed["plugins"];
502746
503407
  if (!Array.isArray(rawPlugins)) throw new TypeError("Plugin marketplace must contain a \"plugins\" array.");
502747
503408
  return {
@@ -502785,7 +503446,7 @@ async function readMarketplaceText(location, fetchImpl) {
502785
503446
  return response.text();
502786
503447
  }
502787
503448
  function parseMarketplaceEntry(value, index, location) {
502788
- if (!isRecord$7(value)) throw new TypeError(`Plugin marketplace entry ${index + 1} must be an object.`);
503449
+ if (!isRecord$10(value)) throw new TypeError(`Plugin marketplace entry ${index + 1} must be an object.`);
502789
503450
  const id = requiredString(value, "id", index);
502790
503451
  validateMarketplaceEntryType(value, id);
502791
503452
  const source = stringField$2(value, "source") ?? stringField$2(value, "url") ?? stringField$2(value, "downloadUrl");
@@ -502921,7 +503582,7 @@ function stringArrayField(value, field) {
502921
503582
  const out = raw.filter((item) => typeof item === "string").map((item) => item.trim()).filter((item) => item.length > 0);
502922
503583
  return out.length > 0 ? out : void 0;
502923
503584
  }
502924
- function isRecord$7(value) {
503585
+ function isRecord$10(value) {
502925
503586
  return typeof value === "object" && value !== null && !Array.isArray(value);
502926
503587
  }
502927
503588
  function formatParseError(error) {
@@ -505023,6 +505684,7 @@ async function handleBlunApiKeyLogin(host, options, promptOptions) {
505023
505684
  provider: DEFAULT_OAUTH_PROVIDER_NAME,
505024
505685
  method: "api_key"
505025
505686
  });
505687
+ host.accountMemoryRuntime?.retryPending().catch(() => {});
505026
505688
  host.showStatus(uiText("auth.login.success"));
505027
505689
  return "authenticated";
505028
505690
  }
@@ -505065,6 +505727,7 @@ async function handleBlunCodeOAuthLogin(host, options = {}) {
505065
505727
  method: "oauth",
505066
505728
  already_logged_in: alreadyLoggedIn
505067
505729
  });
505730
+ host.accountMemoryRuntime?.retryPending().catch(() => {});
505068
505731
  if (alreadyLoggedIn) host.showStatus(uiText("auth.login.already"));
505069
505732
  return "authenticated";
505070
505733
  } catch (error) {
@@ -505109,11 +505772,16 @@ async function handleLogoutCommand(host) {
505109
505772
  const currentProvider = host.state.appState.availableModels[currentModel]?.provider;
505110
505773
  const target = await promptLogoutProviderSelection(host, options, currentProvider);
505111
505774
  if (target === void 0) return;
505775
+ const memoryRetractionPending = await host.accountMemoryRuntime?.flushRetractionsBeforeLogout() ?? false;
505112
505776
  showAuthWarnings(host, (await host.harness.auth.logout(DEFAULT_OAUTH_PROVIDER_NAME)).warnings);
505113
505777
  await host.authFlow.refreshConfigAfterLogout({ clearCustomerAccount: true });
505114
505778
  await host.authFlow.clearActiveSessionAfterLogout({ clearCustomerAccount: true });
505115
505779
  host.track("logout", { provider: target });
505116
505780
  host.showStatus(uiText("auth.logout.complete", { provider: PRODUCT_NAME }));
505781
+ if (memoryRetractionPending) {
505782
+ const key = hasManagedApiKey ? "auth.warning.memoryRetractionApiKeyPending" : "auth.warning.memoryRetractionOAuthPending";
505783
+ host.showStatus(uiText(key), "warning");
505784
+ }
505117
505785
  }
505118
505786
  function showAuthWarnings(host, warnings) {
505119
505787
  if (warnings?.some((warning) => warning.code === "remote_revoke_failed") === true) host.showStatus(uiText("auth.warning.remoteRevokeFailed"), "warning");
@@ -505477,11 +506145,15 @@ async function showContextReport(host, detailed) {
505477
506145
  const sources = detailed !== "map" && request?.systemPromptContributions?.version === 1 ? request.systemPromptContributions : void 0;
505478
506146
  const instructionSources = detailed === true && sources?.instructionSources?.version === 1 ? sources.instructionSources : void 0;
505479
506147
  const skillSources = detailed === true && sources?.skillListingSources?.version === 1 ? sources.skillListingSources : void 0;
505480
- const files = instructionSources?.files.map((file) => ({
506148
+ const files = instructionSources === void 0 ? void 0 : [...instructionSources.files.map((file) => ({
505481
506149
  path: diagnosticLabel(file.path),
505482
506150
  bytes: validTextSize(file.bytes),
505483
506151
  sourceTextBytes: validTextSize(file.sourceTextBytes)
505484
- }));
506152
+ })), ...(instructionSources.notLoadedCandidates ?? []).map((path) => ({
506153
+ path: diagnosticLabel(path),
506154
+ bytes: 0,
506155
+ sourceTextBytes: void 0
506156
+ }))];
505485
506157
  const memorySource = detailed === true ? sources?.runtimeMemorySource : void 0;
505486
506158
  const origins = detailed === true && request?.historyTextOrigins?.version === 1 && request.historyTextOrigins.unit === "utf8-text" ? request.historyTextOrigins : void 0;
505487
506159
  const lastRequest = request === void 0 ? void 0 : {
@@ -505541,6 +506213,11 @@ async function showContextReport(host, detailed) {
505541
506213
  name: tool.name === void 0 ? void 0 : diagnosticLabel(tool.name),
505542
506214
  bytes: validTextSize(tool.bytes)
505543
506215
  })) : void 0,
506216
+ toolResults: detailed === true ? breakdown?.toolResultByTool?.map((tool) => ({
506217
+ name: tool.name === void 0 ? void 0 : diagnosticLabel(tool.name),
506218
+ count: validTextSize(tool.count),
506219
+ bytes: validTextSize(tool.bytes)
506220
+ })) : void 0,
505544
506221
  toolArrayOverheadBytes: validTextSize(breakdown?.toolArrayOverheadBytes),
505545
506222
  historyOrigins: origins === void 0 ? void 0 : {
505546
506223
  totalBytes: validTextSize(origins.totalBytes),
@@ -505608,6 +506285,15 @@ async function showContextReport(host, detailed) {
505608
506285
  if (lastRequest.tools.length > 20) lines.push(`... (+${String(lastRequest.tools.length - 20)})`);
505609
506286
  lines.push(row("context.otherPart", lastRequest.toolArrayOverheadBytes));
505610
506287
  }
506288
+ if (lastRequest.toolResults !== void 0) {
506289
+ lines.push("", currentTheme.boldFg("primary", uiText("context.toolResultsPart")));
506290
+ for (const tool of lastRequest.toolResults.toSorted((a, b) => (b.bytes ?? -1) - (a.bytes ?? -1)).slice(0, 20)) {
506291
+ const count = tool.count === void 0 ? "?" : formatExactTokenCount(tool.count, getCurrentUiLocale());
506292
+ const size = tool.bytes === void 0 ? uiText("context.unavailable") : formatExactTokenCount(tool.bytes, getCurrentUiLocale());
506293
+ lines.push(`${tool.name ?? "?"} (${count}): ${size}`);
506294
+ }
506295
+ if (lastRequest.toolResults.length > 20) lines.push(`... (+${String(lastRequest.toolResults.length - 20)})`);
506296
+ }
505611
506297
  lines.push("", currentTheme.boldFg("primary", uiText("context.promptTextBytes")), currentTheme.fg("textDim", uiText("context.sourceNote")), row("context.instructionPart", lastRequest.sources[0]), row("context.skillListingPart", lastRequest.sources[1]), row("context.runtimeMemoryPart", lastRequest.sources[2]), row("context.templatePart", lastRequest.sources[3]), row("context.totalPart", lastRequest.sources[4]), "", currentTheme.boldFg("primary", uiText("context.sourceFilesPart")), row("context.generatedPart", lastRequest.sources[5]));
505612
506298
  if (lastRequest.files === void 0) lines.push(uiText("context.unavailable"));
505613
506299
  else {
@@ -505994,7 +506680,7 @@ var ChannelCommandController = class {
505994
506680
  function requireValid(condition) {
505995
506681
  if (!condition) throw new Error("Invalid Telegram session queue state or transition");
505996
506682
  }
505997
- function isRecord$6(value) {
506683
+ function isRecord$9(value) {
505998
506684
  return typeof value === "object" && value !== null && !Array.isArray(value);
505999
506685
  }
506000
506686
  function isId(value) {
@@ -506004,7 +506690,7 @@ function isOffset(value) {
506004
506690
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
506005
506691
  }
506006
506692
  function readSpan(value) {
506007
- requireValid(isRecord$6(value));
506693
+ requireValid(isRecord$9(value));
506008
506694
  const { start, end } = value;
506009
506695
  requireValid(isOffset(start) && isOffset(end) && start < end);
506010
506696
  return {
@@ -506017,7 +506703,7 @@ function ownsRange(state, sessionId, span) {
506017
506703
  }
506018
506704
  /** Reject incompatible or corrupt state; never silently fall back to the profile cursor. */
506019
506705
  function parseSessionQueue(value) {
506020
- requireValid(isRecord$6(value));
506706
+ requireValid(isRecord$9(value));
506021
506707
  const { version, fileId, frontier, activeSessionId, sessions, spans, acknowledged } = value;
506022
506708
  requireValid(version === 1 && isId(fileId) && isOffset(frontier) && isId(activeSessionId));
506023
506709
  requireValid(Array.isArray(sessions) && sessions.every(isId));
@@ -506026,7 +506712,7 @@ function parseSessionQueue(value) {
506026
506712
  requireValid(Array.isArray(spans) && Array.isArray(acknowledged));
506027
506713
  const owned = spans.map((raw) => {
506028
506714
  const span = readSpan(raw);
506029
- requireValid(isRecord$6(raw));
506715
+ requireValid(isRecord$9(raw));
506030
506716
  const sessionId = raw["sessionId"];
506031
506717
  requireValid(sessionId === null || isId(sessionId) && known.has(sessionId));
506032
506718
  return {
@@ -508517,14 +509203,14 @@ function findGoalIndex(file, goalId) {
508517
509203
  return index;
508518
509204
  }
508519
509205
  function isGoalQueueFile(value) {
508520
- if (!isRecord$5(value)) return false;
509206
+ if (!isRecord$8(value)) return false;
508521
509207
  return value["version"] === GOAL_QUEUE_VERSION && Array.isArray(value["goals"]) && value["goals"].every(isUpcomingGoal);
508522
509208
  }
508523
509209
  function isUpcomingGoal(value) {
508524
- if (!isRecord$5(value)) return false;
509210
+ if (!isRecord$8(value)) return false;
508525
509211
  return isNonEmptyString(value["id"]) && isNonEmptyString(value["objective"]) && isNonEmptyString(value["createdAt"]) && isNonEmptyString(value["updatedAt"]);
508526
509212
  }
508527
- function isRecord$5(value) {
509213
+ function isRecord$8(value) {
508528
509214
  return typeof value === "object" && value !== null && !Array.isArray(value);
508529
509215
  }
508530
509216
  function isNonEmptyString(value) {
@@ -508537,7 +509223,7 @@ function timestampAfter(previous) {
508537
509223
  return now.toISOString();
508538
509224
  }
508539
509225
  function isErrno(error, code) {
508540
- return isRecord$5(error) && error["code"] === code;
509226
+ return isRecord$8(error) && error["code"] === code;
508541
509227
  }
508542
509228
  function describeError(error) {
508543
509229
  return error instanceof Error ? error.message : String(error);
@@ -512178,7 +512864,8 @@ async function handleMemoryCommand(host, args, dependencies) {
512178
512864
  const enabled = parsed.action === "on";
512179
512865
  await setLocalToolEventRecordingEnabled(host.harness.homeDir, enabled);
512180
512866
  host.setLocalToolEventRecordingEnabled?.(enabled);
512181
- await host.refreshPersonalMemory?.(false);
512867
+ if (host.refreshLocalToolSearch !== void 0) await host.refreshLocalToolSearch();
512868
+ else await host.refreshPersonalMemory?.(false);
512182
512869
  }
512183
512870
  host.showStatus(`/memory tools ${localToolEventRecordingEnabled(host.harness.homeDir) ? "enabled" : "disabled"}`);
512184
512871
  return;
@@ -513307,148 +513994,6 @@ function isAbortError$1(error) {
513307
513994
  return isAbortMessage(String(error));
513308
513995
  }
513309
513996
  //#endregion
513310
- //#region src/tui/utils/export-markdown.copy.ts
513311
- registerUiCatalogFragment({
513312
- en: {
513313
- "export.thinking": "Thinking",
513314
- "export.image": "image",
513315
- "export.audio": "audio",
513316
- "export.video": "video",
513317
- "export.toolCall": "Tool Call: {name}",
513318
- "export.toolResult": "Tool Result: {name}",
513319
- "export.turn": "Turn {number}",
513320
- "export.user": "User",
513321
- "export.assistant": "Assistant",
513322
- "export.system": "System",
513323
- "export.unknownTool": "unknown",
513324
- "export.overview": "Overview",
513325
- "export.topic": "Topic",
513326
- "export.labelSeparator": ":",
513327
- "export.empty": "empty",
513328
- "export.conversation": "Conversation",
513329
- "export.turnCount.one": "{count} turn",
513330
- "export.turnCount.other": "{count} turns",
513331
- "export.toolCallCount.one": "{count} tool call",
513332
- "export.toolCallCount.other": "{count} tool calls",
513333
- "export.title": "King Session Export"
513334
- },
513335
- de: {
513336
- "export.thinking": "Denken",
513337
- "export.image": "Bild",
513338
- "export.audio": "Audio",
513339
- "export.video": "Video",
513340
- "export.toolCall": "Werkzeugaufruf: {name}",
513341
- "export.toolResult": "Werkzeugergebnis: {name}",
513342
- "export.turn": "Durchlauf {number}",
513343
- "export.user": "Benutzer",
513344
- "export.assistant": "Assistent",
513345
- "export.system": "System",
513346
- "export.unknownTool": "unbekannt",
513347
- "export.overview": "Übersicht",
513348
- "export.topic": "Thema",
513349
- "export.labelSeparator": ":",
513350
- "export.empty": "leer",
513351
- "export.conversation": "Gespräch",
513352
- "export.turnCount.one": "{count} Durchlauf",
513353
- "export.turnCount.other": "{count} Durchläufe",
513354
- "export.toolCallCount.one": "{count} Werkzeugaufruf",
513355
- "export.toolCallCount.other": "{count} Werkzeugaufrufe",
513356
- "export.title": "King-Sitzungsexport"
513357
- },
513358
- es: {
513359
- "export.thinking": "Razonamiento",
513360
- "export.image": "imagen",
513361
- "export.audio": "audio",
513362
- "export.video": "vídeo",
513363
- "export.toolCall": "Llamada a herramienta: {name}",
513364
- "export.toolResult": "Resultado de la herramienta: {name}",
513365
- "export.turn": "Turno {number}",
513366
- "export.user": "Usuario",
513367
- "export.assistant": "Asistente",
513368
- "export.system": "Sistema",
513369
- "export.unknownTool": "desconocida",
513370
- "export.overview": "Resumen",
513371
- "export.topic": "Tema",
513372
- "export.labelSeparator": ":",
513373
- "export.empty": "vacío",
513374
- "export.conversation": "Conversación",
513375
- "export.turnCount.one": "{count} turno",
513376
- "export.turnCount.other": "{count} turnos",
513377
- "export.toolCallCount.one": "{count} llamada a herramienta",
513378
- "export.toolCallCount.other": "{count} llamadas a herramientas",
513379
- "export.title": "Exportación de la sesión de King"
513380
- },
513381
- fr: {
513382
- "export.thinking": "Réflexion",
513383
- "export.image": "image",
513384
- "export.audio": "audio",
513385
- "export.video": "vidéo",
513386
- "export.toolCall": "Appel d’outil\xA0: {name}",
513387
- "export.toolResult": "Résultat de l’outil\xA0: {name}",
513388
- "export.turn": "Tour {number}",
513389
- "export.user": "Utilisateur",
513390
- "export.assistant": "Assistant",
513391
- "export.system": "Système",
513392
- "export.unknownTool": "inconnu",
513393
- "export.overview": "Vue d’ensemble",
513394
- "export.topic": "Sujet",
513395
- "export.labelSeparator": "\xA0:",
513396
- "export.empty": "vide",
513397
- "export.conversation": "Conversation",
513398
- "export.turnCount.one": "{count} tour",
513399
- "export.turnCount.other": "{count} tours",
513400
- "export.toolCallCount.one": "{count} appel d’outil",
513401
- "export.toolCallCount.other": "{count} appels d’outil",
513402
- "export.title": "Export de la session King"
513403
- },
513404
- sv: {
513405
- "export.thinking": "Resonemang",
513406
- "export.image": "bild",
513407
- "export.audio": "ljud",
513408
- "export.video": "video",
513409
- "export.toolCall": "Verktygsanrop: {name}",
513410
- "export.toolResult": "Verktygsresultat: {name}",
513411
- "export.turn": "Omgång {number}",
513412
- "export.user": "Användare",
513413
- "export.assistant": "Assistent",
513414
- "export.system": "System",
513415
- "export.unknownTool": "okänt",
513416
- "export.overview": "Översikt",
513417
- "export.topic": "Ämne",
513418
- "export.labelSeparator": ":",
513419
- "export.empty": "tomt",
513420
- "export.conversation": "Konversation",
513421
- "export.turnCount.one": "{count} omgång",
513422
- "export.turnCount.other": "{count} omgångar",
513423
- "export.toolCallCount.one": "{count} verktygsanrop",
513424
- "export.toolCallCount.other": "{count} verktygsanrop",
513425
- "export.title": "Export av King-session"
513426
- },
513427
- cs: {
513428
- "export.thinking": "Uvažování",
513429
- "export.image": "obrázek",
513430
- "export.audio": "zvuk",
513431
- "export.video": "video",
513432
- "export.toolCall": "Volání nástroje: {name}",
513433
- "export.toolResult": "Výsledek nástroje: {name}",
513434
- "export.turn": "Kolo {number}",
513435
- "export.user": "Uživatel",
513436
- "export.assistant": "Asistent",
513437
- "export.system": "Systém",
513438
- "export.unknownTool": "neznámý",
513439
- "export.overview": "Přehled",
513440
- "export.topic": "Téma",
513441
- "export.labelSeparator": ":",
513442
- "export.empty": "prázdné",
513443
- "export.conversation": "Konverzace",
513444
- "export.turnCount.one": "Kola: {count}",
513445
- "export.turnCount.other": "Kola: {count}",
513446
- "export.toolCallCount.one": "{count} volání nástroje",
513447
- "export.toolCallCount.other": "{count} volání nástrojů",
513448
- "export.title": "Export relace King"
513449
- }
513450
- });
513451
- //#endregion
513452
513997
  //#region src/tui/utils/export-markdown.ts
513453
513998
  const HINT_KEYS = [
513454
513999
  "path",
@@ -520453,10 +520998,10 @@ function parseGoalValue(output) {
520453
520998
  } catch {
520454
520999
  return;
520455
521000
  }
520456
- if (!isRecord$4(parsed) || !("goal" in parsed)) return void 0;
521001
+ if (!isRecord$7(parsed) || !("goal" in parsed)) return void 0;
520457
521002
  const goal = parsed["goal"];
520458
521003
  if (goal === null) return null;
520459
- if (!isRecord$4(goal)) return void 0;
521004
+ if (!isRecord$7(goal)) return void 0;
520460
521005
  return goal;
520461
521006
  }
520462
521007
  function formatGoalStats(goal) {
@@ -520478,7 +521023,7 @@ function stringArg(args, key) {
520478
521023
  const value = args[key];
520479
521024
  return typeof value === "string" && value.length > 0 ? value : void 0;
520480
521025
  }
520481
- function isRecord$4(value) {
521026
+ function isRecord$7(value) {
520482
521027
  return typeof value === "object" && value !== null && !Array.isArray(value);
520483
521028
  }
520484
521029
  function stringField$1(record, key) {
@@ -524530,10 +525075,10 @@ var CustomerMistakeBrokerError = class extends Error {
524530
525075
  }
524531
525076
  };
524532
525077
  function parseMistakeConsent(payload) {
524533
- if (!isRecord$3(payload)) return void 0;
524534
- const settings = (isRecord$3(payload["data"]) ? payload["data"] : payload)["settings"];
524535
- const dataControls = isRecord$3(settings) ? settings["data_controls"] : void 0;
524536
- if (!isRecord$3(dataControls)) return void 0;
525078
+ if (!isRecord$6(payload)) return void 0;
525079
+ const settings = (isRecord$6(payload["data"]) ? payload["data"] : payload)["settings"];
525080
+ const dataControls = isRecord$6(settings) ? settings["data_controls"] : void 0;
525081
+ if (!isRecord$6(dataControls)) return void 0;
524537
525082
  const asked = dataControls["mistake_consent_asked"];
524538
525083
  const allowed = dataControls["allow_mistake"];
524539
525084
  if (typeof asked !== "boolean" || typeof allowed !== "boolean") return void 0;
@@ -524647,7 +525192,7 @@ function normalizeBaseUrl(value) {
524647
525192
  if (url.protocol !== "https:" || url.username.length > 0 || url.password.length > 0 || url.search.length > 0 || url.hash.length > 0 || url.pathname !== "/" && url.pathname !== "") throw new CustomerMistakeBrokerError("INVALID_PAYLOAD");
524648
525193
  return url.origin;
524649
525194
  }
524650
- function isRecord$3(value) {
525195
+ function isRecord$6(value) {
524651
525196
  return typeof value === "object" && value !== null && !Array.isArray(value);
524652
525197
  }
524653
525198
  //#endregion
@@ -524739,6 +525284,902 @@ var CustomerMistakeHostController = class {
524739
525284
  }
524740
525285
  };
524741
525286
  //#endregion
525287
+ //#region src/personal-memory/account-memory-broker.ts
525288
+ const MAX_CAPTURE_BYTES = 1e6;
525289
+ const UUID_V4$1 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
525290
+ var AccountMemoryBroker = class {
525291
+ client;
525292
+ constructor(client) {
525293
+ this.client = client;
525294
+ }
525295
+ async workspace(sessionId) {
525296
+ if (sessionId !== void 0 && (!sessionId.trim() || sessionId.length > 200)) invalid();
525297
+ const path = sessionId === void 0 ? "/api/memory/workspace" : `/api/memory/workspace?source=tui&sessionId=${encodeURIComponent(sessionId)}`;
525298
+ const value = await this.client.request("GET", path);
525299
+ if (!isRecord$5(value) || typeof value["workspaceId"] !== "string" || !/^blun-[0-9a-f]{64}$/iu.test(value["workspaceId"]) || !generation(value["forgetGeneration"]) || sessionId !== void 0 && !generation(value["sessionEpoch"]) || value["forgetCutoff"] !== null && !isoTime$1(value["forgetCutoff"])) invalid();
525300
+ return {
525301
+ workspaceId: value["workspaceId"],
525302
+ forgetGeneration: value["forgetGeneration"],
525303
+ forgetCutoff: value["forgetCutoff"],
525304
+ sessionEpoch: sessionId === void 0 ? null : value["sessionEpoch"]
525305
+ };
525306
+ }
525307
+ async capture(input) {
525308
+ if (!UUID_V4$1.test(input.captureId) || !input.sessionId.trim() || !generation(input.forgetGeneration) || input.sessionEpoch !== null && !generation(input.sessionEpoch) || input.messages.length === 0 || input.messages.length > 200 || input.messages.some((message) => !messageId$1(message.id) || !["user", "assistant"].includes(message.role) || !message.content.trim() || !isoTime$1(message.at))) invalid();
525309
+ if (new Set(input.messages.map((message) => message.id)).size !== input.messages.length) invalid();
525310
+ const body = {
525311
+ captureId: input.captureId,
525312
+ source: "tui",
525313
+ sessionId: input.sessionId,
525314
+ forgetGeneration: input.forgetGeneration,
525315
+ sessionEpoch: input.sessionEpoch,
525316
+ messages: input.messages.map((message) => ({
525317
+ id: message.id,
525318
+ role: message.role,
525319
+ content: message.content,
525320
+ at: message.at
525321
+ }))
525322
+ };
525323
+ if (Buffer.byteLength(JSON.stringify(body), "utf8") > MAX_CAPTURE_BYTES) invalid();
525324
+ const value = await this.client.request("POST", "/api/memory/capture", body);
525325
+ if (isRecord$5(value) && value["accepted"] === 0 && value["reason"] === "memory_disabled") return {
525326
+ accepted: 0,
525327
+ reason: "memory_disabled"
525328
+ };
525329
+ if (isRecord$5(value) && value["accepted"] === 0 && value["reason"] === "session_retracted" && generation(value["skipped"]) && generation(value["sessionEpoch"])) return {
525330
+ accepted: 0,
525331
+ skipped: value["skipped"],
525332
+ reason: "session_retracted",
525333
+ sessionEpoch: value["sessionEpoch"]
525334
+ };
525335
+ if (!isRecord$5(value) || !generation(value["accepted"]) || !generation(value["skipped"]) || typeof value["duplicate"] !== "boolean" || !generation(value["forgetGeneration"]) || !generation(value["sessionEpoch"])) invalid();
525336
+ return {
525337
+ accepted: value["accepted"],
525338
+ skipped: value["skipped"],
525339
+ duplicate: value["duplicate"],
525340
+ forgetGeneration: value["forgetGeneration"],
525341
+ sessionEpoch: value["sessionEpoch"]
525342
+ };
525343
+ }
525344
+ async retract(input) {
525345
+ if (!UUID_V4$1.test(input.retractId) || !input.sessionId.trim() || input.sessionId.length > 200 || "wholeSession" in input && input.expectedEpoch !== null && !generation(input.expectedEpoch)) invalid();
525346
+ const body = "wholeSession" in input ? {
525347
+ retractId: input.retractId,
525348
+ source: "tui",
525349
+ sessionId: input.sessionId,
525350
+ wholeSession: true,
525351
+ expectedEpoch: input.expectedEpoch
525352
+ } : {
525353
+ retractId: input.retractId,
525354
+ source: "tui",
525355
+ sessionId: input.sessionId,
525356
+ messageIds: input.messageIds
525357
+ };
525358
+ if (!("wholeSession" in input) && (input.messageIds.length === 0 || input.messageIds.length > 200 || input.messageIds.some((id) => !messageId$1(id)) || new Set(input.messageIds).size !== input.messageIds.length)) invalid();
525359
+ const value = await this.client.request("POST", "/api/memory/retract", body);
525360
+ if ("wholeSession" in input && isRecord$5(value) && value["retracted"] === 0 && value["rederive"] === false && value["reason"] === "already_retracted" && generation(value["sessionEpoch"]) && input.expectedEpoch !== null && value["sessionEpoch"] >= input.expectedEpoch) return {
525361
+ retracted: 0,
525362
+ rederive: false,
525363
+ reason: "already_retracted",
525364
+ sessionEpoch: value["sessionEpoch"]
525365
+ };
525366
+ if (!isRecord$5(value) || !generation(value["retracted"]) || value["rederive"] !== "queued" || "wholeSession" in input && !generation(value["sessionEpoch"]) || value["sessionEpoch"] !== void 0 && !generation(value["sessionEpoch"])) invalid();
525367
+ return {
525368
+ retracted: value["retracted"],
525369
+ rederive: "queued",
525370
+ ...value["sessionEpoch"] === void 0 ? {} : { sessionEpoch: value["sessionEpoch"] }
525371
+ };
525372
+ }
525373
+ async recall(query, limit = 8, sources) {
525374
+ const body = queryBody(query, limit, sources);
525375
+ const value = await this.client.request("POST", "/api/memory/recall", body);
525376
+ if (!isRecord$5(value) || !isRecord$5(value["profile"]) || !Array.isArray(value["items"]) || !generation(value["forgetGeneration"])) invalid();
525377
+ const profile = value["profile"];
525378
+ if (!Array.isArray(profile["card"]) || profile["card"].length > 20 || !profile["card"].every((item) => typeof item === "string" && item.length <= 1e3) || typeof profile["representation"] !== "string" || profile["representation"].length > 4e3) invalid();
525379
+ return {
525380
+ profile: {
525381
+ card: profile["card"],
525382
+ representation: profile["representation"]
525383
+ },
525384
+ items: parseItems(value["items"]),
525385
+ forgetGeneration: value["forgetGeneration"]
525386
+ };
525387
+ }
525388
+ async search(query, options = {}) {
525389
+ const body = queryBody(query, options.limit ?? 20, options.sources);
525390
+ if (options.after !== void 0 && !isoTime$1(options.after) || options.before !== void 0 && !isoTime$1(options.before)) invalid();
525391
+ const value = await this.client.request("POST", "/api/memory/search", {
525392
+ ...body,
525393
+ ...options.after === void 0 ? {} : { after: options.after },
525394
+ ...options.before === void 0 ? {} : { before: options.before }
525395
+ });
525396
+ if (!isRecord$5(value) || !Array.isArray(value["items"]) || !generation(value["forgetGeneration"])) invalid();
525397
+ return {
525398
+ items: parseItems(value["items"]),
525399
+ forgetGeneration: value["forgetGeneration"]
525400
+ };
525401
+ }
525402
+ };
525403
+ function queryBody(query, limit, sources) {
525404
+ if (!query.trim() || query.length > 1e3 || !Number.isInteger(limit) || limit < 1 || limit > 20 || sources !== void 0 && (!Array.isArray(sources) || sources.some((source) => !/^(?:chat|tui|plugin:[a-z0-9_-]+)$/iu.test(source)))) invalid();
525405
+ return {
525406
+ query,
525407
+ limit,
525408
+ ...sources === void 0 ? {} : { sources }
525409
+ };
525410
+ }
525411
+ function parseItems(value) {
525412
+ if (value.length > 20) invalid();
525413
+ return value.map((item) => {
525414
+ if (!isRecord$5(item) || typeof item["id"] !== "string" || item["id"].length > 200 || typeof item["text"] !== "string" || item["text"].length > 2e3 || typeof item["source"] !== "string" || !/^(?:chat|tui|plugin:[a-z0-9_-]+)$/iu.test(item["source"]) || typeof item["sessionId"] !== "string" || item["sessionId"].length > 200 || !isoTime$1(item["at"]) || typeof item["score"] !== "number" || !Number.isFinite(item["score"]) || item["role"] !== void 0 && item["role"] !== "user" && item["role"] !== "assistant") invalid();
525415
+ return item;
525416
+ });
525417
+ }
525418
+ function generation(value) {
525419
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
525420
+ }
525421
+ function messageId$1(value) {
525422
+ return typeof value === "string" && value.length > 0 && value.length <= 200 && /^[a-z0-9][a-z0-9._:-]*$/iu.test(value);
525423
+ }
525424
+ function isoTime$1(value) {
525425
+ return typeof value === "string" && Number.isFinite(Date.parse(value)) && /(?:Z|[+-]\d\d:\d\d)$/u.test(value);
525426
+ }
525427
+ function isRecord$5(value) {
525428
+ return typeof value === "object" && value !== null && !Array.isArray(value);
525429
+ }
525430
+ function invalid() {
525431
+ throw new PersonalMemoryBrokerError("INVALID_PAYLOAD");
525432
+ }
525433
+ //#endregion
525434
+ //#region src/personal-memory/honcho-capture-source.ts
525435
+ const SECRET_PATTERN = /\b(?:password|passwort|api[-_ ]?key|secret|bearer|credential|cvv|cvc|iban)\b|sk-[a-z0-9_-]{20,}|ghp_[a-z0-9]{20,}|\b(?:\d[ -]?){13,19}\b/iu;
525436
+ const GROUP_MARKER = /^\[tg\s+(?:group|supergroup)\b/im;
525437
+ const MAX_WIRE_RECORD_CHARS = 4 * 1024 * 1024;
525438
+ async function readCompletedHonchoTurn(homeDir, session, turnId) {
525439
+ const sessionsRoot = await realpath(path.join(homeDir, "sessions"));
525440
+ const sessionDir = await realpath(session.sessionDir);
525441
+ if (path.basename(sessionDir) !== session.id || !isInside(sessionsRoot, sessionDir)) throw new Error("Honcho session path is outside this profile.");
525442
+ const canonicalWire = await realpath(path.join(sessionDir, "agents", "main", "wire.jsonl"));
525443
+ if (!isInside(sessionDir, canonicalWire)) throw new Error("Honcho Wire path escapes the session.");
525444
+ const wireStat = await stat(canonicalWire);
525445
+ if (!wireStat.isFile() || wireStat.size === 0) return void 0;
525446
+ const scanner = createTurnScanner(turnId);
525447
+ for await (const line of boundedLines(canonicalWire, wireStat.size)) scanner.accept(JSON.parse(line));
525448
+ return scanner.finish();
525449
+ }
525450
+ function createTurnScanner(completedTurnId) {
525451
+ let latestUserText;
525452
+ let latestUserTime;
525453
+ let userText;
525454
+ let occurredAt;
525455
+ let assistantText = "";
525456
+ let finalStepEnded = false;
525457
+ const targetTurnId = String(completedTurnId);
525458
+ const accept = (raw) => {
525459
+ if (!isRecord$4(raw)) return;
525460
+ if (raw["type"] === "turn.prompt") {
525461
+ const origin = raw["origin"];
525462
+ const input = raw["input"];
525463
+ const text = isRecord$4(origin) && origin["kind"] === "user" && Array.isArray(input) && input.every((part) => isRecord$4(part) && part["type"] === "text") ? textParts(input) : void 0;
525464
+ latestUserText = text && !GROUP_MARKER.test(text) && !SECRET_PATTERN.test(text) ? text : void 0;
525465
+ latestUserTime = latestUserText === void 0 ? void 0 : isoTime(raw["time"]);
525466
+ return;
525467
+ }
525468
+ if (raw["type"] !== "context.append_loop_event" || !isRecord$4(raw["event"])) return;
525469
+ const event = raw["event"];
525470
+ if (event["type"] === "step.begin" && event["turnId"] === targetTurnId) {
525471
+ userText ??= latestUserText;
525472
+ occurredAt ??= latestUserTime;
525473
+ assistantText = "";
525474
+ finalStepEnded = false;
525475
+ return;
525476
+ }
525477
+ if (event["type"] === "content.part" && event["turnId"] === targetTurnId && userText !== void 0 && isRecord$4(event["part"]) && event["part"]["type"] === "text" && typeof event["part"]["text"] === "string") {
525478
+ assistantText += event["part"]["text"];
525479
+ return;
525480
+ }
525481
+ if (event["type"] === "step.end" && event["turnId"] === targetTurnId) finalStepEnded = event["finishReason"] === "end_turn";
525482
+ };
525483
+ return {
525484
+ accept,
525485
+ finish: () => {
525486
+ const answer = assistantText.trim();
525487
+ return finalStepEnded && userText !== void 0 && occurredAt !== void 0 && answer.length > 0 && !SECRET_PATTERN.test(answer) ? {
525488
+ userText,
525489
+ assistantText: answer,
525490
+ occurredAt
525491
+ } : void 0;
525492
+ }
525493
+ };
525494
+ }
525495
+ function isoTime(value) {
525496
+ if (typeof value !== "string") return void 0;
525497
+ const timestamp = Date.parse(value);
525498
+ return Number.isFinite(timestamp) && new Date(timestamp).toISOString() === value ? value : void 0;
525499
+ }
525500
+ function textParts(parts) {
525501
+ return parts.filter((part) => isRecord$4(part) && part["type"] === "text" && typeof part["text"] === "string").map((part) => part.text).join("\n").trim() || void 0;
525502
+ }
525503
+ function isRecord$4(value) {
525504
+ return typeof value === "object" && value !== null && !Array.isArray(value);
525505
+ }
525506
+ function isInside(root, candidate) {
525507
+ const relative = path.relative(root, candidate);
525508
+ return relative !== "" && relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
525509
+ }
525510
+ async function* boundedLines(wirePath, size) {
525511
+ const stream = createReadStream(wirePath, {
525512
+ encoding: "utf8",
525513
+ end: size - 1
525514
+ });
525515
+ let pending = "";
525516
+ try {
525517
+ for await (const chunk of stream) {
525518
+ let offset = 0;
525519
+ while (offset < chunk.length) {
525520
+ const newline = chunk.indexOf("\n", offset);
525521
+ const end = newline < 0 ? chunk.length : newline;
525522
+ pending += chunk.slice(offset, end);
525523
+ if (pending.length > MAX_WIRE_RECORD_CHARS) throw new Error("Honcho Wire record is too large.");
525524
+ if (newline < 0) break;
525525
+ if (pending.length > 0) yield pending.replace(/\r$/u, "");
525526
+ pending = "";
525527
+ offset = newline + 1;
525528
+ }
525529
+ }
525530
+ } finally {
525531
+ stream.destroy();
525532
+ }
525533
+ }
525534
+ //#endregion
525535
+ //#region src/personal-memory/account-memory-capture.ts
525536
+ const MAX_PENDING = 2e3;
525537
+ const MAX_COMPLETED = 1e4;
525538
+ const MAX_RETRACTIONS = 2e3;
525539
+ const UUID_V4 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
525540
+ var AccountMemoryCaptureQueue = class {
525541
+ homeDir;
525542
+ broker;
525543
+ readTurn;
525544
+ workspaceCache;
525545
+ work = Promise.resolve();
525546
+ constructor(homeDir, broker, readTurn = readCompletedHonchoTurn, workspaceCache) {
525547
+ this.homeDir = homeDir;
525548
+ this.broker = broker;
525549
+ this.readTurn = readTurn;
525550
+ this.workspaceCache = workspaceCache;
525551
+ }
525552
+ captureCompletedTurn(session, turnId) {
525553
+ return this.serial(async () => {
525554
+ if (!Number.isSafeInteger(turnId) || turnId < 0) return "unavailable";
525555
+ let state;
525556
+ try {
525557
+ state = await this.readSessionState(session.id);
525558
+ if (turnId <= state.blockedThroughTurnId) return "skipped";
525559
+ if (turnId > state.highestObservedTurnId) {
525560
+ state = {
525561
+ ...state,
525562
+ highestObservedTurnId: turnId
525563
+ };
525564
+ await this.writeSessionState(state);
525565
+ }
525566
+ } catch {
525567
+ return "unavailable";
525568
+ }
525569
+ let workspace;
525570
+ let turn;
525571
+ try {
525572
+ workspace = await this.broker.workspace(session.id);
525573
+ turn = await this.readTurn(this.homeDir, session, turnId);
525574
+ } catch {
525575
+ return "unavailable";
525576
+ }
525577
+ if (state.workspaceId !== null && state.workspaceId !== workspace.workspaceId) return "unavailable";
525578
+ if (state.workspaceId === null || state.sessionEpoch !== workspace.sessionEpoch) try {
525579
+ await this.writeSessionState({
525580
+ ...state,
525581
+ workspaceId: workspace.workspaceId,
525582
+ sessionEpoch: workspace.sessionEpoch
525583
+ });
525584
+ } catch {
525585
+ return "unavailable";
525586
+ }
525587
+ if (this.workspaceCache !== void 0) try {
525588
+ if (!await this.workspaceCache.set(workspace.workspaceId)) return "unavailable";
525589
+ } catch {
525590
+ return "unavailable";
525591
+ }
525592
+ if (turn === void 0 || beforeCutoff(turn.occurredAt, workspace.forgetCutoff)) return "skipped";
525593
+ const journalPath = this.journalPath(workspace.workspaceId);
525594
+ let journal;
525595
+ try {
525596
+ journal = await this.readJournal(journalPath, workspace.workspaceId);
525597
+ } catch {
525598
+ return "unavailable";
525599
+ }
525600
+ if (journal.suppressedTurns.includes(turnKey(session.id, turnId))) return "skipped";
525601
+ if (journal.known.some((entry) => entry.sessionId === session.id && entry.turnId === turnId)) return "skipped";
525602
+ const revision = journal.revisions[turnKey(session.id, turnId)] ?? 0;
525603
+ const messageIds = turnMessageIds(session.id, turnId, turn, revision);
525604
+ const key = captureKey(session.id, turnId, turn.occurredAt, messageIds);
525605
+ if (journal.completed.includes(key)) return "skipped";
525606
+ const old = journal.pending.find((entry) => entry.sessionId === session.id && entry.turnId === turnId);
525607
+ if (old !== void 0 && (old.occurredAt !== turn.occurredAt || old.messageIds.some((id, index) => id !== messageIds[index]))) return "skipped";
525608
+ if (old === void 0) {
525609
+ if (journal.pending.length >= MAX_PENDING) return "unavailable";
525610
+ journal = {
525611
+ ...journal,
525612
+ pending: [...journal.pending, {
525613
+ captureId: randomUUID(),
525614
+ sessionId: session.id,
525615
+ sessionDir: session.sessionDir,
525616
+ turnId,
525617
+ occurredAt: turn.occurredAt,
525618
+ messageIds,
525619
+ sessionEpoch: workspace.sessionEpoch,
525620
+ awaitingSessionRetract: journal.retractions.some((entry) => entry.sessionId === session.id && "wholeSession" in entry)
525621
+ }]
525622
+ };
525623
+ try {
525624
+ await this.writeJournal(journalPath, journal);
525625
+ } catch {
525626
+ return "unavailable";
525627
+ }
525628
+ }
525629
+ if (!await this.flushRetractions(journalPath, journal)) return "queued";
525630
+ journal = await this.readJournal(journalPath, workspace.workspaceId);
525631
+ return this.flushJournal(journalPath, journal, workspace, {
525632
+ sessionId: session.id,
525633
+ turnId,
525634
+ turn
525635
+ });
525636
+ });
525637
+ }
525638
+ retryPending() {
525639
+ return this.serial(async () => {
525640
+ try {
525641
+ const workspace = await this.broker.workspace();
525642
+ const journalPath = this.journalPath(workspace.workspaceId);
525643
+ let journal = await this.readJournal(journalPath, workspace.workspaceId);
525644
+ if (!await this.flushRetractions(journalPath, journal)) return "queued";
525645
+ journal = await this.readJournal(journalPath, workspace.workspaceId);
525646
+ return await this.flushJournal(journalPath, journal, workspace);
525647
+ } catch {
525648
+ return "unavailable";
525649
+ }
525650
+ });
525651
+ }
525652
+ retryRetractions() {
525653
+ return this.serial(async () => {
525654
+ try {
525655
+ const workspace = await this.broker.workspace();
525656
+ const journalPath = this.journalPath(workspace.workspaceId);
525657
+ const journal = await this.readJournal(journalPath, workspace.workspaceId);
525658
+ if (journal.retractions.length === 0) return "skipped";
525659
+ return await this.flushRetractions(journalPath, journal) ? "retracted" : "queued";
525660
+ } catch {
525661
+ return "unavailable";
525662
+ }
525663
+ });
525664
+ }
525665
+ flushRetractionsBeforeLogout() {
525666
+ return this.serial(async () => {
525667
+ try {
525668
+ const cachedWorkspaceId = await this.workspaceCache?.get();
525669
+ if (cachedWorkspaceId === void 0) return false;
525670
+ const journalPath = this.journalPath(cachedWorkspaceId);
525671
+ const journal = await this.readJournal(journalPath, cachedWorkspaceId);
525672
+ if (journal.retractions.length === 0) return false;
525673
+ if ((await this.broker.workspace()).workspaceId !== cachedWorkspaceId) return true;
525674
+ return !await this.flushRetractions(journalPath, journal);
525675
+ } catch {
525676
+ return true;
525677
+ }
525678
+ });
525679
+ }
525680
+ retractTurn(sessionId, turnId) {
525681
+ return this.serial(async () => {
525682
+ try {
525683
+ const workspace = await this.broker.workspace();
525684
+ const journalPath = this.journalPath(workspace.workspaceId);
525685
+ const journal = await this.readJournal(journalPath, workspace.workspaceId);
525686
+ const matching = [...journal.pending, ...journal.known].filter((entry) => entry.sessionId === sessionId && entry.turnId === turnId);
525687
+ const messageIds = [...new Set(matching.flatMap((entry) => entry.messageIds))];
525688
+ if (messageIds.length === 0) return "skipped";
525689
+ if (journal.retractions.length >= MAX_RETRACTIONS) return "unavailable";
525690
+ const next = {
525691
+ ...journal,
525692
+ pending: journal.pending.filter((entry) => entry.sessionId !== sessionId || entry.turnId !== turnId),
525693
+ known: journal.known.filter((entry) => entry.sessionId !== sessionId || entry.turnId !== turnId),
525694
+ retractions: [...journal.retractions, {
525695
+ retractId: randomUUID(),
525696
+ sessionId,
525697
+ messageIds
525698
+ }],
525699
+ revisions: {
525700
+ ...journal.revisions,
525701
+ [turnKey(sessionId, turnId)]: (journal.revisions[turnKey(sessionId, turnId)] ?? 0) + 1
525702
+ }
525703
+ };
525704
+ await this.writeJournal(journalPath, next);
525705
+ return await this.flushRetractions(journalPath, next) ? "retracted" : "queued";
525706
+ } catch {
525707
+ return "unavailable";
525708
+ }
525709
+ });
525710
+ }
525711
+ retractSession(sessionId, throughTurnId) {
525712
+ return this.serial(async () => {
525713
+ if (throughTurnId !== void 0 && (!Number.isSafeInteger(throughTurnId) || throughTurnId < 0)) return "unavailable";
525714
+ let state;
525715
+ try {
525716
+ state = await this.readSessionState(sessionId);
525717
+ } catch {
525718
+ return "unavailable";
525719
+ }
525720
+ let workspace;
525721
+ try {
525722
+ workspace = await this.broker.workspace(sessionId);
525723
+ } catch {
525724
+ if (state.workspaceId !== null) {
525725
+ let cachedWorkspaceId;
525726
+ try {
525727
+ cachedWorkspaceId = await this.workspaceCache?.get();
525728
+ } catch {
525729
+ return "unavailable";
525730
+ }
525731
+ if (cachedWorkspaceId !== state.workspaceId) {
525732
+ try {
525733
+ await this.writeSessionState({
525734
+ ...state,
525735
+ highestObservedTurnId: Math.max(state.highestObservedTurnId, throughTurnId ?? -1),
525736
+ blockedThroughTurnId: Math.max(state.blockedThroughTurnId, state.highestObservedTurnId, throughTurnId ?? -1)
525737
+ });
525738
+ } catch {
525739
+ return "unavailable";
525740
+ }
525741
+ return "unavailable";
525742
+ }
525743
+ return this.queueSessionRetraction(sessionId, state, cachedWorkspaceId, state.sessionEpoch, throughTurnId, false);
525744
+ }
525745
+ try {
525746
+ await this.writeSessionState({
525747
+ ...state,
525748
+ highestObservedTurnId: Math.max(state.highestObservedTurnId, throughTurnId ?? -1),
525749
+ blockedThroughTurnId: Math.max(state.blockedThroughTurnId, state.highestObservedTurnId, throughTurnId ?? -1)
525750
+ });
525751
+ return "retracted";
525752
+ } catch {
525753
+ return "unavailable";
525754
+ }
525755
+ }
525756
+ if (workspace.sessionEpoch === null) return "unavailable";
525757
+ if (state.workspaceId !== null && state.workspaceId !== workspace.workspaceId) return "unavailable";
525758
+ if (this.workspaceCache !== void 0) try {
525759
+ if (!await this.workspaceCache.set(workspace.workspaceId)) return "unavailable";
525760
+ } catch {
525761
+ return "unavailable";
525762
+ }
525763
+ return this.queueSessionRetraction(sessionId, state, workspace.workspaceId, workspace.sessionEpoch, throughTurnId, true);
525764
+ });
525765
+ }
525766
+ async queueSessionRetraction(sessionId, state, workspaceId, expectedEpoch, throughTurnId, sendNow) {
525767
+ try {
525768
+ const journalPath = this.journalPath(workspaceId);
525769
+ const journal = await this.readJournal(journalPath, workspaceId);
525770
+ if (journal.retractions.length >= MAX_RETRACTIONS) return "unavailable";
525771
+ const next = {
525772
+ ...journal,
525773
+ pending: journal.pending.filter((entry) => entry.sessionId !== sessionId),
525774
+ known: journal.known.filter((entry) => entry.sessionId !== sessionId),
525775
+ retractions: [...journal.retractions, {
525776
+ retractId: randomUUID(),
525777
+ sessionId,
525778
+ wholeSession: true,
525779
+ expectedEpoch
525780
+ }],
525781
+ suppressedTurns: [...new Set([...journal.suppressedTurns, ...[...journal.pending, ...journal.known].filter((entry) => entry.sessionId === sessionId).map((entry) => turnKey(entry.sessionId, entry.turnId))])].slice(-MAX_COMPLETED)
525782
+ };
525783
+ await this.writeJournal(journalPath, next);
525784
+ await this.writeSessionState({
525785
+ ...state,
525786
+ highestObservedTurnId: Math.max(state.highestObservedTurnId, throughTurnId ?? -1),
525787
+ blockedThroughTurnId: Math.max(state.blockedThroughTurnId, state.highestObservedTurnId, throughTurnId ?? -1),
525788
+ workspaceId,
525789
+ sessionEpoch: expectedEpoch
525790
+ });
525791
+ return sendNow && await this.flushRetractions(journalPath, next) ? "retracted" : "queued";
525792
+ } catch {
525793
+ return "unavailable";
525794
+ }
525795
+ }
525796
+ async flushRetractions(journalPath, journal) {
525797
+ if (this.broker.retract === void 0) return journal.retractions.length === 0;
525798
+ let current = journal;
525799
+ for (const entry of journal.retractions) {
525800
+ let response;
525801
+ try {
525802
+ response = await this.broker.retract(entry);
525803
+ } catch {
525804
+ return false;
525805
+ }
525806
+ if ("wholeSession" in entry && response.sessionEpoch !== void 0) try {
525807
+ const state = await this.readSessionState(entry.sessionId);
525808
+ await this.writeSessionState({
525809
+ ...state,
525810
+ sessionEpoch: response.sessionEpoch
525811
+ });
525812
+ } catch {
525813
+ return false;
525814
+ }
525815
+ current = {
525816
+ ...current,
525817
+ retractions: current.retractions.filter((item) => item !== entry),
525818
+ pending: "wholeSession" in entry && response.sessionEpoch !== void 0 ? response.rederive === false ? current.pending.filter((item) => item.sessionId !== entry.sessionId || !item.awaitingSessionRetract) : current.pending.map((item) => item.sessionId === entry.sessionId && item.awaitingSessionRetract ? {
525819
+ ...item,
525820
+ sessionEpoch: response.sessionEpoch,
525821
+ awaitingSessionRetract: false
525822
+ } : item) : current.pending
525823
+ };
525824
+ await this.writeJournal(journalPath, current);
525825
+ }
525826
+ return true;
525827
+ }
525828
+ discardPending() {
525829
+ return this.serial(async () => {
525830
+ const directory = path.join(this.homeDir, "memory");
525831
+ let names;
525832
+ try {
525833
+ names = await readdir(directory);
525834
+ } catch (error) {
525835
+ if (isMissing(error)) return;
525836
+ throw error;
525837
+ }
525838
+ for (const name of names) {
525839
+ if (!/^honcho-pending-[0-9a-f]{64}\.json$/u.test(name)) continue;
525840
+ const journalPath = path.join(directory, name);
525841
+ if (!(await lstat(journalPath)).isFile()) continue;
525842
+ const value = JSON.parse(await readFile(journalPath, "utf8"));
525843
+ if (!isRecord$3(value) || typeof value["workspaceId"] !== "string") continue;
525844
+ const journal = await this.readJournal(journalPath, value["workspaceId"]);
525845
+ if (journal.pending.length > 0) await this.writeJournal(journalPath, {
525846
+ ...journal,
525847
+ pending: []
525848
+ });
525849
+ }
525850
+ });
525851
+ }
525852
+ async flushJournal(journalPath, journal, workspace, fresh) {
525853
+ if (journal.pending.length === 0) return "skipped";
525854
+ let pending = [...journal.pending];
525855
+ let completed = [...journal.completed];
525856
+ let known = [...journal.known];
525857
+ let result = "skipped";
525858
+ for (const entry of journal.pending) {
525859
+ if (entry.awaitingSessionRetract) return "queued";
525860
+ const session = {
525861
+ id: entry.sessionId,
525862
+ sessionDir: entry.sessionDir
525863
+ };
525864
+ let turn;
525865
+ try {
525866
+ turn = fresh?.sessionId === entry.sessionId && fresh.turnId === entry.turnId ? fresh.turn : await this.readTurn(this.homeDir, session, entry.turnId);
525867
+ } catch {
525868
+ return "queued";
525869
+ }
525870
+ if (turn === void 0 || turn.occurredAt !== entry.occurredAt || beforeCutoff(entry.occurredAt, workspace.forgetCutoff)) {
525871
+ pending = pending.filter((item) => item.captureId !== entry.captureId);
525872
+ await this.writeJournal(journalPath, {
525873
+ ...journal,
525874
+ pending,
525875
+ completed,
525876
+ known
525877
+ });
525878
+ continue;
525879
+ }
525880
+ const revision = journal.revisions[turnKey(entry.sessionId, entry.turnId)] ?? 0;
525881
+ if (turnMessageIds(entry.sessionId, entry.turnId, turn, revision).some((id, index) => id !== entry.messageIds[index])) {
525882
+ pending = pending.filter((item) => item.captureId !== entry.captureId);
525883
+ await this.writeJournal(journalPath, {
525884
+ ...journal,
525885
+ pending,
525886
+ completed,
525887
+ known
525888
+ });
525889
+ continue;
525890
+ }
525891
+ try {
525892
+ const response = await this.broker.capture({
525893
+ captureId: entry.captureId,
525894
+ sessionId: entry.sessionId,
525895
+ forgetGeneration: workspace.forgetGeneration,
525896
+ sessionEpoch: entry.sessionEpoch,
525897
+ messages: [{
525898
+ id: entry.messageIds[0],
525899
+ role: "user",
525900
+ content: turn.userText,
525901
+ at: turn.occurredAt
525902
+ }, {
525903
+ id: entry.messageIds[1],
525904
+ role: "assistant",
525905
+ content: turn.assistantText,
525906
+ at: turn.occurredAt
525907
+ }]
525908
+ });
525909
+ const key = captureKey(entry.sessionId, entry.turnId, entry.occurredAt, entry.messageIds);
525910
+ if ("reason" in response && response.reason === "memory_disabled") {
525911
+ completed = [...completed, key].slice(-MAX_COMPLETED);
525912
+ await this.writeJournal(journalPath, {
525913
+ ...journal,
525914
+ pending: [],
525915
+ completed
525916
+ });
525917
+ return "skipped";
525918
+ }
525919
+ if ("reason" in response && response.reason === "session_retracted") {
525920
+ pending = pending.filter((item) => item.sessionId !== entry.sessionId || item.sessionEpoch !== entry.sessionEpoch);
525921
+ await this.writeJournal(journalPath, {
525922
+ ...journal,
525923
+ pending,
525924
+ completed,
525925
+ known
525926
+ });
525927
+ return "skipped";
525928
+ }
525929
+ pending = pending.filter((item) => item.captureId !== entry.captureId);
525930
+ completed = [...completed, key].slice(-MAX_COMPLETED);
525931
+ known = [...known, {
525932
+ key,
525933
+ sessionId: entry.sessionId,
525934
+ turnId: entry.turnId,
525935
+ occurredAt: entry.occurredAt,
525936
+ messageIds: entry.messageIds
525937
+ }].slice(-MAX_COMPLETED);
525938
+ await this.writeJournal(journalPath, {
525939
+ ...journal,
525940
+ pending,
525941
+ completed,
525942
+ known
525943
+ });
525944
+ result = "captured";
525945
+ } catch (error) {
525946
+ if (error instanceof PersonalMemoryBrokerError && error.status === 403) {
525947
+ const suppressedTurns = [...new Set([...journal.suppressedTurns, ...pending.map((item) => turnKey(item.sessionId, item.turnId))])].slice(-MAX_COMPLETED);
525948
+ try {
525949
+ await this.writeJournal(journalPath, {
525950
+ ...journal,
525951
+ pending: [],
525952
+ completed,
525953
+ known,
525954
+ suppressedTurns
525955
+ });
525956
+ } catch {
525957
+ return "unavailable";
525958
+ }
525959
+ return "skipped";
525960
+ }
525961
+ if (error instanceof PersonalMemoryBrokerError && (error.code === "INVALID_PAYLOAD" || error.code === "PAYLOAD_TOO_LARGE" || error.code === "SECRET_REJECTED")) {
525962
+ pending = pending.filter((item) => item.captureId !== entry.captureId);
525963
+ await this.writeJournal(journalPath, {
525964
+ ...journal,
525965
+ pending,
525966
+ completed,
525967
+ known
525968
+ });
525969
+ continue;
525970
+ }
525971
+ if (error instanceof PersonalMemoryBrokerError && error.code === "FORGET_GENERATION_CHANGED") return "queued";
525972
+ return "queued";
525973
+ }
525974
+ }
525975
+ return result;
525976
+ }
525977
+ journalPath(workspaceId) {
525978
+ const name = createHash("sha256").update(workspaceId).digest("hex");
525979
+ return path.join(this.homeDir, "memory", `honcho-pending-${name}.json`);
525980
+ }
525981
+ sessionStatePath(sessionId) {
525982
+ const name = createHash("sha256").update(sessionId).digest("hex");
525983
+ return path.join(this.homeDir, "memory", `honcho-session-${name}.json`);
525984
+ }
525985
+ async readSessionState(sessionId) {
525986
+ let value;
525987
+ try {
525988
+ value = JSON.parse(await readFile(this.sessionStatePath(sessionId), "utf8"));
525989
+ } catch (error) {
525990
+ if (isMissing(error)) return {
525991
+ version: 1,
525992
+ sessionId,
525993
+ highestObservedTurnId: -1,
525994
+ blockedThroughTurnId: -1,
525995
+ workspaceId: null,
525996
+ sessionEpoch: null
525997
+ };
525998
+ throw error;
525999
+ }
526000
+ if (!isRecord$3(value) || value["version"] !== 1 || value["sessionId"] !== sessionId || !Number.isSafeInteger(value["highestObservedTurnId"]) || value["highestObservedTurnId"] < -1 || !Number.isSafeInteger(value["blockedThroughTurnId"]) || value["blockedThroughTurnId"] < -1 || value["blockedThroughTurnId"] > value["highestObservedTurnId"] || value["workspaceId"] !== null && (typeof value["workspaceId"] !== "string" || value["workspaceId"].length === 0) || value["sessionEpoch"] !== null && (!Number.isSafeInteger(value["sessionEpoch"]) || value["sessionEpoch"] < 0)) throw new Error("Invalid account memory session state.");
526001
+ return value;
526002
+ }
526003
+ async writeSessionState(state) {
526004
+ const statePath = this.sessionStatePath(state.sessionId);
526005
+ const directory = path.dirname(statePath);
526006
+ await mkdir(directory, {
526007
+ recursive: true,
526008
+ mode: 448
526009
+ });
526010
+ const root = await realpath(this.homeDir);
526011
+ if (path.dirname(await realpath(directory)) !== root) throw new Error("Account memory session state escapes the BLUN profile.");
526012
+ const temporary = `${statePath}.${randomUUID()}.tmp`;
526013
+ try {
526014
+ await writeFile(temporary, JSON.stringify(state), {
526015
+ encoding: "utf8",
526016
+ mode: 384,
526017
+ flag: "wx"
526018
+ });
526019
+ await rename(temporary, statePath);
526020
+ } finally {
526021
+ await unlink(temporary).catch(() => {});
526022
+ }
526023
+ }
526024
+ async readJournal(journalPath, workspaceId) {
526025
+ let text;
526026
+ try {
526027
+ text = await readFile(journalPath, "utf8");
526028
+ } catch (error) {
526029
+ if (isMissing(error)) return {
526030
+ version: 2,
526031
+ workspaceId,
526032
+ pending: [],
526033
+ completed: [],
526034
+ known: [],
526035
+ retractions: [],
526036
+ suppressedTurns: [],
526037
+ revisions: {}
526038
+ };
526039
+ throw error;
526040
+ }
526041
+ const value = JSON.parse(text);
526042
+ if (!isRecord$3(value) || value["version"] !== 2 || value["workspaceId"] !== workspaceId || !Array.isArray(value["pending"]) || value["pending"].length > MAX_PENDING || !value["pending"].every(validPending) || !Array.isArray(value["completed"]) || value["completed"].length > MAX_COMPLETED || !value["completed"].every((item) => typeof item === "string" && /^[0-9a-f]{64}$/u.test(item)) || !Array.isArray(value["known"]) || value["known"].length > MAX_COMPLETED || !value["known"].every(validKnown) || !Array.isArray(value["retractions"]) || value["retractions"].length > MAX_RETRACTIONS || !value["retractions"].every(validRetraction) || !Array.isArray(value["suppressedTurns"]) || value["suppressedTurns"].length > MAX_COMPLETED || !value["suppressedTurns"].every((item) => typeof item === "string" && /^[0-9a-f]{64}$/u.test(item)) || !isRecord$3(value["revisions"]) || Object.keys(value["revisions"]).length > MAX_COMPLETED || !Object.entries(value["revisions"]).every(([key, revision]) => /^[0-9a-f]{64}$/u.test(key) && Number.isSafeInteger(revision) && revision >= 0)) throw new Error("Invalid account memory journal.");
526043
+ return value;
526044
+ }
526045
+ async writeJournal(journalPath, journal) {
526046
+ const directory = path.dirname(journalPath);
526047
+ await mkdir(directory, {
526048
+ recursive: true,
526049
+ mode: 448
526050
+ });
526051
+ const root = await realpath(this.homeDir);
526052
+ if (path.dirname(await realpath(directory)) !== root) throw new Error("Account memory journal escapes the BLUN profile.");
526053
+ const temporary = `${journalPath}.${randomUUID()}.tmp`;
526054
+ try {
526055
+ await writeFile(temporary, JSON.stringify(journal), {
526056
+ encoding: "utf8",
526057
+ mode: 384,
526058
+ flag: "wx"
526059
+ });
526060
+ await rename(temporary, journalPath);
526061
+ } finally {
526062
+ await unlink(temporary).catch(() => {});
526063
+ }
526064
+ }
526065
+ serial(run) {
526066
+ const task = this.work.then(run, run);
526067
+ this.work = task.then(() => void 0, () => void 0);
526068
+ return task;
526069
+ }
526070
+ };
526071
+ function beforeCutoff(occurredAt, cutoff) {
526072
+ return cutoff !== null && Date.parse(occurredAt) <= Date.parse(cutoff);
526073
+ }
526074
+ function captureKey(sessionId, turnId, occurredAt, messageIds) {
526075
+ return createHash("sha256").update(`${sessionId}\0${turnId}\0${occurredAt}\0${messageIds.join("\0")}`).digest("hex");
526076
+ }
526077
+ function turnKey(sessionId, turnId) {
526078
+ return createHash("sha256").update(`${sessionId}\0${turnId}`).digest("hex");
526079
+ }
526080
+ function turnMessageIds(sessionId, turnId, turn, revision) {
526081
+ return [stableMessageId(sessionId, turnId, revision, "user", turn.userText), stableMessageId(sessionId, turnId, revision, "assistant", turn.assistantText)];
526082
+ }
526083
+ function stableMessageId(sessionId, turnId, revision, role, content) {
526084
+ return `tui-${createHash("sha256").update(`${sessionId}\0${turnId}\0${revision}\0${role}\0${content}`).digest("hex")}`;
526085
+ }
526086
+ function validPending(value) {
526087
+ return isRecord$3(value) && typeof value["captureId"] === "string" && UUID_V4.test(value["captureId"]) && typeof value["sessionId"] === "string" && typeof value["sessionDir"] === "string" && Number.isSafeInteger(value["turnId"]) && value["turnId"] >= 0 && typeof value["occurredAt"] === "string" && Number.isFinite(Date.parse(value["occurredAt"])) && validMessageIds(value["messageIds"]) && typeof value["awaitingSessionRetract"] === "boolean" && (value["sessionEpoch"] === null || Number.isSafeInteger(value["sessionEpoch"]) && value["sessionEpoch"] >= 0);
526088
+ }
526089
+ function validKnown(value) {
526090
+ return isRecord$3(value) && typeof value["key"] === "string" && /^[0-9a-f]{64}$/u.test(value["key"]) && typeof value["sessionId"] === "string" && Number.isSafeInteger(value["turnId"]) && typeof value["occurredAt"] === "string" && Number.isFinite(Date.parse(value["occurredAt"])) && validMessageIds(value["messageIds"]);
526091
+ }
526092
+ function validRetraction(value) {
526093
+ return isRecord$3(value) && typeof value["retractId"] === "string" && UUID_V4.test(value["retractId"]) && typeof value["sessionId"] === "string" && value["sessionId"].length > 0 && (value["wholeSession"] === true && (value["expectedEpoch"] === null || Number.isSafeInteger(value["expectedEpoch"]) && value["expectedEpoch"] >= 0) || Array.isArray(value["messageIds"]) && value["messageIds"].length > 0 && value["messageIds"].length <= 200 && value["messageIds"].every(validMessageId));
526094
+ }
526095
+ function validMessageIds(value) {
526096
+ return Array.isArray(value) && value.length === 2 && value.every(validMessageId);
526097
+ }
526098
+ function validMessageId(value) {
526099
+ return typeof value === "string" && /^tui-[0-9a-f]{64}$/u.test(value);
526100
+ }
526101
+ function isRecord$3(value) {
526102
+ return typeof value === "object" && value !== null && !Array.isArray(value);
526103
+ }
526104
+ function isMissing(error) {
526105
+ return isRecord$3(error) && error["code"] === "ENOENT";
526106
+ }
526107
+ //#endregion
526108
+ //#region src/personal-memory/account-memory-runtime.ts
526109
+ var TuiAccountMemoryRuntime = class {
526110
+ client;
526111
+ broker;
526112
+ queue;
526113
+ getManagedQuota;
526114
+ constructor(client, broker, queue, getManagedQuota) {
526115
+ this.client = client;
526116
+ this.broker = broker;
526117
+ this.queue = queue;
526118
+ this.getManagedQuota = getManagedQuota;
526119
+ }
526120
+ async captureCompletedTurn(session, turnId) {
526121
+ const permission = await this.permission("write");
526122
+ if (permission === "unavailable") return "unavailable";
526123
+ if (permission === "denied") {
526124
+ await this.queue.discardPending().catch(() => {});
526125
+ return "skipped";
526126
+ }
526127
+ return this.queue.captureCompletedTurn(session, turnId).catch(() => "unavailable");
526128
+ }
526129
+ async retryPending() {
526130
+ const permission = await this.permission("write");
526131
+ if (permission === "denied") await this.queue.discardPending().catch(() => {});
526132
+ const retractions = await this.queue.retryRetractions().catch(() => "unavailable");
526133
+ if (retractions === "queued") return "queued";
526134
+ if (permission === "denied") return "skipped";
526135
+ if (permission === "unavailable" || retractions === "unavailable") return "unavailable";
526136
+ return this.queue.retryPending().catch(() => "unavailable");
526137
+ }
526138
+ retractTurn(sessionId, turnId) {
526139
+ return this.queue.retractTurn(sessionId, turnId).catch(() => "unavailable");
526140
+ }
526141
+ retractSession(sessionId, throughTurnId) {
526142
+ return (throughTurnId === void 0 ? this.queue.retractSession(sessionId) : this.queue.retractSession(sessionId, throughTurnId)).catch(() => "unavailable");
526143
+ }
526144
+ flushRetractionsBeforeLogout() {
526145
+ return this.queue.flushRetractionsBeforeLogout().catch(() => true);
526146
+ }
526147
+ async recall(query) {
526148
+ if (await this.permission("read") !== "allowed") return void 0;
526149
+ return this.broker.recall(query, 8).catch(() => void 0);
526150
+ }
526151
+ async search(query, limit = 20) {
526152
+ if (await this.permission("read") !== "allowed") return void 0;
526153
+ return this.broker.search(query, { limit }).catch(() => void 0);
526154
+ }
526155
+ async permission(operation) {
526156
+ let settings;
526157
+ try {
526158
+ const quota = await this.getManagedQuota();
526159
+ if (quota.kind !== "ok") return "unavailable";
526160
+ if (quota.paid !== true) return "denied";
526161
+ settings = await this.client.getSettings();
526162
+ } catch {
526163
+ return "unavailable";
526164
+ }
526165
+ if (settings.consentStatus !== "enabled" || !settings.memoryEnabled || !settings.useChatHistory) return "denied";
526166
+ return operation === "write" ? settings.allowNewMemories ? "allowed" : "denied" : settings.useSavedMemories ? "allowed" : "denied";
526167
+ }
526168
+ };
526169
+ function createTuiAccountMemoryRuntime(harness, env = process.env) {
526170
+ if (env["BLUN_ACCOUNT_MEMORY_BROKER_ENABLED"] !== "1") return void 0;
526171
+ try {
526172
+ const client = createPersonalMemoryBrokerClient(harness);
526173
+ const broker = new AccountMemoryBroker(client);
526174
+ return new TuiAccountMemoryRuntime(client, broker, new AccountMemoryCaptureQueue(harness.homeDir, broker, void 0, {
526175
+ get: () => harness.auth.getCachedMemoryWorkspaceId(),
526176
+ set: (workspaceId) => harness.auth.cacheMemoryWorkspaceId(workspaceId)
526177
+ }), () => harness.auth.getManagedQuota(DEFAULT_OAUTH_PROVIDER_NAME));
526178
+ } catch {
526179
+ return;
526180
+ }
526181
+ }
526182
+ //#endregion
524742
526183
  //#region src/utils/persistence.ts
524743
526184
  /**
524744
526185
  * Small persistence helpers for CLI-owned data files.
@@ -532647,6 +534088,29 @@ var PersonalMemoryController = class {
532647
534088
  this.queue = run.then(() => {}, () => {});
532648
534089
  return run;
532649
534090
  }
534091
+ refreshLocalToolSearch() {
534092
+ const generation = this.generation;
534093
+ const session = this.host.session;
534094
+ const refresh = async () => {
534095
+ if (!this.isCurrent(generation, session)) return "stale";
534096
+ if (session === void 0) return "unavailable";
534097
+ try {
534098
+ await this.dependencies.bindTools(session, this.host.harness, {
534099
+ binding: personalMemoryHostBinding(),
534100
+ localHistory: this.host.harness,
534101
+ searchOnly: true,
534102
+ accountMemory: this.host.accountMemoryRuntime
534103
+ });
534104
+ return this.isCurrent(generation, session) ? "ready" : "stale";
534105
+ } catch {
534106
+ await this.dependencies.clearTools(session).catch(() => {});
534107
+ return "unavailable";
534108
+ }
534109
+ };
534110
+ const run = this.queue.then(refresh, refresh);
534111
+ this.queue = run.then(() => {}, () => {});
534112
+ return run;
534113
+ }
532650
534114
  clear(session = this.host.session) {
532651
534115
  ++this.generation;
532652
534116
  const run = this.queue.then(async () => {
@@ -532717,7 +534181,8 @@ var PersonalMemoryController = class {
532717
534181
  await this.dependencies.bindTools(session, this.host.harness, {
532718
534182
  binding,
532719
534183
  client,
532720
- localHistory: this.host.harness
534184
+ localHistory: this.host.harness,
534185
+ accountMemory: this.host.accountMemoryRuntime
532721
534186
  });
532722
534187
  return "ready";
532723
534188
  } catch {
@@ -535540,7 +537005,10 @@ var SessionEventHandler = class {
535540
537005
  this.showPendingCompactionRetry();
535541
537006
  this.goalCompletionTurnEnded = true;
535542
537007
  this.scheduleQueuedGoalPromotion();
535543
- if (event.reason === "completed") this.host.refreshManagedQuotaWindows();
537008
+ if (event.reason === "completed") {
537009
+ this.host.refreshManagedQuotaWindows();
537010
+ this.host.recordAccountMemoryTurn?.(event);
537011
+ }
535544
537012
  }
535545
537013
  handleStepBegin(event) {
535546
537014
  this.host.commitQueuedSteerAtStepStart(event.turnId);
@@ -542805,6 +544273,7 @@ var BlunTUI = class {
542805
544273
  editorKeyboard;
542806
544274
  scrollbackController;
542807
544275
  personalMemoryController;
544276
+ accountMemoryRuntime;
542808
544277
  customerMistakeController;
542809
544278
  managedQuotaWarningController;
542810
544279
  managedQuotaWarningPersistence = Promise.resolve();
@@ -542889,6 +544358,7 @@ var BlunTUI = class {
542889
544358
  this.loopCountdown = new LoopCountdownController(() => this.state.ui.requestRender());
542890
544359
  this.authFlow = new AuthFlowController(this);
542891
544360
  this.personalMemoryController = new PersonalMemoryController(this);
544361
+ this.accountMemoryRuntime = createTuiAccountMemoryRuntime(harness);
542892
544362
  this.customerMistakeController = new CustomerMistakeHostController();
542893
544363
  this.btwPanelController = new BtwPanelController(this);
542894
544364
  this.sessionEventHandler = new SessionEventHandler(this);
@@ -544582,9 +546052,21 @@ var BlunTUI = class {
544582
546052
  refreshManagedQuotaWindows() {
544583
546053
  this.authFlow.refreshManagedQuotaWindows();
544584
546054
  }
546055
+ recordAccountMemoryTurn(event) {
546056
+ const session = this.session;
546057
+ const sessionDir = session?.summary?.sessionDir;
546058
+ if (session === void 0 || sessionDir === void 0) return;
546059
+ this.accountMemoryRuntime?.captureCompletedTurn({
546060
+ id: session.id,
546061
+ sessionDir
546062
+ }, event.turnId).catch(() => {});
546063
+ }
544585
546064
  async refreshPersonalMemory(promptIfNeverAsked = false) {
544586
546065
  await this.personalMemoryController.refresh({ promptIfNeverAsked });
544587
546066
  }
546067
+ async refreshLocalToolSearch() {
546068
+ await this.personalMemoryController.refreshLocalToolSearch();
546069
+ }
544588
546070
  setLocalToolEventRecordingEnabled(enabled) {
544589
546071
  this.sessionEventHandler.setLocalToolEventRecordingEnabled(enabled);
544590
546072
  }
@@ -544720,6 +546202,7 @@ var BlunTUI = class {
544720
546202
  await this.refreshManagedImageReaderAvailability(session);
544721
546203
  await this.authFlow.applyManagedAccountContextToSession();
544722
546204
  await this.personalMemoryController.refresh();
546205
+ this.accountMemoryRuntime?.retryPending().catch(() => {});
544723
546206
  this.telegramSessionScope = queueScope;
544724
546207
  this.telegramChannel?.bindSessionQueue(queueScope);
544725
546208
  if (selectionScope !== void 0 && this.session === session) {
@@ -545003,6 +546486,7 @@ var BlunTUI = class {
545003
546486
  this.registerSessionHandlers(session);
545004
546487
  await this.refreshManagedImageReaderAvailability(session);
545005
546488
  await this.personalMemoryController.refresh();
546489
+ this.accountMemoryRuntime?.retryPending().catch(() => {});
545006
546490
  await this.syncRuntimeState(session);
545007
546491
  this.updateTerminalTitle();
545008
546492
  try {
@@ -546066,7 +547550,7 @@ var BlunTUI = class {
546066
547550
  //#endregion
546067
547551
  //#region src/constant/update.ts
546068
547552
  var import_runtime_exit_ledger = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
546069
- const fs = __require("node:fs");
547553
+ const fs$1 = __require("node:fs");
546070
547554
  const os$1 = __require("node:os");
546071
547555
  const path$2 = __require("node:path");
546072
547556
  const DEFAULT_MAX_BYTES = 1024 * 1024;
@@ -546120,7 +547604,7 @@ var import_runtime_exit_ledger = (/* @__PURE__ */ __commonJSMin(((exports, modul
546120
547604
  return record;
546121
547605
  }
546122
547606
  function directoryIdentity(directory) {
546123
- const stat = fs.lstatSync(directory, { bigint: true });
547607
+ const stat = fs$1.lstatSync(directory, { bigint: true });
546124
547608
  if (!stat.isDirectory() || stat.isSymbolicLink()) throw new Error("Unsafe exit directory");
546125
547609
  return stat;
546126
547610
  }
@@ -546132,16 +547616,16 @@ var import_runtime_exit_ledger = (/* @__PURE__ */ __commonJSMin(((exports, modul
546132
547616
  return stat;
546133
547617
  }
546134
547618
  function trimLedger(descriptor, maxBytes, retainBytes, incomingBytes) {
546135
- const size = Number(regularLedger(fs.fstatSync(descriptor, { bigint: true })).size);
547619
+ const size = Number(regularLedger(fs$1.fstatSync(descriptor, { bigint: true })).size);
546136
547620
  if (!Number.isSafeInteger(size)) throw new Error("Invalid exit ledger size");
546137
547621
  if (size + incomingBytes <= maxBytes) return;
546138
547622
  const keepBytes = Math.max(0, Math.min(size, retainBytes, maxBytes - incomingBytes));
546139
547623
  const contents = Buffer.alloc(keepBytes);
546140
- const read = fs.readSync(descriptor, contents, 0, keepBytes, size - keepBytes);
547624
+ const read = fs$1.readSync(descriptor, contents, 0, keepBytes, size - keepBytes);
546141
547625
  const tail = contents.subarray(0, read);
546142
547626
  const lineStart = size > keepBytes ? tail.indexOf(10) + 1 : 0;
546143
- fs.ftruncateSync(descriptor, 0);
546144
- fs.writeFileSync(descriptor, lineStart > 0 || size === keepBytes ? tail.subarray(lineStart) : "");
547627
+ fs$1.ftruncateSync(descriptor, 0);
547628
+ fs$1.writeFileSync(descriptor, lineStart > 0 || size === keepBytes ? tail.subarray(lineStart) : "");
546145
547629
  }
546146
547630
  function recordRuntimeExit(input = {}) {
546147
547631
  let descriptor;
@@ -546149,7 +547633,7 @@ var import_runtime_exit_ledger = (/* @__PURE__ */ __commonJSMin(((exports, modul
546149
547633
  try {
546150
547634
  const homeDir = typeof input.homeDir === "string" ? input.homeDir.trim() : "";
546151
547635
  if (!homeDir || !path$2.isAbsolute(homeDir)) return false;
546152
- fs.mkdirSync(homeDir, {
547636
+ fs$1.mkdirSync(homeDir, {
546153
547637
  recursive: true,
546154
547638
  mode: 448
546155
547639
  });
@@ -546157,21 +547641,21 @@ var import_runtime_exit_ledger = (/* @__PURE__ */ __commonJSMin(((exports, modul
546157
547641
  const file = runtimeExitLedgerPath(homeDir);
546158
547642
  const directory = path$2.dirname(file);
546159
547643
  try {
546160
- fs.mkdirSync(directory, { mode: 448 });
547644
+ fs$1.mkdirSync(directory, { mode: 448 });
546161
547645
  } catch (error) {
546162
547646
  if (error.code !== "EEXIST") throw error;
546163
547647
  }
546164
547648
  const directoryStat = directoryIdentity(directory);
546165
547649
  let before;
546166
547650
  try {
546167
- before = regularLedger(fs.lstatSync(file, { bigint: true }));
547651
+ before = regularLedger(fs$1.lstatSync(file, { bigint: true }));
546168
547652
  } catch (error) {
546169
547653
  if (error.code !== "ENOENT") throw error;
546170
547654
  }
546171
- const flags = fs.constants.O_RDWR | (fs.constants.O_NOFOLLOW ?? 0) | (fs.constants.O_NONBLOCK ?? 0) | (before ? 0 : fs.constants.O_CREAT | fs.constants.O_EXCL);
546172
- descriptor = fs.openSync(file, flags, 384);
546173
- const opened = regularLedger(fs.fstatSync(descriptor, { bigint: true }));
546174
- if (before && !sameIdentity(before, opened) || !sameIdentity(opened, regularLedger(fs.lstatSync(file, { bigint: true }))) || !sameIdentity(homeIdentity, directoryIdentity(homeDir)) || !sameIdentity(directoryStat, directoryIdentity(directory))) throw new Error("Exit ledger changed");
547655
+ const flags = fs$1.constants.O_RDWR | (fs$1.constants.O_NOFOLLOW ?? 0) | (fs$1.constants.O_NONBLOCK ?? 0) | (before ? 0 : fs$1.constants.O_CREAT | fs$1.constants.O_EXCL);
547656
+ descriptor = fs$1.openSync(file, flags, 384);
547657
+ const opened = regularLedger(fs$1.fstatSync(descriptor, { bigint: true }));
547658
+ if (before && !sameIdentity(before, opened) || !sameIdentity(opened, regularLedger(fs$1.lstatSync(file, { bigint: true }))) || !sameIdentity(homeIdentity, directoryIdentity(homeDir)) || !sameIdentity(directoryStat, directoryIdentity(directory))) throw new Error("Exit ledger changed");
546175
547659
  const maxBytes = Math.max(1024, Number.isInteger(input.maxBytes) ? input.maxBytes : DEFAULT_MAX_BYTES);
546176
547660
  const retainBytes = Math.max(0, Number.isInteger(input.retainBytes) ? input.retainBytes : DEFAULT_RETAIN_BYTES);
546177
547661
  const record = buildRuntimeExitRecord(input);
@@ -546194,21 +547678,21 @@ var import_runtime_exit_ledger = (/* @__PURE__ */ __commonJSMin(((exports, modul
546194
547678
  line = `${JSON.stringify(record)}\n`;
546195
547679
  }
546196
547680
  trimLedger(descriptor, maxBytes, retainBytes, Buffer.byteLength(line));
546197
- appendDescriptor = fs.openSync(file, fs.constants.O_WRONLY | fs.constants.O_APPEND | (fs.constants.O_NOFOLLOW ?? 0) | (fs.constants.O_NONBLOCK ?? 0));
546198
- if (!sameIdentity(opened, regularLedger(fs.fstatSync(appendDescriptor, { bigint: true }))) || !sameIdentity(opened, regularLedger(fs.lstatSync(file, { bigint: true }))) || !sameIdentity(homeIdentity, directoryIdentity(homeDir)) || !sameIdentity(directoryStat, directoryIdentity(directory))) throw new Error("Exit ledger changed");
546199
- fs.appendFileSync(appendDescriptor, line, { encoding: "utf8" });
547681
+ appendDescriptor = fs$1.openSync(file, fs$1.constants.O_WRONLY | fs$1.constants.O_APPEND | (fs$1.constants.O_NOFOLLOW ?? 0) | (fs$1.constants.O_NONBLOCK ?? 0));
547682
+ if (!sameIdentity(opened, regularLedger(fs$1.fstatSync(appendDescriptor, { bigint: true }))) || !sameIdentity(opened, regularLedger(fs$1.lstatSync(file, { bigint: true }))) || !sameIdentity(homeIdentity, directoryIdentity(homeDir)) || !sameIdentity(directoryStat, directoryIdentity(directory))) throw new Error("Exit ledger changed");
547683
+ fs$1.appendFileSync(appendDescriptor, line, { encoding: "utf8" });
546200
547684
  try {
546201
- fs.fchmodSync(descriptor, 384);
547685
+ fs$1.fchmodSync(descriptor, 384);
546202
547686
  } catch {}
546203
547687
  return true;
546204
547688
  } catch {
546205
547689
  return false;
546206
547690
  } finally {
546207
547691
  if (appendDescriptor !== void 0) try {
546208
- fs.closeSync(appendDescriptor);
547692
+ fs$1.closeSync(appendDescriptor);
546209
547693
  } catch {}
546210
547694
  if (descriptor !== void 0) try {
546211
- fs.closeSync(descriptor);
547695
+ fs$1.closeSync(descriptor);
546212
547696
  } catch {}
546213
547697
  }
546214
547698
  }
@@ -546346,6 +547830,7 @@ async function runShell(opts, version, updateStartupNotice) {
546346
547830
  }
546347
547831
  });
546348
547832
  log.info("blun starting", {
547833
+ pid: process.pid,
546349
547834
  version,
546350
547835
  uiMode: CLI_UI_MODE,
546351
547836
  nodeVersion: process.version,
@@ -546472,11 +547957,16 @@ async function runShell(opts, version, updateStartupNotice) {
546472
547957
  const initMs = Date.now() - initStartedAt;
546473
547958
  const startupSessionId = tui.getCurrentSessionId();
546474
547959
  const mcpMs = await tui.getStartupMcpMs();
546475
- trackLifecycleForSession(startupSessionId, "startup_perf", {
547960
+ const startupPerformance = {
546476
547961
  duration_ms: Date.now() - startedAt,
546477
547962
  config_ms: configMs,
546478
547963
  init_ms: initMs,
546479
547964
  mcp_ms: mcpMs
547965
+ };
547966
+ trackLifecycleForSession(startupSessionId, "startup_perf", startupPerformance);
547967
+ log.info("startup performance", {
547968
+ pid: process.pid,
547969
+ ...startupPerformance
546480
547970
  });
546481
547971
  } catch (error) {
546482
547972
  removeCrashHandlers();