noumen 0.5.0 → 0.6.0

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.
Files changed (50) hide show
  1. package/dist/a2a/index.d.ts +4 -4
  2. package/dist/acp/index.d.ts +4 -4
  3. package/dist/{agent-C3eDRsxs.d.ts → agent-DWE4_P5X.d.ts} +179 -6
  4. package/dist/{cache-DsRqxx6v.d.ts → cache-BlBwXXPS.d.ts} +1 -1
  5. package/dist/{chunk-WPCYGZOE.js → chunk-6MMYCGJQ.js} +325 -16
  6. package/dist/chunk-6MMYCGJQ.js.map +1 -0
  7. package/dist/{chunk-WTLK2ZAR.js → chunk-7IQCQI2G.js} +1 -1
  8. package/dist/{chunk-L3L3FG5T.js → chunk-CCM2AXZG.js} +1 -1
  9. package/dist/{chunk-L3L3FG5T.js.map → chunk-CCM2AXZG.js.map} +1 -1
  10. package/dist/{chunk-CS6WNDCF.js → chunk-I3JTUFPK.js} +2 -2
  11. package/dist/chunk-I3JTUFPK.js.map +1 -0
  12. package/dist/{chunk-EKOGVTBT.js → chunk-ZXSDKBYB.js} +4 -2
  13. package/dist/chunk-ZXSDKBYB.js.map +1 -0
  14. package/dist/cli/index.js +6 -6
  15. package/dist/client/index.d.ts +1 -1
  16. package/dist/index.d.ts +16 -9
  17. package/dist/index.js +17 -3
  18. package/dist/lsp/index.d.ts +3 -3
  19. package/dist/mcp/index.d.ts +4 -4
  20. package/dist/{provider-factory-KI7OZUY3.js → provider-factory-TUHU3DIG.js} +2 -2
  21. package/dist/providers/anthropic.d.ts +3 -3
  22. package/dist/providers/anthropic.js +4 -3
  23. package/dist/providers/anthropic.js.map +1 -1
  24. package/dist/providers/bedrock.d.ts +3 -3
  25. package/dist/providers/bedrock.js +2 -2
  26. package/dist/providers/bedrock.js.map +1 -1
  27. package/dist/providers/gemini.d.ts +2 -2
  28. package/dist/providers/gemini.js +1 -1
  29. package/dist/providers/gemini.js.map +1 -1
  30. package/dist/providers/ollama.d.ts +1 -1
  31. package/dist/providers/ollama.js +2 -2
  32. package/dist/providers/openai.d.ts +2 -2
  33. package/dist/providers/openai.js +2 -2
  34. package/dist/providers/openrouter.d.ts +1 -1
  35. package/dist/providers/openrouter.js +2 -2
  36. package/dist/providers/vertex.d.ts +3 -3
  37. package/dist/providers/vertex.js +4 -3
  38. package/dist/providers/vertex.js.map +1 -1
  39. package/dist/{resolve-GDSHNMG6.js → resolve-6KUZNEYW.js} +2 -2
  40. package/dist/server/index.d.ts +4 -4
  41. package/dist/{server-Cu9gv1dk.d.ts → server-BzNGKTP6.d.ts} +1 -1
  42. package/dist/{types-BA87bHPV.d.ts → types-DhXwOQwD.d.ts} +1 -1
  43. package/dist/{types-LrU4LRmX.d.ts → types-kiGBF35b.d.ts} +40 -2
  44. package/package.json +1 -1
  45. package/dist/chunk-CS6WNDCF.js.map +0 -1
  46. package/dist/chunk-EKOGVTBT.js.map +0 -1
  47. package/dist/chunk-WPCYGZOE.js.map +0 -1
  48. /package/dist/{chunk-WTLK2ZAR.js.map → chunk-7IQCQI2G.js.map} +0 -0
  49. /package/dist/{provider-factory-KI7OZUY3.js.map → provider-factory-TUHU3DIG.js.map} +0 -0
  50. /package/dist/{resolve-GDSHNMG6.js.map → resolve-6KUZNEYW.js.map} +0 -0
@@ -15,7 +15,7 @@ import {
15
15
  } from "./chunk-HEQQQGK5.js";
16
16
  import {
17
17
  ChatStreamError
18
- } from "./chunk-L3L3FG5T.js";
18
+ } from "./chunk-CCM2AXZG.js";
19
19
  import {
20
20
  generateUUID
21
21
  } from "./chunk-3HEYCV26.js";
@@ -316,6 +316,127 @@ function LocalSandbox(opts) {
316
316
  };
317
317
  }
318
318
 
319
+ // src/session/auto-title.ts
320
+ var DEFAULT_AUTO_TITLE_MAX_INPUT_CHARS = 2e3;
321
+ var DEFAULT_AUTO_TITLE_SYSTEM_PROMPT = `Generate a concise, sentence-case title (3-7 words) that captures the main topic or goal of this coding session. The title should be clear enough that the user recognizes the session in a list. Use sentence case: capitalize only the first word and proper nouns.
322
+
323
+ Return JSON with a single "title" field.
324
+
325
+ Good examples:
326
+ {"title": "Fix login button on mobile"}
327
+ {"title": "Add OAuth authentication"}
328
+ {"title": "Debug failing CI tests"}
329
+ {"title": "Refactor API client error handling"}
330
+
331
+ Bad (too vague): {"title": "Code changes"}
332
+ Bad (too long): {"title": "Investigate and fix the issue where the login button does not respond on mobile devices"}
333
+ Bad (wrong case): {"title": "Fix Login Button On Mobile"}`;
334
+ function extractTitleSeedText(messages, maxChars = DEFAULT_AUTO_TITLE_MAX_INPUT_CHARS) {
335
+ const parts = [];
336
+ for (const msg of messages) {
337
+ if (msg.role !== "user" && msg.role !== "assistant") continue;
338
+ const content = msg.content;
339
+ if (content === null || content === void 0) continue;
340
+ if (typeof content === "string") {
341
+ if (content.trim()) parts.push(content);
342
+ continue;
343
+ }
344
+ if (Array.isArray(content)) {
345
+ for (const block of content) {
346
+ if (block.type === "text" && typeof block.text === "string") {
347
+ if (block.text.trim()) parts.push(block.text);
348
+ }
349
+ }
350
+ }
351
+ }
352
+ const text = parts.join("\n").trim();
353
+ if (text.length <= maxChars) return text;
354
+ return text.slice(-maxChars);
355
+ }
356
+ function extractTitleFromResponse(raw) {
357
+ if (!raw) return null;
358
+ const trimmed = raw.trim();
359
+ const parseTitle = (s) => {
360
+ let obj;
361
+ try {
362
+ obj = JSON.parse(s);
363
+ } catch {
364
+ return { kind: "none" };
365
+ }
366
+ if (obj && typeof obj === "object" && "title" in obj) {
367
+ const v = obj.title;
368
+ if (typeof v === "string") {
369
+ const t = v.trim();
370
+ if (t) return { kind: "ok", title: t };
371
+ }
372
+ }
373
+ return { kind: "empty" };
374
+ };
375
+ const whole = parseTitle(trimmed);
376
+ if (whole.kind === "ok") return whole.title;
377
+ if (whole.kind === "empty") return null;
378
+ const start = trimmed.indexOf("{");
379
+ const end = trimmed.lastIndexOf("}");
380
+ if (start >= 0 && end > start) {
381
+ const sliced = parseTitle(trimmed.slice(start, end + 1));
382
+ if (sliced.kind === "ok") return sliced.title;
383
+ if (sliced.kind === "empty") return null;
384
+ }
385
+ const quoteMatch = trimmed.match(/"([^"\\]{2,120})"/);
386
+ if (quoteMatch?.[1]) return quoteMatch[1].trim();
387
+ return null;
388
+ }
389
+ async function generateAutoTitle(messages, opts) {
390
+ const seed = extractTitleSeedText(messages, opts.maxInputChars);
391
+ if (!seed) return null;
392
+ const model = opts.model ?? opts.provider.defaultModel;
393
+ if (!model) return null;
394
+ const system = opts.systemPrompt ?? DEFAULT_AUTO_TITLE_SYSTEM_PROMPT;
395
+ const params = {
396
+ model,
397
+ system,
398
+ messages: [{ role: "user", content: seed }],
399
+ max_tokens: 60,
400
+ outputFormat: {
401
+ type: "json_schema",
402
+ schema: {
403
+ type: "object",
404
+ properties: { title: { type: "string" } },
405
+ required: ["title"],
406
+ additionalProperties: false
407
+ },
408
+ name: "session_title",
409
+ strict: true
410
+ },
411
+ signal: opts.signal
412
+ };
413
+ let text = "";
414
+ try {
415
+ for await (const chunk of opts.provider.chat(params)) {
416
+ for (const choice of chunk.choices) {
417
+ const delta = choice.delta.content;
418
+ if (typeof delta === "string") text += delta;
419
+ }
420
+ }
421
+ } catch {
422
+ return null;
423
+ }
424
+ if (!text) return null;
425
+ const extracted = extractTitleFromResponse(text) ?? text.trim();
426
+ return normalizeTitle(extracted);
427
+ }
428
+ function normalizeTitle(raw) {
429
+ if (!raw) return null;
430
+ let t = raw.replace(/\s+/g, " ").trim();
431
+ if (t.length >= 2 && (t.startsWith('"') && t.endsWith('"') || t.startsWith("'") && t.endsWith("'"))) {
432
+ t = t.slice(1, -1).trim();
433
+ }
434
+ t = t.replace(/\.+$/, "").trim();
435
+ if (!t) return null;
436
+ if (t.length > 120) t = t.slice(0, 120).trim();
437
+ return t;
438
+ }
439
+
319
440
  // src/checkpoint/manager.ts
320
441
  import { createHash } from "crypto";
321
442
 
@@ -1805,31 +1926,83 @@ var SessionStorage = class {
1805
1926
  await this.appendEntry(sessionId, entry);
1806
1927
  }
1807
1928
  /**
1808
- * Re-append custom-title and key metadata entries after a compact boundary
1809
- * so they remain discoverable in the active-entries window.
1929
+ * Append a user-set session title. Wins over any `ai-title` when read.
1930
+ * Idempotent-ish: callers may append as many as they like; the last one
1931
+ * wins according to file order.
1932
+ */
1933
+ async appendCustomTitle(sessionId, title) {
1934
+ const entry = {
1935
+ type: "custom-title",
1936
+ sessionId,
1937
+ title,
1938
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1939
+ };
1940
+ await this.appendEntry(sessionId, entry);
1941
+ }
1942
+ /**
1943
+ * Append an AI-generated session title. A `custom-title` (if present)
1944
+ * always takes precedence on read.
1945
+ */
1946
+ async appendAiTitle(sessionId, title) {
1947
+ const entry = {
1948
+ type: "ai-title",
1949
+ sessionId,
1950
+ title,
1951
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1952
+ };
1953
+ await this.appendEntry(sessionId, entry);
1954
+ }
1955
+ /**
1956
+ * Re-append custom-title, ai-title, and key metadata entries after a
1957
+ * compact boundary so they remain discoverable in the active-entries
1958
+ * window. Written as a single batched append so a crash mid-write can't
1959
+ * leave the transcript with only a subset of the re-emitted entries.
1810
1960
  */
1811
1961
  async reAppendMetadataAfterCompact(sessionId) {
1812
1962
  const entries = await this.loadAllEntries(sessionId);
1813
1963
  let customTitle;
1964
+ let aiTitle;
1814
1965
  const metadataByKey = /* @__PURE__ */ new Map();
1815
1966
  for (const entry of entries) {
1816
1967
  if (entry.type === "custom-title") {
1817
1968
  customTitle = entry.title;
1818
1969
  }
1970
+ if (entry.type === "ai-title") {
1971
+ aiTitle = entry.title;
1972
+ }
1819
1973
  if (entry.type === "metadata") {
1820
1974
  metadataByKey.set(entry.key, entry.value);
1821
1975
  }
1822
1976
  }
1977
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
1978
+ const batch = [];
1823
1979
  if (customTitle) {
1824
- await this.appendEntry(sessionId, {
1980
+ batch.push({
1825
1981
  type: "custom-title",
1826
1982
  sessionId,
1827
1983
  title: customTitle,
1828
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
1984
+ timestamp
1985
+ });
1986
+ }
1987
+ if (aiTitle) {
1988
+ batch.push({
1989
+ type: "ai-title",
1990
+ sessionId,
1991
+ title: aiTitle,
1992
+ timestamp
1829
1993
  });
1830
1994
  }
1831
1995
  for (const [key, value] of metadataByKey) {
1832
- await this.appendMetadata(sessionId, key, value);
1996
+ batch.push({
1997
+ type: "metadata",
1998
+ sessionId,
1999
+ timestamp,
2000
+ key,
2001
+ value
2002
+ });
2003
+ }
2004
+ if (batch.length > 0) {
2005
+ await this.appendEntriesBatch(sessionId, batch);
1833
2006
  }
1834
2007
  }
1835
2008
  async loadMessages(sessionId) {
@@ -1880,6 +2053,21 @@ var SessionStorage = class {
1880
2053
  async sessionExists(sessionId) {
1881
2054
  return this.fs.exists(this.getTranscriptPath(sessionId));
1882
2055
  }
2056
+ /**
2057
+ * Return the currently persisted titles for a session. `title` reflects
2058
+ * the display preference (custom > ai). Returns all-undefined if the
2059
+ * session file doesn't exist.
2060
+ */
2061
+ async getSessionTitles(sessionId) {
2062
+ const entries = await this.loadAllEntries(sessionId);
2063
+ let customTitle;
2064
+ let aiTitle;
2065
+ for (const entry of entries) {
2066
+ if (entry.type === "custom-title") customTitle = entry.title;
2067
+ if (entry.type === "ai-title") aiTitle = entry.title;
2068
+ }
2069
+ return { title: customTitle ?? aiTitle, customTitle, aiTitle };
2070
+ }
1883
2071
  async deleteSession(sessionId) {
1884
2072
  const filePath = this.getTranscriptPath(sessionId);
1885
2073
  const exists = await this.fs.exists(filePath);
@@ -1918,8 +2106,8 @@ var SessionStorage = class {
1918
2106
  tailSlice = content;
1919
2107
  }
1920
2108
  const headEntries = parseJSONL(headSlice);
1921
- const tailEntries = isSplit ? parseJSONL(tailSlice) : headEntries;
1922
- let title;
2109
+ let customTitle;
2110
+ let aiTitle;
1923
2111
  let firstTimestamp;
1924
2112
  let lastTimestamp;
1925
2113
  let messageCount = 0;
@@ -1929,22 +2117,27 @@ var SessionStorage = class {
1929
2117
  if (!firstTimestamp) firstTimestamp = e.timestamp;
1930
2118
  lastTimestamp = e.timestamp;
1931
2119
  }
1932
- if (e.type === "custom-title") title = e.title;
2120
+ if (e.type === "custom-title") customTitle = e.title;
2121
+ if (e.type === "ai-title") aiTitle = e.title;
1933
2122
  }
1934
2123
  if (isSplit) {
2124
+ const tailEntries = parseJSONL(tailSlice);
1935
2125
  for (const e of tailEntries) {
1936
2126
  if (e.type === "message" || e.type === "summary") {
1937
2127
  messageCount++;
1938
2128
  if (e.timestamp) lastTimestamp = e.timestamp;
1939
2129
  }
1940
- if (e.type === "custom-title") title = e.title;
2130
+ if (e.type === "custom-title") customTitle = e.title;
2131
+ if (e.type === "ai-title") aiTitle = e.title;
1941
2132
  }
1942
2133
  }
1943
2134
  sessions.push({
1944
2135
  sessionId,
1945
2136
  createdAt: firstTimestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
1946
2137
  lastMessageAt: lastTimestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
1947
- title,
2138
+ title: customTitle ?? aiTitle,
2139
+ customTitle,
2140
+ aiTitle,
1948
2141
  messageCount
1949
2142
  });
1950
2143
  } catch {
@@ -7052,7 +7245,13 @@ var Thread = class {
7052
7245
  this.config = config;
7053
7246
  this.sessionId = opts?.sessionId ?? generateUUID();
7054
7247
  this.cwd = opts?.cwd ?? "/";
7055
- this.model = opts?.model ?? config.model ?? "gpt-5.4";
7248
+ const resolvedModel = opts?.model ?? config.model ?? config.provider.defaultModel;
7249
+ if (!resolvedModel) {
7250
+ throw new Error(
7251
+ "Thread: no model resolved. Pass `model` to Thread / Agent / preset options, set `config.model`, or provide a provider with a `defaultModel` (built-in providers expose one automatically)."
7252
+ );
7253
+ }
7254
+ this.model = resolvedModel;
7056
7255
  this.storage = new SessionStorage(config.fs, config.sessionDir);
7057
7256
  if (config.permissions) {
7058
7257
  this.permissionContext = {
@@ -7977,6 +8176,14 @@ var Agent = class {
7977
8176
  historySnipConfig;
7978
8177
  outputFormat;
7979
8178
  structuredOutputMode;
8179
+ autoTitleConfig;
8180
+ /**
8181
+ * Keyed by `${sessionId}:${force ? "force" : "normal"}`. Parallel calls
8182
+ * that pass the same `force` mode coalesce to one in-flight request; a
8183
+ * `force: true` call arriving during a normal in-flight request runs its
8184
+ * own pass so the caller's intent isn't silently dropped.
8185
+ */
8186
+ autoTitleInFlight = /* @__PURE__ */ new Map();
7980
8187
  providerPromise = null;
7981
8188
  initPromise = null;
7982
8189
  constructor(opts) {
@@ -8047,6 +8254,12 @@ var Agent = class {
8047
8254
  this.historySnipConfig = opts.options?.historySnip;
8048
8255
  this.outputFormat = opts.options?.outputFormat;
8049
8256
  this.structuredOutputMode = opts.options?.structuredOutputMode;
8257
+ const autoTitleOpt = opts.options?.autoTitle;
8258
+ if (autoTitleOpt === true) {
8259
+ this.autoTitleConfig = { enabled: true };
8260
+ } else if (autoTitleOpt && typeof autoTitleOpt === "object") {
8261
+ this.autoTitleConfig = { enabled: true, ...autoTitleOpt };
8262
+ }
8050
8263
  if (opts.options?.checkpoint?.enabled) {
8051
8264
  this.checkpointManager = new FileCheckpointManager(
8052
8265
  this.fs,
@@ -8058,7 +8271,7 @@ var Agent = class {
8058
8271
  if (this.resolvedProvider) return this.resolvedProvider;
8059
8272
  if (!this.providerPromise) {
8060
8273
  this.providerPromise = (async () => {
8061
- const { resolveProvider: resolveProvider2 } = await import("./resolve-GDSHNMG6.js");
8274
+ const { resolveProvider: resolveProvider2 } = await import("./resolve-6KUZNEYW.js");
8062
8275
  return resolveProvider2(this.providerInput, { model: this.model });
8063
8276
  })();
8064
8277
  }
@@ -8216,6 +8429,92 @@ var Agent = class {
8216
8429
  async listSessions() {
8217
8430
  return this.storage.listSessions();
8218
8431
  }
8432
+ /**
8433
+ * Load the message history for a stored session, respecting compact
8434
+ * boundaries and history snips. Returns `[]` when the session does
8435
+ * not exist. Use this to rehydrate a UI — resuming a Thread for
8436
+ * further execution should go through `resumeThread()` instead.
8437
+ */
8438
+ async getMessages(sessionId) {
8439
+ return this.storage.loadMessages(sessionId);
8440
+ }
8441
+ /**
8442
+ * Persist a user-set title for a session. Takes precedence over any
8443
+ * AI-generated title on read. No-op on empty / whitespace-only input.
8444
+ */
8445
+ async setCustomTitle(sessionId, title) {
8446
+ const trimmed = title.trim();
8447
+ if (!trimmed) return;
8448
+ await this.storage.appendCustomTitle(sessionId, trimmed);
8449
+ }
8450
+ /**
8451
+ * Persist an AI-generated title for a session. A user-set title
8452
+ * (see `setCustomTitle`) always wins on read, so writing this after a
8453
+ * user has renamed the session is harmless.
8454
+ */
8455
+ async setAiTitle(sessionId, title) {
8456
+ const trimmed = title.trim();
8457
+ if (!trimmed) return;
8458
+ await this.storage.appendAiTitle(sessionId, trimmed);
8459
+ }
8460
+ /**
8461
+ * Delete a session's persisted transcript. Does not affect any
8462
+ * currently-running `Thread` reading from the same session id.
8463
+ */
8464
+ async deleteSession(sessionId) {
8465
+ await this.storage.deleteSession(sessionId);
8466
+ }
8467
+ /**
8468
+ * Return the currently persisted titles for a session.
8469
+ * `title` reflects the display preference (custom > ai).
8470
+ */
8471
+ async getSessionTitles(sessionId) {
8472
+ return this.storage.getSessionTitles(sessionId);
8473
+ }
8474
+ /**
8475
+ * When `autoTitle` is enabled and the session has no title yet,
8476
+ * generate one via the configured provider + model and persist it
8477
+ * as an `ai-title` entry. Returns the new title on success, or `null`
8478
+ * when skipped (feature disabled, title already present, empty seed,
8479
+ * or provider error).
8480
+ *
8481
+ * Concurrency-safe: parallel calls for the same session coalesce to
8482
+ * a single in-flight request.
8483
+ */
8484
+ async autoTitleIfMissing(sessionId, opts) {
8485
+ const cfg = this.autoTitleConfig;
8486
+ if (!cfg?.enabled) return null;
8487
+ const force = opts?.force === true;
8488
+ const key = `${sessionId}:${force ? "force" : "normal"}`;
8489
+ const existing = this.autoTitleInFlight.get(key);
8490
+ if (existing) return existing;
8491
+ const task = (async () => {
8492
+ try {
8493
+ if (!force) {
8494
+ const titles = await this.storage.getSessionTitles(sessionId);
8495
+ if (titles.customTitle || titles.aiTitle) return null;
8496
+ }
8497
+ await this.ensureProvider();
8498
+ const provider = cfg.provider ?? this.getProvider();
8499
+ const messages = await this.storage.loadMessages(sessionId);
8500
+ if (messages.length === 0) return null;
8501
+ const title = await generateAutoTitle(messages, {
8502
+ provider,
8503
+ model: cfg.model ?? provider.defaultModel ?? this.model,
8504
+ systemPrompt: cfg.systemPrompt ?? DEFAULT_AUTO_TITLE_SYSTEM_PROMPT,
8505
+ maxInputChars: cfg.maxInputChars ?? DEFAULT_AUTO_TITLE_MAX_INPUT_CHARS,
8506
+ signal: opts?.signal
8507
+ });
8508
+ if (!title) return null;
8509
+ await this.storage.appendAiTitle(sessionId, title);
8510
+ return title;
8511
+ } finally {
8512
+ this.autoTitleInFlight.delete(key);
8513
+ }
8514
+ })();
8515
+ this.autoTitleInFlight.set(key, task);
8516
+ return task;
8517
+ }
8219
8518
  getCostSummary() {
8220
8519
  return this.costTracker?.getSummary() ?? null;
8221
8520
  }
@@ -8461,7 +8760,8 @@ function codingAgent(opts) {
8461
8760
  costTracking: { enabled: true },
8462
8761
  retry: true,
8463
8762
  hooks: opts.hooks,
8464
- mcpServers: opts.mcpServers
8763
+ mcpServers: opts.mcpServers,
8764
+ autoTitle: opts.autoTitle
8465
8765
  }
8466
8766
  });
8467
8767
  }
@@ -8483,7 +8783,8 @@ function planningAgent(opts) {
8483
8783
  costTracking: { enabled: true },
8484
8784
  retry: true,
8485
8785
  hooks: opts.hooks,
8486
- mcpServers: opts.mcpServers
8786
+ mcpServers: opts.mcpServers,
8787
+ autoTitle: opts.autoTitle
8487
8788
  }
8488
8789
  });
8489
8790
  }
@@ -8506,6 +8807,7 @@ function reviewAgent(opts) {
8506
8807
  retry: true,
8507
8808
  hooks: opts.hooks,
8508
8809
  mcpServers: opts.mcpServers,
8810
+ autoTitle: opts.autoTitle,
8509
8811
  webSearch: {
8510
8812
  search: async (query) => {
8511
8813
  try {
@@ -9081,6 +9383,12 @@ export {
9081
9383
  SandboxedLocalComputer,
9082
9384
  UnsandboxedLocal,
9083
9385
  LocalSandbox,
9386
+ DEFAULT_AUTO_TITLE_MAX_INPUT_CHARS,
9387
+ DEFAULT_AUTO_TITLE_SYSTEM_PROMPT,
9388
+ extractTitleSeedText,
9389
+ extractTitleFromResponse,
9390
+ generateAutoTitle,
9391
+ normalizeTitle,
9084
9392
  createCheckpointState,
9085
9393
  FileCheckpointManager,
9086
9394
  runPreToolUseHooks,
@@ -9108,6 +9416,7 @@ export {
9108
9416
  findModelPricing,
9109
9417
  calculateCost,
9110
9418
  CostTracker,
9419
+ SessionStorage,
9111
9420
  TaskStore,
9112
9421
  buildProjectContextSection,
9113
9422
  parseFrontmatter,
@@ -9192,4 +9501,4 @@ export {
9192
9501
  truncateIndex,
9193
9502
  FileMemoryProvider
9194
9503
  };
9195
- //# sourceMappingURL=chunk-WPCYGZOE.js.map
9504
+ //# sourceMappingURL=chunk-6MMYCGJQ.js.map