@genesislcap/ai-assistant 15.8.2 → 15.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../node_modules/tslib/tslib.es6.mjs", "../../../foundation-ai/dist/esm/utils/combine-signals.js", "../../../../../node_modules/consola/dist/core.mjs", "../../../../../node_modules/consola/dist/browser.mjs", "../../../foundation-logger/dist/esm/logger.js", "../../../foundation-ai/dist/esm/utils/logger.js", "../../../foundation-ai/dist/esm/interactions/criteria-interpretation.js", "../../../foundation-ai/dist/esm/providers/anthropic-provider.js", "../../../foundation-ai/dist/esm/providers/default-provider.js", "../../../foundation-ai/dist/esm/providers/gemini-provider.js", "../../../foundation-ai/dist/esm/transports/budget-exhausted-error.js", "../../../foundation-ai/dist/esm/types/config.types.js", "../../../foundation-ai/dist/esm/utils/temperature.js", "../../../foundation-ai/dist/esm/utils/abort-reason.js", "../../../foundation-ai/dist/esm/utils/abortable-delay.js", "../../../foundation-ai/dist/esm/transports/ndjson-frames.js", "../../../foundation-ai/dist/esm/transports/post-with-retry.js", "../../../foundation-ai/dist/esm/transports/anthropic-transport.js", "../../../foundation-ai/dist/esm/transports/gemini-malformed-call.js", "../../../foundation-ai/dist/esm/transports/gemini-transport.js", "../../../foundation-ai/dist/esm/ai-provider.js", "../src/channel/ai-activity-bus.ts", "../src/config/validate-providers.ts", "../src/state/debug-event-log.ts", "../src/utils/logger.ts", "../src/state/interaction-context.ts", "../src/utils/condense-history.ts", "../src/utils/history-transform.ts", "../src/utils/sum-usage.ts", "../src/utils/tool-fold.ts", "../src/components/chat-driver/chat-driver.ts", "../src/components/orchestrating-driver/orchestrating-driver.ts", "../src/config/config.ts", "../src/config/define-stateful-agent.ts", "../src/config/fallback-agents.ts", "../src/utils/flatten-sub-agent-messages.ts", "../src/state/persistence/build-timeline-entries.ts", "../src/state/persistence/diagnostics.ts"],
4
- "sourcesContent": ["/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nvar ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n var r, s = 0;\n function next() {\n while (r = env.stack.pop()) {\n try {\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\n if (r.dispose) {\n var result = r.dispose.call(r.value);\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n else s |= 1;\n }\n catch (e) {\n fail(e);\n }\n }\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\n });\n }\n return path;\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __esDecorate,\n __runInitializers,\n __propKey,\n __setFunctionName,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n __rewriteRelativeImportExtension,\n};\n", "const noop = () => { };\n/**\n * Fan several `AbortSignal`s into one. The returned signal aborts as soon\n * as any input signal aborts, adopting that signal's `reason` \u2014 so callers can\n * distinguish, for example, a timeout (`TimeoutError`) from a user/lifecycle\n * cancellation (`AbortError`) by inspecting `signal.reason`. `undefined`\n * entries are ignored, letting callers pass optional signals directly.\n *\n * NOTE: the platform already provides exactly this \u2014 `AbortSignal.any([...])`\n * \u2014 but it is part of a newer spec than we target here. Our TypeScript config\n * is pinned to an older standard library (tsconfig `target: ES2015`,\n * `lib: [...ES2020]`), which predates `AbortSignal.any()`/`AbortSignal.timeout()`,\n * so those APIs are not in our typings (and have a narrower runtime-support\n * floor). This helper is the hand-rolled stand-in until the lib target is\n * raised, at which point this can be deleted in favour of `AbortSignal.any`.\n *\n * @example\n * const timeout = new AbortController();\n * const timer = setTimeout(\n * () => timeout.abort(new DOMException('Request timed out', 'TimeoutError')),\n * ms,\n * );\n * const { signal, dispose } = combineSignals([callerSignal, timeout.signal]);\n * try {\n * return await fetch(url, { signal });\n * } finally {\n * clearTimeout(timer);\n * dispose();\n * }\n */\nexport function combineSignals(signals) {\n const controller = new AbortController();\n const inputs = signals.filter((s) => s != null);\n // If any input is already aborted, adopt its reason immediately. Nothing to\n // wire up, so the disposer is a no-op.\n const preAborted = inputs.find((s) => s.aborted);\n if (preAborted) {\n controller.abort(preAborted.reason);\n return { signal: controller.signal, dispose: noop };\n }\n // `dispose` and `onAbort` reference each other; both are hoisted function\n // declarations so neither is read before it is initialised.\n function dispose() {\n for (const s of inputs) {\n s.removeEventListener('abort', onAbort);\n }\n }\n // `this` is the input signal the listener was attached to, so `this.reason`\n // is the reason of whichever signal aborted first.\n function onAbort() {\n controller.abort(this.reason);\n dispose();\n }\n for (const s of inputs) {\n s.addEventListener('abort', onAbort);\n }\n return { signal: controller.signal, dispose };\n}\n", "const LogLevels = {\n silent: Number.NEGATIVE_INFINITY,\n fatal: 0,\n error: 0,\n warn: 1,\n log: 2,\n info: 3,\n success: 3,\n fail: 3,\n ready: 3,\n start: 3,\n box: 3,\n debug: 4,\n trace: 5,\n verbose: Number.POSITIVE_INFINITY\n};\nconst LogTypes = {\n // Silent\n silent: {\n level: -1\n },\n // Level 0\n fatal: {\n level: LogLevels.fatal\n },\n error: {\n level: LogLevels.error\n },\n // Level 1\n warn: {\n level: LogLevels.warn\n },\n // Level 2\n log: {\n level: LogLevels.log\n },\n // Level 3\n info: {\n level: LogLevels.info\n },\n success: {\n level: LogLevels.success\n },\n fail: {\n level: LogLevels.fail\n },\n ready: {\n level: LogLevels.info\n },\n start: {\n level: LogLevels.info\n },\n box: {\n level: LogLevels.info\n },\n // Level 4\n debug: {\n level: LogLevels.debug\n },\n // Level 5\n trace: {\n level: LogLevels.trace\n },\n // Verbose\n verbose: {\n level: LogLevels.verbose\n }\n};\n\nfunction isPlainObject$1(value) {\n if (value === null || typeof value !== \"object\") {\n return false;\n }\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) {\n return false;\n }\n if (Symbol.iterator in value) {\n return false;\n }\n if (Symbol.toStringTag in value) {\n return Object.prototype.toString.call(value) === \"[object Module]\";\n }\n return true;\n}\n\nfunction _defu(baseObject, defaults, namespace = \".\", merger) {\n if (!isPlainObject$1(defaults)) {\n return _defu(baseObject, {}, namespace, merger);\n }\n const object = Object.assign({}, defaults);\n for (const key in baseObject) {\n if (key === \"__proto__\" || key === \"constructor\") {\n continue;\n }\n const value = baseObject[key];\n if (value === null || value === void 0) {\n continue;\n }\n if (merger && merger(object, key, value, namespace)) {\n continue;\n }\n if (Array.isArray(value) && Array.isArray(object[key])) {\n object[key] = [...value, ...object[key]];\n } else if (isPlainObject$1(value) && isPlainObject$1(object[key])) {\n object[key] = _defu(\n value,\n object[key],\n (namespace ? `${namespace}.` : \"\") + key.toString(),\n merger\n );\n } else {\n object[key] = value;\n }\n }\n return object;\n}\nfunction createDefu(merger) {\n return (...arguments_) => (\n // eslint-disable-next-line unicorn/no-array-reduce\n arguments_.reduce((p, c) => _defu(p, c, \"\", merger), {})\n );\n}\nconst defu = createDefu();\n\nfunction isPlainObject(obj) {\n return Object.prototype.toString.call(obj) === \"[object Object]\";\n}\nfunction isLogObj(arg) {\n if (!isPlainObject(arg)) {\n return false;\n }\n if (!arg.message && !arg.args) {\n return false;\n }\n if (arg.stack) {\n return false;\n }\n return true;\n}\n\nlet paused = false;\nconst queue = [];\nclass Consola {\n options;\n _lastLog;\n _mockFn;\n /**\n * Creates an instance of Consola with specified options or defaults.\n *\n * @param {Partial<ConsolaOptions>} [options={}] - Configuration options for the Consola instance.\n */\n constructor(options = {}) {\n const types = options.types || LogTypes;\n this.options = defu(\n {\n ...options,\n defaults: { ...options.defaults },\n level: _normalizeLogLevel(options.level, types),\n reporters: [...options.reporters || []]\n },\n {\n types: LogTypes,\n throttle: 1e3,\n throttleMin: 5,\n formatOptions: {\n date: true,\n colors: false,\n compact: true\n }\n }\n );\n for (const type in types) {\n const defaults = {\n type,\n ...this.options.defaults,\n ...types[type]\n };\n this[type] = this._wrapLogFn(defaults);\n this[type].raw = this._wrapLogFn(\n defaults,\n true\n );\n }\n if (this.options.mockFn) {\n this.mockTypes();\n }\n this._lastLog = {};\n }\n /**\n * Gets the current log level of the Consola instance.\n *\n * @returns {number} The current log level.\n */\n get level() {\n return this.options.level;\n }\n /**\n * Sets the minimum log level that will be output by the instance.\n *\n * @param {number} level - The new log level to set.\n */\n set level(level) {\n this.options.level = _normalizeLogLevel(\n level,\n this.options.types,\n this.options.level\n );\n }\n /**\n * Displays a prompt to the user and returns the response.\n * Throw an error if `prompt` is not supported by the current configuration.\n *\n * @template T\n * @param {string} message - The message to display in the prompt.\n * @param {T} [opts] - Optional options for the prompt. See {@link PromptOptions}.\n * @returns {promise<T>} A promise that infer with the prompt options. See {@link PromptOptions}.\n */\n prompt(message, opts) {\n if (!this.options.prompt) {\n throw new Error(\"prompt is not supported!\");\n }\n return this.options.prompt(message, opts);\n }\n /**\n * Creates a new instance of Consola, inheriting options from the current instance, with possible overrides.\n *\n * @param {Partial<ConsolaOptions>} options - Optional overrides for the new instance. See {@link ConsolaOptions}.\n * @returns {ConsolaInstance} A new Consola instance. See {@link ConsolaInstance}.\n */\n create(options) {\n const instance = new Consola({\n ...this.options,\n ...options\n });\n if (this._mockFn) {\n instance.mockTypes(this._mockFn);\n }\n return instance;\n }\n /**\n * Creates a new Consola instance with the specified default log object properties.\n *\n * @param {InputLogObject} defaults - Default properties to include in any log from the new instance. See {@link InputLogObject}.\n * @returns {ConsolaInstance} A new Consola instance. See {@link ConsolaInstance}.\n */\n withDefaults(defaults) {\n return this.create({\n ...this.options,\n defaults: {\n ...this.options.defaults,\n ...defaults\n }\n });\n }\n /**\n * Creates a new Consola instance with a specified tag, which will be included in every log.\n *\n * @param {string} tag - The tag to include in each log of the new instance.\n * @returns {ConsolaInstance} A new Consola instance. See {@link ConsolaInstance}.\n */\n withTag(tag) {\n return this.withDefaults({\n tag: this.options.defaults.tag ? this.options.defaults.tag + \":\" + tag : tag\n });\n }\n /**\n * Adds a custom reporter to the Consola instance.\n * Reporters will be called for each log message, depending on their implementation and log level.\n *\n * @param {ConsolaReporter} reporter - The reporter to add. See {@link ConsolaReporter}.\n * @returns {Consola} The current Consola instance.\n */\n addReporter(reporter) {\n this.options.reporters.push(reporter);\n return this;\n }\n /**\n * Removes a custom reporter from the Consola instance.\n * If no reporter is specified, all reporters will be removed.\n *\n * @param {ConsolaReporter} reporter - The reporter to remove. See {@link ConsolaReporter}.\n * @returns {Consola} The current Consola instance.\n */\n removeReporter(reporter) {\n if (reporter) {\n const i = this.options.reporters.indexOf(reporter);\n if (i !== -1) {\n return this.options.reporters.splice(i, 1);\n }\n } else {\n this.options.reporters.splice(0);\n }\n return this;\n }\n /**\n * Replaces all reporters of the Consola instance with the specified array of reporters.\n *\n * @param {ConsolaReporter[]} reporters - The new reporters to set. See {@link ConsolaReporter}.\n * @returns {Consola} The current Consola instance.\n */\n setReporters(reporters) {\n this.options.reporters = Array.isArray(reporters) ? reporters : [reporters];\n return this;\n }\n wrapAll() {\n this.wrapConsole();\n this.wrapStd();\n }\n restoreAll() {\n this.restoreConsole();\n this.restoreStd();\n }\n /**\n * Overrides console methods with Consola logging methods for consistent logging.\n */\n wrapConsole() {\n for (const type in this.options.types) {\n if (!console[\"__\" + type]) {\n console[\"__\" + type] = console[type];\n }\n console[type] = this[type].raw;\n }\n }\n /**\n * Restores the original console methods, removing Consola overrides.\n */\n restoreConsole() {\n for (const type in this.options.types) {\n if (console[\"__\" + type]) {\n console[type] = console[\"__\" + type];\n delete console[\"__\" + type];\n }\n }\n }\n /**\n * Overrides standard output and error streams to redirect them through Consola.\n */\n wrapStd() {\n this._wrapStream(this.options.stdout, \"log\");\n this._wrapStream(this.options.stderr, \"log\");\n }\n _wrapStream(stream, type) {\n if (!stream) {\n return;\n }\n if (!stream.__write) {\n stream.__write = stream.write;\n }\n stream.write = (data) => {\n this[type].raw(String(data).trim());\n };\n }\n /**\n * Restores the original standard output and error streams, removing the Consola redirection.\n */\n restoreStd() {\n this._restoreStream(this.options.stdout);\n this._restoreStream(this.options.stderr);\n }\n _restoreStream(stream) {\n if (!stream) {\n return;\n }\n if (stream.__write) {\n stream.write = stream.__write;\n delete stream.__write;\n }\n }\n /**\n * Pauses logging, queues incoming logs until resumed.\n */\n pauseLogs() {\n paused = true;\n }\n /**\n * Resumes logging, processing any queued logs.\n */\n resumeLogs() {\n paused = false;\n const _queue = queue.splice(0);\n for (const item of _queue) {\n item[0]._logFn(item[1], item[2]);\n }\n }\n /**\n * Replaces logging methods with mocks if a mock function is provided.\n *\n * @param {ConsolaOptions[\"mockFn\"]} mockFn - The function to use for mocking logging methods. See {@link ConsolaOptions[\"mockFn\"]}.\n */\n mockTypes(mockFn) {\n const _mockFn = mockFn || this.options.mockFn;\n this._mockFn = _mockFn;\n if (typeof _mockFn !== \"function\") {\n return;\n }\n for (const type in this.options.types) {\n this[type] = _mockFn(type, this.options.types[type]) || this[type];\n this[type].raw = this[type];\n }\n }\n _wrapLogFn(defaults, isRaw) {\n return (...args) => {\n if (paused) {\n queue.push([this, defaults, args, isRaw]);\n return;\n }\n return this._logFn(defaults, args, isRaw);\n };\n }\n _logFn(defaults, args, isRaw) {\n if ((defaults.level || 0) > this.level) {\n return false;\n }\n const logObj = {\n date: /* @__PURE__ */ new Date(),\n args: [],\n ...defaults,\n level: _normalizeLogLevel(defaults.level, this.options.types)\n };\n if (!isRaw && args.length === 1 && isLogObj(args[0])) {\n Object.assign(logObj, args[0]);\n } else {\n logObj.args = [...args];\n }\n if (logObj.message) {\n logObj.args.unshift(logObj.message);\n delete logObj.message;\n }\n if (logObj.additional) {\n if (!Array.isArray(logObj.additional)) {\n logObj.additional = logObj.additional.split(\"\\n\");\n }\n logObj.args.push(\"\\n\" + logObj.additional.join(\"\\n\"));\n delete logObj.additional;\n }\n logObj.type = typeof logObj.type === \"string\" ? logObj.type.toLowerCase() : \"log\";\n logObj.tag = typeof logObj.tag === \"string\" ? logObj.tag : \"\";\n const resolveLog = (newLog = false) => {\n const repeated = (this._lastLog.count || 0) - this.options.throttleMin;\n if (this._lastLog.object && repeated > 0) {\n const args2 = [...this._lastLog.object.args];\n if (repeated > 1) {\n args2.push(`(repeated ${repeated} times)`);\n }\n this._log({ ...this._lastLog.object, args: args2 });\n this._lastLog.count = 1;\n }\n if (newLog) {\n this._lastLog.object = logObj;\n this._log(logObj);\n }\n };\n clearTimeout(this._lastLog.timeout);\n const diffTime = this._lastLog.time && logObj.date ? logObj.date.getTime() - this._lastLog.time.getTime() : 0;\n this._lastLog.time = logObj.date;\n if (diffTime < this.options.throttle) {\n try {\n const serializedLog = JSON.stringify([\n logObj.type,\n logObj.tag,\n logObj.args\n ]);\n const isSameLog = this._lastLog.serialized === serializedLog;\n this._lastLog.serialized = serializedLog;\n if (isSameLog) {\n this._lastLog.count = (this._lastLog.count || 0) + 1;\n if (this._lastLog.count > this.options.throttleMin) {\n this._lastLog.timeout = setTimeout(\n resolveLog,\n this.options.throttle\n );\n return;\n }\n }\n } catch {\n }\n }\n resolveLog(true);\n }\n _log(logObj) {\n for (const reporter of this.options.reporters) {\n reporter.log(logObj, {\n options: this.options\n });\n }\n }\n}\nfunction _normalizeLogLevel(input, types = {}, defaultLevel = 3) {\n if (input === void 0) {\n return defaultLevel;\n }\n if (typeof input === \"number\") {\n return input;\n }\n if (types[input] && types[input].level !== void 0) {\n return types[input].level;\n }\n return defaultLevel;\n}\nConsola.prototype.add = Consola.prototype.addReporter;\nConsola.prototype.remove = Consola.prototype.removeReporter;\nConsola.prototype.clear = Consola.prototype.removeReporter;\nConsola.prototype.withScope = Consola.prototype.withTag;\nConsola.prototype.mock = Consola.prototype.mockTypes;\nConsola.prototype.pause = Consola.prototype.pauseLogs;\nConsola.prototype.resume = Consola.prototype.resumeLogs;\nfunction createConsola(options = {}) {\n return new Consola(options);\n}\n\nexport { Consola, LogLevels, LogTypes, createConsola };\n", "import { createConsola as createConsola$1 } from './core.mjs';\nexport { Consola, LogLevels, LogTypes } from './core.mjs';\n\nclass BrowserReporter {\n options;\n defaultColor;\n levelColorMap;\n typeColorMap;\n constructor(options) {\n this.options = { ...options };\n this.defaultColor = \"#7f8c8d\";\n this.levelColorMap = {\n 0: \"#c0392b\",\n // Red\n 1: \"#f39c12\",\n // Yellow\n 3: \"#00BCD4\"\n // Cyan\n };\n this.typeColorMap = {\n success: \"#2ecc71\"\n // Green\n };\n }\n _getLogFn(level) {\n if (level < 1) {\n return console.__error || console.error;\n }\n if (level === 1) {\n return console.__warn || console.warn;\n }\n return console.__log || console.log;\n }\n log(logObj) {\n const consoleLogFn = this._getLogFn(logObj.level);\n const type = logObj.type === \"log\" ? \"\" : logObj.type;\n const tag = logObj.tag || \"\";\n const color = this.typeColorMap[logObj.type] || this.levelColorMap[logObj.level] || this.defaultColor;\n const style = `\n background: ${color};\n border-radius: 0.5em;\n color: white;\n font-weight: bold;\n padding: 2px 0.5em;\n `;\n const badge = `%c${[tag, type].filter(Boolean).join(\":\")}`;\n if (typeof logObj.args[0] === \"string\") {\n consoleLogFn(\n `${badge}%c ${logObj.args[0]}`,\n style,\n // Empty string as style resets to default console style\n \"\",\n ...logObj.args.slice(1)\n );\n } else {\n consoleLogFn(badge, style, ...logObj.args);\n }\n }\n}\n\nfunction createConsola(options = {}) {\n const consola2 = createConsola$1({\n reporters: options.reporters || [new BrowserReporter({})],\n prompt(message, options2 = {}) {\n if (options2.type === \"confirm\") {\n return Promise.resolve(confirm(message));\n }\n return Promise.resolve(prompt(message));\n },\n ...options\n });\n return consola2;\n}\nconst consola = createConsola();\n\nexport { consola, createConsola, consola as default };\n", "import { createConsola as createConsolaBrowser } from 'consola/browser';\nimport { LogLevels, createConsola as createConsolaCore, } from 'consola/core';\n/**\n * Used to set the logging level.\n *\n * @example Explicitly set the level of an imported package beyond the current runtime level.\n * ```ts\n * import { LogLevel } from '@genesislcap/foundation-logger';\n * import { logger as myPackageLogger } from 'my-package';\n * myPackageLogger.level = LogLevel.Error;\n * ```\n *\n * @public\n */\nexport { LogLevels } from 'consola/core';\n/**\n * The default logger options.\n * @public\n */\nexport const defaultLoggerOptions = {\n level: LogLevels.debug,\n};\n/**\n * Creates a logger with the given name and options.\n *\n * @example Create a logger in my-package/utils.\n * ```ts\n * import { createLogger } from '@genesislcap/foundation-logger';\n * export const logger = createLogger('my-package');\n * ```\n *\n * @example Using the logger within my-package.\n * ```ts\n * import { logger } from '../utils';\n * logger.debug(`Data retrieved from ${resourceName}`);\n * logger.info(this.toggled ? 'On' : 'Off');\n * logger.warn('Not available in this browser.');\n * ```\n *\n * @example Explicitly set the level of an imported package.\n * ```ts\n * import { logger as commsLogger } from '@genesislcap/foundation-comms';\n * import { LogLevel } from '@genesislcap/foundation-logger';\n * commsLogger.level = LogLevel.Warn;\n * ```\n *\n * @param name - The name to give the logger.\n * @param options - The options to use when creating the logger.\n * @returns The resulting logger.\n * @public\n */\nexport function createLogger(name, options = defaultLoggerOptions) {\n const createConsola = typeof window !== 'undefined' ? createConsolaBrowser : createConsolaCore;\n const logger = createConsola().withTag(name);\n if ((options === null || options === void 0 ? void 0 : options.level) !== undefined)\n logger.level = options.level;\n const typedLogger = logger;\n typedLogger.deprecated = (symbol, instruction = 'Consult docs for better alternative.', removalVersionTarget) => {\n typedLogger.warn(`Deprecated symbol used '${symbol}'. ${instruction}`, `${removalVersionTarget ? `Will be removed in version ${removalVersionTarget}.` : ''}`);\n };\n return typedLogger;\n}\n", "import { createLogger } from '@genesislcap/foundation-logger';\nexport const logger = createLogger('foundation-ai');\n", "import { logger } from '../utils';\nconst CLAUSE_SCHEMA = {\n type: 'object',\n properties: {\n field: { type: 'string', description: 'Field name from available metadata' },\n operator: {\n type: 'string',\n enum: [\n 'contains',\n 'equals',\n 'startsWith',\n 'endsWith',\n 'greaterThan',\n 'lessThan',\n 'greaterThanOrEqual',\n 'lessThanOrEqual',\n 'notEqual',\n 'dateIsToday',\n 'dateIsAfter',\n 'dateIsBefore',\n 'dateIsEqual',\n 'dateIsGreaterEqual',\n 'dateIsLessEqual',\n 'dateTimeIsAfter',\n 'dateTimeIsBefore',\n 'dateTimeIsGreaterEqual',\n 'dateTimeIsLessEqual',\n ],\n },\n value: {\n type: ['string', 'number', 'boolean', 'null'],\n description: 'Value for the clause; null for dateIsToday',\n },\n },\n required: ['field', 'operator', 'value'],\n additionalProperties: false,\n};\n/**\n * Standard JSON Schema for criteria interpretation output.\n * Used by Chrome Prompt API (responseConstraint) and other providers.\n *\n * @beta\n */\nexport const CRITERIA_JSON_SCHEMA = {\n type: 'object',\n properties: {\n groups: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n logic: {\n type: 'string',\n enum: ['and', 'or'],\n description: 'How clauses within the group are combined',\n },\n negated: {\n type: 'boolean',\n default: false,\n description: 'If true, negate the entire group',\n },\n clauses: {\n type: 'array',\n items: CLAUSE_SCHEMA,\n },\n },\n required: ['logic', 'negated', 'clauses'],\n additionalProperties: false,\n },\n },\n },\n required: ['groups'],\n additionalProperties: false,\n};\n/**\n * OpenAI-specific response_format wrapper for structured output.\n *\n * @beta\n */\nexport const OPENAI_CRITERIA_RESPONSE_FORMAT = {\n type: 'json_schema',\n json_schema: {\n name: 'criteria_interpretation',\n strict: true,\n schema: CRITERIA_JSON_SCHEMA,\n },\n};\nconst DEFAULT_SYSTEM_PROMPT = `You are a criteria builder. Convert natural language into structured search criteria.\nReturn a JSON object with a \"groups\" array. Each group has: logic (\"and\" or \"or\"), optional negated (boolean), and clauses (array).\nEach clause has: field (string), operator (from enum), value (string|number|boolean|null).\n- When the user says \"or\" (e.g. \"quantity 100 or price > 50\"), use a group with logic \"or\" and multiple clauses.\n- When the user says \"not\" or \"except\", set negated: true on the group.\n- When the user says \"and\" or lists conditions without \"or\", use logic \"and\".\nUse dateIsToday with value null for \"today\" queries. Use yyyyMMdd for dates, yyyyMMdd-HH:mm for datetimes.`;\n/**\n * Builds the system prompt for criteria interpretation.\n *\n * @beta\n */\nexport function buildCriteriaSystemPrompt(fields = [], customInstructions) {\n const fieldList = fields\n .map((f) => {\n var _a, _b, _c, _d;\n return typeof f === 'string'\n ? f\n : ((_d = (_c = (_b = (_a = f === null || f === void 0 ? void 0 : f.NAME) !== null && _a !== void 0 ? _a : f === null || f === void 0 ? void 0 : f.name) !== null && _b !== void 0 ? _b : f === null || f === void 0 ? void 0 : f.field) !== null && _c !== void 0 ? _c : f === null || f === void 0 ? void 0 : f.label) !== null && _d !== void 0 ? _d : '');\n })\n .filter(Boolean)\n .join(', ');\n const basePrompt = customInstructions !== null && customInstructions !== void 0 ? customInstructions : DEFAULT_SYSTEM_PROMPT;\n const fieldsLine = `Available fields: ${fieldList || 'unknown - use common field names like NAME, ID, DATE, etc.'}`;\n return `${basePrompt}\\n${fieldsLine}`;\n}\n/**\n * Builds the user prompt for criteria interpretation.\n *\n * @beta\n */\nexport function buildCriteriaUserPrompt(input) {\n return `Convert to criteria: \"${input}\"`;\n}\n/**\n * Parses the raw response text into CriteriaInterpretationResult.\n *\n * @beta\n */\nexport function parseCriteriaResponse(text) {\n if (!(text === null || text === void 0 ? void 0 : text.trim())) {\n logger.debug('parseCriteriaResponse: empty or null input');\n return null;\n }\n try {\n const parsed = JSON.parse(text);\n if (!(parsed === null || parsed === void 0 ? void 0 : parsed.groups) || !Array.isArray(parsed.groups)) {\n logger.debug('parseCriteriaResponse: missing or invalid groups in response');\n return null;\n }\n return {\n groups: parsed.groups,\n };\n }\n catch (e) {\n logger.debug('parseCriteriaResponse: invalid JSON', e);\n return null;\n }\n}\n", "import { __asyncDelegator, __asyncGenerator, __asyncValues, __await, __awaiter } from \"tslib\";\nimport { buildCriteriaSystemPrompt, buildCriteriaUserPrompt, CRITERIA_JSON_SCHEMA, parseCriteriaResponse, } from '../interactions';\nimport { logger } from '../utils';\n/**\n * Anthropic Claude AI provider. Uses {@link AnthropicTransport} to handle requests.\n * Implements criteria interpretation and multi-turn chat.\n *\n * @beta\n */\nexport class AnthropicProvider {\n constructor(config, transport) {\n this.transport = transport;\n this.criteriaInstructions = config.criteriaInstructions;\n }\n getStatus() {\n return __awaiter(this, void 0, void 0, function* () {\n const config = this.transport.getConfig();\n return { provider: 'anthropic', model: config.model, contextLimit: config.contextLimit };\n });\n }\n interpretCriteria(input, context) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a;\n const fields = (_a = context === null || context === void 0 ? void 0 : context.fields) !== null && _a !== void 0 ? _a : [];\n const systemPrompt = buildCriteriaSystemPrompt(fields, this.criteriaInstructions);\n const userPrompt = buildCriteriaUserPrompt(input);\n try {\n const raw = yield this.transport.sendStructuredPrompt({\n systemPrompt,\n userPrompt,\n responseSchema: CRITERIA_JSON_SCHEMA,\n });\n return parseCriteriaResponse(raw);\n }\n catch (e) {\n logger.error('AnthropicProvider interpretCriteria failed:', e);\n return null;\n }\n });\n }\n prompt(message, options) {\n return __awaiter(this, void 0, void 0, function* () {\n const response = yield this.transport.sendChatMessage([], message, options);\n return response.content;\n });\n }\n chat(history, userMessage, options) {\n return __awaiter(this, void 0, void 0, function* () {\n return this.transport.sendChatMessage(history, userMessage, options);\n });\n }\n streamChat(history, userMessage, options) {\n return __asyncGenerator(this, arguments, function* streamChat_1() {\n if ('streamChatMessage' in this.transport &&\n typeof this.transport.streamChatMessage === 'function') {\n yield __await(yield* __asyncDelegator(__asyncValues(this.transport.streamChatMessage(history, userMessage, options))));\n }\n else {\n const msg = yield __await(this.transport.sendChatMessage(history, userMessage, options));\n yield yield __await({ delta: msg.content, done: true, toolCalls: msg.toolCalls });\n }\n });\n }\n}\n", "import { __awaiter } from \"tslib\";\n/**\n * Default no-op AI provider. Used when no provider is configured.\n * Components should check for capability support and show \"Configure AI\" state when appropriate.\n *\n * @beta\n */\nexport class DefaultAIProvider {\n getStatus() {\n return __awaiter(this, void 0, void 0, function* () {\n return { provider: 'none', model: '' };\n });\n }\n interpretCriteria(_input, _context) {\n return __awaiter(this, void 0, void 0, function* () {\n return null;\n });\n }\n}\n", "import { __asyncDelegator, __asyncGenerator, __asyncValues, __await, __awaiter } from \"tslib\";\nimport { buildCriteriaSystemPrompt, buildCriteriaUserPrompt, CRITERIA_JSON_SCHEMA, parseCriteriaResponse, } from '../interactions';\nimport { logger } from '../utils';\n/**\n * Gemini AI provider. Uses {@link GeminiTransport} to handle requests.\n * Implements criteria interpretation and multi-turn chat.\n *\n * @beta\n */\nexport class GeminiProvider {\n constructor(config, transport) {\n this.transport = transport;\n this.criteriaInstructions = config.criteriaInstructions;\n }\n getStatus() {\n return __awaiter(this, void 0, void 0, function* () {\n const config = this.transport.getConfig();\n return { provider: 'gemini', model: config.model, contextLimit: config.contextLimit };\n });\n }\n interpretCriteria(input, context) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a;\n const fields = (_a = context === null || context === void 0 ? void 0 : context.fields) !== null && _a !== void 0 ? _a : [];\n const systemPrompt = buildCriteriaSystemPrompt(fields, this.criteriaInstructions);\n const userPrompt = buildCriteriaUserPrompt(input);\n try {\n const raw = yield this.transport.sendStructuredPrompt({\n systemPrompt,\n userPrompt,\n responseSchema: CRITERIA_JSON_SCHEMA,\n });\n return parseCriteriaResponse(raw);\n }\n catch (e) {\n logger.error('GeminiProvider interpretCriteria failed:', e);\n return null;\n }\n });\n }\n prompt(message, options) {\n return __awaiter(this, void 0, void 0, function* () {\n const response = yield this.transport.sendChatMessage([], message, options);\n return response.content;\n });\n }\n chat(history, userMessage, options) {\n return __awaiter(this, void 0, void 0, function* () {\n return this.transport.sendChatMessage(history, userMessage, options);\n });\n }\n streamChat(history, userMessage, options) {\n return __asyncGenerator(this, arguments, function* streamChat_1() {\n if ('streamChatMessage' in this.transport &&\n typeof this.transport.streamChatMessage === 'function') {\n yield __await(yield* __asyncDelegator(__asyncValues(this.transport.streamChatMessage(history, userMessage, options))));\n }\n else {\n // Fallback: non-streaming chat exposed as a single chunk\n const msg = yield __await(this.transport.sendChatMessage(history, userMessage, options));\n yield yield __await({ delta: msg.content, done: true, toolCalls: msg.toolCalls });\n }\n });\n }\n}\n", "/**\n * The AI-spend budget wall (GENC-1464 workstream C/D).\n *\n * Lives in its own module rather than beside `ResponseTruncatedError` in\n * `anthropic-transport.ts` because it is raised from `post-with-retry.ts`, which\n * both transports import \u2014 homing it in a transport would close an import cycle\n * (transport \u2192 post-with-retry \u2192 transport) that the repo's `circular` check\n * rejects.\n */\n/** The proxy's machine-readable rejection code for an exhausted AI budget. */\nexport const BUDGET_EXCEEDED_CODE = 'BUDGET_EXCEEDED';\n/**\n * Display name for each concrete AI vendor: the **single source** every\n * transport's `vendorLabel` is read from, and the only place a vendor's name is\n * spelled for a user.\n *\n * This map is the hinge of the per-vendor budget model (GENC-1464). A wall is\n * attributed to a vendor by reverse-looking-up the label the refused transport\n * stamped on its {@link BudgetExhaustedError} \u2014 so a label that drifts from this\n * map (a literal typo, a casing change, a new vendor added with a hardcoded\n * string) silently degrades every wall from that transport to \"unattributable\"\n * and re-locks the whole session instead of just that vendor. It fails safe, but\n * the feature quietly stops working, which is why the transports read their label\n * from here rather than restating it.\n *\n * The map has **two kinds of entry**, and the difference matters:\n *\n * - The {@link BUDGETED_VENDORS} \u2014 `anthropic` and `gemini` \u2014 reach the model\n * through the ai-service proxy, are metered by it, and stamp their label on a\n * {@link BudgetExhaustedError}. For these the label is both an attribution key\n * and display copy.\n * - `chrome` and `openai` are **display-only**. `ChromeProvider` talks to the\n * on-device Prompt API and the proxy refuses `openai` outright, so neither can\n * be refused for budget or stamp a label \u2014 but both report a `provider` from\n * `getStatus()`, which puts them in the assistant's reachable set, which is\n * what the blocked banner names when it tells a walled user where they can\n * still go (\"Switch to Chrome to keep going.\"). Dropping either entry would\n * print the raw type there.\n *\n * `'none'` is excluded deliberately: it is the \"no provider configured\" sentinel,\n * not a vendor, and nothing can be refused by it \u2014 nor switched to.\n *\n * @beta\n */\nexport const VENDOR_LABELS = Object.freeze({\n anthropic: 'Anthropic',\n gemini: 'Gemini',\n openai: 'OpenAI',\n chrome: 'Chrome',\n});\n/**\n * The vendors whose spend the ai-service proxy meters \u2014 i.e. the only vendors\n * that can raise a {@link BudgetExhaustedError}, and therefore the only ones a\n * 402's `otherVendorAvailable: false` is a statement about.\n *\n * Deliberately narrower than the keys of {@link VENDOR_LABELS}, and it must stay\n * exactly the proxy's own list \u2014 `VENDORS` in ai-service's `utils/aiVendor.js`.\n * A vendor listed here that the proxy does not meter gets walled by the\n * `otherVendorAvailable: false` sweep on a verdict that says nothing about it,\n * and if it is reachable, `blocked` then derives true and locks a composer with\n * headroom left.\n *\n * Two vendors are excluded for that reason:\n * - `chrome` runs on-device \u2014 no pot to exhaust, and free.\n * - `openai` is **not budgeted by the proxy**. ai-service rejects it up front\n * with `400 UNSUPPORTED_PROVIDER` (`SUPPORTED_PROVIDERS` in `aiVendor.js`), no\n * `MODEL_PRICING` row names it, and `otherVendorAvailable` is computed over\n * Anthropic and Gemini alone. So it can never raise a 402, and a 402 is never\n * a statement about it.\n *\n * @beta\n */\nexport const BUDGETED_VENDORS = Object.freeze([\n 'anthropic',\n 'gemini',\n]);\n/**\n * Whether this vendor's spend is metered by the proxy \u2014 see\n * {@link BUDGETED_VENDORS}.\n *\n * A HOST-FACING helper with, deliberately, no internal caller: the library's\n * own consumers iterate {@link BUDGETED_VENDORS} directly (structural, cannot\n * drift), while a host writing its own budget pre-flight or status surface\n * needs the membership test in predicate form. Kept exported for that use \u2014\n * genesis-create's pre-flight is the shape of consumer it exists for.\n *\n * @beta\n */\nexport const isBudgetedVendor = (vendor) => vendor != null && BUDGETED_VENDORS.includes(vendor);\n/** Reverse index of {@link VENDOR_LABELS}, lower-cased, built once. */\nconst VENDOR_TYPE_BY_LABEL = new Map(Object.entries(VENDOR_LABELS).map(([type, label]) => [\n label.toLowerCase(),\n type,\n]));\n/**\n * The {@link AIProviderType} behind a vendor label, or `undefined` for a label\n * no vendor claims.\n *\n * Case-insensitive and whitespace-tolerant, because the label travels as free\n * text on the wire (the driver contract carries `vendorLabel`, not the type) and\n * an unrecognised label must degrade to \"unattributable\" rather than to a wrong\n * attribution \u2014 blocking the wrong vendor is worse than blocking none.\n *\n * @beta\n */\nexport function vendorTypeOfLabel(label) {\n if (typeof label !== 'string')\n return undefined;\n return VENDOR_TYPE_BY_LABEL.get(label.trim().toLowerCase());\n}\n/**\n * HTTP status the ai-service proxy rejects an over-budget request with, in both\n * the legacy JSON mode (the response status) and the NDJSON framed mode (the\n * `status` on the terminal `err` frame).\n *\n * Deliberately **absent** from every transport's `RETRYABLE_STATUSES`: the budget\n * does not refill on a backoff ladder, so retrying only delays the inevitable\n * five times over.\n */\nexport const BUDGET_EXCEEDED_STATUS = 402;\n/**\n * The single copy shown to a user whose AI budget is gone \u2014 the transcript bubble\n * the chat driver appends, and the default text of the assistant's blocked banner.\n *\n * Deliberately **vendor-neutral**: the same bundle ships to white-labelled\n * deployments where \"contact Genesis\" is simply wrong. A host that wants\n * branded wording overrides both surfaces \u2014 the banner via\n * `FoundationAiAssistant.setBlocked(true, reason)`, the transcript bubble via\n * `ChatDriverConfig.budgetExhaustedMessage` \u2014 so neither is stuck with this\n * default while the other is customised.\n *\n * @beta\n */\nexport const DEFAULT_BUDGET_EXHAUSTED_MESSAGE = \"You've reached your AI usage limit. Contact your administrator to raise it.\";\n/**\n * Thrown when the AI-spend budget for the caller (user, tenant, or project) is\n * exhausted and the ai-service proxy refuses the request outright \u2014 HTTP `402`\n * with `code: 'BUDGET_EXCEEDED'`, in either the legacy JSON or the NDJSON framed\n * mode.\n *\n * This is a **terminal, non-transient** condition, in the same family as\n * `ResponseTruncatedError`: no amount of retrying clears it, because nothing\n * about the request is wrong. The budget has to be raised out-of-band before any\n * further call can succeed, so both the transport retry ladder and the driver's\n * transient-retry catch step aside for it and the failure surfaces immediately\n * as the `'budget-exhausted'` `TurnFailureReason`.\n *\n * `budgetUsd`/`spentUsd` are populated from the rejection body when the proxy\n * supplies them (the workstream-C contract does); they are optional because a\n * plain-text or truncated 402 from an older proxy still has to classify.\n *\n * @beta\n */\nexport class BudgetExhaustedError extends Error {\n constructor(\n /** Vendor label of the transport that was refused (e.g. `'Anthropic'`). */\n vendorLabel, \n /** The configured spend cap in USD, when the proxy reported one. */\n budgetUsd, \n /** Spend already booked against that cap in USD, when the proxy reported it. */\n spentUsd, \n /** The proxy's human-readable rejection message, when present. */\n detail, \n /**\n * The fields the proxy reports about the wider budget picture. An object\n * rather than two more positional arguments: the four above are already the\n * limit of what reads at a call site, and these two are set together or not\n * at all.\n */\n extra) {\n super(`${vendorLabel} request refused: the AI usage budget is exhausted` +\n (budgetUsd != null\n ? ` (spent ${spentUsd != null ? `$${spentUsd}` : 'an unknown amount'} of a $${budgetUsd} budget)`\n : '') +\n (detail ? `: ${detail}` : '') +\n '. Retrying will not clear this \u2014 the budget must be raised.');\n this.vendorLabel = vendorLabel;\n this.budgetUsd = budgetUsd;\n this.spentUsd = spentUsd;\n this.detail = detail;\n this.name = 'BudgetExhaustedError';\n this.otherVendorAvailable = extra === null || extra === void 0 ? void 0 : extra.otherVendorAvailable;\n this.serverVendor = extra === null || extra === void 0 ? void 0 : extra.serverVendor;\n }\n}\n/**\n * True for a budget rejection in either wire mode: the contracted `402`, or the\n * `BUDGET_EXCEEDED` code under **any** status.\n *\n * Both keys are load-bearing, and they are not redundant:\n *\n * - `status` is the key the workstream-C contract guarantees (\"402 always\"), and\n * the only one a plain-text or unparseable rejection carries.\n * - `code` is the cheap defence against that contract drifting. Nothing stops a\n * proxy from mapping the refusal onto `403` or `429` \u2014 and `429` is in *both*\n * transports' `RETRYABLE_STATUSES`, so a status-only check would hand the user\n * the exact bug GENC-1464 exists to fix: five doomed requests and ~31s of backoff\n * before an opaque failure. A well-formed `{ t: 'err', status: 429, code:\n * 'BUDGET_EXCEEDED' }` frame is accepted by `readFramedBody` (it only rejects a\n * non-numeric status), so this is a reachable shape, not a hypothetical one.\n *\n * The false-positive cost is a proxy sending `code: 'BUDGET_EXCEEDED'` on a\n * genuinely retryable failure \u2014 a shape the contract does not permit.\n *\n * Internal to the transports (unlike `BudgetExhaustedError`, which hosts branch\n * on): deliberately **not** re-exported from the package index.\n *\n * @internal\n */\nexport const isBudgetRejection = (status, code) => status === BUDGET_EXCEEDED_STATUS || code === BUDGET_EXCEEDED_CODE;\n/**\n * Best-effort JSON parse of an error body \u2014 `undefined` rather than a throw.\n * Shared by every caller that has to classify a rejection body before it knows\n * whether the body is JSON at all.\n *\n * @internal\n */\nexport const parseJsonOrUndefined = (text) => {\n try {\n return JSON.parse(text);\n }\n catch (_a) {\n return undefined;\n }\n};\n/**\n * Read the `code` field off an already-parsed rejection body, ignoring anything\n * that is not a string. Pairs with {@link isBudgetRejection} at the legacy call\n * sites, which have a parsed body rather than a typed frame.\n *\n * @internal\n */\nexport const codeOf = (payload) => {\n const code = payload === null || payload === void 0 ? void 0 : payload.code;\n return typeof code === 'string' ? code : undefined;\n};\n/** Narrow an unknown JSON value to a number, ignoring anything else. */\nconst numberOrUndefined = (value) => typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n/** Narrow an unknown JSON value to a boolean, ignoring anything else. */\nconst booleanOrUndefined = (value) => typeof value === 'boolean' ? value : undefined;\n/** Narrow an unknown JSON value to a non-empty string, ignoring anything else. */\nconst stringOrUndefined = (value) => typeof value === 'string' && value.trim() !== '' ? value : undefined;\n/**\n * Build a {@link BudgetExhaustedError} from a rejection payload of either shape:\n * the legacy body `{ error, code, budgetUsd, spentUsd, vendor,\n * otherVendorAvailable }` or the framed err frame's `details` (the same fields\n * minus `error`) plus its top-level `error`.\n *\n * The fields read off the wire, and why each is here:\n *\n * | field | used for |\n * | ---------------------- | ----------------------------------------------------- |\n * | `budgetUsd` | the cap in the banner's figures |\n * | `spentUsd` | the spend in the banner's figures |\n * | `error` | the proxy's human-readable detail |\n * | `vendor` | attribution when the transport's own label is unclaimed |\n * | `otherVendorAvailable` | whether \"switch vendor\" is honest advice at all |\n *\n * Tolerant by design \u2014 a `402` classifies even when the payload is missing,\n * unparseable, or carries none of these. Each field is narrowed independently,\n * so a proxy that sends `null` for a figure it does not know (which the\n * ai-service side now does, in preference to a misleading `0`) still yields the\n * vendor and the availability verdict.\n */\nexport function budgetExhaustedFrom(vendorLabel, payload, fallbackDetail) {\n var _a, _b, _c, _d;\n const body = (typeof payload === 'object' && payload !== null ? payload : {});\n // The framed shape nests everything but `error` under `details`; the legacy\n // body has it all at the top level. Read both so one helper serves both call\n // sites.\n const details = (typeof body.details === 'object' && body.details !== null ? body.details : {});\n const detail = typeof body.error === 'string' ? body.error : fallbackDetail;\n return new BudgetExhaustedError(vendorLabel, (_a = numberOrUndefined(body.budgetUsd)) !== null && _a !== void 0 ? _a : numberOrUndefined(details.budgetUsd), (_b = numberOrUndefined(body.spentUsd)) !== null && _b !== void 0 ? _b : numberOrUndefined(details.spentUsd), detail, {\n otherVendorAvailable: (_c = booleanOrUndefined(body.otherVendorAvailable)) !== null && _c !== void 0 ? _c : booleanOrUndefined(details.otherVendorAvailable),\n serverVendor: (_d = stringOrUndefined(body.vendor)) !== null && _d !== void 0 ? _d : stringOrUndefined(details.vendor),\n });\n}\n", "/** @beta */\nexport const SUPPORTED_GEMINI_MODEL_IDS = [\n 'gemini-2.5-pro',\n 'gemini-2.5-flash',\n 'gemini-2.5-flash-lite',\n 'gemini-3.5-flash',\n 'gemini-3.1-flash-lite',\n 'gemini-3.1-pro-preview',\n];\n/** @beta */\nexport const SUPPORTED_ANTHROPIC_MODEL_IDS = [\n 'claude-fable-5',\n 'claude-opus-4-8',\n 'claude-opus-4-7',\n 'claude-sonnet-5',\n 'claude-sonnet-4-6',\n 'claude-haiku-4-5-20251001',\n];\n", "/**\n * Normalized-temperature anchor. Values at or below it scale into\n * `[0, providerDefault]`; values above it scale into `[providerDefault, providerMax]`.\n * So a normalized `0.5` maps to each provider's own default temperature.\n */\nconst DEFAULT_ANCHOR = 0.5;\n/**\n * Translate a provider-agnostic, normalized temperature into a provider's\n * native range, anchored on the provider's own default so the normalized scale\n * means the same thing everywhere:\n *\n * - `0` \u2192 `0` (fully deterministic),\n * - `0.5` \u2192 the provider's default temperature,\n * - `1` \u2192 the provider's maximum.\n *\n * Values between the anchors interpolate linearly within each half, so `< 0.5`\n * is \"more focused than default\" and `> 0.5` is \"more random than default\" on\n * every provider \u2014 even though the providers' native ranges differ (Anthropic\n * default/max `1`/`1`, Gemini `1`/`2`). Where a provider's default equals its\n * max (Anthropic), the upper half is flat: it cannot go hotter than its default.\n *\n * The input is clamped to `[0, 1]` before scaling, so an out-of-range value can\n * never produce a native temperature the provider would reject.\n */\nexport function scaleTemperature(normalized, { defaultTemp, maxTemp }) {\n const t = Math.min(Math.max(normalized, 0), 1);\n return t <= DEFAULT_ANCHOR\n ? (t / DEFAULT_ANCHOR) * defaultTemp\n : defaultTemp + ((t - DEFAULT_ANCHOR) / (1 - DEFAULT_ANCHOR)) * (maxTemp - defaultTemp);\n}\n/**\n * Provider-agnostic, normalized sampling-temperature presets in `0`\u2013`1` space \u2014\n * named handles for the values most callers actually want, so intent reads\n * better than a bare magnitude. Each maps through `scaleTemperature` to the\n * active provider's native range, so the same preset means the same intent\n * whichever provider services the turn:\n *\n * - `ChatTemperature.Deterministic` (`0`) \u2014 greedy/argmax sampling.\n * - `ChatTemperature.Focused` (`0.25`) \u2014 low but not greedy; precise tool calls\n * and extraction work where you still want a little slack.\n * - `ChatTemperature.Balanced` (`0.5`) \u2014 the provider's own default.\n * - `ChatTemperature.Creative` (`0.75`) \u2014 hotter than default, short of the ceiling.\n * - `ChatTemperature.Maximum` (`1`) \u2014 the hottest the active provider allows.\n *\n * (On a provider whose default equals its max \u2014 Anthropic \u2014 `Creative` and\n * `Maximum` coincide; see `scaleTemperature`.)\n *\n * @beta\n */\nexport const ChatTemperature = {\n Deterministic: 0,\n Focused: 0.25,\n Balanced: 0.5,\n Creative: 0.75,\n Maximum: 1,\n};\n", "/**\n * Resolve the authoritative reason behind an abort-shaped rejection.\n *\n * Chromium/Firefox reject an aborted fetch/body read with the signal's\n * `reason`, but older WebKit rejects with a generic `AbortError` \u2014 which would\n * send a transport timeout down a caller's user-cancel path. Node and jsdom\n * test environments can raise the same shape as a plain `Error` rather than a\n * `DOMException`, so both are accepted (gated on the exact abort names).\n *\n * When `error` is abort-shaped the CALLER signal wins a same-tick tie: if the\n * user hits Stop in the same tick a stall/timeout fires, their intent takes\n * precedence, so the turn still routes to the user-cancel path and keeps its\n * \"Stopped.\" marker (first-cancel-wins, matching the pre-refactor behaviour).\n * A pure timeout \u2014 caller not aborted \u2014 still yields the timeout signal's\n * tagged `TimeoutError`, which is the WebKit fix. Anything not abort-shaped\n * passes through untouched.\n */\nexport function authoritativeAbortReason(error, timeoutSignal, callerSignal) {\n const abortShaped = (error instanceof DOMException || error instanceof Error) &&\n (error.name === 'AbortError' || error.name === 'TimeoutError');\n if (!abortShaped)\n return error;\n if (callerSignal === null || callerSignal === void 0 ? void 0 : callerSignal.aborted)\n return callerSignal.reason;\n if (timeoutSignal.aborted)\n return timeoutSignal.reason;\n return error;\n}\n", "/**\n * A `setTimeout`-based delay that rejects as soon as `signal` aborts, with the\n * signal's reason \u2014 so retry backoffs unwind immediately on a caller cancel or\n * dispose instead of waiting out the full wait. Resolves normally when `ms`\n * elapses first (the abort listener is detached, so a long-lived signal reused\n * across many delays does not accumulate dead listeners).\n */\nexport function abortableDelay(ms, signal) {\n return new Promise((resolve, reject) => {\n const abortReason = () => { var _a; return (_a = signal === null || signal === void 0 ? void 0 : signal.reason) !== null && _a !== void 0 ? _a : new DOMException('The operation was aborted.', 'AbortError'); };\n if (signal === null || signal === void 0 ? void 0 : signal.aborted) {\n reject(abortReason());\n return;\n }\n const onAbort = () => {\n clearTimeout(timer);\n reject(abortReason());\n };\n const timer = setTimeout(() => {\n signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', onAbort, { once: true });\n });\n}\n", "/**\n * Shared reader for the ai-service proxy's NDJSON heartbeat protocol (v1),\n * used by the server-proxied transports (Anthropic, Gemini). The proxy streams\n * `ping` frames while the upstream call runs and ends the body with exactly one\n * terminal `ok`/`err` frame, one JSON object per LF-terminated line.\n */\nimport { __awaiter } from \"tslib\";\n/** Cap on how much of a malformed proxy frame is quoted in the error message. */\nconst MALFORMED_FRAME_PREVIEW_CHARS = 120;\n/**\n * Read an NDJSON heartbeat body to its terminal frame. Buffers partial lines\n * across chunks, tolerates blank lines, and skips unknown frame types \u2014 pings\n * matter only as activity, which `onChunk` reports to the caller's stall\n * timer. An abort (stall timer or caller signal) rejects the pending `read()`\n * with the abort reason, which propagates to the caller's finally cleanup.\n * `vendorLabel` (e.g. `'Anthropic'`) prefixes the protocol-violation messages.\n *\n * `stallTimeout` (ms) arms a client-side backstop: the proxy's own pings re-arm\n * the caller's inactivity timer, so a proxy whose upstream has wedged but which\n * keeps pinging would never trip it. Each ping stamps `sinceLastEventMs` (time\n * since the last upstream event); when that exceeds `stallTimeout` we treat it\n * as a stall and throw the tagged `TimeoutError`, independent of the proxy\n * noticing its own stall. `<= 0` disables the backstop (inactivity detection off).\n */\nexport function readFramedBody(stream, onChunk, vendorLabel, stallTimeout) {\n return __awaiter(this, void 0, void 0, function* () {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n const malformedFrame = (line) => new Error(`${vendorLabel} proxy sent a malformed frame: ${line.slice(0, MALFORMED_FRAME_PREVIEW_CHARS)}`);\n const parseLine = (line) => {\n if (!line)\n return undefined;\n let parsed;\n try {\n parsed = JSON.parse(line);\n }\n catch (_a) {\n throw malformedFrame(line);\n }\n // JSON.parse also accepts null/scalars/arrays \u2014 a frame must be an object\n // (dereferencing `.t` on null would otherwise throw a raw TypeError).\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw malformedFrame(line);\n }\n const frame = parsed;\n if (frame.t === 'ok') {\n if (frame.body == null) {\n throw new Error(`${vendorLabel} proxy sent an ok frame without a body`);\n }\n return frame;\n }\n if (frame.t === 'err') {\n // The cast below promises a numeric status; hold the proxy to it rather\n // than letting `undefined` leak into the retry/status checks downstream.\n if (typeof frame.status !== 'number') {\n throw new Error(`${vendorLabel} proxy sent an err frame without a numeric status`);\n }\n return frame;\n }\n if (frame.t === 'ping') {\n // Client-side stall backstop: the proxy stamps how long its upstream has\n // been silent. Its pings keep the caller's inactivity timer alive, so\n // this is the only signal that catches a wedged upstream behind a proxy\n // that is itself still healthy. Surface the same tagged TimeoutError a\n // local inactivity fire would.\n if (stallTimeout > 0 &&\n typeof frame.sinceLastEventMs === 'number' &&\n frame.sinceLastEventMs > stallTimeout) {\n throw new DOMException(`${vendorLabel} request stalled: proxy reported ${frame.sinceLastEventMs}ms since the last upstream event (exceeds ${stallTimeout}ms)`, 'TimeoutError');\n }\n return undefined;\n }\n return undefined; // unknown frame types (forward compat)\n };\n try {\n for (;;) {\n // oxlint-disable-next-line no-await-in-loop -- sequential stream reads\n const { done, value } = yield reader.read();\n if (done)\n break;\n onChunk();\n buffer += decoder.decode(value, { stream: true });\n let newline = buffer.indexOf('\\n');\n while (newline !== -1) {\n const line = buffer.slice(0, newline).trim();\n buffer = buffer.slice(newline + 1);\n const frame = parseLine(line);\n if (frame)\n return frame;\n newline = buffer.indexOf('\\n');\n }\n }\n // Tolerate a final terminal frame missing its LF.\n const frame = parseLine((buffer + decoder.decode()).trim());\n if (frame)\n return frame;\n throw new Error(`${vendorLabel} proxy stream ended without a terminal frame`);\n }\n finally {\n // Stop the stream on early return, error, or abort; cancel rejects on an\n // already-errored stream, which is fine to ignore.\n void reader.cancel().catch(() => { });\n }\n });\n}\n", "import { __awaiter } from \"tslib\";\nimport { authoritativeAbortReason } from '../utils/abort-reason';\nimport { abortableDelay } from '../utils/abortable-delay';\nimport { combineSignals } from '../utils/combine-signals';\nimport { logger } from '../utils/logger';\nimport { budgetExhaustedFrom, codeOf, isBudgetRejection, parseJsonOrUndefined, } from './budget-exhausted-error';\nimport { readFramedBody } from './ndjson-frames';\nconst MAX_RETRIES = 5;\n/**\n * POST with the shared retry ladder, wall-clock timeout, framed-mode stall\n * detection and abort-reason preservation. Returns the terminal `ok` frame body\n * (framed proxy) or the parsed JSON (legacy proxy / direct API) as `unknown` \u2014\n * the caller casts. Throws a tagged `TimeoutError` on a stall (local inactivity,\n * the proxy's `sinceLastEventMs` backstop, or an `UPSTREAM_STALLED` frame), the\n * caller's reason on a caller abort, or a plain `Error` otherwise.\n */\nexport function postWithRetry(options) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a, _b, _c, _d;\n const { url, headers, body, credentials, vendorLabel, retryableStatuses, timeout, stallTimeout, backoffBaseMs, signal, } = options;\n // Exponential backoff between retries: base, 2\u00D7, 4\u00D7, 8\u00D7, 16\u00D7. Abortable on the\n // CALLER signal only \u2014 the timeout is cleared before each backoff, so a caller\n // cancel mid-wait unwinds immediately while a timeout does not.\n const backoff = (attempt) => abortableDelay(backoffBaseMs * (1 << attempt), signal);\n // Sequential retries are intentional \u2014 each attempt depends on the previous response.\n /* oxlint-disable no-await-in-loop -- intentional sequential retries with backoff */\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt += 1) {\n const timeoutController = new AbortController();\n // Wall clock for connect/headers (and the whole body on the legacy JSON\n // path). The framed path swaps it for the inactivity timer below once the\n // heartbeat body starts streaming.\n let timeoutId = setTimeout(() => timeoutController.abort(new DOMException(`${vendorLabel} request timed out`, 'TimeoutError')), timeout);\n // Re-armed on every received chunk. With proxy pings every 5s it only fires\n // when the proxy/network actually dies \u2014 a framed body that keeps streaming\n // has no wall cap (max_tokens bounds generation; the proxy watches upstream).\n // A non-positive stallTimeout disables inactivity detection: leave the wall\n // clock armed as the only cap (and the sinceLastEventMs backstop stays off).\n const rearmStallTimer = () => {\n if (stallTimeout <= 0)\n return;\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => timeoutController.abort(new DOMException(`${vendorLabel} request stalled (no data for ${stallTimeout}ms)`, 'TimeoutError')), stallTimeout);\n };\n // Combine so BOTH the local timeout and an optional caller signal can abort\n // the fetch. A plain `signal ?? timeoutController.signal` would silently\n // disarm the timeout whenever a caller signal was supplied. The tagged\n // `TimeoutError` lets callers distinguish a timeout from a caller-initiated\n // cancellation by inspecting the abort reason.\n const { signal: combinedSignal, dispose } = combineSignals([signal, timeoutController.signal]);\n // The finally guards the WHOLE attempt \u2014 body reads included. Disarming on\n // headers alone left `response.json()` with no deadline and no caller abort.\n try {\n const response = yield fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: combinedSignal,\n credentials,\n });\n if (!response.ok) {\n // One read of the error body per failing attempt \u2014 it feeds BOTH the\n // budget classification and the thrown message, and the response is\n // discarded either way. Note this means a retryable attempt now reads\n // the (small, proxy-authored) error body before backing off. That is the\n // price of the classification winning over the ladder in this branch as\n // well as the framed one; the attempt's wall-clock timer is still armed\n // and the read runs on the fetch's combined signal, so a pathological\n // non-terminating body times out rather than hanging.\n //\n // That timeout is a real behaviour change for a RETRYABLE status, and the\n // accepted cost of the symmetry: a 503 used to reach the ladder without\n // the body being touched, so a non-terminating one still backed off and\n // retried. Now the abort propagates out of `postWithRetry` instead.\n // Acceptable because these bodies are proxy-authored and small \u2014 if that\n // ever stops being true, read the body only when the status is\n // non-retryable or already budget-shaped.\n const errText = yield response.text();\n const parsed = parseJsonOrUndefined(errText);\n // The budget wall (GENC-1464) wins over ANY status-based retry \u2014 the same\n // rule the framed branch below applies, now symmetric. It must be\n // classified BEFORE the ladder, not after it: 402 is absent from every\n // RETRYABLE_STATUSES today, but a proxy that maps the refusal onto a\n // retryable status (or a future set that includes 402) would otherwise\n // cost five doomed requests and ~31s of backoff before an opaque error \u2014\n // exactly the bug this classification exists to remove. Parsing is\n // best-effort: an unparseable or plain-text 402 still classifies, just\n // without the budget/spent figures.\n if (isBudgetRejection(response.status, codeOf(parsed))) {\n throw budgetExhaustedFrom(vendorLabel, parsed, errText || undefined);\n }\n if (retryableStatuses.includes(response.status) && attempt < MAX_RETRIES) {\n logger.warn(`${vendorLabel}Transport: retryable status ${response.status}, retrying (attempt ${attempt + 1}/${MAX_RETRIES})`);\n clearTimeout(timeoutId); // this attempt is over \u2014 don't let its timer tick through the backoff\n yield backoff(attempt);\n continue;\n }\n throw new Error(`${vendorLabel} request error ${response.status}: ${errText}`);\n }\n // The proxy streams NDJSON heartbeat frames when it supports them; an old\n // proxy ignores our Accept header and returns plain JSON, so branch on\n // what actually came back.\n if (((_b = (_a = response.headers) === null || _a === void 0 ? void 0 : _a.get('content-type')) === null || _b === void 0 ? void 0 : _b.toLowerCase().includes('application/x-ndjson')) &&\n response.body) {\n rearmStallTimer();\n const frame = yield readFramedBody(response.body, rearmStallTimer, vendorLabel, stallTimeout);\n if (frame.t === 'ok')\n return frame.body;\n // Classify a stall by `code` BEFORE the retryable-status ladder: a stall\n // paired with a retryable status must surface as the non-retried\n // TimeoutError, not get retried 5\u00D7 as that status.\n if (frame.code === 'UPSTREAM_STALLED') {\n // The proxy watchdog saw no upstream data \u2014 same tagged shape as a\n // local stall, so the driver's TimeoutError branch handles both.\n throw new DOMException(`${vendorLabel} request stalled: ${(_c = frame.error) !== null && _c !== void 0 ? _c : 'no upstream data'}`, 'TimeoutError');\n }\n // The budget wall, framed (GENC-1464) \u2014 the in-band twin of the 402 above,\n // through the same predicate, keyed on status OR code. Classified before\n // the retryable ladder for the same reason UPSTREAM_STALLED is: the\n // classification must win over any status-based retry. That ordering is\n // no longer unique to this branch \u2014 the legacy branch above now applies\n // the identical rule, so the two read as one policy rather than two.\n if (isBudgetRejection(frame.status, frame.code)) {\n throw budgetExhaustedFrom(vendorLabel, frame);\n }\n // An in-band retryable status joins the same attempt/backoff ladder as\n // its HTTP-status equivalent (shared attempt counter).\n if (retryableStatuses.includes(frame.status) && attempt < MAX_RETRIES) {\n logger.warn(`${vendorLabel}Transport: retryable status ${frame.status} (err frame), retrying (attempt ${attempt + 1}/${MAX_RETRIES})`);\n clearTimeout(timeoutId); // disarm the stall timer \u2014 the stream is done, only the backoff remains\n yield backoff(attempt);\n continue;\n }\n throw new Error(`${vendorLabel} request error ${frame.status}: ${(_d = frame.error) !== null && _d !== void 0 ? _d : JSON.stringify(frame.details)}`);\n }\n return (yield response.json());\n }\n catch (e) {\n // Some engines reject an aborted read with a generic AbortError instead of\n // the signal's reason \u2014 rethrow the authoritative one so a timeout stays a\n // tagged TimeoutError rather than looking like a user cancel.\n throw authoritativeAbortReason(e, timeoutController.signal, signal);\n }\n finally {\n clearTimeout(timeoutId);\n dispose();\n }\n }\n /* oxlint-enable no-await-in-loop */\n throw new Error(`${vendorLabel} request failed: max retries exceeded`);\n });\n}\n", "import { __awaiter } from \"tslib\";\nimport { SUPPORTED_ANTHROPIC_MODEL_IDS, } from '../types';\nimport { logger } from '../utils/logger';\nimport { scaleTemperature } from '../utils/temperature';\nimport { VENDOR_LABELS } from './budget-exhausted-error';\nimport { postWithRetry } from './post-with-retry';\nconst ANTHROPIC_DIRECT_URL = 'https://api.anthropic.com/v1/messages';\nconst ANTHROPIC_API_VERSION = '2023-06-01';\nconst DEFAULT_MODEL = 'claude-haiku-4-5-20251001';\nconst DEFAULT_TIMEOUT = 300000; // healthy >200s generations observed at 128k max_tokens; wall clock is a last resort\nconst DEFAULT_STALL_TIMEOUT = 30000; // inactivity window on the framed proxy path; pings arrive every 5s\nconst DEFAULT_MAX_TOKENS = 4096;\n/** Anthropic's native default + ceiling temperature \u2014 https://docs.claude.com/en/api/messages */\nconst ANTHROPIC_DEFAULT_TEMPERATURE = 1;\nconst ANTHROPIC_MAX_TEMPERATURE = 1;\n/**\n * Map a provider-agnostic {@link ChatToolChoice} to Anthropic's `tool_choice`.\n * Returns undefined for the default (`'auto'`) so the request omits the field.\n */\nfunction toAnthropicToolChoice(choice) {\n if (!choice || choice === 'auto')\n return undefined;\n if (choice === 'required')\n return { type: 'any' };\n if (choice === 'none')\n return { type: 'none' };\n return { type: 'tool', name: choice.tool };\n}\n/**\n * Maximum input context window (tokens) per supported Claude model.\n * Source: https://docs.claude.com/en/docs/about-claude/models/overview\n */\nconst ANTHROPIC_CONTEXT_LIMITS = {\n 'claude-fable-5': 1000000,\n 'claude-opus-4-8': 1000000,\n 'claude-opus-4-7': 1000000,\n 'claude-sonnet-5': 1000000,\n 'claude-sonnet-4-6': 1000000,\n 'claude-haiku-4-5-20251001': 200000,\n};\n/**\n * Tool name used to coerce JSON-schema output from the model when the caller\n * provided a `responseSchema`. The transport forces `tool_choice` to this tool\n * and surfaces the `input` field as the structured response.\n */\nconst STRUCTURED_OUTPUT_TOOL_NAME = 'emit_structured_response';\n/** Beta flag enabling the server-side `fallbacks` request parameter (refusal rescue). */\nconst SERVER_SIDE_FALLBACK_BETA = 'server-side-fallback-2026-06-01';\nfunction assertSupportedAnthropicModel(model) {\n if (!SUPPORTED_ANTHROPIC_MODEL_IDS.includes(model)) {\n throw new Error(`AnthropicTransport: unsupported model \"${model}\". Use one of: ${SUPPORTED_ANTHROPIC_MODEL_IDS.join(', ')}.`);\n }\n}\n/**\n * Standard tier pricing per million tokens \u2014 https://docs.claude.com/en/docs/about-claude/pricing\n */\nfunction estimatedAnthropicRatesUsdPerMillion(model) {\n if (model === 'claude-haiku-4-5-20251001') {\n return { promptPerMillion: 1, candidatePerMillion: 5 };\n }\n // Fable 5 \u2014 Anthropic's most capable widely-released model; priced above Opus tier.\n if (model === 'claude-fable-5') {\n return { promptPerMillion: 10, candidatePerMillion: 50 };\n }\n // Sonnet 5 and Sonnet 4.6 share the standard Sonnet tier ($3 / $15 per MTok). Sonnet 5's\n // introductory rate ($2 / $10 through 2026-08-31) is deliberately NOT used here \u2014 standard rates.\n if (model === 'claude-sonnet-5' || model === 'claude-sonnet-4-6') {\n return { promptPerMillion: 3, candidatePerMillion: 15 };\n }\n // Opus 4.7 / 4.8 \u2014 same $5 / $25 per MTok.\n return { promptPerMillion: 5, candidatePerMillion: 25 };\n}\n/**\n * Models that reject non-default sampling parameters (`temperature`/`top_p`/`top_k`) with a 400 \u2014\n * the Opus 4.7+ / Sonnet 5 / Fable 5 generation. Sonnet 4.6 and Haiku 4.5 still accept them.\n */\nfunction rejectsSamplingParams(model) {\n return (model === 'claude-fable-5' ||\n model === 'claude-opus-4-8' ||\n model === 'claude-opus-4-7' ||\n model === 'claude-sonnet-5');\n}\n/**\n * Whether the model enforces structured output natively via decode-time `output_config.format`\n * (json_schema). True for Fable 5, Opus 4.8, Sonnet 5, and Haiku 4.5; false for Opus 4.7 and\n * Sonnet 4.6, which fall back to the forced-tool approach on the one-shot path. `output_config`\n * composes with a live `tools` array, so no tool-vs-schema gating is needed on this provider.\n */\nfunction supportsNativeStructuredOutput(model) {\n return (model === 'claude-fable-5' ||\n model === 'claude-opus-4-8' ||\n model === 'claude-sonnet-5' ||\n model === 'claude-haiku-4-5-20251001');\n}\n/**\n * Extended-thinking posture for a request. Sonnet 5 and Fable 5 run adaptive thinking with\n * `display:'summarized'` \u2014 regardless of `tool_choice`. First-party has no forced-tool-vs-thinking\n * restriction (that's Bedrock-only), and \"adaptive\" self-regulates (the model thinks little on\n * trivial/mechanical turns on its own), so there is no reason to special-case forced tool calls.\n * `display:'summarized'` means the reasoning summary is always returned (billed regardless; the\n * host's toggle decides visibility).\n *\n * Fable 5 runs thinking *unconditionally* (it cannot be disabled \u2014 an explicit\n * `{type:'disabled'}` is a 400), so it must never be sent `disabled`; `{type:'adaptive'}`\n * is the accepted posture and is what we return.\n *\n * Every other model (Opus 4.8/4.7, Sonnet 4.6, Haiku) returns undefined \u2192 `thinking` is omitted\n * \u2192 it runs WITHOUT thinking on the chat path (Opus 4.8 adaptive thinking is opt-in). So the older\n * \"forced tool + thinking is incompatible\" restriction never applies to them (you can't hit it when\n * thinking is off). If thinking is ever enabled for one of those, revisit the forced-tool\n * interaction for that model then.\n */\nfunction anthropicThinking(model) {\n if (model !== 'claude-sonnet-5' && model !== 'claude-fable-5')\n return undefined;\n return { type: 'adaptive', display: 'summarized' };\n}\n/**\n * Prompt-cache pricing multipliers, applied to the model's base input rate\n * (`promptPerMillion`) \u2014 https://docs.claude.com/en/docs/build-with-claude/prompt-caching\n * Reads bill at ~0.1\u00D7 base input; writes bill by TTL \u2014 5-minute at ~1.25\u00D7 and 1-hour at 2\u00D7.\n * Both write TTLs are reachable (`CachePolicy.ttl` is `'5m' | '1h'` and `applyCacheControl`\n * emits either), so the cost path costs each TTL bucket from the response's per-TTL\n * `cache_creation` breakdown rather than assuming a single rate.\n */\nconst ANTHROPIC_CACHE_READ_MULTIPLIER = 0.1;\nconst ANTHROPIC_CACHE_WRITE_5M_MULTIPLIER = 1.25;\nconst ANTHROPIC_CACHE_WRITE_1H_MULTIPLIER = 2;\n/**\n * Thrown when a response was cut off at the output-token limit (Anthropic\n * `stop_reason: 'max_tokens'`, Gemini `finishReason: 'MAX_TOKENS'`) in a way\n * that leaves nothing safe to keep. Both transports raise it when the truncated\n * turn carries tool calls: the model ran out of its output-token budget\n * mid-stream, so the cut-off call's arguments are incomplete or untrustworthy\n * (e.g. a `vfs_write` whose `content` never finished serializing) \u2014 rather than\n * hand a corrupt tool call to the caller, which silently runs with missing args\n * and tends to be retried into an identical wall, the failure is loud and\n * diagnosable. The Gemini transport also raises it when truncation leaves no\n * usable answer text (a blank or thinking-only response), which would otherwise\n * be misclassified \u2014 and pointlessly retried \u2014 as an \"empty\" response.\n *\n * It is deterministic: re-issuing the same request hits the same cap. The remedy\n * is to raise the provider's `maxTokens` where configurable (see\n * {@link AnthropicAIConfig.maxTokens}) or to split the work into smaller\n * outputs \u2014 not to retry verbatim.\n *\n * Shared by both transports; it lives here with the transport that introduced it.\n *\n * @beta\n */\nexport class ResponseTruncatedError extends Error {\n constructor(\n /** The model that produced the truncated response. */\n model, \n /**\n * The `max_tokens` cap the request was sent with, when the transport sends\n * one (Anthropic). Undefined when no explicit cap was requested and the\n * model's own output-token limit applied instead (Gemini).\n */\n maxTokens, \n /** Output tokens generated before truncation, when the usage block is present. */\n outputTokens, \n /** Names of the tool call(s) on the truncated turn (the last is the cut-off one). */\n toolNames) {\n super(`Response truncated at ${maxTokens != null ? `the max_tokens cap (${maxTokens})` : \"the model's output-token limit\"} for model ${model}` +\n (toolNames.length > 0 ? ` while emitting tool call(s): ${toolNames.join(', ')}` : '') +\n '. The output exceeds the per-response limit \u2014 raise the provider maxTokens (where configurable) or split the work into smaller outputs.');\n this.model = model;\n this.maxTokens = maxTokens;\n this.outputTokens = outputTokens;\n this.toolNames = toolNames;\n this.name = 'ResponseTruncatedError';\n }\n}\n/**\n * Transport for Anthropic Claude. Calls the Messages API directly when `apiKey`\n * is provided, otherwise falls back to a server-proxy endpoint (if `serverEndpoint`\n * is configured).\n *\n * Implements `AITransport` (structured prompt via tool-forcing) and `ChatTransport`\n * (multi-turn chat).\n *\n * @beta\n */\nexport class AnthropicTransport {\n constructor(config = {}) {\n var _a, _b, _c, _d;\n /**\n * Estimated USD cost accumulated across every successful request on this\n * transport instance. Convenience accessor for non-chat consumers\n * (telemetry, debug overlays). The main chat UI sums per-message `cost`\n * fields instead so its session total stays attributed to chat turns only.\n */\n this.lifetimeCostUsd = 0;\n /**\n * Estimated USD saved by prompt caching vs paying full input price, accumulated across\n * every request. Net of cache-write premiums, so it can be briefly negative before reads\n * accrue. Surfaced alongside `getLifetimeCost`.\n */\n this.lifetimeSavingsUsd = 0;\n const model = (_a = config.model) !== null && _a !== void 0 ? _a : DEFAULT_MODEL;\n assertSupportedAnthropicModel(model);\n this.model = model;\n if (model === 'claude-sonnet-5') {\n logger.warn('AnthropicTransport: using claude-sonnet-5 \u2014 standard Sonnet tier, higher cost than Haiku, and adaptive thinking runs by default so reasoning tokens add to output cost. Use for stronger reasoning or agent tasks.');\n }\n else if (model === 'claude-sonnet-4-6') {\n logger.warn('AnthropicTransport: using claude-sonnet-4-6 \u2014 higher cost than Haiku; use for stronger reasoning or agent tasks.');\n }\n else if (model === 'claude-opus-4-7' || model === 'claude-opus-4-8') {\n logger.warn(`AnthropicTransport: using ${model} \u2014 significantly higher cost; reserve for tasks where Sonnet reliability is insufficient.`);\n }\n else if (model === 'claude-fable-5') {\n logger.warn('AnthropicTransport: using claude-fable-5 \u2014 Anthropic\\'s most capable model, priced above Opus tier ($10 / $50 per MTok) with thinking always on. Reserve for the hardest reasoning/long-horizon work. Requires \u226530-day data retention (unavailable under ZDR) and may return stop_reason \"refusal\"; pair with an Opus 4.8 fallback.');\n }\n this.timeout = (_b = config.timeout) !== null && _b !== void 0 ? _b : DEFAULT_TIMEOUT;\n this.stallTimeout = (_c = config.stallTimeout) !== null && _c !== void 0 ? _c : DEFAULT_STALL_TIMEOUT;\n this.apiKey = config.apiKey;\n this.serverEndpoint = config.serverEndpoint;\n this.maxTokens = (_d = config.maxTokens) !== null && _d !== void 0 ? _d : DEFAULT_MAX_TOKENS;\n }\n getConfig() {\n return {\n provider: 'anthropic',\n model: this.model,\n contextLimit: ANTHROPIC_CONTEXT_LIMITS[this.model],\n };\n }\n /** Estimated USD cost accumulated across every successful request on this transport instance. */\n getLifetimeCost() {\n return this.lifetimeCostUsd;\n }\n /** Estimated USD saved by prompt caching (net of write premiums) across this instance. */\n getLifetimeSavings() {\n return this.lifetimeSavingsUsd;\n }\n /** Reset the lifetime cost + savings counters. Intended for chat-clear / new-session flows. */\n resetLifetimeCost() {\n this.lifetimeCostUsd = 0;\n this.lifetimeSavingsUsd = 0;\n }\n // \u2500\u2500 AITransport (structured prompt) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n sendStructuredPrompt(options) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a, _b, _c;\n const { systemPrompt, userPrompt, responseSchema } = options;\n const messages = [{ role: 'user', content: userPrompt }];\n const body = {\n model: this.model,\n max_tokens: this.maxTokens,\n messages,\n };\n if (systemPrompt)\n body.system = systemPrompt;\n // Prefer native decode-time enforcement (`output_config.format`) where the model supports it \u2014\n // the answer comes back as ordinary text conforming to the schema. On models without native\n // support (Opus 4.7, Sonnet 4.6), fall back to the legacy pattern: a tool whose `input_schema`\n // is the schema, forced via `tool_choice`, with the structured payload read from its `tool_use`.\n const useNative = responseSchema != null && supportsNativeStructuredOutput(this.model);\n const useForcedTool = responseSchema != null && !useNative;\n if (useNative) {\n body.output_config = {\n format: { type: 'json_schema', schema: responseSchema },\n };\n }\n else if (useForcedTool) {\n body.tools = [\n {\n name: STRUCTURED_OUTPUT_TOOL_NAME,\n description: 'Emit the structured response that matches the required schema.',\n input_schema: responseSchema,\n },\n ];\n body.tool_choice = { type: 'tool', name: STRUCTURED_OUTPUT_TOOL_NAME };\n }\n // Sonnet 5 runs adaptive thinking by default; disable it for one-shot prompts \u2014 the reasoning\n // would be billed but discarded. Fable 5 runs thinking unconditionally (cannot be disabled \u2014 a\n // 400), so it is left on; its summary is simply unused here.\n if (this.model === 'claude-sonnet-5')\n body.thinking = { type: 'disabled' };\n const response = yield this.post(body);\n if (useForcedTool) {\n const toolUse = ((_a = response.content) !== null && _a !== void 0 ? _a : []).find((b) => b.type === 'tool_use' && b.name === STRUCTURED_OUTPUT_TOOL_NAME);\n return toolUse ? JSON.stringify((_b = toolUse.input) !== null && _b !== void 0 ? _b : {}) : '';\n }\n // Native structured output and plain prompts both return the answer as text.\n return ((_c = response.content) !== null && _c !== void 0 ? _c : [])\n .filter((b) => b.type === 'text')\n .map((b) => b.text)\n .join('');\n });\n }\n // \u2500\u2500 ChatTransport (multi-turn chat) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n sendChatMessage(history, userMessage, options) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a, _b, _c;\n const messages = this.toAnthropicMessages(history, userMessage, options === null || options === void 0 ? void 0 : options.attachments);\n const body = {\n model: this.model,\n max_tokens: this.maxTokens,\n messages,\n };\n if (options === null || options === void 0 ? void 0 : options.systemPrompt)\n body.system = options.systemPrompt;\n if ((_a = options === null || options === void 0 ? void 0 : options.tools) === null || _a === void 0 ? void 0 : _a.length) {\n body.tools = options.tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.parameters,\n }));\n }\n // Map the requested tool-call mode to Anthropic's tool_choice \u2014 only\n // meaningful when tools exist. `'required'`/`{ tool }` force a tool call so\n // a turn can only end via one (e.g. a sub-agent's completion tool).\n if ((_b = body.tools) === null || _b === void 0 ? void 0 : _b.length) {\n const toolChoice = toAnthropicToolChoice(options === null || options === void 0 ? void 0 : options.toolChoice);\n if (toolChoice)\n body.tool_choice = toolChoice;\n }\n // Extended thinking (Sonnet 5). Always adaptive regardless of `tool_choice` \u2014 first-party has\n // no forced-tool-vs-thinking restriction (that's Bedrock-only) and adaptive self-regulates on\n // mechanical turns. Older models omit it (see `anthropicThinking`).\n const thinking = anthropicThinking(this.model);\n if (thinking)\n body.thinking = thinking;\n // Normalized [0,1] temperature \u2192 Anthropic's native range, anchored so 0.5 maps to its default.\n // (Default == max here, so the upper half is flat.) Skipped on models that reject sampling\n // params (Opus 4.7+ / Sonnet 5), where sending `temperature` is a 400.\n if ((options === null || options === void 0 ? void 0 : options.temperature) != null && !rejectsSamplingParams(this.model)) {\n body.temperature = scaleTemperature(options.temperature, {\n defaultTemp: ANTHROPIC_DEFAULT_TEMPERATURE,\n maxTemp: ANTHROPIC_MAX_TEMPERATURE,\n });\n }\n // Structured output: constrain the final text answer to the caller's JSON schema via\n // decode-time `output_config.format`. Composes with a live `tools` array \u2014 the model still\n // calls tools through the turn and conforms its closing answer to the schema. Applied only on\n // models that support it natively; elsewhere the schema is dropped here (the caller keeps a\n // prompt-instruction + validator fallback). No beta header needed.\n if ((options === null || options === void 0 ? void 0 : options.responseSchema) && supportsNativeStructuredOutput(this.model)) {\n body.output_config = {\n format: { type: 'json_schema', schema: options.responseSchema },\n };\n }\n // Refusal fallback chain (e.g. Fable 5 \u2192 Opus 4.8). Sent as the server-side `fallbacks`\n // param; `post` adds the required beta header when this is present. A refused turn is\n // re-run on the next model in one round trip.\n if ((_c = options === null || options === void 0 ? void 0 : options.fallbacks) === null || _c === void 0 ? void 0 : _c.length) {\n body.fallbacks = options.fallbacks.map((f) => f.maxTokens != null ? { model: f.model, max_tokens: f.maxTokens } : { model: f.model });\n }\n // Place prompt-cache breakpoints per the resolved policy (no-op for `'default'`/absent).\n if (options === null || options === void 0 ? void 0 : options.cachePolicy) {\n this.applyCacheControl(body, options.cachePolicy);\n }\n // Inject never-stored tail context AFTER the cache breakpoints, so this per-turn volatile\n // block stays outside the cached prefix. The caller has already framed it.\n if (options === null || options === void 0 ? void 0 : options.tailContext) {\n this.appendTailContext(body, options.tailContext);\n }\n const response = yield this.post(body, options === null || options === void 0 ? void 0 : options.signal);\n return this.fromAnthropicResponse(response);\n });\n }\n /**\n * Place prompt-cache breakpoints on the outgoing request per the resolved {@link CachePolicy}.\n * A breakpoint is `cache_control: {type:'ephemeral'}` on a content block / tool / system block;\n * the API caches the byte-exact prefix up to it. Below a model's minimum cacheable prefix the\n * marker is silently ignored (no error), so placing one is always safe.\n *\n * Render order is tools \u2192 system \u2192 messages, so a breakpoint's cached prefix covers everything\n * before it:\n * - `'tools'` \u2014 last tool (caches the tool block; survives a later system-prompt change).\n * - `'prompt'` \u2014 system block (caches tools + system); falls back to the last tool when there\n * is no system prompt.\n * - `'history'` \u2014 last stored message block (caches tools + system + the whole stored history),\n * keeping the system-tier breakpoint as a cheaper fallback. The injected, never-stored tail\n * context (if any) sits after this and is intentionally left uncached.\n */\n applyCacheControl(body, policy) {\n var _a, _b;\n if (policy.scope === 'default')\n return;\n const cacheControl = policy.ttl === '1h' ? { type: 'ephemeral', ttl: '1h' } : { type: 'ephemeral' };\n if (policy.scope === 'tools') {\n if ((_a = body.tools) === null || _a === void 0 ? void 0 : _a.length) {\n body.tools[body.tools.length - 1].cache_control = cacheControl;\n }\n return;\n }\n // 'prompt' and 'history' both cache through the system prompt. A breakpoint on the (single)\n // system block caches tools + system together; with no system prompt, fall back to the last\n // tool \u2014 the furthest stable prefix available.\n if (typeof body.system === 'string' && body.system.length > 0) {\n body.system = [{ type: 'text', text: body.system, cache_control: cacheControl }];\n }\n else if ((_b = body.tools) === null || _b === void 0 ? void 0 : _b.length) {\n body.tools[body.tools.length - 1].cache_control = cacheControl;\n }\n if (policy.scope === 'history') {\n const lastMessage = body.messages[body.messages.length - 1];\n if (lastMessage && Array.isArray(lastMessage.content) && lastMessage.content.length > 0) {\n lastMessage.content[lastMessage.content.length - 1].cache_control = cacheControl;\n }\n }\n }\n /**\n * Append never-stored tail context (already framed by the caller) as the final block of the\n * outbound messages. Called AFTER `applyCacheControl`, so any `'history'` breakpoint sits\n * on the last *stored* block and this per-turn volatile block stays outside the cached prefix.\n * At a model-call the last message is user-role; if not (defensive), start a fresh user turn.\n */\n appendTailContext(body, tailContext) {\n const block = { type: 'text', text: tailContext };\n const lastMessage = body.messages[body.messages.length - 1];\n if ((lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) === 'user' && Array.isArray(lastMessage.content)) {\n lastMessage.content.push(block);\n }\n else {\n body.messages.push({ role: 'user', content: [block] });\n }\n }\n /**\n * Logs the per-call cost breakdown, accumulates the lifetime running total,\n * and returns the per-call total so the caller can attach it to the response\n * message.\n */\n logTokenUsage(promptTokens, candidateTokens, cacheReadTokens, cacheCreationTokens, cacheCreation1hTokens) {\n const { promptPerMillion, candidatePerMillion } = estimatedAnthropicRatesUsdPerMillion(this.model);\n const m = AnthropicTransport.TOKENS_PER_MILLION;\n // `promptTokens` is `input_tokens` \u2014 the UNCACHED remainder, billed at the full input\n // rate. Cache reads bill at ~0.1\u00D7. Cache writes bill by TTL \u2014 5-min at ~1.25\u00D7, 1-hour at\n // 2\u00D7 \u2014 so split the creation total into its 1-hour portion (from the response breakdown)\n // and the 5-min remainder, costing each at its own rate. All buckets are off the same base\n // input rate. Summing them keeps the cost correct whether or not caching was active (all\n // cache fields are 0 when it wasn't).\n const cacheCreation5mTokens = Math.max(0, cacheCreationTokens - cacheCreation1hTokens);\n const promptCost = (promptTokens / m) * promptPerMillion;\n const cacheReadCost = (cacheReadTokens / m) * promptPerMillion * ANTHROPIC_CACHE_READ_MULTIPLIER;\n const cacheWriteCost = (cacheCreation5mTokens / m) * promptPerMillion * ANTHROPIC_CACHE_WRITE_5M_MULTIPLIER +\n (cacheCreation1hTokens / m) * promptPerMillion * ANTHROPIC_CACHE_WRITE_1H_MULTIPLIER;\n const candidateCost = (candidateTokens / m) * candidatePerMillion;\n const totalCost = promptCost + cacheReadCost + cacheWriteCost + candidateCost;\n this.lifetimeCostUsd += totalCost;\n // Net savings vs no caching: the cache-read tokens would have cost full input price\n // (we paid ~0.1\u00D7 of that), while the write premium (~0.25\u00D7 over full) is an upfront cost\n // that pays back on later reads \u2014 so the net can dip negative on a write-heavy request and\n // climb positive as reads accrue. Zero when caching was inactive.\n const cacheReadFull = (cacheReadTokens / m) * promptPerMillion;\n const cacheWriteFull = (cacheCreationTokens / m) * promptPerMillion;\n const saved = cacheReadFull - cacheReadCost + (cacheWriteFull - cacheWriteCost);\n this.lifetimeSavingsUsd += saved;\n const dp = AnthropicTransport.COST_DECIMAL_PLACES;\n console.log(`--- Anthropic Token Usage (${this.model}) ---`);\n console.log(`Prompt Tokens: ${promptTokens} ($${promptCost.toFixed(dp)})`);\n console.log(`Cache Read: ${cacheReadTokens} ($${cacheReadCost.toFixed(dp)})`);\n console.log(`Cache Write: ${cacheCreationTokens} ($${cacheWriteCost.toFixed(dp)})`);\n console.log(`Candidate Tokens: ${candidateTokens} ($${candidateCost.toFixed(dp)})`);\n console.log(`Total Cost: $${totalCost.toFixed(dp)}`);\n console.log(`Cache Saved: $${saved.toFixed(dp)} (lifetime $${this.lifetimeSavingsUsd.toFixed(dp)})`);\n console.log(`Lifetime Cost: $${this.lifetimeCostUsd.toFixed(dp)}`);\n console.log('--------------------------');\n return totalCost;\n }\n /**\n * Convert the internal `ChatMessage[]` history into Anthropic's message format.\n *\n * Anthropic alternates strictly `user` / `assistant`. Tool calls are emitted by\n * the assistant as `tool_use` blocks; the corresponding `tool_result` blocks\n * must appear in the *next* user message and reference the tool by `tool_use_id`.\n * Consecutive same-role turns are merged by the API but we merge here to keep\n * the payload tidy.\n */\n toAnthropicMessages(history, userMessage, attachments) {\n var _a, _b, _c;\n const messages = [];\n const pushBlock = (role, block) => {\n const last = messages[messages.length - 1];\n if (last && last.role === role && Array.isArray(last.content)) {\n last.content.push(block);\n return;\n }\n messages.push({ role, content: [block] });\n };\n for (const msg of history) {\n if (msg.role === 'system' ||\n msg.role === 'system-event' ||\n msg.role === 'synthetic-user' ||\n msg.role === 'compacted-summary' ||\n msg.category === 'reasoning' ||\n msg.category === 'narration' ||\n msg.thinking // legacy pre-split sessions\n )\n continue;\n if (msg.toolResult) {\n pushBlock('user', {\n type: 'tool_result',\n tool_use_id: msg.toolResult.toolCallId,\n content: msg.toolResult.content,\n });\n continue;\n }\n if ((_a = msg.toolCalls) === null || _a === void 0 ? void 0 : _a.length) {\n if (msg.content) {\n pushBlock('assistant', { type: 'text', text: msg.content });\n }\n for (const tc of msg.toolCalls) {\n pushBlock('assistant', {\n type: 'tool_use',\n id: tc.id,\n name: tc.name,\n input: (_b = tc.args) !== null && _b !== void 0 ? _b : {},\n });\n }\n continue;\n }\n const role = msg.role === 'user' ? 'user' : 'assistant';\n if (role === 'user' && ((_c = msg.attachments) === null || _c === void 0 ? void 0 : _c.length)) {\n pushBlock(role, { type: 'text', text: msg.content });\n for (const att of msg.attachments) {\n pushBlock(role, { type: 'text', text: `[File: ${att.name}]\\n${att.content}` });\n }\n }\n else if (msg.content) {\n pushBlock(role, { type: 'text', text: msg.content });\n }\n }\n if (userMessage || (attachments === null || attachments === void 0 ? void 0 : attachments.length)) {\n if (userMessage) {\n pushBlock('user', { type: 'text', text: userMessage });\n }\n for (const att of attachments !== null && attachments !== void 0 ? attachments : []) {\n pushBlock('user', { type: 'text', text: `[File: ${att.name}]\\n${att.content}` });\n }\n }\n return messages;\n }\n fromAnthropicResponse(response) {\n var _a, _b, _c, _d, _e, _f, _g, _h;\n let inputTokens;\n let outputTokens;\n let cacheReadTokens;\n let cacheWriteTokens;\n let cost;\n if (response.usage) {\n const uncachedInput = (_a = response.usage.input_tokens) !== null && _a !== void 0 ? _a : 0;\n const cacheRead = (_b = response.usage.cache_read_input_tokens) !== null && _b !== void 0 ? _b : 0;\n // 1-hour writes bill at 2\u00D7 vs 1.25\u00D7 for 5-min, so read the per-TTL breakdown when present\n // and let the cost path split the buckets. Fall back to the flat total (treated as 5-min)\n // when the breakdown is absent.\n const breakdown = response.usage.cache_creation;\n const cacheCreation1h = (_c = breakdown === null || breakdown === void 0 ? void 0 : breakdown.ephemeral_1h_input_tokens) !== null && _c !== void 0 ? _c : 0;\n const cacheCreation = (_d = response.usage.cache_creation_input_tokens) !== null && _d !== void 0 ? _d : (breakdown ? ((_e = breakdown.ephemeral_5m_input_tokens) !== null && _e !== void 0 ? _e : 0) + cacheCreation1h : 0);\n cost = this.logTokenUsage(uncachedInput, (_f = response.usage.output_tokens) !== null && _f !== void 0 ? _f : 0, cacheRead, cacheCreation, cacheCreation1h);\n // Report TOTAL prompt size (uncached + cache read + cache write) so `inputTokens` means\n // \"prompt tokens\" consistently whether or not caching was active \u2014 matching Gemini's\n // `promptTokenCount`, which already includes cached tokens. Cost (above) reflects the\n // cache discount; this field is the size, not the bill.\n inputTokens = uncachedInput + cacheRead + cacheCreation;\n // The two cache buckets BREAK DOWN the prompt total above rather than adding\n // to it, so a consumer derives uncached input by subtracting them. Reported\n // even when zero: \"this provider measured the split and it was 0\" is distinct\n // from \"this provider reports no split at all\" (undefined).\n cacheReadTokens = cacheRead;\n cacheWriteTokens = cacheCreation;\n if (response.usage.output_tokens != null) {\n outputTokens = response.usage.output_tokens;\n }\n }\n const blocks = (_g = response.content) !== null && _g !== void 0 ? _g : [];\n const toolCalls = [];\n const thoughtParts = [];\n const textParts = [];\n for (const block of blocks) {\n if (block.type === 'tool_use') {\n toolCalls.push({\n id: block.id,\n name: block.name,\n args: (_h = block.input) !== null && _h !== void 0 ? _h : {},\n });\n }\n else if (block.type === 'thinking') {\n thoughtParts.push(block.thinking);\n }\n else if (block.type === 'text') {\n textParts.push(block.text);\n }\n }\n // A `max_tokens` stop means the response was cut off mid-stream. For a turn\n // carrying tool calls this is fatal: the final tool call's argument JSON was\n // truncated before it closed, so its args are incomplete and the call cannot\n // be run. Raise rather than return a corrupt tool call (which would run with\n // missing args and get retried into the same wall). Usage/cost is already\n // logged above, so the spent tokens are still accounted for on this instance.\n if (response.stop_reason === 'max_tokens' && toolCalls.length > 0) {\n throw new ResponseTruncatedError(this.model, this.maxTokens, outputTokens, toolCalls.map((tc) => tc.name));\n }\n // Reasoning (extended-thinking summary) and answer/narration travel in separate channels:\n // `content` is the answer text, `reasoning` is the summary. The driver splits them into\n // separate category-tagged messages. (Previously `thoughtParts.join('') || textParts.join('')`\n // put reasoning in `content` and DROPPED the answer text whenever thinking was present.)\n const reasoning = thoughtParts.join('') || undefined;\n const base = toolCalls.length > 0\n ? { role: 'assistant', content: textParts.join(''), reasoning, toolCalls }\n : { role: 'assistant', content: textParts.join(''), reasoning };\n if (inputTokens != null)\n base.inputTokens = inputTokens;\n if (outputTokens != null)\n base.outputTokens = outputTokens;\n if (cacheReadTokens != null)\n base.cacheReadTokens = cacheReadTokens;\n if (cacheWriteTokens != null)\n base.cacheWriteTokens = cacheWriteTokens;\n if (cost != null)\n base.cost = cost;\n // Surface a non-standard stop reason for observability and parity with the\n // Gemini transport's `responseMeta.finishReason`. A text-only `max_tokens`\n // stop yields partial-but-legible content, so it is returned (not raised) with\n // the truncation flagged \u2014 the caller can decide what to do with it.\n if (response.stop_reason === 'max_tokens') {\n base.responseMeta = { finishReason: 'max_tokens' };\n }\n // A `refusal` stop means safety classifiers declined the request (Fable 5 and other\n // recent models). Content is empty (pre-output) or partial (mid-stream) \u2014 return it\n // rather than crash on an assumed non-empty block, and flag the reason so the driver\n // (or a server-side `fallbacks` chain) can respond deterministically instead of\n // retrying into the same wall. Usage/cost is already logged above.\n if (response.stop_reason === 'refusal') {\n base.responseMeta = { finishReason: 'refusal' };\n }\n return base;\n }\n buildEndpoint() {\n if (this.apiKey) {\n return {\n url: ANTHROPIC_DIRECT_URL,\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n 'anthropic-version': ANTHROPIC_API_VERSION,\n // Anthropic blocks browser-origin requests by default. This header is the\n // documented opt-in (equivalent to the SDK's `dangerouslyAllowBrowser`).\n 'anthropic-dangerous-direct-browser-access': 'true',\n },\n credentials: 'omit',\n };\n }\n if (this.serverEndpoint) {\n return {\n url: this.serverEndpoint,\n // Opt in to the proxy's NDJSON heartbeat framing. An old proxy ignores\n // this and returns plain JSON \u2014 see the Content-Type branch in `post`.\n headers: { 'Content-Type': 'application/json', Accept: 'application/x-ndjson' },\n credentials: 'include',\n };\n }\n throw new Error('AnthropicTransport: no API key or server endpoint configured. ' +\n 'Set ANTHROPIC_API_KEY in your .env or pass apiKey/serverEndpoint in AnthropicAIConfig.');\n }\n post(body, signal) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a;\n const { url, headers, credentials } = this.buildEndpoint();\n // The server-side `fallbacks` param is gated behind a beta flag; add it per-request only\n // when a fallback chain is set (the param without the header is a 400, and vice-versa is fine).\n const requestHeaders = ((_a = body.fallbacks) === null || _a === void 0 ? void 0 : _a.length)\n ? Object.assign(Object.assign({}, headers), { 'anthropic-beta': [headers['anthropic-beta'], SERVER_SIDE_FALLBACK_BETA]\n .filter(Boolean)\n .join(',') }) : headers;\n return (yield postWithRetry({\n url,\n headers: requestHeaders,\n body,\n credentials,\n vendorLabel: VENDOR_LABELS.anthropic,\n retryableStatuses: AnthropicTransport.RETRYABLE_STATUSES,\n timeout: this.timeout,\n stallTimeout: this.stallTimeout,\n backoffBaseMs: AnthropicTransport.BACKOFF_BASE_MS,\n signal,\n }));\n });\n }\n}\n// \u2500\u2500 Private helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nAnthropicTransport.TOKENS_PER_MILLION = 1000000;\nAnthropicTransport.COST_DECIMAL_PLACES = 6;\nAnthropicTransport.RATE_LIMIT_STATUS = 429;\nAnthropicTransport.SERVICE_UNAVAILABLE_STATUS = 503;\nAnthropicTransport.OVERLOADED_STATUS = 529;\nAnthropicTransport.RETRYABLE_STATUSES = [\n AnthropicTransport.RATE_LIMIT_STATUS,\n AnthropicTransport.SERVICE_UNAVAILABLE_STATUS,\n AnthropicTransport.OVERLOADED_STATUS,\n];\n// Base backoff for the shared retry ladder (1s, 2s, 4s, 8s, 16s).\nAnthropicTransport.BACKOFF_BASE_MS = 1000;\n", "// \u2500\u2500 MALFORMED_FUNCTION_CALL repair \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Gemini occasionally returns `finishReason: \"MALFORMED_FUNCTION_CALL\"` when it\n// has actually produced a complete, correct tool call but serialised it as a\n// Python statement instead of the API's structured format, e.g.\n//\n// print(default_api.vfs_edit(new_string = \"\u2026\", old_string = \"\u2026\", path = \"\u2026\", replace_all = true))\n//\n// The intended call is fully present in `candidates[0].finishMessage`. Rather\n// than throw and burn a ChatDriver retry (a full re-roll that may regenerate\n// something worse, or malform again), we parse the call back out and hand it to\n// the transport as a normal structured tool call \u2014 unwrapping a wrong envelope,\n// not guessing. The parser is deliberately fail-closed: on ANY ambiguity it\n// returns null and the transport falls back to throwing\n// `MalformedFunctionCallError`, leaving today's retry behaviour unchanged. It\n// never returns a half-parsed call.\nconst MALFORMED_CALL_ANCHOR = 'default_api.';\nconst PRINT_WRAPPER_RE = /print\\(\\s*$/;\nconst UNICODE_ESCAPE_DIGITS = 4;\nconst HEX_ESCAPE_DIGITS = 2;\nconst HEX_RADIX = 16;\n/**\n * Recursive-descent scanner for a single Python-style `default_api.<tool>(...)`\n * call. Walks the string character by character so that delimiters (commas,\n * parens, quotes, brackets, newlines) appearing *inside* string-literal\n * arguments don't prematurely terminate parsing. Throws on the first unexpected\n * token; callers treat any throw as \"not confidently parseable\".\n */\nclass MalformedFunctionCallParser {\n constructor(src) {\n this.src = src;\n this.pos = 0;\n }\n parse() {\n const anchor = this.src.indexOf(MALFORMED_CALL_ANCHOR);\n if (anchor === -1)\n this.bail();\n // Tolerate an enclosing `print(` wrapper (the observed Python form) or a\n // bare call. Any other preamble (e.g. \"Malformed function call: \") is\n // ignored \u2014 we only anchor on `default_api.`.\n const wrapped = PRINT_WRAPPER_RE.test(this.src.slice(0, anchor));\n this.pos = anchor;\n const call = this.parseCall();\n this.skipWhitespace();\n if (wrapped) {\n this.expect(')');\n this.skipWhitespace();\n }\n // Strict: nothing may follow the call. In particular a second\n // `default_api.` (batched calls) bails rather than silently dropping work.\n if (this.pos !== this.src.length)\n this.bail();\n return call;\n }\n parseCall() {\n this.expectLiteral(MALFORMED_CALL_ANCHOR);\n const name = this.readIdentifier();\n this.expect('(');\n const args = this.parseKwargs();\n this.expect(')');\n return { name, args };\n }\n parseKwargs() {\n const args = {};\n for (;;) {\n this.skipWhitespace();\n // Empty arg list, or a tolerated trailing comma before the closing paren.\n if (this.peek() === ')')\n break;\n const key = this.readIdentifier();\n this.skipWhitespace();\n this.expect('=');\n this.skipWhitespace();\n const value = this.parseValue();\n if (Object.prototype.hasOwnProperty.call(args, key))\n this.bail();\n args[key] = value;\n this.skipWhitespace();\n const next = this.peek();\n if (next === ',') {\n this.pos += 1;\n continue;\n }\n if (next === ')')\n break;\n this.bail();\n }\n return args;\n }\n parseValue() {\n const ch = this.peek();\n if (ch === '\"' || ch === \"'\")\n return this.readString();\n if (ch === '-' || ch === '+' || this.isDigit(ch))\n return this.readNumber();\n if (/[A-Za-z]/.test(ch))\n return this.readBareword();\n // Unhandled value form (e.g. a list `[\u2026]` or dict `{\u2026}`) \u2014 bail.\n return this.bail();\n }\n readString() {\n const quote = this.src[this.pos];\n this.pos += 1; // opening quote\n let out = '';\n for (;;) {\n if (this.pos >= this.src.length)\n this.bail(); // unterminated \u2192 truncation guard\n const c = this.src[this.pos];\n this.pos += 1;\n if (c === quote)\n return out; // closing quote\n if (c === '\\\\') {\n out += this.readEscape();\n continue;\n }\n out += c;\n }\n }\n readEscape() {\n if (this.pos >= this.src.length)\n this.bail();\n const e = this.src[this.pos];\n this.pos += 1;\n switch (e) {\n case 'n':\n return '\\n';\n case 't':\n return '\\t';\n case 'r':\n return '\\r';\n case 'b':\n return '\\b';\n case 'f':\n return '\\f';\n case '\\\\':\n return '\\\\';\n case '\"':\n return '\"';\n case \"'\":\n return \"'\";\n case '/':\n return '/';\n case 'u':\n return this.readHexCodepoint(UNICODE_ESCAPE_DIGITS);\n case 'x':\n return this.readHexCodepoint(HEX_ESCAPE_DIGITS);\n default:\n // Unknown escape \u2014 refuse rather than risk a silent mis-decode.\n return this.bail();\n }\n }\n readHexCodepoint(digits) {\n const hex = this.src.slice(this.pos, this.pos + digits);\n if (hex.length !== digits || !/^[0-9a-fA-F]+$/.test(hex))\n this.bail();\n this.pos += digits;\n return String.fromCharCode(parseInt(hex, HEX_RADIX));\n }\n readNumber() {\n const start = this.pos;\n if (this.peek() === '-' || this.peek() === '+')\n this.pos += 1;\n while (this.pos < this.src.length && /[0-9.eE+-]/.test(this.src[this.pos])) {\n this.pos += 1;\n }\n const value = Number(this.src.slice(start, this.pos));\n if (!Number.isFinite(value))\n this.bail();\n return value;\n }\n readBareword() {\n const word = this.readIdentifier();\n switch (word) {\n case 'true':\n case 'True':\n return true;\n case 'false':\n case 'False':\n return false;\n // Python serialises an omitted/optional kwarg as `None` (and sometimes a\n // JSON-ish `null`); decode both to `null` rather than bailing the whole call.\n case 'null':\n case 'None':\n return null;\n default:\n return this.bail();\n }\n }\n readIdentifier() {\n const start = this.pos;\n if (!/[A-Za-z_]/.test(this.peek()))\n this.bail();\n while (this.pos < this.src.length && /[A-Za-z0-9_]/.test(this.src[this.pos])) {\n this.pos += 1;\n }\n return this.src.slice(start, this.pos);\n }\n isDigit(ch) {\n return ch >= '0' && ch <= '9';\n }\n peek() {\n return this.pos < this.src.length ? this.src[this.pos] : '';\n }\n skipWhitespace() {\n while (this.pos < this.src.length && /\\s/.test(this.src[this.pos])) {\n this.pos += 1;\n }\n }\n expect(ch) {\n if (this.src[this.pos] !== ch)\n this.bail();\n this.pos += 1;\n }\n expectLiteral(literal) {\n if (this.src.slice(this.pos, this.pos + literal.length) !== literal)\n this.bail();\n this.pos += literal.length;\n }\n bail() {\n throw new Error('MalformedFunctionCallParser: unexpected token');\n }\n}\n/**\n * Attempts to recover a structured tool call from a Gemini\n * `MALFORMED_FUNCTION_CALL` `finishMessage`. Returns the parsed call only when\n * it parses cleanly AND its tool name is one of the offered tools; otherwise\n * returns null so the caller can fall back to the existing retry path.\n */\nexport function repairMalformedFunctionCall(finishMessage, offeredToolNames) {\n if (!finishMessage)\n return null;\n let call;\n try {\n call = new MalformedFunctionCallParser(finishMessage).parse();\n }\n catch (_a) {\n return null;\n }\n if (!offeredToolNames.has(call.name))\n return null;\n return call;\n}\n", "import { __awaiter } from \"tslib\";\nimport { SUPPORTED_GEMINI_MODEL_IDS, } from '../types';\nimport { logger } from '../utils/logger';\nimport { scaleTemperature } from '../utils/temperature';\nimport { ResponseTruncatedError } from './anthropic-transport';\nimport { VENDOR_LABELS } from './budget-exhausted-error';\nimport { repairMalformedFunctionCall } from './gemini-malformed-call';\nimport { postWithRetry } from './post-with-retry';\nconst GEMINI_DIRECT_URL = (model) => `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent`;\nconst DEFAULT_MODEL = 'gemini-2.5-flash-lite';\nconst DEFAULT_TIMEOUT = 300000; // healthy >200s generations observed at 128k max_tokens; wall clock is a last resort\nconst DEFAULT_STALL_TIMEOUT = 30000; // inactivity window on the framed proxy path; pings arrive every 5s\n/**\n * Maximum input context window (tokens) per supported Gemini model.\n * Source: https://ai.google.dev/gemini-api/docs/models\n */\nconst GEMINI_CONTEXT_LIMITS = {\n 'gemini-2.5-pro': 1048576,\n 'gemini-2.5-flash': 1048576,\n 'gemini-2.5-flash-lite': 1048576,\n 'gemini-3.5-flash': 1048576,\n 'gemini-3.1-flash-lite': 1048576,\n 'gemini-3.1-pro-preview': 1048576,\n};\n/** Gemini's native default + ceiling temperature \u2014 https://ai.google.dev/gemini-api/docs */\nconst GEMINI_DEFAULT_TEMPERATURE = 1;\nconst GEMINI_MAX_TEMPERATURE = 2;\n/**\n * Map a provider-agnostic {@link ChatToolChoice} to Gemini's `toolConfig`.\n * Returns undefined for the default (`'auto'`) so the request omits the field.\n */\nfunction toGeminiToolConfig(choice) {\n if (!choice || choice === 'auto')\n return undefined;\n if (choice === 'required')\n return { functionCallingConfig: { mode: 'ANY' } };\n if (choice === 'none')\n return { functionCallingConfig: { mode: 'NONE' } };\n return { functionCallingConfig: { mode: 'ANY', allowedFunctionNames: [choice.tool] } };\n}\nfunction assertSupportedGeminiModel(model) {\n if (!SUPPORTED_GEMINI_MODEL_IDS.includes(model)) {\n throw new Error(`GeminiTransport: unsupported model \"${model}\". Use one of: ${SUPPORTED_GEMINI_MODEL_IDS.join(', ')}.`);\n }\n}\n/**\n * Prompt size (tokens) at or below which the standard pricing tier applies.\n * Above it, Gemini's long-context tier kicks in. Google applies a single tier\n * to the whole request based on prompt size \u2014 it is not a marginal/blended rate.\n */\nconst GEMINI_LONG_CONTEXT_THRESHOLD = 200000;\n/**\n * Cached / context-cache input tokens bill at a flat ~10% of the model's normal input\n * rate \u2014 consistent across models (flash $0.30\u2192$0.03, flash-lite $0.10\u2192$0.01,\n * pro $1.25\u2192$0.125). Source: https://ai.google.dev/gemini-api/docs/pricing.\n * (Explicit context caching also has an hourly storage fee; implicit caching \u2014 what we\n * rely on \u2014 has none, so only this read discount applies.)\n */\nconst GEMINI_CACHED_INPUT_MULTIPLIER = 0.1;\n/**\n * Paid Standard tier rates (USD per million tokens) \u2014 https://ai.google.dev/gemini-api/docs/pricing\n */\nconst GEMINI_PRICING = {\n 'gemini-2.5-flash-lite': {\n kind: 'flat',\n rate: { promptPerMillion: 0.1, candidatePerMillion: 0.4 },\n },\n 'gemini-2.5-flash': { kind: 'flat', rate: { promptPerMillion: 0.3, candidatePerMillion: 2.5 } },\n 'gemini-2.5-pro': {\n kind: 'tiered',\n standard: { promptPerMillion: 1.25, candidatePerMillion: 10.0 },\n longContext: { promptPerMillion: 2.5, candidatePerMillion: 15.0 },\n },\n 'gemini-3.1-flash-lite': {\n kind: 'flat',\n rate: { promptPerMillion: 0.25, candidatePerMillion: 1.5 },\n },\n 'gemini-3.5-flash': { kind: 'flat', rate: { promptPerMillion: 1.5, candidatePerMillion: 9.0 } },\n 'gemini-3.1-pro-preview': {\n kind: 'tiered',\n standard: { promptPerMillion: 2.0, candidatePerMillion: 12.0 },\n longContext: { promptPerMillion: 4.0, candidatePerMillion: 18.0 },\n },\n};\n/**\n * Resolves the per-million-token rates for a model given the request's prompt\n * size, selecting the long-context tier for tiered models when the prompt\n * exceeds {@link GEMINI_LONG_CONTEXT_THRESHOLD}.\n */\nfunction estimatedGeminiPaidRatesUsdPerMillion(model, promptTokens) {\n const pricing = GEMINI_PRICING[model];\n if (pricing.kind === 'flat') {\n return pricing.rate;\n }\n return promptTokens > GEMINI_LONG_CONTEXT_THRESHOLD ? pricing.longContext : pricing.standard;\n}\n/**\n * Per-model warnings emitted on construction. flash-lite tiers are the cheap\n * default and warn-free; higher-cost, frontier, and preview models flag their\n * trade-offs so callers don't pick them by accident.\n */\nconst GEMINI_MODEL_WARNINGS = {\n 'gemini-2.5-flash': 'GeminiTransport: using gemini-2.5-flash \u2014 higher cost than flash-lite; use for harder reasoning or agent tasks.',\n 'gemini-2.5-pro': 'GeminiTransport: using gemini-2.5-pro \u2014 significantly higher, prompt-size-tiered cost; reserve for tasks where flash reliability is insufficient.',\n 'gemini-3.5-flash': 'GeminiTransport: using gemini-3.5-flash \u2014 frontier model, materially higher cost than flash-lite; use for harder reasoning or agent tasks.',\n 'gemini-3.1-pro-preview': 'GeminiTransport: using gemini-3.1-pro-preview \u2014 PREVIEW model (no stability guarantee, may be withdrawn) with significantly higher, prompt-size-tiered cost; reserve for tasks where flash reliability is insufficient.',\n};\n/**\n * Token accepted by the Gemini 3 API in place of a real `thoughtSignature` to\n * skip signature validation. Used when replaying a tool call whose signature\n * belongs to a different model (a mid-execution model switch) or was never\n * captured: the step's first function call still needs *a* signature to pass\n * validation, but a foreign signature can't be honoured.\n * Source: https://ai.google.dev/gemini-api/docs/thought-signatures\n */\nconst SKIP_SIGNATURE = 'skip_thought_signature_validator';\n/**\n * Key under which this transport stashes its round-trip state on a tool call's\n * provider-neutral `providerMetadata` bag. Private to GeminiTransport.\n */\nconst GEMINI_PROVIDER_KEY = 'gemini';\n/**\n * Thrown when Gemini returns a `MALFORMED_FUNCTION_CALL` finish reason,\n * typically because the model tried to batch multiple tool calls using\n * Python-style syntax instead of the proper API format.\n *\n * @beta\n */\nexport class MalformedFunctionCallError extends Error {\n constructor(finishMessage) {\n super('Gemini returned MALFORMED_FUNCTION_CALL');\n this.finishMessage = finishMessage;\n this.name = 'MalformedFunctionCallError';\n }\n}\n/**\n * Transport for Gemini. Calls the Gemini REST API directly when `apiKey` is\n * provided, otherwise falls back to a server-proxy endpoint (if `serverEndpoint`\n * is configured).\n *\n * Implements `AITransport` (structured prompt) and `ChatTransport` (multi-turn chat).\n *\n * @beta\n */\nexport class GeminiTransport {\n constructor(config = {}) {\n var _a, _b, _c;\n /**\n * Estimated USD cost accumulated across every successful request on this\n * transport instance. Convenience accessor for non-chat consumers\n * (telemetry, debug overlays). The main chat UI sums per-message `cost`\n * fields instead so its session total stays attributed to chat turns only.\n */\n this.lifetimeCostUsd = 0;\n /**\n * Estimated USD saved by context caching vs paying full input price, accumulated across\n * every request. Gemini implicit caching has no write premium, so this is always \u2265 0.\n * Surfaced alongside `getLifetimeCost`.\n */\n this.lifetimeSavingsUsd = 0;\n const model = (_a = config.model) !== null && _a !== void 0 ? _a : DEFAULT_MODEL;\n assertSupportedGeminiModel(model);\n this.model = model;\n const warning = GEMINI_MODEL_WARNINGS[model];\n if (warning) {\n logger.warn(warning);\n }\n this.timeout = (_b = config.timeout) !== null && _b !== void 0 ? _b : DEFAULT_TIMEOUT;\n this.stallTimeout = (_c = config.stallTimeout) !== null && _c !== void 0 ? _c : DEFAULT_STALL_TIMEOUT;\n this.apiKey = config.apiKey;\n this.serverEndpoint = config.serverEndpoint;\n }\n getConfig() {\n return {\n provider: 'gemini',\n model: this.model,\n contextLimit: GEMINI_CONTEXT_LIMITS[this.model],\n };\n }\n /** Estimated USD cost accumulated across every successful request on this transport instance. */\n getLifetimeCost() {\n return this.lifetimeCostUsd;\n }\n /** Estimated USD saved by context caching across this instance (implicit caching \u2192 always \u2265 0). */\n getLifetimeSavings() {\n return this.lifetimeSavingsUsd;\n }\n /** Reset the lifetime cost + savings counters. Intended for chat-clear / new-session flows. */\n resetLifetimeCost() {\n this.lifetimeCostUsd = 0;\n this.lifetimeSavingsUsd = 0;\n }\n // \u2500\u2500 AITransport (structured prompt) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n sendStructuredPrompt(options) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a;\n const { systemPrompt, userPrompt, responseSchema } = options;\n const contents = [];\n if (systemPrompt) {\n contents.push({ role: 'user', parts: [{ text: systemPrompt }] });\n contents.push({ role: 'model', parts: [{ text: 'Understood.' }] });\n }\n contents.push({ role: 'user', parts: [{ text: userPrompt }] });\n const response = yield this.post({ model: this.model, contents, responseSchema });\n return (_a = response === null || response === void 0 ? void 0 : response.content) !== null && _a !== void 0 ? _a : '';\n });\n }\n // \u2500\u2500 ChatTransport (multi-turn chat) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n sendChatMessage(history, userMessage, options) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a, _b;\n // NOTE: `options.cachePolicy` is intentionally NOT read here. Gemini 2.5+ does *implicit*\n // caching automatically and always-on \u2014 it caches as much of the stable request prefix as it\n // can on every call, regardless of the policy's `scope` (including `'default'`). We issue no\n // explicit `cachedContent`, so there is no request-side field to set; the only lever is\n // keeping the prefix byte-stable (a consumer concern). The cached tokens that come back are\n // priced in `logTokenUsage` via `cachedContentTokenCount`. See `CachePolicy` docs.\n const contents = this.toGeminiContents(history, userMessage, options === null || options === void 0 ? void 0 : options.attachments);\n // Never-stored tail context as a trailing user content (after the stable prefix). Verified\n // valid even directly after a functionResponse content. The caller has already framed it.\n if (options === null || options === void 0 ? void 0 : options.tailContext) {\n contents.push({ role: 'user', parts: [{ text: options.tailContext }] });\n }\n const tools = ((_a = options === null || options === void 0 ? void 0 : options.tools) === null || _a === void 0 ? void 0 : _a.length)\n ? [\n {\n functionDeclarations: options.tools.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n })),\n },\n ]\n : undefined;\n const systemInstruction = (options === null || options === void 0 ? void 0 : options.systemPrompt)\n ? { role: 'system', parts: [{ text: options.systemPrompt }] }\n : undefined;\n // Map the requested tool-call mode to Gemini's toolConfig \u2014 only meaningful\n // when functions are declared. NOTE: forcing (`ANY` / allowedFunctionNames)\n // can make the model batch calls in Python-ish syntax \u2192\n // `MALFORMED_FUNCTION_CALL`, which `fromGeminiResponse` repairs in place when\n // it can confidently parse the call (see `repairMalformedFunctionCall`),\n // falling back to the caller's retry otherwise.\n const toolConfig = tools ? toGeminiToolConfig(options === null || options === void 0 ? void 0 : options.toolChoice) : undefined;\n // Request thought summaries so the model's official reasoning is returned\n // (and a thinking-only turn surfaces *something* rather than going silently\n // blank). Gemini 2.5 Pro always thinks regardless, so this only changes what\n // is RETURNED, not what is billed \u2014 see `logTokenUsage` for the thinking-token\n // accounting it lets us finally capture.\n const generationConfig = { thinkingConfig: { includeThoughts: true } };\n // Normalized [0,1] temperature \u2192 Gemini's native range, anchored so 0.5\n // maps to its default (native 1) and 1 to its ceiling (native 2).\n if ((options === null || options === void 0 ? void 0 : options.temperature) != null) {\n generationConfig.temperature = scaleTemperature(options.temperature, {\n defaultTemp: GEMINI_DEFAULT_TEMPERATURE,\n maxTemp: GEMINI_MAX_TEMPERATURE,\n });\n }\n // Names of the tools offered this turn \u2014 used to validate a repaired\n // malformed call against the real tool surface before accepting it.\n const offeredToolNames = new Set(((_b = options === null || options === void 0 ? void 0 : options.tools) !== null && _b !== void 0 ? _b : []).map((t) => t.name));\n // Structured output (native JSON mode). Gemini 3 can combine it with function calling;\n // Gemini 2.x cannot, so on 2.x apply the schema only on a pure structured turn (no tools) and\n // otherwise drop it (the caller keeps a prompt-instruction + validator fallback). Passed as a\n // top-level `responseSchema` that `toDirectPayload` maps to `generationConfig.responseMimeType`\n // + `responseSchema` on the direct path (the proxy forwards it).\n const schemaCoexistsWithTools = this.model.startsWith('gemini-3');\n const applyResponseSchema = (options === null || options === void 0 ? void 0 : options.responseSchema) != null && (!tools || schemaCoexistsWithTools);\n const response = yield this.post(Object.assign({ model: this.model, contents,\n tools,\n systemInstruction,\n toolConfig,\n generationConfig }, (applyResponseSchema ? { responseSchema: options.responseSchema } : {})), options === null || options === void 0 ? void 0 : options.signal);\n return this.fromGeminiResponse(response, offeredToolNames);\n });\n }\n /**\n * Logs the per-call cost breakdown, accumulates the lifetime running total,\n * and returns the per-call total so the caller can attach it to the response\n * message.\n */\n logTokenUsage(promptTokens, candidateTokens, thoughtTokens, cachedTokens) {\n const { promptPerMillion, candidatePerMillion } = estimatedGeminiPaidRatesUsdPerMillion(this.model, promptTokens);\n const m = GeminiTransport.TOKENS_PER_MILLION;\n // `promptTokenCount` INCLUDES the cached portion (opposite of Anthropic's `input_tokens`),\n // so split it: the uncached remainder bills at the full input rate and the cached slice at\n // ~0.1\u00D7. The pricing TIER is still chosen on the full prompt size (above). `cachedTokens`\n // is 0 when caching wasn't active, so this is a no-op then.\n const uncachedPromptTokens = Math.max(0, promptTokens - cachedTokens);\n const promptCost = (uncachedPromptTokens / m) * promptPerMillion;\n const cacheReadCost = (cachedTokens / m) * promptPerMillion * GEMINI_CACHED_INPUT_MULTIPLIER;\n // Thinking tokens are billed at the output (candidate) rate. They are\n // incurred whenever the model thinks (always, on 2.5 Pro) \u2014 counting them\n // here corrects a long-standing undercount, it does not raise the bill.\n const candidateCost = ((candidateTokens + thoughtTokens) / m) * candidatePerMillion;\n const totalCost = promptCost + cacheReadCost + candidateCost;\n this.lifetimeCostUsd += totalCost;\n // Savings vs no caching: the cached tokens would have cost full input price; we paid ~0.1\u00D7.\n // Implicit caching has no write premium, so this is always \u2265 0.\n const saved = (cachedTokens / m) * promptPerMillion - cacheReadCost;\n this.lifetimeSavingsUsd += saved;\n const dp = GeminiTransport.COST_DECIMAL_PLACES;\n console.log(`--- Gemini Token Usage (${this.model}) ---`);\n console.log(`Prompt Tokens: ${promptTokens} (${cachedTokens} cached) ($${promptCost.toFixed(dp)} + $${cacheReadCost.toFixed(dp)})`);\n console.log(`Candidate Tokens: ${candidateTokens} (+${thoughtTokens} thinking) ($${candidateCost.toFixed(dp)})`);\n console.log(`Total Cost: $${totalCost.toFixed(dp)}`);\n console.log(`Cache Saved: $${saved.toFixed(dp)} (lifetime $${this.lifetimeSavingsUsd.toFixed(dp)})`);\n console.log(`Lifetime Cost: $${this.lifetimeCostUsd.toFixed(dp)}`);\n console.log('--------------------------');\n return totalCost;\n }\n toGeminiContents(history, userMessage, attachments) {\n var _a, _b, _c;\n const contents = [];\n // Gemini requires functionResponse.name to match the original functionCall.name.\n // Our internal IDs are UUIDs, so build a lookup from ID \u2192 function name as we go.\n const toolCallNameById = new Map();\n for (const msg of history) {\n if (msg.role === 'system' ||\n msg.role === 'system-event' ||\n msg.role === 'synthetic-user' ||\n msg.role === 'compacted-summary' ||\n msg.category === 'reasoning' ||\n msg.category === 'narration' ||\n msg.thinking // legacy pre-split sessions\n )\n continue;\n const role = msg.role === 'user' ? 'user' : 'model';\n if (msg.toolResult) {\n const fnName = (_a = toolCallNameById.get(msg.toolResult.toolCallId)) !== null && _a !== void 0 ? _a : msg.toolResult.toolCallId;\n contents.push({\n role: 'user',\n parts: [\n {\n functionResponse: {\n name: fnName,\n response: { content: msg.toolResult.content },\n },\n },\n ],\n });\n }\n else if ((_b = msg.toolCalls) === null || _b === void 0 ? void 0 : _b.length) {\n for (const tc of msg.toolCalls) {\n toolCallNameById.set(tc.id, tc.name);\n }\n contents.push({\n role: 'model',\n parts: msg.toolCalls.map((tc, i) => {\n var _a;\n const part = { functionCall: { name: tc.name, args: tc.args } };\n const state = (_a = tc.providerMetadata) === null || _a === void 0 ? void 0 : _a[GEMINI_PROVIDER_KEY];\n // A signature is only valid for the model that produced it. Replay\n // the real one only when the producing model matches this request's\n // model; on a mid-execution model switch (or when none was captured)\n // put the skip token on the step's first call so validation passes.\n // Parallel sibling calls (i > 0) carry no signature, matching what\n // Gemini emits.\n const sig = (state === null || state === void 0 ? void 0 : state.model) === this.model ? state.thoughtSignature : undefined;\n if (sig) {\n part.thoughtSignature = sig;\n }\n else if (i === 0) {\n part.thoughtSignature = SKIP_SIGNATURE;\n }\n return part;\n }),\n });\n }\n else if (role === 'user' && ((_c = msg.attachments) === null || _c === void 0 ? void 0 : _c.length)) {\n const msgAttachmentParts = msg.attachments.map((att) => ({\n text: `[File: ${att.name}]\\n${att.content}`,\n }));\n contents.push({ role: 'user', parts: [{ text: msg.content }, ...msgAttachmentParts] });\n }\n else {\n contents.push({ role, parts: [{ text: msg.content }] });\n }\n }\n const attachmentParts = (attachments !== null && attachments !== void 0 ? attachments : []).map((att) => ({\n text: `[File: ${att.name}]\\n${att.content}`,\n }));\n if (userMessage || attachmentParts.length) {\n contents.push({ role: 'user', parts: [{ text: userMessage }, ...attachmentParts] });\n }\n return contents;\n }\n /**\n * Map Gemini's `usageMetadata` onto the provider-agnostic usage fields, pricing\n * the call as a side effect (`logTokenUsage`). Returns an empty object when the\n * response carries no usage \u2014 every field is optional, so an absent count stays\n * `undefined` rather than being reported as a measured 0.\n *\n * Split out of `fromGeminiResponse` because it is self-contained bookkeeping\n * that reads better alone \u2014 and because folding it inline pushed that method\n * past the complexity ceiling.\n */\n usageFromGemini(usageMetadata) {\n var _a, _b, _c, _d, _e, _f;\n if (!usageMetadata)\n return {};\n const usage = usageMetadata;\n const cost = this.logTokenUsage((_a = usage.promptTokenCount) !== null && _a !== void 0 ? _a : 0, (_b = usage.candidatesTokenCount) !== null && _b !== void 0 ? _b : 0, (_c = usage.thoughtsTokenCount) !== null && _c !== void 0 ? _c : 0, (_d = usage.cachedContentTokenCount) !== null && _d !== void 0 ? _d : 0);\n return {\n inputTokens: usage.promptTokenCount,\n // Thinking tokens are generated output, billed at the candidate rate, but\n // reported in a field disjoint from `candidatesTokenCount`. Fold them into the\n // provider-agnostic `outputTokens` so it reflects the true generated total \u2014\n // matching Anthropic, whose `output_tokens` already includes them. Left\n // `undefined` only when the provider reported neither count.\n outputTokens: usage.candidatesTokenCount != null || usage.thoughtsTokenCount != null\n ? ((_e = usage.candidatesTokenCount) !== null && _e !== void 0 ? _e : 0) + ((_f = usage.thoughtsTokenCount) !== null && _f !== void 0 ? _f : 0)\n : undefined,\n thoughtsTokens: usage.thoughtsTokenCount,\n // Gemini reports cache HITS only \u2014 implicit caching bills no separate write, so\n // `cacheWriteTokens` is left unset rather than 0 (there is no write bucket to\n // measure, which is not the same as measuring 0). Already counted inside\n // `promptTokenCount`, so this breaks that total down rather than adding to it.\n cacheReadTokens: usage.cachedContentTokenCount,\n cost,\n };\n }\n fromGeminiResponse(response, offeredToolNames = new Set()) {\n var _a, _b, _c, _d;\n const { inputTokens, outputTokens, thoughtsTokens, cacheReadTokens, cost } = this.usageFromGemini(response.usageMetadata);\n const candidates = response === null || response === void 0 ? void 0 : response.candidates;\n const firstCandidate = candidates === null || candidates === void 0 ? void 0 : candidates[0];\n const parts = (_b = (_a = firstCandidate === null || firstCandidate === void 0 ? void 0 : firstCandidate.content) === null || _a === void 0 ? void 0 : _a.parts) !== null && _b !== void 0 ? _b : [];\n const toolCalls = [];\n const thoughtParts = [];\n const textParts = [];\n for (const part of parts) {\n if (part.functionCall) {\n // Stash the reasoning signature (and the producing model) so it can be\n // replayed on the next request \u2014 Gemini 3 requires the first function\n // call of each step to carry its signature or the request 400s. The\n // API only returns a signature on the first of a set of parallel calls.\n const state = { model: this.model };\n if (part.thoughtSignature) {\n state.thoughtSignature = part.thoughtSignature;\n }\n toolCalls.push({\n id: crypto.randomUUID(),\n name: part.functionCall.name,\n args: (_c = part.functionCall.args) !== null && _c !== void 0 ? _c : {},\n providerMetadata: { [GEMINI_PROVIDER_KEY]: state },\n });\n }\n else if (part.thought && part.text) {\n thoughtParts.push(part.text);\n }\n else if (part.text) {\n textParts.push(part.text);\n }\n }\n // Gemini sometimes flags MALFORMED_FUNCTION_CALL when it produced a complete\n // tool call but serialised it as a Python statement. Recover it in place\n // when we can parse it with full confidence (its `parts` are empty in this\n // case, so the repaired call flows through the normal token/cost handling\n // below); otherwise throw so the ChatDriver retry takes over.\n if ((firstCandidate === null || firstCandidate === void 0 ? void 0 : firstCandidate.finishReason) === 'MALFORMED_FUNCTION_CALL') {\n const repaired = repairMalformedFunctionCall(firstCandidate.finishMessage, offeredToolNames);\n if (!repaired) {\n throw new MalformedFunctionCallError(firstCandidate.finishMessage);\n }\n toolCalls.push({ id: crypto.randomUUID(), name: repaired.name, args: repaired.args });\n }\n // The model's official thinking (thought-summary parts, returned because we set\n // `thinkingConfig.includeThoughts`) travels in its OWN channel, distinct from the answer /\n // tool-call narration: `content` carries the answer text, `reasoning` carries the summary. The\n // driver splits them into separate category-tagged messages (reasoning vs narration) so each has\n // its own visibility toggle and log category. Final answers surface only the answer text; the\n // reasoning summary rides `reasoning` and is deliberately not promoted to be the answer.\n const reasoning = thoughtParts.join('');\n const narration = textParts.join('');\n const base = toolCalls.length > 0\n ? { role: 'assistant', content: narration, reasoning: reasoning || undefined, toolCalls }\n : { role: 'assistant', content: narration, reasoning: reasoning || undefined };\n // Blank / non-STOP finishes are the recurring failure mode (especially empty\n // STOP on 2.5 Pro). Log the full shape so the cause is legible from the\n // breakdown rather than inferred. MALFORMED is excluded \u2014 it has its own\n // repair/throw path above.\n const finishReason = firstCandidate === null || firstCandidate === void 0 ? void 0 : firstCandidate.finishReason;\n const isBlank = toolCalls.length === 0 && !reasoning && !narration;\n if (isBlank ||\n (finishReason && finishReason !== 'STOP' && finishReason !== 'MALFORMED_FUNCTION_CALL')) {\n this.logAbnormalResponse(response, {\n finishReason,\n functionCallParts: toolCalls.length,\n thoughtParts: thoughtParts.length,\n textParts: textParts.length,\n });\n }\n this.guardMaxTokensTruncation(finishReason, toolCalls, narration, outputTokens);\n if (inputTokens != null)\n base.inputTokens = inputTokens;\n if (outputTokens != null)\n base.outputTokens = outputTokens;\n if (cacheReadTokens != null)\n base.cacheReadTokens = cacheReadTokens;\n if (cost != null)\n base.cost = cost;\n // Surface the provider diagnostic on the message so the driver can fold it\n // into the debug-log meta events (the console log above is dev-only). Only\n // when there's signal \u2014 a finish reason, thinking tokens, or a block reason.\n const blockReason = (_d = response.promptFeedback) === null || _d === void 0 ? void 0 : _d.blockReason;\n if (finishReason != null || thoughtsTokens != null || blockReason != null) {\n base.responseMeta = {\n finishReason,\n thoughtsTokens,\n parts: {\n functionCall: toolCalls.length,\n thought: thoughtParts.length,\n text: textParts.length,\n },\n blockReason,\n };\n }\n return base;\n }\n /**\n * Raises {@link ResponseTruncatedError} when a `MAX_TOKENS` finish left nothing\n * safe to keep. A MAX_TOKENS finish means generation was cut off at the\n * output-token limit (no explicit cap is requested, so this is the model's own\n * output ceiling \u2014 which thinking tokens share). Truncation is DETERMINISTIC:\n * re-issuing the identical request hits the same limit, so it must not fall\n * through to the caller's empty-response retry. Mirrors the Anthropic\n * transport's contract: with tool calls the cut-off call's args can't be\n * trusted, and with no usable answer text (blank or thinking-only) there is\n * nothing to keep either \u2014 the typed truncation error is raised for both.\n * Partial answer TEXT is instead returned by `fromGeminiResponse`, flagged via\n * `responseMeta.finishReason`, for the caller to decide. Usage/cost is logged\n * before this check runs, so the spent tokens stay accounted for.\n */\n guardMaxTokensTruncation(finishReason, toolCalls, narration, outputTokens) {\n if (finishReason !== 'MAX_TOKENS')\n return;\n // A truncated text-only answer is partial but legible \u2014 keep it (the driver's\n // emptiness rule is `!content.trim()`, so whitespace-only does NOT count).\n if (toolCalls.length === 0 && narration.trim() !== '')\n return;\n throw new ResponseTruncatedError(this.model, undefined, outputTokens, toolCalls.map((tc) => tc.name));\n }\n /**\n * Log the full shape of a blank or non-STOP response so its cause is legible\n * without re-deriving it: a thinking-only STOP (substantial `thoughtsTokenCount`,\n * ~0 `candidatesTokenCount`) vs a content block (`SAFETY` / `RECITATION`) vs a\n * token cap (`MAX_TOKENS`) vs a prompt-level block (top-level\n * `promptFeedback.blockReason`). On 2.5 Pro \u2014 which always thinks \u2014 a blank\n * STOP carrying substantial thought tokens is the \"thought, then stopped\n * without answering\" signature.\n */\n logAbnormalResponse(response, parsed) {\n var _a, _b, _c;\n const usage = ((_a = response.usageMetadata) !== null && _a !== void 0 ? _a : {});\n const candidate = (_c = (_b = response.candidates) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : {};\n logger.warn('GeminiTransport: blank/non-STOP response', {\n model: this.model,\n finishReason: parsed.finishReason,\n finishMessage: candidate.finishMessage,\n parts: {\n total: parsed.functionCallParts + parsed.thoughtParts + parsed.textParts,\n functionCall: parsed.functionCallParts,\n thought: parsed.thoughtParts,\n text: parsed.textParts,\n },\n usage: {\n promptTokenCount: usage.promptTokenCount,\n candidatesTokenCount: usage.candidatesTokenCount,\n thoughtsTokenCount: usage.thoughtsTokenCount,\n totalTokenCount: usage.totalTokenCount,\n },\n promptFeedback: response.promptFeedback,\n safetyRatings: candidate.safetyRatings,\n citationMetadata: candidate.citationMetadata,\n });\n }\n buildEndpoint(body) {\n if (this.apiKey) {\n return {\n url: `${GEMINI_DIRECT_URL(this.model)}?key=${this.apiKey}`,\n payload: this.toDirectPayload(body),\n headers: { 'Content-Type': 'application/json' },\n credentials: 'omit',\n };\n }\n if (this.serverEndpoint) {\n return {\n url: this.serverEndpoint,\n payload: body,\n // Opt in to the proxy's NDJSON heartbeat framing. An old proxy ignores\n // this and returns plain JSON \u2014 see the Content-Type branch in `post`.\n headers: { 'Content-Type': 'application/json', Accept: 'application/x-ndjson' },\n credentials: 'include',\n };\n }\n throw new Error('GeminiTransport: no API key or server endpoint configured. ' +\n 'Set GEMINI_API_KEY in your .env or pass apiKey/serverEndpoint in GeminiAIConfig.');\n }\n post(body, signal) {\n return __awaiter(this, void 0, void 0, function* () {\n const { url, payload, headers, credentials } = this.buildEndpoint(body);\n return (yield postWithRetry({\n url,\n headers,\n body: payload,\n credentials,\n vendorLabel: VENDOR_LABELS.gemini,\n retryableStatuses: GeminiTransport.RETRYABLE_STATUSES,\n timeout: this.timeout,\n stallTimeout: this.stallTimeout,\n backoffBaseMs: GeminiTransport.BACKOFF_BASE_MS,\n signal,\n }));\n });\n }\n toDirectPayload(body) {\n const payload = Object.assign({}, body);\n delete payload.model;\n if (payload.responseSchema) {\n payload.generationConfig = Object.assign(Object.assign({}, payload.generationConfig), { responseMimeType: 'application/json', responseSchema: payload.responseSchema });\n delete payload.responseSchema;\n }\n return payload;\n }\n}\n// \u2500\u2500 Private helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nGeminiTransport.TOKENS_PER_MILLION = 1000000;\nGeminiTransport.COST_DECIMAL_PLACES = 6;\nGeminiTransport.RATE_LIMIT_STATUS = 429;\nGeminiTransport.SERVICE_UNAVAILABLE_STATUS = 503;\n/**\n * 502 BAD_GATEWAY is a cleanly transient fault from an intermediate proxy or load\n * balancer fronting the API \u2014 back off and retry it alongside 429/503.\n *\n * Deliberately NOT retried: 500 INTERNAL and 504 DEADLINE_EXCEEDED. Google documents\n * both as also carrying a deterministic cause (\"input context is too long\" / \"prompt\n * too large to process in time\"); re-issuing the identical request just re-hits the\n * same wall and burns the whole backoff ladder \u2014 the same deterministic-retry trap\n * this transport avoids for MAX_TOKENS, and especially wasteful on the large-context\n * agent path. They fail fast instead.\n */\nGeminiTransport.BAD_GATEWAY_STATUS = 502;\nGeminiTransport.RETRYABLE_STATUSES = [\n GeminiTransport.RATE_LIMIT_STATUS,\n GeminiTransport.SERVICE_UNAVAILABLE_STATUS,\n GeminiTransport.BAD_GATEWAY_STATUS,\n];\n// Base backoff for the shared retry ladder (1s, 2s, 4s, 8s, 16s).\nGeminiTransport.BACKOFF_BASE_MS = 1000;\n", "import { __awaiter } from \"tslib\";\nimport { AnthropicProvider } from './providers/anthropic-provider';\nimport { ChromeProvider } from './providers/chrome-provider';\nimport { DefaultAIProvider } from './providers/default-provider';\nimport { GeminiProvider } from './providers/gemini-provider';\nimport { OpenAIProvider } from './providers/openai-provider';\nimport { AnthropicTransport } from './transports/anthropic-transport';\nimport { ChromePromptTransport } from './transports/chrome-prompt-transport';\nimport { GeminiTransport } from './transports/gemini-transport';\nimport { ServerOpenAITransport } from './transports/server-openai-transport';\nimport { SUPPORTED_ANTHROPIC_MODEL_IDS, SUPPORTED_GEMINI_MODEL_IDS, } from './types';\nimport { logger } from './utils';\nimport { isAIFeatureEnabled } from './utils/feature-flags';\nfunction isChromeConfig(config) {\n return 'providerType' in config && config.providerType === 'chrome';\n}\nfunction isGeminiConfig(config) {\n return 'providerType' in config && config.providerType === 'gemini';\n}\nfunction isAnthropicConfig(config) {\n return 'providerType' in config && config.providerType === 'anthropic';\n}\nfunction isServerAIConfig(config) {\n return !!config.provider;\n}\n/**\n * Creates an AIProvider from config.\n * Uses ChromeProvider when providerType is 'chrome'.\n * Uses OpenAIProvider with ServerOpenAITransport when provider is set (server-only).\n * Otherwise returns DefaultAIProvider.\n * When the AI feature flag is disabled (?feature.ai), always returns DefaultAIProvider.\n *\n * @beta\n */\nexport function createAIProvider(config) {\n if (!isAIFeatureEnabled()) {\n logger.warn('createAIProvider: AI feature flag disabled, using DefaultAIProvider');\n return new DefaultAIProvider();\n }\n if (config && isChromeConfig(config)) {\n logger.debug('createAIProvider: using ChromeProvider');\n return new ChromeProvider(config);\n }\n if (config && isGeminiConfig(config)) {\n logger.debug('createAIProvider: using GeminiProvider');\n const transport = new GeminiTransport({\n model: config.model,\n timeout: config.timeout,\n stallTimeout: config.stallTimeout,\n serverEndpoint: config.serverEndpoint,\n apiKey: config.apiKey,\n });\n return new GeminiProvider({ criteriaInstructions: config.criteriaInstructions }, transport);\n }\n if (config && isAnthropicConfig(config)) {\n logger.debug('createAIProvider: using AnthropicProvider');\n const transport = new AnthropicTransport({\n model: config.model,\n timeout: config.timeout,\n stallTimeout: config.stallTimeout,\n serverEndpoint: config.serverEndpoint,\n apiKey: config.apiKey,\n maxTokens: config.maxTokens,\n });\n return new AnthropicProvider({ criteriaInstructions: config.criteriaInstructions }, transport);\n }\n if (config && isServerAIConfig(config)) {\n if (config.provider !== 'openai') {\n logger.warn('createAIProvider: only openai server provider supported for now, using default');\n return new DefaultAIProvider();\n }\n logger.debug('createAIProvider: using OpenAIProvider (server proxy)');\n const transport = new ServerOpenAITransport({\n model: config.model,\n timeout: config.timeout,\n });\n return new OpenAIProvider({ criteriaInstructions: config.criteriaInstructions }, transport);\n }\n logger.debug('createAIProvider: using DefaultAIProvider');\n return new DefaultAIProvider();\n}\n/**\n * Resolves AI config, optionally preferring Chrome when available.\n * Use before registering AIProvider. Server URL is derived from API_HOST.\n * Returns null when the AI feature flag is disabled (?feature.ai).\n *\n * @beta\n */\nexport function resolveAIConfig() {\n return __awaiter(this, arguments, void 0, function* (options = {}) {\n if (!isAIFeatureEnabled()) {\n logger.warn('resolveAIConfig: AI feature flag disabled');\n return null;\n }\n const { provider = 'openai', model, preferChrome = true } = options;\n if (preferChrome) {\n const transport = new ChromePromptTransport();\n const availability = yield transport.getAvailability();\n if (availability === 'available' ||\n availability === 'downloadable' ||\n availability === 'downloading') {\n return { providerType: 'chrome' };\n }\n logger.warn('resolveAIConfig: Chrome not available', availability);\n }\n if (provider === 'gemini') {\n const geminiModel = model !== null && model !== void 0 ? model : 'gemini-2.5-flash-lite';\n if (!SUPPORTED_GEMINI_MODEL_IDS.includes(geminiModel)) {\n throw new Error(`resolveAIConfig: unsupported Gemini model \"${geminiModel}\". Use one of: ${SUPPORTED_GEMINI_MODEL_IDS.join(', ')}.`);\n }\n return { providerType: 'gemini', model: geminiModel };\n }\n if (provider === 'anthropic') {\n const anthropicModel = model !== null && model !== void 0 ? model : 'claude-haiku-4-5-20251001';\n if (!SUPPORTED_ANTHROPIC_MODEL_IDS.includes(anthropicModel)) {\n throw new Error(`resolveAIConfig: unsupported Anthropic model \"${anthropicModel}\". Use one of: ${SUPPORTED_ANTHROPIC_MODEL_IDS.join(', ')}.`);\n }\n return { providerType: 'anthropic', model: anthropicModel };\n }\n return { provider, model: model !== null && model !== void 0 ? model : 'gpt-4o-mini' };\n });\n}\n/**\n * Feature-detects an {@link ObservableAIProviderRegistry}. Returns `true` when\n * `r` exposes a `subscribe` method \u2014 i.e. it can notify on runtime changes \u2014\n * and `false` for the immutable built-ins.\n *\n * @beta\n */\nexport function isObservableAIProviderRegistry(r) {\n return typeof r.subscribe === 'function';\n}\n/**\n * Built-in fallback registry. Resolved by the DI container when no host has\n * registered an {@link (AIProviderRegistry:interface)}. Holds a single\n * `DefaultAIProvider` (no-op) under the name `'default'`, preserving the\n * \"no host registration \u2192 assistant inert\" behavior.\n *\n * @internal\n */\nexport class EmptyAIProviderRegistry {\n constructor() {\n this.noopProvider = new DefaultAIProvider();\n }\n get(name) {\n return name === EmptyAIProviderRegistry.DEFAULT_NAME ? this.noopProvider : undefined;\n }\n default() {\n return this.noopProvider;\n }\n defaultName() {\n return EmptyAIProviderRegistry.DEFAULT_NAME;\n }\n names() {\n return [EmptyAIProviderRegistry.DEFAULT_NAME];\n }\n getStatus(name) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a, _b, _c;\n if (name !== undefined && name !== EmptyAIProviderRegistry.DEFAULT_NAME)\n return null;\n return (_c = (yield ((_b = (_a = this.noopProvider).getStatus) === null || _b === void 0 ? void 0 : _b.call(_a)))) !== null && _c !== void 0 ? _c : null;\n });\n }\n listStatuses() {\n return __awaiter(this, void 0, void 0, function* () {\n var _a, _b, _c;\n const status = (_c = (yield ((_b = (_a = this.noopProvider).getStatus) === null || _b === void 0 ? void 0 : _b.call(_a)))) !== null && _c !== void 0 ? _c : null;\n return [{ name: EmptyAIProviderRegistry.DEFAULT_NAME, isDefault: true, status }];\n });\n }\n}\nEmptyAIProviderRegistry.DEFAULT_NAME = 'default';\n/**\n * Map-backed registry built by {@link registerAIProviders}. Preserves the\n * insertion order of `providers` for {@link (AIProviderRegistry:interface).names}\n * and {@link (AIProviderRegistry:interface).listStatuses}.\n *\n * Mutable and observable: a host that holds a reference can rebind names,\n * change the default, or atomically replace the whole mapping at runtime via\n * {@link MutableAIProviderRegistry.set}, {@link MutableAIProviderRegistry.setDefault}\n * and {@link MutableAIProviderRegistry.update}, and subscribe to be told when\n * any of those happen. This is the substrate for runtime provider switching:\n * the DI token resolves one stable instance, and consumers re-resolve their\n * cached providers when {@link MutableAIProviderRegistry.subscribe | subscribe}\n * fires. A registry that is never mutated behaves identically to an immutable\n * one, so existing single-registration callers are unaffected.\n *\n * @beta\n */\nexport class MutableAIProviderRegistry {\n constructor(providers, defaultName) {\n this.listeners = new Set();\n // Defensive copy so external mutation of the caller's Map can't desync the\n // registry from its own invariants. Validate the copy we will actually keep.\n const next = new Map(providers);\n MutableAIProviderRegistry.assertValidMapping(next, defaultName);\n this.providers = next;\n this._defaultName = defaultName;\n }\n /**\n * The mapping invariant shared by construction and\n * {@link MutableAIProviderRegistry.update}: at least one provider, and the\n * resolved default name must be one of the keys. Throws\n * with the same messages from both call sites. Validates the finalized map, so\n * callers normalize/copy and resolve the default name first, then validate.\n */\n static assertValidMapping(providers, defaultName) {\n if (providers.size === 0) {\n throw new Error('MutableAIProviderRegistry: at least one provider is required.');\n }\n if (!providers.has(defaultName)) {\n throw new Error(`MutableAIProviderRegistry: default name \"${defaultName}\" not present in providers.`);\n }\n }\n get(name) {\n return this.providers.get(name);\n }\n default() {\n // Construction and every mutator guarantee this lookup succeeds.\n return this.providers.get(this._defaultName);\n }\n defaultName() {\n return this._defaultName;\n }\n names() {\n return [...this.providers.keys()];\n }\n getStatus(name) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a, _b;\n const provider = name === undefined ? this.default() : this.providers.get(name);\n if (!provider)\n return null;\n return (_b = (yield ((_a = provider.getStatus) === null || _a === void 0 ? void 0 : _a.call(provider)))) !== null && _b !== void 0 ? _b : null;\n });\n }\n listStatuses() {\n return __awaiter(this, void 0, void 0, function* () {\n const entries = [...this.providers.entries()];\n return Promise.all(entries.map((_a) => __awaiter(this, [_a], void 0, function* ([name, provider]) {\n var _b, _c;\n return ({\n name,\n isDefault: name === this._defaultName,\n status: (_c = (yield ((_b = provider.getStatus) === null || _b === void 0 ? void 0 : _b.call(provider)))) !== null && _c !== void 0 ? _c : null,\n });\n })));\n });\n }\n /**\n * Rebind (or add) a single name. Rebinding an existing name preserves its\n * position in `names()`; a new name is appended. Notifies subscribers.\n */\n set(name, provider) {\n this.providers.set(name, provider);\n this.notify();\n }\n /**\n * Change the default provider. Throws if `name` is not currently registered.\n * Notifies subscribers.\n */\n setDefault(name) {\n if (!this.providers.has(name)) {\n throw new Error(`MutableAIProviderRegistry: cannot set default to \"${name}\" \u2014 not present in providers.`);\n }\n this._defaultName = name;\n this.notify();\n }\n /**\n * Atomically replace the whole mapping (and optionally the default) in one\n * step, then notify subscribers once. Applies the same validation as the\n * constructor: an empty mapping throws, and the resolved default must be\n * present. When `options.default` is omitted the current default name is\n * retained (and must still exist in the new mapping).\n */\n update(providers, options = {}) {\n var _a;\n const next = providers instanceof Map ? new Map(providers) : new Map(Object.entries(providers));\n const nextDefault = (_a = options.default) !== null && _a !== void 0 ? _a : this._defaultName;\n MutableAIProviderRegistry.assertValidMapping(next, nextDefault);\n this.providers = next;\n this._defaultName = nextDefault;\n this.notify();\n }\n subscribe(listener) {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n /**\n * Fire every listener once. Iterates a snapshot so a listener that\n * unsubscribes (or subscribes) during notification doesn't perturb the\n * in-flight iteration.\n */\n notify() {\n for (const listener of Array.from(this.listeners))\n listener();\n }\n}\n", "import type { AgenticActivityEvents } from './ai-activity-channel';\n\n/**\n * Configuration for {@link AgenticActivityBus}.\n *\n * @beta\n */\nexport interface AgenticActivityBusConfig {\n /** Events that should also be forwarded via BroadcastChannel to other tabs. */\n crossTabEvents?: (keyof AgenticActivityEvents)[];\n /** BroadcastChannel name. Only used when crossTabEvents is non-empty. */\n channelName?: string;\n /**\n * Lazy alternative to {@link AgenticActivityBusConfig.channelName}: called the first\n * time a cross-tab channel is actually needed, in a browser only. Deferring the name\n * computation keeps side effects (e.g. `sessionStorage` reads) out of module-eval and\n * off the non-browser path. Ignored if `channelName` is also set.\n */\n channelNameFactory?: () => string;\n}\n\ntype AnyHandler = (detail: any) => void;\n\n/**\n * Minimal activity-bus surface the drivers depend on. `ChatDriver`/`OrchestratingDriver`\n * only ever *publish* \u2014 accepting this narrow interface (rather than importing the module\n * singleton) lets a headless/server or unit-test host omit the bus entirely, so no live\n * `BroadcastChannel` is ever opened on that path. See {@link NOOP_ACTIVITY_BUS}.\n *\n * @beta\n */\nexport interface ActivityBus {\n publish<K extends keyof AgenticActivityEvents>(type: K, detail: AgenticActivityEvents[K]): void;\n}\n\n/**\n * No-op {@link ActivityBus}. The default when no bus is injected (Node, tests, headless\n * server use) \u2014 publishing goes nowhere and nothing is left open to tear down.\n *\n * @beta\n */\nexport const NOOP_ACTIVITY_BUS: ActivityBus = { publish: () => {} };\n\n/**\n * Typed in-process event bus for AI assistant activity events.\n *\n * Dispatches events synchronously to all local subscribers in the same JS module instance\n * (i.e. the same browser tab). Events listed in `crossTabEvents` are additionally forwarded\n * via a shared `BroadcastChannel` so that other tabs on the same origin receive them.\n *\n * @remarks\n * The pre-instantiated {@link agenticActivityBus} singleton covers all platform use cases.\n * App developers can extend the event map using TypeScript declaration merging on\n * {@link AgenticActivityEvents} and subscribe/publish custom events without any platform changes.\n *\n * @beta\n */\nexport class AgenticActivityBus {\n private readonly subscribers = new Map<string, Set<AnyHandler>>();\n private readonly crossTabEvents: Set<string>;\n private readonly channelNameFactory?: () => string;\n private channel?: BroadcastChannel;\n private channelInitialised = false;\n\n /**\n * @param config - Optional configuration. Omit to create an in-memory-only bus.\n * @beta\n */\n constructor(config?: AgenticActivityBusConfig) {\n this.crossTabEvents = new Set(config?.crossTabEvents ?? []);\n this.channelNameFactory =\n config?.channelName != null ? () => config.channelName! : config?.channelNameFactory;\n }\n\n /**\n * Lazily open the cross-tab `BroadcastChannel` on first use. Deferred (rather than\n * created in the constructor) so that importing this module, or constructing the bus\n * off-browser (Node, tests, headless server), never opens a live channel or reads\n * `sessionStorage` \u2014 both would keep a Node event loop alive and hang the process.\n * Cross-tab forwarding is inherently browser-only, so channel creation is gated on a\n * browser environment; elsewhere the bus stays purely in-process.\n */\n private ensureChannel(): void {\n if (this.channelInitialised) return;\n this.channelInitialised = true;\n const inBrowser = typeof window !== 'undefined' && typeof BroadcastChannel !== 'undefined';\n if (this.crossTabEvents.size === 0 || !this.channelNameFactory || !inBrowser) return;\n this.channel = new BroadcastChannel(this.channelNameFactory());\n this.channel.onmessage = (ev) => {\n const { type, detail } = (ev.data ?? {}) as { type?: string; detail?: unknown };\n if (type) this.notifyLocal(type, detail);\n };\n }\n\n /**\n * Subscribe to an event. Returns an unsubscribe function \u2014 call it in\n * `disconnectedCallback` to avoid memory leaks.\n *\n * @beta\n */\n subscribe<K extends keyof AgenticActivityEvents>(\n type: K,\n handler: (detail: AgenticActivityEvents[K]) => void,\n ): () => void {\n // Open the cross-tab channel (browser only) so this subscriber receives events\n // forwarded from other tabs; no-op off-browser.\n this.ensureChannel();\n let handlers = this.subscribers.get(type as string);\n if (!handlers) {\n handlers = new Set();\n this.subscribers.set(type as string, handlers);\n }\n const h = handler as AnyHandler;\n handlers.add(h);\n return () => handlers!.delete(h);\n }\n\n /**\n * Publish an event to all local subscribers and, if configured, to other tabs\n * via BroadcastChannel.\n *\n * @beta\n */\n publish<K extends keyof AgenticActivityEvents>(type: K, detail: AgenticActivityEvents[K]): void {\n this.notifyLocal(type as string, detail);\n if (this.crossTabEvents.has(type as string)) {\n this.ensureChannel();\n this.channel?.postMessage({ type, detail });\n }\n }\n\n /**\n * Add an event type to the cross-tab forwarding set at runtime.\n * Must be called before the first {@link AgenticActivityBus.publish} of that event type.\n *\n * @beta\n */\n addCrossTabEvent(type: keyof AgenticActivityEvents): void {\n this.crossTabEvents.add(type as string);\n }\n\n /**\n * Close the underlying BroadcastChannel. Call once on application teardown if needed.\n *\n * @beta\n */\n close(): void {\n this.channel?.close();\n this.channel = undefined;\n }\n\n private notifyLocal(type: string, detail: unknown): void {\n this.subscribers.get(type)?.forEach((handler) => handler(detail));\n }\n}\n\n/**\n * Returns a `BroadcastChannel` name that is scoped to the current tab and any popout windows\n * it opens, while remaining isolated from unrelated tabs on the same origin.\n *\n * **How it works:**\n * A UUID is generated once and stored in `sessionStorage`. `sessionStorage` persists across\n * page refreshes (so the channel name stays stable after an F5), but is cleared when the tab\n * is closed. Crucially, when a page opens a child window via `window.open()`, the browser\n * initialises the new window's `sessionStorage` as a copy of the opener's \u2014 so the child\n * inherits the same UUID and therefore the same channel name.\n *\n * Result:\n * - **Same tab + its `window.open()` popouts** share one channel \u2192 events flow as intended.\n * - **Independent tabs** (opened from the address bar, bookmarks, or links) each get a fresh\n * `sessionStorage` and therefore a distinct channel \u2192 no cross-talk between unrelated app\n * instances on the same origin.\n */\nfunction getTabScopedChannelName(base: string): string {\n // Belt-and-braces: this only runs in a browser (see `ensureChannel`), but guard anyway\n // so a direct call off-browser never throws a `sessionStorage is not defined` ReferenceError.\n if (typeof sessionStorage === 'undefined') return `${base}-nostorage`;\n const key = `${base}-tab-id`;\n let id = sessionStorage.getItem(key);\n if (!id) {\n id = crypto.randomUUID();\n sessionStorage.setItem(key, id);\n }\n return `${base}-${id}`;\n}\n\n/**\n * Pre-instantiated singleton event bus for AI assistant activity.\n *\n * - `halo-start` / `halo-stop` are forwarded via a tab-scoped `BroadcastChannel` so that\n * popout windows opened from this tab show halo animations, while remaining isolated from\n * unrelated tabs on the same origin (tab-scoped channel name).\n * - `tool-loop-start` / `tool-loop-end` are cross-tab for the same reason: they describe the\n * assistant's lifecycle (a turn beginning / ending), and the most common subscribers\n * (workspace transitions, post-turn deferred recomputation, UI gates tied to the assistant\n * being idle) need the event regardless of whether the user is interacting with the chat\n * in the main tab or a popout window. Tab-local-only telemetry can subscribe and filter.\n * - `chat-popout` / `chat-popin` are in-memory only \u2014 they must only affect the tab where the\n * user clicked.\n *\n * @beta\n */\nexport const agenticActivityBus = new AgenticActivityBus({\n crossTabEvents: ['halo-start', 'halo-stop', 'tool-loop-start', 'tool-loop-end'],\n // Lazy: the tab-scoped name (and its `sessionStorage` read) is computed on first\n // cross-tab use in a browser, not at module-eval \u2014 so importing this module is\n // side-effect-free and Node/test-safe.\n channelNameFactory: () => getTabScopedChannelName('foundation-ai-activity'),\n});\n", "import type { AIProvider, AIProviderRegistry } from '@genesislcap/foundation-ai';\nimport type { AgentConfig } from './config';\n\n/**\n * Resolve a provider name against the registry and assert it implements\n * `chat()` \u2014 the capability the chat tool-loop depends on. Throws with a\n * message naming the agent so misconfigured agents are easy to track down.\n *\n * Used by both the up-front static walk in `OrchestratingDriver` and by\n * `ChatDriver`'s per-turn resolver for function-form `provider` values.\n *\n * @internal\n */\nexport function resolveChatProvider(\n registry: AIProviderRegistry,\n providerName: string,\n agentName: string,\n): AIProvider {\n const provider = registry.get(providerName);\n if (!provider) {\n const available = registry.names().join(', ') || '(none)';\n throw new Error(\n `Agent \"${agentName}\" references unknown provider \"${providerName}\". Registered: ${available}`,\n );\n }\n if (!provider.chat) {\n throw new Error(\n `Agent \"${agentName}\" resolved to provider \"${providerName}\" which does not implement chat().`,\n );\n }\n return provider;\n}\n\n/**\n * Walk an agent tree (including nested `subAgents`) and validate every static\n * `provider: string` against the registry. Function-form `provider` values are\n * deferred \u2014 they validate on first resolution inside the driver.\n *\n * Throws on the first failure, with the same message shape produced by\n * {@link resolveChatProvider}.\n *\n * @internal\n */\nexport function validateStaticAgentProviders(\n agents: AgentConfig[],\n registry: AIProviderRegistry,\n): void {\n const visited = new Set<AgentConfig>();\n const walk = (agent: AgentConfig): void => {\n if (visited.has(agent)) return;\n visited.add(agent);\n if (typeof agent.provider === 'string') {\n resolveChatProvider(registry, agent.provider, agent.name);\n }\n for (const sub of agent.subAgents ?? []) walk(sub);\n };\n for (const root of agents) walk(root);\n}\n", "/**\n * Module-level append-only timeline of meta/lifecycle events, keyed by session\n * identity (the same `stateKey` space used by the driver registry and the\n * session store).\n *\n * Why a module registry rather than the redux store or the driver:\n * - **Survives the pop-in/pop-out element churn.** A single session can be\n * emitted from up to two element instances (an `expand` bubble + a `collapse`\n * panel) sharing one driver; keying by `stateKey` unifies them into one\n * timeline.\n * - **Survives driver rebuilds.** The driver is torn down and recreated when the\n * host swaps the agents array (see `agentsChanged` / `deleteDriver`), so a\n * driver-owned buffer would lose the timeline mid-session. The `stateKey`\n * outlives the driver.\n * - **Stays out of redux reactivity.** These appends never drive the UI, so\n * there's no reason to pay immutable-reducer cost or flood the Redux DevTools\n * action log with debug noise.\n *\n * Surfaced in `getDebugLog().timeline`, merged chronologically with messages and\n * turn snapshots. Ring-buffered \u2014 the oldest non-`high` events are evicted first\n * while `high`-importance failure events are retained \u2014 so a long-lived session\n * stays bounded in normal use without ever dropping a failure signal.\n *\n * @internal\n */\n\nimport type { TurnFailureReason } from '@genesislcap/foundation-ai';\n\n/**\n * Catalogue of meta event names. This is the documented surface \u2014 extend it as\n * new events are wired in (Tier 2/3 lifecycle, interaction, provider events).\n */\nexport type MetaEventType =\n // Element lifecycle + window placement\n | 'assistant.connected'\n | 'assistant.disconnected'\n | 'assistant.popout'\n | 'assistant.popin'\n // Driver lifecycle / wiring\n | 'driver.created'\n | 'driver.wired'\n | 'driver.unwired'\n // Turn lifecycle\n | 'state.changed'\n | 'turn.start'\n | 'turn.end'\n | 'turn.retry'\n | 'turn.error'\n | 'tool.failed'\n | 'tool.unresolved'\n | 'subagent.started'\n | 'subagent.completed'\n | 'subagent.failed'\n // Routing / providers\n | 'agent.handoff'\n | 'agent.pinned'\n | 'agent.unpinned'\n | 'provider.selected'\n // Blocking interactions\n | 'interaction.requested'\n | 'interaction.resolved'\n // External / unified diagnostics (GENC-1461) \u2014 an out-of-band engine's log folded into this session\n | 'external-diagnostics.folded'\n // Context / cost\n | 'context.updated'\n | 'context.threshold-crossed'\n | 'context.compacted'\n | 'context.condensed'\n // UI + input\n | 'panel.toggled'\n | 'attachment.added'\n | 'file.read-failed'\n | 'suggestions.failed'\n // Session lifecycle (GENC-1351)\n | 'session.cleared'\n | 'session.switched'\n | 'session.switch-deferred'\n | 'persistence.toggled'\n | 'persistence.saved'\n | 'persistence.suppressed'\n | 'persistence.not-resumable'\n | 'persistence.restored'\n | 'persistence.restore-orphan';\n\n/**\n * How much a reader should care about an event \u2014 lets a consumer (or an AI\n * agent) filter the timeline: skip `low` UI/bookkeeping noise, skim `normal`\n * session flow, or jump straight to `high` problem/limit signals when triaging.\n */\nexport type MetaEventImportance = 'high' | 'normal' | 'low';\n\n/**\n * Importance is intrinsic to the event *type*, not the instance, so it's\n * defined once here and stamped automatically by {@link recordMetaEvent} \u2014 call\n * sites never pass it. The `Record` is exhaustive: adding a `MetaEventType`\n * without a level here is a compile error.\n *\n * - `high` \u2014 failures and hard limits you almost always want to see.\n * - `normal` \u2014 meaningful session flow you read to follow what happened.\n * - `low` \u2014 frequent UI / bookkeeping noise, usually safe to skip.\n */\nexport const META_EVENT_IMPORTANCE: Record<MetaEventType, MetaEventImportance> = {\n 'turn.error': 'high',\n 'tool.failed': 'high',\n 'subagent.failed': 'high',\n 'file.read-failed': 'high',\n 'suggestions.failed': 'high',\n 'context.threshold-crossed': 'high',\n 'context.compacted': 'high',\n 'persistence.restore-orphan': 'high',\n\n 'assistant.connected': 'normal',\n 'assistant.disconnected': 'normal',\n 'assistant.popout': 'normal',\n 'assistant.popin': 'normal',\n 'driver.created': 'normal',\n 'state.changed': 'normal',\n 'turn.start': 'normal',\n 'turn.end': 'normal',\n 'turn.retry': 'normal',\n 'tool.unresolved': 'normal',\n 'subagent.started': 'normal',\n 'subagent.completed': 'normal',\n 'agent.handoff': 'normal',\n 'agent.pinned': 'normal',\n 'agent.unpinned': 'normal',\n 'provider.selected': 'normal',\n 'interaction.requested': 'normal',\n 'interaction.resolved': 'normal',\n 'external-diagnostics.folded': 'normal',\n 'session.cleared': 'normal',\n 'session.switched': 'low',\n 'session.switch-deferred': 'low',\n 'persistence.restored': 'normal',\n 'persistence.suppressed': 'normal',\n 'persistence.not-resumable': 'normal',\n\n 'driver.wired': 'low',\n 'driver.unwired': 'low',\n 'context.updated': 'low',\n 'context.condensed': 'low',\n 'panel.toggled': 'low',\n 'persistence.toggled': 'low',\n 'persistence.saved': 'low',\n 'attachment.added': 'low',\n};\n\n/** One entry in the meta-event timeline. */\nexport interface MetaEvent {\n /** Monotonic counter across the session's lifetime (does not reset on driver rebuild). */\n index: number;\n /** ISO timestamp, matching the format used elsewhere in the debug log. */\n timestamp: string;\n /** Event name \u2014 see {@link MetaEventType}. */\n type: MetaEventType;\n /** How much to care about this event \u2014 see {@link META_EVENT_IMPORTANCE}. */\n importance: MetaEventImportance;\n /** Optional structured payload. */\n detail?: Record<string, unknown>;\n}\n\n/**\n * Soft ring-buffer cap. Once exceeded, the oldest *non-`high`* event is evicted;\n * `high`-importance events (failures and hard limits) are never dropped \u2014 they're\n * the whole reason the log exists. So a buffer dominated by `high` events is\n * allowed to float above this cap rather than lose a failure signal; in normal\n * use the frequent `low`/`normal` events keep it near the cap. Entries are cheap.\n */\nconst DEFAULT_MAX_META_EVENTS = 800;\n\ninterface MetaEventBuffer {\n events: MetaEvent[];\n /** Next index to assign \u2014 kept separate from `events.length` so it stays monotonic after eviction. */\n next: number;\n}\n\nconst registry = new Map<string, MetaEventBuffer>();\n\n/**\n * Append a meta event to the timeline for `key`. Once the buffer exceeds\n * {@link DEFAULT_MAX_META_EVENTS}, evicts the oldest *non-`high`* event;\n * `high`-importance events are never evicted. An empty `key` is bucketed under\n * `''`, matching how drivers/stores handle an absent session identity, so\n * callers never need to guard.\n */\nexport function recordMetaEvent(\n key: string,\n type: MetaEventType,\n detail?: Record<string, unknown>,\n): void {\n let buffer = registry.get(key);\n if (!buffer) {\n buffer = { events: [], next: 0 };\n registry.set(key, buffer);\n }\n buffer.events.push({\n index: buffer.next,\n timestamp: new Date().toISOString(),\n type,\n importance: META_EVENT_IMPORTANCE[type],\n detail,\n });\n buffer.next += 1;\n if (buffer.events.length > DEFAULT_MAX_META_EVENTS) {\n // Drop the oldest event that isn't `high` importance. `high` events\n // (failures/limits) are retained even past the cap \u2014 losing a failure\n // signal is worse than briefly exceeding the buffer size. If every retained\n // event is `high` (all-failures session), nothing is evicted and the buffer\n // grows; in practice frequent `low`/`normal` events keep it bounded.\n const evictAt = buffer.events.findIndex((e) => e.importance !== 'high');\n if (evictAt !== -1) {\n buffer.events.splice(evictAt, 1);\n }\n }\n}\n\n/**\n * Why a turn failed or was retried \u2014 stamped as `detail.reason` on `turn.error`\n * and `turn.retry` events, and (since PTC-0) surfaced at the driver's loop\n * boundary via {@link ChatDriverResult.failureReason}. Re-exported from\n * `@genesislcap/foundation-ai` \u2014 where it lives alongside `ChatDriverResult` so\n * the boundary field and this log surface can never drift apart \u2014 under its\n * historical name so existing importers are unaffected. Enumerated so the set\n * stays in sync with the README and call sites can't drift to ad-hoc strings.\n */\nexport type { TurnFailureReason };\n\n/**\n * Record a turn-ending failure (`turn.error`, importance `high`). The `reason`\n * is typed so the high-importance triage surface stays consistent; pass any\n * diagnostic specifics (attempt counts, offending tool names, etc.) in `detail`.\n */\nexport function recordTurnError(\n key: string,\n reason: TurnFailureReason,\n detail?: Record<string, unknown>,\n): void {\n recordMetaEvent(key, 'turn.error', { reason, ...detail });\n}\n\n/**\n * Record a recoverable retry *within* a turn (`turn.retry`, importance `normal`)\n * \u2014 e.g. one malformed/empty attempt that will be retried, as distinct from the\n * final attempt that bails out as a `turn.error`. Include `attempt`/`maxAttempts`\n * in `detail` so the timeline shows which try this was.\n */\nexport function recordTurnRetry(\n key: string,\n reason: TurnFailureReason,\n detail?: Record<string, unknown>,\n): void {\n recordMetaEvent(key, 'turn.retry', { reason, ...detail });\n}\n\n/** Returns the meta-event timeline for `key`, or an empty array if none recorded. */\nexport function getMetaEvents(key: string): ReadonlyArray<MetaEvent> {\n return registry.get(key)?.events ?? [];\n}\n\n/**\n * Merge pre-built meta events into the timeline for `targetKey`, **preserving each\n * event's original `timestamp`** (so it interleaves chronologically on export)\n * while re-indexing onto the target buffer's monotonic counter. Used to fold a\n * sub-agent's harvested events into the parent session \u2014 see\n * `ChatDriver.invokeSubAgent`. Unlike {@link recordMetaEvent} it does not stamp a\n * fresh timestamp; the same non-`high` eviction policy is applied once after the\n * batch so the buffer stays bounded.\n */\nexport function mergeMetaEvents(targetKey: string, events: readonly MetaEvent[]): void {\n if (events.length === 0) return;\n let buffer = registry.get(targetKey);\n if (!buffer) {\n buffer = { events: [], next: 0 };\n registry.set(targetKey, buffer);\n }\n for (const event of events) {\n buffer.events.push({ ...event, index: buffer.next });\n buffer.next += 1;\n }\n // Evict oldest non-`high` events until back under the cap \u2014 same policy as\n // recordMetaEvent; `high` events (failures/limits) are never dropped. Single\n // pass: take the overflow count, then drop that many of the oldest non-`high`\n // events in order (if there aren't enough non-`high`, the buffer floats above\n // the cap rather than losing a failure signal).\n let toEvict = buffer.events.length - DEFAULT_MAX_META_EVENTS;\n if (toEvict > 0) {\n buffer.events = buffer.events.filter((e) => {\n if (toEvict > 0 && e.importance !== 'high') {\n toEvict -= 1;\n return false;\n }\n return true;\n });\n }\n}\n\n/**\n * Drop the entire timeline for `key`. Used to discard a sub-agent's transient\n * per-invocation session once its events have been harvested into the parent, so\n * the module registry doesn't accumulate one orphaned bucket per sub-agent run.\n */\nexport function clearSession(key: string): void {\n registry.delete(key);\n}\n\n/**\n * Human/agent-facing guide emitted as the first key of the exported debug log,\n * so whoever opens the JSON (often an AI agent) knows how to read it without\n * reverse-engineering the shape. Kept here next to the event catalogue it\n * describes \u2014 but proximity alone demonstrably did NOT keep the two in sync\n * (`refusal` was missing from both reason lists for a whole release), so\n * `debug-event-log.test.ts` now asserts that every `TurnFailureReason` and every\n * `SubAgentFailureReason` is named here, and fails the build when one is added\n * without a matching sentence. Enumerations below read as exhaustive and WILL be\n * trusted by an agent reading the JSON \u2014 keep them so.\n */\nexport const DEBUG_LOG_README: readonly string[] = [\n 'This is an exported debug log for the Genesis AI assistant. Read it top-to-bottom.',\n '`timeline` is the entire session as one array, already sorted chronologically by `timestamp` (ISO 8601). Every entry has a `kind`.',\n 'Timestamps are millisecond-resolution; entries that share the same millisecond are ordered by a fixed kind rank (event, then turn, then message), which is a heuristic and may not reflect exact causal order within that millisecond \u2014 e.g. a user message and the turn it triggered, or a final assistant message and its turn.end event, can appear in either order depending on whether they landed in the same millisecond. Read the logical structure of a turn rather than over-interpreting the micro-ordering of co-timestamped entries of different kinds.',\n \"kind:'message' \u2014 the conversation. `role` is user/assistant/tool/system-event/synthetic-user; `agentName` says which agent produced it; `toolCalls`/`toolResult`/`interaction` carry tool and widget activity; `inputTokens`/`outputTokens`/`cost` are per-message LLM usage, where `inputTokens` is the WHOLE prompt for that request and `cacheReadTokens`/`cacheWriteTokens` BREAK IT DOWN rather than add to it \u2014 uncached input is `inputTokens` minus those two, and adding the cache fields to `inputTokens` counts the prompt twice. The cache fields are absent on providers that report no cache split (Gemini reports reads only, since implicit caching bills no write) and on messages persisted before they existed, so read them as 0 when missing. Each bucket bills at a different rate \u2014 cache reads a fraction of uncached input, cache writes a premium, output highest \u2014 so a large token count at a small cost means the prompt was mostly cache hits. `externalCostUsd` is any non-LLM cost a widget reported for its own external service calls (folded into the session cost total alongside `cost`). On model-produced assistant messages, `model` is the concrete model id that generated it (e.g. 'gemini-2.5-flash-lite') and `providerName` is the registry slot it resolved under (e.g. a tier name like 'high'/'low', or the default); together they attribute the message \u2014 and any tool calls it carries \u2014 to an exact model even across a mid-session vendor/tier switch, where one slot name can map to different models before and after the switch. Both are undefined on any entry that is NOT an LLM response: non-assistant roles (user/tool/system-event) and 'synthetic-user' echoes; assistant interaction/widget entries (empty content carrying an `interaction` \u2014 a rendered widget, not a model turn); driver-authored assistant fallbacks (the timeout, repeated-malformed-call, and empty-response apology messages); and messages restored from a session persisted before these fields existed. One partial case: on a genuine model turn whose provider exposes no `getStatus` (or reports no model), `providerName` is still set but `model` alone is undefined. A 'synthetic-user' message is a display-only echo of an interaction outcome (e.g. the answer a widget reported): it renders on the user's side of the chat and `agentName` is the agent that created it, but it is never sent to the LLM \u2014 so it has no matching 'turn' and the model learns the outcome only from the corresponding tool result.\",\n \"Sub-agent messages appear inline. When a tool delegates to a sub-agent (via `requestSubAgent`), the sub-agent's whole conversation \u2014 its own assistant/tool messages, each with their own `content`/`thinking`/`toolCalls`/`toolResult` and per-message `model`/`providerName`/`inputTokens`/`outputTokens`/`cacheReadTokens`/`cacheWriteTokens`/`cost` \u2014 is hoisted into the timeline as ordinary kind:'message' entries, interleaved by timestamp right after the tool call that spawned them (so you read the delegation top-to-bottom). A hoisted entry is marked: `subAgentDepth` is its delegation depth (1 for a sub-agent, 2 for a sub-agent's sub-agent, \u2026), `subAgentOf` is the id of the parent tool call that spawned it (correlates it back even when two sub-agents run in one parent turn), `subAgentName` is the sub-agent's own name, and `agentName` is rewritten to a `\\\"<parent> \u203A <sub-agent>\\\"` breadcrumb (composing when nested, e.g. `\\\"UI Builder \u203A Planner \u203A Grounding\\\"`). The sub-agent's per-LLM-call snapshots also surface as kind:'turn' entries with an N-M `turnIndex`, and subagent.started/completed (or subagent.failed) events bracket the run. Per-message `cost` on hoisted entries is already part of the session total (it is summed from the un-flattened history), so summing the top-level timeline does NOT double-count.\",\n \"kind:'turn' \u2014 one LLM call. `turnIndex` is a string: a top-level turn is the bare counter ('0', '1', \u2026); a sub-agent's turns are numbered under the parent turn that activated them ('3-1', '3-2', \u2026, and a nested sub-agent contributes '3-2-1', \u2026), and `agentName` names the agent that ran the turn. `systemPrompt` and `toolNames` are what the model saw. A systemPrompt of '<repeated \u2014 identical to turn N>' was byte-identical to turn N and de-duplicated; the full prompt is shown whenever it changes (often because a stateful agent advanced), so prompt evolution is visible.\",\n \"kind:'turn'.`agentSnapshot` \u2014 the active agent's own view of its internal state, captured at that turn. An agent opts into this by exposing a `getDebugSnapshot()` that returns JSON-serializable per-state info; stateful/flow agents wire it automatically, so you can watch a flow advance turn-by-turn (e.g. current step, cursor, collected fields, pending changes). Absent for agents that don't expose one.\",\n \"kind:'event' \u2014 a meta/lifecycle event. `type` names it (see below); `detail` carries structured data. `detail.placement` is the emitting UI instance: 'bubble' (collapsed), 'panel' (popped-out), or 'standalone'.\",\n \"Each 'event' also has an `importance`: 'high' (failures/limits \u2014 turn.error, tool.failed, subagent.failed, file.read-failed, suggestions.failed, context.threshold-crossed), 'normal' (session flow \u2014 connects, turns, retries, handoffs, agent/provider changes, interactions, sub-agent start/complete), or 'low' (skippable UI/bookkeeping noise \u2014 panel.toggled, attachment.added, driver.wired/unwired, context.updated, context.condensed). To skim, ignore importance:'low'; to triage a failure, filter to importance:'high' then read the nearby messages and turns. A 'high' turn.error is often preceded by one or more 'normal' turn.retry events for the same reason \u2014 read them together to see how many attempts were made before bailing. 'message' and 'turn' entries carry no importance \u2014 they are the substance, always read them.\",\n 'Event types: assistant.connected/disconnected (mount + placement + whether the session was created or restored), assistant.popout/popin (window placement), driver.created/wired/unwired (which driver is live and why it stops/starts responding across a popout), state.changed (idle\u2194loading), turn.start/turn.end (turn boundary; turn.end carries durationMs), turn.retry (a recoverable in-turn retry \u2014 detail.reason plus attempt/maxAttempts; for malformed calls also finishMessage; for empty responses also the provider finishReason + thoughtsTokens + parts breakdown), turn.error (a turn failed or hit a guardrail \u2014 detail.reason is one of exception/malformed-function-call/empty-response/unknown-tool-limit/max-iterations/response-truncated/refusal/budget-exhausted, plus reason-specific diagnostics: attempts (for empty-response also finishReason + thoughtsTokens + a parts breakdown, distinguishing a thinking-only STOP from a truly empty turn), finishMessage, for response-truncated the model + maxTokens + outputTokens + tools, unknownTools (split into staleTools \u2014 real earlier this activation but retired by the current state or hidden behind an open exclusive fold \u2014 and hallucinatedTools \u2014 never advertised) + availableTools, iterations + limit, for budget-exhausted the budgetUsd + spentUsd figures reported by the proxy plus the resolved vendor, or name + message for exceptions), tool.failed (a tool threw), tool.unresolved (the model called a tool that could not be dispatched \u2014 detail.kind is folded/fold-hidden/stale/unknown, plus tool + agent and, for the counted kinds, the consecutive streak; the recurring lead-up to an unknown-tool-limit turn.error), subagent.started/completed/failed (the lifecycle of a `requestSubAgent` delegation \u2014 detail.agent names the sub-agent; these bracket the sub-agent turns that appear as kind:turn entries with an N-M `turnIndex`; subagent.failed also carries detail.reason, one of max_iterations/malformed_tool_call/empty_response/unknown_tool_limit/timeout/response_truncated/refusal/budget_exhausted; budget_exhausted is terminal for the PARENT turn too \u2014 the parent stops rather than calling the model again into the same wall), agent.handoff (routing; from=null is the initial activation), agent.pinned/unpinned (forced routing), provider.selected (model/provider for the upcoming turns), interaction.requested/resolved (blocking user widgets \u2014 explain quiet gaps; note that when a sub-agent opens a widget, detail.agent \u2014 and the agentName on the interaction message \u2014 is the HOST agent that owns the widget, NOT the sub-agent that asked, because widgets render and resolve on the host driver), context.updated/threshold-crossed (token + cost), context.condensed (a stale tool payload was collapsed out of the model-bound history by a `condenseWhen` declaration on the tool \u2014 detail.tool + toolCallId, target args|response, trigger (superseded:<key> or age:<n>), stubLen, and an estimated tokensSaved; stored history and this log keep the FULL payload, so the model-visible slice at any point is the full history minus the condensations recorded up to then), panel.toggled, attachment.added, file.read-failed, suggestions.failed.',\n 'Sub-agent meta events: a sub-agent\\'s own turn.retry/turn.error/tool.failed/tool.unresolved events are merged into this same timeline, tagged with `detail.subAgent` \u2014 a `\"<parent> \u203A <sub-agent>\"` breadcrumb that composes when nested (e.g. `\"UI Builder \u203A Planner \u203A Grounding\"`) \u2014 and interleaved by their original timestamps within the subagent.started\u2192completed/failed bracket. These are the per-attempt/per-failure signals that do NOT appear among the sub-agent\\'s (hoisted) messages: a malformed/empty attempt that gets retried produces no message, and the stale-vs-hallucinated split and streak counts live only on the event. A sub-agent\\'s high-volume, message-derivable events (turn.start/turn.end, provider.selected, context.updated) are intentionally NOT merged \u2014 read its hoisted messages for model/tokens/cost and turn-by-turn activity, and the bracketing subagent.* events for the run\\'s span.',\n \"`meta` holds context captured at export time: agentSummary (full agent configs), context (active model, token usage, session cost), activeDebugSnapshot (the active agent's `getDebugSnapshot()` taken fresh at export \u2014 reflects state NOW, which may have advanced beyond the last turn's agentSnapshot), debug (optional host-supplied debug state), host, and the export timestamp.\",\n 'To debug a failure: find the last turn.error or tool.failed, then read upward for the user message, the turn(s), and the agent/provider/state events that led into it.',\n];\n\n/**\n * Removes all entries. Exposed for test isolation only \u2014 not part of the\n * public API.\n *\n * @internal\n */\nexport function clearMetaEventRegistry(): void {\n registry.clear();\n}\n", "import { createLogger } from '@genesislcap/foundation-logger';\n\nexport const logger = createLogger('ai-assistant');\n", "import type { InteractionContext } from '../types/interaction-context';\nimport { logger } from '../utils/logger';\n\n/**\n * A created {@link InteractionContext} plus the host-only `dispose` handle. The\n * driver keeps the handle (so it can tear the context down on resolve/evict) and\n * hands only `context` to the widget \u2014 widgets must not dispose their own context.\n *\n * @internal\n */\nexport interface InteractionContextHandle {\n readonly context: InteractionContext;\n /**\n * Run every registered `onDispose` callback once (in registration order), then\n * clear listeners. Idempotent. Called by the driver from `resolveInteraction`\n * and on driver teardown \u2014 never on element unmount.\n */\n dispose(): void;\n}\n\n/**\n * Create a live, per-interaction context (GENC-1390). Framework-agnostic: the\n * `subscribe`/`notify` pair is a plain observer set, not FAST reactivity. See\n * {@link InteractionContext} for the lifetime/semantics contract.\n *\n * @internal\n */\nexport function createInteractionContext(interactionId: string): InteractionContextHandle {\n const state: Record<string, unknown> = {};\n const onceCache = new Map<string, unknown>();\n const listeners = new Set<() => void>();\n const disposers = new Set<() => void>();\n let disposed = false;\n\n const context: InteractionContext = {\n interactionId,\n state,\n once<T>(key: string, factory: () => T): T | null {\n if (onceCache.has(key)) return onceCache.get(key) as T;\n // Interaction already ended (resolve/timeout/evict): refuse to run the factory.\n // A resource created here would leak \u2014 dispose has already run every `onDispose`\n // and won't run again. Return null so a stray late call (e.g. an async callback\n // that lands after a `timeoutMs` timeout) degrades instead of crashing or leaking.\n if (disposed) {\n logger.warn(\n `InteractionContext.once(\"${key}\") called after dispose; not creating a resource on an ended interaction.`,\n );\n return null;\n }\n const value = factory();\n onceCache.set(key, value);\n return value;\n },\n notify(): void {\n // A Set tolerates a listener unsubscribing mid-walk (matches\n // interaction-panel-session's forEach); a throwing subscriber must not stop the rest.\n for (const listener of listeners) {\n try {\n listener();\n } catch (e) {\n logger.error('InteractionContext subscriber threw during notify()', e);\n }\n }\n },\n subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n onDispose(fn: () => void): void {\n // Late registration after the interaction already ended: run immediately so\n // callers never leak a resource by registering a beat too late.\n if (disposed) {\n fn();\n return;\n }\n disposers.add(fn);\n },\n };\n\n return {\n context,\n dispose(): void {\n if (disposed) return;\n disposed = true;\n for (const fn of disposers) {\n try {\n fn();\n } catch (e) {\n logger.error('InteractionContext onDispose callback threw', e);\n }\n }\n disposers.clear();\n listeners.clear();\n // Release memoised `once` values (sockets, timers, service handles) for GC \u2014 the resources\n // themselves are closed via their `onDispose`, but drop the references too.\n onceCache.clear();\n },\n };\n}\n", "import type { ChatMessage, CondensePolicy, CondenseTrigger } from '@genesislcap/foundation-ai';\n\n/**\n * Tool-context condensation: collapse stale tool payloads out of the history\n * sent to the model, while leaving stored history untouched.\n *\n * The driver owns the registry (tool handlers populate it via `condenseWhen`)\n * and the cadence (this runs before every provider call). This module owns the\n * pure application: given the registry + the current loop iteration, produce a\n * rewritten copy of the history with stale args/results replaced by stubs. Kept\n * pure (no driver/session state, no logging) so it unit-tests in isolation \u2014\n * the one-time `context.condensed` signal is delivered via an `onCondensed`\n * callback rather than reaching into the debug-event log directly.\n *\n * @packageDocumentation\n */\n\n/**\n * Below this serialized size a tool payload isn't worth condensing \u2014 the stub\n * would save little and cost a breadcrumb. A driver-level floor so the public\n * `condenseWhen` API needs no per-policy threshold field.\n */\nexport const CONDENSE_MIN_CHARS = 1000;\n\n/** Key the collapsed args are stored under \u2014 a tool-call's args must stay a Record. */\nexport const CONDENSED_ARGS_KEY = 'condensed';\n\n/**\n * Rough chars-per-token divisor for the `tokensSaved` estimate. No tokenizer is\n * available in this stack; ~4 chars/token is the usual English approximation.\n */\nconst APPROX_CHARS_PER_TOKEN = 4;\n\n/**\n * A `condenseWhen` policy registered against a tool-call id, with its age clock\n * and report-once flags. The driver holds these in a `Map<toolCallId, \u2026>`;\n * {@link applyCondensation} reads them and flips the `reported*` flags so the\n * `context.condensed` signal fires once per payload, not once per provider call.\n */\nexport interface RegisteredCondensePolicy {\n policy: CondensePolicy;\n /**\n * Monotonic model-call sequence (`modelCallSeq`) when `condenseWhen` was called\n * \u2014 the origin of the age clock. Driver-lifetime and NOT reset per turn, so age\n * is measured consistently across turn boundaries (the field name is historical;\n * it is not the per-turn loop iteration).\n */\n iteration: number;\n /** Turn (`sendMessage`) sequence when the call was made \u2014 the `turnEnd` clock. */\n turn: number;\n /** Agent-activation sequence when the call was made \u2014 the `agentEnd` clock. */\n activation: number;\n /** App-controlled phase epoch when the call was made \u2014 the `phaseEnd` clock. */\n phaseEpoch: number;\n /** `context.condensed` already emitted for the args payload (fire-once). */\n reportedArgs?: boolean;\n /** `context.condensed` already emitted for the response payload (fire-once). */\n reportedResponse?: boolean;\n}\n\n/**\n * The driver's live state at the moment of a provider call \u2014 the clocks every\n * trigger is evaluated against. Passed by the driver; kept as an interface so the\n * transform stays a pure function of (history, policies, clocks).\n */\nexport interface CondenseContext {\n /** Monotonic model-call sequence now \u2014 the `age` clock. */\n modelCall: number;\n /** Monotonic turn (`sendMessage`) sequence now \u2014 the `turnEnd` clock. */\n turn: number;\n /** Whether the agent activation that made a call has since ended \u2014 the `agentEnd` clock. */\n activationEnded: (activation: number) => boolean;\n /**\n * Whether a later phase epoch is current than the one a call was made in \u2014 the\n * `phaseEnd` clock. True once `endPhase()` has been called since the call.\n */\n phaseEnded: (phaseEpoch: number) => boolean;\n /**\n * Collapse in batches of this many model-calls instead of continuously. A positive\n * integer; decimals are floored and anything below `1` becomes `1`. Omit (or `1`) to\n * collapse as soon as a trigger fires, which is the historical behaviour.\n *\n * Condensation rewrites a payload *in place*, so the model-bound history is not\n * append-only and every prompt-cache entry written before the rewrite is invalidated\n * from that position on. Collapsing the moment each trigger fires therefore breaks the\n * cache on nearly every call of a re-read loop \u2014 the case condensation exists to\n * contain. Batching holds the collapse set still between boundaries so the prefix is\n * append-only in between, trading up to `batchCalls` calls' worth of extra context for\n * one cache break per batch instead of one per call.\n *\n * `agentEnd` and `phaseEnd` are exempt and still collapse as they fire: they mark a\n * discontinuity that invalidates the cached prefix anyway, so deferring them would hold\n * stale payloads longer for nothing.\n */\n batchCalls?: number;\n}\n\n/**\n * Structured detail for a `context.condensed` meta-event. The index signature\n * lets it satisfy `recordMetaEvent`'s `Record<string, unknown>` detail param\n * while the named fields stay strictly typed.\n */\nexport interface CondensedEventDetail {\n [key: string]: unknown;\n /** Tool-loop iteration the collapsed call was made on. */\n turn: number;\n toolCallId: string;\n tool: string;\n target: 'args' | 'response';\n /** Human-readable trigger, e.g. `superseded:Foo.tsx` or `age:3`. */\n trigger: string;\n /** Length of the replacement stub. */\n stubLen: number;\n /** Estimated input tokens saved this collapse (char/4 \u2014 no tokenizer in-stack). */\n tokensSaved: number;\n}\n\n/** Short human-readable reason for the stub text, per fired trigger. */\nfunction triggerReason(trigger: CondenseTrigger): string {\n switch (trigger.kind) {\n case 'age':\n return 'aged out';\n case 'turnEnd':\n return 'turn ended';\n case 'agentEnd':\n return 'agent finished';\n case 'phaseEnd':\n return 'phase ended';\n default:\n return 'superseded';\n }\n}\n\n/** Framework-generated `pointer` stub \u2014 advertises that re-calling restores the content. */\nfunction condenseStub(\n target: 'args' | 'response',\n tool: string,\n trigger: CondenseTrigger,\n origLen: number,\n): string {\n const what = target === 'args' ? 'args' : 'result';\n const key = trigger.kind === 'superseded' ? ` ${trigger.by}` : '';\n return `[${tool}${key} \u2014 ${what} elided, ~${origLen} chars (${triggerReason(trigger)}); re-call to restore]`;\n}\n\n/** Stable label for the `context.condensed` meta-event's `trigger` field. */\nfunction triggerLabel(trigger: CondenseTrigger): string {\n switch (trigger.kind) {\n case 'age':\n return `age:${trigger.turns}`;\n case 'superseded':\n return `superseded:${trigger.by}`;\n default:\n return trigger.kind; // 'turnEnd' | 'agentEnd' | 'phaseEnd'\n }\n}\n\nfunction estimateTokensSaved(origLen: number, stubLen: number): number {\n return Math.max(0, Math.ceil((origLen - stubLen) / APPROX_CHARS_PER_TOKEN));\n}\n\n/**\n * Whether a trigger marks a genuine discontinuity rather than firing continuously, and so is\n * exempt from batching.\n *\n * `agentEnd` advances only when the active agent's name changes (or a sub-agent completes /\n * the agent is released), which swaps the system prompt and tool definitions \u2014 those render\n * before the messages, so the cached prefix is invalidated at that point regardless. `phaseEnd`\n * is the app declaring the same kind of boundary explicitly, and falls back to `agentEnd`.\n * Deferring either to the next batch would buy no cache and only hold stale payloads longer.\n *\n * The rest fire continuously (`superseded`, `age`) or at a point where the history is otherwise\n * append-only (`turnEnd` \u2014 a new turn appends a user message, leaving the previous entry live),\n * so batching them is exactly where the cache is won.\n */\nfunction marksDiscontinuity(kind: CondenseTrigger['kind']): boolean {\n return kind === 'agentEnd' || kind === 'phaseEnd';\n}\n\n/**\n * Collapse stale tool payloads (declared via `condenseWhen`) out of the\n * model-bound history. Pure over the `history` array \u2014 it emits new message\n * objects and never mutates the input messages (mirroring the agent-masking\n * transform). It DOES, however, flip the `reported*` flag on the matching\n * `policies` entry the first time a payload collapses \u2014 the report-once gate that\n * keeps `onCondensed` firing once per (tool call, payload) even though the\n * collapse itself re-runs before every provider call.\n *\n * Triggers (a policy may list several via `on: Trigger[]` \u2014 the FIRST to fire\n * collapses the payload; all are monotonic, so the collapse never reverts):\n * - `superseded` \u2014 among all registered calls sharing a `by` key, the LAST in\n * history order survives; every earlier one's targeted payload collapses. A\n * re-call with the same key becomes the new survivor and re-arms the rest.\n * - `age` \u2014 the result is first visible one model-call after the call, so `turns`\n * is how many model-calls may see the full result before it collapses\n * (fires when `modelCall \u2212 callModelCall > turns`): `turns: 1` is seen once,\n * then collapses. The clock is monotonic across turns.\n * - `turnEnd` \u2014 collapses once the turn (`sendMessage`) that made the call has\n * ended (fires when `turn > callTurn`): full for the rest of that request,\n * gone on every later one.\n * - `agentEnd` \u2014 collapses once the agent activation that made the call has ended\n * (a swap to another agent, or `releaseAgent`/`completeSubAgent`): kept across\n * all of the agent's turns, dropped when its flow finishes.\n * - `phaseEnd` \u2014 collapses once the app advances its phase epoch via `endPhase()`\n * after the call (a sub-`agentEnd` boundary the author declares), OR at\n * `agentEnd` as a backstop if no boundary is ever declared.\n *\n * The tool-call/result envelope is never removed (providers reject orphaned\n * calls/results) \u2014 only the args object or the result content is replaced.\n *\n * @param history - The to-model history copy to rewrite (not mutated).\n * @param policies - The driver's registry, keyed by tool-call id. Its entries'\n * `reported*` flags are flipped as payloads first collapse.\n * @param ctx - The driver's live clocks (model-call / turn / agent-activation).\n * @param onCondensed - Invoked once per payload at its full\u2192stub transition.\n */\nexport function applyCondensation(\n history: ChatMessage[],\n policies: Map<string, RegisteredCondensePolicy>,\n ctx: CondenseContext,\n onCondensed: (detail: CondensedEventDetail) => void,\n): ChatMessage[] {\n if (policies.size === 0) return history;\n\n const triggersOf = (entry: RegisteredCondensePolicy): CondenseTrigger[] =>\n Array.isArray(entry.policy.on) ? entry.policy.on : [entry.policy.on];\n\n // One pass: resolve supersession survivors and a toolCallId \u2192 tool-name\n // lookup. For each `superseded` key the LAST call in history order survives.\n // The name lookup lets a tool message (which carries only an id) name its tool\n // in stubs and events.\n // Batch boundary: the collapse set is resolved as of this model-call and stays put\n // until the next boundary, so the prefix is append-only in between. `batchCalls` of 1\n // (the default) makes this `ctx.modelCall` \u2014 i.e. no batching.\n const batchCalls = Math.max(1, Math.floor(ctx.batchCalls ?? 1));\n const asOf =\n batchCalls === 1 ? ctx.modelCall : Math.floor(ctx.modelCall / batchCalls) * batchCalls;\n // A call made after the boundary is invisible to this pass in BOTH directions: it\n // cannot supersede an older call (which would collapse the older payload early), and\n // it cannot itself collapse (which would elide the very result just fetched). Unbatched,\n // the boundary is the live clock and this gate is off entirely \u2014 a call registered on\n // the current model-call is still eligible, as it always was.\n const withinBatch = (entry: RegisteredCondensePolicy): boolean =>\n batchCalls === 1 || entry.iteration <= asOf;\n\n const latestByKey = new Map<string, string>();\n const nameById = new Map<string, string>();\n for (const msg of history) {\n if (!msg.toolCalls?.length) continue;\n for (const tc of msg.toolCalls) {\n nameById.set(tc.id, tc.name);\n const entry = policies.get(tc.id);\n if (!entry || !withinBatch(entry)) continue;\n for (const t of triggersOf(entry)) {\n if (t.kind === 'superseded') latestByKey.set(t.by, tc.id);\n }\n }\n }\n\n const triggerFires = (\n toolCallId: string,\n entry: RegisteredCondensePolicy,\n trig: CondenseTrigger,\n ): boolean => {\n switch (trig.kind) {\n // Result first visible one model-call after the call, so collapse one call\n // past the last allowed view: turns:1 \u2192 seen once, then gone. Monotonic\n // clock, so this holds across turn boundaries too.\n case 'age':\n return asOf - entry.iteration > trig.turns;\n case 'turnEnd':\n return ctx.turn > entry.turn;\n case 'agentEnd':\n return ctx.activationEnded(entry.activation);\n // Fires when the app advanced the phase epoch since the call \u2014 OR, as a\n // backstop, when the whole activation has ended, so a phase boundary that\n // is never declared still collapses at `agentEnd` rather than never.\n case 'phaseEnd':\n return ctx.phaseEnded(entry.phaseEpoch) || ctx.activationEnded(entry.activation);\n default:\n return latestByKey.get(trig.by) !== toolCallId; // superseded by a newer call\n }\n };\n\n // The first listed trigger that fires \u2014 drives the collapse, the stub reason,\n // and the event label. `undefined` means the payload stays full.\n const firstFired = (\n toolCallId: string,\n entry: RegisteredCondensePolicy,\n ): CondenseTrigger | undefined =>\n triggersOf(entry).find(\n (t) =>\n (marksDiscontinuity(t.kind) || withinBatch(entry)) && triggerFires(toolCallId, entry, t),\n );\n\n return history.map((msg) => {\n // Tool-call ARGS live on the assistant message.\n if (msg.toolCalls?.length) {\n let changed = false;\n const toolCalls = msg.toolCalls.map((tc) => {\n const entry = policies.get(tc.id);\n if (!entry?.policy.args) return tc;\n const fired = firstFired(tc.id, entry);\n if (!fired) return tc;\n const origLen = JSON.stringify(tc.args ?? {}).length;\n if (origLen < CONDENSE_MIN_CHARS) return tc;\n changed = true;\n const result = entry.policy.args;\n // Args must stay a Record; `drop` is an empty object, otherwise stash the\n // stub under a single key. Spread `tc` so providerMetadata (e.g. the\n // Gemini reasoning signature that must round-trip) and UI fields survive.\n const args: Record<string, unknown> =\n result === 'drop'\n ? {}\n : {\n [CONDENSED_ARGS_KEY]:\n result === 'pointer'\n ? condenseStub('args', tc.name, fired, origLen)\n : result.replaceWith,\n };\n if (!entry.reportedArgs) {\n entry.reportedArgs = true;\n const stubLen = JSON.stringify(args).length;\n onCondensed({\n turn: entry.iteration,\n toolCallId: tc.id,\n tool: tc.name,\n target: 'args',\n trigger: triggerLabel(fired),\n stubLen,\n tokensSaved: estimateTokensSaved(origLen, stubLen),\n });\n }\n return { ...tc, args };\n });\n return changed ? { ...msg, toolCalls } : msg;\n }\n\n // The tool RESULT lives on the tool message.\n if (msg.toolResult) {\n const entry = policies.get(msg.toolResult.toolCallId);\n // Defensive `?? 0` for restored/malformed history \u2014 `content` is typed\n // `string`, but a 0-length payload is simply below the floor and skipped.\n const origLen = msg.toolResult.content?.length ?? 0;\n const fired = entry?.policy.response\n ? firstFired(msg.toolResult.toolCallId, entry)\n : undefined;\n if (entry && fired && origLen >= CONDENSE_MIN_CHARS) {\n const tool = nameById.get(msg.toolResult.toolCallId) ?? msg.toolResult.toolCallId;\n const result = entry.policy.response!; // `fired` is only set when response is declared\n // Kept non-empty \u2014 Anthropic rejects empty tool_result content.\n const content =\n result === 'drop'\n ? '[elided]'\n : result === 'pointer'\n ? condenseStub('response', tool, fired, origLen)\n : result.replaceWith;\n if (!entry.reportedResponse) {\n entry.reportedResponse = true;\n onCondensed({\n turn: entry.iteration,\n toolCallId: msg.toolResult.toolCallId,\n tool,\n target: 'response',\n trigger: triggerLabel(fired),\n stubLen: content.length,\n tokensSaved: estimateTokensSaved(origLen, content.length),\n });\n }\n return { ...msg, toolResult: { ...msg.toolResult, content } };\n }\n }\n\n return msg;\n });\n}\n", "import type { ChatMessage } from '@genesislcap/foundation-ai';\n\n/**\n * Masks the tool-specific payload of a single message \u2014 clears tool call args\n * and replaces tool result content with a placeholder. Used when passing history\n * to an agent that should not see another agent's implementation detail.\n */\nfunction maskToolPayload(msg: ChatMessage): ChatMessage {\n if (msg.toolCalls?.length) {\n return { ...msg, toolCalls: msg.toolCalls.map((tc) => ({ ...tc, args: {} })) };\n }\n if (msg.toolResult) {\n return {\n ...msg,\n toolResult: { ...msg.toolResult, content: \"[other agent's tool result omitted]\" },\n };\n }\n return msg;\n}\n\n/**\n * Prepares history for the LLM only: masks tool call args and results from other\n * agents so the active specialist is not confused by tools it does not have.\n * Canonical history in `ChatDriver` stays unmasked for UI and logging.\n */\nexport function transformHistoryForAgent(history: ChatMessage[], agentName: string): ChatMessage[] {\n return history.map((msg) => {\n if (!msg.agentName || msg.agentName === agentName) return msg;\n return maskToolPayload(msg);\n });\n}\n\n/**\n * Applies a history cap for sub-agent context: the last `cap` messages are passed\n * verbatim; older messages have their tool payloads masked.\n */\nexport function applyHistoryCap(history: readonly ChatMessage[], cap: number): ChatMessage[] {\n const cutoff = history.length - cap;\n return history.map((msg, i) => (i < cutoff ? maskToolPayload(msg) : msg));\n}\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Compaction (GENC-1351 \u00A75.7) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Recent messages kept verbatim when compacting; everything earlier is summarized. */\nexport const COMPACT_KEEP_RECENT_MESSAGES = 4;\n\n/** Don't bother compacting unless at least this many messages would be summarized. */\nexport const COMPACT_MIN_MESSAGES_TO_COMPACT = 4;\n\n/**\n * Index at which the verbatim tail begins \u2014 everything before it gets summarized.\n * The tail starts on a clean turn boundary (a `user` message): a user message\n * never appears between a `tool_use` and its `tool_result`, so cutting there\n * guarantees the summarized region is tool-pair-balanced (compaction only runs\n * when idle, so history is turn-complete). Returns `null` when there is nothing\n * worth compacting (too short, or no earlier user boundary) \u2014 e.g. a freshly\n * restored session whose only user turn is the current one.\n */\nexport function findCompactionCut(history: readonly ChatMessage[]): number | null {\n if (history.length < COMPACT_KEEP_RECENT_MESSAGES + COMPACT_MIN_MESSAGES_TO_COMPACT) {\n return null;\n }\n const target = history.length - COMPACT_KEEP_RECENT_MESSAGES;\n for (let i = target; i > 0; i -= 1) {\n if (history[i].role === 'user') {\n return i >= COMPACT_MIN_MESSAGES_TO_COMPACT ? i : null;\n }\n }\n return null;\n}\n\n/** One-line rendering of a message for the summarizer transcript. */\nfunction renderMessageForSummary(m: ChatMessage): string {\n switch (m.role) {\n case 'compacted-summary':\n return `[Earlier summary] ${m.content}`;\n case 'user':\n return m.content ? `User: ${m.content}` : '';\n case 'assistant': {\n // Reasoning (\"Thinking\") and narration (\"Working\") are display-only assistant splits\n // (GENC-1410) with no tool calls of their own \u2014 fold them into the summary too, labelled\n // the same as the UI so the summarizer knows they were internal, not a final answer.\n if (m.category === 'reasoning') {\n return m.content ? `Thinking: ${m.content}` : '';\n }\n if (m.category === 'narration') {\n return m.content ? `Working: ${m.content}` : '';\n }\n if (m.toolCalls?.length) {\n const calls = m.toolCalls.map((t) => t.name).join(', ');\n return m.content\n ? `Assistant: ${m.content} (called: ${calls})`\n : `Assistant called: ${calls}`;\n }\n return m.content ? `Assistant: ${m.content}` : '';\n }\n case 'tool':\n return m.toolResult ? `Tool result: ${m.toolResult.content}` : '';\n default:\n return ''; // system-event / synthetic-user \u2014 not part of the model transcript\n }\n}\n\n/**\n * Build the one-shot summarizer prompt for a run of older messages (used with\n * `AIProvider.prompt`). Mirrors the `<conversation_history>` block convention\n * that suggestions use. Any existing `compacted-summary` at the head is folded\n * in (rendered as prior-summary context), so rolling re-compaction produces one\n * combined summary.\n */\nexport function buildCompactionSummaryPrompt(toCompact: readonly ChatMessage[]): {\n systemPrompt: string;\n userMessage: string;\n} {\n const transcript = toCompact.map(renderMessageForSummary).filter(Boolean).join('\\n');\n const systemPrompt =\n 'You compress a conversation transcript into a concise summary that lets an AI ' +\n 'assistant continue the conversation seamlessly. Preserve key facts, decisions, ' +\n 'what the user wants, entity names and IDs, and any unresolved threads. Write ' +\n 'plain prose. Never roleplay or continue the conversation.';\n const userMessage =\n `<conversation_history>\\n${transcript}\\n</conversation_history>\\n\\n` +\n 'Summarize the conversation above so it can be dropped from context while ' +\n 'preserving everything needed to continue. Output only the summary prose.';\n return { systemPrompt, userMessage };\n}\n\n/**\n * Normalize history for a provider request (GENC-1351 \u00A75.7): translate each\n * `compacted-summary` message into a `user` message that wraps its summary in a\n * `<conversation_summary>` block, so the raw display-only role never reaches a\n * transport. Other roles pass through untouched. Pure \u2014 returns a new array.\n *\n * Applied at the request-build chokepoint *before* per-agent masking, so the\n * guarantee holds for every provider/transport regardless of any optional\n * per-agent history transform.\n */\nexport function normalizeForProvider(history: readonly ChatMessage[]): ChatMessage[] {\n return history.map((m) => {\n if (m.role !== 'compacted-summary') return m;\n return {\n ...m,\n role: 'user',\n content:\n `<conversation_summary>\\n${m.content}\\n</conversation_summary>\\n\\n` +\n 'The above summarizes earlier parts of this conversation that were compacted. ' +\n 'Continue naturally from it.',\n compaction: undefined,\n };\n });\n}\n\n/** Human-facing divider label for a `compacted-summary` message. */\nexport function compactionDividerLabel(m: ChatMessage): string {\n const n = m.compaction?.compactedCount ?? 0;\n return `Compacted ${n} earlier message${n === 1 ? '' : 's'}`;\n}\n", "import type { AggregateUsage, ChatMessage } from '@genesislcap/foundation-ai';\n\n/**\n * Zeroed {@link AggregateUsage}. A factory, not a shared const, because callers\n * accumulate into the returned object.\n *\n * @internal\n */\nexport function emptyUsage(): AggregateUsage {\n return {\n costUsd: 0,\n uncachedInputTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n outputTokens: 0,\n };\n}\n\n/**\n * Total tokens processed \u2014 the four buckets added up. Safe to sum because the\n * buckets are disjoint (see {@link AggregateUsage}); the equivalent sum over\n * per-message fields would double-count the prompt.\n *\n * Bear in mind what this number is: because every turn resends the conversation,\n * a turn's prompt is counted again in the next turn's. It is billed throughput,\n * NOT the count of distinct tokens in the conversation, so it grows\n * super-linearly with turn count and is expected to dwarf the context size.\n *\n * @internal\n */\nexport function totalTokens(usage: AggregateUsage): number {\n return (\n usage.uncachedInputTokens + usage.cacheReadTokens + usage.cacheWriteTokens + usage.outputTokens\n );\n}\n\n/**\n * `a + b`, per bucket, as a new object.\n *\n * Used to lay a row's banked (pre-transcript) spend over what the live transcript\n * proves. Pure rather than in-place because both operands are live state a caller\n * must not mutate.\n *\n * @internal\n */\nexport function addUsage(a: AggregateUsage, b: AggregateUsage): AggregateUsage {\n return {\n costUsd: a.costUsd + b.costUsd,\n uncachedInputTokens: a.uncachedInputTokens + b.uncachedInputTokens,\n cacheReadTokens: a.cacheReadTokens + b.cacheReadTokens,\n cacheWriteTokens: a.cacheWriteTokens + b.cacheWriteTokens,\n outputTokens: a.outputTokens + b.outputTokens,\n };\n}\n\n/**\n * Sum cost and per-bucket token usage across a message list.\n *\n * One walk produces everything a usage display needs, replacing separate cost and\n * token passes over the same (potentially deep) transcript. Recurses into each\n * tool call's `subAgentTrace`, so LLM work a sub-agent did \u2014 possibly on another\n * provider at other rates \u2014 lands in the total; the driver embeds a whole\n * sub-agent conversation in the parent's tool result, so this is the only place\n * that spend is visible.\n *\n * Splitting the prompt into buckets is the point: `cost` already has the cache\n * discount applied, but a single token total cannot show that a session was cheap\n * because most of its prompt was a cache hit. The three input buckets are derived\n * from the per-message fields, where `inputTokens` is the whole prompt and the\n * cache fields break it down \u2014 so uncached input is the remainder, never an\n * addition.\n *\n * Also counts `compaction.rolledUpUsage`: compaction destroys the messages it\n * summarises, and without their banked usage every total re-derived from the\n * transcript would drop by whatever those turns had already spent.\n *\n * Returns a zeroed total when no message carries usage \u2014 providers that report\n * none (e.g. Chrome built-in) are skipped silently rather than guessed at.\n *\n * @internal\n */\nexport function sumUsage(messages: readonly ChatMessage[]): AggregateUsage {\n const total = emptyUsage();\n accumulate(messages, total);\n return total;\n}\n\n/** Add `from` into `into`, in place. */\nfunction addInto(into: AggregateUsage, from: AggregateUsage): void {\n into.costUsd += from.costUsd;\n into.uncachedInputTokens += from.uncachedInputTokens;\n into.cacheReadTokens += from.cacheReadTokens;\n into.cacheWriteTokens += from.cacheWriteTokens;\n into.outputTokens += from.outputTokens;\n}\n\n/**\n * Walk `messages`, accumulating into `into`. Mutates a single accumulator rather\n * than merging returned objects \u2014 this runs on every transcript change, so the\n * per-message allocation is worth avoiding.\n */\nfunction accumulate(messages: readonly ChatMessage[], into: AggregateUsage): void {\n for (const m of messages) {\n // Provider/LLM cost plus any non-LLM cost a widget reported for its own\n // external service calls. Both are real spend on this session.\n if (m.cost != null) into.costUsd += m.cost;\n if (m.externalCostUsd != null) into.costUsd += m.externalCostUsd;\n\n const cacheRead = m.cacheReadTokens ?? 0;\n const cacheWrite = m.cacheWriteTokens ?? 0;\n into.cacheReadTokens += cacheRead;\n into.cacheWriteTokens += cacheWrite;\n // The uncached remainder of the prompt. Clamped at zero so malformed or\n // hand-edited history whose buckets exceed the prompt total can't drive the\n // session total negative \u2014 a wrong-but-plausible number is worse than a\n // conservative one here, since this feeds a cost display.\n into.uncachedInputTokens += Math.max(0, (m.inputTokens ?? 0) - cacheRead - cacheWrite);\n into.outputTokens += m.outputTokens ?? 0;\n\n // Spend banked by a compaction on this summary's behalf. NOTE: deliberately\n // not `compaction.tokensBefore` \u2014 that is a one-turn context-window reading,\n // not cumulative spend, and counting it here would inflate the total.\n const rolled = m.compaction?.rolledUpUsage;\n if (rolled) addInto(into, rolled);\n\n for (const tc of m.toolCalls ?? []) {\n if (tc.subAgentTrace) accumulate(tc.subAgentTrace, into);\n }\n }\n}\n", "import type { ChatToolDefinition, ChatToolHandlers } from '@genesislcap/foundation-ai';\n\n/**\n * Symbol used to attach ToolFold metadata to a facade handler function.\n * The ChatDriver inspects this to detect fold facades at runtime.\n *\n * @internal\n */\nexport const TOOL_FOLD_SYMBOL = Symbol('toolFold');\n\n/**\n * Internal metadata for a tool fold. Attached to the facade handler via TOOL_FOLD_SYMBOL.\n *\n * @internal\n */\nexport interface ToolFold {\n /** Facade tool name. */\n name: string;\n /** Description shown to the model. */\n description: string;\n /** Optional guidance injected in the fold-open response. */\n usageNotes?: string;\n /** Tool definitions inside this fold. */\n tools: ChatToolDefinition[];\n /** Handlers for the inner tools (keyed by tool name). */\n handlers: ChatToolHandlers;\n /**\n * When true (default), all other tools are removed when this fold opens \u2014\n * the model can only see this fold's tools until it closes.\n * When false, sibling tools remain alongside the inner tools.\n */\n exclusive: boolean;\n}\n\n/**\n * The value returned by `createToolFold`.\n *\n * @beta\n */\nexport interface ToolFoldResult {\n /**\n * The facade tool definition. Add this to your agent's `toolDefinitions`.\n * It is a regular `ChatToolDefinition` with an empty parameter schema.\n */\n definition: ChatToolDefinition;\n /**\n * The facade handler \u2014 a single-entry map keyed by the fold name.\n * Spread this into your agent's `toolHandlers`.\n * Inner tool handlers are NOT included here \u2014 they are encapsulated inside\n * the fold metadata and installed by the driver only when the fold opens.\n */\n handler: ChatToolHandlers;\n}\n\n/**\n * Creates a tool fold \u2014 a facade that hides a group of related tools behind a single\n * named entry, revealing them progressively when the model invokes the facade.\n *\n * The `tools` and `handlers` parameters accept the exact same types as `AgentConfig.toolDefinitions`\n * and `AgentConfig.toolHandlers`, so existing tool creation functions can be passed in unchanged.\n *\n * @example\n * ```typescript\n * const tradingTools = createToolFold({\n * name: 'trading_tools',\n * tools: createTradesToolDefinitions(),\n * handlers: createTradesToolHandlers(connect),\n * });\n *\n * const agent: AgentConfig = {\n * name: 'Trades',\n * systemPrompt: '...',\n * toolDefinitions: [getCurrentDateDef, tradingTools.definition],\n * toolHandlers: { get_current_date: handler, ...tradingTools.handler },\n * };\n * ```\n *\n * @example Nesting folds\n * ```typescript\n * const insertFold = createToolFold({\n * name: 'trade_insertion',\n * tools: [validateDef, insertDef],\n * handlers: { validate_trade: vHandler, insert_trade: iHandler },\n * });\n *\n * const tradingFold = createToolFold({\n * name: 'trading_tools',\n * tools: [searchDef, insertFold.definition],\n * handlers: { search_trades: sHandler, ...insertFold.handler },\n * });\n * ```\n *\n * @beta\n */\nexport function createToolFold(config: {\n /** Facade tool name \u2014 used as the tool name the model calls to open this fold. */\n name: string;\n /**\n * Description shown to the model for the facade tool.\n * If omitted, auto-generated from the inner tool names:\n * \"Contains: tool_a, tool_b. Invoke to access these tools.\"\n */\n description?: string;\n /**\n * Optional usage guidance injected into the fold-open response message.\n * Not included in the facade description \u2014 only visible once the fold is open.\n */\n usageNotes?: string;\n /** Inner tool definitions. Same type as `AgentConfig.toolDefinitions`. */\n tools: ChatToolDefinition[];\n /** Inner tool handlers. Same type as `AgentConfig.toolHandlers`. */\n handlers: ChatToolHandlers;\n /**\n * When true (default), all other tools are removed when this fold opens.\n * When false, sibling tools remain available alongside the inner tools.\n */\n exclusive?: boolean;\n}): ToolFoldResult {\n const description =\n config.description ??\n `Contains: ${config.tools.map((t) => t.name).join(', ')}. Invoke to access these tools.`;\n\n const fold: ToolFold = {\n name: config.name,\n description,\n usageNotes: config.usageNotes,\n tools: config.tools,\n handlers: config.handlers,\n exclusive: config.exclusive ?? true,\n };\n\n const definition: ChatToolDefinition = {\n name: config.name,\n description,\n parameters: { type: 'object', properties: {} },\n };\n\n // The facade handler body is never actually called \u2014 the driver intercepts it\n // via TOOL_FOLD_SYMBOL before dispatch. The body is a no-op fallback.\n const facadeHandler = async (): Promise<string> => `Fold: ${config.name}`;\n (facadeHandler as any)[TOOL_FOLD_SYMBOL] = fold;\n\n return {\n definition,\n handler: {\n [config.name]: facadeHandler,\n },\n };\n}\n\n/**\n * A tool entry in the expanded debug tree.\n * Folds are represented as nodes with a `tools` array; regular tools have none.\n *\n * @beta\n */\nexport interface ToolTreeNode extends ChatToolDefinition {\n /** Present when this tool is a fold \u2014 contains its inner tools recursively expanded. */\n tools?: ToolTreeNode[];\n}\n\n/**\n * Expands a flat list of tool definitions into a nested tree by resolving fold\n * metadata from the corresponding handlers. Use this for debug output so the\n * full tool hierarchy is visible rather than just the top-level facade names.\n *\n * @beta\n */\nexport function expandToolTree(\n definitions: ChatToolDefinition[],\n handlers: ChatToolHandlers,\n): ToolTreeNode[] {\n return definitions.map((def) => {\n const handler = handlers[def.name];\n const fold: ToolFold | undefined = handler ? (handler as any)[TOOL_FOLD_SYMBOL] : undefined;\n if (fold) {\n return { ...def, tools: expandToolTree(fold.tools, fold.handlers) };\n }\n return { ...def };\n });\n}\n", "import type {\n AIProvider,\n AIProviderRegistry,\n AIProviderType,\n CachePolicy,\n ChatAttachment,\n ChatDriverResult,\n ChatFallback,\n ChatMessage,\n ChatRequestOptions,\n ChatToolCall,\n ChatToolChoice,\n ChatToolDefinition,\n ChatToolHandlers,\n CondensePolicy,\n CondenseTrigger,\n InteractionRequestOptions,\n InteractionResult,\n SubAgentFailureReason,\n SubAgentRequestOptions,\n TurnFailureReason,\n} from '@genesislcap/foundation-ai';\nimport {\n BudgetExhaustedError,\n DEFAULT_BUDGET_EXHAUSTED_MESSAGE,\n isObservableAIProviderRegistry,\n MalformedFunctionCallError,\n ResponseTruncatedError,\n vendorTypeOfLabel,\n} from '@genesislcap/foundation-ai';\nimport { type ActivityBus, NOOP_ACTIVITY_BUS } from '../../channel/ai-activity-bus';\nimport type {\n AgentConfig,\n CachePolicyInput,\n ProviderInput,\n ResponseSchemaInput,\n SystemPromptContext,\n SystemPromptInput,\n TailContextInput,\n TemperatureInput,\n ToolChoiceInput,\n ToolDefinitionsInput,\n ToolHandlersInput,\n UnresolvedToolInput,\n} from '../../config/config';\nimport { resolveChatProvider } from '../../config/validate-providers';\nimport {\n clearSession,\n getMetaEvents,\n type MetaEvent,\n mergeMetaEvents,\n type MetaEventType,\n recordMetaEvent,\n recordTurnError,\n recordTurnRetry,\n} from '../../state/debug-event-log';\nimport {\n createInteractionContext,\n type InteractionContextHandle,\n} from '../../state/interaction-context';\nimport type { DiagnosticEntry } from '../../state/persistence/diagnostics';\nimport type { InteractionContext } from '../../types/interaction-context';\nimport { applyCondensation, type RegisteredCondensePolicy } from '../../utils/condense-history';\nimport {\n applyHistoryCap,\n buildCompactionSummaryPrompt,\n findCompactionCut,\n normalizeForProvider,\n} from '../../utils/history-transform';\nimport { logger } from '../../utils/logger';\nimport { sumUsage } from '../../utils/sum-usage';\nimport { TOOL_FOLD_SYMBOL, type ToolFold } from '../../utils/tool-fold';\nimport type { AiDriver, AllAgentSummary } from '../ai-driver/ai-driver';\n\n/**\n * The `budget` payload carried on a `'budget-exhausted'` {@link ChatDriverResult}.\n * Derived from the type rather than restated so the two cannot drift.\n */\ntype BudgetDetail = NonNullable<Extract<ChatDriverResult, { reason: 'done' }>['budget']>;\n\n/**\n * Lift the reportable facts off a {@link BudgetExhaustedError}, or `undefined`\n * when it carries none.\n *\n * \"None\" means **no figures AND no attributable vendor** \u2014 not merely no\n * figures. Dropping the whole object on a figure-less 402 also dropped\n * `vendorLabel`, which is the authoritative attribution source, and left the\n * element's latch falling back to the driver's last-resolved provider, i.e. the\n * PREVIOUS turn's vendor. A turn-1 Gemini call followed by a turn-2 classifier\n * refused by Anthropic with a figure-less 402 then walled *Gemini* and advised\n * switching to the vendor that had actually run out. Three live shapes reach\n * here with no figures \u2014 a bare gateway 402, a code-only body, and the framed\n * err frame whose figures are `null` (which the proxy now prefers over a\n * misleading `0`, so this path is getting more common, not less).\n *\n * The figures alone still decide whether banner copy is composed \u2014 see\n * `formatBlockedReason`, which returns `undefined` for a figure-less budget so a\n * host-set explanation survives the latch.\n */\nconst budgetDetailOf = (e: BudgetExhaustedError): BudgetDetail | undefined => {\n // The typed vendor is derived from the LABEL, not from `lastResolvedProvider`:\n // the label comes from the transport that was actually refused, whereas the\n // last-resolved provider is stale on the classification seam (an orchestrated\n // turn classifies against the registry default, which this driver may never\n // have resolved). The proxy's own `vendor` is the fallback for a transport\n // whose static label no vendor claims (a multiplexing or white-labelled\n // gateway). Omitted rather than set to `undefined` when neither resolves, so\n // \"we know the vendor\" stays testable by presence alone.\n const vendor = vendorTypeOfLabel(e.vendorLabel) ?? vendorTypeOfLabel(e.serverVendor);\n if (e.budgetUsd == null && e.spentUsd == null && !vendor) return undefined;\n return {\n budgetUsd: e.budgetUsd,\n spentUsd: e.spentUsd,\n vendorLabel: e.vendorLabel,\n ...(vendor ? { vendor } : {}),\n // Server-known truth the client cannot re-derive, so it rides all the way to\n // the banner rather than being re-guessed there from registry membership.\n ...(e.otherVendorAvailable != null ? { otherVendorAvailable: e.otherVendorAvailable } : {}),\n };\n};\n\nconst DEFAULT_MAX_TOOL_ITERATIONS = 50;\nconst DEFAULT_MAX_FOLD_OPERATIONS = 5;\n// TODO: dedup system prompts in-memory to allow raising this cap much higher.\n// Each TurnSnapshot stores the full resolved `systemPrompt`, so the buffer's\n// memory cost scales with cap \u00D7 prompt size \u2014 a stable agent repeats a multi-KB\n// prompt every turn. `getDebugLog` already dedups identical consecutive prompts\n// at export time (`<repeated \u2014 identical to turn N>`); applying the same dedup\n// at capture time (store the prompt only when it changes, back-reference\n// otherwise) would make snapshots nearly as cheap as meta events and let this\n// cap reach thousands for full-session capture without the memory blowup.\nconst DEFAULT_MAX_TURN_SNAPSHOTS = 400;\nconst DEFAULT_MAX_UNKNOWN_TOOL_CALLS = 5;\n// Stale tools (advertised in an earlier state, retired now) and fold-hidden tools are\n// self-correcting \u2014 the model drops them once guided \u2014 so they get a higher loop-protection\n// ceiling than hallucinated names: a few legitimate stale calls across state transitions must\n// not prematurely end the turn. Still bounded so a genuinely stuck loop terminates.\nconst MAX_STALE_TOOL_CALLS = DEFAULT_MAX_UNKNOWN_TOOL_CALLS * 2;\n// Gemini in particular emits short bursts of MALFORMED_FUNCTION_CALL; allow more CONSECUTIVE\n// retries. These counters reset on any productive response, so this is a consecutive-failure\n// ceiling, not a per-turn total.\nconst MAX_MALFORMED_RETRIES = 5;\nconst MAX_EMPTY_RESPONSE_RETRIES = 3;\n// Transient throws while building the per-turn tool surface or calling the provider retry the\n// SAME iteration up to this many times before propagating, rather than tearing down the turn.\nconst MAX_SETUP_TRANSPORT_RETRIES = 3;\nconst SUGGESTIONS_HISTORY_WINDOW = 8;\n\n/**\n * Sub-agent meta events worth folding into the parent's debug timeline: the\n * per-attempt and per-failure signals that do NOT otherwise surface in the\n * sub-agent's (now hoisted) messages \u2014 a retried-away malformed/empty attempt\n * produces no message, and the stale-vs-hallucinated/streak diagnostics live only\n * on the event. High-volume, message-derivable events (turn.start/turn.end,\n * provider.selected, context.updated) are intentionally excluded: read the\n * sub-agent's hoisted messages for model/tokens/cost and turn-by-turn activity.\n * See `ChatDriver.invokeSubAgent`.\n */\nconst HARVESTED_SUBAGENT_EVENTS: ReadonlySet<MetaEventType> = new Set([\n 'turn.retry',\n 'turn.error',\n 'tool.failed',\n 'tool.unresolved',\n]);\n\n/** Name reserved for the cross-agent handoff tool \u2014 injected by OrchestratingDriver. */\nexport const REQUEST_CONTINUATION_TOOL = 'request_continuation';\n\n/** Paired in history for each `request_continuation` so tool_calls stay balanced for the provider. */\nconst HANDOFF_TOOL_RESULT_PLACEHOLDER =\n 'Handoff to another specialist \u2014 routing continues on the next turn.';\n\n/**\n * Event emitted when the chat history is updated (new message appended).\n *\n * @beta\n */\nexport type ChatHistoryUpdatedEvent = CustomEvent<ReadonlyArray<ChatMessage>>;\n\n/**\n * One captured frame of what the LLM saw on a single tool-loop iteration.\n * The driver records these as a ring buffer (cap: configurable via\n * `chatConfig.agent.maxTurnSnapshots`, default 400) so the export log can show,\n * per turn: which agent was active, the resolved system prompt, the tool names\n * visible to the LLM, and any agent-supplied debug snapshot (e.g. machine\n * state for stateful agents).\n *\n * @beta\n */\nexport interface TurnSnapshot {\n /**\n * Turn identifier, always a string. A driver's own turns are the bare counter\n * (`\"0\"`, `\"1\"`, \u2026 \u2014 monotonic, does not reset on agent swap). Turns forwarded\n * up from a sub-agent are re-labelled under the parent turn that activated them\n * \u2014 a sub-agent invoked on parent turn 5 contributes `\"5-1\"`, `\"5-2\"`, \u2026, and a\n * nested sub-agent on `\"5-2\"` contributes `\"5-2-1\"`, \u2026. See\n * `forwardSubAgentSnapshots`.\n */\n turnIndex: string;\n /** ISO timestamp captured just before the LLM call. */\n timestamp: string;\n /** Name of the agent active when this LLM call ran. */\n agentName?: string;\n /**\n * The agent's resolved system prompt sent to the LLM, verbatim. NOTE: this is\n * now the *bare* prompt \u2014 the fold-surface suffix and the malformed/empty retry\n * nudge no longer mutate it (they kept it byte-unstable and busted prompt\n * caching), so they moved to {@link TurnSnapshot.tailContext}. To reconstruct\n * exactly what the model saw, read both fields.\n */\n systemPrompt?: string;\n /**\n * The framed `<system-reminder>` tail appended to the final user turn for this\n * call, verbatim \u2014 never part of stored history, so this snapshot is the only\n * record of it. Carries the framework's volatile additions (fold suffix, retry\n * nudge) and the agent's per-turn `tailContext` (e.g. current file spec, live\n * diagnostics). Undefined when the tail was empty (the normal case).\n */\n tailContext?: string;\n /** Tool names sent to the LLM, in order \u2014 definitions are static per name so names alone suffice. */\n toolNames: string[];\n /**\n * Normalized `0`\u2013`1` sampling temperature in effect for this call, if the\n * agent (or its current state) configured one. Undefined \u2192 provider/model\n * default. Mirrors the value resolved from `BaseAgentConfig.temperature`.\n */\n temperature?: number;\n /**\n * Tool-call mode actually sent to the provider this call \u2014 the effective\n * value, including the sub-agent `'required'` default. Undefined \u2192 `'auto'`.\n * Mirrors the value resolved from `BaseAgentConfig.toolChoice`.\n */\n toolChoice?: ChatToolChoice;\n /**\n * Per-turn display label resolved from the agent's `displayName`, e.g.\n * \"Guided Booking (Counterparties)\". `agentName` stays as the canonical\n * identity used for routing/filtering.\n */\n agentLabel?: string;\n /** Agent-supplied snapshot \u2014 machine state/context for stateful agents, undefined otherwise. */\n agentSnapshot?: unknown;\n}\n\ninterface FoldStackFrame {\n foldName: string;\n previousDefinitions: ChatToolDefinition[];\n previousHandlers: ChatToolHandlers;\n}\n\n/**\n * Construction-time configuration for {@link ChatDriver}. Everything except the provider\n * registry is optional \u2014 most fields are also settable per-agent via `applyAgent`, so a\n * bare `new ChatDriver(registry)` is valid. Mirrors the `(registry, options)` shape of\n * `OrchestratingDriver`.\n *\n * @beta\n */\nexport interface ChatDriverConfig {\n /** Initial tool handlers (static map or per-turn factory). Default `{}`. */\n toolHandlers?: ToolHandlersInput;\n /** Initial tool definitions (static array or per-turn factory). Default `[]`. */\n toolDefinitions?: ToolDefinitionsInput;\n /** Initial system prompt (string or per-turn resolver). */\n systemPrompt?: SystemPromptInput;\n /** Primer history prepended to the conversation. */\n primerHistory?: ChatMessage[];\n /** Hard cap on tool-loop iterations. Default `50`. */\n maxToolIterations?: number;\n /** Hard cap on fold operations. Default `5`. */\n maxFoldOperations?: number;\n /**\n * Collapse `condenseWhen` payloads in batches of this many model-calls rather than as\n * soon as each trigger fires. A positive integer; decimals are floored and anything\n * below `1` becomes `1`. Default `1` \u2014 collapse immediately, the historical behaviour.\n *\n * Condensation rewrites history in place, so collapsing continuously breaks the\n * provider's prompt cache on nearly every call of a re-read loop. Raising this trades\n * up to that many calls' worth of extra context for one cache break per batch.\n */\n condenseBatchCalls?: number;\n /** Ring-buffer size for per-turn snapshots. Default `400`. */\n maxTurnSnapshots?: number;\n /** Session identity used to file meta events onto the shared debug-log timeline. */\n sessionKey?: string;\n /**\n * Activity bus for lifecycle/halo/tool-loop events. Injected by the browser host\n * (the shared cross-tab singleton); omitted off-browser (Node, tests, headless), where\n * it defaults to {@link NOOP_ACTIVITY_BUS} so no `BroadcastChannel` is ever opened.\n */\n activityBus?: ActivityBus;\n /**\n * Transcript copy appended when the AI-spend budget wall is hit (GENC-1464).\n * Defaults to `DEFAULT_BUDGET_EXHAUSTED_MESSAGE`.\n *\n * The assistant element already lets a host override the blocked **banner**\n * via `setBlocked(true, reason)`; without this the transcript **bubble** stayed\n * on the default, so a white-labelled host got its own copy in the banner and\n * the shipped default directly below it. Passing the same effective copy here\n * keeps the two surfaces saying one thing.\n *\n * Deliberately a driver-config field rather than something read off a chat\n * config: `ChatDriver` has no `chatConfig` and is used standalone (see\n * `chat-driver-node`), so threading one in would be a much larger and less\n * reversible change.\n */\n budgetExhaustedMessage?: string;\n}\n\n/**\n * Plain TS class that drives a multi-turn chat conversation, including the tool-call loop.\n * Owned by `FoundationAiAssistant` \u2014 created in `connectedCallback`, torn down in `disconnectedCallback`.\n *\n * Dispatches `'history-updated'` events on itself so the owning element can observe changes.\n *\n * @fires history-updated - Fired whenever the in-memory chat history changes (append, tool loop, interaction resolution) with the full history snapshot. detail: `ReadonlyArray<ChatMessage>`\n *\n * @beta\n */\nexport class ChatDriver extends EventTarget implements AiDriver {\n private history: ChatMessage[] = [];\n private busy = false;\n /** Epoch ms when the current turn loop began \u2014 drives the `turn.end` duration. */\n private turnStartedAt = 0;\n private pendingInteractions = new Map<\n string,\n {\n resolve: (value: any) => void;\n reject: (reason?: any) => void;\n /** Present when the call requested a chat-input override. */\n overrideId?: string;\n /** Present when the call set `timeoutMs`; cleared on resolution. */\n timeoutHandle?: ReturnType<typeof setTimeout>;\n }\n >();\n /**\n * Live per-interaction contexts (GENC-1390), keyed by interactionId. Created in\n * `requestInteraction` alongside the pending entry, disposed + removed in\n * `resolveInteraction`. Non-serialisable (sockets, timers, subscriber sets), so\n * they live here on the driver \u2014 not on the DOM, not in the persisted store \u2014 and\n * therefore survive the element remounts (layout reflow/drag, transcript\n * re-render) that this feature exists to make harmless. At most one is live at a\n * time (see the one-interaction-at-a-time guard in `requestInteraction`).\n */\n private interactionContexts = new Map<string, InteractionContextHandle>();\n\n private systemPrompt?: SystemPromptInput;\n /**\n * Resolved tool definitions visible to the LLM. Folds mutate this in place\n * (push/pop on open/close). When `toolDefinitionsFactory` is set, this is\n * overwritten each tool-loop iteration with the factory's output.\n */\n private toolDefinitions: ChatToolDefinition[];\n /**\n * Optional dynamic-tools source. When set, called each tool-loop iteration\n * to recompute `toolDefinitions` before the LLM call. `defineStatefulAgent`\n * forbids folds when this is set, so the fold-mutation path is unreachable\n * in that case.\n */\n private toolDefinitionsFactory?: (\n ctx: SystemPromptContext,\n ) => ChatToolDefinition[] | Promise<ChatToolDefinition[]>;\n /**\n * Resolved tool handler map used for dispatch. When `toolHandlersFactory` is\n * set, this is overwritten each tool-loop iteration with the factory's output\n * \u2014 keeping it in lockstep with `toolDefinitions` so handlers don't have to\n * defend themselves against being dispatched in states where their tool\n * isn't advertised. Folds mutate this in place; `defineStatefulAgent`\n * forbids folds when a factory is set, so the fold-mutation path is\n * unreachable in that case.\n */\n private toolHandlers: ChatToolHandlers;\n /**\n * Optional per-turn handler-map source. Mirrors `toolDefinitionsFactory` so\n * the LLM-visible tools and the dispatchable handlers can be narrowed in\n * lockstep. Resolved each tool-loop iteration before the LLM call.\n */\n private toolHandlersFactory?: (\n ctx: SystemPromptContext,\n ) => ChatToolHandlers | Promise<ChatToolHandlers>;\n private primerHistory?: ChatMessage[];\n private activeAgentName?: string;\n /**\n * Per-turn display label resolved from the agent's `displayName`. Stamped\n * onto outgoing messages and turn snapshots for UX; `activeAgentName` stays\n * stable for routing/history-transform identity matching.\n */\n private activeAgentLabel?: string;\n private displayName?: SystemPromptInput;\n /**\n * When set, `requestInteraction` delegates to this callback instead of using\n * this driver's own pending map. Wired by `invokeSubAgent` so a sub-agent's\n * widget renders in \u2014 and resolves through \u2014 the parent (ultimately the\n * root) driver, where the main UI is listening.\n */\n private hostInteractionRequester?: <T>(\n componentName: string,\n data: any,\n options?: InteractionRequestOptions,\n ) => Promise<T>;\n /**\n * When set (e.g. by OrchestratingDriver), applied only to the conversation slice\n * sent to the model \u2014 stored `history` stays unchanged for UI and logging.\n */\n private providerHistoryTransform?: (history: ChatMessage[]) => ChatMessage[];\n /**\n * Tool-declared condensation policies, keyed by tool-call id. Populated by\n * `condenseWhen` (first-wins per call); read by `applyCondensation` before each\n * provider call to collapse stale payloads from the model-bound history only.\n * Accumulates across agents on a shared driver (a superseded read collapses no\n * matter which agent made it) and is never cleared \u2014 it dies with the driver.\n */\n private readonly condensePolicies = new Map<string, RegisteredCondensePolicy>();\n /**\n * Monotonic model-call counter for the driver's whole lifetime \u2014 the age clock\n * for `condenseWhen({ on: { kind: 'age' } })`. The per-`sendMessage` `iterations`\n * loop counter resets to 0 every turn, so it can only measure age WITHIN a\n * single turn; this never resets, so `age` counts model-calls since the result\n * appeared across turn boundaries (each short turn still advances it \u2265 1).\n * Bumped once per tool-loop iteration (provider call).\n */\n private modelCallSeq = 0;\n /**\n * Monotonic turn counter \u2014 the `turnEnd` clock. Bumped once per `sendMessage`\n * (a user turn; NOT per handoff continuation, which is the same request), never\n * reset. `turnEnd` collapses a payload once `turnSeq` exceeds the turn it was\n * created in.\n */\n private turnSeq = 0;\n /**\n * Monotonic agent-activation counter \u2014 the `agentEnd` clock. Advances when the\n * active flow ends: a swap to a different-named agent (`applyAgent`) OR an\n * explicit `releaseAgent` / `completeSubAgent`. A stateful agent re-resolving\n * the same name across turns keeps one activation. `agentEnd` fires for a\n * payload once a LATER activation is current (`callActivation < currentActivation`)\n * \u2014 so a re-run of a released agent gets a fresh activation and is NOT\n * collapsed until IT ends.\n */\n private currentActivation = 0;\n /**\n * Monotonic phase-epoch counter \u2014 the `phaseEnd` clock. Advanced by the\n * handler-context `endPhase()` (an app-declared phase boundary within one\n * activation), never reset. Unlike `currentActivation` it is NOT tied to agent\n * swaps or releases \u2014 it ticks only when the agent itself declares a phase\n * done. `phaseEnd` fires for a payload once a LATER epoch is current\n * (`callPhaseEpoch < currentPhaseEpoch`), with an `agentEnd` backstop.\n */\n private currentPhaseEpoch = 0;\n\n /** Stack of fold frames \u2014 grows when a fold opens, shrinks when it closes. */\n private foldStack: FoldStackFrame[] = [];\n /** Consecutive fold open/close ops without a real tool call. Reset on real tool execution. */\n private consecutiveFoldOps = 0;\n /** Consecutive unknown-tool calls without a real tool call. Reset on real tool execution. */\n private consecutiveUnknownToolCalls = 0;\n /**\n * Distinct unknown-tool names seen in the current consecutive streak \u2014 stamped\n * onto the `unknown-tool-limit` turn.error so a triager knows which tools were\n * hallucinated. Reset alongside `consecutiveUnknownToolCalls`.\n */\n private readonly recentUnknownToolNames = new Set<string>();\n /**\n * Union of every tool name advertised at any point during the current agent\n * activation. Lets the unknown-tool path tell a *stale* call (a real tool from\n * an earlier state, now retired \u2014 or one an open exclusive fold is hiding)\n * apart from a *hallucinated* one. Reset on agent swap in `applyAgent`.\n */\n private readonly everSeenToolNames = new Set<string>();\n /**\n * Subset of the current unknown-tool streak that was stale (previously\n * available) rather than hallucinated \u2014 surfaced separately on the\n * `unknown-tool-limit` turn.error so triage can tell a state/prompt-design\n * problem from a model that's inventing tools. Reset alongside\n * `recentUnknownToolNames`.\n */\n private readonly recentStaleToolNames = new Set<string>();\n private readonly maxFoldOperations: number;\n\n /** Sub-agents declared on the active agent config, keyed by name. */\n private subAgentsMap: Map<string, AgentConfig> = new Map();\n /**\n * Set by `completeSubAgent` inside a sub-agent tool handler. Checked at the\n * same point in the loop as `REQUEST_CONTINUATION_TOOL` \u2014 after tool results\n * are appended \u2014 so the exit path mirrors the system-call pattern.\n * `undefined` means the loop has not been stopped early.\n */\n private subAgentCompletion: { result: unknown } | undefined;\n /**\n * True when this driver runs as a child sub-agent (created by a parent\n * driver's `invokeSubAgent`). Sub-agents force tool use every turn so a turn\n * can only end via their completion tool, and on any non-completion exit they\n * record a typed `SubAgentFailureReason` instead of appending a\n * user-facing message \u2014 the parent decides how to surface the failure.\n */\n private isSubAgent = false;\n /**\n * Set when a sub-agent's tool loop ends without `completeSubAgent` being\n * called. Read by the parent's `invokeSubAgent` to build the `{ ok: false }`\n * branch of `requestSubAgent`. Only ever set when `isSubAgent` is true.\n *\n * `budget` rides along on a `'budget_exhausted'` failure so the parent inherits\n * the child's ATTRIBUTION, not just the fact of a wall \u2014 see\n * `budgetWallDetail`.\n */\n private subAgentFailure: { reason: SubAgentFailureReason; budget?: BudgetDetail } | undefined;\n /**\n * Set by `releaseAgent` inside a top-level tool handler \u2014 typically a stateful\n * agent's terminal-state handler signalling that its flow is complete and the\n * auto-pin lock can release. Checked by the orchestrator after `sendMessage`\n * returns; the orchestrator fires `onDeactivate` and clears the pin.\n *\n * Reset at the start of each `sendMessage` so a release from a previous turn\n * doesn't leak forward.\n */\n private agentReleaseRequested = false;\n /**\n * Ring buffer of per-LLM-call snapshots. Cap is configurable via\n * `chatConfig.agent.maxTurnSnapshots`; older entries drop off as new ones\n * arrive. See {@link TurnSnapshot} for the captured shape.\n */\n private turnSnapshots: TurnSnapshot[] = [];\n /**\n * `turn` + `message` diagnostic-log entries harvested from an out-of-band source (a resolved\n * interaction whose widget returned `InteractionResult.diagnostics` \u2014 e.g. a server-side\n * ChatDriver's debug log). `event` entries are NOT kept here \u2014 they're folded into the session's\n * meta-event registry via `mergeMetaEvents` (see `resolveInteraction`) so they inherit fresh host\n * indices, and reach the log through `getMetaEvents`. Append-only; the host folds these into its\n * debug log alongside this driver's own timeline. Not cleared here \u2014 it lives with the driver\n * instance, like `turnSnapshots`, so a new chat (fresh driver) starts empty while a compaction\n * (same instance) keeps it. (GENC-1461.)\n */\n private readonly externalDiagnostics: DiagnosticEntry[] = [];\n /**\n * Monotonic count of external-diagnostics batches harvested this driver-lifetime. Namespaces each\n * batch's re-keyed `turn` entries so distinct server generations in one chat session can't collide\n * on `turnIndex` in the forward-capture persister (which dedups turns by that key). (GENC-1461.)\n */\n private externalDiagnosticsBatches = 0;\n /** Monotonic counter that survives agent swaps \u2014 useful for cross-referencing with history. */\n private globalTurnIndex = 0;\n /** Captured from `applyAgent` so we don't store the whole `AgentConfig`. */\n private debugSnapshotter?: () => unknown;\n private readonly maxTurnSnapshots: number;\n\n /**\n * Aborted by `dispose()` on driver teardown (e.g. an agent-config swap).\n * Threaded into every provider call as `ChatRequestOptions.signal`, so a\n * disposed driver's in-flight LLM request is cancelled instead of running on\n * to completion or the transport timeout. Also passed to prompt/tool\n * factories via `SystemPromptContext.signal`.\n */\n private readonly lifecycleController = new AbortController();\n\n /**\n * Per-turn abort controller, reset at the start of every turn by `beginTurn`.\n * Aborted by `cancel()` (user stop) and chained to `lifecycleController` so a\n * driver dispose also ends the current turn. Its signal \u2014 not the lifecycle\n * one \u2014 is what reaches the provider call, so a turn can be cancelled without\n * bricking the driver for the next message.\n */\n private turnController = new AbortController();\n /** True when the current turn was stopped via `cancel()` (vs a dispose). Drives the \"Stopped.\" marker. */\n private turnCancelled = false;\n /** Detaches the lifecycle\u2192turn abort link at turn end; set by `beginTurn`. */\n private unlinkLifecycleFromTurn?: () => void;\n\n /**\n * Active agent's provider selector (static name or per-turn resolver).\n * `undefined` means \"use the registry default\".\n */\n private activeProviderInput?: ProviderInput;\n /**\n * Active agent's temperature selector (static number or per-turn resolver),\n * normalized to `0`\u2013`1`. `undefined` means \"use the provider/model default\".\n */\n private activeTemperatureInput?: TemperatureInput;\n /**\n * Active agent's tool-call mode selector (static value or per-turn resolver).\n * `undefined` falls back to the per-turn default (sub-agents force a tool\n * call; top-level turns are `'auto'`).\n */\n private activeToolChoiceInput?: ToolChoiceInput;\n /**\n * Active agent's prompt-cache policy selector (static value or per-turn resolver).\n * `undefined` requests no caching (equivalent to `{ scope: 'default' }`).\n */\n private activeCachePolicyInput?: CachePolicyInput;\n /**\n * Active agent's tail-context selector (static value or per-turn resolver). The driver frames\n * the resolved string in a `<system-reminder>` marker and injects it at the message tail.\n */\n private activeTailContextInput?: TailContextInput;\n /**\n * Active agent's structured-output schema selector (static value or per-turn resolver).\n * When it resolves to a schema, the model's final answer is constrained to it this turn.\n */\n private activeResponseSchemaInput?: ResponseSchemaInput;\n /**\n * Active agent's refusal-fallback chain (static). Passed through to the provider so a refused\n * turn (e.g. Fable 5) is re-run on the next model server-side.\n */\n private activeFallbacks?: ChatFallback[];\n /**\n * Active agent's unresolved-tool hook, captured from `applyAgent`. Consulted\n * only when a tool call cannot be dispatched (a stale or hallucinated name);\n * `undefined` keeps the framework's default messages. See\n * `resolveUnresolvedToolContent`.\n */\n private activeOnUnresolvedTool?: UnresolvedToolInput;\n /**\n * Caches validated provider lookups per name within the current agent. Cleared\n * by `applyAgent` so each new agent's static/function-resolved names are\n * validated fresh.\n */\n private resolvedProviderCache = new Map<string, AIProvider>();\n /** Last successfully resolved provider name \u2014 drives `getActiveProviderName`. */\n private lastResolvedProviderName?: string;\n /** Last dispatched `provider-changed` name; avoids duplicate events on stable turns. */\n private lastDispatchedProviderName?: string;\n /**\n * Concrete model id of the provider resolved for the current turn, read from\n * its `getStatus()` and stamped onto the resulting assistant message so the\n * debug log carries per-message model lineage. Re-resolved each turn in\n * `resolveProviderForTurn`.\n */\n private lastResolvedModel?: string;\n /**\n * Vendor id from the provider's `getStatus()` for the current turn (e.g.\n * `'anthropic'`, `'gemini'`). Stamped onto assistant messages alongside\n * `lastResolvedModel`.\n */\n private lastResolvedProvider?: AIProviderType;\n /**\n * Memoised `name \u2192 getStatus()` lookups, so per-turn resolution doesn't\n * re-await `getStatus()` every turn. Cleared (with `resolvedProviderCache`) on\n * an observable-registry change, so a model swapped behind a stable name is\n * picked up on the next turn.\n */\n private resolvedStatusCache = new Map<string, { model?: string; provider?: AIProviderType }>();\n /**\n * Unsubscribe handle for the provider-registry change listener (only set when\n * the injected registry is observable). Called in `dispose` so the long-lived\n * registry doesn't retain this driver \u2014 see the constructor and the sub-agent\n * teardown in `runSubAgent`.\n */\n private unsubscribeRegistry?: () => void;\n\n /** Hard cap on tool-loop iterations. */\n private readonly maxToolIterations: number;\n /** Model-calls per condensation batch; `1` collapses as soon as a trigger fires. */\n private readonly condenseBatchCalls: number;\n /** Session identity used to file meta events onto the shared debug-log timeline. */\n private readonly sessionKey: string;\n /** Injected activity bus; defaults to a no-op off-browser (Node/tests/headless). */\n private readonly activityBus: ActivityBus;\n /** Transcript copy for a budget wall \u2014 see `ChatDriverConfig.budgetExhaustedMessage`. */\n private readonly budgetExhaustedMessage: string;\n /**\n * Set the moment a budget wall is observed anywhere in this turn \u2014 this\n * driver's own 402, or a sub-agent's (which surfaces here only as a\n * `'budget_exhausted'` tool result). Read at the top of the tool loop to end\n * the turn before issuing another model call that would hit the same wall.\n * Reset per turn alongside the other per-turn counters.\n */\n private budgetExhaustedThisTurn = false;\n /**\n * The refusing vendor's own attribution for the wall `budgetExhaustedThisTurn`\n * records, when it was knowable. Kept SEPARATE from the flag rather than\n * replacing it: a figure-less 402 from a transport no vendor claims yields no\n * detail at all (`budgetDetailOf` returns `undefined`), and folding the two\n * would make that case stop ending the turn.\n *\n * It matters most for a sub-agent's wall. The child can sit on a different\n * vendor from its parent \u2014 `applyAgent` reads `config.provider` \u2014 so without\n * this the parent's short-circuit reports `lastResolvedProvider`, i.e. the one\n * vendor that did NOT refuse. Under a mixed registry that walls Gemini because\n * an Anthropic child 402'd, and if those are the only two reachable vendors the\n * host then derives `blocked` and locks a composer that still had headroom.\n */\n private budgetWallDetail?: BudgetDetail;\n /**\n * Whether this turn's budget wall came from a SUB-AGENT rather than this\n * driver's own request. Decides whether `lastResolvedProvider` is a valid\n * attribution fallback: for an own wall it is the refusing vendor, for a\n * child's wall it is the parent's vendor \u2014 the one known NOT to have refused.\n * Reset per turn alongside `budgetWallDetail`.\n */\n private budgetWallViaSubAgent = false;\n\n constructor(\n private readonly providerRegistry: AIProviderRegistry,\n config: ChatDriverConfig = {},\n ) {\n super();\n const {\n toolHandlers = {},\n toolDefinitions = [],\n systemPrompt,\n primerHistory,\n maxToolIterations = DEFAULT_MAX_TOOL_ITERATIONS,\n maxFoldOperations = DEFAULT_MAX_FOLD_OPERATIONS,\n condenseBatchCalls = 1,\n maxTurnSnapshots = DEFAULT_MAX_TURN_SNAPSHOTS,\n sessionKey = '',\n activityBus = NOOP_ACTIVITY_BUS,\n budgetExhaustedMessage = DEFAULT_BUDGET_EXHAUSTED_MESSAGE,\n } = config;\n this.maxToolIterations = maxToolIterations;\n this.condenseBatchCalls = condenseBatchCalls;\n this.sessionKey = sessionKey;\n this.activityBus = activityBus;\n this.budgetExhaustedMessage = budgetExhaustedMessage;\n if (typeof toolHandlers === 'function') {\n this.toolHandlersFactory = toolHandlers;\n this.toolHandlers = {};\n } else {\n this.toolHandlersFactory = undefined;\n this.toolHandlers = toolHandlers;\n }\n if (typeof toolDefinitions === 'function') {\n this.toolDefinitionsFactory = toolDefinitions;\n this.toolDefinitions = [];\n } else {\n this.toolDefinitionsFactory = undefined;\n this.toolDefinitions = toolDefinitions;\n }\n this.systemPrompt = systemPrompt;\n this.primerHistory = primerHistory;\n this.maxFoldOperations = maxFoldOperations;\n this.maxTurnSnapshots = maxTurnSnapshots;\n // Runtime provider switching: when the host registered an observable\n // registry, drop our memoised provider lookups whenever its mapping/default\n // changes so the next turn re-resolves against the new providers. Resetting\n // `lastDispatchedProviderName` forces the next `resolveProviderForTurn` to\n // re-emit `provider-changed` even when the resolved *name* is unchanged\n // (e.g. a tier name like 'high' kept, but the vendor underneath swapped) \u2014\n // that's what lets status UI refresh on a same-name switch. Feature-detect\n // means immutable/empty registries are a no-op. Child sub-agent drivers get\n // the same registry and so subscribe here too; each cleans up in `dispose`.\n if (isObservableAIProviderRegistry(this.providerRegistry)) {\n this.unsubscribeRegistry = this.providerRegistry.subscribe(() => {\n this.resolvedProviderCache.clear();\n this.resolvedStatusCache.clear();\n this.lastResolvedProviderName = undefined;\n this.lastResolvedModel = undefined;\n this.lastResolvedProvider = undefined;\n this.lastDispatchedProviderName = undefined;\n });\n }\n }\n\n /**\n * Tear down the driver: aborts the lifecycle signal so any in-flight provider\n * request (and prompt/tool factories awaiting it) cancels instead of running\n * on to completion or the transport timeout. Called by the host on driver\n * swap and by `OrchestratingDriver.dispose()`. Idempotent.\n *\n * Deliberately does NOT settle `pendingInteractions` here: dispose is never\n * reached while one is pending. The only host-level dispose is the agent-swap\n * rebuild, which is guarded by `isBusy()` \u2014 a pending interaction keeps the\n * tool loop suspended (`busy === true`), so the swap is deferred until the\n * widget resolves. Sub-agent child disposes always have an empty pending map\n * (widgets park on the parent via `setHostInteractionRequester`). A pending\n * interaction is instead settled by `resolveInteraction` (user response or\n * timeout), which also stamps history and reverts the chat-input override.\n */\n dispose(): void {\n this.lifecycleController.abort(new DOMException('AI assistant driver disposed', 'AbortError'));\n // Drop any live interaction contexts (GENC-1390). Normally empty at teardown\n // (a context is created and destroyed with its pending interaction, and dispose\n // is not reached mid-interaction); disposed defensively so a stray context can\n // never leak an open socket/timer.\n for (const handle of this.interactionContexts.values()) handle.dispose();\n this.interactionContexts.clear();\n // Detach from the provider registry so the long-lived registry doesn't pin\n // this driver (and its closure) after teardown. Guard-cleared so a second\n // dispose is a no-op, matching this method's idempotent contract.\n this.unsubscribeRegistry?.();\n this.unsubscribeRegistry = undefined;\n }\n\n /**\n * Stop the current turn (user \"stop\" button). Aborts the in-flight provider\n * request immediately; if a tool is mid-execution it runs to completion and\n * the loop bails at the next boundary (tools are atomic). No-op when idle.\n * The driver stays usable for the next message.\n */\n cancel(): void {\n if (!this.busy) return;\n this.turnCancelled = true;\n this.turnController.abort(new DOMException('Cancelled by user', 'AbortError'));\n }\n\n /**\n * Start a fresh per-turn abort scope. Chains `lifecycleController` into the\n * new `turnController` so a dispose mid-turn also aborts the request.\n */\n private beginTurn(): void {\n this.turnCancelled = false;\n this.turnController = new AbortController();\n const lifecycle = this.lifecycleController.signal;\n if (lifecycle.aborted) {\n this.turnController.abort(lifecycle.reason);\n this.unlinkLifecycleFromTurn = undefined;\n return;\n }\n const onDispose = () => this.turnController.abort(lifecycle.reason);\n lifecycle.addEventListener('abort', onDispose, { once: true });\n this.unlinkLifecycleFromTurn = () => lifecycle.removeEventListener('abort', onDispose);\n }\n\n /** Detach the lifecycle\u2192turn link so a long-lived lifecycle signal doesn't accumulate listeners. */\n private endTurn(): void {\n this.unlinkLifecycleFromTurn?.();\n this.unlinkLifecycleFromTurn = undefined;\n }\n\n /**\n * Finish a turn whose signal aborted. A user cancel adds a subtle \"Stopped.\"\n * marker; a dispose-driven abort stops quietly (the widget is gone and the\n * cached history would otherwise gain a stray marker on remount).\n */\n private completeAbortedTurn(): ChatDriverResult {\n if (this.turnCancelled) {\n logger.warn('ChatDriver: turn cancelled by user');\n this.appendToHistory({ role: 'system-event', content: 'Stopped.' });\n } else {\n logger.warn('ChatDriver: turn aborted (driver disposed)');\n }\n return { reason: 'done' };\n }\n\n /**\n * Build the `done` loop result, carrying the typed failure reason when the turn\n * bailed (PTC-0). The discriminant stays `'done'` either way \u2014 the same value a\n * clean turn returns \u2014 so consumers matching on `reason === 'done'` are unchanged;\n * `failureReason` is simply present on a failure and absent on success. Omitted\n * (rather than set to `undefined`) so a happy-path result stays byte-identical to\n * the historical `{ reason: 'done' }`.\n */\n private turnDone(failureReason?: TurnFailureReason, budget?: BudgetDetail): ChatDriverResult {\n if (!failureReason) return { reason: 'done' };\n // `budget` is likewise omitted rather than set to `undefined`, so a non-budget\n // failure's shape is unchanged for a consumer that structurally compares it.\n return budget ? { reason: 'done', failureReason, budget } : { reason: 'done', failureReason };\n }\n\n /**\n * Terminal budget outcome for a wall hit **outside** the tool loop \u2014 today,\n * `OrchestratingDriver`'s classification phase, which calls the provider\n * directly and so never enters `runToolLoop`.\n *\n * Does **not** publish `tool-loop-end`: no `tool-loop-start` was published for\n * the classify phase, and an unbalanced end would break start/end pairing for\n * subscribers that rely on it. The driver **return value** is what reports this\n * case \u2014 see `FoundationAiAssistant`'s latch, which reads both seams for\n * exactly this reason.\n *\n * The non-sub-agent tail of the in-loop `BudgetExhaustedError` branch lives\n * here so there is one copy of the log line, the debug-log entry, the\n * transcript bubble and the result shape rather than two that can drift.\n *\n * @param pendingUserMessage - a user message that has NOT yet been appended,\n * appended first so the answer does not end up replying to nothing. Only the\n * classification seam passes it: `OrchestratingDriver` dispatches the user's\n * text as an optimistic `history-updated` detail and leaves the real append\n * to `chatDriver.sendMessage`, which never runs when `classify()` throws \u2014 so\n * the bubble below would re-dispatch a history the user's own message was\n * never in, and it would vanish from the transcript on the next render. The\n * in-loop caller has already appended it and passes nothing.\n *\n * @internal\n */\n reportBudgetExhausted(\n e: BudgetExhaustedError,\n pendingUserMessage?: ChatMessage,\n ): ChatDriverResult {\n if (pendingUserMessage) this.appendToHistory(pendingUserMessage);\n this.budgetExhaustedThisTurn = true;\n logger.error('ChatDriver: AI budget exhausted', e);\n recordTurnError(this.sessionKey, 'budget-exhausted', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n // The registry ALIAS (e.g. 'high') is what `provider` records; the vendor\n // is the thing a per-vendor budget is actually scoped to, and it was known\n // at both ends and discarded in the middle until now. Taken from the\n // refusing transport's label first \u2014 this method also serves the\n // classification seam, where `lastResolvedProvider` is the PREVIOUS turn's\n // vendor (or nothing), because classify runs against the registry default.\n vendor:\n vendorTypeOfLabel(e.vendorLabel) ??\n vendorTypeOfLabel(e.serverVendor) ??\n this.lastResolvedProvider,\n budgetUsd: e.budgetUsd,\n spentUsd: e.spentUsd,\n isSubAgent: this.isSubAgent,\n });\n this.appendToHistory({ role: 'assistant', content: this.budgetExhaustedMessage });\n return this.turnDone('budget-exhausted', budgetDetailOf(e));\n }\n\n /** The typed failure reason on a loop result, or `undefined` for a clean turn / handoff. */\n private static failureReasonOf(result: ChatDriverResult): TurnFailureReason | undefined {\n return result.reason === 'done' ? result.failureReason : undefined;\n }\n\n /**\n * Build the `tool-loop-end` event detail for a turn's result. A failure carries a\n * `{ failureReason }` detail; a clean turn emits `undefined` \u2014 the historical shape,\n * kept byte-identical so subscribers see exactly what they always have.\n *\n * A budget failure additionally carries `vendor` \u2014 the concrete vendor\n * (`'anthropic'`/`'gemini'`) the walled turn resolved to, which the driver knows\n * and used to discard. Optional and additive: a subscriber reading only\n * `failureReason` is unaffected, a non-budget failure still emits the historical\n * `{ failureReason }` with no `vendor` key, and the value is a plain string so\n * the detail stays structured-cloneable for the cross-tab hop. It is the field a\n * per-vendor budget model needs and the one that would be awkward to retrofit.\n */\n private loopEndDetail(result: ChatDriverResult):\n | {\n failureReason: TurnFailureReason;\n vendor?: AIProviderType;\n budget?: BudgetDetail;\n }\n | undefined {\n const failureReason = ChatDriver.failureReasonOf(result);\n if (!failureReason) return undefined;\n if (failureReason !== 'budget-exhausted') {\n return { failureReason };\n }\n // The figures ride the event, not just the return value: this publish happens in\n // sendMessage's `finally`, so for an in-loop wall it reaches the host's latch FIRST\n // and the return-value seam is then a no-op (the latch is idempotent). Omitted\n // entirely \u2014 never set to undefined \u2014 when the proxy sent no figures.\n const budget = result.reason === 'done' ? result.budget : undefined;\n // Prefer the refusing transport's own attribution over the driver's\n // last-resolved provider, for the same staleness reason as `budgetDetailOf`.\n //\n // The fallback is legitimate ONLY for this driver's own wall \u2014 its resolved\n // provider IS the refuser then. When the wall came from a SUB-AGENT\n // (`budgetWallViaSubAgent`), the refuser is the child's vendor, and on a\n // mixed registry `lastResolvedProvider` is the one vendor known NOT to have\n // refused; an unattributable child wall degrades to the vendor-agnostic\n // event instead, which the host's latch handles fail-safe.\n const vendor =\n budget?.vendor ?? (this.budgetWallViaSubAgent ? undefined : this.lastResolvedProvider);\n return {\n failureReason,\n ...(vendor ? { vendor } : {}),\n ...(budget ? { budget } : {}),\n };\n }\n\n /**\n * Swap in a new agent's configuration. Called by OrchestratingDriver before\n * each specialist turn so the shared driver runs with the right tools and prompt.\n */\n applyAgent(config: AgentConfig): void {\n // A real swap to a different agent begins a NEW activation \u2014 the prior agent's\n // flow is over, so its `agentEnd`-tagged payloads become collapsible. Guarded\n // on a name change so re-applying the same agent (e.g. a per-turn re-resolve)\n // does not spuriously advance the clock and prematurely drop its payloads.\n if (config.name !== this.activeAgentName) this.currentActivation += 1;\n this.systemPrompt = config.systemPrompt;\n if (typeof config.toolDefinitions === 'function') {\n this.toolDefinitionsFactory = config.toolDefinitions;\n // Cleared each turn by the factory in runToolLoop; empty is safe in the\n // meantime (no LLM call happens before resolution).\n this.toolDefinitions = [];\n } else {\n this.toolDefinitionsFactory = undefined;\n this.toolDefinitions = config.toolDefinitions ?? [];\n }\n if (typeof config.toolHandlers === 'function') {\n this.toolHandlersFactory = config.toolHandlers;\n // Cleared each turn by the factory in runToolLoop; empty is safe in the\n // meantime (no LLM call happens before resolution).\n this.toolHandlers = {};\n } else {\n this.toolHandlersFactory = undefined;\n this.toolHandlers = config.toolHandlers ?? {};\n }\n this.primerHistory = config.primerHistory;\n this.activeAgentName = config.name;\n this.displayName = config.displayName;\n // Static string form resolves to a stable label up-front; the function\n // form gets re-resolved each tool-loop iteration. Falls back to the\n // canonical name when displayName is unset.\n this.activeAgentLabel =\n typeof config.displayName === 'string' ? config.displayName : config.name;\n this.debugSnapshotter = config.getDebugSnapshot;\n this.subAgentsMap = new Map((config.subAgents ?? []).map((s) => [s.name, s]));\n this.activeProviderInput = config.provider;\n this.activeTemperatureInput = config.temperature;\n this.activeToolChoiceInput = config.toolChoice;\n this.activeCachePolicyInput = config.cachePolicy;\n this.activeTailContextInput = config.tailContext;\n this.activeResponseSchemaInput = config.responseSchema;\n this.activeFallbacks = config.fallbacks;\n this.activeOnUnresolvedTool = config.onUnresolvedTool;\n this.resolvedProviderCache.clear();\n this.lastResolvedProviderName = undefined;\n // Static validation: resolve the name now so unknown-provider and missing-\n // capability errors fire at agent swap rather than on the first LLM call.\n // Function-form `provider` is validated lazily inside `resolveProviderForTurn`.\n if (typeof config.provider === 'string') {\n this.resolveProviderByName(config.provider, config.name);\n }\n // Reset fold state when agent changes \u2014 each specialist starts fresh\n this.foldStack = [];\n this.consecutiveFoldOps = 0;\n // Forget the previous agent's tools \u2014 \"previously available\" is scoped to\n // the current activation, so a stateful agent accumulates its tools across\n // states while a swap to a different specialist starts clean.\n this.everSeenToolNames.clear();\n }\n\n /**\n * Resolve the tool-result content for an unresolved tool call. Consults the\n * active agent's `onUnresolvedTool` hook (if any) with the attempted tool\n * name, the failure `kind`, and the currently dispatchable tools, and returns\n * the hook's non-empty string. Falls back to `fallback` when no hook is set,\n * the hook returns nothing/empty, or the hook throws \u2014 so a misbehaving hook\n * can never break tool dispatch.\n */\n private async resolveUnresolvedToolContent(\n toolName: string,\n kind: 'stale' | 'unknown',\n fallback: string,\n ): Promise<string> {\n if (typeof this.activeOnUnresolvedTool !== 'function') {\n return fallback;\n }\n try {\n const custom = await this.activeOnUnresolvedTool({\n toolName,\n kind,\n availableTools: Object.keys(this.toolHandlers),\n });\n return typeof custom === 'string' && custom.trim().length > 0 ? custom : fallback;\n } catch (e) {\n logger.warn(\n `ChatDriver: onUnresolvedTool threw for \"${toolName}\" \u2014 using default message`,\n e,\n );\n return fallback;\n }\n }\n\n /**\n * Returns the most recently resolved provider name. Falls back to the\n * registry's default when no per-turn resolution has happened yet.\n */\n getActiveProviderName(): string {\n return this.lastResolvedProviderName ?? this.providerRegistry.defaultName();\n }\n\n /**\n * Resolve a named provider against the registry. Cached per-agent so\n * repeated lookups during one agent's lifetime don't re-validate.\n * Validation lives in `resolveChatProvider`; this wrapper just adds the\n * cache.\n */\n private resolveProviderByName(name: string, agentName: string): AIProvider {\n const cached = this.resolvedProviderCache.get(name);\n if (cached) return cached;\n const provider = resolveChatProvider(this.providerRegistry, name, agentName);\n this.resolvedProviderCache.set(name, provider);\n return provider;\n }\n\n /**\n * Resolve the provider to use for the current turn. Walks the agent's\n * `provider` selector (static or function form) or falls back to the\n * registry default. Dispatches `provider-changed` when the resolved name\n * differs from the last dispatched value.\n */\n private async resolveProviderForTurn(ctx: SystemPromptContext): Promise<AIProvider> {\n let provider: AIProvider;\n let resolvedName: string;\n if (this.activeProviderInput === undefined) {\n provider = this.providerRegistry.default();\n resolvedName = this.providerRegistry.defaultName();\n } else {\n const name =\n typeof this.activeProviderInput === 'function'\n ? await this.activeProviderInput(ctx)\n : this.activeProviderInput;\n provider = this.resolveProviderByName(name, this.activeAgentName ?? '<unknown>');\n resolvedName = name;\n }\n this.lastResolvedProviderName = resolvedName;\n const status = await this.resolveStatusForProvider(resolvedName, provider);\n this.lastResolvedModel = status.model;\n this.lastResolvedProvider = status.provider;\n if (resolvedName !== this.lastDispatchedProviderName) {\n this.lastDispatchedProviderName = resolvedName;\n recordMetaEvent(this.sessionKey, 'provider.selected', {\n provider: resolvedName,\n agent: this.activeAgentName,\n });\n this.dispatchEvent(\n new CustomEvent<{ name: string }>('provider-changed', { detail: { name: resolvedName } }),\n );\n }\n return provider;\n }\n\n /**\n * Resolve model id and vendor from a provider via its optional `getStatus()`,\n * memoised by registry name. Used to stamp `model` and `provider` onto outgoing\n * messages. Best-effort: a provider without `getStatus`, a null status, or a\n * throw all yield empty fields \u2014 attribution is diagnostic, never load-bearing.\n */\n private async resolveStatusForProvider(\n name: string,\n provider: AIProvider,\n ): Promise<{ model?: string; provider?: AIProviderType }> {\n if (this.resolvedStatusCache.has(name)) return this.resolvedStatusCache.get(name)!;\n let status: { model?: string; provider?: AIProviderType } = {};\n try {\n const resolved = await provider.getStatus?.();\n if (resolved) {\n status = { model: resolved.model, provider: resolved.provider };\n }\n } catch {\n status = {};\n }\n this.resolvedStatusCache.set(name, status);\n return status;\n }\n\n /**\n * Resolve a per-turn config input that is either a static value or a function\n * of the turn context \u2014 the value-or-resolver shape shared by `provider`,\n * `temperature`, and `toolChoice`. Returns undefined when the input is unset.\n */\n private async resolveTurnInput<T>(\n input: T | ((ctx: SystemPromptContext) => T | Promise<T>) | undefined,\n ctx: SystemPromptContext,\n ): Promise<T | undefined> {\n if (input === undefined) return undefined;\n return typeof input === 'function'\n ? (input as (ctx: SystemPromptContext) => T | Promise<T>)(ctx)\n : input;\n }\n\n /**\n * Returns the early-stop result set by `completeSubAgent`, if any.\n * Called by a parent `ChatDriver` after running this instance as a sub-agent.\n */\n getSubAgentCompletion(): { result: unknown } | undefined {\n return this.subAgentCompletion;\n }\n\n /**\n * Mark this driver as running as a sub-agent. Called by a parent driver's\n * `invokeSubAgent` immediately after construction, before the first turn.\n * Enables forced tool use and typed failure reporting (see `isSubAgent`).\n */\n markAsSubAgent(): void {\n this.isSubAgent = true;\n }\n\n /**\n * Returns the typed failure recorded when a sub-agent run ended without\n * `completeSubAgent`, if any. Called by a parent `ChatDriver` after running\n * this instance as a sub-agent.\n */\n getSubAgentFailure(): { reason: SubAgentFailureReason; budget?: BudgetDetail } | undefined {\n return this.subAgentFailure;\n }\n\n /**\n * Record a sub-agent failure reason (first one wins). No-op for top-level\n * agents, so loop-exit sites can call it unconditionally. The parent reads\n * this via `getSubAgentFailure()` and emits the `subagent.failed` meta event\n * under its *own* session \u2014 see `invokeSubAgent`. (A child sub-agent runs\n * under a separate session key, so recording here would orphan the event off\n * the user-visible debug-log timeline.)\n */\n private failSubAgent(reason: SubAgentFailureReason, budget?: BudgetDetail): void {\n if (!this.isSubAgent || this.subAgentFailure) return;\n // Omitted rather than set to `undefined` so a non-budget failure's shape is\n // unchanged for a structural comparison, matching `turnDone`.\n this.subAgentFailure = budget ? { reason, budget } : { reason };\n }\n\n /**\n * Returns true if `releaseAgent` was called during the most recent turn.\n * Consumed by the orchestrator to trigger the auto-pin release path.\n */\n getAgentReleaseRequested(): boolean {\n return this.agentReleaseRequested;\n }\n\n /**\n * Return the per-turn snapshots captured so far. Used by the host's debug\n * log exporter to show what the LLM saw on each turn \u2014 system prompt, tool\n * surface, and agent-supplied state (e.g. a machine snapshot).\n *\n * Ring-buffered at `MAX_TURN_SNAPSHOTS`; older entries are dropped.\n */\n getTurnSnapshots(): ReadonlyArray<TurnSnapshot> {\n return this.turnSnapshots;\n }\n\n /**\n * The `turn` + `message` diagnostic-log entries harvested from resolved interactions'\n * `InteractionResult.diagnostics` (e.g. a server-side ChatDriver's collated debug log). The host\n * concatenates these into its own debug log so `downloadDebugLog`/the persisted diagnostics stream\n * include external-engine logs; `event` entries are excluded here because they're merged into the\n * session's meta-event registry instead (see `resolveInteraction`) and reach the log via\n * `getMetaEvents`. Opaque, chronologically sorted by the host at assemble time. (GENC-1461.)\n */\n getExternalDiagnostics(): ReadonlyArray<DiagnosticEntry> {\n return this.externalDiagnostics;\n }\n\n /**\n * Merge a sub-agent's turn snapshots into this driver's buffer so they surface\n * as `kind:'turn'` entries in the exported debug log. The child runs as a\n * separate, discarded driver, so its snapshots would otherwise be lost. Each is\n * re-labelled under the parent turn that activated the sub-agent: the child's\n * own (numeric) turns become `\"<parentTurn>-1\"`, `\"-2\"`, \u2026 (1-based, in order);\n * any already-forwarded grand-child labels (strings) have their leading segment\n * remapped the same way, so nesting composes (`\"5-2\"` \u2192 `\"5-2-1\"`).\n *\n * Note: two sub-agents invoked in the *same* parent turn share the prefix, so\n * their labels can repeat \u2014 `agentName` on each snapshot disambiguates them.\n */\n private forwardSubAgentSnapshots(childSnapshots: ReadonlyArray<TurnSnapshot>): void {\n if (childSnapshots.length === 0) return;\n // The activating parent turn = the most recent snapshot this driver recorded\n // before entering the tool handler that invoked the sub-agent.\n const parentTurn = Math.max(0, this.globalTurnIndex - 1);\n const ownTurnLabel = new Map<string, string>();\n let ownPos = 0;\n for (const snap of childSnapshots) {\n let turnIndex: string;\n if (!snap.turnIndex.includes('-')) {\n // The child's own turn (a bare counter) \u2192 number it under the parent turn.\n ownPos += 1;\n turnIndex = `${parentTurn}-${ownPos}`;\n ownTurnLabel.set(snap.turnIndex, turnIndex);\n } else {\n // An already-forwarded grand-child label \u2014 remap its leading segment.\n const [lead, ...rest] = snap.turnIndex.split('-');\n const leadLabel = ownTurnLabel.get(lead) ?? `${parentTurn}-${lead}`;\n turnIndex = [leadLabel, ...rest].join('-');\n }\n this.turnSnapshots.push({ ...snap, turnIndex });\n }\n while (this.turnSnapshots.length > this.maxTurnSnapshots) {\n this.turnSnapshots.shift();\n }\n }\n\n /**\n * Push one snapshot to the ring buffer. Called inside `runToolLoop` just\n * before each LLM call \u2014 that's the latest point where the prompt, tool\n * surface, and agent state line up with what the model is about to see.\n */\n private recordTurnSnapshot(\n resolvedSystemPrompt: string | undefined,\n temperature: number | undefined,\n toolChoice: ChatToolChoice | undefined,\n tailContext: string | undefined,\n ): void {\n let agentSnapshot: unknown;\n if (this.debugSnapshotter) {\n try {\n agentSnapshot = this.debugSnapshotter();\n } catch (e) {\n // A snapshotter throwing must not derail the LLM call \u2014 capture the\n // error string in place of the snapshot so the export still shows\n // *something* happened.\n agentSnapshot = `<getDebugSnapshot threw: ${e instanceof Error ? e.message : String(e)}>`;\n }\n }\n const turnIndex = String(this.globalTurnIndex);\n this.globalTurnIndex += 1;\n this.turnSnapshots.push({\n turnIndex,\n timestamp: new Date().toISOString(),\n agentName: this.activeAgentName,\n agentLabel: this.activeAgentLabel,\n systemPrompt: resolvedSystemPrompt,\n tailContext,\n toolNames: this.toolDefinitions.map((t) => t.name),\n temperature,\n toolChoice,\n agentSnapshot,\n });\n if (this.turnSnapshots.length > this.maxTurnSnapshots) {\n this.turnSnapshots.shift();\n }\n }\n\n /**\n * Optional transform applied to conversation history immediately before each LLM request.\n * Cleared when `undefined`. Does not alter stored history.\n */\n setProviderHistoryTransform(transform?: (history: ChatMessage[]) => ChatMessage[]): void {\n this.providerHistoryTransform = transform;\n }\n\n getHistory(): ReadonlyArray<ChatMessage> {\n return this.history;\n }\n\n getRawHistory(): readonly ChatMessage[] {\n return this.history;\n }\n\n /** Returns the current fold stack names for debugging. */\n getActiveFoldNames(): string[] {\n return this.foldStack.map((f) => f.foldName);\n }\n\n async getSuggestions(\n history: ChatMessage[],\n prompt: string,\n count: number,\n allAgentInfo?: AllAgentSummary[],\n ): Promise<string[]> {\n // Suggestions are an out-of-turn UI helper, not bound to any single agent \u2014\n // always run against the registry default. Best-effort: a default with no\n // `prompt()` just means no suggestions, not a hard error.\n const defaultProvider = this.providerRegistry.default();\n if (!defaultProvider.prompt) {\n logger.warn('ChatDriver: default AI provider does not implement prompt()');\n return [];\n }\n\n let agentContext = '';\n let toolContext = '';\n\n if (allAgentInfo?.length) {\n const agentDescriptions = allAgentInfo\n .map((agent) => {\n const tools = agent.tools.map((t) => t.name).join(', ');\n return `- ${agent.name} (${agent.description}): ${tools ? `(Tools: ${tools})` : 'No tools'}`;\n })\n .join('\\n');\n agentContext = `The assistant has the following capabilities:\\n${agentDescriptions}`;\n\n const allToolNames = allAgentInfo\n .flatMap((agent) => agent.tools.map((t) => t.name))\n .filter((value, index, self) => self.indexOf(value) === index)\n .join(', ');\n toolContext = allToolNames\n ? `You have access to the following tools across all agents: ${allToolNames}.`\n : '';\n } else if (this.activeAgentName) {\n const toolNames = this.toolDefinitions.map((tool) => tool.name).join(', ');\n agentContext = `You are currently acting as the \"${this.activeAgentName}\" agent.`;\n toolContext = toolNames ? `You have access to the following tools: ${toolNames}.` : '';\n }\n\n // System prompt is intentionally short: it sets the role only. Concrete\n // instructions live in the user message *after* the transcript so the\n // immediately-preceding context for the model is \"here is data, now do X\"\n // rather than \"here is a dialogue, continue it\". This matters for Anthropic\n // \u2014 without it, Claude reads the transcript as an in-progress conversation\n // and produces a normal assistant turn instead of a list of suggestions.\n const systemPrompt =\n 'You generate suggested prompts that a user could send to an AI assistant. ' +\n 'You never continue the conversation or roleplay as the assistant.';\n\n const capabilitiesBlock =\n agentContext || toolContext\n ? `\\n\\n<capabilities>\\n${[agentContext, toolContext].filter(Boolean).join('\\n')}\\n</capabilities>\\nSuggestions must only cover what the agent is capable of. Do not suggest anything outside these capabilities.`\n : '';\n\n const guidanceBlock = prompt ? `\\n\\nAdditional guidance: \"${prompt}\"` : '';\n\n let userMessage: string;\n if (history.length === 0) {\n userMessage =\n `Generate exactly ${count} brief starter prompts to show a user what an AI assistant can do. ` +\n `Phrase each one as the user would write it. Keep them short and generic \u2014 do not invent specific names, IDs, or data (e.g. prefer \"Search for a trade\" over \"Find all trades with Client A\").` +\n capabilitiesBlock +\n guidanceBlock +\n `\\n\\nOutput format (strict):\\n` +\n `- Exactly ${count} lines.\\n` +\n `- One suggestion per line.\\n` +\n `- No numbering, bullets, markdown, emojis, code blocks, or quotes around the suggestion.\\n` +\n `- No preamble, headings, summary, or commentary before or after the list.`;\n } else {\n const conversationContext = history\n .filter(\n (m) =>\n (m.role === 'user' || m.role === 'assistant') &&\n !m.toolCalls?.length &&\n !m.thinking &&\n !!m.content?.trim(),\n )\n .slice(-SUGGESTIONS_HISTORY_WINDOW)\n .map((m) => `${m.role === 'user' ? 'User' : 'Assistant'}: ${m.content}`)\n .join('\\n');\n\n userMessage =\n `<conversation_history>\\n${conversationContext}\\n</conversation_history>\\n\\n` +\n `The conversation above has ended. Do not continue it or respond as the assistant. ` +\n `Generate exactly ${count} follow-up prompts the *user* might send next, phrased in first person as the user would write them. ` +\n `The first ${Math.max(0, count - 1)} should be natural follow-ups to the last turn. ` +\n `Do not invent specific names, IDs, or data values that do not appear in <conversation_history>.` +\n capabilitiesBlock +\n guidanceBlock +\n `\\n\\nOutput format (strict):\\n` +\n `- Exactly ${count} lines.\\n` +\n `- One suggestion per line.\\n` +\n `- No numbering, bullets, markdown, emojis, code blocks, or quotes around the suggestion.\\n` +\n `- No preamble, headings, summary, or commentary before or after the list.`;\n }\n\n const text = await defaultProvider.prompt!(userMessage, { systemPrompt });\n\n // Lenient parsing as a defensive backstop: even with the strict prompt,\n // models occasionally slip in numbering, bullets, or surrounding markdown.\n return (\n text\n .split('\\n')\n .map((s) => s.trim())\n // strip leading bullets/numbers (\"- \", \"* \", \"\u2022 \", \"1. \", \"1) \")\n .map((s) => s.replace(/^([-*\u2022]|\\d+[.)])\\s+/, ''))\n // strip surrounding bold/italic markers\n .map((s) => s.replace(/^[*_]{1,3}|[*_]{1,3}$/g, '').trim())\n // drop empty lines, separators, and obvious preamble lines\n .filter((s) => s.length > 0)\n .filter((s) => !/^[-=]{2,}$/.test(s))\n .filter((s) => !/^here (are|is) /i.test(s))\n .filter((s) => !s.endsWith(':'))\n .slice(0, count)\n );\n }\n\n /**\n * Whether `compact()` would do anything right now \u2014 a summarizable run of older\n * turns exists behind a clean boundary. Uses the same `history` `compact()`\n * acts on, so the UI's gate can't disagree with the action (GENC-1351 follow-up).\n */\n canCompact(): boolean {\n return findCompactionCut(this.history) != null;\n }\n\n /**\n * Destructively compact older turns into a single `compacted-summary` message\n * (GENC-1351 \u00A75.7). Summarizes everything before a clean recent-tail boundary\n * via the registry-default provider's one-shot `prompt()`, then **atomically**\n * replaces the covered turns with one summary message at the head \u2014 history is\n * mutated only on success. Rolling: any existing head summary is folded into\n * the new one. Returns the created summary message, or `null` when there is\n * nothing worth compacting or the default provider cannot summarize.\n */\n async compact(): Promise<ChatMessage | null> {\n if (this.busy) return null;\n const defaultProvider = this.providerRegistry.default();\n if (!defaultProvider.prompt) {\n logger.warn('ChatDriver: default AI provider has no prompt(); cannot compact');\n return null;\n }\n\n const history = this.history;\n const cut = findCompactionCut(history);\n if (cut == null) return null;\n\n const toCompact = history.slice(0, cut);\n const tail = history.slice(cut);\n\n // Summarize BEFORE mutating history \u2014 a failed/empty call leaves the\n // transcript untouched (atomic generate-then-replace).\n const { systemPrompt, userMessage } = buildCompactionSummaryPrompt(toCompact);\n // Surface a failure the way turn errors are surfaced \u2014 a brief \"sorry\" agent\n // message \u2014 while leaving the transcript itself untouched (atomic). Retrying\n // is safe (nothing was spliced).\n const failMessage =\n \"Sorry, I couldn't compact the conversation just now. Nothing was changed \u2014 please try again.\";\n let summaryText: string;\n try {\n summaryText = (await defaultProvider.prompt!(userMessage, { systemPrompt }))?.trim() ?? '';\n } catch (e) {\n logger.warn(`ChatDriver: compaction summary failed: ${e instanceof Error ? e.message : e}`);\n this.appendToHistory({ role: 'assistant', content: failMessage });\n return null;\n }\n if (!summaryText) {\n logger.warn('ChatDriver: compaction summary was empty; leaving history untouched');\n this.appendToHistory({ role: 'assistant', content: failMessage });\n return null;\n }\n\n let tokensBefore: number | undefined;\n for (let i = history.length - 1; i >= 0; i -= 1) {\n if (history[i].inputTokens != null) {\n tokensBefore = history[i].inputTokens;\n break;\n }\n }\n const status = await defaultProvider.getStatus?.();\n const createdAt = new Date().toISOString();\n const summaryMessage: ChatMessage = {\n role: 'compacted-summary',\n content: summaryText,\n // Stamp with the covered region's start, not \"now\": the summary stands in\n // for the oldest messages and sits at the head of history, so this keeps it\n // sorted to the head in any timestamp-ordered view (the debug timeline) and\n // history time-monotonic. Its true creation time is in compaction.createdAt.\n timestamp: toCompact[0]?.timestamp ?? createdAt,\n compaction: {\n compactedCount: toCompact.length,\n coveredThroughTimestamp: toCompact[toCompact.length - 1]?.timestamp,\n tokensBefore,\n model: status?.model,\n createdAt,\n // Bank what the replaced turns spent. `toCompact` is dropped from history\n // below, taking its per-message cost/token fields with it \u2014 so a host total\n // re-derived from the transcript would otherwise fall by exactly this much\n // on every compaction. Summarising a turn does not refund what it cost.\n rolledUpUsage: sumUsage(toCompact),\n },\n };\n\n this.loadHistory([summaryMessage, ...tail]);\n return summaryMessage;\n }\n\n isBusy(): boolean {\n return this.busy;\n }\n\n /**\n * Wire a parent driver as the host for this driver's interactions. When set,\n * `requestInteraction` delegates upward so the widget renders in (and\n * resolves through) the parent's history and pending map. Calls chain\n * naturally: a grandchild \u2192 child \u2192 root.\n */\n public setHostInteractionRequester(\n fn: <T>(componentName: string, data: any, options?: InteractionRequestOptions) => Promise<T>,\n ): void {\n this.hostInteractionRequester = fn;\n }\n\n /**\n * Request a custom UI interaction. Emits a new message with the interaction.\n * Tool handlers can call this to pause execution until the user completes the UI interaction.\n *\n * If a host requester is wired (sub-agent case), the call delegates upward\n * so the interaction lives on the parent \u2014 the main UI is only listening to\n * the root driver. Only one interaction may be in flight at any time on a\n * given root: concurrent calls (e.g. two parallel sub-agents both spawning a\n * widget) throw. Parallel sub-agents are for parallel work, not for user\n * interaction, which is inherently sequential.\n *\n * @param componentName - The custom element name to render.\n * @param data - Data to pass to the component.\n * @param options - Optional per-call overrides, including\n * `chatInputDuringExecution` to hide or disable the main chat input while\n * the widget is awaiting user input (reverts when the interaction resolves),\n * and `presentation` to control whether the host wraps the widget in a chat\n * bubble and/or shows the \"Assistant\" label.\n */\n public async requestInteraction<T>(\n componentName: string,\n data: any,\n options?: InteractionRequestOptions,\n ): Promise<T> {\n if (this.hostInteractionRequester) {\n return this.hostInteractionRequester<T>(componentName, data, options);\n }\n if (this.pendingInteractions.size > 0) {\n throw new Error(\n 'requestInteraction: another user interaction is already in flight. ' +\n 'Only one interaction may be active at a time \u2014 sequence them in a single tool handler ' +\n 'rather than spawning widgets from parallel sub-agents or parallel tool calls.',\n );\n }\n const interactionId = crypto.randomUUID();\n const chatInputDuringExecution = options?.chatInputDuringExecution;\n const timeoutMs = options?.timeoutMs;\n const presentation = options?.presentation;\n return new Promise((resolve, reject) => {\n this.pendingInteractions.set(interactionId, {\n resolve,\n reject,\n overrideId: chatInputDuringExecution ? interactionId : undefined,\n // Resolve the interaction with a timeout result if the user does not\n // respond in time. `resolveInteraction` runs the same teardown a normal\n // resolution does (marks the widget read-only, reverts any input\n // override) and clears any still-pending handle.\n timeoutHandle:\n timeoutMs != null\n ? setTimeout(() => {\n this.resolveInteraction(interactionId, {\n status: 'timeout',\n message: `Interaction timed out after ${timeoutMs}ms.`,\n } satisfies InteractionResult);\n }, timeoutMs)\n : undefined,\n });\n recordMetaEvent(this.sessionKey, 'interaction.requested', {\n interactionId,\n component: componentName,\n agent: this.activeAgentName,\n });\n // Signal the park boundary on the activity bus so turn-aware UI can tell\n // \"actively computing\" from \"parked awaiting the user\" \u2014 the latter is a\n // safe window for actions disallowed mid-request (e.g. switching provider\n // during a long journey step). Paired with `interaction-resolved`.\n this.activityBus.publish('interaction-requested', undefined);\n if (chatInputDuringExecution) {\n this.dispatchEvent(\n new CustomEvent('interaction-start', {\n detail: { interactionId, chatInputDuringExecution },\n }),\n );\n }\n // Create the live context (GENC-1390) BEFORE the widget can mount, so the\n // wrapper finds it when it builds the pending `interaction` descriptor.\n this.interactionContexts.set(interactionId, createInteractionContext(interactionId));\n this.appendToHistory({\n role: 'assistant',\n content: '',\n interaction: {\n interactionId,\n componentName,\n data,\n ...(presentation ? { presentation } : {}),\n },\n });\n });\n }\n\n /**\n * Resolve a pending interaction. The wrapper component calls this on completion.\n * Marks the interaction message as resolved so it renders read-only on re-render.\n */\n public resolveInteraction(interactionId: string, result: any): void {\n const interaction = this.pendingInteractions.get(interactionId);\n if (interaction) {\n // Clear the timeout so a user resolution doesn't later fire a stale\n // timeout (and a timeout firing here clears its own already-fired handle).\n if (interaction.timeoutHandle) clearTimeout(interaction.timeoutHandle);\n // Harvest any out-of-band diagnostic entries the widget collated (e.g. from a server-side\n // ChatDriver) so the host's debug log + persisted diagnostics include them. Independent of the\n // message `idx` below \u2014 they describe the widget's own work, not this message.\n //\n // The harvested entries carry the SOURCE engine's own index space (0-based turns/events), which\n // would collide with this host's cursors in the forward-capture persister \u2014 turns dedup by\n // `turnIndex`, events by an `index` high-water mark \u2014 so foreign entries get silently dropped\n // from the persisted stream. Route each kind through the host's own collision-safe machinery,\n // mirroring how a sub-agent's log is folded in (see `invokeSubAgent`):\n // \u2022 `event` \u2192 `mergeMetaEvents`, which re-indexes them onto this session's monotonic event\n // counter (clearing the high-water) while preserving their timestamps; they then\n // reach the log via `getMetaEvents` in `buildTimelineEntries`, not this buffer.\n // \u2022 `turn` \u2192 re-key `turnIndex` to the turn's local position within a per-batch namespace,\n // so turns stay unique even when one interaction folds in several independent\n // server runs that each number their own turns from 0 (a consolidator carries a\n // consolidator-code run AND a table-code run), and never collide with the host's\n // own bare-integer turn keys.\n // \u2022 `message` \u2192 kept as-is; the persister already keys messages by content, so they survive.\n // TODO(GENC-1461, option 2 / streaming): expose an imperative `appendDiagnostics(entries)` on\n // the handler context (see buildHandlerContext) that runs this same decomposition as SSE ticks\n // arrive, so a streaming widget can surface its external engine's log live rather than only at\n // resolve time. Batch-at-resolve (here) is the current, non-streaming path.\n const harvestedDiagnostics = (result as { diagnostics?: readonly unknown[] } | undefined)\n ?.diagnostics;\n if (Array.isArray(harvestedDiagnostics) && harvestedDiagnostics.length) {\n const batch = (this.externalDiagnosticsBatches += 1);\n const externalEvents: MetaEvent[] = [];\n let turnCount = 0;\n let messageCount = 0;\n for (const raw of harvestedDiagnostics) {\n // The harvest is external and typed `unknown[]`, so an element could be a primitive, null,\n // or an object without a string `kind`. Guard before reading `.kind` so a malformed entry\n // can't throw here (and gets skipped rather than derailing the whole fold).\n if (\n !raw ||\n typeof raw !== 'object' ||\n typeof (raw as { kind?: unknown }).kind !== 'string'\n ) {\n continue;\n }\n const entry = raw as DiagnosticEntry;\n if (entry.kind === 'event') {\n const { kind: _kind, ...event } = entry;\n externalEvents.push(event as unknown as MetaEvent);\n } else if (entry.kind === 'turn') {\n // Local position within THIS harvest, not the source engine's own `turnIndex`: one\n // interaction can carry several independent server runs (a consolidator folds in its\n // consolidator-code run and its table-code run), each numbering its turns from 0, so\n // keying by the source index would collide them. The local position keeps every turn key\n // distinct within the batch, so the persister's per-`turnIndex` dedup keeps them all.\n this.externalDiagnostics.push({\n ...entry,\n turnIndex: `server-generation.${batch}:${turnCount}`,\n });\n turnCount += 1;\n } else if (entry.kind === 'message') {\n messageCount += 1;\n this.externalDiagnostics.push(entry);\n }\n // Any other kind is intentionally dropped, not folded. A sibling's `buildTimelineEntries`\n // only ever emits message/turn/event; `meta-snapshot` is host/DOM-owned (latest-wins on\n // reassembly, plus its own persister dedup), so folding a foreign one would pollute this\n // host's timeline and meta cursor. Restricting to the three real kinds also keeps the\n // manifest counts accurate (nothing miscounted as a `message`).\n }\n if (externalEvents.length) mergeMetaEvents(this.sessionKey, externalEvents);\n // Manifest: one provenance marker for the fold itself \u2014 records that an out-of-band engine's\n // log crossed into this session and how much of each kind, so a regression that silently\n // drops a generation's diagnostics (e.g. a new path that forgets to thread them across the\n // boundary) surfaces as a zero/absent manifest rather than only by diffing a download. Also\n // the natural seed for the streaming PR's open/close bracket. Stamped at resolve, so it\n // closes the block on the sorted timeline. (GENC-1461.)\n recordMetaEvent(this.sessionKey, 'external-diagnostics.folded', {\n interactionId,\n batch,\n counts: { turn: turnCount, event: externalEvents.length, message: messageCount },\n });\n }\n const idx = this.history.findIndex((m) => m.interaction?.interactionId === interactionId);\n if (idx !== -1) {\n // Fold any widget-reported external (non-LLM) cost onto the message, so\n // the host's `sumCosts` recompute includes it in the session total.\n // Accumulates defensively in case a widget reports more than once.\n const costUsd =\n typeof result?.costUsd === 'number' &&\n Number.isFinite(result.costUsd) &&\n result.costUsd > 0\n ? result.costUsd\n : undefined;\n this.history[idx] = {\n ...this.history[idx],\n interaction: { ...this.history[idx].interaction!, resolved: result },\n ...(costUsd != null\n ? { externalCostUsd: (this.history[idx].externalCostUsd ?? 0) + costUsd }\n : {}),\n };\n this.dispatchEvent(\n new CustomEvent<ReadonlyArray<ChatMessage>>('history-updated', {\n detail: this.history,\n }),\n );\n }\n // A widget may opt into echoing its outcome on the user's side of the\n // chat by returning `userMessage`. Appended as a display-only\n // `'synthetic-user'` message: it is tracked in history (and the debug log)\n // and rendered like a user message, but transports never serialize it \u2014\n // the model already learns the outcome from this handler's return value.\n // Appended before `interaction.resolve` so it precedes the tool result and\n // any follow-up turn the resumed handler produces.\n if (typeof result?.userMessage === 'string' && result.userMessage.trim()) {\n this.appendToHistory({ role: 'synthetic-user', content: result.userMessage });\n }\n if (interaction.overrideId) {\n this.dispatchEvent(new CustomEvent('interaction-stop', { detail: { interactionId } }));\n }\n recordMetaEvent(this.sessionKey, 'interaction.resolved', { interactionId });\n // The park is ending and the loop is about to resume computing \u2014 paired\n // with `interaction-requested`. Fires for every resolution path (user\n // completion, timeout, cancellation), since all route through here.\n this.activityBus.publish('interaction-resolved', undefined);\n interaction.resolve(result);\n this.pendingInteractions.delete(interactionId);\n // Tear down the live context on RESOLVE (not on element unmount) \u2014 this closes\n // any sockets/timers the widget parked on it via `onDispose`. (GENC-1390)\n this.interactionContexts.get(interactionId)?.dispose();\n this.interactionContexts.delete(interactionId);\n } else {\n logger.warn(`Interaction with ID ${interactionId} not found.`);\n }\n }\n\n /**\n * The live {@link InteractionContext} for a pending interaction (GENC-1390), or\n * `undefined` once resolved/evicted. Read by `AiChatInteractionWrapper` (via the\n * host) to build the widget's pending `interaction` descriptor.\n */\n public getInteractionContext(interactionId: string): InteractionContext | undefined {\n return this.interactionContexts.get(interactionId)?.context;\n }\n\n /**\n * Resolve every in-flight interaction with a `'timeout'` result, closing its\n * widget read-only. Used when a sub-agent that owns the open widget times out:\n * the widget is parked in *this* driver's map (interactions resolve on the\n * host, not the child), so cancelling it here unblocks the sub-agent handler\n * awaiting it. The \"one interaction at a time\" invariant means there is at\n * most one.\n */\n private cancelPendingInteractions(message: string): void {\n for (const interactionId of [...this.pendingInteractions.keys()]) {\n this.resolveInteraction(interactionId, {\n status: 'timeout',\n message,\n } satisfies InteractionResult);\n }\n }\n\n /**\n * Seeds the driver with a prior conversation history so a new component instance\n * can continue an existing conversation. Call this before the first user message.\n */\n public loadHistory(messages: ChatMessage[]): void {\n this.history = [...messages];\n this.dispatchEvent(\n new CustomEvent<ReadonlyArray<ChatMessage>>('history-updated', {\n detail: this.history,\n }),\n );\n }\n\n async sendMessage(userInput: string, attachments?: ChatAttachment[]): Promise<ChatDriverResult> {\n if (this.busy || (!userInput.trim() && !attachments?.length)) return { reason: 'done' };\n\n this.busy = true;\n this.beginTurn();\n // A new user turn \u2014 advances the `turnEnd` clock (continuations after a\n // handoff stay on the same turn; they go through `continueFromHistory`).\n this.turnSeq += 1;\n this.subAgentCompletion = undefined;\n this.subAgentFailure = undefined;\n this.agentReleaseRequested = false;\n this.budgetExhaustedThisTurn = false;\n this.budgetWallDetail = undefined;\n this.budgetWallViaSubAgent = false;\n this.appendToHistory({ role: 'user', content: userInput, attachments });\n this.turnStartedAt = Date.now();\n recordMetaEvent(this.sessionKey, 'turn.start', {\n phase: 'sendMessage',\n agent: this.activeAgentName,\n });\n this.activityBus.publish('tool-loop-start', undefined);\n\n // Captured so the `finally` can carry the turn's outcome onto `tool-loop-end`.\n let result: ChatDriverResult = { reason: 'done' };\n try {\n result = await this.runToolLoop(userInput, attachments);\n return result;\n } catch (e) {\n logger.error('ChatDriver error:', e);\n recordTurnError(this.sessionKey, 'exception', {\n phase: 'sendMessage',\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n name: e instanceof Error ? e.name : undefined,\n message: e instanceof Error ? e.message : String(e),\n });\n this.appendToHistory({\n role: 'assistant',\n content: 'Sorry, something went wrong on my end. Please try again in a moment.',\n });\n result = this.turnDone('exception');\n return result;\n } finally {\n recordMetaEvent(this.sessionKey, 'turn.end', {\n phase: 'sendMessage',\n agent: this.activeAgentName,\n durationMs: Date.now() - this.turnStartedAt,\n });\n this.busy = false;\n this.endTurn();\n this.activityBus.publish('tool-loop-end', this.loopEndDetail(result));\n }\n }\n\n /**\n * Builds the context object passed to every tool handler call.\n * Centralised here so fold shortcut dispatch and the main tool loop use the\n * same context without duplication.\n *\n * @param activeToolCallId - The id of the tool call this context belongs to, so\n * `condenseWhen` can register against the right call (it stamps the clocks\n * straight off the driver). Absent for dispatch paths with no addressable tool\n * call (e.g. the fold-close handler), where `condenseWhen` is a no-op.\n * @param traceCapture - Optional per-invocation slot. When provided, the trace\n * from any sub-agent call is written here rather than to shared instance state,\n * so parallel tool calls each capture their own trace independently.\n */\n private buildHandlerContext(activeToolCallId?: string, traceCapture?: { trace?: ChatMessage[] }) {\n return {\n requestInteraction: <T>(\n componentName: string,\n data: any,\n options?: InteractionRequestOptions,\n ): Promise<T> => this.requestInteraction(componentName, data, options),\n ...(this.subAgentsMap.size > 0 && {\n requestSubAgent: <T = never>(\n name: string,\n options?: SubAgentRequestOptions,\n ): Promise<\n | { ok: true; result: T; reason?: never }\n | { ok: false; result?: never; reason: SubAgentFailureReason }\n > =>\n this.invokeSubAgent<T>(name, options).then(({ outcome, trace }) => {\n if (traceCapture) traceCapture.trace = trace;\n return outcome;\n }),\n }),\n completeSubAgent: (result: unknown): void => {\n if (this.subAgentCompletion) {\n logger.warn(\n `ChatDriver(${this.activeAgentName ?? 'unknown'}): completeSubAgent called more than once \u2014 ignoring`,\n );\n return;\n }\n this.subAgentCompletion = { result };\n // This activation's flow has ended \u2014 advance the clock so its\n // `agentEnd` payloads collapse and a re-run starts a fresh activation.\n this.currentActivation += 1;\n },\n releaseAgent: (): void => {\n if (this.agentReleaseRequested) {\n logger.warn(\n `ChatDriver(${this.activeAgentName ?? 'unknown'}): releaseAgent called more than once \u2014 ignoring`,\n );\n return;\n }\n this.agentReleaseRequested = true;\n // The stateful flow has wrapped up \u2014 advance the clock so its `agentEnd`\n // payloads collapse and a re-run starts a fresh activation.\n this.currentActivation += 1;\n },\n endPhase: (): void => {\n // Advance the phase epoch so payloads registered with `{ on: phaseEnd }`\n // during the phase that just ended collapse on the next provider call.\n // Repeatable (no once-only guard, unlike releaseAgent/completeSubAgent):\n // each call opens a fresh phase for subsequent reads to accumulate in.\n this.currentPhaseEpoch += 1;\n },\n condenseWhen: (policy: CondensePolicy): void => {\n // No addressable tool call (e.g. fold-close handler) \u2014 nothing to attach to.\n if (!activeToolCallId) return;\n if (!policy?.args && !policy?.response) {\n logger.warn(\n `ChatDriver(${this.activeAgentName ?? 'unknown'}): condenseWhen called with neither args nor response \u2014 ignoring`,\n );\n return;\n }\n const triggers = Array.isArray(policy.on) ? policy.on : [policy.on];\n const validTrigger = (t: CondenseTrigger | undefined): boolean =>\n t?.kind === 'superseded'\n ? typeof t.by === 'string' && t.by.length > 0\n : t?.kind === 'age'\n ? typeof t.turns === 'number' && t.turns >= 1\n : t?.kind === 'turnEnd' || t?.kind === 'agentEnd' || t?.kind === 'phaseEnd';\n if (triggers.length === 0 || !triggers.every(validTrigger)) {\n logger.warn(\n `ChatDriver(${this.activeAgentName ?? 'unknown'}): condenseWhen called with an invalid trigger \u2014 ignoring`,\n );\n return;\n }\n // First-wins: a handler declares its policy once per call. A second\n // declaration for the same tool call is a handler bug, not a refinement.\n if (this.condensePolicies.has(activeToolCallId)) {\n logger.error(\n `ChatDriver(${this.activeAgentName ?? 'unknown'}): condenseWhen called more than once for the same tool call \u2014 keeping the first policy, ignoring this one`,\n );\n return;\n }\n // Stamp the three clocks NOW (read straight off the driver \u2014 the handler\n // runs during the current model-call's tool batch).\n this.condensePolicies.set(activeToolCallId, {\n policy,\n iteration: this.modelCallSeq,\n turn: this.turnSeq,\n activation: this.currentActivation,\n phaseEpoch: this.currentPhaseEpoch,\n });\n },\n };\n }\n\n /**\n * Creates a child `ChatDriver` for the named sub-agent, runs it to completion,\n * and returns its structured result (or final text fallback) together with the\n * full child conversation trace. Callers receive both values so each parallel\n * invocation can capture its own trace without touching shared instance state.\n */\n private async invokeSubAgent<T = never>(\n name: string,\n options?: SubAgentRequestOptions,\n ): Promise<{\n // Closed union (see ChatToolHandlers.requestSubAgent) \u2014 keeps `result`/`reason`\n // accessible for consumers compiled without strictNullChecks.\n outcome:\n | { ok: true; result: T; reason?: never }\n | { ok: false; result?: never; reason: SubAgentFailureReason };\n trace: ChatMessage[];\n }> {\n const subConfig = this.subAgentsMap.get(name);\n if (!subConfig) {\n const available = [...this.subAgentsMap.keys()].join(', ') || '(none)';\n throw new Error(\n `Sub-agent \"${name}\" not found on agent \"${this.activeAgentName}\". Available: ${available}`,\n );\n }\n\n const { task, historyCap, context, timeoutMs } = options ?? {};\n\n // Exclude the current in-flight assistant message (the one with tool calls that\n // triggered this invocation) \u2014 it has unresolved tool calls that would confuse\n // the sub-agent into thinking it needs to handle tools it doesn't own.\n const lastMsg = this.history[this.history.length - 1];\n const baseHistory =\n lastMsg?.role === 'assistant' && lastMsg.toolCalls?.length\n ? this.history.slice(0, -1)\n : this.history;\n\n const snapshotHistory =\n historyCap != null ? applyHistoryCap(baseHistory, historyCap) : [...baseHistory];\n\n const contextMessages: ChatMessage[] = context\n ? [{ role: 'user', content: `[Sub-agent context]: ${JSON.stringify(context)}` }]\n : [];\n\n const effectivePrimer: ChatMessage[] = [\n ...snapshotHistory,\n ...contextMessages,\n ...(subConfig.primerHistory ?? []),\n ];\n\n // Unique per-invocation id \u2014 reused for the lifecycle event bracket below \u2014\n // and a child session key derived from it. The child files its meta events\n // under this own bucket (rather than the shared empty-key sink), so they can\n // be harvested into THIS session on completion and then discarded.\n const invocationId = crypto.randomUUID();\n const childSessionKey = `${this.sessionKey}::sub:${invocationId}`;\n const child = new ChatDriver(this.providerRegistry, {\n sessionKey: childSessionKey,\n // Inherit the parent's bus so the sub-agent's tool-loop events still surface\n // (off-browser this is the shared no-op).\n activityBus: this.activityBus,\n });\n // Mark before the first turn so the child forces tool use and reports a\n // typed failure (rather than user-facing text) if it never completes.\n child.markAsSubAgent();\n // Propagate disposal: if this (parent) driver is torn down while the\n // sub-agent is mid-flight, dispose the child too so its in-flight request\n // aborts. Detached in the `finally` below once the sub-agent completes.\n const disposeChild = () => child.dispose();\n if (this.lifecycleController.signal.aborted) {\n disposeChild();\n } else {\n this.lifecycleController.signal.addEventListener('abort', disposeChild, { once: true });\n }\n child.applyAgent({ ...subConfig, primerHistory: effectivePrimer });\n // Route interactions back through this driver so widgets render in the\n // parent's (ultimately the root's) history and resolve via the same\n // pending map the main UI is wired to. Recurses naturally for nested\n // sub-agents.\n child.setHostInteractionRequester(\n <R>(componentName: string, data: any, opts?: InteractionRequestOptions): Promise<R> =>\n this.requestInteraction<R>(componentName, data, opts),\n );\n\n const forwardTrace = (e: Event) => {\n this.dispatchEvent(\n new CustomEvent('sub-agent-history-updated', {\n detail: { agentName: subConfig.name, history: (e as CustomEvent<ChatMessage[]>).detail },\n }),\n );\n };\n // Re-dispatch the child's `provider-changed` so the UI reflects whichever\n // provider is *actually* running right now (the sub-agent may use a\n // different provider than the parent). Restoration of the parent's\n // provider on `sub-agent-stop` is handled by the listener in main.ts.\n const forwardProviderChanged = (e: Event) => {\n this.dispatchEvent(\n new CustomEvent('provider-changed', { detail: (e as CustomEvent).detail }),\n );\n };\n child.addEventListener('history-updated', forwardTrace);\n child.addEventListener('provider-changed', forwardProviderChanged);\n\n const chatInputDuringExecution = options?.chatInputDuringExecution;\n const lifecycleDetail = { name, invocationId, chatInputDuringExecution };\n\n this.dispatchEvent(new CustomEvent('sub-agent-start', { detail: lifecycleDetail }));\n // Bracket the run on the timeline (mirrors turn.start/turn.end). Recorded\n // under THIS (parent) session \u2014 like subagent.completed/failed below \u2014 so the\n // sub-agent's span is visible on the user-facing timeline, not the child's.\n recordMetaEvent(this.sessionKey, 'subagent.started', { agent: name });\n let timedOut = false;\n const runPromise = child.sendMessage(task ?? '');\n try {\n if (timeoutMs == null) {\n await runPromise;\n } else {\n // Race the run against the deadline. On timeout, abort the child (which\n // cancels its in-flight provider request) and let the aborted run settle\n // before we tear down and return the timeout outcome.\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n try {\n const timeoutSignal = new Promise<'timeout'>((resolveTimeout) => {\n timeoutHandle = setTimeout(() => resolveTimeout('timeout'), timeoutMs);\n });\n const winner = await Promise.race([\n runPromise.then(() => 'done' as const),\n timeoutSignal,\n ]);\n if (winner === 'timeout') {\n timedOut = true;\n child.dispose();\n // The sub-agent may be parked awaiting a user interaction, which is\n // routed up to this driver and parked in *this* pending map (widgets\n // resolve on the host, not the child). Disposing the child does not\n // settle that promise, so the child stays suspended \u2014 cancel the\n // interaction to close the widget and unblock the child. Without this,\n // `await runPromise` below would hang forever and the timeout would\n // never complete (or record `subagent.failed`).\n this.cancelPendingInteractions(`Sub-agent \"${name}\" timed out after ${timeoutMs}ms.`);\n await runPromise.catch(() => undefined);\n }\n } finally {\n // Always clear the timer \u2014 even if the race rejects \u2014 so it never leaks.\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n }\n } finally {\n this.lifecycleController.signal.removeEventListener('abort', disposeChild);\n child.removeEventListener('history-updated', forwardTrace);\n child.removeEventListener('provider-changed', forwardProviderChanged);\n // Tear the child down on every exit path, not just timeout/parent-abort.\n // A child that completes normally is otherwise never disposed, so its\n // provider-registry subscription (wired in the ChatDriver constructor)\n // would leak \u2014 the long-lived registry would retain every completed\n // sub-agent driver. dispose() is idempotent and only aborts the (already\n // settled) lifecycle, so the snapshot/completion reads below still work.\n child.dispose();\n this.dispatchEvent(new CustomEvent('sub-agent-stop', { detail: lifecycleDetail }));\n // Capture the child's diagnostics into THIS session, then ALWAYS discard its\n // transient bucket \u2014 done in the `finally` so an unexpected `sendMessage`\n // rejection (which propagates out of this method) can't orphan the bucket in\n // the registry, and a crashed sub-agent still leaves its turns/events behind.\n // Forward the child's per-LLM-call snapshots so they show as `kind:'turn'`\n // entries in the exported debug log, re-numbered under the activating parent turn.\n this.forwardSubAgentSnapshots(child.getTurnSnapshots());\n // Fold the sub-agent's high-value meta events (retries/errors/tool failures \u2014\n // see HARVESTED_SUBAGENT_EVENTS) into THIS session, preserving their original\n // timestamps so they interleave within the subagent.started\u2192completed/failed\n // bracket. Each is breadcrumbed `\"<parent> \u203A <sub-agent>\"`, composing for a\n // nested sub-agent whose own breadcrumb the child already merged.\n const parentName = this.activeAgentName ?? '?';\n const harvested = getMetaEvents(childSessionKey)\n .filter((e) => HARVESTED_SUBAGENT_EVENTS.has(e.type))\n .map((e) => {\n const existing = e.detail?.subAgent as string | undefined;\n return { ...e, detail: { ...e.detail, subAgent: `${parentName} \u203A ${existing ?? name}` } };\n });\n mergeMetaEvents(this.sessionKey, harvested);\n clearSession(childSessionKey);\n }\n\n const trace = child.getHistory() as ChatMessage[];\n\n if (timedOut) {\n // Same failure shape as any other non-completion \u2014 the parent handler\n // recovers on its existing `{ ok: false }` branch. Recorded under THIS\n // (parent) session so it lands on the user-visible debug-log timeline.\n recordMetaEvent(this.sessionKey, 'subagent.failed', { agent: name, reason: 'timeout' });\n return { outcome: { ok: false, reason: 'timeout' }, trace };\n }\n\n const completion = child.getSubAgentCompletion();\n\n if (completion) {\n recordMetaEvent(this.sessionKey, 'subagent.completed', { agent: name });\n return { outcome: { ok: true, result: completion.result as T }, trace };\n }\n\n // No completion \u2192 the sub-agent's loop ended without calling its completion\n // tool. Surface the typed reason it recorded; default to 'max_iterations'\n // for the defensive case where the loop ended with no reason set (e.g. a\n // provider ignored forced tool use and returned text). The previous\n // final-text fallback is intentionally gone \u2014 sub-agents return a\n // structured outcome only, and the parent handler decides how to recover.\n const failure = child.getSubAgentFailure();\n const reason = failure?.reason ?? 'max_iterations';\n // Record under THIS (parent) driver's session so the failure lands on the\n // user-visible debug-log timeline \u2014 the child ran under its own session key.\n // This is also the only telemetry for the defensive default above, where the\n // child's loop ended without recording an explicit failure reason.\n recordMetaEvent(this.sessionKey, 'subagent.failed', { agent: name, reason });\n // A child that hit the budget wall walls this driver too \u2014 the cap is shared,\n // and the parent's very next model call would 402 as well. Flagged (not\n // thrown) because the handler's return value is still appended as a tool\n // result: the loop reads the flag before the next provider call and ends the\n // turn there, which is what makes the `'budget_exhausted'` doc's \"terminal\n // for the parent too\" actually true.\n //\n // The child's attribution is inherited with it: the vendor that refused is\n // the child's, which under a mixed registry is not this driver's. See\n // `budgetWallDetail` for what mis-attributing it costs.\n //\n // FIRST attribution wins (`??=`). With batched delegations, child A walling\n // WITH attribution can be followed by child B walling WITHOUT one (a\n // figure-less 402 behind a transport label no vendor claims); a plain\n // assignment reset the field to `undefined` and the short-circuit's\n // fallback then named the parent's own vendor \u2014 the one known NOT to have\n // refused.\n if (reason === 'budget_exhausted') {\n this.budgetExhaustedThisTurn = true;\n this.budgetWallViaSubAgent = true;\n this.budgetWallDetail ??= failure?.budget;\n }\n return { outcome: { ok: false, reason }, trace };\n }\n\n /**\n * Continue the tool loop from current history without appending a new user message.\n * Used by OrchestratingDriver after an agent handoff.\n */\n async continueFromHistory(transientPrimer?: ChatMessage[]): Promise<ChatDriverResult> {\n if (this.busy) return { reason: 'done' };\n\n this.busy = true;\n this.beginTurn();\n this.subAgentCompletion = undefined;\n this.subAgentFailure = undefined;\n this.budgetExhaustedThisTurn = false;\n this.budgetWallDetail = undefined;\n this.budgetWallViaSubAgent = false;\n this.turnStartedAt = Date.now();\n recordMetaEvent(this.sessionKey, 'turn.start', {\n phase: 'continueFromHistory',\n agent: this.activeAgentName,\n });\n this.activityBus.publish('tool-loop-start', undefined);\n // Captured so the `finally` can carry the turn's outcome onto `tool-loop-end`.\n let result: ChatDriverResult = { reason: 'done' };\n try {\n result = await this.runToolLoop('', undefined, transientPrimer);\n return result;\n } catch (e) {\n logger.error('ChatDriver error:', e);\n recordTurnError(this.sessionKey, 'exception', {\n phase: 'continueFromHistory',\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n name: e instanceof Error ? e.name : undefined,\n message: e instanceof Error ? e.message : String(e),\n });\n this.appendToHistory({\n role: 'assistant',\n content: 'Sorry, something went wrong on my end. Please try again in a moment.',\n });\n result = this.turnDone('exception');\n return result;\n } finally {\n recordMetaEvent(this.sessionKey, 'turn.end', {\n phase: 'continueFromHistory',\n agent: this.activeAgentName,\n durationMs: Date.now() - this.turnStartedAt,\n });\n this.busy = false;\n this.endTurn();\n this.activityBus.publish('tool-loop-end', this.loopEndDetail(result));\n }\n }\n\n // ---------------------------------------------------------------------------\n // Fold mechanics\n // ---------------------------------------------------------------------------\n\n /** Extract ToolFold metadata from a handler, or undefined if it isn't a fold facade. */\n private getFold(toolName: string): ToolFold | undefined {\n const handler = this.toolHandlers[toolName];\n return handler ? ((handler as any)[TOOL_FOLD_SYMBOL] as ToolFold | undefined) : undefined;\n }\n\n /**\n * Search all currently registered fold facades (and their nested folds recursively)\n * to find which fold contains a given tool name. Returns the immediate parent fold name.\n */\n private findFoldContaining(toolName: string, handlers?: ChatToolHandlers): string | null {\n const source = handlers ?? this.toolHandlers;\n for (const [, handler] of Object.entries(source)) {\n const fold = (handler as any)[TOOL_FOLD_SYMBOL] as ToolFold | undefined;\n if (!fold) continue;\n // Direct inner tool match\n if (fold.handlers[toolName]) return fold.name;\n // Recurse into nested folds\n const nested = this.findFoldContaining(toolName, fold.handlers);\n if (nested) return fold.name;\n }\n return null;\n }\n\n /**\n * If an open fold is hiding a previously-available tool, return the name of\n * the fold to close to start getting it back. Only exclusive folds hide tools\n * (they replace the tool set on open rather than extending it), so a base tool\n * that was visible before the fold opened now sits in a fold-stack frame's\n * `previousHandlers` but not in the live handler map. Only the top fold's\n * `close_` tool is active, so that's always the actionable next step \u2014 even\n * when the tool lives further down the stack, closing repeatedly walks back to\n * it. Returns null when no open fold accounts for the tool.\n */\n private foldHidingTool(toolName: string): string | null {\n if (this.foldStack.length === 0) return null;\n const hidden = this.foldStack.some((f) => f.previousHandlers[toolName]);\n return hidden ? this.foldStack[this.foldStack.length - 1].foldName : null;\n }\n\n /**\n * Install the fold's inner tool set, replacing (exclusive) or extending (non-exclusive)\n * the current tool set. Also injects the close tool. Does NOT touch the fold stack.\n */\n private applyFoldToolSet(fold: ToolFold, foldName: string): void {\n const closeToolName = `close_${foldName}`;\n const newDefs: ChatToolDefinition[] = [];\n const newHandlers: ChatToolHandlers = {};\n\n if (!fold.exclusive) {\n // Non-exclusive: keep existing tools minus the facade we just opened\n for (const def of this.toolDefinitions) {\n if (def.name !== foldName) newDefs.push(def);\n }\n for (const [name, handler] of Object.entries(this.toolHandlers)) {\n if (name !== foldName) newHandlers[name] = handler;\n }\n }\n\n // Install inner tools from fold metadata\n newDefs.push(...fold.tools);\n Object.assign(newHandlers, fold.handlers);\n\n // Inject the close tool\n newDefs.push({\n name: closeToolName,\n description: `Close the ${foldName} fold and return to the previous set of tools.`,\n parameters: { type: 'object', properties: {} },\n });\n newHandlers[closeToolName] = async (): Promise<string> => this.closeFold();\n\n this.toolDefinitions = newDefs;\n this.toolHandlers = newHandlers;\n }\n\n /** Open a fold: push a stack frame, swap the tool set, return the response message. */\n private openFold(\n foldName: string,\n fold: ToolFold,\n args: Record<string, unknown>,\n activeToolCallId?: string,\n ): Promise<string> {\n // Shortcut dispatch: model passed inner tool args directly, e.g.\n // trading_tools({ search_trades: { side: \"BUY\" } })\n for (const key of Object.keys(args)) {\n const innerHandler = fold.handlers[key];\n if (innerHandler) {\n logger.debug(`ChatDriver: fold shortcut dispatch \"${foldName}\" \u2192 \"${key}\"`);\n // Open the fold first so the tool set is correct for subsequent calls\n this.pushFoldFrame(foldName);\n this.applyFoldToolSet(fold, foldName);\n this.consecutiveFoldOps = 0; // shortcut dispatch counts as real work\n const innerArgs =\n typeof args[key] === 'object' && args[key] !== null\n ? (args[key] as Record<string, unknown>)\n : {};\n return innerHandler(innerArgs, this.buildHandlerContext(activeToolCallId)).then((r) =>\n typeof r === 'string' ? r : JSON.stringify(r),\n );\n }\n }\n\n // Normal two-step open\n this.pushFoldFrame(foldName);\n this.applyFoldToolSet(fold, foldName);\n\n const innerToolNames = fold.tools.map((t) => t.name);\n const closeToolName = `close_${foldName}`;\n let message = `Fold opened: ${foldName}. Tools now available: ${[...innerToolNames, closeToolName].join(', ')}.`;\n if (fold.usageNotes) message += ` Notes: ${fold.usageNotes}`;\n message += ` Call ${closeToolName} when done to return to the previous tools.`;\n return Promise.resolve(message);\n }\n\n private pushFoldFrame(foldName: string): void {\n this.foldStack.push({\n foldName,\n previousDefinitions: [...this.toolDefinitions],\n previousHandlers: { ...this.toolHandlers },\n });\n }\n\n /** Close the top fold: pop the stack frame, restore the previous tool set. */\n private closeFold(): string {\n const frame = this.foldStack.pop();\n if (!frame) return 'No fold is currently open.';\n\n this.toolDefinitions = frame.previousDefinitions;\n this.toolHandlers = frame.previousHandlers;\n\n const toolNames = this.toolDefinitions.map((t) => t.name);\n return `Fold closed: ${frame.foldName}. Tools now available: ${toolNames.join(', ')}.`;\n }\n\n /** Build the fold-awareness suffix appended to the system prompt each LLM call. */\n private buildFoldSystemPromptSuffix(): string {\n // Collect fold facades from the current handler map\n const activeFolds: ToolFold[] = [];\n for (const handler of Object.values(this.toolHandlers)) {\n const fold = (handler as any)[TOOL_FOLD_SYMBOL] as ToolFold | undefined;\n if (fold) activeFolds.push(fold);\n }\n\n if (activeFolds.length === 0 && this.foldStack.length === 0) return '';\n\n const parts: string[] = ['\\n\\n--- Tool Folds ---'];\n parts.push(\n 'Some tools are grouped into folds. You may see tool calls in the conversation history for tools that are not currently available \u2014 they are inside a fold. To access them, invoke the fold tool first.',\n );\n\n if (this.foldStack.length > 0) {\n const current = this.foldStack[this.foldStack.length - 1];\n parts.push(\n `You are currently inside the \"${current.foldName}\" fold. Call close_${current.foldName} when you are done with these tools.`,\n );\n }\n\n for (const fold of activeFolds) {\n parts.push(`\u2022 ${fold.name}: ${fold.description}`);\n }\n\n return parts.join('\\n');\n }\n\n // ---------------------------------------------------------------------------\n // Tool loop\n // ---------------------------------------------------------------------------\n\n // oxlint-disable-next-line complexity\n private async runToolLoop(\n userInput: string,\n attachments?: ChatAttachment[],\n transientPrimer?: ChatMessage[],\n ): Promise<ChatDriverResult> {\n if (!this.systemPrompt) {\n logger.warn(\n 'ChatDriver: no systemPrompt set. The assistant will have no instructions \u2014 provide a systemPrompt via agents config or the foundation-ai-assistant property.',\n );\n }\n\n let currentInput = userInput;\n let currentAttachments: ChatAttachment[] | undefined = attachments;\n let iterations = 0;\n let malformedAttempts = 0;\n let emptyResponseAttempts = 0;\n // Bounded retries for transient throws while resolving the per-turn tool surface or\n // calling the provider. Without this, a single transient throw tears down the whole turn\n // and strands the agent's unflushed work behind an opaque error.\n let setupTransportAttempts = 0;\n // True only for the very first LLM call. Used to exclude the pending user message\n // from history (it is passed separately as currentInput). Must not be derived from\n // `iterations` because fold operations decrement iterations, which would incorrectly\n // re-trigger the slice on subsequent calls after a fold open/close.\n let firstLlmCall = !!currentInput;\n\n while (iterations < this.maxToolIterations) {\n iterations += 1;\n // Monotonic across the driver's life \u2014 the age clock. Unlike `iterations`,\n // it is NOT reset per turn and NOT decremented for folds, so `age` keeps\n // counting model-calls once a turn ends. (See the `modelCallSeq` field.)\n this.modelCallSeq += 1;\n\n // A cancel (or dispose) that landed while the previous iteration's tool\n // batch was running takes effect here \u2014 before issuing another LLM call.\n // An abort during the call itself is handled by the catch below.\n if (this.turnController.signal.aborted) {\n return this.completeAbortedTurn();\n }\n\n // A budget wall observed earlier this turn ends it HERE, before another\n // model call. Reachable only via a sub-agent (this driver's own 402\n // returns straight out of the catch below) \u2014 `invokeSubAgent` sets the\n // flag, its `{ ok: false, reason: 'budget_exhausted' }` outcome is\n // appended as a tool result, and without this the loop would call the\n // provider again into the same wall: N batched sub-agent calls otherwise\n // cost N doomed children AND a doomed parent call.\n //\n // Scoped strictly to the budget reason: every other SubAgentFailureReason\n // is something the parent can legitimately recover from, so those still\n // let the loop continue.\n if (this.budgetExhaustedThisTurn) {\n logger.error('ChatDriver: ending the turn \u2014 a sub-agent hit the AI budget wall');\n recordTurnError(this.sessionKey, 'budget-exhausted', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n // The CHILD's vendor when it knew one, and NOTHING otherwise. On this\n // path the wall is definitionally the child's, and on a mixed registry\n // `lastResolvedProvider` is this driver's own vendor \u2014 the one known\n // NOT to have refused. An unattributable child wall must degrade to\n // the vendor-agnostic block (which `latchBlockedFrom` handles\n // fail-safe), never to a vendor that is known to be wrong: naming the\n // parent's vendor here walled BOTH \u2014 the child's via its own\n // tool-loop-end, the parent's via this event \u2014 and derived `blocked`\n // over headroom that still existed.\n vendor: this.budgetWallDetail?.vendor,\n via: 'sub-agent',\n isSubAgent: this.isSubAgent,\n });\n if (this.isSubAgent) {\n this.failSubAgent('budget_exhausted', this.budgetWallDetail);\n } else {\n this.appendToHistory({ role: 'assistant', content: this.budgetExhaustedMessage });\n }\n // Carried onto the result so `loopEndDetail` publishes the refusing\n // vendor rather than falling through to `lastResolvedProvider`, and the\n // host's latch walls the vendor that actually ran out.\n return this.turnDone('budget-exhausted', this.budgetWallDetail);\n }\n\n const promptCtx: SystemPromptContext = {\n agentName: this.activeAgentName ?? '',\n history: this.history,\n turnIndex: iterations - 1,\n signal: this.turnController.signal,\n };\n\n // Re-resolve dynamic tool definitions before each LLM call. The static\n // case is a no-op (factory is undefined and `this.toolDefinitions` was\n // set by applyAgent). Folds operate on `this.toolDefinitions` and are\n // forbidden when a factory is set, so the array form is always valid.\n // Sequential await is required \u2014 each iteration must see fresh values\n // before constructing the LLM request.\n // A transient throw while building the tool surface should retry the iteration, not\n // tear down the whole turn and strand the agent's unflushed buffer behind an opaque\n // error. The handler-map factory re-resolves in lockstep so dispatch sees only the\n // handlers valid for the current state, in step with the tool definitions exposed\n // above. Folds are forbidden when either factory is set, so the fold-mutation paths\n // on `this.toolDefinitions` / `this.toolHandlers` are unreachable.\n try {\n if (this.toolDefinitionsFactory) {\n // oxlint-disable-next-line no-await-in-loop\n this.toolDefinitions = await this.toolDefinitionsFactory(promptCtx);\n }\n if (this.toolHandlersFactory) {\n // oxlint-disable-next-line no-await-in-loop\n this.toolHandlers = await this.toolHandlersFactory(promptCtx);\n }\n } catch (e) {\n setupTransportAttempts += 1;\n if (setupTransportAttempts < MAX_SETUP_TRANSPORT_RETRIES) {\n logger.warn(\n `ChatDriver: tool-surface resolution failed, retrying (${setupTransportAttempts}/${MAX_SETUP_TRANSPORT_RETRIES})`,\n );\n iterations -= 1;\n continue;\n }\n throw e;\n }\n\n // Record everything advertised this turn so the unknown-tool path can tell\n // a stale tool (real earlier, retired now) from a hallucinated one. Runs\n // for both the static and factory cases; folds also flow through here as\n // their inner tools become visible on the iteration after they open.\n for (const def of this.toolDefinitions) this.everSeenToolNames.add(def.name);\n\n const resolvedSystemPrompt =\n typeof this.systemPrompt === 'function'\n ? // oxlint-disable-next-line no-await-in-loop\n await this.systemPrompt(promptCtx)\n : this.systemPrompt;\n\n // Re-resolve the per-turn display label. Falls back to the canonical\n // agent name when displayName is unset. Stamped onto outgoing messages\n // and turn snapshots for UX only; routing/history-transform continues\n // to read `activeAgentName`.\n if (typeof this.displayName === 'function') {\n // oxlint-disable-next-line no-await-in-loop\n this.activeAgentLabel = await this.displayName(promptCtx);\n }\n\n // Volatile framework additions \u2014 the fold-surface suffix and the per-attempt malformed/empty\n // retry nudge \u2014 that would otherwise destabilize a cached system prompt. They are routed to\n // the framed tail (below), never appended to the system string, so the system prompt stays\n // byte-stable for every agent.\n const foldSuffix = this.buildFoldSystemPromptSuffix();\n const retryNudge =\n malformedAttempts > 0\n ? '\\n\\nIMPORTANT: Use only the structured function-call API to invoke tools. Do not write Python code or use Python-style syntax to call tools.'\n : emptyResponseAttempts > 0\n ? \"\\n\\nIMPORTANT: You must respond to the user's message. Call the appropriate tool or provide a text response \u2014 do not return an empty response.\"\n : '';\n const frameworkSystemSuffix = `${foldSuffix}${retryNudge}`;\n\n // Normalize the primer at the same chokepoint as the driver's own history\n // (GENC-1351 \u00A75.7): a parent's `compacted-summary` message rides into a\n // sub-agent's primer (`requestSubAgent` snapshots the parent's raw history),\n // and it must be translated to a `<conversation_summary>` user message here \u2014\n // otherwise the transports' role filter silently drops it and the sub-agent\n // loses all summarized context. `normalizeForProvider` only touches\n // `compacted-summary`, so it's a safe pass-through for everything else.\n const primer = normalizeForProvider([\n ...(this.primerHistory ?? []),\n ...(transientPrimer ?? []),\n ]);\n const baseHistory = firstLlmCall ? this.history.slice(0, -1) : this.history;\n firstLlmCall = false;\n // Collapse stale tool payloads this agent declared via `condenseWhen`\n // (GENC-1369), then translate any compacted-summary \u2192 a\n // <conversation_summary> user message (GENC-1351 \u00A75.7) before any per-agent\n // masking, so the raw display-only role can never reach a transport. Each\n // step runs on a copy \u2014 stored history is untouched.\n const condensedHistory = applyCondensation(\n [...baseHistory],\n this.condensePolicies,\n {\n modelCall: this.modelCallSeq,\n turn: this.turnSeq,\n // A call's activation has ended once a later activation is current \u2014 a\n // swap or release/complete both advance the counter.\n activationEnded: (activation) => activation < this.currentActivation,\n // A call's phase has ended once the app declared a later phase epoch\n // current via `endPhase()`.\n phaseEnded: (phaseEpoch) => phaseEpoch < this.currentPhaseEpoch,\n batchCalls: this.condenseBatchCalls,\n },\n (detail) => recordMetaEvent(this.sessionKey, 'context.condensed', detail),\n );\n const normalizedHistory = normalizeForProvider(condensedHistory);\n const historyForProvider = this.providerHistoryTransform\n ? this.providerHistoryTransform(normalizedHistory)\n : normalizedHistory;\n const historyForCall = [...primer, ...historyForProvider];\n\n // Resolve the per-turn temperature and tool-call mode the same way the\n // provider is resolved \u2014 static value or a function of the turn context\n // (which carries the live state for stateful agents). Resolved before the\n // snapshot so the debug log records the exact request config the model saw.\n const [\n resolvedTemperature,\n resolvedToolChoice,\n resolvedCachePolicy,\n resolvedTailContext,\n resolvedResponseSchema,\n ] =\n // oxlint-disable-next-line no-await-in-loop\n await Promise.all([\n this.resolveTurnInput<number>(this.activeTemperatureInput, promptCtx),\n this.resolveTurnInput<ChatToolChoice>(this.activeToolChoiceInput, promptCtx),\n this.resolveTurnInput<CachePolicy>(this.activeCachePolicyInput, promptCtx),\n this.resolveTurnInput<string>(this.activeTailContextInput, promptCtx),\n this.resolveTurnInput<object | undefined>(this.activeResponseSchemaInput, promptCtx),\n ]);\n // The system prompt is always just the agent's resolved prompt \u2014 byte-stable, so it can be\n // cached. The framework's volatile additions (fold suffix, retry nudge) and the agent's tail\n // context all go to the framed tail: one uniform channel, no cache-scope branch. On a normal\n // turn `frameworkSystemSuffix` is empty, so the tail is empty too \u2014 a no-op. The framework\n // owns the framing; the corrective retry nudge lands last (recency).\n const systemPrompt = resolvedSystemPrompt || undefined;\n const tailBody = [resolvedTailContext, frameworkSystemSuffix]\n .map((part) => (part ?? '').trim())\n .filter((part) => part.length > 0)\n .join('\\n\\n');\n const tailContext = tailBody\n ? `<system-reminder>\\n${tailBody}\\n</system-reminder>`\n : undefined;\n // An agent/state-configured tool-call mode wins. Otherwise sub-agents must\n // finish by calling a tool (their completion tool) so the turn can't end\n // on a free-text answer; top-level agents stay 'auto'. (Transports no-op a\n // force when no tools are advertised.)\n const effectiveToolChoice = resolvedToolChoice ?? (this.isSubAgent ? 'required' : undefined);\n\n this.recordTurnSnapshot(systemPrompt, resolvedTemperature, effectiveToolChoice, tailContext);\n\n // Capture the pending user input, then clear the slots BEFORE the chat\n // call. `sendMessage` already appended the user message to `this.history`,\n // so on retries (empty / malformed) we must rely on history alone \u2014\n // otherwise the message gets sent twice (once via history, once via\n // `currentInput`), which Gemini answers with an empty response and then\n // we retry forever.\n const userInputForCall = currentInput;\n const attachmentsForCall = currentAttachments;\n currentInput = '';\n currentAttachments = undefined;\n\n const options: ChatRequestOptions = {\n systemPrompt,\n // Strip fold-only properties (foldEvent, foldPath) before sending to provider\n tools: this.toolDefinitions.length ? this.toolDefinitions : undefined,\n attachments: attachmentsForCall,\n // Per-turn signal: aborts on user cancel, and (via beginTurn's chain)\n // on driver dispose. Cancels the in-flight request either way.\n signal: this.turnController.signal,\n toolChoice: effectiveToolChoice,\n // Agent/state-configured sampling temperature (normalized 0\u20131); each\n // transport translates it to its native range. Undefined \u2192 provider default.\n temperature: resolvedTemperature,\n // Prompt-cache policy for this turn (Anthropic places breakpoints per scope; Gemini\n // caches implicitly regardless). Undefined \u2192 no caching requested.\n cachePolicy: resolvedCachePolicy,\n // Framed volatile context injected at the message tail (never stored). Undefined \u2192 none.\n tailContext,\n // Structured-output schema for this turn (agent/state-resolved). When set, the transport\n // constrains the final answer to it natively where the model supports it. Undefined \u2192 free text.\n responseSchema: resolvedResponseSchema,\n // Refusal-fallback chain (e.g. Fable 5 \u2192 Opus 4.8). Passed to the provider; applied\n // server-side where supported. Undefined \u2192 no fallback.\n fallbacks: this.activeFallbacks,\n };\n\n // Resolve the active provider for this turn. Static names were validated\n // in `applyAgent`; function-form names are validated on first resolution\n // here and cached for the agent's lifetime.\n // oxlint-disable-next-line no-await-in-loop\n const activeProvider = await this.resolveProviderForTurn(promptCtx);\n\n let response: ChatMessage;\n try {\n // oxlint-disable-next-line no-await-in-loop\n response = await activeProvider.chat!(historyForCall, userInputForCall, options);\n } catch (e) {\n if (e instanceof MalformedFunctionCallError) {\n malformedAttempts += 1;\n if (malformedAttempts < MAX_MALFORMED_RETRIES) {\n logger.warn(\n `ChatDriver: MALFORMED_FUNCTION_CALL, retrying (${malformedAttempts}/${MAX_MALFORMED_RETRIES})`,\n );\n recordTurnRetry(this.sessionKey, 'malformed-function-call', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n attempt: malformedAttempts,\n maxAttempts: MAX_MALFORMED_RETRIES,\n finishMessage: e.finishMessage,\n });\n iterations -= 1;\n continue;\n }\n logger.error('ChatDriver: MALFORMED_FUNCTION_CALL, max retries reached');\n recordTurnError(this.sessionKey, 'malformed-function-call', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n attempts: malformedAttempts,\n finishMessage: e.finishMessage,\n isSubAgent: this.isSubAgent,\n });\n if (this.isSubAgent) {\n // Bubble a typed failure to the parent instead of speaking to the user.\n this.failSubAgent('malformed_tool_call');\n } else {\n this.appendToHistory({\n role: 'assistant',\n content:\n 'While working on your request, I repeatedly called my tools incorrectly. This often works on a second try \u2014 would you like me to try again? If it happens again, try breaking your request into smaller steps.',\n });\n }\n return this.turnDone('malformed-function-call');\n }\n // The response was truncated at the provider's output-token cap while it\n // still carried a tool call \u2014 its arguments are incomplete and unusable.\n // Unlike a malformed call this is DETERMINISTIC: re-issuing the same\n // request hits the same cap, so a silent retry just loops. Bail with a\n // clear, actionable signal instead. The remedy is config (raise the\n // provider maxTokens) or a smaller step \u2014 neither is fixed by retrying.\n if (e instanceof ResponseTruncatedError) {\n logger.error('ChatDriver: response truncated at the output-token cap', e);\n recordTurnError(this.sessionKey, 'response-truncated', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n model: e.model,\n maxTokens: e.maxTokens,\n outputTokens: e.outputTokens,\n tools: e.toolNames,\n isSubAgent: this.isSubAgent,\n });\n if (this.isSubAgent) {\n // Bubble a typed failure to the parent instead of speaking to the user.\n this.failSubAgent('response_truncated');\n } else {\n this.appendToHistory({\n role: 'assistant',\n content:\n 'My response was cut off because a single step reached the model output limit. This usually means one step tried to produce too much at once \u2014 try breaking your request into smaller steps.',\n });\n }\n return this.turnDone('response-truncated');\n }\n // The AI-spend budget is gone and the proxy refused the request (HTTP\n // 402). Terminal in the strongest sense available to us: unlike a\n // truncation \u2014 which a smaller request would get past \u2014 *no* request\n // succeeds until someone raises the budget out of band. So there is no\n // retry here and no \"try again\" in the copy; the turn ends and the host\n // locks the composer off the `'budget-exhausted'` failure reason (see\n // `FoundationAiAssistant.blocked`).\n if (e instanceof BudgetExhaustedError) {\n // Flagged as well as returned: a sub-agent's wall reaches the PARENT\n // only as a tool result, and the parent must not issue another model\n // call after it (see the short-circuit at the top of this loop).\n this.budgetExhaustedThisTurn = true;\n this.budgetWallDetail = budgetDetailOf(e);\n // Paired with the detail everywhere it is written: this is the\n // driver's OWN wall, so the sub-agent marker must not survive from an\n // earlier child and suppress the `lastResolvedProvider` fallback that\n // is legitimate here. Unreachable today (the short-circuit fires\n // before a second wall can land in one turn) \u2014 kept structural so the\n // pairing does not depend on that ordering staying true.\n this.budgetWallViaSubAgent = false;\n if (this.isSubAgent) {\n logger.error('ChatDriver: AI budget exhausted', e);\n recordTurnError(this.sessionKey, 'budget-exhausted', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n vendor:\n vendorTypeOfLabel(e.vendorLabel) ??\n vendorTypeOfLabel(e.serverVendor) ??\n this.lastResolvedProvider,\n budgetUsd: e.budgetUsd,\n spentUsd: e.spentUsd,\n isSubAgent: true,\n });\n // Bubble a typed failure to the parent instead of speaking to the\n // user, carrying the attribution so the parent walls the vendor that\n // actually refused rather than its own.\n this.failSubAgent('budget_exhausted', this.budgetWallDetail);\n return this.turnDone('budget-exhausted', this.budgetWallDetail);\n }\n return this.reportBudgetExhausted(e);\n }\n // A request timeout from the transport (tagged `TimeoutError`) is not a\n // bug on our end \u2014 surface it distinctly instead of letting it fall\n // through to the generic \"something went wrong\" catch. No auto-retry:\n // the timeout ceiling is already minutes long, so a silent retry would\n // just make the user wait again.\n if (e instanceof DOMException && e.name === 'TimeoutError') {\n logger.error('ChatDriver: request timed out', e);\n recordTurnError(this.sessionKey, 'exception', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n name: e.name,\n message: e.message,\n isSubAgent: this.isSubAgent,\n });\n if (this.isSubAgent) {\n // Bubble a typed failure to the parent instead of speaking to the user.\n this.failSubAgent('timeout');\n } else {\n this.appendToHistory({\n role: 'assistant',\n content:\n 'The request timed out. You can ask me to try again, or break this into a smaller step.',\n });\n }\n // Recorded as `exception` above (there is no separate `timeout` member of\n // TurnFailureReason for the main turn); surface the same reason here.\n return this.turnDone('exception');\n }\n // The request was aborted: either a user cancel (turnController) or a\n // driver dispose (lifecycleController, chained into the turn). A user\n // cancel adds a \"Stopped.\" marker; a dispose stops quietly. Handled\n // before the transient-retry below so an intentional abort/timeout is\n // never retried.\n if (e instanceof DOMException && e.name === 'AbortError') {\n return this.completeAbortedTurn();\n }\n // A transient provider/transport error should retry the SAME iteration a bounded\n // number of times rather than tearing down the whole turn (which strands the\n // agent's unflushed buffer behind an opaque error message).\n setupTransportAttempts += 1;\n if (setupTransportAttempts < MAX_SETUP_TRANSPORT_RETRIES) {\n logger.warn(\n `ChatDriver: provider/transport error, retrying (${setupTransportAttempts}/${MAX_SETUP_TRANSPORT_RETRIES})`,\n );\n iterations -= 1;\n continue;\n }\n throw e;\n }\n\n // Attribute the response to the concrete model + registry slot that\n // produced it (resolved for this turn in `resolveProviderForTurn`). Carried\n // on the assistant message so the debug-log timeline shows per-message\n // model lineage \u2014 and thus per-tool-call, since tool calls ride on the\n // assistant message that requests them. Harmless on a response later\n // discarded as empty/retried; only kept copies reach history.\n //\n // Attach each key only when resolved: a provider with no `getStatus` (etc.)\n // leaves the key off entirely rather than carrying it as `undefined`.\n // JSON.stringify already drops undefined from the exported log, so this is\n // chiefly about keeping the in-memory message shape honest.\n if (this.lastResolvedModel !== undefined) response.model = this.lastResolvedModel;\n if (this.lastResolvedProvider !== undefined) response.provider = this.lastResolvedProvider;\n if (this.lastResolvedProviderName !== undefined) {\n response.providerName = this.lastResolvedProviderName;\n }\n\n const isThinkingStep = response.content && response.toolCalls?.length;\n const isEmptyResponse = !response.content?.trim() && !response.toolCalls?.length;\n // A pre-output refusal (safety-classifier decline, e.g. Fable 5 `stop_reason: 'refusal'`)\n // comes back with empty content, so it looks like a blank response \u2014 but it is deterministic:\n // retrying re-sends the identical request and refuses again, burning up to\n // MAX_EMPTY_RESPONSE_RETRIES turns on the most expensive models for the same outcome, ending\n // in the misleading \"blank response\" message. Treat it as a terminal, non-retried failure with\n // its own reason and message. (GENC-1461)\n const isRefusal = response.responseMeta?.finishReason === 'refusal';\n\n if (isEmptyResponse) {\n emptyResponseAttempts += 1;\n if (!isRefusal && emptyResponseAttempts < MAX_EMPTY_RESPONSE_RETRIES) {\n logger.warn(\n `ChatDriver: empty model response, retrying (${emptyResponseAttempts}/${MAX_EMPTY_RESPONSE_RETRIES})`,\n );\n recordTurnRetry(this.sessionKey, 'empty-response', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n attempt: emptyResponseAttempts,\n maxAttempts: MAX_EMPTY_RESPONSE_RETRIES,\n // Provider diagnostic (Gemini: finishReason, thoughtsTokens, parts,\n // blockReason) so the timeline shows *why* the turn came back blank \u2014\n // e.g. a high thoughtsTokens with a 'STOP' finish is \"thought, then\n // stopped without answering\".\n ...response.responseMeta,\n });\n iterations -= 1;\n continue;\n }\n const failureReason = isRefusal ? 'refusal' : 'empty-response';\n logger.error(\n isRefusal\n ? 'ChatDriver: model refused the request (safety decline) \u2014 not retrying'\n : 'ChatDriver: empty model response after all retries',\n );\n recordTurnError(this.sessionKey, failureReason, {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n attempts: emptyResponseAttempts,\n isSubAgent: this.isSubAgent,\n ...response.responseMeta,\n });\n if (this.isSubAgent) {\n this.failSubAgent(isRefusal ? 'refusal' : 'empty_response');\n } else {\n this.appendToHistory({\n role: 'assistant',\n content: isRefusal\n ? 'This request was declined. Try rephrasing it, or breaking it into smaller steps.'\n : 'While working on your request, I repeatedly generated a blank response. This often works on a second try \u2014 would you like me to try again? If it happens again, try breaking your request into smaller steps.',\n });\n }\n return this.turnDone(failureReason);\n } else {\n // Split one model response into separate, individually-toggleable messages so each has its\n // own visibility toggle and debug-log category:\n // - reasoning (chain-of-thought summary) \u2192 category 'reasoning', hidden unless showThinkingSteps\n // - narration (interstitial prose emitted alongside a tool call) \u2192 category 'narration',\n // hidden unless showNarration\n // - the answer / tool-call message \u2192 always shown; carries this turn's usage.\n // Cost invariant (GENC-1410): exactly ONE message carries cost/tokens and is appended LAST, so\n // `sumCosts`/`sumTokens` don't double-count and `contextTokens` reads it. Reasoning/narration are\n // display-only (usage undefined) and are skipped when building the provider request. `model` /\n // `provider` / `providerName` stay on every split message so each is still attributed.\n const { reasoning, ...rest } = response;\n const displayOnly = { cost: undefined, inputTokens: undefined, outputTokens: undefined };\n if (reasoning) {\n this.appendToHistory({\n ...rest,\n ...displayOnly,\n content: reasoning,\n toolCalls: undefined,\n category: 'reasoning',\n });\n }\n if (isThinkingStep) {\n // content + tool call \u2192 the content is interstitial narration, not the final answer.\n this.appendToHistory({\n ...rest,\n ...displayOnly,\n toolCalls: undefined,\n category: 'narration',\n });\n this.appendToHistory({ ...rest, content: '' });\n } else {\n // No tool call \u2192 `content` is the final answer (always shown), or this is a bare tool-call\n // turn with no narration. Either way it carries this turn's usage; append it last.\n this.appendToHistory(rest);\n }\n }\n\n // Reset retry budgets on any productive (non-empty) response, so the caps mean\n // \"N CONSECUTIVE failures\" not \"N total per turn\".\n emptyResponseAttempts = 0;\n malformedAttempts = 0;\n setupTransportAttempts = 0;\n\n if (!response.toolCalls?.length) {\n break;\n }\n\n const [toolCalls, systemCalls] = response.toolCalls.reduce<[ChatToolCall[], ChatToolCall[]]>(\n (acc, tc) => {\n if (tc.name === REQUEST_CONTINUATION_TOOL) acc[1].push(tc);\n else acc[0].push(tc);\n return acc;\n },\n [[], []],\n );\n\n const executedById = new Map<\n string,\n { toolCallId: string; content: string; subAgentTrace?: ChatMessage[] }\n >();\n const unknownToolIds = new Set<string>();\n // Subset of unknownToolIds that were stale (previously available) rather\n // than hallucinated \u2014 drives the `stale` UI flag back-patched below.\n const staleToolIds = new Set<string>();\n let anyRealToolExecuted = false;\n let hitUnknownToolLimit = false;\n\n if (toolCalls.length > 0) {\n // oxlint-disable-next-line no-await-in-loop -- Promise.all is correct parallelism, not sequential loop awaiting\n await Promise.all(\n toolCalls.map(async (tc) => {\n // Check for fold facade\n const fold = this.getFold(tc.name);\n if (fold) {\n this.consecutiveFoldOps += 1;\n if (this.consecutiveFoldOps > this.maxFoldOperations) {\n logger.warn(\n `ChatDriver: fold operation limit (${this.maxFoldOperations}) reached \u2014 injecting guidance`,\n );\n executedById.set(tc.id, {\n toolCallId: tc.id,\n content: `You have opened and closed folds ${this.consecutiveFoldOps} times without calling any tools. Please call a specific tool to make progress, or respond to the user.`,\n });\n return;\n }\n const content = await this.openFold(tc.name, fold, tc.args, tc.id);\n executedById.set(tc.id, { toolCallId: tc.id, content });\n // Fold open/close does NOT count as a real iteration \u2014 decrement to compensate\n iterations -= 1;\n return;\n }\n\n // Check for close-fold tool\n if (tc.name.startsWith('close_') && this.foldStack.length > 0) {\n const topFoldName = this.foldStack[this.foldStack.length - 1].foldName;\n if (tc.name === `close_${topFoldName}`) {\n this.consecutiveFoldOps += 1;\n if (this.consecutiveFoldOps > this.maxFoldOperations) {\n executedById.set(tc.id, {\n toolCallId: tc.id,\n content: `You have opened and closed folds ${this.consecutiveFoldOps} times without calling any tools. Please call a specific tool to make progress, or respond to the user.`,\n });\n return;\n }\n const content = this.closeFold();\n executedById.set(tc.id, { toolCallId: tc.id, content });\n iterations -= 1;\n return;\n }\n }\n\n // Regular tool \u2014 check if it's inside a fold and guide the model\n const handler = this.toolHandlers[tc.name];\n if (!handler) {\n const containingFold = this.findFoldContaining(tc.name);\n if (containingFold) {\n logger.debug(\n `ChatDriver: model called folded tool \"${tc.name}\" \u2014 guiding to open \"${containingFold}\"`,\n );\n recordMetaEvent(this.sessionKey, 'tool.unresolved', {\n tool: tc.name,\n agent: this.activeAgentName,\n kind: 'folded',\n fold: containingFold,\n });\n executedById.set(tc.id, {\n toolCallId: tc.id,\n content: `\"${tc.name}\" is not directly available. It is inside the \"${containingFold}\" fold. Call ${containingFold} first to access it.`,\n });\n // Guidance does not count as a real iteration or fold op\n iterations -= 1;\n return;\n }\n\n // Not in any registered fold. If the tool was advertised earlier\n // in this agent's lifetime it's *stale* (a stateful agent moved on,\n // or an exclusive fold is hiding it) rather than hallucinated \u2014 a\n // distinction worth making, because the model should stop retrying\n // a retired tool rather than treat the failure as a typo. Stale\n // calls still trip loop protection, but at a higher ceiling than\n // hallucinated tools (see below) \u2014 they are self-correcting, so the\n // guidance, telemetry, and limit differ.\n if (this.everSeenToolNames.has(tc.name)) {\n this.consecutiveUnknownToolCalls += 1;\n const hidingFold = this.foldHidingTool(tc.name);\n let content: string;\n if (hidingFold) {\n content = `\"${tc.name}\" is not available while the \"${hidingFold}\" fold is open. Call close_${hidingFold} to return to the previous set of tools, then call ${tc.name}.`;\n logger.warn(\n `ChatDriver: tool \"${tc.name}\" is hidden behind open fold \"${hidingFold}\" (${this.consecutiveUnknownToolCalls}/${MAX_STALE_TOOL_CALLS})`,\n );\n } else {\n content = `\"${tc.name}\" was available earlier but is not part of the current step \u2014 that step is complete, so do not call it again. Continue with the tools available now: ${Object.keys(this.toolHandlers).join(', ') || '(none)'}.`;\n logger.warn(\n `ChatDriver: stale tool \"${tc.name}\" \u2014 advertised earlier this activation but retired in the current state (${this.consecutiveUnknownToolCalls}/${MAX_STALE_TOOL_CALLS})`,\n );\n }\n recordMetaEvent(this.sessionKey, 'tool.unresolved', {\n tool: tc.name,\n agent: this.activeAgentName,\n kind: hidingFold ? 'fold-hidden' : 'stale',\n fold: hidingFold ?? undefined,\n consecutive: this.consecutiveUnknownToolCalls,\n max: MAX_STALE_TOOL_CALLS,\n });\n // Fold-hidden tools keep their fold-specific guidance; a plain\n // stale tool is a step-ordering miss, so offer the agent's\n // redirect when it supplies one.\n const staleContent = hidingFold\n ? content\n : await this.resolveUnresolvedToolContent(tc.name, 'stale', content);\n executedById.set(tc.id, { toolCallId: tc.id, content: staleContent });\n unknownToolIds.add(tc.id);\n staleToolIds.add(tc.id);\n this.recentUnknownToolNames.add(tc.name);\n this.recentStaleToolNames.add(tc.name);\n if (this.consecutiveUnknownToolCalls >= MAX_STALE_TOOL_CALLS) {\n hitUnknownToolLimit = true;\n }\n return;\n }\n\n // Never advertised \u2014 a hallucinated tool name.\n this.consecutiveUnknownToolCalls += 1;\n logger.warn(\n `ChatDriver: no handler registered for tool \"${tc.name}\" (${this.consecutiveUnknownToolCalls}/${DEFAULT_MAX_UNKNOWN_TOOL_CALLS}). Available tools: ${Object.keys(this.toolHandlers).join(', ') || '(none)'}`,\n );\n recordMetaEvent(this.sessionKey, 'tool.unresolved', {\n tool: tc.name,\n agent: this.activeAgentName,\n kind: 'unknown',\n consecutive: this.consecutiveUnknownToolCalls,\n max: DEFAULT_MAX_UNKNOWN_TOOL_CALLS,\n availableTools: Object.keys(this.toolHandlers),\n });\n const unknownContent = await this.resolveUnresolvedToolContent(\n tc.name,\n 'unknown',\n `Unknown tool: ${tc.name}`,\n );\n executedById.set(tc.id, { toolCallId: tc.id, content: unknownContent });\n unknownToolIds.add(tc.id);\n this.recentUnknownToolNames.add(tc.name);\n if (this.consecutiveUnknownToolCalls >= DEFAULT_MAX_UNKNOWN_TOOL_CALLS) {\n hitUnknownToolLimit = true;\n }\n return;\n }\n\n // Real tool execution\n try {\n const traceCapture: { trace?: ChatMessage[] } = {};\n const result = await handler(tc.args, this.buildHandlerContext(tc.id, traceCapture));\n const content = typeof result === 'string' ? result : JSON.stringify(result);\n executedById.set(tc.id, {\n toolCallId: tc.id,\n content,\n subAgentTrace: traceCapture.trace,\n });\n anyRealToolExecuted = true;\n } catch (e) {\n logger.error(`ChatDriver tool \"${tc.name}\" failed:`, e);\n recordMetaEvent(this.sessionKey, 'tool.failed', {\n tool: tc.name,\n agent: this.activeAgentName,\n message: e instanceof Error ? e.message : String(e),\n });\n executedById.set(tc.id, {\n toolCallId: tc.id,\n // Structured recovery hint so the model retries or routes around a tool\n // failure instead of apologising and giving up.\n content: `Tool error: ${(e as Error).message}\\nRECOVERY: this tool failed once \u2014 you may retry it, or take a different valid action to make progress. Do NOT abandon the task, ask the user to rephrase, or claim you cannot make changes. If a planning tool failed, retry it or proceed with the information you already have.`,\n });\n anyRealToolExecuted = true; // treat errors as real work for fold op counting\n }\n }),\n );\n }\n\n // Reset counters whenever a real tool executes\n if (anyRealToolExecuted) {\n this.consecutiveFoldOps = 0;\n this.consecutiveUnknownToolCalls = 0;\n this.recentUnknownToolNames.clear();\n this.recentStaleToolNames.clear();\n }\n\n // Tag tool calls with fold UI metadata before appending results\n const foldPath = this.foldStack.map((f) => f.foldName);\n\n for (const tc of response.toolCalls) {\n if (tc.name === REQUEST_CONTINUATION_TOOL) {\n this.appendToHistory({\n role: 'tool',\n content: '',\n toolResult: { toolCallId: tc.id, content: HANDOFF_TOOL_RESULT_PLACEHOLDER },\n });\n } else {\n const r = executedById.get(tc.id);\n if (r) {\n // Persist only `toolCallId`/`content` on the tool result \u2014 the sub-agent\n // trace lives on the tool *call* (back-patched below from `executedById`),\n // which is what the UI's trace panel and `sumCosts` read. Appending the\n // trace here too would duplicate the entire child conversation in history\n // (and the exported debug log) for no reader.\n this.appendToHistory({\n role: 'tool',\n content: '',\n toolResult: { toolCallId: r.toolCallId, content: r.content },\n });\n }\n }\n }\n\n // Back-patch foldEvent and foldPath onto the tool call message we just appended.\n // The response was appended before execution \u2014 find it and annotate.\n let tcMsgIdx = -1;\n for (let i = this.history.length - 1; i >= 0; i -= 1) {\n if (this.history[i].role === 'assistant' && this.history[i].toolCalls?.length) {\n tcMsgIdx = i;\n break;\n }\n }\n if (tcMsgIdx !== -1) {\n const tcMsg = this.history[tcMsgIdx];\n const availableToolNames = Object.keys(this.toolHandlers);\n const annotatedCalls = tcMsg.toolCalls!.map((tc) => {\n const isFoldOpen =\n !!this.getFold(tc.name) ||\n // Was a fold facade at time of the call (now the tool set has changed)\n // \u2014 detect by checking if the result message indicated a fold open\n executedById.get(tc.id)?.content?.startsWith('Fold opened:');\n const isFoldClose = executedById.get(tc.id)?.content?.startsWith('Fold closed:');\n const isUnknown = unknownToolIds.has(tc.id);\n return {\n ...tc,\n foldEvent: isFoldOpen\n ? ('open' as const)\n : isFoldClose\n ? ('close' as const)\n : undefined,\n // Use the fold path that was active at the START of this iteration (before any opens/closes)\n foldPath: !isFoldOpen && !isFoldClose && foldPath.length > 0 ? foldPath : undefined,\n unknown: isUnknown || undefined,\n availableTools: isUnknown ? availableToolNames : undefined,\n // Distinguish a retired tool from a hallucinated one so the UI can\n // say \"no longer available here\" rather than \"does not exist\".\n stale: staleToolIds.has(tc.id) || undefined,\n subAgentTrace: executedById.get(tc.id)?.subAgentTrace,\n };\n });\n this.history[tcMsgIdx] = { ...tcMsg, toolCalls: annotatedCalls };\n this.dispatchEvent(\n new CustomEvent<ReadonlyArray<ChatMessage>>('history-updated', {\n detail: this.history,\n }),\n );\n }\n\n if (hitUnknownToolLimit) {\n logger.error(\n `ChatDriver: unknown-tool limit (${DEFAULT_MAX_UNKNOWN_TOOL_CALLS}) reached \u2014 stopping`,\n );\n const unknownTools = [\n ...new Set([\n ...this.recentUnknownToolNames,\n ...(response.toolCalls ?? [])\n .filter((tc) => unknownToolIds.has(tc.id))\n .map((tc) => tc.name),\n ]),\n ];\n // Stale tools were real earlier this activation; hallucinated tools\n // never existed. The hard stop counts both the same way, but the split\n // tells a triager whether the cause is a state/prompt-design problem\n // (stale) or a model inventing tool names (hallucinated).\n const staleTools = [\n ...new Set([\n ...this.recentStaleToolNames,\n ...(response.toolCalls ?? [])\n .filter((tc) => staleToolIds.has(tc.id))\n .map((tc) => tc.name),\n ]),\n ];\n const hallucinatedTools = unknownTools.filter((t) => !staleTools.includes(t));\n recordTurnError(this.sessionKey, 'unknown-tool-limit', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n unknownTools,\n staleTools,\n hallucinatedTools,\n availableTools: Object.keys(this.toolHandlers),\n isSubAgent: this.isSubAgent,\n });\n if (this.isSubAgent) {\n this.failSubAgent('unknown_tool_limit');\n } else {\n this.appendToHistory({\n role: 'assistant',\n content:\n \"I'm sorry, I repeatedly tried to use tools that aren't available to me, so I couldn't complete that. If a 'Download agent log' option appears in the Settings (cog) menu, you can download the log and share it with whoever set up this assistant to help fix the issue.\",\n });\n }\n return this.turnDone('unknown-tool-limit');\n }\n\n const firstContinuation = systemCalls[0];\n if (firstContinuation) {\n const { summary, remaining_task: remainingTask } = firstContinuation.args as {\n summary: string;\n remaining_task: string;\n };\n return { reason: 'agent-handoff', summary, remainingTask };\n }\n\n // Sub-agent early exit \u2014 checked here so the exit point mirrors the\n // system-call pattern above. Set by completeSubAgent() in a tool handler.\n if (this.subAgentCompletion) {\n return this.turnDone();\n }\n }\n\n // The loop fell through: either it hit the iteration cap (a failure) or it\n // broke on a clean final answer (success). Only the former carries a reason.\n let failureReason: TurnFailureReason | undefined;\n if (iterations >= this.maxToolIterations) {\n logger.warn('ChatDriver: reached max tool iterations, stopping');\n recordTurnError(this.sessionKey, 'max-iterations', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n iterations,\n limit: this.maxToolIterations,\n isSubAgent: this.isSubAgent,\n });\n if (this.isSubAgent) {\n this.failSubAgent('max_iterations');\n } else {\n this.appendToHistory({\n role: 'assistant',\n content:\n \"I've reached my limit for this response. You can ask me to continue and I'll pick up where I left off.\",\n });\n }\n failureReason = 'max-iterations';\n }\n\n return this.turnDone(failureReason);\n }\n\n private appendToHistory(message: ChatMessage): void {\n const tagged: ChatMessage = {\n ...message,\n // Stamp on first append; preserve any caller-supplied timestamp.\n timestamp: message.timestamp ?? new Date().toISOString(),\n ...(this.activeAgentName\n ? {\n agentName: this.activeAgentName,\n // Display-only \u2014 falls back to agentName in renderers when unset.\n agentLabel: this.activeAgentLabel,\n }\n : {}),\n };\n this.history = [...this.history, tagged];\n this.dispatchEvent(\n new CustomEvent<ReadonlyArray<ChatMessage>>('history-updated', {\n detail: this.history,\n }),\n );\n }\n}\n", "import type {\n AIProviderRegistry,\n ChatAttachment,\n ChatDriverResult,\n ChatMessage,\n ChatRequestOptions,\n} from '@genesislcap/foundation-ai';\nimport { BudgetExhaustedError } from '@genesislcap/foundation-ai';\nimport type { ActivityBus } from '../../channel/ai-activity-bus';\nimport type {\n AgentConfig,\n FallbackAgentConfig,\n SpecialistAgentConfig,\n SystemPromptContext,\n SystemPromptInput,\n} from '../../config/config';\nimport { validateStaticAgentProviders } from '../../config/validate-providers';\nimport { recordMetaEvent } from '../../state/debug-event-log';\nimport type { DiagnosticEntry } from '../../state/persistence/diagnostics';\nimport type { InteractionContext } from '../../types/interaction-context';\nimport { transformHistoryForAgent } from '../../utils/history-transform';\nimport { logger } from '../../utils/logger';\nimport type { AiDriver, AllAgentSummary } from '../ai-driver/ai-driver';\nimport {\n ChatDriver,\n REQUEST_CONTINUATION_TOOL,\n type TurnSnapshot,\n} from '../chat-driver/chat-driver';\n\nconst DEFAULT_MAX_HANDOFFS = 3;\nconst DEFAULT_CLASSIFIER_HISTORY_LENGTH = 4;\nconst DEFAULT_CLASSIFIER_RETRIES = 2;\n\nconst REQUEST_CONTINUATION_DEFINITION = {\n name: REQUEST_CONTINUATION_TOOL,\n description:\n \"Call this when you have completed your part of the task but fulfilling the user's full request requires capabilities outside your domain. Do not call this if you can complete the request yourself. Pass a plain-language description of what still needs to be done \u2014 another specialist will be selected automatically.\",\n parameters: {\n type: 'object',\n required: ['summary', 'remaining_task'],\n properties: {\n summary: {\n type: 'string',\n description: 'What you found or did \u2014 passed as context to the next specialist.',\n },\n remaining_task: {\n type: 'string',\n description:\n 'What still needs to be done, in plain language. Used to route to the right specialist.',\n },\n },\n },\n};\n\nfunction isSpecialist(agent: AgentConfig): agent is SpecialistAgentConfig {\n return !agent.fallback;\n}\n\nfunction isFallback(agent: AgentConfig): agent is FallbackAgentConfig {\n return agent.fallback === true;\n}\n\nfunction buildFallbackSystemPrompt(\n fallback: FallbackAgentConfig,\n specialists: SpecialistAgentConfig[],\n): SystemPromptInput | undefined {\n const agentList = specialists.map((s) => `- ${s.name}: ${s.description}`).join('\\n');\n if (typeof fallback.systemPrompt === 'string') {\n return fallback.systemPrompt.replace('{{agents}}', agentList);\n }\n if (typeof fallback.systemPrompt === 'function') {\n // Function-form fallback prompt \u2014 pass through unchanged. The `{{agents}}`\n // substitution is a string-template convenience; consumers using the\n // function form can compose the agent list themselves if they want it.\n return fallback.systemPrompt;\n }\n return `You are a helpful assistant. You cannot directly help with the user's request, but the following specialists are available:\\n\\n${agentList}\\n\\nPolitely let the user know what you can help with and invite them to rephrase their request.`;\n}\n\n/**\n * Orchestrates multiple specialist agents. Sits between `FoundationAiAssistant`\n * and `ChatDriver`, classifying each user message and routing it to the right\n * specialist \u2014 each with its own focused system prompt, tools, and primer.\n *\n * @beta\n */\nexport class OrchestratingDriver extends EventTarget implements AiDriver {\n private readonly chatDriver: ChatDriver;\n private readonly specialists: SpecialistAgentConfig[];\n private readonly fallback?: FallbackAgentConfig;\n private readonly maxHandoffs: number;\n private readonly classifierHistoryLength: number;\n private readonly classifierRetries: number;\n private readonly sessionKey: string;\n /**\n * Aborted on driver disposal. Threaded into `AgentLifecycleContext.signal`\n * so long-running `onActivate` work can bail if the session disconnects.\n */\n private readonly lifecycleAbortController = new AbortController();\n /**\n * Set by `cancel()` for the duration of a `sendMessage` run. Breaks the\n * handoff loop so we don't classify or start another agent turn after the\n * user stops. Reset at the start of each `sendMessage`.\n */\n private cancelled = false;\n /**\n * Whether the CURRENT turn's user message has reached the inner driver's\n * history. False through the pre-first-turn classify (where the only echo of\n * the message is an optimistic `history-updated` dispatch), true from the\n * moment `chatDriver.sendMessage` is entered \u2014 including through every later\n * handoff classify. Read by the budget-wall catch in `sendMessage` to decide\n * whether `reportBudgetExhausted` must append the message itself: appending\n * it when already appended duplicated it; not appending it when unappended\n * made it vanish. Reset at the top of each `runOrchestratedTurn`.\n */\n private userMessageAppended = false;\n /**\n * Sticky user pick from the picker (or the host's `setAgent` API). Only\n * changes on explicit user action. Survives flow completion: when a stateful\n * agent releases, the user-pin stays put and routing falls back to it on\n * the next turn.\n */\n private pinnedAgentName: string | null = null;\n /**\n * Transient flow lock \u2014 set when a stateful agent's `onActivate` fires,\n * cleared by `releaseActiveAgent`. While non-null, routing precedence goes\n * to this agent and the picker is locked. Independent of\n * `pinnedAgentName` so completing a flow doesn't wipe the user's sticky\n * choice.\n */\n private flowOwnerAgentName: string | null = null;\n\n /**\n * Per-agent restored state for a rehydrated session, keyed by agent name.\n * Primed by the host on restore; each entry is passed to that agent's\n * `onActivate` as `ctx.restored` on its next activation, then deleted so a\n * later re-activation starts fresh.\n */\n private restoredAgentStates: Record<string, unknown> = {};\n\n activeAgent?: AgentConfig;\n\n constructor(\n private readonly providerRegistry: AIProviderRegistry,\n private readonly agents: AgentConfig[],\n options: {\n sessionKey?: string;\n maxHandoffs?: number;\n classifierHistoryLength?: number;\n classifierRetries?: number;\n maxToolIterations?: number;\n maxFoldOperations?: number;\n maxTurnSnapshots?: number;\n /** Activity bus passed through to the inner ChatDriver (browser host injects the singleton). */\n activityBus?: ActivityBus;\n /** Budget-wall transcript copy, passed through to the inner ChatDriver (GENC-1464). */\n budgetExhaustedMessage?: string;\n } = {},\n ) {\n super();\n this.sessionKey = options.sessionKey ?? '';\n this.maxHandoffs = options.maxHandoffs ?? DEFAULT_MAX_HANDOFFS;\n this.classifierHistoryLength =\n options.classifierHistoryLength ?? DEFAULT_CLASSIFIER_HISTORY_LENGTH;\n this.classifierRetries = options.classifierRetries ?? DEFAULT_CLASSIFIER_RETRIES;\n\n // Static-name validation: walk every agent (and nested sub-agents). Any\n // `provider: '<name>'` that isn't registered, or resolves to a provider\n // without `chat()`, throws now rather than at first turn.\n validateStaticAgentProviders(agents, providerRegistry);\n\n // Specialists drive the classifier. `excludeFromClassifier` agents are still\n // resolvable by name (so manual pinning works) but never auto-routed.\n this.specialists = agents.filter(isSpecialist).filter((a) => !a.excludeFromClassifier);\n const fallbacks = agents.filter(isFallback);\n if (fallbacks.length > 1) {\n logger.warn(\n 'OrchestratingDriver: multiple fallback agents found \u2014 only the first will be used.',\n );\n }\n\n const rawFallback = fallbacks[0];\n this.fallback = rawFallback\n ? { ...rawFallback, systemPrompt: buildFallbackSystemPrompt(rawFallback, this.specialists) }\n : undefined;\n\n this.chatDriver = new ChatDriver(providerRegistry, {\n maxToolIterations: options.maxToolIterations,\n maxFoldOperations: options.maxFoldOperations,\n maxTurnSnapshots: options.maxTurnSnapshots,\n sessionKey: this.sessionKey,\n activityBus: options.activityBus,\n budgetExhaustedMessage: options.budgetExhaustedMessage,\n });\n\n // Proxy events from the shared driver\n this.chatDriver.addEventListener('history-updated', (e: Event) => {\n this.dispatchEvent(new CustomEvent('history-updated', { detail: (e as CustomEvent).detail }));\n });\n this.chatDriver.addEventListener('sub-agent-history-updated', (e: Event) => {\n this.dispatchEvent(\n new CustomEvent('sub-agent-history-updated', { detail: (e as CustomEvent).detail }),\n );\n });\n this.chatDriver.addEventListener('sub-agent-start', (e: Event) => {\n this.dispatchEvent(new CustomEvent('sub-agent-start', { detail: (e as CustomEvent).detail }));\n });\n this.chatDriver.addEventListener('sub-agent-stop', (e: Event) => {\n this.dispatchEvent(new CustomEvent('sub-agent-stop', { detail: (e as CustomEvent).detail }));\n });\n this.chatDriver.addEventListener('interaction-start', (e: Event) => {\n this.dispatchEvent(\n new CustomEvent('interaction-start', { detail: (e as CustomEvent).detail }),\n );\n });\n this.chatDriver.addEventListener('interaction-stop', (e: Event) => {\n this.dispatchEvent(\n new CustomEvent('interaction-stop', { detail: (e as CustomEvent).detail }),\n );\n });\n this.chatDriver.addEventListener('provider-changed', (e: Event) => {\n this.dispatchEvent(\n new CustomEvent('provider-changed', { detail: (e as CustomEvent).detail }),\n );\n });\n }\n\n resolveInteraction(interactionId: string, result: unknown): void {\n this.chatDriver.resolveInteraction(interactionId, result);\n }\n\n getInteractionContext(interactionId: string): InteractionContext | undefined {\n return this.chatDriver.getInteractionContext(interactionId);\n }\n\n isBusy(): boolean {\n return this.chatDriver.isBusy();\n }\n\n /** Currently active provider name from the underlying ChatDriver. */\n getActiveProviderName(): string {\n return this.chatDriver.getActiveProviderName();\n }\n\n /**\n * Pins routing to a specific agent by name. While pinned, the classifier is\n * skipped and the continuation tool is hidden from the agent's tool list, so\n * the agent cannot quietly hand back to the orchestrator. Pass `null` to\n * return to automatic routing.\n */\n setPinnedAgent(name: string | null): void {\n this.pinnedAgentName = name;\n }\n\n /**\n * Set the flow-owner lock \u2014 used to restore state from Redux on driver\n * reconstruction (agents-array changes, pop-in/pop-out). Not intended for\n * external callers to manipulate routing; that's what `setPinnedAgent` is\n * for.\n */\n setFlowOwner(name: string | null): void {\n this.flowOwnerAgentName = name;\n }\n\n loadHistory(messages: ChatMessage[]): void {\n this.chatDriver.loadHistory(messages);\n }\n\n getRawHistory(): readonly ChatMessage[] {\n return this.chatDriver.getHistory();\n }\n\n /** {@inheritDoc AiDriver.compact} */\n compact(): Promise<ChatMessage | null> {\n return this.chatDriver.compact();\n }\n\n /** {@inheritDoc AiDriver.canCompact} */\n canCompact(): boolean {\n return this.chatDriver.canCompact();\n }\n\n /** Delegates to the inner {@link ChatDriver} \u2014 turns are captured there. */\n getTurnSnapshots(): ReadonlyArray<TurnSnapshot> {\n return this.chatDriver.getTurnSnapshots();\n }\n\n /** Delegates to the inner {@link ChatDriver} \u2014 interactions resolve there, so it holds the buffer. */\n getExternalDiagnostics(): ReadonlyArray<DiagnosticEntry> {\n return this.chatDriver.getExternalDiagnostics();\n }\n\n async getSuggestions(\n history: ChatMessage[],\n prompt: string,\n count: number,\n allAgentInfo?: AllAgentSummary[],\n ): Promise<string[]> {\n // When pinned to a specialist, scope suggestions to that agent so the\n // proposed prompts reflect the active routing instead of the full panel.\n const pinned = this.resolvePinnedAgent();\n const candidates = pinned && isSpecialist(pinned) ? [pinned] : this.specialists;\n const agentInfo = candidates.map((s) => ({\n name: s.name,\n description: s.description,\n // Suggestions use tool names for prompt hints. Dynamic agents resolve\n // their tools per-turn against a SystemPromptContext we don't have here\n // \u2014 pass an empty list rather than invoke the factory with a fake one.\n tools: Array.isArray(s.toolDefinitions) ? s.toolDefinitions : [],\n }));\n return this.chatDriver.getSuggestions(history, prompt, count, agentInfo);\n }\n\n async sendMessage(input: string, attachments?: ChatAttachment[]): Promise<ChatDriverResult> {\n try {\n return await this.runOrchestratedTurn(input, attachments);\n } catch (e) {\n // The classifier calls the provider directly, outside any ChatDriver turn,\n // so a budget wall raised there would escape as an unhandled rejection \u2014\n // `FoundationAiAssistant.send()` has a `finally` but no `catch`. Land it on\n // the driver that owns the transcript, which appends the user-facing copy\n // and returns the same terminal result an in-loop wall would.\n //\n // The user's message rides along ONLY while it is genuinely unappended.\n // `classify()` runs at two seams: before the first agent turn \u2014 where the\n // `history-updated` dispatch in `runOrchestratedTurn` is optimistic only\n // and the real append lives inside `chatDriver.sendMessage`, which the\n // wall prevents from ever running \u2014 and again at the END of every handoff\n // iteration, by which point `chatDriver.sendMessage` HAS appended it.\n // Passing the message unconditionally duplicated it on the handoff seam:\n // `['user','assistant','tool','user','assistant']` in the transcript, the\n // snapshot, and the history sent to the model once the budget is raised.\n if (e instanceof BudgetExhaustedError) {\n return this.chatDriver.reportBudgetExhausted(\n e,\n this.userMessageAppended\n ? undefined\n : {\n role: 'user',\n content: input,\n ...(attachments ? { attachments } : {}),\n },\n );\n }\n throw e;\n }\n }\n\n private async runOrchestratedTurn(\n input: string,\n attachments?: ChatAttachment[],\n ): Promise<ChatDriverResult> {\n this.cancelled = false;\n this.userMessageAppended = false;\n const history = this.chatDriver.getHistory() as ChatMessage[];\n\n // Emit the user message immediately so the UI reflects it during the classify\n // round-trip \u2014 without this the chat appears frozen until classify returns.\n this.dispatchEvent(\n new CustomEvent('history-updated', {\n detail: [...history, { role: 'user', content: input, attachments }],\n }),\n );\n\n const pinned = this.resolvePinnedAgent();\n if (!pinned) this.dispatchEvent(new CustomEvent('orchestrating-start'));\n let currentAgent = pinned ?? (await this.classify(input, history, this.activeAgent));\n let isHandoff = false;\n let handoffs = 0;\n let handoffSummary = '';\n let remainingTask = '';\n // The outcome of the agent turn that ENDS the loop \u2014 see the return below.\n let lastResult: ChatDriverResult | undefined;\n\n while (true) {\n // Cancelled before a (next) agent turn started \u2014 e.g. during classify.\n // The chat driver appends its own \"Stopped.\" marker when a turn it was\n // running is cancelled, so we just stop here without a duplicate.\n if (this.cancelled) break;\n\n // oxlint-disable-next-line no-await-in-loop\n await this.applyAgent(currentAgent);\n\n let result: ChatDriverResult;\n if (isHandoff) {\n const contextPrimer: ChatMessage[] = handoffSummary\n ? [{ role: 'user', content: `[Context from previous agent]: ${handoffSummary}` }]\n : [];\n // oxlint-disable-next-line no-await-in-loop\n result = await this.chatDriver.continueFromHistory(contextPrimer);\n } else {\n // From here the inner driver owns the user message \u2014 it appends it as\n // its first act, before any provider call can throw. Set BEFORE the\n // await so a wall raised anywhere inside the turn (or on a later\n // handoff classify) sees the append as done.\n this.userMessageAppended = true;\n // oxlint-disable-next-line no-await-in-loop\n result = await this.chatDriver.sendMessage(input, attachments);\n }\n lastResult = result;\n\n // Release check: a stateful agent called `releaseAgent` from a terminal\n // tool handler. Fire onDeactivate, clear the pin, drop the user back to\n // classifier-mode. The LLM has already emitted its final wrap-up message\n // by the time we get here \u2014 release is purely a teardown.\n if (this.chatDriver.getAgentReleaseRequested()) {\n // oxlint-disable-next-line no-await-in-loop\n await this.releaseActiveAgent();\n break;\n }\n\n // Pinned agents never hand off \u2014 the continuation tool is filtered out in\n // applyAgent, but this guards against a model hallucinating a handoff result.\n if (result.reason !== 'agent-handoff' || isFallback(currentAgent) || pinned) {\n break;\n }\n\n handoffs += 1;\n if (handoffs > this.maxHandoffs) {\n this.appendInlineMessage(\n `I wasn't able to fully complete your request \u2014 the task required more hand-offs between specialists than allowed. Please try breaking your request into smaller steps.`,\n );\n break;\n }\n\n handoffSummary = result.summary;\n remainingTask = result.remainingTask;\n isHandoff = true;\n\n const updatedHistory = this.chatDriver.getHistory() as ChatMessage[];\n this.dispatchEvent(new CustomEvent('orchestrating-start'));\n // oxlint-disable-next-line no-await-in-loop\n currentAgent = await this.classify(remainingTask, updatedHistory);\n }\n\n // The orchestrated turn reports the outcome of the agent turn that ENDED it.\n // The hardcoded `{ reason: 'done' }` that used to live here made every\n // typed failure unreachable for an agents-configured host \u2014 including\n // `'budget-exhausted'`, which the element latches its blocked state off.\n //\n // \"Last wins\" cannot hide an earlier failure behind a later success: a\n // failing inner turn always ends the loop, because the loop only continues\n // on `reason === 'agent-handoff'`. The two breaks that hold a non-'done'\n // result (the handoff cap, and the pinned/fallback break) both carry\n // `'agent-handoff'`, which is an internal routing protocol that must never\n // escape to the host \u2014 the collapse below strips it. A cancel before the\n // first turn leaves `lastResult` undefined; the release break returns the\n // inner turn's real result, which is correct, because that turn ran.\n return lastResult?.reason === 'done' ? lastResult : { reason: 'done' };\n }\n\n async continueFromHistory(transientPrimer?: ChatMessage[]): Promise<ChatDriverResult> {\n return this.chatDriver.continueFromHistory(transientPrimer);\n }\n\n /** {@inheritDoc AiDriver.primeRestoredAgentState} */\n primeRestoredAgentState(snapshots: Record<string, unknown>): void {\n this.restoredAgentStates = { ...snapshots };\n }\n\n /** {@inheritDoc AiDriver.getActiveAgent} */\n getActiveAgent(): AgentConfig | undefined {\n return this.activeAgent;\n }\n\n private async applyAgent(agent: AgentConfig): Promise<void> {\n const previousAgent = this.activeAgent;\n const isSwitch = !previousAgent || previousAgent.name !== agent.name;\n\n // Record the agent transition on the debug-log timeline. A `null` `from`\n // marks the initial activation; a named `from` is a handoff between agents.\n if (isSwitch) {\n recordMetaEvent(this.sessionKey, 'agent.handoff', {\n from: previousAgent?.name ?? null,\n to: agent.name,\n // GENC-1351: was a restored snapshot waiting for this agent at activation?\n restored: this.restoredAgentStates[agent.name] !== undefined,\n });\n }\n\n // Fire lifecycle hooks around the swap \u2014 outgoing first, then incoming.\n // Both are awaited so a heavy `onActivate` (e.g. machine restore) completes\n // before the agent's first turn runs.\n if (isSwitch && previousAgent?.onDeactivate) {\n try {\n await previousAgent.onDeactivate({\n agentName: previousAgent.name,\n sessionKey: this.sessionKey,\n signal: this.lifecycleAbortController.signal,\n });\n } catch (e) {\n logger.warn(`OrchestratingDriver: onDeactivate(\"${previousAgent.name}\") threw:`, e);\n }\n }\n if (isSwitch && agent.onActivate) {\n // On a session restore, hand this agent its persisted state exactly once\n // (consumed here) so a stateful machine resumes at the right step; a later\n // re-activation of the same agent then starts fresh.\n const restored = this.restoredAgentStates[agent.name];\n if (restored !== undefined) delete this.restoredAgentStates[agent.name];\n try {\n await agent.onActivate({\n agentName: agent.name,\n sessionKey: this.sessionKey,\n previousAgentName: previousAgent?.name,\n signal: this.lifecycleAbortController.signal,\n restored,\n });\n } catch (e) {\n logger.warn(`OrchestratingDriver: onActivate(\"${agent.name}\") threw:`, e);\n }\n }\n\n const hasLifecycleHooks = !!(agent.onActivate || agent.onDeactivate);\n\n // Stateful agents auto-lock the flow on activation. The lock guarantees\n // the machine survives subsequent turns (the classifier would otherwise be\n // free to route away mid-flow, tearing the machine down). Release happens\n // when the agent calls `releaseAgent` from a terminal-state tool handler\n // \u2014 see the post-sendMessage check below. We write `flowOwnerAgentName`\n // rather than `pinnedAgentName` so completing a flow doesn't wipe the\n // user's sticky picker choice.\n if (isSwitch && hasLifecycleHooks && this.flowOwnerAgentName !== agent.name) {\n this.flowOwnerAgentName = agent.name;\n this.dispatchEvent(new CustomEvent('flow-owner-changed', { detail: agent.name }));\n }\n\n // Terminal agents do not get the cross-agent handoff tool. Four cases:\n // \u2022 fallback \u2014 already a leaf; handoff would loop\n // \u2022 user-pinned \u2014 user explicitly selected this agent; do not auto-route away\n // \u2022 flow-owner \u2014 a stateful flow is mid-stream; do not auto-route away\n // \u2022 stateful \u2014 agents with lifecycle hooks own state for the duration of\n // their flow. Initiating a handoff mid-flow would abandon\n // that state with no clean exit and dump the user into the\n // classifier mid-machine. Capture the tool loop until the\n // user (or the agent itself, via `releaseAgent`) releases.\n const isTerminal =\n isFallback(agent) ||\n this.pinnedAgentName !== null ||\n this.flowOwnerAgentName !== null ||\n hasLifecycleHooks;\n\n let agentToApply: AgentConfig = agent;\n if (!isTerminal) {\n const declaredTools = agent.toolDefinitions;\n agentToApply = {\n ...agent,\n toolDefinitions:\n typeof declaredTools === 'function'\n ? async (ctx: SystemPromptContext) => [\n ...(await declaredTools(ctx)),\n REQUEST_CONTINUATION_DEFINITION,\n ]\n : [...(declaredTools ?? []), REQUEST_CONTINUATION_DEFINITION],\n };\n }\n\n if (previousAgent && previousAgent.name !== agent.name) {\n const rawHistory = this.chatDriver.getHistory() as ChatMessage[];\n this.chatDriver.loadHistory([\n ...rawHistory,\n { role: 'system-event', content: agent.name, timestamp: new Date().toISOString() },\n ]);\n }\n\n this.chatDriver.setProviderHistoryTransform((h) => transformHistoryForAgent(h, agent.name));\n this.chatDriver.applyAgent(agentToApply);\n this.activeAgent = agent;\n this.dispatchEvent(new CustomEvent('orchestrating-stop'));\n this.dispatchEvent(new CustomEvent('agent-changed', { detail: agent }));\n }\n\n /**\n * Release the current stateful agent: fire `onDeactivate`, clear the\n * flow-owner lock, dispatch events so the host (and Redux) reflect the\n * unlocked state. Called automatically when a tool handler invokes\n * `context.releaseAgent`.\n *\n * The user-pin (`pinnedAgentName`) is intentionally *not* cleared \u2014 a user\n * who explicitly picked this agent should stay on it after the flow ends,\n * so the next message starts a fresh flow on the same agent rather than\n * routing through the classifier.\n */\n private async releaseActiveAgent(): Promise<void> {\n const agent = this.activeAgent;\n if (!agent) return;\n if (agent.onDeactivate) {\n try {\n await agent.onDeactivate({\n agentName: agent.name,\n sessionKey: this.sessionKey,\n signal: this.lifecycleAbortController.signal,\n });\n } catch (e) {\n logger.warn(`OrchestratingDriver: release onDeactivate(\"${agent.name}\") threw:`, e);\n }\n }\n this.activeAgent = undefined;\n if (this.flowOwnerAgentName !== null) {\n this.flowOwnerAgentName = null;\n this.dispatchEvent(new CustomEvent('flow-owner-changed', { detail: null }));\n }\n this.dispatchEvent(new CustomEvent('agent-released', { detail: agent }));\n this.dispatchEvent(new CustomEvent('agent-changed', { detail: undefined }));\n }\n\n /**\n * Stop the current turn (user \"stop\" button). Cancels the inner chat driver's\n * in-flight request and breaks the handoff loop so no further agent turn or\n * classify runs. The driver stays usable for the next message.\n */\n cancel(): void {\n this.cancelled = true;\n this.chatDriver.cancel();\n }\n\n /**\n * Fire `onDeactivate` on the current active agent and abort any pending\n * lifecycle work. Called by the host on session teardown so machines can\n * release resources cleanly.\n */\n async dispose(): Promise<void> {\n const previousAgent = this.activeAgent;\n if (previousAgent?.onDeactivate) {\n try {\n await previousAgent.onDeactivate({\n agentName: previousAgent.name,\n sessionKey: this.sessionKey,\n signal: this.lifecycleAbortController.signal,\n });\n } catch (e) {\n logger.warn(`OrchestratingDriver: dispose onDeactivate(\"${previousAgent.name}\") threw:`, e);\n }\n }\n this.lifecycleAbortController.abort();\n // Tear down the inner driver too, so any in-flight provider request aborts.\n this.chatDriver.dispose();\n this.activeAgent = undefined;\n }\n\n private async classify(\n input: string,\n history: ChatMessage[],\n contextAgent?: AgentConfig,\n ): Promise<AgentConfig> {\n // Single-candidate short-circuits. No point asking the LLM to route\n // when there's only one viable choice. Skipped if a fallback is\n // configured \u2014 that's an explicit \"escape hatch\" signal from the\n // consumer, and we preserve the LLM's ability to send unrelated\n // messages there by returning -1 from select_agent.\n if (this.specialists.length === 1 && !this.fallback) {\n return this.specialists[0];\n }\n if (this.specialists.length === 0) {\n // No classifier-eligible specialists. If exactly one non-fallback\n // agent exists (typically a stateful agent flagged\n // `excludeFromClassifier`) and there's no fallback to preserve as an\n // escape hatch, route to it \u2014 this is what fixes the previously-\n // silent single-stateful-agent case. Otherwise drop to the fallback;\n // excluded specialists remain reachable via manual pin.\n if (!this.fallback) {\n const routable = this.agents.filter((a) => !isFallback(a));\n if (routable.length === 1) {\n return routable[0];\n }\n }\n return this.fallback ?? { name: 'Assistant', fallback: true };\n }\n\n const agentList = this.specialists\n .map((a, i) => `${i}: ${a.name} \u2014 ${a.description}`)\n .join('\\n');\n\n const recentMessages = history\n .filter((m) => m.role === 'user' || m.role === 'assistant')\n .slice(-this.classifierHistoryLength)\n .map((m) => `${m.role === 'user' ? 'User' : 'Assistant'}: ${m.content}`)\n .join('\\n');\n\n const continuationHint =\n contextAgent && isSpecialist(contextAgent)\n ? `\\n\\nThe previous turn was handled by \"${contextAgent.name}\". If the new message is a refinement, correction, or continuation of that work, prefer \"${contextAgent.name}\" \u2014 unless the topic has clearly shifted to another specialist's domain.`\n : '';\n\n const classifierPrompt = `You are a routing classifier. Call select_agent with the index of the best matching agent for the user message. Use -1 only if the request is entirely unrelated to every agent listed \u2014 prefer the closest match when in doubt. If the request spans multiple agents, pick the one that should act first; I will re-classify and route again once that agent is done.\\n\\nAgents:\\n${agentList}${continuationHint}${recentMessages ? `\\n\\nRecent conversation:\\n${recentMessages}` : ''}`;\n\n const routingTool = {\n name: 'select_agent',\n description: 'Select the most appropriate agent for the user message.',\n parameters: {\n type: 'object',\n required: ['agent_index'],\n properties: {\n agent_index: {\n type: 'integer',\n description: 'Zero-based index of the matching agent, or -1 if no agent matches.',\n },\n },\n },\n };\n\n // True only when the classifier RAN and answered \"no match\" (index -1). The\n // no-fallback apology below is gated on it: an exhausted-retries exit never\n // earned that apology, and emitting it there put a routing excuse ahead of\n // the real error the routed turn is about to produce.\n let routedNoMatch = false;\n\n for (let attempt = 0; attempt <= this.classifierRetries; attempt += 1) {\n try {\n const options: ChatRequestOptions = {\n systemPrompt: classifierPrompt,\n tools: [routingTool],\n };\n // Classification is orchestrator-level, not bound to any single agent \u2014\n // always run against the registry default.\n const classifierProvider = this.providerRegistry.default();\n if (!classifierProvider.chat) {\n logger.warn(\n 'OrchestratingDriver: default AI provider does not implement chat() \u2014 cannot classify.',\n );\n break;\n }\n // oxlint-disable-next-line no-await-in-loop\n const response = await classifierProvider.chat([], input, options);\n const tc = response.toolCalls?.[0];\n const index = tc?.name === 'select_agent' ? (tc.args.agent_index as number) : -1;\n\n if (index >= 0 && index < this.specialists.length) {\n return this.specialists[index];\n }\n // index === -1 \u2014 fall through to fallback\n routedNoMatch = true;\n break;\n } catch (e) {\n // Terminal: no ladder clears a budget wall. Short-circuit the\n // classifier's own retries the same way 402 short-circuits the\n // transport's \u2014 this loop is a SECOND retry ladder stacked on that one,\n // so without this a single wall costs `classifierRetries + 1` doomed\n // classifier calls and then a doomed fallback turn on top. Deliberately\n // narrow: a generic classifier failure must still retry and fall back.\n if (e instanceof BudgetExhaustedError) throw e;\n logger.warn(`OrchestratingDriver: classifier attempt ${attempt + 1} failed:`, e);\n if (attempt === this.classifierRetries) {\n logger.error('OrchestratingDriver: classifier failed after all retries, using fallback');\n }\n }\n }\n\n if (this.fallback) return this.fallback;\n\n // No fallback configured. Route to the first specialist as a no-op \u2014 but\n // only APOLOGISE when the classifier actually said \"none of these\". On an\n // exhausted-retries exit the classifier never expressed an opinion, so the\n // apology would be a routing excuse the user reads immediately above the\n // real error that turn is about to produce.\n if (routedNoMatch) {\n const specialistNames = this.specialists.map((s) => s.name).join(', ');\n this.appendInlineMessage(\n `I'm not sure how to help with that. I can assist with: ${specialistNames}.`,\n );\n }\n return this.specialists[0];\n }\n\n /**\n * Returns the agent that the current turn is locked to, if any. Flow-owner\n * (transient, set by stateful-agent activation) wins over user-pin (sticky,\n * set by picker click). `undefined` falls back to the classifier.\n *\n * Logs and returns `undefined` if a name no longer matches the agents array\n * \u2014 protects against stale state after an agents-array reassignment.\n */\n private resolvePinnedAgent(): AgentConfig | undefined {\n const name = this.flowOwnerAgentName ?? this.pinnedAgentName;\n if (name === null) return undefined;\n const match = this.agents.find((a) => a.name === name);\n if (!match) {\n logger.warn(\n `OrchestratingDriver: pinned agent \"${name}\" not found in agents array \u2014 falling back to classifier.`,\n );\n return undefined;\n }\n return match;\n }\n\n private appendInlineMessage(content: string): void {\n const history = this.chatDriver.getHistory() as ChatMessage[];\n this.chatDriver.loadHistory([\n ...history,\n { role: 'assistant', content, timestamp: new Date().toISOString() },\n ]);\n this.dispatchEvent(\n new CustomEvent('history-updated', { detail: this.chatDriver.getHistory() }),\n );\n }\n}\n", "import type {\n CachePolicy,\n ChatFallback,\n ChatInputDuringExecutionMode,\n ChatMessage,\n ChatToolChoice,\n ChatToolDefinition,\n ChatToolHandlers,\n} from '@genesislcap/foundation-ai';\n\nexport type { CachePolicy, ChatFallback, ChatInputDuringExecutionMode, ChatToolChoice };\n\n/**\n * Context passed to `onActivate` / `onDeactivate` lifecycle hooks on an agent.\n *\n * @beta\n */\nexport interface AgentLifecycleContext {\n /** The agent the hook is firing for. */\n agentName: string;\n /** The assistant session key \u2014 stable across reloads, unique per assistant instance. */\n sessionKey: string;\n /** The agent that was active immediately before this one, if any. Only set on `onActivate`. */\n previousAgentName?: string;\n /** Aborted if the session disconnects mid-activation. */\n signal: AbortSignal;\n /**\n * A previously-serialized state image for this agent (from the agent's\n * `serialize`), passed only on `onActivate` when resuming a persisted\n * session. A stateful\n * agent's `init` rebuilds from it \u2014 e.g. via `restoreMachine` \u2014 or starts\n * fresh when it is `undefined`.\n */\n restored?: unknown;\n}\n\n/**\n * Context passed to an agent's `resumable` predicate (GENC-1351 \u00A75.9), evaluated\n * at session-save time on the active agent (which, for a locked guided flow, is\n * the flow-owner).\n *\n * @beta\n */\nexport interface AgentPersistenceContext {\n /** The agent being consulted. */\n agentName: string;\n /** The assistant session key \u2014 stable across reloads. */\n sessionKey: string;\n /**\n * This agent's just-serialized state image \u2014 the value its `serialize()`\n * returned for this save (or the carried-forward image). Inspect the machine\n * step here. Derive the decision from this (not live closure state): the\n * predicate must be a pure function of the state so a resumable snapshot stays\n * resumable when re-evaluated on restore.\n */\n state: unknown;\n /** Full conversation transcript at save time. */\n messages: ReadonlyArray<ChatMessage>;\n /** True when this agent currently owns the guided flow (`name === flowOwnerAgentName`). */\n isFlowOwner: boolean;\n}\n\n/**\n * Context passed to the function form of `systemPrompt` / `toolDefinitions`.\n * Resolved each tool-loop iteration so the agent can vary what the LLM sees per turn.\n *\n * @beta\n */\nexport interface SystemPromptContext {\n /** The active agent's name. */\n agentName: string;\n /** Full conversation history up to (but not including) the message being processed. */\n history: ReadonlyArray<ChatMessage>;\n /** 0 = first LLM call this turn; > 0 = retry or subsequent tool-loop iteration. */\n turnIndex: number;\n /** Aborted if the turn is cancelled. */\n signal: AbortSignal;\n}\n\n/**\n * System prompt for an agent. Either a static string (resolved once) or a function\n * resolved each tool-loop iteration. The function form lets the agent compute the\n * prompt from external state \u2014 e.g. a state machine's current step.\n *\n * @beta\n */\nexport type SystemPromptInput = string | ((ctx: SystemPromptContext) => string | Promise<string>);\n\n/**\n * Tool definitions for an agent. Either a static array (the conventional shape) or\n * a function resolved each tool-loop iteration. The function form lets the agent\n * narrow the tool surface per turn \u2014 e.g. expose only the tools valid in the\n * current state of a state machine.\n *\n * @beta\n */\nexport type ToolDefinitionsInput =\n | ChatToolDefinition[]\n | ((ctx: SystemPromptContext) => ChatToolDefinition[] | Promise<ChatToolDefinition[]>);\n\n/**\n * Tool handlers for an agent. Either a static map (the conventional shape) or a\n * function resolved each tool-loop iteration. The function form lets the agent\n * narrow the dispatchable handler set per turn \u2014 pair it with the function form\n * of `toolDefinitions` so the LLM-visible tools and the dispatchable handlers\n * stay in lockstep, and handlers don't have to defend themselves against being\n * dispatched in states where their tool isn't advertised.\n *\n * @beta\n */\nexport type ToolHandlersInput =\n | ChatToolHandlers\n | ((ctx: SystemPromptContext) => ChatToolHandlers | Promise<ChatToolHandlers>);\n\n/**\n * Names which registered `AIProviderRegistry` entry an agent uses. Either\n * a static string (resolved once at agent registration) or a function resolved\n * each tool-loop iteration \u2014 pick the function form to vary the provider by\n * current state (e.g. a stateful agent that switches providers between\n * machine states).\n *\n * Unknown provider names hard-error: static names at agent registration time,\n * function-resolved names on first resolution.\n *\n * @beta\n */\nexport type ProviderInput = string | ((ctx: SystemPromptContext) => string | Promise<string>);\n\n/**\n * Sampling temperature for an agent, normalized to `0`\u2013`1` (`0` = deterministic,\n * `1` = the most random the active provider allows). Either a static number\n * (resolved once) or a function resolved each tool-loop iteration \u2014 pick the\n * function form to vary it by current state (e.g. a lower temperature for a\n * precise extraction step, higher for brainstorming). Each transport translates\n * the normalized value into its own native range. Omit to use the\n * provider/model default. See `ChatRequestOptions.temperature`.\n *\n * @beta\n */\nexport type TemperatureInput = number | ((ctx: SystemPromptContext) => number | Promise<number>);\n\n/**\n * Tool-call mode for an agent. Either a static `ChatToolChoice` (resolved\n * once) or a function resolved each tool-loop iteration \u2014 pick the function form\n * to vary it by current state (e.g. force a classifier tool in an intake step,\n * then `'auto'` everywhere multi-step work happens). Omit to use the default\n * (`'auto'`, except sub-agent turns which force `'required'`).\n *\n * @beta\n */\nexport type ToolChoiceInput =\n | ChatToolChoice\n | ((ctx: SystemPromptContext) => ChatToolChoice | Promise<ChatToolChoice>);\n\n/**\n * Prompt-cache policy for an agent. Either a static `CachePolicy` (resolved once) or a\n * function resolved each tool-loop iteration \u2014 pick the function form to vary it by current state\n * (e.g. cache `'history'` in a long generating phase, `'default'` in short low-touch ones). Omit\n * to request no caching. Resolved and applied the same way as {@link TemperatureInput}.\n *\n * @beta\n */\nexport type CachePolicyInput =\n | CachePolicy\n | ((ctx: SystemPromptContext) => CachePolicy | Promise<CachePolicy>);\n\n/**\n * Per-turn tail context for an agent \u2014 volatile content (current file/spec, diagnostics, live\n * state) injected at the tail of every model-call so the model sees it without invalidating the\n * cached prefix. Either a static string or a function resolved each tool-loop iteration. **Provide\n * raw content** \u2014 the framework frames it (wraps it in a `<system-reminder>` marker) so the model\n * reads it as ambient context, not user input. Omit, or return an empty string, for none.\n *\n * @beta\n */\nexport type TailContextInput = string | ((ctx: SystemPromptContext) => string | Promise<string>);\n\n/**\n * Structured-output schema for an agent. When set, the model's final (non-tool) answer is\n * constrained to this JSON Schema instead of free text. Either a static schema or a function\n * resolved each tool-loop iteration \u2014 return the schema on the turn(s) it should apply and\n * `undefined` otherwise, so \"whole-loop\" vs \"finalize-turn\" enforcement is just what the\n * resolver returns (e.g. `({ state }) => state.machine.matches('finalizing') ? schema : undefined`).\n *\n * Orthogonal to {@link ToolChoiceInput}: an agent can carry both `tools` and a `responseSchema`.\n * Each provider applies it natively where possible (Anthropic `output_config.format`, Gemini\n * JSON mode) and degrades gracefully otherwise. The schema is a plain JSON Schema object; keep to\n * the portable subset providers share (`additionalProperties: false`, explicit `required`, enums,\n * `anyOf` for nullables \u2014 no numeric/string constraints or recursion).\n *\n * @beta\n */\nexport type ResponseSchemaInput =\n | object\n | ((ctx: SystemPromptContext) => object | undefined | Promise<object | undefined>);\n\n/**\n * Context passed to an agent's `onUnresolvedTool` hook when the model calls a\n * tool the driver cannot dispatch.\n *\n * @beta\n */\nexport interface UnresolvedToolContext {\n /** The tool name the model attempted to call. */\n toolName: string;\n /**\n * Why the call could not be dispatched:\n * - `'stale'` \u2014 the tool was advertised earlier this activation but is not\n * part of the current step (e.g. a stateful agent has moved on).\n * - `'unknown'` \u2014 the tool was never advertised this activation (a\n * hallucinated name).\n */\n kind: 'stale' | 'unknown';\n /**\n * The tool names dispatchable right now, so the hook can steer the model\n * back to a valid call.\n */\n availableTools: string[];\n}\n\n/**\n * Optional per-agent hook consulted only on the already-failing unresolved-tool\n * path \u2014 when the model calls a tool the driver cannot dispatch. Lets the agent\n * replace the framework's default message with a context-aware redirect.\n *\n * Return a non-empty string to override the default tool-result message; return\n * `undefined` (or an empty/whitespace string, or throw) to fall back to the\n * framework default. The happy path is never affected. See\n * {@link UnresolvedToolContext}.\n *\n * @beta\n */\nexport type UnresolvedToolInput = (\n ctx: UnresolvedToolContext,\n) => string | undefined | Promise<string | undefined>;\n\n/**\n * Opts an agent in to manual selection from the assistant's agent picker.\n *\n * Only applies to top-level agents \u2014 sub-agents are never user-selectable.\n * Has no effect unless the assistant's `agentPicker` is also enabled.\n *\n * @beta\n */\nexport interface ManualSelectionConfig {\n /**\n * Whether this agent appears in the picker.\n */\n enabled: boolean;\n /**\n * Optional short description shown as a tooltip on the picker entry, and as\n * a secondary line in the dropdown variant.\n */\n hint?: string;\n}\n\ninterface BaseAgentConfig {\n /**\n * Stable identity for this agent. Used for classifier routing, manual\n * pinning, and history filtering \u2014 must not vary per turn. For a per-turn\n * display label (e.g. \"Guided Booking (Counterparties)\"), supply\n * {@link BaseAgentConfig.displayName}.\n */\n name: string;\n /**\n * Optional per-turn display label. Resolved each tool-loop iteration and\n * stamped onto outgoing messages (`agentLabel`) and the debug-log timeline.\n * Renderers fall back to `name` when this is unset. Use the function form\n * to vary the label by current state (e.g. a state machine's step).\n *\n * Identity stays on `name` \u2014 this is for UX only.\n */\n displayName?: SystemPromptInput;\n /**\n * System prompt injected into every conversation turn for this agent.\n *\n * Either a string (resolved once) or a function resolved each tool-loop\n * iteration \u2014 pick the function form when the prompt depends on per-turn state\n * (e.g. a state machine's current step). See {@link SystemPromptInput}.\n */\n systemPrompt?: SystemPromptInput;\n /**\n * Tool definitions (JSON Schema) passed to the AI provider for this agent.\n *\n * Either a static array or a function resolved each tool-loop iteration \u2014\n * pick the function form to narrow the tool surface per turn (e.g. expose\n * only the tools valid in the current state of a state machine).\n * See {@link ToolDefinitionsInput}.\n */\n toolDefinitions?: ToolDefinitionsInput;\n /**\n * Tool handler implementations for this agent.\n *\n * Either a static map or a function resolved each tool-loop iteration \u2014\n * pick the function form to narrow the dispatchable handler set per turn,\n * matching the function form of `toolDefinitions`.\n * See {@link ToolHandlersInput}.\n */\n toolHandlers?: ToolHandlersInput;\n /**\n * Which registered AI provider this agent uses, by name. Either a static\n * string (resolved once at agent registration) or a function resolved each\n * tool-loop iteration \u2014 pick the function form to vary the provider by\n * current state (e.g. a stateful agent that switches providers between\n * machine states).\n *\n * Omit to use the registry's default provider. Unknown names hard-error:\n * static names at registration time, function-resolved names on first\n * resolution.\n *\n * Known limitation: switching provider mid-conversation can blow the\n * smaller provider's context window if history accumulated under a\n * larger one. No automatic trimming is performed.\n *\n * @beta\n */\n provider?: ProviderInput;\n /**\n * Sampling temperature for this agent, normalized to `0`\u2013`1`. Either a static\n * number or a function resolved each tool-loop iteration \u2014 pick the function\n * form to vary it by current state. Omit to use the provider/model default.\n * Resolved and applied the same way as {@link BaseAgentConfig.provider}.\n * See {@link TemperatureInput}.\n *\n * @beta\n */\n temperature?: TemperatureInput;\n /**\n * Tool-call mode for this agent \u2014 whether the model may, must, or must not\n * call a tool this turn (and optionally which one). Either a static value or\n * a function resolved each tool-loop iteration \u2014 pick the function form to\n * vary it by current state (e.g. force a single tool at a known juncture).\n * Omit to use the default (`'auto'`, except sub-agent turns which force\n * `'required'`). See {@link ToolChoiceInput}.\n *\n * @beta\n */\n toolChoice?: ToolChoiceInput;\n /**\n * Prompt-cache policy for this agent \u2014 whether to emit cache breakpoints and how far up the\n * prefix. Either a static value or a function resolved each tool-loop iteration (vary by state).\n * Resolved and applied the same way as {@link BaseAgentConfig.temperature}. Omit to request no\n * caching. Provider-neutral \u2014 see {@link CachePolicyInput} / `CachePolicy` for the\n * Anthropic-vs-Gemini behaviour. See {@link CachePolicyInput}.\n *\n * @beta\n */\n cachePolicy?: CachePolicyInput;\n /**\n * Volatile per-turn context injected at the tail of every model-call (after the history and any\n * cache breakpoint), so it is seen each turn without busting the cached prefix \u2014 the place to put\n * the changing parts (current file/spec, diagnostics, live state) that would otherwise\n * destabilize a cached system prompt. Provide *raw* content; the framework frames it (wraps it in\n * a `<system-reminder>` marker). Resolved per turn like {@link BaseAgentConfig.temperature}. See\n * {@link TailContextInput}.\n *\n * @beta\n */\n tailContext?: TailContextInput;\n /**\n * Structured-output schema for this agent. When resolved to a schema on a turn, the model's\n * final (non-tool) answer is constrained to it instead of free text. Composes with `tools`;\n * resolved per turn like {@link BaseAgentConfig.cachePolicy}, so returning `undefined` on\n * working turns and the schema on the finalize turn gives finalize-turn enforcement for free.\n * See {@link ResponseSchemaInput}.\n *\n * @beta\n */\n responseSchema?: ResponseSchemaInput;\n /**\n * Refusal-fallback chain for this agent (provider-neutral). If the model declines a turn\n * (`stop_reason: 'refusal'` \u2014 e.g. Fable 5 safety classifiers), the provider re-runs it on the\n * next listed model. Typical use: a Fable 5 agent with `[{ model: 'claude-opus-4-8' }]`. Static\n * (not per-turn); providers that support it apply it server-side, others ignore it.\n *\n * @beta\n */\n fallbacks?: ChatFallback[];\n /**\n * Optional hook consulted when the model calls a tool the driver cannot\n * dispatch \u2014 either a *stale* tool (advertised earlier this activation but\n * not part of the current step) or an *unknown* one (never advertised this\n * activation). Return a context-aware redirect string to replace the\n * framework's default message, or `undefined` to keep it. Consulted only on\n * the already-failing unresolved-tool path; the happy path is unaffected.\n * See {@link UnresolvedToolInput}.\n *\n * @beta\n */\n onUnresolvedTool?: UnresolvedToolInput;\n /**\n * Optional primer history prepended to every call (not visible to the user).\n * Used to establish agent identity and behavioural rules.\n */\n primerHistory?: ChatMessage[];\n /**\n * Sub-agents available to this agent's tool handlers via `requestSubAgent`.\n */\n subAgents?: AgentConfig[];\n /**\n * How the main chat input area behaves while this agent is executing.\n * Defaults to `'disabled'`. See {@link ChatInputDuringExecutionMode}.\n */\n chatInputDuringExecution?: ChatInputDuringExecutionMode;\n /**\n * Opts this agent in to manual selection from the assistant's agent picker.\n * Has no effect on sub-agents or when the assistant's `agentPicker` is\n * disabled. See {@link ManualSelectionConfig}.\n */\n manualSelection?: ManualSelectionConfig;\n /**\n * Fires when this agent becomes the active specialist (including being pinned).\n * Use to instantiate per-agent state that should outlive a single turn \u2014 e.g.\n * a state machine the agent owns across the conversation. Awaited before the\n * agent's first turn runs.\n *\n * Capture dependencies (services, redux store refs, etc.) via closure on the\n * host element rather than expecting them on the context.\n *\n * @beta\n */\n onActivate?: (ctx: AgentLifecycleContext) => void | Promise<void>;\n /**\n * Fires when this agent is being deactivated (the user switches to another\n * agent, the session is torn down, or the agent is unpinned and replaced).\n * Use to dispose per-agent state created in `onActivate`. Awaited before the\n * incoming agent's `onActivate` runs.\n *\n * @beta\n */\n onDeactivate?: (ctx: AgentLifecycleContext) => void | Promise<void>;\n /**\n * Returns an agent-supplied debug payload for the export log. Called once per\n * LLM call by the driver (alongside the resolved prompt and tool list) and\n * once at log-export time for the latest snapshot. Stateful agents should\n * return their machine state and captured context so the exported timeline\n * captures what drove each turn.\n *\n * Return value must be JSON-serializable. {@link defineStatefulAgent} wires a\n * sensible default that snapshots any machine-shaped state automatically.\n *\n * @beta\n */\n getDebugSnapshot?: () => unknown;\n /**\n * Returns a lossless, JSON-serializable image of the agent's state for session\n * persistence \u2014 distinct from `getDebugSnapshot`, which may abbreviate for\n * readability. Pass the value back to the agent on restore (as\n * `ctx.restored` in its `init`) to resume. {@link defineStatefulAgent} wires a\n * default that snapshots any machine-shaped state via `getPersistedSnapshot()`\n * and returns plain state as-is.\n *\n * @beta\n */\n serialize?: () => unknown;\n /**\n * Whether the agent's current state is resumable \u2014 i.e. worth persisting so the\n * session can be restored mid-flow (GENC-1351 \u00A75.9). Consulted at save time on\n * the active agent (the flow-owner during a locked flow). Return `true`\n * (or leave the field absent) to persist and resume normally; return `false`\n * for a point that shouldn't be resumed \u2014 the session is not persisted, and on\n * return the assistant shows {@link AgentConfig.notResumableMessage} (or a\n * default) and pre-fills the composer with the prompt that started the flow so\n * the user can re-run it.\n *\n * Only consulted when the user has persistence enabled. Must be a **pure\n * function of `ctx.state`** \u2014 it may be re-evaluated on a restored snapshot, so\n * a resumable state must stay resumable. A thrown error is treated as `true`\n * (fail-safe: never drop a resumable chat on a predicate bug).\n *\n * @beta\n */\n resumable?: (ctx: AgentPersistenceContext) => boolean | Promise<boolean>;\n /**\n * Message shown on return when {@link AgentConfig.resumable} returned `false`\n * and the user comes back to a non-resumable session (GENC-1351 \u00A75.9). Falls\n * back to a built-in default when omitted.\n *\n * @beta\n */\n notResumableMessage?: string;\n}\n\n/**\n * Configuration for a specialist agent.\n *\n * Specialist agents are offered to the classifier for intent routing. The\n * `description` is used to auto-generate the classifier prompt \u2014 no manual\n * routing prompt authoring required.\n *\n * @beta\n */\nexport interface SpecialistAgentConfig extends BaseAgentConfig {\n /**\n * Plain-language description of what this agent handles.\n * Used by the classifier to auto-generate its routing prompt.\n */\n description: string;\n fallback?: never;\n /**\n * When `true`, the classifier never auto-routes to this agent. The user can\n * still select it manually via the picker, provided both prerequisites are\n * met: this agent has `manualSelection.enabled` set to `true`, *and* the\n * assistant has the picker enabled via `chatConfig.picker.mode`.\n *\n * Use this for agents that overlap heavily with a sibling (e.g. a guided\n * wizard sitting next to a free-form agent in the same domain) and should\n * only be reached intentionally rather than via classifier routing.\n *\n * @beta\n */\n excludeFromClassifier?: boolean;\n}\n\n/**\n * Configuration for a fallback agent.\n *\n * Invoked when the classifier returns no match. Excluded from the classifier\n * prompt. Only one fallback is permitted per agents array.\n *\n * @beta\n */\nexport interface FallbackAgentConfig extends BaseAgentConfig {\n /**\n * Marks this agent as the fallback for unrecognised requests.\n */\n fallback: true;\n description?: never;\n}\n\n/**\n * Configuration for an agent passed to `FoundationAiAssistant`.\n *\n * Either a specialist (requires `description`) or a fallback (requires\n * `fallback: true`). Passing both or neither is a compile error.\n *\n * @beta\n */\nexport type AgentConfig = SpecialistAgentConfig | FallbackAgentConfig;\n\n/**\n * Identity helper that infers the narrowest possible type for an agent config,\n * preserving string literal types (including `name`) without requiring `as const`.\n *\n * Use this when you need `typeof myAgent` to carry the literal `name` type \u2014\n * for example, when wiring `ChatToolHandlers<typeof myAgent>`.\n *\n * ```ts\n * const myAgent = defineAgent({ name: 'my_agent', ... });\n * type Handlers = ChatToolHandlers<typeof myAgent>;\n * // requestSubAgent name param is now typed as 'my_agent'\n * ```\n *\n * @beta\n */\n\nexport function defineAgent<const T extends AgentConfig>(config: T): T {\n return config;\n}\n", "import type {\n CachePolicy,\n ChatMessage,\n ChatToolChoice,\n ChatToolDefinition,\n ChatToolHandlers,\n} from '@genesislcap/foundation-ai';\nimport { TOOL_FOLD_SYMBOL } from '../utils/tool-fold';\nimport type {\n AgentConfig,\n AgentLifecycleContext,\n AgentPersistenceContext,\n CachePolicyInput,\n ChatInputDuringExecutionMode,\n ManualSelectionConfig,\n ProviderInput,\n SystemPromptContext,\n SystemPromptInput,\n TailContextInput,\n TemperatureInput,\n ToolChoiceInput,\n ToolDefinitionsInput,\n ToolHandlersInput,\n UnresolvedToolContext,\n UnresolvedToolInput,\n} from './config';\n\n/**\n * Context passed to per-turn resolvers on a stateful agent \u2014 the standard\n * {@link SystemPromptContext} plus the live `state` value. Used by\n * `systemPrompt`, `displayName`, and the function form of `toolDefinitions`.\n *\n * Exported so consumers can lift resolvers into separate files without\n * re-deriving the shape.\n *\n * @beta\n */\nexport type StatefulAgentContext<S> = SystemPromptContext & { state: S };\n\n/**\n * Context passed to a stateful agent's `resumable` predicate (GENC-1351 \u00A75.9) \u2014\n * the standard {@link AgentPersistenceContext} but with `state` as the **live**\n * state bag `S` (not the serialized image), so a machine agent can gate on its\n * current step directly.\n *\n * @beta\n */\nexport type StatefulAgentPersistenceContext<S> = Omit<AgentPersistenceContext, 'state'> & {\n state: S;\n};\n\n/**\n * Init options for {@link defineStatefulAgent}. Generic over the state shape `S`\n * the agent owns (a state machine, an observable controller, anything).\n *\n * The helper threads `state` through `systemPrompt`, `toolDefinitions`, and the\n * `toolHandlers` factory so consumer code never has to reach for a closure or\n * a module-level mutable.\n *\n * @beta\n */\nexport interface StatefulAgentInit<S> {\n /** Display name \u2014 must be unique within the agents array. */\n name: string;\n /** Plain-language description used by the classifier. Required: stateful agents are always specialists. */\n description: string;\n /**\n * Hide this agent from the classifier \u2014 only reachable via manual pinning.\n * Stateful agents are always specialists; they cannot be the fallback (a\n * fallback is a leaf invoked when no specialist matches, with no flow to\n * own state for).\n */\n excludeFromClassifier?: boolean;\n /** Static primer history prepended to every call (not visible to the user). */\n primerHistory?: ChatMessage[];\n /** Sub-agents available to this agent's tool handlers via `requestSubAgent`. */\n subAgents?: AgentConfig[];\n /** Opt this agent in to manual picker selection. */\n manualSelection?: ManualSelectionConfig;\n /** How the main chat input behaves while this agent is executing. */\n chatInputDuringExecution?: ChatInputDuringExecutionMode;\n\n /**\n * Construct the agent-scoped state. Called by the framework when this agent\n * becomes active (`onActivate`). Awaited before the agent's first turn runs.\n *\n * On a persisted-session restore, `ctx.restored` carries this agent's previous\n * `serialize` output \u2014 rebuild from it (e.g. via `restoreMachine`), or start\n * fresh when it is `undefined`.\n */\n init: (ctx: AgentLifecycleContext) => S | Promise<S>;\n\n /**\n * Tear down the agent-scoped state. Called when the agent is being replaced.\n * Awaited before the incoming agent's `init` runs.\n */\n dispose?: (ctx: AgentLifecycleContext & { state: S }) => void | Promise<void>;\n\n /**\n * System prompt composed from current state. Resolved each tool-loop\n * iteration. Use this to feed the LLM whatever the current state implies\n * (e.g. a state machine's `meta.systemPrompt` plus captured context).\n */\n systemPrompt?: (ctx: StatefulAgentContext<S>) => string | Promise<string>;\n\n /**\n * Per-turn display label, e.g. \"Guided Booking (Counterparties)\". Resolved\n * each tool-loop iteration and stamped onto outgoing messages and the\n * debug-log timeline \u2014 display only. The agent's `name` stays as the\n * canonical identity used for routing/history filtering.\n */\n displayName?: (ctx: StatefulAgentContext<S>) => string | Promise<string>;\n\n /**\n * Tool definitions the LLM sees. Either a static array (resolved once) or a\n * function resolved each tool-loop iteration. The function form is how a\n * machine-driven agent narrows the surface per state.\n *\n * **Constraint:** the resolved handlers (returned from {@link StatefulAgentInit.toolHandlers})\n * must not include fold facades. Folds are an LLM-driven UX optimisation\n * that competes with the machine for control of the tool view; one of them\n * has to be in charge. Helper throws at init time if a fold-tagged handler\n * is detected.\n */\n toolDefinitions?:\n | ChatToolDefinition[]\n | ((ctx: StatefulAgentContext<S>) => ChatToolDefinition[] | Promise<ChatToolDefinition[]>);\n\n /**\n * Factory returning the handler map for the **current state**. Called each\n * tool-loop iteration with the live `state` value, so the handler set the\n * driver dispatches against matches what `toolDefinitions` exposes to the\n * LLM that turn. Return only the handlers valid right now \u2014 no need to\n * advertise every handler the agent might ever expose, and no defensive\n * `if (!machine.matches(...))` guards inside each handler.\n *\n * Pair with the function form of `toolDefinitions` so the visible tools and\n * the dispatchable handlers stay in lockstep.\n *\n * **Constraint:** resolved handlers must not include fold facades. Folds and\n * state-machine-driven tool filtering both try to control the LLM's tool\n * view \u2014 pick one. Helper samples once on activation (init state) and\n * throws if a fold-tagged handler is detected; subsequent resolves also\n * validate, so misuse on a non-init state surfaces when that state is\n * reached.\n */\n toolHandlers?: (state: S) => ChatToolHandlers | Promise<ChatToolHandlers>;\n\n /**\n * Which registered AI provider this agent uses, by name. Either a static\n * string or a function resolved each tool-loop iteration with the current\n * `state` \u2014 pick the function form to vary provider per machine state\n * (e.g. swap to a heavier model only for the planning step).\n *\n * Omit to use the registry's default provider. Unknown names hard-error.\n */\n provider?: string | ((ctx: StatefulAgentContext<S>) => string | Promise<string>);\n\n /**\n * Sampling temperature, normalized to `0`\u2013`1`. Either a static number or a\n * function resolved each tool-loop iteration with the current `state` \u2014 pick\n * the function form to vary it per machine state (e.g. low for a precise\n * extraction step, higher for free-form drafting). Omit for the default.\n */\n temperature?: number | ((ctx: StatefulAgentContext<S>) => number | Promise<number>);\n\n /**\n * Tool-call mode. Either a static `ChatToolChoice` or a function\n * resolved each tool-loop iteration with the current `state` \u2014 pick the\n * function form to force a specific tool in one state (e.g. a classifier in\n * intake) and leave `'auto'` in states where multi-step work happens. Omit\n * for the default.\n */\n toolChoice?:\n | ChatToolChoice\n | ((ctx: StatefulAgentContext<S>) => ChatToolChoice | Promise<ChatToolChoice>);\n\n /**\n * Prompt-cache policy. Either a static `CachePolicy` or a function resolved each tool-loop\n * iteration with the current `state` \u2014 pick the function form to vary it per machine state\n * (e.g. `'history'` in a long generating phase, `'default'` in short low-touch ones). Omit to\n * request no caching.\n */\n cachePolicy?:\n | CachePolicy\n | ((ctx: StatefulAgentContext<S>) => CachePolicy | Promise<CachePolicy>);\n\n /**\n * Volatile per-turn tail context (current file/spec, diagnostics, live state). Either a static\n * string or a function resolved each tool-loop iteration with the current `state`. Provide raw\n * content; the framework frames it. Omit, or return an empty string, for none.\n */\n tailContext?: string | ((ctx: StatefulAgentContext<S>) => string | Promise<string>);\n\n /**\n * Hook consulted when the model calls a tool that isn't dispatchable in the\n * current state \u2014 a *stale* tool (valid in an earlier state of this agent) or\n * an *unknown* one. Receives the current `state` alongside the attempted tool\n * name and the currently dispatchable tools, so a machine-driven agent can\n * return a step-aware redirect (e.g. \"that belongs to a later step \u2014 finish\n * this one first\"). Return `undefined` to keep the framework default; a\n * pre-init call also degrades to the default rather than throwing.\n * See {@link UnresolvedToolContext}.\n */\n onUnresolvedTool?: (\n ctx: UnresolvedToolContext & { state: S },\n ) => string | undefined | Promise<string | undefined>;\n\n /**\n * Optional getter for the debug-log snapshot. Defaults to auto-snapshotting\n * any property on `state` that looks like a foundation-state-machine\n * instance (has `state`, `context`, and `complete` fields). Override when\n * the default doesn't capture what you need \u2014 e.g. multiple machines, or\n * non-machine state worth recording.\n *\n * Return value must be JSON-serializable.\n */\n getDebugSnapshot?: (state: S) => unknown;\n\n /**\n * Lossless serializer for session persistence \u2014 infra-agnostic. Return any\n * JSON/structured-clone-safe image of `state`.\n * \u2022 Machine agents (`{ machine }`): omit \u2014 the default snapshots every\n * machine-shaped property via `getPersistedSnapshot()`.\n * \u2022 Plain-data agents (e.g. `{ plan, cursor }`): omit too \u2014 the default\n * returns plain state as-is. Provide one only when the state holds\n * something the default can't capture.\n * Distinct from `getDebugSnapshot` (which may be lossy by design). Pair with\n * `init` reading `ctx.restored` to rebuild.\n */\n serialize?: (state: S) => unknown;\n\n /**\n * Whether the agent's current state is resumable \u2014 worth persisting so the\n * session restores mid-flow (GENC-1351 \u00A75.9). Receives the **live** state bag\n * `S` (like the other per-turn resolvers), so a machine agent gates on its step\n * directly: `resumable: ({ state }) => state.machine.state !== 'confirm'`.\n * Return `false` for a point that shouldn't resume \u2014 the session isn't persisted,\n * and on return the assistant shows {@link StatefulAgentInit.notResumableMessage}\n * (or a default) and pre-fills the composer with the prompt that started the flow.\n * Only consulted with persistence enabled; a thrown error is treated as `true`\n * (fail-safe \u2014 never drop a resumable chat on a predicate bug).\n */\n resumable?: (ctx: StatefulAgentPersistenceContext<S>) => boolean | Promise<boolean>;\n /**\n * Message shown on return when {@link StatefulAgentInit.resumable} returned\n * `false`. Falls back to a built-in default when omitted.\n */\n notResumableMessage?: string;\n}\n\n/**\n * Walk a state object and snapshot any machine-shaped values found on it.\n * Recognises foundation-state-machine instances by structural shape rather\n * than `instanceof`, so the helper stays free of a runtime dep on\n * foundation-state-machine.\n *\n * Strips the `errors`/`error` framework noise from each machine's context \u2014\n * these are foundation-state-machine internals (an ErrorMap instance and its\n * last-error pointer) that bloat the debug payload without aiding debugging.\n */\nfunction defaultStatefulDebugSnapshot(state: unknown): unknown {\n if (!state || typeof state !== 'object') return state;\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(state as Record<string, unknown>)) {\n if (val && typeof val === 'object' && 'state' in val && 'context' in val && 'complete' in val) {\n const m = val as {\n state: unknown;\n context: Record<string, unknown>;\n complete: unknown;\n output?: unknown;\n };\n const ctx = m.context ?? {};\n const { errors: _e, error: _err, ...userContext } = ctx;\n result[key] = {\n state: m.state,\n context: userContext,\n complete: m.complete,\n output: m.output,\n };\n }\n }\n return Object.keys(result).length\n ? result\n : '<no auto-snapshot \u2014 state has no machine-shaped properties; provide getDebugSnapshot>';\n}\n\n/**\n * Build a restore-ready snapshot of agent state. Each property exposing a\n * `getPersistedSnapshot()` method (a foundation-state-machine `AbstractMachine`)\n * is replaced by its persisted snapshot \u2014 the lossless, JSON-safe image\n * {@link restoreMachine} feeds back via `start({ state })`. Every other property\n * is kept as-is, so plain serializable state (e.g. a planner's `{ plan, cursor }`)\n * round-trips directly with no per-agent `serialize`.\n *\n * Distinct from `defaultStatefulDebugSnapshot`, which abbreviates for the debug\n * log and is not guaranteed lossless.\n */\nfunction defaultStatefulSerialize(state: unknown): unknown {\n if (!state || typeof state !== 'object') return state;\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(state as Record<string, unknown>)) {\n result[key] =\n val &&\n typeof val === 'object' &&\n typeof (val as { getPersistedSnapshot?: unknown }).getPersistedSnapshot === 'function'\n ? (val as { getPersistedSnapshot: () => unknown }).getPersistedSnapshot()\n : val;\n }\n return result;\n}\n\n/**\n * Restore a foundation-state-machine instance from a snapshot produced by the\n * default serializer (or `machine.getPersistedSnapshot()`). Call inside a\n * stateful agent's `init` to resume the machine in its exact prior place:\n *\n * ```ts\n * init: ({ restored }) => {\n * const machine = new MyMachine();\n * restoreMachine(machine, restored); // resume, or no-op on a fresh start\n * return { machine };\n * }\n * ```\n *\n * No-ops when there is nothing to restore (a fresh session), leaving the\n * freshly-constructed machine in its initial state.\n *\n * @param machine - the machine to restore (already constructed/started).\n * @param restored - the agent's serialized image (`ctx.restored` in `init`).\n * @param key - the property the machine occupies in the snapshot; defaults to\n * `'machine'` to match the conventional `{ machine }` state bag.\n * @beta\n */\nexport function restoreMachine(\n machine: { stop: () => void; start: (options?: { state?: unknown }) => void },\n restored: unknown,\n key = 'machine',\n): void {\n const snapshot = (restored as Record<string, unknown> | undefined)?.[key];\n if (snapshot === undefined || snapshot === null) {\n return;\n }\n machine.stop();\n machine.start({ state: snapshot });\n}\n\n/**\n * Build an `AgentConfig` whose `systemPrompt`, `toolDefinitions`, and tool\n * handlers all close over a long-lived state object created on activation.\n *\n * The framework wires the lifecycle: `init` on `onActivate`, `dispose` on\n * `onDeactivate`. State is held inside the helper's closure \u2014 never exposed on\n * the resulting `AgentConfig` \u2014 so the redux serializer doesn't see it.\n *\n * @example\n * ```ts\n * const guidedBooking = defineStatefulAgent<{ machine: GuidedBookingMachine }>({\n * name: 'Guided Booking',\n * description: 'Books a trade via a guided wizard.',\n * excludeFromClassifier: true,\n * manualSelection: { enabled: true, hint: 'Step-by-step trade booking' },\n * init: () => ({ machine: new GuidedBookingMachine() }),\n * dispose: ({ state }) => state.machine.stop(),\n * systemPrompt: ({ state }) => composeFromMachine(state.machine),\n * toolDefinitions: ({ state }) => toolsForState(state.machine.state),\n * toolHandlers: ({ machine }) => ({ ... }),\n * });\n * ```\n *\n * @beta\n */\nexport function defineStatefulAgent<S>(opts: StatefulAgentInit<S>): AgentConfig {\n let state: S | undefined;\n\n const assertNoFolds = (handlers: ChatToolHandlers): void => {\n for (const [name, handler] of Object.entries(handlers)) {\n if ((handler as any)[TOOL_FOLD_SYMBOL]) {\n throw new Error(\n `Stateful agent \"${opts.name}\" tool \"${name}\" carries fold metadata. ` +\n `Folds and state-machine-driven tool filtering both try to control the ` +\n `LLM's tool view \u2014 pick one. Remove the fold or migrate this agent to ` +\n `a non-stateful AgentConfig.`,\n );\n }\n }\n };\n\n // Wrap the optional dynamic-tools factory so it threads `state` in and asserts\n // we never accidentally resolved a fold-tagged tool. Static arrays are passed\n // through unchanged.\n const wrappedTools: ToolDefinitionsInput | undefined = (() => {\n const td = opts.toolDefinitions;\n if (typeof td === 'function') {\n return async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" tools called before init`);\n }\n return td({ ...ctx, state });\n };\n }\n return td;\n })();\n\n // Wrap the handler factory into the ctx-shaped form the driver expects, and\n // validate folds on each resolve. The driver re-resolves this per tool-loop\n // iteration, so the handler set the driver dispatches against always\n // matches the LLM-visible tools for the current state \u2014 handlers don't need\n // defensive `if (!machine.matches(...))` guards.\n const wrappedHandlers: ToolHandlersInput | undefined = opts.toolHandlers\n ? async () => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" handlers called before init`);\n }\n const handlers = await opts.toolHandlers!(state);\n assertNoFolds(handlers);\n return handlers;\n }\n : undefined;\n\n const wrappedDisplayName: SystemPromptInput | undefined = opts.displayName\n ? async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" displayName called before init`);\n }\n return opts.displayName!({ ...ctx, state });\n }\n : undefined;\n\n // Function-form `provider` needs `state` injected the same way the other\n // per-turn resolvers do; the static-string form is passed through unchanged\n // and validated up-front by OrchestratingDriver.\n const wrappedProvider: ProviderInput | undefined =\n typeof opts.provider === 'function'\n ? async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" provider called before init`);\n }\n return (opts.provider as (ctx: StatefulAgentContext<S>) => string | Promise<string>)({\n ...ctx,\n state,\n });\n }\n : opts.provider;\n\n // `temperature` and `toolChoice` thread `state` in exactly like `provider`;\n // static values pass through unchanged.\n const wrappedTemperature: TemperatureInput | undefined =\n typeof opts.temperature === 'function'\n ? async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" temperature called before init`);\n }\n return (opts.temperature as (ctx: StatefulAgentContext<S>) => number | Promise<number>)({\n ...ctx,\n state,\n });\n }\n : opts.temperature;\n\n const wrappedToolChoice: ToolChoiceInput | undefined =\n typeof opts.toolChoice === 'function'\n ? async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" toolChoice called before init`);\n }\n return (\n opts.toolChoice as (\n ctx: StatefulAgentContext<S>,\n ) => ChatToolChoice | Promise<ChatToolChoice>\n )({ ...ctx, state });\n }\n : opts.toolChoice;\n\n const wrappedCachePolicy: CachePolicyInput | undefined =\n typeof opts.cachePolicy === 'function'\n ? async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" cachePolicy called before init`);\n }\n return (\n opts.cachePolicy as (ctx: StatefulAgentContext<S>) => CachePolicy | Promise<CachePolicy>\n )({ ...ctx, state });\n }\n : opts.cachePolicy;\n\n const wrappedTailContext: TailContextInput | undefined =\n typeof opts.tailContext === 'function'\n ? async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" tailContext called before init`);\n }\n return (opts.tailContext as (ctx: StatefulAgentContext<S>) => string | Promise<string>)({\n ...ctx,\n state,\n });\n }\n : opts.tailContext;\n\n // `onUnresolvedTool` threads `state` in like the resolvers above, but unlike\n // them returns `undefined` before init rather than throwing: it fires on the\n // tool-dispatch path, so a pre-init call must degrade to the framework\n // default instead of breaking dispatch.\n const wrappedOnUnresolvedTool: UnresolvedToolInput | undefined =\n typeof opts.onUnresolvedTool === 'function'\n ? async (ctx) => {\n if (!state) {\n return undefined;\n }\n return opts.onUnresolvedTool!({ ...ctx, state });\n }\n : opts.onUnresolvedTool;\n\n // `resumable` threads the LIVE state bag in (like the resolvers above) rather\n // than the serialized image the raw `AgentConfig` form receives \u2014 so a machine\n // agent gates on `state.machine.state` directly. Consulted only while active\n // (state is set); a pre-init call degrades to `true` (resumable, fail-safe).\n const wrappedResumable: AgentConfig['resumable'] | undefined = opts.resumable\n ? async (ctx: AgentPersistenceContext): Promise<boolean> => {\n if (state === undefined) return true;\n return opts.resumable!({\n agentName: ctx.agentName,\n sessionKey: ctx.sessionKey,\n messages: ctx.messages,\n isFlowOwner: ctx.isFlowOwner,\n state,\n });\n }\n : undefined;\n\n const base = {\n name: opts.name,\n displayName: wrappedDisplayName,\n primerHistory: opts.primerHistory,\n subAgents: opts.subAgents,\n manualSelection: opts.manualSelection,\n chatInputDuringExecution: opts.chatInputDuringExecution,\n toolDefinitions: wrappedTools,\n toolHandlers: wrappedHandlers,\n provider: wrappedProvider,\n temperature: wrappedTemperature,\n toolChoice: wrappedToolChoice,\n cachePolicy: wrappedCachePolicy,\n tailContext: wrappedTailContext,\n onUnresolvedTool: wrappedOnUnresolvedTool,\n resumable: wrappedResumable,\n notResumableMessage: opts.notResumableMessage,\n\n onActivate: async (ctx: AgentLifecycleContext) => {\n state = await opts.init(ctx);\n // Sample once with the init state to fail loud on fold misuse at the\n // agent-switch boundary instead of waiting for the first tool call.\n // The driver re-resolves the factory each iteration, so misuse on\n // handlers gated behind a non-init state surfaces when that state is\n // reached \u2014 same loud failure mode, narrower coverage.\n if (opts.toolHandlers) {\n const sampled = await opts.toolHandlers(state);\n assertNoFolds(sampled);\n }\n },\n\n onDeactivate: async (ctx: AgentLifecycleContext) => {\n if (state !== undefined && opts.dispose) {\n await opts.dispose({ ...ctx, state });\n }\n // Orchestrator serializes onActivate/onDeactivate; concurrent calls\n // cannot interleave the read-then-write of `state`.\n // eslint-disable-next-line require-atomic-updates\n state = undefined;\n },\n\n systemPrompt: opts.systemPrompt\n ? async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" systemPrompt called before init`);\n }\n return opts.systemPrompt!({ ...ctx, state });\n }\n : undefined,\n\n // Called per LLM call by ChatDriver, and once at debug-log export time.\n // Returns `undefined` before activation (state hasn't been built yet) and\n // after deactivation (state was disposed) \u2014 the snapshotter is best-effort\n // and the driver tolerates undefined.\n getDebugSnapshot: () => {\n if (!state) return undefined;\n return opts.getDebugSnapshot\n ? opts.getDebugSnapshot(state)\n : defaultStatefulDebugSnapshot(state);\n },\n\n // Lossless restore image for session persistence (see `serialize` on the\n // config). Returns undefined before activation / after disposal.\n serialize: () => {\n if (state === undefined) return undefined;\n return opts.serialize ? opts.serialize(state) : defaultStatefulSerialize(state);\n },\n };\n\n return {\n ...base,\n description: opts.description,\n excludeFromClassifier: opts.excludeFromClassifier,\n } as AgentConfig;\n}\n", "import type { FallbackAgentConfig } from './config';\n\n/**\n * A warm, conversational fallback agent. Acknowledges it can't help directly,\n * explains what the available specialists can do, and invites the user to retry.\n *\n * The system prompt is generated at runtime by `OrchestratingDriver` from the\n * specialist list \u2014 no manual authoring required.\n *\n * @beta\n */\nexport const friendlyFallbackAgent: FallbackAgentConfig = {\n name: 'Assistant',\n fallback: true,\n systemPrompt: `You are a warm, friendly assistant. For general conversation like \"Hi\" or \"How are you\", you can have a friendly chat. For anything more complex, you cannot directly help, but you can explain what specialists are available. The available specialists are:\\n\\n{{agents}}\\n\\nPolitely let the user know what you can help with and invite them to rephrase their request if it is outside your scope.`,\n};\n\n/**\n * A brief, professional fallback agent. States what is available without\n * elaboration. The `{{agents}}` placeholder is replaced at runtime by\n * `OrchestratingDriver` with the generated specialist list.\n *\n * @beta\n */\nexport const strictFallbackAgent: FallbackAgentConfig = {\n name: 'Assistant',\n fallback: true,\n systemPrompt: `You are a concise assistant. The user's request is outside your scope. Respond with a single short sentence stating what you can assist with. Do not elaborate. The available specialists are: {{agents}}.`,\n};\n", "import type { ChatMessage } from '@genesislcap/foundation-ai';\n\n/**\n * A chat message lifted into the debug-log timeline as a `kind: 'message'` entry.\n *\n * @beta\n */\nexport type TimelineMessage = ChatMessage & {\n kind: 'message';\n /**\n * Set only on entries hoisted out of a `subAgentTrace`: the sub-agent's own\n * (un-breadcrumbed) `agentName`, kept for filtering since the displayed\n * `agentName` is rewritten to a `\"<parent> \u203A <sub-agent>\"` breadcrumb.\n */\n subAgentName?: string;\n /** Delegation depth \u2014 absent/0 for top-level, 1 for a sub-agent, 2 for a sub-agent's sub-agent, \u2026 */\n subAgentDepth?: number;\n /** Id of the parent tool call that spawned this run \u2014 correlates a hoisted message back to its delegation. */\n subAgentOf?: string;\n};\n\n/**\n * Flatten sub-agent conversations into a single top-level message stream for the\n * debug-log timeline.\n *\n * A tool call that delegates to a sub-agent carries the sub-agent's entire\n * conversation on `toolCall.subAgentTrace`. The live UI reads that nested shape,\n * but a top-to-bottom timeline reads far better with those messages inline next to\n * the turn that produced them. This walks the list and, for every tool call with a\n * `subAgentTrace`, hoists the sub-agent's messages up as their own timeline\n * entries while **removing** the nested copy from the emitted parent tool call \u2014 a\n * move, not a copy. The data is relocated, never duplicated: the export stays the\n * same size and a naive `sum(timeline[].cost)` does not double-count (the\n * canonical `sumCosts` total still reads the un-flattened history).\n *\n * Hoisted entries are:\n * - **breadcrumbed**: `agentName` becomes `\"<parent> \u203A <sub-agent>\"`, composing for\n * nested sub-agents (`\"<parent> \u203A <sub> \u203A <subsub>\"`); the raw sub-agent name is\n * preserved on `subAgentName`.\n * - **depth-tagged** (`subAgentDepth`) and **correlated** to the spawning tool call\n * (`subAgentOf`), so the delegation tree is reconstructable even when two\n * sub-agents run within the same parent turn.\n *\n * Top-level messages (depth 0) are emitted unchanged apart from the trace strip.\n * Order is preserved within each list; the caller sorts the whole timeline by\n * timestamp afterwards, and every sub-agent message carries its own timestamp, so\n * hoisted entries interleave chronologically between the parent's tool-call and\n * tool-result messages.\n *\n * @internal\n */\nexport function flattenSubAgentMessages(\n messages: readonly ChatMessage[],\n prefix = '',\n depth = 0,\n subAgentOf?: string,\n): TimelineMessage[] {\n return messages.flatMap((m) => {\n const breadcrumb = prefix ? `${prefix} \u203A ${m.agentName ?? '?'}` : m.agentName;\n const traceCalls = m.toolCalls?.filter((tc) => tc.subAgentTrace?.length) ?? [];\n\n const entry: TimelineMessage = {\n kind: 'message',\n ...m,\n // Move the (about-to-be-hoisted) child conversations out of the emitted tool\n // calls. Setting it to `undefined` drops the key from the serialized export.\n ...(traceCalls.length > 0 && {\n toolCalls: m.toolCalls!.map((tc) =>\n tc.subAgentTrace ? { ...tc, subAgentTrace: undefined } : tc,\n ),\n }),\n // Mark + breadcrumb hoisted sub-agent messages; top-level (depth 0) stays as-is.\n ...(depth > 0 && {\n agentName: breadcrumb,\n subAgentName: m.agentName,\n subAgentDepth: depth,\n subAgentOf,\n }),\n };\n\n if (traceCalls.length === 0) return [entry];\n\n const hoisted = traceCalls.flatMap((tc) =>\n flattenSubAgentMessages(tc.subAgentTrace!, breadcrumb ?? '', depth + 1, tc.id),\n );\n return [entry, ...hoisted];\n });\n}\n", "/**\n * Shared, pure builder for the debug-log timeline entries (`message` / `turn` / `event`) \u2014 the\n * common core of the host element's `buildDiagnosticEntries` and any HEADLESS consumer that drives\n * a `ChatDriver` of its own (e.g. `ai-service` running the engine server-side) and needs to harvest\n * that engine's debug log for the client to fold into its own download / persisted stream\n * (GENC-1461 unified diagnostics). DOM-clean and dependency-light so it works in bare Node.\n *\n * It deliberately excludes the `meta-snapshot` entry: that block is host/DOM-specific (it reads\n * `window.location.host`, the element's agent list, live context/cost), and a merged log keeps only\n * the newest snapshot anyway \u2014 a headless source's agent/prompt/tools are already captured in its\n * `turn` entries.\n *\n * @packageDocumentation\n */\n\nimport type { ChatMessage } from '@genesislcap/foundation-ai';\nimport { flattenSubAgentMessages } from '../../utils/flatten-sub-agent-messages';\nimport type { MetaEvent } from '../debug-event-log';\nimport type { DiagnosticEntry } from './diagnostics';\n\n/**\n * The minimal shape this builder reads off a turn snapshot. The driver's full `TurnSnapshot` is a\n * structural superset, so it assigns to this without the builder depending on the component layer.\n */\nexport interface TurnSnapshotLike {\n turnIndex: string;\n systemPrompt?: string;\n}\n\n/**\n * Build the `message` / `turn` / `event` timeline entries from a driver's pull surfaces\n * (`getRawHistory()` / `getTurnSnapshots()` / `getMetaEvents(sessionKey)`). Order within the array\n * is message \u2192 turn \u2192 event; the caller (`assembleDebugLog`) sorts the whole timeline by timestamp,\n * so this ordering only sets the co-timestamp tie-break. Pure.\n */\nexport function buildTimelineEntries(input: {\n turnSnapshots: readonly TurnSnapshotLike[];\n messages: readonly ChatMessage[];\n metaEvents: readonly MetaEvent[];\n}): DiagnosticEntry[] {\n const { turnSnapshots, messages, metaEvents } = input;\n\n // Collapse a turn's systemPrompt when byte-identical to the previous turn's \u2014 a stable agent\n // repeats the same (often multi-KB) prompt every turn, while a stateful agent's changes. The\n // prompt is shown in full whenever it changes, so prompt evolution stays visible.\n let lastFullPrompt: string | undefined;\n let lastFullIndex = '';\n const turns = turnSnapshots.map((t) => {\n let { systemPrompt } = t;\n if (systemPrompt != null && systemPrompt === lastFullPrompt) {\n systemPrompt = `<repeated \u2014 identical to turn ${lastFullIndex}>`;\n } else if (systemPrompt != null) {\n lastFullPrompt = systemPrompt;\n lastFullIndex = t.turnIndex;\n }\n return { kind: 'turn' as const, ...t, systemPrompt };\n });\n\n // Sub-agent conversations are stored nested on the parent tool call's `subAgentTrace`;\n // `flattenSubAgentMessages` hoists them to top-level `kind: 'message'` entries (breadcrumbed +\n // correlated, the nested copy moved out \u2014 not duplicated) so the timeline reads chronologically.\n const messageEntries = flattenSubAgentMessages(messages);\n const eventEntries = metaEvents.map((e) => ({ kind: 'event' as const, ...e }));\n\n return [...messageEntries, ...turns, ...eventEntries] as DiagnosticEntry[];\n}\n", "/**\n * Server-saved diagnostics (GENC-1351 \u00A75.8) \u2014 the forward-only stream that lets\n * the debug log persist across a whole session lifetime, not just the current\n * page load. This module owns the *pure* pieces: the entry type and the\n * reassembly back into the `{ readme, timeline, meta }` debug-log shape. The\n * element owns capture/cadence; the provider owns storage layout.\n *\n * @packageDocumentation\n */\n\n/**\n * One entry in the diagnostics stream \u2014 the debug-log timeline-entry union\n * (`message` / `turn` / `event`, as `getDebugLog()` builds) plus a point-in-time\n * **`meta-snapshot`** carrying the export-time `meta` block (agent summary,\n * context, active debug snapshot, \u2026). Kept permissive: a provider stores and\n * returns these opaquely, and reassembly reads only `kind`, `timestamp` (for\n * ordering), and `meta` (on a snapshot).\n *\n * @public\n */\nexport interface DiagnosticEntry {\n kind: 'message' | 'turn' | 'event' | 'meta-snapshot';\n /** ISO timestamp \u2014 string-comparable, so it orders the stream chronologically. */\n timestamp?: string;\n /** Present on `meta-snapshot` entries: the export-time `meta` block. */\n meta?: unknown;\n /**\n * Present on `meta-snapshot` entries: a stable signature of the near-static config\n * (excludes volatile timestamp/context/debug-snapshot), used by the forward-capture\n * delta to skip re-appending an unchanged block (GENC-1351 \u00A75.8). Absent on other\n * kinds and on pre-signature entries (the delta falls back to the full `meta` then).\n */\n dedupSignature?: string;\n [key: string]: unknown;\n}\n\n/** The reassembled debug log \u2014 the exact shape `getDebugLog()` returns. @public */\nexport interface DebugLog {\n readme: readonly string[];\n timeline: DiagnosticEntry[];\n meta: unknown;\n}\n\n/**\n * Stable identity for a message diagnostic entry \u2014 `timestamp::role::subAgentOf::category`.\n * Used by the forward-capture delta (skip already-emitted messages) and by the\n * restore watermark (skip messages already present in a prior load's stream).\n * `null` when the entry has no timestamp \u2192 treat as always-new. Shared so the\n * element's diagnostics capture and the `SessionPersister`'s restore watermark\n * compute identity identically (GENC-1351 \u00A75.8/\u00A75.10).\n *\n * `category` is part of the key because the reasoning/narration/answer split (GENC-1411) emits\n * SEVERAL messages from one model response \u2014 the thought summary, any interstitial narration, and\n * the answer/tool-call message \u2014 which share `timestamp` + `role` + `subAgentOf`. Keying on those\n * alone collapsed them to one, so the forward-capture dropped all but the first: a server\n * generation's answer message vanished from the persisted debug log while its reasoning survived\n * (GENC-1461). `category` is stable across a message's in-place annotation (only `toolCalls` change,\n * which is deliberately excluded), so a genuine re-append of the same message still dedups.\n *\n * @internal\n */\nexport function diagnosticsMessageKey(entry: DiagnosticEntry): string | null {\n return typeof entry.timestamp === 'string'\n ? `${entry.timestamp}::${(entry.role as string) ?? ''}::${(entry.subAgentOf as string) ?? ''}::${(entry.category as string) ?? ''}`\n : null;\n}\n\n// Tie-break co-timestamped entries by cause \u2192 call \u2192 output (event, turn, message),\n// matching the original in-place `getDebugLog` sort.\nconst KIND_RANK: Record<string, number> = { event: 0, turn: 1, message: 2 };\n// Any non-{event,turn,message} kind (shouldn't reach the timeline \u2014 meta-snapshots\n// are filtered out first) sorts last.\nconst UNKNOWN_KIND_RANK = 99;\n\n/**\n * Reassemble diagnostic entries into the `{ readme, timeline, meta }` debug-log\n * shape (GENC-1351 \u00A75.8). `timeline` = the `message`/`turn`/`event` entries sorted\n * by ISO `timestamp` (kind-rank tie-break). `meta` = the **newest** `meta-snapshot`'s\n * block only \u2014 a \"state at export\" photo, matching the single-page log. The older\n * snapshots are intentionally dropped: the per-turn evolution they would show is\n * already in the timeline (`turn.agentSnapshot` + `context.updated` events), so\n * keeping them would just repeat the bulky, near-static `agentSummary`. `readme` =\n * the passed (current) constant. Pure \u2014 reused for both the live current-page log\n * and the reassembled lifetime log stitched from the persisted stream, so both\n * come out shape-identical.\n */\nexport function assembleDebugLog(entries: DiagnosticEntry[], readme: readonly string[]): DebugLog {\n // Safety net for exact-duplicate entries: two element instances sharing one\n // session (bubble + popped-out panel) can each append the same entry, and a\n // reload's second instance can re-append restored history. Such copies are\n // byte-identical, so collapse by serialized identity \u2014 genuinely-distinct entries\n // (e.g. two real `assistant.connected` from two instances) differ in index /\n // placement and are kept. (The shared cursor store prevents most of this at\n // write time; this guards the read path regardless of what's in the stream.)\n const seen = new Set<string>();\n let latestMeta: DiagnosticEntry | undefined;\n const timeline: DiagnosticEntry[] = [];\n for (const entry of entries) {\n const id = JSON.stringify(entry);\n if (seen.has(id)) continue;\n seen.add(id);\n if (entry.kind === 'meta-snapshot') {\n if (!latestMeta || (entry.timestamp ?? '') >= (latestMeta.timestamp ?? '')) {\n latestMeta = entry;\n }\n } else {\n timeline.push(entry);\n }\n }\n timeline.sort((a, b) => {\n const ta = a.timestamp ?? '';\n const tb = b.timestamp ?? '';\n if (ta < tb) return -1;\n if (ta > tb) return 1;\n return (KIND_RANK[a.kind] ?? UNKNOWN_KIND_RANK) - (KIND_RANK[b.kind] ?? UNKNOWN_KIND_RANK);\n });\n return { readme, timeline, meta: latestMeta?.meta };\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nvar ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n var r, s = 0;\n function next() {\n while (r = env.stack.pop()) {\n try {\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\n if (r.dispose) {\n var result = r.dispose.call(r.value);\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n else s |= 1;\n }\n catch (e) {\n fail(e);\n }\n }\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\n });\n }\n return path;\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __esDecorate,\n __runInitializers,\n __propKey,\n __setFunctionName,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n __rewriteRelativeImportExtension,\n};\n", "const noop = () => { };\n/**\n * Fan several `AbortSignal`s into one. The returned signal aborts as soon\n * as any input signal aborts, adopting that signal's `reason` \u2014 so callers can\n * distinguish, for example, a timeout (`TimeoutError`) from a user/lifecycle\n * cancellation (`AbortError`) by inspecting `signal.reason`. `undefined`\n * entries are ignored, letting callers pass optional signals directly.\n *\n * NOTE: the platform already provides exactly this \u2014 `AbortSignal.any([...])`\n * \u2014 but it is part of a newer spec than we target here. Our TypeScript config\n * is pinned to an older standard library (tsconfig `target: ES2015`,\n * `lib: [...ES2020]`), which predates `AbortSignal.any()`/`AbortSignal.timeout()`,\n * so those APIs are not in our typings (and have a narrower runtime-support\n * floor). This helper is the hand-rolled stand-in until the lib target is\n * raised, at which point this can be deleted in favour of `AbortSignal.any`.\n *\n * @example\n * const timeout = new AbortController();\n * const timer = setTimeout(\n * () => timeout.abort(new DOMException('Request timed out', 'TimeoutError')),\n * ms,\n * );\n * const { signal, dispose } = combineSignals([callerSignal, timeout.signal]);\n * try {\n * return await fetch(url, { signal });\n * } finally {\n * clearTimeout(timer);\n * dispose();\n * }\n */\nexport function combineSignals(signals) {\n const controller = new AbortController();\n const inputs = signals.filter((s) => s != null);\n // If any input is already aborted, adopt its reason immediately. Nothing to\n // wire up, so the disposer is a no-op.\n const preAborted = inputs.find((s) => s.aborted);\n if (preAborted) {\n controller.abort(preAborted.reason);\n return { signal: controller.signal, dispose: noop };\n }\n // `dispose` and `onAbort` reference each other; both are hoisted function\n // declarations so neither is read before it is initialised.\n function dispose() {\n for (const s of inputs) {\n s.removeEventListener('abort', onAbort);\n }\n }\n // `this` is the input signal the listener was attached to, so `this.reason`\n // is the reason of whichever signal aborted first.\n function onAbort() {\n controller.abort(this.reason);\n dispose();\n }\n for (const s of inputs) {\n s.addEventListener('abort', onAbort);\n }\n return { signal: controller.signal, dispose };\n}\n", "const LogLevels = {\n silent: Number.NEGATIVE_INFINITY,\n fatal: 0,\n error: 0,\n warn: 1,\n log: 2,\n info: 3,\n success: 3,\n fail: 3,\n ready: 3,\n start: 3,\n box: 3,\n debug: 4,\n trace: 5,\n verbose: Number.POSITIVE_INFINITY\n};\nconst LogTypes = {\n // Silent\n silent: {\n level: -1\n },\n // Level 0\n fatal: {\n level: LogLevels.fatal\n },\n error: {\n level: LogLevels.error\n },\n // Level 1\n warn: {\n level: LogLevels.warn\n },\n // Level 2\n log: {\n level: LogLevels.log\n },\n // Level 3\n info: {\n level: LogLevels.info\n },\n success: {\n level: LogLevels.success\n },\n fail: {\n level: LogLevels.fail\n },\n ready: {\n level: LogLevels.info\n },\n start: {\n level: LogLevels.info\n },\n box: {\n level: LogLevels.info\n },\n // Level 4\n debug: {\n level: LogLevels.debug\n },\n // Level 5\n trace: {\n level: LogLevels.trace\n },\n // Verbose\n verbose: {\n level: LogLevels.verbose\n }\n};\n\nfunction isPlainObject$1(value) {\n if (value === null || typeof value !== \"object\") {\n return false;\n }\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) {\n return false;\n }\n if (Symbol.iterator in value) {\n return false;\n }\n if (Symbol.toStringTag in value) {\n return Object.prototype.toString.call(value) === \"[object Module]\";\n }\n return true;\n}\n\nfunction _defu(baseObject, defaults, namespace = \".\", merger) {\n if (!isPlainObject$1(defaults)) {\n return _defu(baseObject, {}, namespace, merger);\n }\n const object = Object.assign({}, defaults);\n for (const key in baseObject) {\n if (key === \"__proto__\" || key === \"constructor\") {\n continue;\n }\n const value = baseObject[key];\n if (value === null || value === void 0) {\n continue;\n }\n if (merger && merger(object, key, value, namespace)) {\n continue;\n }\n if (Array.isArray(value) && Array.isArray(object[key])) {\n object[key] = [...value, ...object[key]];\n } else if (isPlainObject$1(value) && isPlainObject$1(object[key])) {\n object[key] = _defu(\n value,\n object[key],\n (namespace ? `${namespace}.` : \"\") + key.toString(),\n merger\n );\n } else {\n object[key] = value;\n }\n }\n return object;\n}\nfunction createDefu(merger) {\n return (...arguments_) => (\n // eslint-disable-next-line unicorn/no-array-reduce\n arguments_.reduce((p, c) => _defu(p, c, \"\", merger), {})\n );\n}\nconst defu = createDefu();\n\nfunction isPlainObject(obj) {\n return Object.prototype.toString.call(obj) === \"[object Object]\";\n}\nfunction isLogObj(arg) {\n if (!isPlainObject(arg)) {\n return false;\n }\n if (!arg.message && !arg.args) {\n return false;\n }\n if (arg.stack) {\n return false;\n }\n return true;\n}\n\nlet paused = false;\nconst queue = [];\nclass Consola {\n options;\n _lastLog;\n _mockFn;\n /**\n * Creates an instance of Consola with specified options or defaults.\n *\n * @param {Partial<ConsolaOptions>} [options={}] - Configuration options for the Consola instance.\n */\n constructor(options = {}) {\n const types = options.types || LogTypes;\n this.options = defu(\n {\n ...options,\n defaults: { ...options.defaults },\n level: _normalizeLogLevel(options.level, types),\n reporters: [...options.reporters || []]\n },\n {\n types: LogTypes,\n throttle: 1e3,\n throttleMin: 5,\n formatOptions: {\n date: true,\n colors: false,\n compact: true\n }\n }\n );\n for (const type in types) {\n const defaults = {\n type,\n ...this.options.defaults,\n ...types[type]\n };\n this[type] = this._wrapLogFn(defaults);\n this[type].raw = this._wrapLogFn(\n defaults,\n true\n );\n }\n if (this.options.mockFn) {\n this.mockTypes();\n }\n this._lastLog = {};\n }\n /**\n * Gets the current log level of the Consola instance.\n *\n * @returns {number} The current log level.\n */\n get level() {\n return this.options.level;\n }\n /**\n * Sets the minimum log level that will be output by the instance.\n *\n * @param {number} level - The new log level to set.\n */\n set level(level) {\n this.options.level = _normalizeLogLevel(\n level,\n this.options.types,\n this.options.level\n );\n }\n /**\n * Displays a prompt to the user and returns the response.\n * Throw an error if `prompt` is not supported by the current configuration.\n *\n * @template T\n * @param {string} message - The message to display in the prompt.\n * @param {T} [opts] - Optional options for the prompt. See {@link PromptOptions}.\n * @returns {promise<T>} A promise that infer with the prompt options. See {@link PromptOptions}.\n */\n prompt(message, opts) {\n if (!this.options.prompt) {\n throw new Error(\"prompt is not supported!\");\n }\n return this.options.prompt(message, opts);\n }\n /**\n * Creates a new instance of Consola, inheriting options from the current instance, with possible overrides.\n *\n * @param {Partial<ConsolaOptions>} options - Optional overrides for the new instance. See {@link ConsolaOptions}.\n * @returns {ConsolaInstance} A new Consola instance. See {@link ConsolaInstance}.\n */\n create(options) {\n const instance = new Consola({\n ...this.options,\n ...options\n });\n if (this._mockFn) {\n instance.mockTypes(this._mockFn);\n }\n return instance;\n }\n /**\n * Creates a new Consola instance with the specified default log object properties.\n *\n * @param {InputLogObject} defaults - Default properties to include in any log from the new instance. See {@link InputLogObject}.\n * @returns {ConsolaInstance} A new Consola instance. See {@link ConsolaInstance}.\n */\n withDefaults(defaults) {\n return this.create({\n ...this.options,\n defaults: {\n ...this.options.defaults,\n ...defaults\n }\n });\n }\n /**\n * Creates a new Consola instance with a specified tag, which will be included in every log.\n *\n * @param {string} tag - The tag to include in each log of the new instance.\n * @returns {ConsolaInstance} A new Consola instance. See {@link ConsolaInstance}.\n */\n withTag(tag) {\n return this.withDefaults({\n tag: this.options.defaults.tag ? this.options.defaults.tag + \":\" + tag : tag\n });\n }\n /**\n * Adds a custom reporter to the Consola instance.\n * Reporters will be called for each log message, depending on their implementation and log level.\n *\n * @param {ConsolaReporter} reporter - The reporter to add. See {@link ConsolaReporter}.\n * @returns {Consola} The current Consola instance.\n */\n addReporter(reporter) {\n this.options.reporters.push(reporter);\n return this;\n }\n /**\n * Removes a custom reporter from the Consola instance.\n * If no reporter is specified, all reporters will be removed.\n *\n * @param {ConsolaReporter} reporter - The reporter to remove. See {@link ConsolaReporter}.\n * @returns {Consola} The current Consola instance.\n */\n removeReporter(reporter) {\n if (reporter) {\n const i = this.options.reporters.indexOf(reporter);\n if (i !== -1) {\n return this.options.reporters.splice(i, 1);\n }\n } else {\n this.options.reporters.splice(0);\n }\n return this;\n }\n /**\n * Replaces all reporters of the Consola instance with the specified array of reporters.\n *\n * @param {ConsolaReporter[]} reporters - The new reporters to set. See {@link ConsolaReporter}.\n * @returns {Consola} The current Consola instance.\n */\n setReporters(reporters) {\n this.options.reporters = Array.isArray(reporters) ? reporters : [reporters];\n return this;\n }\n wrapAll() {\n this.wrapConsole();\n this.wrapStd();\n }\n restoreAll() {\n this.restoreConsole();\n this.restoreStd();\n }\n /**\n * Overrides console methods with Consola logging methods for consistent logging.\n */\n wrapConsole() {\n for (const type in this.options.types) {\n if (!console[\"__\" + type]) {\n console[\"__\" + type] = console[type];\n }\n console[type] = this[type].raw;\n }\n }\n /**\n * Restores the original console methods, removing Consola overrides.\n */\n restoreConsole() {\n for (const type in this.options.types) {\n if (console[\"__\" + type]) {\n console[type] = console[\"__\" + type];\n delete console[\"__\" + type];\n }\n }\n }\n /**\n * Overrides standard output and error streams to redirect them through Consola.\n */\n wrapStd() {\n this._wrapStream(this.options.stdout, \"log\");\n this._wrapStream(this.options.stderr, \"log\");\n }\n _wrapStream(stream, type) {\n if (!stream) {\n return;\n }\n if (!stream.__write) {\n stream.__write = stream.write;\n }\n stream.write = (data) => {\n this[type].raw(String(data).trim());\n };\n }\n /**\n * Restores the original standard output and error streams, removing the Consola redirection.\n */\n restoreStd() {\n this._restoreStream(this.options.stdout);\n this._restoreStream(this.options.stderr);\n }\n _restoreStream(stream) {\n if (!stream) {\n return;\n }\n if (stream.__write) {\n stream.write = stream.__write;\n delete stream.__write;\n }\n }\n /**\n * Pauses logging, queues incoming logs until resumed.\n */\n pauseLogs() {\n paused = true;\n }\n /**\n * Resumes logging, processing any queued logs.\n */\n resumeLogs() {\n paused = false;\n const _queue = queue.splice(0);\n for (const item of _queue) {\n item[0]._logFn(item[1], item[2]);\n }\n }\n /**\n * Replaces logging methods with mocks if a mock function is provided.\n *\n * @param {ConsolaOptions[\"mockFn\"]} mockFn - The function to use for mocking logging methods. See {@link ConsolaOptions[\"mockFn\"]}.\n */\n mockTypes(mockFn) {\n const _mockFn = mockFn || this.options.mockFn;\n this._mockFn = _mockFn;\n if (typeof _mockFn !== \"function\") {\n return;\n }\n for (const type in this.options.types) {\n this[type] = _mockFn(type, this.options.types[type]) || this[type];\n this[type].raw = this[type];\n }\n }\n _wrapLogFn(defaults, isRaw) {\n return (...args) => {\n if (paused) {\n queue.push([this, defaults, args, isRaw]);\n return;\n }\n return this._logFn(defaults, args, isRaw);\n };\n }\n _logFn(defaults, args, isRaw) {\n if ((defaults.level || 0) > this.level) {\n return false;\n }\n const logObj = {\n date: /* @__PURE__ */ new Date(),\n args: [],\n ...defaults,\n level: _normalizeLogLevel(defaults.level, this.options.types)\n };\n if (!isRaw && args.length === 1 && isLogObj(args[0])) {\n Object.assign(logObj, args[0]);\n } else {\n logObj.args = [...args];\n }\n if (logObj.message) {\n logObj.args.unshift(logObj.message);\n delete logObj.message;\n }\n if (logObj.additional) {\n if (!Array.isArray(logObj.additional)) {\n logObj.additional = logObj.additional.split(\"\\n\");\n }\n logObj.args.push(\"\\n\" + logObj.additional.join(\"\\n\"));\n delete logObj.additional;\n }\n logObj.type = typeof logObj.type === \"string\" ? logObj.type.toLowerCase() : \"log\";\n logObj.tag = typeof logObj.tag === \"string\" ? logObj.tag : \"\";\n const resolveLog = (newLog = false) => {\n const repeated = (this._lastLog.count || 0) - this.options.throttleMin;\n if (this._lastLog.object && repeated > 0) {\n const args2 = [...this._lastLog.object.args];\n if (repeated > 1) {\n args2.push(`(repeated ${repeated} times)`);\n }\n this._log({ ...this._lastLog.object, args: args2 });\n this._lastLog.count = 1;\n }\n if (newLog) {\n this._lastLog.object = logObj;\n this._log(logObj);\n }\n };\n clearTimeout(this._lastLog.timeout);\n const diffTime = this._lastLog.time && logObj.date ? logObj.date.getTime() - this._lastLog.time.getTime() : 0;\n this._lastLog.time = logObj.date;\n if (diffTime < this.options.throttle) {\n try {\n const serializedLog = JSON.stringify([\n logObj.type,\n logObj.tag,\n logObj.args\n ]);\n const isSameLog = this._lastLog.serialized === serializedLog;\n this._lastLog.serialized = serializedLog;\n if (isSameLog) {\n this._lastLog.count = (this._lastLog.count || 0) + 1;\n if (this._lastLog.count > this.options.throttleMin) {\n this._lastLog.timeout = setTimeout(\n resolveLog,\n this.options.throttle\n );\n return;\n }\n }\n } catch {\n }\n }\n resolveLog(true);\n }\n _log(logObj) {\n for (const reporter of this.options.reporters) {\n reporter.log(logObj, {\n options: this.options\n });\n }\n }\n}\nfunction _normalizeLogLevel(input, types = {}, defaultLevel = 3) {\n if (input === void 0) {\n return defaultLevel;\n }\n if (typeof input === \"number\") {\n return input;\n }\n if (types[input] && types[input].level !== void 0) {\n return types[input].level;\n }\n return defaultLevel;\n}\nConsola.prototype.add = Consola.prototype.addReporter;\nConsola.prototype.remove = Consola.prototype.removeReporter;\nConsola.prototype.clear = Consola.prototype.removeReporter;\nConsola.prototype.withScope = Consola.prototype.withTag;\nConsola.prototype.mock = Consola.prototype.mockTypes;\nConsola.prototype.pause = Consola.prototype.pauseLogs;\nConsola.prototype.resume = Consola.prototype.resumeLogs;\nfunction createConsola(options = {}) {\n return new Consola(options);\n}\n\nexport { Consola, LogLevels, LogTypes, createConsola };\n", "import { createConsola as createConsola$1 } from './core.mjs';\nexport { Consola, LogLevels, LogTypes } from './core.mjs';\n\nclass BrowserReporter {\n options;\n defaultColor;\n levelColorMap;\n typeColorMap;\n constructor(options) {\n this.options = { ...options };\n this.defaultColor = \"#7f8c8d\";\n this.levelColorMap = {\n 0: \"#c0392b\",\n // Red\n 1: \"#f39c12\",\n // Yellow\n 3: \"#00BCD4\"\n // Cyan\n };\n this.typeColorMap = {\n success: \"#2ecc71\"\n // Green\n };\n }\n _getLogFn(level) {\n if (level < 1) {\n return console.__error || console.error;\n }\n if (level === 1) {\n return console.__warn || console.warn;\n }\n return console.__log || console.log;\n }\n log(logObj) {\n const consoleLogFn = this._getLogFn(logObj.level);\n const type = logObj.type === \"log\" ? \"\" : logObj.type;\n const tag = logObj.tag || \"\";\n const color = this.typeColorMap[logObj.type] || this.levelColorMap[logObj.level] || this.defaultColor;\n const style = `\n background: ${color};\n border-radius: 0.5em;\n color: white;\n font-weight: bold;\n padding: 2px 0.5em;\n `;\n const badge = `%c${[tag, type].filter(Boolean).join(\":\")}`;\n if (typeof logObj.args[0] === \"string\") {\n consoleLogFn(\n `${badge}%c ${logObj.args[0]}`,\n style,\n // Empty string as style resets to default console style\n \"\",\n ...logObj.args.slice(1)\n );\n } else {\n consoleLogFn(badge, style, ...logObj.args);\n }\n }\n}\n\nfunction createConsola(options = {}) {\n const consola2 = createConsola$1({\n reporters: options.reporters || [new BrowserReporter({})],\n prompt(message, options2 = {}) {\n if (options2.type === \"confirm\") {\n return Promise.resolve(confirm(message));\n }\n return Promise.resolve(prompt(message));\n },\n ...options\n });\n return consola2;\n}\nconst consola = createConsola();\n\nexport { consola, createConsola, consola as default };\n", "import { createConsola as createConsolaBrowser } from 'consola/browser';\nimport { LogLevels, createConsola as createConsolaCore, } from 'consola/core';\n/**\n * Used to set the logging level.\n *\n * @example Explicitly set the level of an imported package beyond the current runtime level.\n * ```ts\n * import { LogLevel } from '@genesislcap/foundation-logger';\n * import { logger as myPackageLogger } from 'my-package';\n * myPackageLogger.level = LogLevel.Error;\n * ```\n *\n * @public\n */\nexport { LogLevels } from 'consola/core';\n/**\n * The default logger options.\n * @public\n */\nexport const defaultLoggerOptions = {\n level: LogLevels.debug,\n};\n/**\n * Creates a logger with the given name and options.\n *\n * @example Create a logger in my-package/utils.\n * ```ts\n * import { createLogger } from '@genesislcap/foundation-logger';\n * export const logger = createLogger('my-package');\n * ```\n *\n * @example Using the logger within my-package.\n * ```ts\n * import { logger } from '../utils';\n * logger.debug(`Data retrieved from ${resourceName}`);\n * logger.info(this.toggled ? 'On' : 'Off');\n * logger.warn('Not available in this browser.');\n * ```\n *\n * @example Explicitly set the level of an imported package.\n * ```ts\n * import { logger as commsLogger } from '@genesislcap/foundation-comms';\n * import { LogLevel } from '@genesislcap/foundation-logger';\n * commsLogger.level = LogLevel.Warn;\n * ```\n *\n * @param name - The name to give the logger.\n * @param options - The options to use when creating the logger.\n * @returns The resulting logger.\n * @public\n */\nexport function createLogger(name, options = defaultLoggerOptions) {\n const createConsola = typeof window !== 'undefined' ? createConsolaBrowser : createConsolaCore;\n const logger = createConsola().withTag(name);\n if ((options === null || options === void 0 ? void 0 : options.level) !== undefined)\n logger.level = options.level;\n const typedLogger = logger;\n typedLogger.deprecated = (symbol, instruction = 'Consult docs for better alternative.', removalVersionTarget) => {\n typedLogger.warn(`Deprecated symbol used '${symbol}'. ${instruction}`, `${removalVersionTarget ? `Will be removed in version ${removalVersionTarget}.` : ''}`);\n };\n return typedLogger;\n}\n", "import { createLogger } from '@genesislcap/foundation-logger';\nexport const logger = createLogger('foundation-ai');\n", "import { logger } from '../utils';\nconst CLAUSE_SCHEMA = {\n type: 'object',\n properties: {\n field: { type: 'string', description: 'Field name from available metadata' },\n operator: {\n type: 'string',\n enum: [\n 'contains',\n 'equals',\n 'startsWith',\n 'endsWith',\n 'greaterThan',\n 'lessThan',\n 'greaterThanOrEqual',\n 'lessThanOrEqual',\n 'notEqual',\n 'dateIsToday',\n 'dateIsAfter',\n 'dateIsBefore',\n 'dateIsEqual',\n 'dateIsGreaterEqual',\n 'dateIsLessEqual',\n 'dateTimeIsAfter',\n 'dateTimeIsBefore',\n 'dateTimeIsGreaterEqual',\n 'dateTimeIsLessEqual',\n ],\n },\n value: {\n type: ['string', 'number', 'boolean', 'null'],\n description: 'Value for the clause; null for dateIsToday',\n },\n },\n required: ['field', 'operator', 'value'],\n additionalProperties: false,\n};\n/**\n * Standard JSON Schema for criteria interpretation output.\n * Used by Chrome Prompt API (responseConstraint) and other providers.\n *\n * @beta\n */\nexport const CRITERIA_JSON_SCHEMA = {\n type: 'object',\n properties: {\n groups: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n logic: {\n type: 'string',\n enum: ['and', 'or'],\n description: 'How clauses within the group are combined',\n },\n negated: {\n type: 'boolean',\n default: false,\n description: 'If true, negate the entire group',\n },\n clauses: {\n type: 'array',\n items: CLAUSE_SCHEMA,\n },\n },\n required: ['logic', 'negated', 'clauses'],\n additionalProperties: false,\n },\n },\n },\n required: ['groups'],\n additionalProperties: false,\n};\n/**\n * OpenAI-specific response_format wrapper for structured output.\n *\n * @beta\n */\nexport const OPENAI_CRITERIA_RESPONSE_FORMAT = {\n type: 'json_schema',\n json_schema: {\n name: 'criteria_interpretation',\n strict: true,\n schema: CRITERIA_JSON_SCHEMA,\n },\n};\nconst DEFAULT_SYSTEM_PROMPT = `You are a criteria builder. Convert natural language into structured search criteria.\nReturn a JSON object with a \"groups\" array. Each group has: logic (\"and\" or \"or\"), optional negated (boolean), and clauses (array).\nEach clause has: field (string), operator (from enum), value (string|number|boolean|null).\n- When the user says \"or\" (e.g. \"quantity 100 or price > 50\"), use a group with logic \"or\" and multiple clauses.\n- When the user says \"not\" or \"except\", set negated: true on the group.\n- When the user says \"and\" or lists conditions without \"or\", use logic \"and\".\nUse dateIsToday with value null for \"today\" queries. Use yyyyMMdd for dates, yyyyMMdd-HH:mm for datetimes.`;\n/**\n * Builds the system prompt for criteria interpretation.\n *\n * @beta\n */\nexport function buildCriteriaSystemPrompt(fields = [], customInstructions) {\n const fieldList = fields\n .map((f) => {\n var _a, _b, _c, _d;\n return typeof f === 'string'\n ? f\n : ((_d = (_c = (_b = (_a = f === null || f === void 0 ? void 0 : f.NAME) !== null && _a !== void 0 ? _a : f === null || f === void 0 ? void 0 : f.name) !== null && _b !== void 0 ? _b : f === null || f === void 0 ? void 0 : f.field) !== null && _c !== void 0 ? _c : f === null || f === void 0 ? void 0 : f.label) !== null && _d !== void 0 ? _d : '');\n })\n .filter(Boolean)\n .join(', ');\n const basePrompt = customInstructions !== null && customInstructions !== void 0 ? customInstructions : DEFAULT_SYSTEM_PROMPT;\n const fieldsLine = `Available fields: ${fieldList || 'unknown - use common field names like NAME, ID, DATE, etc.'}`;\n return `${basePrompt}\\n${fieldsLine}`;\n}\n/**\n * Builds the user prompt for criteria interpretation.\n *\n * @beta\n */\nexport function buildCriteriaUserPrompt(input) {\n return `Convert to criteria: \"${input}\"`;\n}\n/**\n * Parses the raw response text into CriteriaInterpretationResult.\n *\n * @beta\n */\nexport function parseCriteriaResponse(text) {\n if (!(text === null || text === void 0 ? void 0 : text.trim())) {\n logger.debug('parseCriteriaResponse: empty or null input');\n return null;\n }\n try {\n const parsed = JSON.parse(text);\n if (!(parsed === null || parsed === void 0 ? void 0 : parsed.groups) || !Array.isArray(parsed.groups)) {\n logger.debug('parseCriteriaResponse: missing or invalid groups in response');\n return null;\n }\n return {\n groups: parsed.groups,\n };\n }\n catch (e) {\n logger.debug('parseCriteriaResponse: invalid JSON', e);\n return null;\n }\n}\n", "import { __asyncDelegator, __asyncGenerator, __asyncValues, __await, __awaiter } from \"tslib\";\nimport { buildCriteriaSystemPrompt, buildCriteriaUserPrompt, CRITERIA_JSON_SCHEMA, parseCriteriaResponse, } from '../interactions';\nimport { logger } from '../utils';\n/**\n * Anthropic Claude AI provider. Uses {@link AnthropicTransport} to handle requests.\n * Implements criteria interpretation and multi-turn chat.\n *\n * @beta\n */\nexport class AnthropicProvider {\n constructor(config, transport) {\n this.transport = transport;\n this.criteriaInstructions = config.criteriaInstructions;\n }\n getStatus() {\n return __awaiter(this, void 0, void 0, function* () {\n const config = this.transport.getConfig();\n return { provider: 'anthropic', model: config.model, contextLimit: config.contextLimit };\n });\n }\n interpretCriteria(input, context) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a;\n const fields = (_a = context === null || context === void 0 ? void 0 : context.fields) !== null && _a !== void 0 ? _a : [];\n const systemPrompt = buildCriteriaSystemPrompt(fields, this.criteriaInstructions);\n const userPrompt = buildCriteriaUserPrompt(input);\n try {\n const raw = yield this.transport.sendStructuredPrompt({\n systemPrompt,\n userPrompt,\n responseSchema: CRITERIA_JSON_SCHEMA,\n });\n return parseCriteriaResponse(raw);\n }\n catch (e) {\n logger.error('AnthropicProvider interpretCriteria failed:', e);\n return null;\n }\n });\n }\n prompt(message, options) {\n return __awaiter(this, void 0, void 0, function* () {\n const response = yield this.transport.sendChatMessage([], message, options);\n return response.content;\n });\n }\n chat(history, userMessage, options) {\n return __awaiter(this, void 0, void 0, function* () {\n return this.transport.sendChatMessage(history, userMessage, options);\n });\n }\n streamChat(history, userMessage, options) {\n return __asyncGenerator(this, arguments, function* streamChat_1() {\n if ('streamChatMessage' in this.transport &&\n typeof this.transport.streamChatMessage === 'function') {\n yield __await(yield* __asyncDelegator(__asyncValues(this.transport.streamChatMessage(history, userMessage, options))));\n }\n else {\n const msg = yield __await(this.transport.sendChatMessage(history, userMessage, options));\n yield yield __await({ delta: msg.content, done: true, toolCalls: msg.toolCalls });\n }\n });\n }\n}\n", "import { __awaiter } from \"tslib\";\n/**\n * Default no-op AI provider. Used when no provider is configured.\n * Components should check for capability support and show \"Configure AI\" state when appropriate.\n *\n * @beta\n */\nexport class DefaultAIProvider {\n getStatus() {\n return __awaiter(this, void 0, void 0, function* () {\n return { provider: 'none', model: '' };\n });\n }\n interpretCriteria(_input, _context) {\n return __awaiter(this, void 0, void 0, function* () {\n return null;\n });\n }\n}\n", "import { __asyncDelegator, __asyncGenerator, __asyncValues, __await, __awaiter } from \"tslib\";\nimport { buildCriteriaSystemPrompt, buildCriteriaUserPrompt, CRITERIA_JSON_SCHEMA, parseCriteriaResponse, } from '../interactions';\nimport { logger } from '../utils';\n/**\n * Gemini AI provider. Uses {@link GeminiTransport} to handle requests.\n * Implements criteria interpretation and multi-turn chat.\n *\n * @beta\n */\nexport class GeminiProvider {\n constructor(config, transport) {\n this.transport = transport;\n this.criteriaInstructions = config.criteriaInstructions;\n }\n getStatus() {\n return __awaiter(this, void 0, void 0, function* () {\n const config = this.transport.getConfig();\n return { provider: 'gemini', model: config.model, contextLimit: config.contextLimit };\n });\n }\n interpretCriteria(input, context) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a;\n const fields = (_a = context === null || context === void 0 ? void 0 : context.fields) !== null && _a !== void 0 ? _a : [];\n const systemPrompt = buildCriteriaSystemPrompt(fields, this.criteriaInstructions);\n const userPrompt = buildCriteriaUserPrompt(input);\n try {\n const raw = yield this.transport.sendStructuredPrompt({\n systemPrompt,\n userPrompt,\n responseSchema: CRITERIA_JSON_SCHEMA,\n });\n return parseCriteriaResponse(raw);\n }\n catch (e) {\n logger.error('GeminiProvider interpretCriteria failed:', e);\n return null;\n }\n });\n }\n prompt(message, options) {\n return __awaiter(this, void 0, void 0, function* () {\n const response = yield this.transport.sendChatMessage([], message, options);\n return response.content;\n });\n }\n chat(history, userMessage, options) {\n return __awaiter(this, void 0, void 0, function* () {\n return this.transport.sendChatMessage(history, userMessage, options);\n });\n }\n streamChat(history, userMessage, options) {\n return __asyncGenerator(this, arguments, function* streamChat_1() {\n if ('streamChatMessage' in this.transport &&\n typeof this.transport.streamChatMessage === 'function') {\n yield __await(yield* __asyncDelegator(__asyncValues(this.transport.streamChatMessage(history, userMessage, options))));\n }\n else {\n // Fallback: non-streaming chat exposed as a single chunk\n const msg = yield __await(this.transport.sendChatMessage(history, userMessage, options));\n yield yield __await({ delta: msg.content, done: true, toolCalls: msg.toolCalls });\n }\n });\n }\n}\n", "/**\n * The AI-spend budget wall (GENC-1464 workstream C/D).\n *\n * Lives in its own module rather than beside `ResponseTruncatedError` in\n * `anthropic-transport.ts` because it is raised from `post-with-retry.ts`, which\n * both transports import \u2014 homing it in a transport would close an import cycle\n * (transport \u2192 post-with-retry \u2192 transport) that the repo's `circular` check\n * rejects.\n */\n/** The proxy's machine-readable rejection code for an exhausted AI budget. */\nexport const BUDGET_EXCEEDED_CODE = 'BUDGET_EXCEEDED';\n/**\n * Display name for each concrete AI vendor: the **single source** every\n * transport's `vendorLabel` is read from, and the only place a vendor's name is\n * spelled for a user.\n *\n * This map is the hinge of the per-vendor budget model (GENC-1464). A wall is\n * attributed to a vendor by reverse-looking-up the label the refused transport\n * stamped on its {@link BudgetExhaustedError} \u2014 so a label that drifts from this\n * map (a literal typo, a casing change, a new vendor added with a hardcoded\n * string) silently degrades every wall from that transport to \"unattributable\"\n * and re-locks the whole session instead of just that vendor. It fails safe, but\n * the feature quietly stops working, which is why the transports read their label\n * from here rather than restating it.\n *\n * The map has **two kinds of entry**, and the difference matters:\n *\n * - The {@link BUDGETED_VENDORS} \u2014 `anthropic` and `gemini` \u2014 reach the model\n * through the ai-service proxy, are metered by it, and stamp their label on a\n * {@link BudgetExhaustedError}. For these the label is both an attribution key\n * and display copy.\n * - `chrome` and `openai` are **display-only**. `ChromeProvider` talks to the\n * on-device Prompt API and the proxy refuses `openai` outright, so neither can\n * be refused for budget or stamp a label \u2014 but both report a `provider` from\n * `getStatus()`, which puts them in the assistant's reachable set, which is\n * what the blocked banner names when it tells a walled user where they can\n * still go (\"Switch to Chrome to keep going.\"). Dropping either entry would\n * print the raw type there.\n *\n * `'none'` is excluded deliberately: it is the \"no provider configured\" sentinel,\n * not a vendor, and nothing can be refused by it \u2014 nor switched to.\n *\n * @beta\n */\nexport const VENDOR_LABELS = Object.freeze({\n anthropic: 'Anthropic',\n gemini: 'Gemini',\n openai: 'OpenAI',\n chrome: 'Chrome',\n});\n/**\n * The vendors whose spend the ai-service proxy meters \u2014 i.e. the only vendors\n * that can raise a {@link BudgetExhaustedError}, and therefore the only ones a\n * 402's `otherVendorAvailable: false` is a statement about.\n *\n * Deliberately narrower than the keys of {@link VENDOR_LABELS}, and it must stay\n * exactly the proxy's own list \u2014 `VENDORS` in ai-service's `utils/aiVendor.js`.\n * A vendor listed here that the proxy does not meter gets walled by the\n * `otherVendorAvailable: false` sweep on a verdict that says nothing about it,\n * and if it is reachable, `blocked` then derives true and locks a composer with\n * headroom left.\n *\n * Two vendors are excluded for that reason:\n * - `chrome` runs on-device \u2014 no pot to exhaust, and free.\n * - `openai` is **not budgeted by the proxy**. ai-service rejects it up front\n * with `400 UNSUPPORTED_PROVIDER` (`SUPPORTED_PROVIDERS` in `aiVendor.js`), no\n * `MODEL_PRICING` row names it, and `otherVendorAvailable` is computed over\n * Anthropic and Gemini alone. So it can never raise a 402, and a 402 is never\n * a statement about it.\n *\n * @beta\n */\nexport const BUDGETED_VENDORS = Object.freeze([\n 'anthropic',\n 'gemini',\n]);\n/**\n * Whether this vendor's spend is metered by the proxy \u2014 see\n * {@link BUDGETED_VENDORS}.\n *\n * A HOST-FACING helper with, deliberately, no internal caller: the library's\n * own consumers iterate {@link BUDGETED_VENDORS} directly (structural, cannot\n * drift), while a host writing its own budget pre-flight or status surface\n * needs the membership test in predicate form. Kept exported for that use \u2014\n * genesis-create's pre-flight is the shape of consumer it exists for.\n *\n * @beta\n */\nexport const isBudgetedVendor = (vendor) => vendor != null && BUDGETED_VENDORS.includes(vendor);\n/** Reverse index of {@link VENDOR_LABELS}, lower-cased, built once. */\nconst VENDOR_TYPE_BY_LABEL = new Map(Object.entries(VENDOR_LABELS).map(([type, label]) => [\n label.toLowerCase(),\n type,\n]));\n/**\n * The {@link AIProviderType} behind a vendor label, or `undefined` for a label\n * no vendor claims.\n *\n * Case-insensitive and whitespace-tolerant, because the label travels as free\n * text on the wire (the driver contract carries `vendorLabel`, not the type) and\n * an unrecognised label must degrade to \"unattributable\" rather than to a wrong\n * attribution \u2014 blocking the wrong vendor is worse than blocking none.\n *\n * @beta\n */\nexport function vendorTypeOfLabel(label) {\n if (typeof label !== 'string')\n return undefined;\n return VENDOR_TYPE_BY_LABEL.get(label.trim().toLowerCase());\n}\n/**\n * HTTP status the ai-service proxy rejects an over-budget request with, in both\n * the legacy JSON mode (the response status) and the NDJSON framed mode (the\n * `status` on the terminal `err` frame).\n *\n * Deliberately **absent** from every transport's `RETRYABLE_STATUSES`: the budget\n * does not refill on a backoff ladder, so retrying only delays the inevitable\n * five times over.\n */\nexport const BUDGET_EXCEEDED_STATUS = 402;\n/**\n * The single copy shown to a user whose AI budget is gone \u2014 the transcript bubble\n * the chat driver appends, and the default text of the assistant's blocked banner.\n *\n * Deliberately **vendor-neutral**: the same bundle ships to white-labelled\n * deployments where \"contact Genesis\" is simply wrong. A host that wants\n * branded wording overrides both surfaces \u2014 the banner via\n * `FoundationAiAssistant.setBlocked(true, reason)`, the transcript bubble via\n * `ChatDriverConfig.budgetExhaustedMessage` \u2014 so neither is stuck with this\n * default while the other is customised.\n *\n * @beta\n */\nexport const DEFAULT_BUDGET_EXHAUSTED_MESSAGE = \"You've reached your AI usage limit. Contact your administrator to raise it.\";\n/**\n * Thrown when the AI-spend budget for the caller (user, tenant, or project) is\n * exhausted and the ai-service proxy refuses the request outright \u2014 HTTP `402`\n * with `code: 'BUDGET_EXCEEDED'`, in either the legacy JSON or the NDJSON framed\n * mode.\n *\n * This is a **terminal, non-transient** condition, in the same family as\n * `ResponseTruncatedError`: no amount of retrying clears it, because nothing\n * about the request is wrong. The budget has to be raised out-of-band before any\n * further call can succeed, so both the transport retry ladder and the driver's\n * transient-retry catch step aside for it and the failure surfaces immediately\n * as the `'budget-exhausted'` `TurnFailureReason`.\n *\n * `budgetUsd`/`spentUsd` are populated from the rejection body when the proxy\n * supplies them (the workstream-C contract does); they are optional because a\n * plain-text or truncated 402 from an older proxy still has to classify.\n *\n * @beta\n */\nexport class BudgetExhaustedError extends Error {\n constructor(\n /** Vendor label of the transport that was refused (e.g. `'Anthropic'`). */\n vendorLabel, \n /** The configured spend cap in USD, when the proxy reported one. */\n budgetUsd, \n /** Spend already booked against that cap in USD, when the proxy reported it. */\n spentUsd, \n /** The proxy's human-readable rejection message, when present. */\n detail, \n /**\n * The fields the proxy reports about the wider budget picture. An object\n * rather than two more positional arguments: the four above are already the\n * limit of what reads at a call site, and these two are set together or not\n * at all.\n */\n extra) {\n super(`${vendorLabel} request refused: the AI usage budget is exhausted` +\n (budgetUsd != null\n ? ` (spent ${spentUsd != null ? `$${spentUsd}` : 'an unknown amount'} of a $${budgetUsd} budget)`\n : '') +\n (detail ? `: ${detail}` : '') +\n '. Retrying will not clear this \u2014 the budget must be raised.');\n this.vendorLabel = vendorLabel;\n this.budgetUsd = budgetUsd;\n this.spentUsd = spentUsd;\n this.detail = detail;\n this.name = 'BudgetExhaustedError';\n this.otherVendorAvailable = extra === null || extra === void 0 ? void 0 : extra.otherVendorAvailable;\n this.serverVendor = extra === null || extra === void 0 ? void 0 : extra.serverVendor;\n }\n}\n/**\n * True for a budget rejection in either wire mode: the contracted `402`, or the\n * `BUDGET_EXCEEDED` code under **any** status.\n *\n * Both keys are load-bearing, and they are not redundant:\n *\n * - `status` is the key the workstream-C contract guarantees (\"402 always\"), and\n * the only one a plain-text or unparseable rejection carries.\n * - `code` is the cheap defence against that contract drifting. Nothing stops a\n * proxy from mapping the refusal onto `403` or `429` \u2014 and `429` is in *both*\n * transports' `RETRYABLE_STATUSES`, so a status-only check would hand the user\n * the exact bug GENC-1464 exists to fix: five doomed requests and ~31s of backoff\n * before an opaque failure. A well-formed `{ t: 'err', status: 429, code:\n * 'BUDGET_EXCEEDED' }` frame is accepted by `readFramedBody` (it only rejects a\n * non-numeric status), so this is a reachable shape, not a hypothetical one.\n *\n * The false-positive cost is a proxy sending `code: 'BUDGET_EXCEEDED'` on a\n * genuinely retryable failure \u2014 a shape the contract does not permit.\n *\n * Internal to the transports (unlike `BudgetExhaustedError`, which hosts branch\n * on): deliberately **not** re-exported from the package index.\n *\n * @internal\n */\nexport const isBudgetRejection = (status, code) => status === BUDGET_EXCEEDED_STATUS || code === BUDGET_EXCEEDED_CODE;\n/**\n * Best-effort JSON parse of an error body \u2014 `undefined` rather than a throw.\n * Shared by every caller that has to classify a rejection body before it knows\n * whether the body is JSON at all.\n *\n * @internal\n */\nexport const parseJsonOrUndefined = (text) => {\n try {\n return JSON.parse(text);\n }\n catch (_a) {\n return undefined;\n }\n};\n/**\n * Read the `code` field off an already-parsed rejection body, ignoring anything\n * that is not a string. Pairs with {@link isBudgetRejection} at the legacy call\n * sites, which have a parsed body rather than a typed frame.\n *\n * @internal\n */\nexport const codeOf = (payload) => {\n const code = payload === null || payload === void 0 ? void 0 : payload.code;\n return typeof code === 'string' ? code : undefined;\n};\n/** Narrow an unknown JSON value to a number, ignoring anything else. */\nconst numberOrUndefined = (value) => typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n/** Narrow an unknown JSON value to a boolean, ignoring anything else. */\nconst booleanOrUndefined = (value) => typeof value === 'boolean' ? value : undefined;\n/** Narrow an unknown JSON value to a non-empty string, ignoring anything else. */\nconst stringOrUndefined = (value) => typeof value === 'string' && value.trim() !== '' ? value : undefined;\n/**\n * Build a {@link BudgetExhaustedError} from a rejection payload of either shape:\n * the legacy body `{ error, code, budgetUsd, spentUsd, vendor,\n * otherVendorAvailable }` or the framed err frame's `details` (the same fields\n * minus `error`) plus its top-level `error`.\n *\n * The fields read off the wire, and why each is here:\n *\n * | field | used for |\n * | ---------------------- | ----------------------------------------------------- |\n * | `budgetUsd` | the cap in the banner's figures |\n * | `spentUsd` | the spend in the banner's figures |\n * | `error` | the proxy's human-readable detail |\n * | `vendor` | attribution when the transport's own label is unclaimed |\n * | `otherVendorAvailable` | whether \"switch vendor\" is honest advice at all |\n *\n * Tolerant by design \u2014 a `402` classifies even when the payload is missing,\n * unparseable, or carries none of these. Each field is narrowed independently,\n * so a proxy that sends `null` for a figure it does not know (which the\n * ai-service side now does, in preference to a misleading `0`) still yields the\n * vendor and the availability verdict.\n */\nexport function budgetExhaustedFrom(vendorLabel, payload, fallbackDetail) {\n var _a, _b, _c, _d;\n const body = (typeof payload === 'object' && payload !== null ? payload : {});\n // The framed shape nests everything but `error` under `details`; the legacy\n // body has it all at the top level. Read both so one helper serves both call\n // sites.\n const details = (typeof body.details === 'object' && body.details !== null ? body.details : {});\n const detail = typeof body.error === 'string' ? body.error : fallbackDetail;\n return new BudgetExhaustedError(vendorLabel, (_a = numberOrUndefined(body.budgetUsd)) !== null && _a !== void 0 ? _a : numberOrUndefined(details.budgetUsd), (_b = numberOrUndefined(body.spentUsd)) !== null && _b !== void 0 ? _b : numberOrUndefined(details.spentUsd), detail, {\n otherVendorAvailable: (_c = booleanOrUndefined(body.otherVendorAvailable)) !== null && _c !== void 0 ? _c : booleanOrUndefined(details.otherVendorAvailable),\n serverVendor: (_d = stringOrUndefined(body.vendor)) !== null && _d !== void 0 ? _d : stringOrUndefined(details.vendor),\n });\n}\n", "/** @beta */\nexport const SUPPORTED_GEMINI_MODEL_IDS = [\n 'gemini-2.5-pro',\n 'gemini-2.5-flash',\n 'gemini-2.5-flash-lite',\n 'gemini-3.5-flash',\n 'gemini-3.1-flash-lite',\n 'gemini-3.1-pro-preview',\n];\n/** @beta */\nexport const SUPPORTED_ANTHROPIC_MODEL_IDS = [\n 'claude-fable-5',\n 'claude-opus-4-8',\n 'claude-opus-4-7',\n 'claude-sonnet-5',\n 'claude-sonnet-4-6',\n 'claude-haiku-4-5-20251001',\n];\n", "/**\n * Normalized-temperature anchor. Values at or below it scale into\n * `[0, providerDefault]`; values above it scale into `[providerDefault, providerMax]`.\n * So a normalized `0.5` maps to each provider's own default temperature.\n */\nconst DEFAULT_ANCHOR = 0.5;\n/**\n * Translate a provider-agnostic, normalized temperature into a provider's\n * native range, anchored on the provider's own default so the normalized scale\n * means the same thing everywhere:\n *\n * - `0` \u2192 `0` (fully deterministic),\n * - `0.5` \u2192 the provider's default temperature,\n * - `1` \u2192 the provider's maximum.\n *\n * Values between the anchors interpolate linearly within each half, so `< 0.5`\n * is \"more focused than default\" and `> 0.5` is \"more random than default\" on\n * every provider \u2014 even though the providers' native ranges differ (Anthropic\n * default/max `1`/`1`, Gemini `1`/`2`). Where a provider's default equals its\n * max (Anthropic), the upper half is flat: it cannot go hotter than its default.\n *\n * The input is clamped to `[0, 1]` before scaling, so an out-of-range value can\n * never produce a native temperature the provider would reject.\n */\nexport function scaleTemperature(normalized, { defaultTemp, maxTemp }) {\n const t = Math.min(Math.max(normalized, 0), 1);\n return t <= DEFAULT_ANCHOR\n ? (t / DEFAULT_ANCHOR) * defaultTemp\n : defaultTemp + ((t - DEFAULT_ANCHOR) / (1 - DEFAULT_ANCHOR)) * (maxTemp - defaultTemp);\n}\n/**\n * Provider-agnostic, normalized sampling-temperature presets in `0`\u2013`1` space \u2014\n * named handles for the values most callers actually want, so intent reads\n * better than a bare magnitude. Each maps through `scaleTemperature` to the\n * active provider's native range, so the same preset means the same intent\n * whichever provider services the turn:\n *\n * - `ChatTemperature.Deterministic` (`0`) \u2014 greedy/argmax sampling.\n * - `ChatTemperature.Focused` (`0.25`) \u2014 low but not greedy; precise tool calls\n * and extraction work where you still want a little slack.\n * - `ChatTemperature.Balanced` (`0.5`) \u2014 the provider's own default.\n * - `ChatTemperature.Creative` (`0.75`) \u2014 hotter than default, short of the ceiling.\n * - `ChatTemperature.Maximum` (`1`) \u2014 the hottest the active provider allows.\n *\n * (On a provider whose default equals its max \u2014 Anthropic \u2014 `Creative` and\n * `Maximum` coincide; see `scaleTemperature`.)\n *\n * @beta\n */\nexport const ChatTemperature = {\n Deterministic: 0,\n Focused: 0.25,\n Balanced: 0.5,\n Creative: 0.75,\n Maximum: 1,\n};\n", "/**\n * Resolve the authoritative reason behind an abort-shaped rejection.\n *\n * Chromium/Firefox reject an aborted fetch/body read with the signal's\n * `reason`, but older WebKit rejects with a generic `AbortError` \u2014 which would\n * send a transport timeout down a caller's user-cancel path. Node and jsdom\n * test environments can raise the same shape as a plain `Error` rather than a\n * `DOMException`, so both are accepted (gated on the exact abort names).\n *\n * When `error` is abort-shaped the CALLER signal wins a same-tick tie: if the\n * user hits Stop in the same tick a stall/timeout fires, their intent takes\n * precedence, so the turn still routes to the user-cancel path and keeps its\n * \"Stopped.\" marker (first-cancel-wins, matching the pre-refactor behaviour).\n * A pure timeout \u2014 caller not aborted \u2014 still yields the timeout signal's\n * tagged `TimeoutError`, which is the WebKit fix. Anything not abort-shaped\n * passes through untouched.\n */\nexport function authoritativeAbortReason(error, timeoutSignal, callerSignal) {\n const abortShaped = (error instanceof DOMException || error instanceof Error) &&\n (error.name === 'AbortError' || error.name === 'TimeoutError');\n if (!abortShaped)\n return error;\n if (callerSignal === null || callerSignal === void 0 ? void 0 : callerSignal.aborted)\n return callerSignal.reason;\n if (timeoutSignal.aborted)\n return timeoutSignal.reason;\n return error;\n}\n", "/**\n * A `setTimeout`-based delay that rejects as soon as `signal` aborts, with the\n * signal's reason \u2014 so retry backoffs unwind immediately on a caller cancel or\n * dispose instead of waiting out the full wait. Resolves normally when `ms`\n * elapses first (the abort listener is detached, so a long-lived signal reused\n * across many delays does not accumulate dead listeners).\n */\nexport function abortableDelay(ms, signal) {\n return new Promise((resolve, reject) => {\n const abortReason = () => { var _a; return (_a = signal === null || signal === void 0 ? void 0 : signal.reason) !== null && _a !== void 0 ? _a : new DOMException('The operation was aborted.', 'AbortError'); };\n if (signal === null || signal === void 0 ? void 0 : signal.aborted) {\n reject(abortReason());\n return;\n }\n const onAbort = () => {\n clearTimeout(timer);\n reject(abortReason());\n };\n const timer = setTimeout(() => {\n signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', onAbort, { once: true });\n });\n}\n", "/**\n * Shared reader for the ai-service proxy's NDJSON heartbeat protocol (v1),\n * used by the server-proxied transports (Anthropic, Gemini). The proxy streams\n * `ping` frames while the upstream call runs and ends the body with exactly one\n * terminal `ok`/`err` frame, one JSON object per LF-terminated line.\n */\nimport { __awaiter } from \"tslib\";\n/** Cap on how much of a malformed proxy frame is quoted in the error message. */\nconst MALFORMED_FRAME_PREVIEW_CHARS = 120;\n/**\n * Read an NDJSON heartbeat body to its terminal frame. Buffers partial lines\n * across chunks, tolerates blank lines, and skips unknown frame types \u2014 pings\n * matter only as activity, which `onChunk` reports to the caller's stall\n * timer. An abort (stall timer or caller signal) rejects the pending `read()`\n * with the abort reason, which propagates to the caller's finally cleanup.\n * `vendorLabel` (e.g. `'Anthropic'`) prefixes the protocol-violation messages.\n *\n * `stallTimeout` (ms) arms a client-side backstop: the proxy's own pings re-arm\n * the caller's inactivity timer, so a proxy whose upstream has wedged but which\n * keeps pinging would never trip it. Each ping stamps `sinceLastEventMs` (time\n * since the last upstream event); when that exceeds `stallTimeout` we treat it\n * as a stall and throw the tagged `TimeoutError`, independent of the proxy\n * noticing its own stall. `<= 0` disables the backstop (inactivity detection off).\n */\nexport function readFramedBody(stream, onChunk, vendorLabel, stallTimeout) {\n return __awaiter(this, void 0, void 0, function* () {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n const malformedFrame = (line) => new Error(`${vendorLabel} proxy sent a malformed frame: ${line.slice(0, MALFORMED_FRAME_PREVIEW_CHARS)}`);\n const parseLine = (line) => {\n if (!line)\n return undefined;\n let parsed;\n try {\n parsed = JSON.parse(line);\n }\n catch (_a) {\n throw malformedFrame(line);\n }\n // JSON.parse also accepts null/scalars/arrays \u2014 a frame must be an object\n // (dereferencing `.t` on null would otherwise throw a raw TypeError).\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw malformedFrame(line);\n }\n const frame = parsed;\n if (frame.t === 'ok') {\n if (frame.body == null) {\n throw new Error(`${vendorLabel} proxy sent an ok frame without a body`);\n }\n return frame;\n }\n if (frame.t === 'err') {\n // The cast below promises a numeric status; hold the proxy to it rather\n // than letting `undefined` leak into the retry/status checks downstream.\n if (typeof frame.status !== 'number') {\n throw new Error(`${vendorLabel} proxy sent an err frame without a numeric status`);\n }\n return frame;\n }\n if (frame.t === 'ping') {\n // Client-side stall backstop: the proxy stamps how long its upstream has\n // been silent. Its pings keep the caller's inactivity timer alive, so\n // this is the only signal that catches a wedged upstream behind a proxy\n // that is itself still healthy. Surface the same tagged TimeoutError a\n // local inactivity fire would.\n if (stallTimeout > 0 &&\n typeof frame.sinceLastEventMs === 'number' &&\n frame.sinceLastEventMs > stallTimeout) {\n throw new DOMException(`${vendorLabel} request stalled: proxy reported ${frame.sinceLastEventMs}ms since the last upstream event (exceeds ${stallTimeout}ms)`, 'TimeoutError');\n }\n return undefined;\n }\n return undefined; // unknown frame types (forward compat)\n };\n try {\n for (;;) {\n // oxlint-disable-next-line no-await-in-loop -- sequential stream reads\n const { done, value } = yield reader.read();\n if (done)\n break;\n onChunk();\n buffer += decoder.decode(value, { stream: true });\n let newline = buffer.indexOf('\\n');\n while (newline !== -1) {\n const line = buffer.slice(0, newline).trim();\n buffer = buffer.slice(newline + 1);\n const frame = parseLine(line);\n if (frame)\n return frame;\n newline = buffer.indexOf('\\n');\n }\n }\n // Tolerate a final terminal frame missing its LF.\n const frame = parseLine((buffer + decoder.decode()).trim());\n if (frame)\n return frame;\n throw new Error(`${vendorLabel} proxy stream ended without a terminal frame`);\n }\n finally {\n // Stop the stream on early return, error, or abort; cancel rejects on an\n // already-errored stream, which is fine to ignore.\n void reader.cancel().catch(() => { });\n }\n });\n}\n", "import { __awaiter } from \"tslib\";\nimport { authoritativeAbortReason } from '../utils/abort-reason';\nimport { abortableDelay } from '../utils/abortable-delay';\nimport { combineSignals } from '../utils/combine-signals';\nimport { logger } from '../utils/logger';\nimport { budgetExhaustedFrom, codeOf, isBudgetRejection, parseJsonOrUndefined, } from './budget-exhausted-error';\nimport { readFramedBody } from './ndjson-frames';\nconst MAX_RETRIES = 5;\n/**\n * POST with the shared retry ladder, wall-clock timeout, framed-mode stall\n * detection and abort-reason preservation. Returns the terminal `ok` frame body\n * (framed proxy) or the parsed JSON (legacy proxy / direct API) as `unknown` \u2014\n * the caller casts. Throws a tagged `TimeoutError` on a stall (local inactivity,\n * the proxy's `sinceLastEventMs` backstop, or an `UPSTREAM_STALLED` frame), the\n * caller's reason on a caller abort, or a plain `Error` otherwise.\n */\nexport function postWithRetry(options) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a, _b, _c, _d, _e, _f, _g;\n const { url, headers, body, credentials, vendorLabel, retryableStatuses, timeout, stallTimeout, backoffBaseMs, signal, } = options;\n // Exponential backoff between retries: base, 2\u00D7, 4\u00D7, 8\u00D7, 16\u00D7. Abortable on the\n // CALLER signal only \u2014 the timeout is cleared before each backoff, so a caller\n // cancel mid-wait unwinds immediately while a timeout does not.\n const backoff = (attempt) => abortableDelay(backoffBaseMs * (1 << attempt), signal);\n // Sequential retries are intentional \u2014 each attempt depends on the previous response.\n /* oxlint-disable no-await-in-loop -- intentional sequential retries with backoff */\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt += 1) {\n const timeoutController = new AbortController();\n // Which phase the request reached before the clock fired. A bare \"timed out\"\n // cannot distinguish \"the service never answered at all\" from \"it answered,\n // then produced no body\" \u2014 and those have completely different owners\n // (network/gateway vs the service itself). `fetch` resolves on HEADERS, so\n // the phase is knowable here and is the single most useful fact when the\n // only evidence available is a client-side log.\n // `performance.now()` (monotonic), not `Date.now()`: an NTP step or suspend/resume mid-request\n // would otherwise land a nonsense duration in the very message someone is reading to diagnose\n // a hang. Only differences are used, so the arbitrary time origin is irrelevant.\n const startedAt = performance.now();\n let headersAt;\n let responseCtype;\n const timedOutMessage = () => {\n const waited = Math.round(performance.now() - startedAt);\n if (headersAt === undefined) {\n return `${vendorLabel} request timed out after ${waited}ms \u2014 no response headers (the service never answered; nothing was received to stall on)`;\n }\n return `${vendorLabel} request timed out after ${waited}ms \u2014 headers arrived in ${Math.round(headersAt - startedAt)}ms (content-type: ${responseCtype !== null && responseCtype !== void 0 ? responseCtype : 'unknown'}) but no body followed`;\n };\n // Wall clock for connect/headers (and the whole body on the legacy JSON\n // path). The framed path swaps it for the inactivity timer below once the\n // heartbeat body starts streaming.\n let timeoutId = setTimeout(() => timeoutController.abort(new DOMException(timedOutMessage(), 'TimeoutError')), timeout);\n // Re-armed on every received chunk. With proxy pings every 5s it only fires\n // when the proxy/network actually dies \u2014 a framed body that keeps streaming\n // has no wall cap (max_tokens bounds generation; the proxy watches upstream).\n // A non-positive stallTimeout disables inactivity detection: leave the wall\n // clock armed as the only cap (and the sinceLastEventMs backstop stays off).\n const rearmStallTimer = () => {\n if (stallTimeout <= 0)\n return;\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => timeoutController.abort(new DOMException(`${vendorLabel} request stalled (no data for ${stallTimeout}ms)`, 'TimeoutError')), stallTimeout);\n };\n // Combine so BOTH the local timeout and an optional caller signal can abort\n // the fetch. A plain `signal ?? timeoutController.signal` would silently\n // disarm the timeout whenever a caller signal was supplied. The tagged\n // `TimeoutError` lets callers distinguish a timeout from a caller-initiated\n // cancellation by inspecting the abort reason.\n const { signal: combinedSignal, dispose } = combineSignals([signal, timeoutController.signal]);\n // The finally guards the WHOLE attempt \u2014 body reads included. Disarming on\n // headers alone left `response.json()` with no deadline and no caller abort.\n try {\n const response = yield fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: combinedSignal,\n credentials,\n });\n // Headers are in \u2014 record the phase so a later timeout can say so. Cheap and\n // unconditional: the value is only read when the clock actually fires.\n headersAt = performance.now();\n // Defensive: `headers` is optional on the Response-likes callers and tests supply, and a\n // diagnostic must never be the thing that breaks the request it is describing.\n responseCtype = (_c = (_b = (_a = response.headers) === null || _a === void 0 ? void 0 : _a.get) === null || _b === void 0 ? void 0 : _b.call(_a, 'content-type')) !== null && _c !== void 0 ? _c : undefined;\n if (!response.ok) {\n // One read of the error body per failing attempt \u2014 it feeds BOTH the\n // budget classification and the thrown message, and the response is\n // discarded either way. Note this means a retryable attempt now reads\n // the (small, proxy-authored) error body before backing off. That is the\n // price of the classification winning over the ladder in this branch as\n // well as the framed one; the attempt's wall-clock timer is still armed\n // and the read runs on the fetch's combined signal, so a pathological\n // non-terminating body times out rather than hanging.\n //\n // That timeout is a real behaviour change for a RETRYABLE status, and the\n // accepted cost of the symmetry: a 503 used to reach the ladder without\n // the body being touched, so a non-terminating one still backed off and\n // retried. Now the abort propagates out of `postWithRetry` instead.\n // Acceptable because these bodies are proxy-authored and small \u2014 if that\n // ever stops being true, read the body only when the status is\n // non-retryable or already budget-shaped.\n const errText = yield response.text();\n const parsed = parseJsonOrUndefined(errText);\n // The budget wall (GENC-1464) wins over ANY status-based retry \u2014 the same\n // rule the framed branch below applies, now symmetric. It must be\n // classified BEFORE the ladder, not after it: 402 is absent from every\n // RETRYABLE_STATUSES today, but a proxy that maps the refusal onto a\n // retryable status (or a future set that includes 402) would otherwise\n // cost five doomed requests and ~31s of backoff before an opaque error \u2014\n // exactly the bug this classification exists to remove. Parsing is\n // best-effort: an unparseable or plain-text 402 still classifies, just\n // without the budget/spent figures.\n if (isBudgetRejection(response.status, codeOf(parsed))) {\n throw budgetExhaustedFrom(vendorLabel, parsed, errText || undefined);\n }\n if (retryableStatuses.includes(response.status) && attempt < MAX_RETRIES) {\n logger.warn(`${vendorLabel}Transport: retryable status ${response.status}, retrying (attempt ${attempt + 1}/${MAX_RETRIES})`);\n clearTimeout(timeoutId); // this attempt is over \u2014 don't let its timer tick through the backoff\n yield backoff(attempt);\n continue;\n }\n throw new Error(`${vendorLabel} request error ${response.status}: ${errText}`);\n }\n // The proxy streams NDJSON heartbeat frames when it supports them; an old\n // proxy ignores our Accept header and returns plain JSON, so branch on\n // what actually came back.\n if (((_e = (_d = response.headers) === null || _d === void 0 ? void 0 : _d.get('content-type')) === null || _e === void 0 ? void 0 : _e.toLowerCase().includes('application/x-ndjson')) &&\n response.body) {\n rearmStallTimer();\n const frame = yield readFramedBody(response.body, rearmStallTimer, vendorLabel, stallTimeout);\n if (frame.t === 'ok')\n return frame.body;\n // Classify a stall by `code` BEFORE the retryable-status ladder: a stall\n // paired with a retryable status must surface as the non-retried\n // TimeoutError, not get retried 5\u00D7 as that status.\n if (frame.code === 'UPSTREAM_STALLED') {\n // The proxy watchdog saw no upstream data \u2014 same tagged shape as a\n // local stall, so the driver's TimeoutError branch handles both.\n throw new DOMException(`${vendorLabel} request stalled: ${(_f = frame.error) !== null && _f !== void 0 ? _f : 'no upstream data'}`, 'TimeoutError');\n }\n // The budget wall, framed (GENC-1464) \u2014 the in-band twin of the 402 above,\n // through the same predicate, keyed on status OR code. Classified before\n // the retryable ladder for the same reason UPSTREAM_STALLED is: the\n // classification must win over any status-based retry. That ordering is\n // no longer unique to this branch \u2014 the legacy branch above now applies\n // the identical rule, so the two read as one policy rather than two.\n if (isBudgetRejection(frame.status, frame.code)) {\n throw budgetExhaustedFrom(vendorLabel, frame);\n }\n // An in-band retryable status joins the same attempt/backoff ladder as\n // its HTTP-status equivalent (shared attempt counter).\n if (retryableStatuses.includes(frame.status) && attempt < MAX_RETRIES) {\n logger.warn(`${vendorLabel}Transport: retryable status ${frame.status} (err frame), retrying (attempt ${attempt + 1}/${MAX_RETRIES})`);\n clearTimeout(timeoutId); // disarm the stall timer \u2014 the stream is done, only the backoff remains\n yield backoff(attempt);\n continue;\n }\n throw new Error(`${vendorLabel} request error ${frame.status}: ${(_g = frame.error) !== null && _g !== void 0 ? _g : JSON.stringify(frame.details)}`);\n }\n return (yield response.json());\n }\n catch (e) {\n // Some engines reject an aborted read with a generic AbortError instead of\n // the signal's reason \u2014 rethrow the authoritative one so a timeout stays a\n // tagged TimeoutError rather than looking like a user cancel.\n throw authoritativeAbortReason(e, timeoutController.signal, signal);\n }\n finally {\n clearTimeout(timeoutId);\n dispose();\n }\n }\n /* oxlint-enable no-await-in-loop */\n throw new Error(`${vendorLabel} request failed: max retries exceeded`);\n });\n}\n", "import { __awaiter } from \"tslib\";\nimport { SUPPORTED_ANTHROPIC_MODEL_IDS, } from '../types';\nimport { logger } from '../utils/logger';\nimport { scaleTemperature } from '../utils/temperature';\nimport { VENDOR_LABELS } from './budget-exhausted-error';\nimport { postWithRetry } from './post-with-retry';\nconst ANTHROPIC_DIRECT_URL = 'https://api.anthropic.com/v1/messages';\nconst ANTHROPIC_API_VERSION = '2023-06-01';\nconst DEFAULT_MODEL = 'claude-haiku-4-5-20251001';\nconst DEFAULT_TIMEOUT = 300000; // healthy >200s generations observed at 128k max_tokens; wall clock is a last resort\nconst DEFAULT_STALL_TIMEOUT = 30000; // inactivity window on the framed proxy path; pings arrive every 5s\nconst DEFAULT_MAX_TOKENS = 4096;\n/** Anthropic's native default + ceiling temperature \u2014 https://docs.claude.com/en/api/messages */\nconst ANTHROPIC_DEFAULT_TEMPERATURE = 1;\nconst ANTHROPIC_MAX_TEMPERATURE = 1;\n/**\n * Map a provider-agnostic {@link ChatToolChoice} to Anthropic's `tool_choice`.\n * Returns undefined for the default (`'auto'`) so the request omits the field.\n */\nfunction toAnthropicToolChoice(choice) {\n if (!choice || choice === 'auto')\n return undefined;\n if (choice === 'required')\n return { type: 'any' };\n if (choice === 'none')\n return { type: 'none' };\n return { type: 'tool', name: choice.tool };\n}\n/**\n * Maximum input context window (tokens) per supported Claude model.\n * Source: https://docs.claude.com/en/docs/about-claude/models/overview\n */\nconst ANTHROPIC_CONTEXT_LIMITS = {\n 'claude-fable-5': 1000000,\n 'claude-opus-4-8': 1000000,\n 'claude-opus-4-7': 1000000,\n 'claude-sonnet-5': 1000000,\n 'claude-sonnet-4-6': 1000000,\n 'claude-haiku-4-5-20251001': 200000,\n};\n/**\n * Tool name used to coerce JSON-schema output from the model when the caller\n * provided a `responseSchema`. The transport forces `tool_choice` to this tool\n * and surfaces the `input` field as the structured response.\n */\nconst STRUCTURED_OUTPUT_TOOL_NAME = 'emit_structured_response';\n/** Beta flag enabling the server-side `fallbacks` request parameter (refusal rescue). */\nconst SERVER_SIDE_FALLBACK_BETA = 'server-side-fallback-2026-06-01';\nfunction assertSupportedAnthropicModel(model) {\n if (!SUPPORTED_ANTHROPIC_MODEL_IDS.includes(model)) {\n throw new Error(`AnthropicTransport: unsupported model \"${model}\". Use one of: ${SUPPORTED_ANTHROPIC_MODEL_IDS.join(', ')}.`);\n }\n}\n/**\n * Standard tier pricing per million tokens \u2014 https://docs.claude.com/en/docs/about-claude/pricing\n */\nfunction estimatedAnthropicRatesUsdPerMillion(model) {\n if (model === 'claude-haiku-4-5-20251001') {\n return { promptPerMillion: 1, candidatePerMillion: 5 };\n }\n // Fable 5 \u2014 Anthropic's most capable widely-released model; priced above Opus tier.\n if (model === 'claude-fable-5') {\n return { promptPerMillion: 10, candidatePerMillion: 50 };\n }\n // Sonnet 5 and Sonnet 4.6 share the standard Sonnet tier ($3 / $15 per MTok). Sonnet 5's\n // introductory rate ($2 / $10 through 2026-08-31) is deliberately NOT used here \u2014 standard rates.\n if (model === 'claude-sonnet-5' || model === 'claude-sonnet-4-6') {\n return { promptPerMillion: 3, candidatePerMillion: 15 };\n }\n // Opus 4.7 / 4.8 \u2014 same $5 / $25 per MTok.\n return { promptPerMillion: 5, candidatePerMillion: 25 };\n}\n/**\n * Models that reject non-default sampling parameters (`temperature`/`top_p`/`top_k`) with a 400 \u2014\n * the Opus 4.7+ / Sonnet 5 / Fable 5 generation. Sonnet 4.6 and Haiku 4.5 still accept them.\n */\nfunction rejectsSamplingParams(model) {\n return (model === 'claude-fable-5' ||\n model === 'claude-opus-4-8' ||\n model === 'claude-opus-4-7' ||\n model === 'claude-sonnet-5');\n}\n/**\n * Whether the model enforces structured output natively via decode-time `output_config.format`\n * (json_schema). True for Fable 5, Opus 4.8, Sonnet 5, and Haiku 4.5; false for Opus 4.7 and\n * Sonnet 4.6, which fall back to the forced-tool approach on the one-shot path. `output_config`\n * composes with a live `tools` array, so no tool-vs-schema gating is needed on this provider.\n */\nfunction supportsNativeStructuredOutput(model) {\n return (model === 'claude-fable-5' ||\n model === 'claude-opus-4-8' ||\n model === 'claude-sonnet-5' ||\n model === 'claude-haiku-4-5-20251001');\n}\n/**\n * Extended-thinking posture for a request. Sonnet 5 and Fable 5 run adaptive thinking with\n * `display:'summarized'` \u2014 regardless of `tool_choice`. First-party has no forced-tool-vs-thinking\n * restriction (that's Bedrock-only), and \"adaptive\" self-regulates (the model thinks little on\n * trivial/mechanical turns on its own), so there is no reason to special-case forced tool calls.\n * `display:'summarized'` means the reasoning summary is always returned (billed regardless; the\n * host's toggle decides visibility).\n *\n * Fable 5 runs thinking *unconditionally* (it cannot be disabled \u2014 an explicit\n * `{type:'disabled'}` is a 400), so it must never be sent `disabled`; `{type:'adaptive'}`\n * is the accepted posture and is what we return.\n *\n * Every other model (Opus 4.8/4.7, Sonnet 4.6, Haiku) returns undefined \u2192 `thinking` is omitted\n * \u2192 it runs WITHOUT thinking on the chat path (Opus 4.8 adaptive thinking is opt-in). So the older\n * \"forced tool + thinking is incompatible\" restriction never applies to them (you can't hit it when\n * thinking is off). If thinking is ever enabled for one of those, revisit the forced-tool\n * interaction for that model then.\n */\nfunction anthropicThinking(model) {\n if (model !== 'claude-sonnet-5' && model !== 'claude-fable-5')\n return undefined;\n return { type: 'adaptive', display: 'summarized' };\n}\n/**\n * Prompt-cache pricing multipliers, applied to the model's base input rate\n * (`promptPerMillion`) \u2014 https://docs.claude.com/en/docs/build-with-claude/prompt-caching\n * Reads bill at ~0.1\u00D7 base input; writes bill by TTL \u2014 5-minute at ~1.25\u00D7 and 1-hour at 2\u00D7.\n * Both write TTLs are reachable (`CachePolicy.ttl` is `'5m' | '1h'` and `applyCacheControl`\n * emits either), so the cost path costs each TTL bucket from the response's per-TTL\n * `cache_creation` breakdown rather than assuming a single rate.\n */\nconst ANTHROPIC_CACHE_READ_MULTIPLIER = 0.1;\nconst ANTHROPIC_CACHE_WRITE_5M_MULTIPLIER = 1.25;\nconst ANTHROPIC_CACHE_WRITE_1H_MULTIPLIER = 2;\n/**\n * Thrown when a response was cut off at the output-token limit (Anthropic\n * `stop_reason: 'max_tokens'`, Gemini `finishReason: 'MAX_TOKENS'`) in a way\n * that leaves nothing safe to keep. Both transports raise it when the truncated\n * turn carries tool calls: the model ran out of its output-token budget\n * mid-stream, so the cut-off call's arguments are incomplete or untrustworthy\n * (e.g. a `vfs_write` whose `content` never finished serializing) \u2014 rather than\n * hand a corrupt tool call to the caller, which silently runs with missing args\n * and tends to be retried into an identical wall, the failure is loud and\n * diagnosable. The Gemini transport also raises it when truncation leaves no\n * usable answer text (a blank or thinking-only response), which would otherwise\n * be misclassified \u2014 and pointlessly retried \u2014 as an \"empty\" response.\n *\n * It is deterministic: re-issuing the same request hits the same cap. The remedy\n * is to raise the provider's `maxTokens` where configurable (see\n * {@link AnthropicAIConfig.maxTokens}) or to split the work into smaller\n * outputs \u2014 not to retry verbatim.\n *\n * Shared by both transports; it lives here with the transport that introduced it.\n *\n * @beta\n */\nexport class ResponseTruncatedError extends Error {\n constructor(\n /** The model that produced the truncated response. */\n model, \n /**\n * The `max_tokens` cap the request was sent with, when the transport sends\n * one (Anthropic). Undefined when no explicit cap was requested and the\n * model's own output-token limit applied instead (Gemini).\n */\n maxTokens, \n /** Output tokens generated before truncation, when the usage block is present. */\n outputTokens, \n /** Names of the tool call(s) on the truncated turn (the last is the cut-off one). */\n toolNames) {\n super(`Response truncated at ${maxTokens != null ? `the max_tokens cap (${maxTokens})` : \"the model's output-token limit\"} for model ${model}` +\n (toolNames.length > 0 ? ` while emitting tool call(s): ${toolNames.join(', ')}` : '') +\n '. The output exceeds the per-response limit \u2014 raise the provider maxTokens (where configurable) or split the work into smaller outputs.');\n this.model = model;\n this.maxTokens = maxTokens;\n this.outputTokens = outputTokens;\n this.toolNames = toolNames;\n this.name = 'ResponseTruncatedError';\n }\n}\n/**\n * Transport for Anthropic Claude. Calls the Messages API directly when `apiKey`\n * is provided, otherwise falls back to a server-proxy endpoint (if `serverEndpoint`\n * is configured).\n *\n * Implements `AITransport` (structured prompt via tool-forcing) and `ChatTransport`\n * (multi-turn chat).\n *\n * @beta\n */\nexport class AnthropicTransport {\n constructor(config = {}) {\n var _a, _b, _c, _d;\n /**\n * Estimated USD cost accumulated across every successful request on this\n * transport instance. Convenience accessor for non-chat consumers\n * (telemetry, debug overlays). The main chat UI sums per-message `cost`\n * fields instead so its session total stays attributed to chat turns only.\n */\n this.lifetimeCostUsd = 0;\n /**\n * Estimated USD saved by prompt caching vs paying full input price, accumulated across\n * every request. Net of cache-write premiums, so it can be briefly negative before reads\n * accrue. Surfaced alongside `getLifetimeCost`.\n */\n this.lifetimeSavingsUsd = 0;\n const model = (_a = config.model) !== null && _a !== void 0 ? _a : DEFAULT_MODEL;\n assertSupportedAnthropicModel(model);\n this.model = model;\n if (model === 'claude-sonnet-5') {\n logger.warn('AnthropicTransport: using claude-sonnet-5 \u2014 standard Sonnet tier, higher cost than Haiku, and adaptive thinking runs by default so reasoning tokens add to output cost. Use for stronger reasoning or agent tasks.');\n }\n else if (model === 'claude-sonnet-4-6') {\n logger.warn('AnthropicTransport: using claude-sonnet-4-6 \u2014 higher cost than Haiku; use for stronger reasoning or agent tasks.');\n }\n else if (model === 'claude-opus-4-7' || model === 'claude-opus-4-8') {\n logger.warn(`AnthropicTransport: using ${model} \u2014 significantly higher cost; reserve for tasks where Sonnet reliability is insufficient.`);\n }\n else if (model === 'claude-fable-5') {\n logger.warn('AnthropicTransport: using claude-fable-5 \u2014 Anthropic\\'s most capable model, priced above Opus tier ($10 / $50 per MTok) with thinking always on. Reserve for the hardest reasoning/long-horizon work. Requires \u226530-day data retention (unavailable under ZDR) and may return stop_reason \"refusal\"; pair with an Opus 4.8 fallback.');\n }\n this.timeout = (_b = config.timeout) !== null && _b !== void 0 ? _b : DEFAULT_TIMEOUT;\n this.stallTimeout = (_c = config.stallTimeout) !== null && _c !== void 0 ? _c : DEFAULT_STALL_TIMEOUT;\n this.apiKey = config.apiKey;\n this.serverEndpoint = config.serverEndpoint;\n this.maxTokens = (_d = config.maxTokens) !== null && _d !== void 0 ? _d : DEFAULT_MAX_TOKENS;\n }\n getConfig() {\n return {\n provider: 'anthropic',\n model: this.model,\n contextLimit: ANTHROPIC_CONTEXT_LIMITS[this.model],\n };\n }\n /** Estimated USD cost accumulated across every successful request on this transport instance. */\n getLifetimeCost() {\n return this.lifetimeCostUsd;\n }\n /** Estimated USD saved by prompt caching (net of write premiums) across this instance. */\n getLifetimeSavings() {\n return this.lifetimeSavingsUsd;\n }\n /** Reset the lifetime cost + savings counters. Intended for chat-clear / new-session flows. */\n resetLifetimeCost() {\n this.lifetimeCostUsd = 0;\n this.lifetimeSavingsUsd = 0;\n }\n // \u2500\u2500 AITransport (structured prompt) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n sendStructuredPrompt(options) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a, _b, _c;\n const { systemPrompt, userPrompt, responseSchema } = options;\n const messages = [{ role: 'user', content: userPrompt }];\n const body = {\n model: this.model,\n max_tokens: this.maxTokens,\n messages,\n };\n if (systemPrompt)\n body.system = systemPrompt;\n // Prefer native decode-time enforcement (`output_config.format`) where the model supports it \u2014\n // the answer comes back as ordinary text conforming to the schema. On models without native\n // support (Opus 4.7, Sonnet 4.6), fall back to the legacy pattern: a tool whose `input_schema`\n // is the schema, forced via `tool_choice`, with the structured payload read from its `tool_use`.\n const useNative = responseSchema != null && supportsNativeStructuredOutput(this.model);\n const useForcedTool = responseSchema != null && !useNative;\n if (useNative) {\n body.output_config = {\n format: { type: 'json_schema', schema: responseSchema },\n };\n }\n else if (useForcedTool) {\n body.tools = [\n {\n name: STRUCTURED_OUTPUT_TOOL_NAME,\n description: 'Emit the structured response that matches the required schema.',\n input_schema: responseSchema,\n },\n ];\n body.tool_choice = { type: 'tool', name: STRUCTURED_OUTPUT_TOOL_NAME };\n }\n // Sonnet 5 runs adaptive thinking by default; disable it for one-shot prompts \u2014 the reasoning\n // would be billed but discarded. Fable 5 runs thinking unconditionally (cannot be disabled \u2014 a\n // 400), so it is left on; its summary is simply unused here.\n if (this.model === 'claude-sonnet-5')\n body.thinking = { type: 'disabled' };\n const response = yield this.post(body);\n if (useForcedTool) {\n const toolUse = ((_a = response.content) !== null && _a !== void 0 ? _a : []).find((b) => b.type === 'tool_use' && b.name === STRUCTURED_OUTPUT_TOOL_NAME);\n return toolUse ? JSON.stringify((_b = toolUse.input) !== null && _b !== void 0 ? _b : {}) : '';\n }\n // Native structured output and plain prompts both return the answer as text.\n return ((_c = response.content) !== null && _c !== void 0 ? _c : [])\n .filter((b) => b.type === 'text')\n .map((b) => b.text)\n .join('');\n });\n }\n // \u2500\u2500 ChatTransport (multi-turn chat) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n sendChatMessage(history, userMessage, options) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a, _b, _c;\n const messages = this.toAnthropicMessages(history, userMessage, options === null || options === void 0 ? void 0 : options.attachments);\n const body = {\n model: this.model,\n max_tokens: this.maxTokens,\n messages,\n };\n if (options === null || options === void 0 ? void 0 : options.systemPrompt)\n body.system = options.systemPrompt;\n if ((_a = options === null || options === void 0 ? void 0 : options.tools) === null || _a === void 0 ? void 0 : _a.length) {\n body.tools = options.tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.parameters,\n }));\n }\n // Map the requested tool-call mode to Anthropic's tool_choice \u2014 only\n // meaningful when tools exist. `'required'`/`{ tool }` force a tool call so\n // a turn can only end via one (e.g. a sub-agent's completion tool).\n if ((_b = body.tools) === null || _b === void 0 ? void 0 : _b.length) {\n const toolChoice = toAnthropicToolChoice(options === null || options === void 0 ? void 0 : options.toolChoice);\n if (toolChoice)\n body.tool_choice = toolChoice;\n }\n // Extended thinking (Sonnet 5). Always adaptive regardless of `tool_choice` \u2014 first-party has\n // no forced-tool-vs-thinking restriction (that's Bedrock-only) and adaptive self-regulates on\n // mechanical turns. Older models omit it (see `anthropicThinking`).\n const thinking = anthropicThinking(this.model);\n if (thinking)\n body.thinking = thinking;\n // Normalized [0,1] temperature \u2192 Anthropic's native range, anchored so 0.5 maps to its default.\n // (Default == max here, so the upper half is flat.) Skipped on models that reject sampling\n // params (Opus 4.7+ / Sonnet 5), where sending `temperature` is a 400.\n if ((options === null || options === void 0 ? void 0 : options.temperature) != null && !rejectsSamplingParams(this.model)) {\n body.temperature = scaleTemperature(options.temperature, {\n defaultTemp: ANTHROPIC_DEFAULT_TEMPERATURE,\n maxTemp: ANTHROPIC_MAX_TEMPERATURE,\n });\n }\n // Structured output: constrain the final text answer to the caller's JSON schema via\n // decode-time `output_config.format`. Composes with a live `tools` array \u2014 the model still\n // calls tools through the turn and conforms its closing answer to the schema. Applied only on\n // models that support it natively; elsewhere the schema is dropped here (the caller keeps a\n // prompt-instruction + validator fallback). No beta header needed.\n if ((options === null || options === void 0 ? void 0 : options.responseSchema) && supportsNativeStructuredOutput(this.model)) {\n body.output_config = {\n format: { type: 'json_schema', schema: options.responseSchema },\n };\n }\n // Refusal fallback chain (e.g. Fable 5 \u2192 Opus 4.8). Sent as the server-side `fallbacks`\n // param; `post` adds the required beta header when this is present. A refused turn is\n // re-run on the next model in one round trip.\n if ((_c = options === null || options === void 0 ? void 0 : options.fallbacks) === null || _c === void 0 ? void 0 : _c.length) {\n body.fallbacks = options.fallbacks.map((f) => f.maxTokens != null ? { model: f.model, max_tokens: f.maxTokens } : { model: f.model });\n }\n // Place prompt-cache breakpoints per the resolved policy (no-op for `'default'`/absent).\n if (options === null || options === void 0 ? void 0 : options.cachePolicy) {\n this.applyCacheControl(body, options.cachePolicy);\n }\n // Inject never-stored tail context AFTER the cache breakpoints, so this per-turn volatile\n // block stays outside the cached prefix. The caller has already framed it.\n if (options === null || options === void 0 ? void 0 : options.tailContext) {\n this.appendTailContext(body, options.tailContext);\n }\n const response = yield this.post(body, options === null || options === void 0 ? void 0 : options.signal);\n return this.fromAnthropicResponse(response);\n });\n }\n /**\n * Place prompt-cache breakpoints on the outgoing request per the resolved {@link CachePolicy}.\n * A breakpoint is `cache_control: {type:'ephemeral'}` on a content block / tool / system block;\n * the API caches the byte-exact prefix up to it. Below a model's minimum cacheable prefix the\n * marker is silently ignored (no error), so placing one is always safe.\n *\n * Render order is tools \u2192 system \u2192 messages, so a breakpoint's cached prefix covers everything\n * before it:\n * - `'tools'` \u2014 last tool (caches the tool block; survives a later system-prompt change).\n * - `'prompt'` \u2014 system block (caches tools + system); falls back to the last tool when there\n * is no system prompt.\n * - `'history'` \u2014 last stored message block (caches tools + system + the whole stored history),\n * keeping the system-tier breakpoint as a cheaper fallback. The injected, never-stored tail\n * context (if any) sits after this and is intentionally left uncached.\n */\n applyCacheControl(body, policy) {\n var _a, _b;\n if (policy.scope === 'default')\n return;\n const cacheControl = policy.ttl === '1h' ? { type: 'ephemeral', ttl: '1h' } : { type: 'ephemeral' };\n if (policy.scope === 'tools') {\n if ((_a = body.tools) === null || _a === void 0 ? void 0 : _a.length) {\n body.tools[body.tools.length - 1].cache_control = cacheControl;\n }\n return;\n }\n // 'prompt' and 'history' both cache through the system prompt. A breakpoint on the (single)\n // system block caches tools + system together; with no system prompt, fall back to the last\n // tool \u2014 the furthest stable prefix available.\n if (typeof body.system === 'string' && body.system.length > 0) {\n body.system = [{ type: 'text', text: body.system, cache_control: cacheControl }];\n }\n else if ((_b = body.tools) === null || _b === void 0 ? void 0 : _b.length) {\n body.tools[body.tools.length - 1].cache_control = cacheControl;\n }\n if (policy.scope === 'history') {\n const lastMessage = body.messages[body.messages.length - 1];\n if (lastMessage && Array.isArray(lastMessage.content) && lastMessage.content.length > 0) {\n lastMessage.content[lastMessage.content.length - 1].cache_control = cacheControl;\n }\n }\n }\n /**\n * Append never-stored tail context (already framed by the caller) as the final block of the\n * outbound messages. Called AFTER `applyCacheControl`, so any `'history'` breakpoint sits\n * on the last *stored* block and this per-turn volatile block stays outside the cached prefix.\n * At a model-call the last message is user-role; if not (defensive), start a fresh user turn.\n */\n appendTailContext(body, tailContext) {\n const block = { type: 'text', text: tailContext };\n const lastMessage = body.messages[body.messages.length - 1];\n if ((lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) === 'user' && Array.isArray(lastMessage.content)) {\n lastMessage.content.push(block);\n }\n else {\n body.messages.push({ role: 'user', content: [block] });\n }\n }\n /**\n * Logs the per-call cost breakdown, accumulates the lifetime running total,\n * and returns the per-call total so the caller can attach it to the response\n * message.\n */\n logTokenUsage(promptTokens, candidateTokens, cacheReadTokens, cacheCreationTokens, cacheCreation1hTokens) {\n const { promptPerMillion, candidatePerMillion } = estimatedAnthropicRatesUsdPerMillion(this.model);\n const m = AnthropicTransport.TOKENS_PER_MILLION;\n // `promptTokens` is `input_tokens` \u2014 the UNCACHED remainder, billed at the full input\n // rate. Cache reads bill at ~0.1\u00D7. Cache writes bill by TTL \u2014 5-min at ~1.25\u00D7, 1-hour at\n // 2\u00D7 \u2014 so split the creation total into its 1-hour portion (from the response breakdown)\n // and the 5-min remainder, costing each at its own rate. All buckets are off the same base\n // input rate. Summing them keeps the cost correct whether or not caching was active (all\n // cache fields are 0 when it wasn't).\n const cacheCreation5mTokens = Math.max(0, cacheCreationTokens - cacheCreation1hTokens);\n const promptCost = (promptTokens / m) * promptPerMillion;\n const cacheReadCost = (cacheReadTokens / m) * promptPerMillion * ANTHROPIC_CACHE_READ_MULTIPLIER;\n const cacheWriteCost = (cacheCreation5mTokens / m) * promptPerMillion * ANTHROPIC_CACHE_WRITE_5M_MULTIPLIER +\n (cacheCreation1hTokens / m) * promptPerMillion * ANTHROPIC_CACHE_WRITE_1H_MULTIPLIER;\n const candidateCost = (candidateTokens / m) * candidatePerMillion;\n const totalCost = promptCost + cacheReadCost + cacheWriteCost + candidateCost;\n this.lifetimeCostUsd += totalCost;\n // Net savings vs no caching: the cache-read tokens would have cost full input price\n // (we paid ~0.1\u00D7 of that), while the write premium (~0.25\u00D7 over full) is an upfront cost\n // that pays back on later reads \u2014 so the net can dip negative on a write-heavy request and\n // climb positive as reads accrue. Zero when caching was inactive.\n const cacheReadFull = (cacheReadTokens / m) * promptPerMillion;\n const cacheWriteFull = (cacheCreationTokens / m) * promptPerMillion;\n const saved = cacheReadFull - cacheReadCost + (cacheWriteFull - cacheWriteCost);\n this.lifetimeSavingsUsd += saved;\n const dp = AnthropicTransport.COST_DECIMAL_PLACES;\n console.log(`--- Anthropic Token Usage (${this.model}) ---`);\n console.log(`Prompt Tokens: ${promptTokens} ($${promptCost.toFixed(dp)})`);\n console.log(`Cache Read: ${cacheReadTokens} ($${cacheReadCost.toFixed(dp)})`);\n console.log(`Cache Write: ${cacheCreationTokens} ($${cacheWriteCost.toFixed(dp)})`);\n console.log(`Candidate Tokens: ${candidateTokens} ($${candidateCost.toFixed(dp)})`);\n console.log(`Total Cost: $${totalCost.toFixed(dp)}`);\n console.log(`Cache Saved: $${saved.toFixed(dp)} (lifetime $${this.lifetimeSavingsUsd.toFixed(dp)})`);\n console.log(`Lifetime Cost: $${this.lifetimeCostUsd.toFixed(dp)}`);\n console.log('--------------------------');\n return totalCost;\n }\n /**\n * Convert the internal `ChatMessage[]` history into Anthropic's message format.\n *\n * Anthropic alternates strictly `user` / `assistant`. Tool calls are emitted by\n * the assistant as `tool_use` blocks; the corresponding `tool_result` blocks\n * must appear in the *next* user message and reference the tool by `tool_use_id`.\n * Consecutive same-role turns are merged by the API but we merge here to keep\n * the payload tidy.\n */\n toAnthropicMessages(history, userMessage, attachments) {\n var _a, _b, _c;\n const messages = [];\n const pushBlock = (role, block) => {\n const last = messages[messages.length - 1];\n if (last && last.role === role && Array.isArray(last.content)) {\n last.content.push(block);\n return;\n }\n messages.push({ role, content: [block] });\n };\n for (const msg of history) {\n if (msg.role === 'system' ||\n msg.role === 'system-event' ||\n msg.role === 'synthetic-user' ||\n msg.role === 'compacted-summary' ||\n msg.category === 'reasoning' ||\n msg.category === 'narration' ||\n msg.thinking // legacy pre-split sessions\n )\n continue;\n if (msg.toolResult) {\n pushBlock('user', {\n type: 'tool_result',\n tool_use_id: msg.toolResult.toolCallId,\n content: msg.toolResult.content,\n });\n continue;\n }\n if ((_a = msg.toolCalls) === null || _a === void 0 ? void 0 : _a.length) {\n if (msg.content) {\n pushBlock('assistant', { type: 'text', text: msg.content });\n }\n for (const tc of msg.toolCalls) {\n pushBlock('assistant', {\n type: 'tool_use',\n id: tc.id,\n name: tc.name,\n input: (_b = tc.args) !== null && _b !== void 0 ? _b : {},\n });\n }\n continue;\n }\n const role = msg.role === 'user' ? 'user' : 'assistant';\n if (role === 'user' && ((_c = msg.attachments) === null || _c === void 0 ? void 0 : _c.length)) {\n pushBlock(role, { type: 'text', text: msg.content });\n for (const att of msg.attachments) {\n pushBlock(role, { type: 'text', text: `[File: ${att.name}]\\n${att.content}` });\n }\n }\n else if (msg.content) {\n pushBlock(role, { type: 'text', text: msg.content });\n }\n }\n if (userMessage || (attachments === null || attachments === void 0 ? void 0 : attachments.length)) {\n if (userMessage) {\n pushBlock('user', { type: 'text', text: userMessage });\n }\n for (const att of attachments !== null && attachments !== void 0 ? attachments : []) {\n pushBlock('user', { type: 'text', text: `[File: ${att.name}]\\n${att.content}` });\n }\n }\n return messages;\n }\n fromAnthropicResponse(response) {\n var _a, _b, _c, _d, _e, _f, _g, _h;\n let inputTokens;\n let outputTokens;\n let cacheReadTokens;\n let cacheWriteTokens;\n let cost;\n if (response.usage) {\n const uncachedInput = (_a = response.usage.input_tokens) !== null && _a !== void 0 ? _a : 0;\n const cacheRead = (_b = response.usage.cache_read_input_tokens) !== null && _b !== void 0 ? _b : 0;\n // 1-hour writes bill at 2\u00D7 vs 1.25\u00D7 for 5-min, so read the per-TTL breakdown when present\n // and let the cost path split the buckets. Fall back to the flat total (treated as 5-min)\n // when the breakdown is absent.\n const breakdown = response.usage.cache_creation;\n const cacheCreation1h = (_c = breakdown === null || breakdown === void 0 ? void 0 : breakdown.ephemeral_1h_input_tokens) !== null && _c !== void 0 ? _c : 0;\n const cacheCreation = (_d = response.usage.cache_creation_input_tokens) !== null && _d !== void 0 ? _d : (breakdown ? ((_e = breakdown.ephemeral_5m_input_tokens) !== null && _e !== void 0 ? _e : 0) + cacheCreation1h : 0);\n cost = this.logTokenUsage(uncachedInput, (_f = response.usage.output_tokens) !== null && _f !== void 0 ? _f : 0, cacheRead, cacheCreation, cacheCreation1h);\n // Report TOTAL prompt size (uncached + cache read + cache write) so `inputTokens` means\n // \"prompt tokens\" consistently whether or not caching was active \u2014 matching Gemini's\n // `promptTokenCount`, which already includes cached tokens. Cost (above) reflects the\n // cache discount; this field is the size, not the bill.\n inputTokens = uncachedInput + cacheRead + cacheCreation;\n // The two cache buckets BREAK DOWN the prompt total above rather than adding\n // to it, so a consumer derives uncached input by subtracting them. Reported\n // even when zero: \"this provider measured the split and it was 0\" is distinct\n // from \"this provider reports no split at all\" (undefined).\n cacheReadTokens = cacheRead;\n cacheWriteTokens = cacheCreation;\n if (response.usage.output_tokens != null) {\n outputTokens = response.usage.output_tokens;\n }\n }\n const blocks = (_g = response.content) !== null && _g !== void 0 ? _g : [];\n const toolCalls = [];\n const thoughtParts = [];\n const textParts = [];\n for (const block of blocks) {\n if (block.type === 'tool_use') {\n toolCalls.push({\n id: block.id,\n name: block.name,\n args: (_h = block.input) !== null && _h !== void 0 ? _h : {},\n });\n }\n else if (block.type === 'thinking') {\n thoughtParts.push(block.thinking);\n }\n else if (block.type === 'text') {\n textParts.push(block.text);\n }\n }\n // A `max_tokens` stop means the response was cut off mid-stream. For a turn\n // carrying tool calls this is fatal: the final tool call's argument JSON was\n // truncated before it closed, so its args are incomplete and the call cannot\n // be run. Raise rather than return a corrupt tool call (which would run with\n // missing args and get retried into the same wall). Usage/cost is already\n // logged above, so the spent tokens are still accounted for on this instance.\n if (response.stop_reason === 'max_tokens' && toolCalls.length > 0) {\n throw new ResponseTruncatedError(this.model, this.maxTokens, outputTokens, toolCalls.map((tc) => tc.name));\n }\n // Reasoning (extended-thinking summary) and answer/narration travel in separate channels:\n // `content` is the answer text, `reasoning` is the summary. The driver splits them into\n // separate category-tagged messages. (Previously `thoughtParts.join('') || textParts.join('')`\n // put reasoning in `content` and DROPPED the answer text whenever thinking was present.)\n const reasoning = thoughtParts.join('') || undefined;\n const base = toolCalls.length > 0\n ? { role: 'assistant', content: textParts.join(''), reasoning, toolCalls }\n : { role: 'assistant', content: textParts.join(''), reasoning };\n if (inputTokens != null)\n base.inputTokens = inputTokens;\n if (outputTokens != null)\n base.outputTokens = outputTokens;\n if (cacheReadTokens != null)\n base.cacheReadTokens = cacheReadTokens;\n if (cacheWriteTokens != null)\n base.cacheWriteTokens = cacheWriteTokens;\n if (cost != null)\n base.cost = cost;\n // Surface a non-standard stop reason for observability and parity with the\n // Gemini transport's `responseMeta.finishReason`. A text-only `max_tokens`\n // stop yields partial-but-legible content, so it is returned (not raised) with\n // the truncation flagged \u2014 the caller can decide what to do with it.\n if (response.stop_reason === 'max_tokens') {\n base.responseMeta = { finishReason: 'max_tokens' };\n }\n // A `refusal` stop means safety classifiers declined the request (Fable 5 and other\n // recent models). Content is empty (pre-output) or partial (mid-stream) \u2014 return it\n // rather than crash on an assumed non-empty block, and flag the reason so the driver\n // (or a server-side `fallbacks` chain) can respond deterministically instead of\n // retrying into the same wall. Usage/cost is already logged above.\n if (response.stop_reason === 'refusal') {\n base.responseMeta = { finishReason: 'refusal' };\n }\n return base;\n }\n buildEndpoint() {\n if (this.apiKey) {\n return {\n url: ANTHROPIC_DIRECT_URL,\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n 'anthropic-version': ANTHROPIC_API_VERSION,\n // Anthropic blocks browser-origin requests by default. This header is the\n // documented opt-in (equivalent to the SDK's `dangerouslyAllowBrowser`).\n 'anthropic-dangerous-direct-browser-access': 'true',\n },\n credentials: 'omit',\n };\n }\n if (this.serverEndpoint) {\n return {\n url: this.serverEndpoint,\n // Opt in to the proxy's NDJSON heartbeat framing. An old proxy ignores\n // this and returns plain JSON \u2014 see the Content-Type branch in `post`.\n headers: { 'Content-Type': 'application/json', Accept: 'application/x-ndjson' },\n credentials: 'include',\n };\n }\n throw new Error('AnthropicTransport: no API key or server endpoint configured. ' +\n 'Set ANTHROPIC_API_KEY in your .env or pass apiKey/serverEndpoint in AnthropicAIConfig.');\n }\n post(body, signal) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a;\n const { url, headers, credentials } = this.buildEndpoint();\n // The server-side `fallbacks` param is gated behind a beta flag; add it per-request only\n // when a fallback chain is set (the param without the header is a 400, and vice-versa is fine).\n const requestHeaders = ((_a = body.fallbacks) === null || _a === void 0 ? void 0 : _a.length)\n ? Object.assign(Object.assign({}, headers), { 'anthropic-beta': [headers['anthropic-beta'], SERVER_SIDE_FALLBACK_BETA]\n .filter(Boolean)\n .join(',') }) : headers;\n return (yield postWithRetry({\n url,\n headers: requestHeaders,\n body,\n credentials,\n vendorLabel: VENDOR_LABELS.anthropic,\n retryableStatuses: AnthropicTransport.RETRYABLE_STATUSES,\n timeout: this.timeout,\n stallTimeout: this.stallTimeout,\n backoffBaseMs: AnthropicTransport.BACKOFF_BASE_MS,\n signal,\n }));\n });\n }\n}\n// \u2500\u2500 Private helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nAnthropicTransport.TOKENS_PER_MILLION = 1000000;\nAnthropicTransport.COST_DECIMAL_PLACES = 6;\nAnthropicTransport.RATE_LIMIT_STATUS = 429;\nAnthropicTransport.SERVICE_UNAVAILABLE_STATUS = 503;\nAnthropicTransport.OVERLOADED_STATUS = 529;\nAnthropicTransport.RETRYABLE_STATUSES = [\n AnthropicTransport.RATE_LIMIT_STATUS,\n AnthropicTransport.SERVICE_UNAVAILABLE_STATUS,\n AnthropicTransport.OVERLOADED_STATUS,\n];\n// Base backoff for the shared retry ladder (1s, 2s, 4s, 8s, 16s).\nAnthropicTransport.BACKOFF_BASE_MS = 1000;\n", "// \u2500\u2500 MALFORMED_FUNCTION_CALL repair \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Gemini occasionally returns `finishReason: \"MALFORMED_FUNCTION_CALL\"` when it\n// has actually produced a complete, correct tool call but serialised it as a\n// Python statement instead of the API's structured format, e.g.\n//\n// print(default_api.vfs_edit(new_string = \"\u2026\", old_string = \"\u2026\", path = \"\u2026\", replace_all = true))\n//\n// The intended call is fully present in `candidates[0].finishMessage`. Rather\n// than throw and burn a ChatDriver retry (a full re-roll that may regenerate\n// something worse, or malform again), we parse the call back out and hand it to\n// the transport as a normal structured tool call \u2014 unwrapping a wrong envelope,\n// not guessing. The parser is deliberately fail-closed: on ANY ambiguity it\n// returns null and the transport falls back to throwing\n// `MalformedFunctionCallError`, leaving today's retry behaviour unchanged. It\n// never returns a half-parsed call.\nconst MALFORMED_CALL_ANCHOR = 'default_api.';\nconst PRINT_WRAPPER_RE = /print\\(\\s*$/;\nconst UNICODE_ESCAPE_DIGITS = 4;\nconst HEX_ESCAPE_DIGITS = 2;\nconst HEX_RADIX = 16;\n/**\n * Recursive-descent scanner for a single Python-style `default_api.<tool>(...)`\n * call. Walks the string character by character so that delimiters (commas,\n * parens, quotes, brackets, newlines) appearing *inside* string-literal\n * arguments don't prematurely terminate parsing. Throws on the first unexpected\n * token; callers treat any throw as \"not confidently parseable\".\n */\nclass MalformedFunctionCallParser {\n constructor(src) {\n this.src = src;\n this.pos = 0;\n }\n parse() {\n const anchor = this.src.indexOf(MALFORMED_CALL_ANCHOR);\n if (anchor === -1)\n this.bail();\n // Tolerate an enclosing `print(` wrapper (the observed Python form) or a\n // bare call. Any other preamble (e.g. \"Malformed function call: \") is\n // ignored \u2014 we only anchor on `default_api.`.\n const wrapped = PRINT_WRAPPER_RE.test(this.src.slice(0, anchor));\n this.pos = anchor;\n const call = this.parseCall();\n this.skipWhitespace();\n if (wrapped) {\n this.expect(')');\n this.skipWhitespace();\n }\n // Strict: nothing may follow the call. In particular a second\n // `default_api.` (batched calls) bails rather than silently dropping work.\n if (this.pos !== this.src.length)\n this.bail();\n return call;\n }\n parseCall() {\n this.expectLiteral(MALFORMED_CALL_ANCHOR);\n const name = this.readIdentifier();\n this.expect('(');\n const args = this.parseKwargs();\n this.expect(')');\n return { name, args };\n }\n parseKwargs() {\n const args = {};\n for (;;) {\n this.skipWhitespace();\n // Empty arg list, or a tolerated trailing comma before the closing paren.\n if (this.peek() === ')')\n break;\n const key = this.readIdentifier();\n this.skipWhitespace();\n this.expect('=');\n this.skipWhitespace();\n const value = this.parseValue();\n if (Object.prototype.hasOwnProperty.call(args, key))\n this.bail();\n args[key] = value;\n this.skipWhitespace();\n const next = this.peek();\n if (next === ',') {\n this.pos += 1;\n continue;\n }\n if (next === ')')\n break;\n this.bail();\n }\n return args;\n }\n parseValue() {\n const ch = this.peek();\n if (ch === '\"' || ch === \"'\")\n return this.readString();\n if (ch === '-' || ch === '+' || this.isDigit(ch))\n return this.readNumber();\n if (/[A-Za-z]/.test(ch))\n return this.readBareword();\n // Unhandled value form (e.g. a list `[\u2026]` or dict `{\u2026}`) \u2014 bail.\n return this.bail();\n }\n readString() {\n const quote = this.src[this.pos];\n this.pos += 1; // opening quote\n let out = '';\n for (;;) {\n if (this.pos >= this.src.length)\n this.bail(); // unterminated \u2192 truncation guard\n const c = this.src[this.pos];\n this.pos += 1;\n if (c === quote)\n return out; // closing quote\n if (c === '\\\\') {\n out += this.readEscape();\n continue;\n }\n out += c;\n }\n }\n readEscape() {\n if (this.pos >= this.src.length)\n this.bail();\n const e = this.src[this.pos];\n this.pos += 1;\n switch (e) {\n case 'n':\n return '\\n';\n case 't':\n return '\\t';\n case 'r':\n return '\\r';\n case 'b':\n return '\\b';\n case 'f':\n return '\\f';\n case '\\\\':\n return '\\\\';\n case '\"':\n return '\"';\n case \"'\":\n return \"'\";\n case '/':\n return '/';\n case 'u':\n return this.readHexCodepoint(UNICODE_ESCAPE_DIGITS);\n case 'x':\n return this.readHexCodepoint(HEX_ESCAPE_DIGITS);\n default:\n // Unknown escape \u2014 refuse rather than risk a silent mis-decode.\n return this.bail();\n }\n }\n readHexCodepoint(digits) {\n const hex = this.src.slice(this.pos, this.pos + digits);\n if (hex.length !== digits || !/^[0-9a-fA-F]+$/.test(hex))\n this.bail();\n this.pos += digits;\n return String.fromCharCode(parseInt(hex, HEX_RADIX));\n }\n readNumber() {\n const start = this.pos;\n if (this.peek() === '-' || this.peek() === '+')\n this.pos += 1;\n while (this.pos < this.src.length && /[0-9.eE+-]/.test(this.src[this.pos])) {\n this.pos += 1;\n }\n const value = Number(this.src.slice(start, this.pos));\n if (!Number.isFinite(value))\n this.bail();\n return value;\n }\n readBareword() {\n const word = this.readIdentifier();\n switch (word) {\n case 'true':\n case 'True':\n return true;\n case 'false':\n case 'False':\n return false;\n // Python serialises an omitted/optional kwarg as `None` (and sometimes a\n // JSON-ish `null`); decode both to `null` rather than bailing the whole call.\n case 'null':\n case 'None':\n return null;\n default:\n return this.bail();\n }\n }\n readIdentifier() {\n const start = this.pos;\n if (!/[A-Za-z_]/.test(this.peek()))\n this.bail();\n while (this.pos < this.src.length && /[A-Za-z0-9_]/.test(this.src[this.pos])) {\n this.pos += 1;\n }\n return this.src.slice(start, this.pos);\n }\n isDigit(ch) {\n return ch >= '0' && ch <= '9';\n }\n peek() {\n return this.pos < this.src.length ? this.src[this.pos] : '';\n }\n skipWhitespace() {\n while (this.pos < this.src.length && /\\s/.test(this.src[this.pos])) {\n this.pos += 1;\n }\n }\n expect(ch) {\n if (this.src[this.pos] !== ch)\n this.bail();\n this.pos += 1;\n }\n expectLiteral(literal) {\n if (this.src.slice(this.pos, this.pos + literal.length) !== literal)\n this.bail();\n this.pos += literal.length;\n }\n bail() {\n throw new Error('MalformedFunctionCallParser: unexpected token');\n }\n}\n/**\n * Attempts to recover a structured tool call from a Gemini\n * `MALFORMED_FUNCTION_CALL` `finishMessage`. Returns the parsed call only when\n * it parses cleanly AND its tool name is one of the offered tools; otherwise\n * returns null so the caller can fall back to the existing retry path.\n */\nexport function repairMalformedFunctionCall(finishMessage, offeredToolNames) {\n if (!finishMessage)\n return null;\n let call;\n try {\n call = new MalformedFunctionCallParser(finishMessage).parse();\n }\n catch (_a) {\n return null;\n }\n if (!offeredToolNames.has(call.name))\n return null;\n return call;\n}\n", "import { __awaiter } from \"tslib\";\nimport { SUPPORTED_GEMINI_MODEL_IDS, } from '../types';\nimport { logger } from '../utils/logger';\nimport { scaleTemperature } from '../utils/temperature';\nimport { ResponseTruncatedError } from './anthropic-transport';\nimport { VENDOR_LABELS } from './budget-exhausted-error';\nimport { repairMalformedFunctionCall } from './gemini-malformed-call';\nimport { postWithRetry } from './post-with-retry';\nconst GEMINI_DIRECT_URL = (model) => `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent`;\nconst DEFAULT_MODEL = 'gemini-2.5-flash-lite';\nconst DEFAULT_TIMEOUT = 300000; // healthy >200s generations observed at 128k max_tokens; wall clock is a last resort\nconst DEFAULT_STALL_TIMEOUT = 30000; // inactivity window on the framed proxy path; pings arrive every 5s\n/**\n * Maximum input context window (tokens) per supported Gemini model.\n * Source: https://ai.google.dev/gemini-api/docs/models\n */\nconst GEMINI_CONTEXT_LIMITS = {\n 'gemini-2.5-pro': 1048576,\n 'gemini-2.5-flash': 1048576,\n 'gemini-2.5-flash-lite': 1048576,\n 'gemini-3.5-flash': 1048576,\n 'gemini-3.1-flash-lite': 1048576,\n 'gemini-3.1-pro-preview': 1048576,\n};\n/** Gemini's native default + ceiling temperature \u2014 https://ai.google.dev/gemini-api/docs */\nconst GEMINI_DEFAULT_TEMPERATURE = 1;\nconst GEMINI_MAX_TEMPERATURE = 2;\n/**\n * Map a provider-agnostic {@link ChatToolChoice} to Gemini's `toolConfig`.\n * Returns undefined for the default (`'auto'`) so the request omits the field.\n */\nfunction toGeminiToolConfig(choice) {\n if (!choice || choice === 'auto')\n return undefined;\n if (choice === 'required')\n return { functionCallingConfig: { mode: 'ANY' } };\n if (choice === 'none')\n return { functionCallingConfig: { mode: 'NONE' } };\n return { functionCallingConfig: { mode: 'ANY', allowedFunctionNames: [choice.tool] } };\n}\nfunction assertSupportedGeminiModel(model) {\n if (!SUPPORTED_GEMINI_MODEL_IDS.includes(model)) {\n throw new Error(`GeminiTransport: unsupported model \"${model}\". Use one of: ${SUPPORTED_GEMINI_MODEL_IDS.join(', ')}.`);\n }\n}\n/**\n * Prompt size (tokens) at or below which the standard pricing tier applies.\n * Above it, Gemini's long-context tier kicks in. Google applies a single tier\n * to the whole request based on prompt size \u2014 it is not a marginal/blended rate.\n */\nconst GEMINI_LONG_CONTEXT_THRESHOLD = 200000;\n/**\n * Cached / context-cache input tokens bill at a flat ~10% of the model's normal input\n * rate \u2014 consistent across models (flash $0.30\u2192$0.03, flash-lite $0.10\u2192$0.01,\n * pro $1.25\u2192$0.125). Source: https://ai.google.dev/gemini-api/docs/pricing.\n * (Explicit context caching also has an hourly storage fee; implicit caching \u2014 what we\n * rely on \u2014 has none, so only this read discount applies.)\n */\nconst GEMINI_CACHED_INPUT_MULTIPLIER = 0.1;\n/**\n * Paid Standard tier rates (USD per million tokens) \u2014 https://ai.google.dev/gemini-api/docs/pricing\n */\nconst GEMINI_PRICING = {\n 'gemini-2.5-flash-lite': {\n kind: 'flat',\n rate: { promptPerMillion: 0.1, candidatePerMillion: 0.4 },\n },\n 'gemini-2.5-flash': { kind: 'flat', rate: { promptPerMillion: 0.3, candidatePerMillion: 2.5 } },\n 'gemini-2.5-pro': {\n kind: 'tiered',\n standard: { promptPerMillion: 1.25, candidatePerMillion: 10.0 },\n longContext: { promptPerMillion: 2.5, candidatePerMillion: 15.0 },\n },\n 'gemini-3.1-flash-lite': {\n kind: 'flat',\n rate: { promptPerMillion: 0.25, candidatePerMillion: 1.5 },\n },\n 'gemini-3.5-flash': { kind: 'flat', rate: { promptPerMillion: 1.5, candidatePerMillion: 9.0 } },\n 'gemini-3.1-pro-preview': {\n kind: 'tiered',\n standard: { promptPerMillion: 2.0, candidatePerMillion: 12.0 },\n longContext: { promptPerMillion: 4.0, candidatePerMillion: 18.0 },\n },\n};\n/**\n * Resolves the per-million-token rates for a model given the request's prompt\n * size, selecting the long-context tier for tiered models when the prompt\n * exceeds {@link GEMINI_LONG_CONTEXT_THRESHOLD}.\n */\nfunction estimatedGeminiPaidRatesUsdPerMillion(model, promptTokens) {\n const pricing = GEMINI_PRICING[model];\n if (pricing.kind === 'flat') {\n return pricing.rate;\n }\n return promptTokens > GEMINI_LONG_CONTEXT_THRESHOLD ? pricing.longContext : pricing.standard;\n}\n/**\n * Per-model warnings emitted on construction. flash-lite tiers are the cheap\n * default and warn-free; higher-cost, frontier, and preview models flag their\n * trade-offs so callers don't pick them by accident.\n */\nconst GEMINI_MODEL_WARNINGS = {\n 'gemini-2.5-flash': 'GeminiTransport: using gemini-2.5-flash \u2014 higher cost than flash-lite; use for harder reasoning or agent tasks.',\n 'gemini-2.5-pro': 'GeminiTransport: using gemini-2.5-pro \u2014 significantly higher, prompt-size-tiered cost; reserve for tasks where flash reliability is insufficient.',\n 'gemini-3.5-flash': 'GeminiTransport: using gemini-3.5-flash \u2014 frontier model, materially higher cost than flash-lite; use for harder reasoning or agent tasks.',\n 'gemini-3.1-pro-preview': 'GeminiTransport: using gemini-3.1-pro-preview \u2014 PREVIEW model (no stability guarantee, may be withdrawn) with significantly higher, prompt-size-tiered cost; reserve for tasks where flash reliability is insufficient.',\n};\n/**\n * Token accepted by the Gemini 3 API in place of a real `thoughtSignature` to\n * skip signature validation. Used when replaying a tool call whose signature\n * belongs to a different model (a mid-execution model switch) or was never\n * captured: the step's first function call still needs *a* signature to pass\n * validation, but a foreign signature can't be honoured.\n * Source: https://ai.google.dev/gemini-api/docs/thought-signatures\n */\nconst SKIP_SIGNATURE = 'skip_thought_signature_validator';\n/**\n * Key under which this transport stashes its round-trip state on a tool call's\n * provider-neutral `providerMetadata` bag. Private to GeminiTransport.\n */\nconst GEMINI_PROVIDER_KEY = 'gemini';\n/**\n * Thrown when Gemini returns a `MALFORMED_FUNCTION_CALL` finish reason,\n * typically because the model tried to batch multiple tool calls using\n * Python-style syntax instead of the proper API format.\n *\n * @beta\n */\nexport class MalformedFunctionCallError extends Error {\n constructor(finishMessage) {\n super('Gemini returned MALFORMED_FUNCTION_CALL');\n this.finishMessage = finishMessage;\n this.name = 'MalformedFunctionCallError';\n }\n}\n/**\n * Transport for Gemini. Calls the Gemini REST API directly when `apiKey` is\n * provided, otherwise falls back to a server-proxy endpoint (if `serverEndpoint`\n * is configured).\n *\n * Implements `AITransport` (structured prompt) and `ChatTransport` (multi-turn chat).\n *\n * @beta\n */\nexport class GeminiTransport {\n constructor(config = {}) {\n var _a, _b, _c;\n /**\n * Estimated USD cost accumulated across every successful request on this\n * transport instance. Convenience accessor for non-chat consumers\n * (telemetry, debug overlays). The main chat UI sums per-message `cost`\n * fields instead so its session total stays attributed to chat turns only.\n */\n this.lifetimeCostUsd = 0;\n /**\n * Estimated USD saved by context caching vs paying full input price, accumulated across\n * every request. Gemini implicit caching has no write premium, so this is always \u2265 0.\n * Surfaced alongside `getLifetimeCost`.\n */\n this.lifetimeSavingsUsd = 0;\n const model = (_a = config.model) !== null && _a !== void 0 ? _a : DEFAULT_MODEL;\n assertSupportedGeminiModel(model);\n this.model = model;\n const warning = GEMINI_MODEL_WARNINGS[model];\n if (warning) {\n logger.warn(warning);\n }\n this.timeout = (_b = config.timeout) !== null && _b !== void 0 ? _b : DEFAULT_TIMEOUT;\n this.stallTimeout = (_c = config.stallTimeout) !== null && _c !== void 0 ? _c : DEFAULT_STALL_TIMEOUT;\n this.apiKey = config.apiKey;\n this.serverEndpoint = config.serverEndpoint;\n }\n getConfig() {\n return {\n provider: 'gemini',\n model: this.model,\n contextLimit: GEMINI_CONTEXT_LIMITS[this.model],\n };\n }\n /** Estimated USD cost accumulated across every successful request on this transport instance. */\n getLifetimeCost() {\n return this.lifetimeCostUsd;\n }\n /** Estimated USD saved by context caching across this instance (implicit caching \u2192 always \u2265 0). */\n getLifetimeSavings() {\n return this.lifetimeSavingsUsd;\n }\n /** Reset the lifetime cost + savings counters. Intended for chat-clear / new-session flows. */\n resetLifetimeCost() {\n this.lifetimeCostUsd = 0;\n this.lifetimeSavingsUsd = 0;\n }\n // \u2500\u2500 AITransport (structured prompt) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n sendStructuredPrompt(options) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a;\n const { systemPrompt, userPrompt, responseSchema } = options;\n const contents = [];\n if (systemPrompt) {\n contents.push({ role: 'user', parts: [{ text: systemPrompt }] });\n contents.push({ role: 'model', parts: [{ text: 'Understood.' }] });\n }\n contents.push({ role: 'user', parts: [{ text: userPrompt }] });\n const response = yield this.post({ model: this.model, contents, responseSchema });\n return (_a = response === null || response === void 0 ? void 0 : response.content) !== null && _a !== void 0 ? _a : '';\n });\n }\n // \u2500\u2500 ChatTransport (multi-turn chat) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n sendChatMessage(history, userMessage, options) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a, _b;\n // NOTE: `options.cachePolicy` is intentionally NOT read here. Gemini 2.5+ does *implicit*\n // caching automatically and always-on \u2014 it caches as much of the stable request prefix as it\n // can on every call, regardless of the policy's `scope` (including `'default'`). We issue no\n // explicit `cachedContent`, so there is no request-side field to set; the only lever is\n // keeping the prefix byte-stable (a consumer concern). The cached tokens that come back are\n // priced in `logTokenUsage` via `cachedContentTokenCount`. See `CachePolicy` docs.\n const contents = this.toGeminiContents(history, userMessage, options === null || options === void 0 ? void 0 : options.attachments);\n // Never-stored tail context as a trailing user content (after the stable prefix). Verified\n // valid even directly after a functionResponse content. The caller has already framed it.\n if (options === null || options === void 0 ? void 0 : options.tailContext) {\n contents.push({ role: 'user', parts: [{ text: options.tailContext }] });\n }\n const tools = ((_a = options === null || options === void 0 ? void 0 : options.tools) === null || _a === void 0 ? void 0 : _a.length)\n ? [\n {\n functionDeclarations: options.tools.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n })),\n },\n ]\n : undefined;\n const systemInstruction = (options === null || options === void 0 ? void 0 : options.systemPrompt)\n ? { role: 'system', parts: [{ text: options.systemPrompt }] }\n : undefined;\n // Map the requested tool-call mode to Gemini's toolConfig \u2014 only meaningful\n // when functions are declared. NOTE: forcing (`ANY` / allowedFunctionNames)\n // can make the model batch calls in Python-ish syntax \u2192\n // `MALFORMED_FUNCTION_CALL`, which `fromGeminiResponse` repairs in place when\n // it can confidently parse the call (see `repairMalformedFunctionCall`),\n // falling back to the caller's retry otherwise.\n const toolConfig = tools ? toGeminiToolConfig(options === null || options === void 0 ? void 0 : options.toolChoice) : undefined;\n // Request thought summaries so the model's official reasoning is returned\n // (and a thinking-only turn surfaces *something* rather than going silently\n // blank). Gemini 2.5 Pro always thinks regardless, so this only changes what\n // is RETURNED, not what is billed \u2014 see `logTokenUsage` for the thinking-token\n // accounting it lets us finally capture.\n const generationConfig = { thinkingConfig: { includeThoughts: true } };\n // Normalized [0,1] temperature \u2192 Gemini's native range, anchored so 0.5\n // maps to its default (native 1) and 1 to its ceiling (native 2).\n if ((options === null || options === void 0 ? void 0 : options.temperature) != null) {\n generationConfig.temperature = scaleTemperature(options.temperature, {\n defaultTemp: GEMINI_DEFAULT_TEMPERATURE,\n maxTemp: GEMINI_MAX_TEMPERATURE,\n });\n }\n // Names of the tools offered this turn \u2014 used to validate a repaired\n // malformed call against the real tool surface before accepting it.\n const offeredToolNames = new Set(((_b = options === null || options === void 0 ? void 0 : options.tools) !== null && _b !== void 0 ? _b : []).map((t) => t.name));\n // Structured output (native JSON mode). Gemini 3 can combine it with function calling;\n // Gemini 2.x cannot, so on 2.x apply the schema only on a pure structured turn (no tools) and\n // otherwise drop it (the caller keeps a prompt-instruction + validator fallback). Passed as a\n // top-level `responseSchema` that `toDirectPayload` maps to `generationConfig.responseMimeType`\n // + `responseSchema` on the direct path (the proxy forwards it).\n const schemaCoexistsWithTools = this.model.startsWith('gemini-3');\n const applyResponseSchema = (options === null || options === void 0 ? void 0 : options.responseSchema) != null && (!tools || schemaCoexistsWithTools);\n const response = yield this.post(Object.assign({ model: this.model, contents,\n tools,\n systemInstruction,\n toolConfig,\n generationConfig }, (applyResponseSchema ? { responseSchema: options.responseSchema } : {})), options === null || options === void 0 ? void 0 : options.signal);\n return this.fromGeminiResponse(response, offeredToolNames);\n });\n }\n /**\n * Logs the per-call cost breakdown, accumulates the lifetime running total,\n * and returns the per-call total so the caller can attach it to the response\n * message.\n */\n logTokenUsage(promptTokens, candidateTokens, thoughtTokens, cachedTokens) {\n const { promptPerMillion, candidatePerMillion } = estimatedGeminiPaidRatesUsdPerMillion(this.model, promptTokens);\n const m = GeminiTransport.TOKENS_PER_MILLION;\n // `promptTokenCount` INCLUDES the cached portion (opposite of Anthropic's `input_tokens`),\n // so split it: the uncached remainder bills at the full input rate and the cached slice at\n // ~0.1\u00D7. The pricing TIER is still chosen on the full prompt size (above). `cachedTokens`\n // is 0 when caching wasn't active, so this is a no-op then.\n const uncachedPromptTokens = Math.max(0, promptTokens - cachedTokens);\n const promptCost = (uncachedPromptTokens / m) * promptPerMillion;\n const cacheReadCost = (cachedTokens / m) * promptPerMillion * GEMINI_CACHED_INPUT_MULTIPLIER;\n // Thinking tokens are billed at the output (candidate) rate. They are\n // incurred whenever the model thinks (always, on 2.5 Pro) \u2014 counting them\n // here corrects a long-standing undercount, it does not raise the bill.\n const candidateCost = ((candidateTokens + thoughtTokens) / m) * candidatePerMillion;\n const totalCost = promptCost + cacheReadCost + candidateCost;\n this.lifetimeCostUsd += totalCost;\n // Savings vs no caching: the cached tokens would have cost full input price; we paid ~0.1\u00D7.\n // Implicit caching has no write premium, so this is always \u2265 0.\n const saved = (cachedTokens / m) * promptPerMillion - cacheReadCost;\n this.lifetimeSavingsUsd += saved;\n const dp = GeminiTransport.COST_DECIMAL_PLACES;\n console.log(`--- Gemini Token Usage (${this.model}) ---`);\n console.log(`Prompt Tokens: ${promptTokens} (${cachedTokens} cached) ($${promptCost.toFixed(dp)} + $${cacheReadCost.toFixed(dp)})`);\n console.log(`Candidate Tokens: ${candidateTokens} (+${thoughtTokens} thinking) ($${candidateCost.toFixed(dp)})`);\n console.log(`Total Cost: $${totalCost.toFixed(dp)}`);\n console.log(`Cache Saved: $${saved.toFixed(dp)} (lifetime $${this.lifetimeSavingsUsd.toFixed(dp)})`);\n console.log(`Lifetime Cost: $${this.lifetimeCostUsd.toFixed(dp)}`);\n console.log('--------------------------');\n return totalCost;\n }\n toGeminiContents(history, userMessage, attachments) {\n var _a, _b, _c;\n const contents = [];\n // Gemini requires functionResponse.name to match the original functionCall.name.\n // Our internal IDs are UUIDs, so build a lookup from ID \u2192 function name as we go.\n const toolCallNameById = new Map();\n for (const msg of history) {\n if (msg.role === 'system' ||\n msg.role === 'system-event' ||\n msg.role === 'synthetic-user' ||\n msg.role === 'compacted-summary' ||\n msg.category === 'reasoning' ||\n msg.category === 'narration' ||\n msg.thinking // legacy pre-split sessions\n )\n continue;\n const role = msg.role === 'user' ? 'user' : 'model';\n if (msg.toolResult) {\n const fnName = (_a = toolCallNameById.get(msg.toolResult.toolCallId)) !== null && _a !== void 0 ? _a : msg.toolResult.toolCallId;\n contents.push({\n role: 'user',\n parts: [\n {\n functionResponse: {\n name: fnName,\n response: { content: msg.toolResult.content },\n },\n },\n ],\n });\n }\n else if ((_b = msg.toolCalls) === null || _b === void 0 ? void 0 : _b.length) {\n for (const tc of msg.toolCalls) {\n toolCallNameById.set(tc.id, tc.name);\n }\n contents.push({\n role: 'model',\n parts: msg.toolCalls.map((tc, i) => {\n var _a;\n const part = { functionCall: { name: tc.name, args: tc.args } };\n const state = (_a = tc.providerMetadata) === null || _a === void 0 ? void 0 : _a[GEMINI_PROVIDER_KEY];\n // A signature is only valid for the model that produced it. Replay\n // the real one only when the producing model matches this request's\n // model; on a mid-execution model switch (or when none was captured)\n // put the skip token on the step's first call so validation passes.\n // Parallel sibling calls (i > 0) carry no signature, matching what\n // Gemini emits.\n const sig = (state === null || state === void 0 ? void 0 : state.model) === this.model ? state.thoughtSignature : undefined;\n if (sig) {\n part.thoughtSignature = sig;\n }\n else if (i === 0) {\n part.thoughtSignature = SKIP_SIGNATURE;\n }\n return part;\n }),\n });\n }\n else if (role === 'user' && ((_c = msg.attachments) === null || _c === void 0 ? void 0 : _c.length)) {\n const msgAttachmentParts = msg.attachments.map((att) => ({\n text: `[File: ${att.name}]\\n${att.content}`,\n }));\n contents.push({ role: 'user', parts: [{ text: msg.content }, ...msgAttachmentParts] });\n }\n else {\n contents.push({ role, parts: [{ text: msg.content }] });\n }\n }\n const attachmentParts = (attachments !== null && attachments !== void 0 ? attachments : []).map((att) => ({\n text: `[File: ${att.name}]\\n${att.content}`,\n }));\n if (userMessage || attachmentParts.length) {\n contents.push({ role: 'user', parts: [{ text: userMessage }, ...attachmentParts] });\n }\n return contents;\n }\n /**\n * Map Gemini's `usageMetadata` onto the provider-agnostic usage fields, pricing\n * the call as a side effect (`logTokenUsage`). Returns an empty object when the\n * response carries no usage \u2014 every field is optional, so an absent count stays\n * `undefined` rather than being reported as a measured 0.\n *\n * Split out of `fromGeminiResponse` because it is self-contained bookkeeping\n * that reads better alone \u2014 and because folding it inline pushed that method\n * past the complexity ceiling.\n */\n usageFromGemini(usageMetadata) {\n var _a, _b, _c, _d, _e, _f;\n if (!usageMetadata)\n return {};\n const usage = usageMetadata;\n const cost = this.logTokenUsage((_a = usage.promptTokenCount) !== null && _a !== void 0 ? _a : 0, (_b = usage.candidatesTokenCount) !== null && _b !== void 0 ? _b : 0, (_c = usage.thoughtsTokenCount) !== null && _c !== void 0 ? _c : 0, (_d = usage.cachedContentTokenCount) !== null && _d !== void 0 ? _d : 0);\n return {\n inputTokens: usage.promptTokenCount,\n // Thinking tokens are generated output, billed at the candidate rate, but\n // reported in a field disjoint from `candidatesTokenCount`. Fold them into the\n // provider-agnostic `outputTokens` so it reflects the true generated total \u2014\n // matching Anthropic, whose `output_tokens` already includes them. Left\n // `undefined` only when the provider reported neither count.\n outputTokens: usage.candidatesTokenCount != null || usage.thoughtsTokenCount != null\n ? ((_e = usage.candidatesTokenCount) !== null && _e !== void 0 ? _e : 0) + ((_f = usage.thoughtsTokenCount) !== null && _f !== void 0 ? _f : 0)\n : undefined,\n thoughtsTokens: usage.thoughtsTokenCount,\n // Gemini reports cache HITS only \u2014 implicit caching bills no separate write, so\n // `cacheWriteTokens` is left unset rather than 0 (there is no write bucket to\n // measure, which is not the same as measuring 0). Already counted inside\n // `promptTokenCount`, so this breaks that total down rather than adding to it.\n cacheReadTokens: usage.cachedContentTokenCount,\n cost,\n };\n }\n fromGeminiResponse(response, offeredToolNames = new Set()) {\n var _a, _b, _c, _d;\n const { inputTokens, outputTokens, thoughtsTokens, cacheReadTokens, cost } = this.usageFromGemini(response.usageMetadata);\n const candidates = response === null || response === void 0 ? void 0 : response.candidates;\n const firstCandidate = candidates === null || candidates === void 0 ? void 0 : candidates[0];\n const parts = (_b = (_a = firstCandidate === null || firstCandidate === void 0 ? void 0 : firstCandidate.content) === null || _a === void 0 ? void 0 : _a.parts) !== null && _b !== void 0 ? _b : [];\n const toolCalls = [];\n const thoughtParts = [];\n const textParts = [];\n for (const part of parts) {\n if (part.functionCall) {\n // Stash the reasoning signature (and the producing model) so it can be\n // replayed on the next request \u2014 Gemini 3 requires the first function\n // call of each step to carry its signature or the request 400s. The\n // API only returns a signature on the first of a set of parallel calls.\n const state = { model: this.model };\n if (part.thoughtSignature) {\n state.thoughtSignature = part.thoughtSignature;\n }\n toolCalls.push({\n id: crypto.randomUUID(),\n name: part.functionCall.name,\n args: (_c = part.functionCall.args) !== null && _c !== void 0 ? _c : {},\n providerMetadata: { [GEMINI_PROVIDER_KEY]: state },\n });\n }\n else if (part.thought && part.text) {\n thoughtParts.push(part.text);\n }\n else if (part.text) {\n textParts.push(part.text);\n }\n }\n // Gemini sometimes flags MALFORMED_FUNCTION_CALL when it produced a complete\n // tool call but serialised it as a Python statement. Recover it in place\n // when we can parse it with full confidence (its `parts` are empty in this\n // case, so the repaired call flows through the normal token/cost handling\n // below); otherwise throw so the ChatDriver retry takes over.\n if ((firstCandidate === null || firstCandidate === void 0 ? void 0 : firstCandidate.finishReason) === 'MALFORMED_FUNCTION_CALL') {\n const repaired = repairMalformedFunctionCall(firstCandidate.finishMessage, offeredToolNames);\n if (!repaired) {\n throw new MalformedFunctionCallError(firstCandidate.finishMessage);\n }\n toolCalls.push({ id: crypto.randomUUID(), name: repaired.name, args: repaired.args });\n }\n // The model's official thinking (thought-summary parts, returned because we set\n // `thinkingConfig.includeThoughts`) travels in its OWN channel, distinct from the answer /\n // tool-call narration: `content` carries the answer text, `reasoning` carries the summary. The\n // driver splits them into separate category-tagged messages (reasoning vs narration) so each has\n // its own visibility toggle and log category. Final answers surface only the answer text; the\n // reasoning summary rides `reasoning` and is deliberately not promoted to be the answer.\n const reasoning = thoughtParts.join('');\n const narration = textParts.join('');\n const base = toolCalls.length > 0\n ? { role: 'assistant', content: narration, reasoning: reasoning || undefined, toolCalls }\n : { role: 'assistant', content: narration, reasoning: reasoning || undefined };\n // Blank / non-STOP finishes are the recurring failure mode (especially empty\n // STOP on 2.5 Pro). Log the full shape so the cause is legible from the\n // breakdown rather than inferred. MALFORMED is excluded \u2014 it has its own\n // repair/throw path above.\n const finishReason = firstCandidate === null || firstCandidate === void 0 ? void 0 : firstCandidate.finishReason;\n const isBlank = toolCalls.length === 0 && !reasoning && !narration;\n if (isBlank ||\n (finishReason && finishReason !== 'STOP' && finishReason !== 'MALFORMED_FUNCTION_CALL')) {\n this.logAbnormalResponse(response, {\n finishReason,\n functionCallParts: toolCalls.length,\n thoughtParts: thoughtParts.length,\n textParts: textParts.length,\n });\n }\n this.guardMaxTokensTruncation(finishReason, toolCalls, narration, outputTokens);\n if (inputTokens != null)\n base.inputTokens = inputTokens;\n if (outputTokens != null)\n base.outputTokens = outputTokens;\n if (cacheReadTokens != null)\n base.cacheReadTokens = cacheReadTokens;\n if (cost != null)\n base.cost = cost;\n // Surface the provider diagnostic on the message so the driver can fold it\n // into the debug-log meta events (the console log above is dev-only). Only\n // when there's signal \u2014 a finish reason, thinking tokens, or a block reason.\n const blockReason = (_d = response.promptFeedback) === null || _d === void 0 ? void 0 : _d.blockReason;\n if (finishReason != null || thoughtsTokens != null || blockReason != null) {\n base.responseMeta = {\n finishReason,\n thoughtsTokens,\n parts: {\n functionCall: toolCalls.length,\n thought: thoughtParts.length,\n text: textParts.length,\n },\n blockReason,\n };\n }\n return base;\n }\n /**\n * Raises {@link ResponseTruncatedError} when a `MAX_TOKENS` finish left nothing\n * safe to keep. A MAX_TOKENS finish means generation was cut off at the\n * output-token limit (no explicit cap is requested, so this is the model's own\n * output ceiling \u2014 which thinking tokens share). Truncation is DETERMINISTIC:\n * re-issuing the identical request hits the same limit, so it must not fall\n * through to the caller's empty-response retry. Mirrors the Anthropic\n * transport's contract: with tool calls the cut-off call's args can't be\n * trusted, and with no usable answer text (blank or thinking-only) there is\n * nothing to keep either \u2014 the typed truncation error is raised for both.\n * Partial answer TEXT is instead returned by `fromGeminiResponse`, flagged via\n * `responseMeta.finishReason`, for the caller to decide. Usage/cost is logged\n * before this check runs, so the spent tokens stay accounted for.\n */\n guardMaxTokensTruncation(finishReason, toolCalls, narration, outputTokens) {\n if (finishReason !== 'MAX_TOKENS')\n return;\n // A truncated text-only answer is partial but legible \u2014 keep it (the driver's\n // emptiness rule is `!content.trim()`, so whitespace-only does NOT count).\n if (toolCalls.length === 0 && narration.trim() !== '')\n return;\n throw new ResponseTruncatedError(this.model, undefined, outputTokens, toolCalls.map((tc) => tc.name));\n }\n /**\n * Log the full shape of a blank or non-STOP response so its cause is legible\n * without re-deriving it: a thinking-only STOP (substantial `thoughtsTokenCount`,\n * ~0 `candidatesTokenCount`) vs a content block (`SAFETY` / `RECITATION`) vs a\n * token cap (`MAX_TOKENS`) vs a prompt-level block (top-level\n * `promptFeedback.blockReason`). On 2.5 Pro \u2014 which always thinks \u2014 a blank\n * STOP carrying substantial thought tokens is the \"thought, then stopped\n * without answering\" signature.\n */\n logAbnormalResponse(response, parsed) {\n var _a, _b, _c;\n const usage = ((_a = response.usageMetadata) !== null && _a !== void 0 ? _a : {});\n const candidate = (_c = (_b = response.candidates) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : {};\n logger.warn('GeminiTransport: blank/non-STOP response', {\n model: this.model,\n finishReason: parsed.finishReason,\n finishMessage: candidate.finishMessage,\n parts: {\n total: parsed.functionCallParts + parsed.thoughtParts + parsed.textParts,\n functionCall: parsed.functionCallParts,\n thought: parsed.thoughtParts,\n text: parsed.textParts,\n },\n usage: {\n promptTokenCount: usage.promptTokenCount,\n candidatesTokenCount: usage.candidatesTokenCount,\n thoughtsTokenCount: usage.thoughtsTokenCount,\n totalTokenCount: usage.totalTokenCount,\n },\n promptFeedback: response.promptFeedback,\n safetyRatings: candidate.safetyRatings,\n citationMetadata: candidate.citationMetadata,\n });\n }\n buildEndpoint(body) {\n if (this.apiKey) {\n return {\n url: `${GEMINI_DIRECT_URL(this.model)}?key=${this.apiKey}`,\n payload: this.toDirectPayload(body),\n headers: { 'Content-Type': 'application/json' },\n credentials: 'omit',\n };\n }\n if (this.serverEndpoint) {\n return {\n url: this.serverEndpoint,\n payload: body,\n // Opt in to the proxy's NDJSON heartbeat framing. An old proxy ignores\n // this and returns plain JSON \u2014 see the Content-Type branch in `post`.\n headers: { 'Content-Type': 'application/json', Accept: 'application/x-ndjson' },\n credentials: 'include',\n };\n }\n throw new Error('GeminiTransport: no API key or server endpoint configured. ' +\n 'Set GEMINI_API_KEY in your .env or pass apiKey/serverEndpoint in GeminiAIConfig.');\n }\n post(body, signal) {\n return __awaiter(this, void 0, void 0, function* () {\n const { url, payload, headers, credentials } = this.buildEndpoint(body);\n return (yield postWithRetry({\n url,\n headers,\n body: payload,\n credentials,\n vendorLabel: VENDOR_LABELS.gemini,\n retryableStatuses: GeminiTransport.RETRYABLE_STATUSES,\n timeout: this.timeout,\n stallTimeout: this.stallTimeout,\n backoffBaseMs: GeminiTransport.BACKOFF_BASE_MS,\n signal,\n }));\n });\n }\n toDirectPayload(body) {\n const payload = Object.assign({}, body);\n delete payload.model;\n if (payload.responseSchema) {\n payload.generationConfig = Object.assign(Object.assign({}, payload.generationConfig), { responseMimeType: 'application/json', responseSchema: payload.responseSchema });\n delete payload.responseSchema;\n }\n return payload;\n }\n}\n// \u2500\u2500 Private helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nGeminiTransport.TOKENS_PER_MILLION = 1000000;\nGeminiTransport.COST_DECIMAL_PLACES = 6;\nGeminiTransport.RATE_LIMIT_STATUS = 429;\nGeminiTransport.SERVICE_UNAVAILABLE_STATUS = 503;\n/**\n * 502 BAD_GATEWAY is a cleanly transient fault from an intermediate proxy or load\n * balancer fronting the API \u2014 back off and retry it alongside 429/503.\n *\n * Deliberately NOT retried: 500 INTERNAL and 504 DEADLINE_EXCEEDED. Google documents\n * both as also carrying a deterministic cause (\"input context is too long\" / \"prompt\n * too large to process in time\"); re-issuing the identical request just re-hits the\n * same wall and burns the whole backoff ladder \u2014 the same deterministic-retry trap\n * this transport avoids for MAX_TOKENS, and especially wasteful on the large-context\n * agent path. They fail fast instead.\n */\nGeminiTransport.BAD_GATEWAY_STATUS = 502;\nGeminiTransport.RETRYABLE_STATUSES = [\n GeminiTransport.RATE_LIMIT_STATUS,\n GeminiTransport.SERVICE_UNAVAILABLE_STATUS,\n GeminiTransport.BAD_GATEWAY_STATUS,\n];\n// Base backoff for the shared retry ladder (1s, 2s, 4s, 8s, 16s).\nGeminiTransport.BACKOFF_BASE_MS = 1000;\n", "import { __awaiter } from \"tslib\";\nimport { AnthropicProvider } from './providers/anthropic-provider';\nimport { ChromeProvider } from './providers/chrome-provider';\nimport { DefaultAIProvider } from './providers/default-provider';\nimport { GeminiProvider } from './providers/gemini-provider';\nimport { OpenAIProvider } from './providers/openai-provider';\nimport { AnthropicTransport } from './transports/anthropic-transport';\nimport { ChromePromptTransport } from './transports/chrome-prompt-transport';\nimport { GeminiTransport } from './transports/gemini-transport';\nimport { ServerOpenAITransport } from './transports/server-openai-transport';\nimport { SUPPORTED_ANTHROPIC_MODEL_IDS, SUPPORTED_GEMINI_MODEL_IDS, } from './types';\nimport { logger } from './utils';\nimport { isAIFeatureEnabled } from './utils/feature-flags';\nfunction isChromeConfig(config) {\n return 'providerType' in config && config.providerType === 'chrome';\n}\nfunction isGeminiConfig(config) {\n return 'providerType' in config && config.providerType === 'gemini';\n}\nfunction isAnthropicConfig(config) {\n return 'providerType' in config && config.providerType === 'anthropic';\n}\nfunction isServerAIConfig(config) {\n return !!config.provider;\n}\n/**\n * Creates an AIProvider from config.\n * Uses ChromeProvider when providerType is 'chrome'.\n * Uses OpenAIProvider with ServerOpenAITransport when provider is set (server-only).\n * Otherwise returns DefaultAIProvider.\n * When the AI feature flag is disabled (?feature.ai), always returns DefaultAIProvider.\n *\n * @beta\n */\nexport function createAIProvider(config) {\n if (!isAIFeatureEnabled()) {\n logger.warn('createAIProvider: AI feature flag disabled, using DefaultAIProvider');\n return new DefaultAIProvider();\n }\n if (config && isChromeConfig(config)) {\n logger.debug('createAIProvider: using ChromeProvider');\n return new ChromeProvider(config);\n }\n if (config && isGeminiConfig(config)) {\n logger.debug('createAIProvider: using GeminiProvider');\n const transport = new GeminiTransport({\n model: config.model,\n timeout: config.timeout,\n stallTimeout: config.stallTimeout,\n serverEndpoint: config.serverEndpoint,\n apiKey: config.apiKey,\n });\n return new GeminiProvider({ criteriaInstructions: config.criteriaInstructions }, transport);\n }\n if (config && isAnthropicConfig(config)) {\n logger.debug('createAIProvider: using AnthropicProvider');\n const transport = new AnthropicTransport({\n model: config.model,\n timeout: config.timeout,\n stallTimeout: config.stallTimeout,\n serverEndpoint: config.serverEndpoint,\n apiKey: config.apiKey,\n maxTokens: config.maxTokens,\n });\n return new AnthropicProvider({ criteriaInstructions: config.criteriaInstructions }, transport);\n }\n if (config && isServerAIConfig(config)) {\n if (config.provider !== 'openai') {\n logger.warn('createAIProvider: only openai server provider supported for now, using default');\n return new DefaultAIProvider();\n }\n logger.debug('createAIProvider: using OpenAIProvider (server proxy)');\n const transport = new ServerOpenAITransport({\n model: config.model,\n timeout: config.timeout,\n });\n return new OpenAIProvider({ criteriaInstructions: config.criteriaInstructions }, transport);\n }\n logger.debug('createAIProvider: using DefaultAIProvider');\n return new DefaultAIProvider();\n}\n/**\n * Resolves AI config, optionally preferring Chrome when available.\n * Use before registering AIProvider. Server URL is derived from API_HOST.\n * Returns null when the AI feature flag is disabled (?feature.ai).\n *\n * @beta\n */\nexport function resolveAIConfig() {\n return __awaiter(this, arguments, void 0, function* (options = {}) {\n if (!isAIFeatureEnabled()) {\n logger.warn('resolveAIConfig: AI feature flag disabled');\n return null;\n }\n const { provider = 'openai', model, preferChrome = true } = options;\n if (preferChrome) {\n const transport = new ChromePromptTransport();\n const availability = yield transport.getAvailability();\n if (availability === 'available' ||\n availability === 'downloadable' ||\n availability === 'downloading') {\n return { providerType: 'chrome' };\n }\n logger.warn('resolveAIConfig: Chrome not available', availability);\n }\n if (provider === 'gemini') {\n const geminiModel = model !== null && model !== void 0 ? model : 'gemini-2.5-flash-lite';\n if (!SUPPORTED_GEMINI_MODEL_IDS.includes(geminiModel)) {\n throw new Error(`resolveAIConfig: unsupported Gemini model \"${geminiModel}\". Use one of: ${SUPPORTED_GEMINI_MODEL_IDS.join(', ')}.`);\n }\n return { providerType: 'gemini', model: geminiModel };\n }\n if (provider === 'anthropic') {\n const anthropicModel = model !== null && model !== void 0 ? model : 'claude-haiku-4-5-20251001';\n if (!SUPPORTED_ANTHROPIC_MODEL_IDS.includes(anthropicModel)) {\n throw new Error(`resolveAIConfig: unsupported Anthropic model \"${anthropicModel}\". Use one of: ${SUPPORTED_ANTHROPIC_MODEL_IDS.join(', ')}.`);\n }\n return { providerType: 'anthropic', model: anthropicModel };\n }\n return { provider, model: model !== null && model !== void 0 ? model : 'gpt-4o-mini' };\n });\n}\n/**\n * Feature-detects an {@link ObservableAIProviderRegistry}. Returns `true` when\n * `r` exposes a `subscribe` method \u2014 i.e. it can notify on runtime changes \u2014\n * and `false` for the immutable built-ins.\n *\n * @beta\n */\nexport function isObservableAIProviderRegistry(r) {\n return typeof r.subscribe === 'function';\n}\n/**\n * Built-in fallback registry. Resolved by the DI container when no host has\n * registered an {@link (AIProviderRegistry:interface)}. Holds a single\n * `DefaultAIProvider` (no-op) under the name `'default'`, preserving the\n * \"no host registration \u2192 assistant inert\" behavior.\n *\n * @internal\n */\nexport class EmptyAIProviderRegistry {\n constructor() {\n this.noopProvider = new DefaultAIProvider();\n }\n get(name) {\n return name === EmptyAIProviderRegistry.DEFAULT_NAME ? this.noopProvider : undefined;\n }\n default() {\n return this.noopProvider;\n }\n defaultName() {\n return EmptyAIProviderRegistry.DEFAULT_NAME;\n }\n names() {\n return [EmptyAIProviderRegistry.DEFAULT_NAME];\n }\n getStatus(name) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a, _b, _c;\n if (name !== undefined && name !== EmptyAIProviderRegistry.DEFAULT_NAME)\n return null;\n return (_c = (yield ((_b = (_a = this.noopProvider).getStatus) === null || _b === void 0 ? void 0 : _b.call(_a)))) !== null && _c !== void 0 ? _c : null;\n });\n }\n listStatuses() {\n return __awaiter(this, void 0, void 0, function* () {\n var _a, _b, _c;\n const status = (_c = (yield ((_b = (_a = this.noopProvider).getStatus) === null || _b === void 0 ? void 0 : _b.call(_a)))) !== null && _c !== void 0 ? _c : null;\n return [{ name: EmptyAIProviderRegistry.DEFAULT_NAME, isDefault: true, status }];\n });\n }\n}\nEmptyAIProviderRegistry.DEFAULT_NAME = 'default';\n/**\n * Map-backed registry built by {@link registerAIProviders}. Preserves the\n * insertion order of `providers` for {@link (AIProviderRegistry:interface).names}\n * and {@link (AIProviderRegistry:interface).listStatuses}.\n *\n * Mutable and observable: a host that holds a reference can rebind names,\n * change the default, or atomically replace the whole mapping at runtime via\n * {@link MutableAIProviderRegistry.set}, {@link MutableAIProviderRegistry.setDefault}\n * and {@link MutableAIProviderRegistry.update}, and subscribe to be told when\n * any of those happen. This is the substrate for runtime provider switching:\n * the DI token resolves one stable instance, and consumers re-resolve their\n * cached providers when {@link MutableAIProviderRegistry.subscribe | subscribe}\n * fires. A registry that is never mutated behaves identically to an immutable\n * one, so existing single-registration callers are unaffected.\n *\n * @beta\n */\nexport class MutableAIProviderRegistry {\n constructor(providers, defaultName) {\n this.listeners = new Set();\n // Defensive copy so external mutation of the caller's Map can't desync the\n // registry from its own invariants. Validate the copy we will actually keep.\n const next = new Map(providers);\n MutableAIProviderRegistry.assertValidMapping(next, defaultName);\n this.providers = next;\n this._defaultName = defaultName;\n }\n /**\n * The mapping invariant shared by construction and\n * {@link MutableAIProviderRegistry.update}: at least one provider, and the\n * resolved default name must be one of the keys. Throws\n * with the same messages from both call sites. Validates the finalized map, so\n * callers normalize/copy and resolve the default name first, then validate.\n */\n static assertValidMapping(providers, defaultName) {\n if (providers.size === 0) {\n throw new Error('MutableAIProviderRegistry: at least one provider is required.');\n }\n if (!providers.has(defaultName)) {\n throw new Error(`MutableAIProviderRegistry: default name \"${defaultName}\" not present in providers.`);\n }\n }\n get(name) {\n return this.providers.get(name);\n }\n default() {\n // Construction and every mutator guarantee this lookup succeeds.\n return this.providers.get(this._defaultName);\n }\n defaultName() {\n return this._defaultName;\n }\n names() {\n return [...this.providers.keys()];\n }\n getStatus(name) {\n return __awaiter(this, void 0, void 0, function* () {\n var _a, _b;\n const provider = name === undefined ? this.default() : this.providers.get(name);\n if (!provider)\n return null;\n return (_b = (yield ((_a = provider.getStatus) === null || _a === void 0 ? void 0 : _a.call(provider)))) !== null && _b !== void 0 ? _b : null;\n });\n }\n listStatuses() {\n return __awaiter(this, void 0, void 0, function* () {\n const entries = [...this.providers.entries()];\n return Promise.all(entries.map((_a) => __awaiter(this, [_a], void 0, function* ([name, provider]) {\n var _b, _c;\n return ({\n name,\n isDefault: name === this._defaultName,\n status: (_c = (yield ((_b = provider.getStatus) === null || _b === void 0 ? void 0 : _b.call(provider)))) !== null && _c !== void 0 ? _c : null,\n });\n })));\n });\n }\n /**\n * Rebind (or add) a single name. Rebinding an existing name preserves its\n * position in `names()`; a new name is appended. Notifies subscribers.\n */\n set(name, provider) {\n this.providers.set(name, provider);\n this.notify();\n }\n /**\n * Change the default provider. Throws if `name` is not currently registered.\n * Notifies subscribers.\n */\n setDefault(name) {\n if (!this.providers.has(name)) {\n throw new Error(`MutableAIProviderRegistry: cannot set default to \"${name}\" \u2014 not present in providers.`);\n }\n this._defaultName = name;\n this.notify();\n }\n /**\n * Atomically replace the whole mapping (and optionally the default) in one\n * step, then notify subscribers once. Applies the same validation as the\n * constructor: an empty mapping throws, and the resolved default must be\n * present. When `options.default` is omitted the current default name is\n * retained (and must still exist in the new mapping).\n */\n update(providers, options = {}) {\n var _a;\n const next = providers instanceof Map ? new Map(providers) : new Map(Object.entries(providers));\n const nextDefault = (_a = options.default) !== null && _a !== void 0 ? _a : this._defaultName;\n MutableAIProviderRegistry.assertValidMapping(next, nextDefault);\n this.providers = next;\n this._defaultName = nextDefault;\n this.notify();\n }\n subscribe(listener) {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n /**\n * Fire every listener once. Iterates a snapshot so a listener that\n * unsubscribes (or subscribes) during notification doesn't perturb the\n * in-flight iteration.\n */\n notify() {\n for (const listener of Array.from(this.listeners))\n listener();\n }\n}\n", "import type { AgenticActivityEvents } from './ai-activity-channel';\n\n/**\n * Configuration for {@link AgenticActivityBus}.\n *\n * @beta\n */\nexport interface AgenticActivityBusConfig {\n /** Events that should also be forwarded via BroadcastChannel to other tabs. */\n crossTabEvents?: (keyof AgenticActivityEvents)[];\n /** BroadcastChannel name. Only used when crossTabEvents is non-empty. */\n channelName?: string;\n /**\n * Lazy alternative to {@link AgenticActivityBusConfig.channelName}: called the first\n * time a cross-tab channel is actually needed, in a browser only. Deferring the name\n * computation keeps side effects (e.g. `sessionStorage` reads) out of module-eval and\n * off the non-browser path. Ignored if `channelName` is also set.\n */\n channelNameFactory?: () => string;\n}\n\ntype AnyHandler = (detail: any) => void;\n\n/**\n * Minimal activity-bus surface the drivers depend on. `ChatDriver`/`OrchestratingDriver`\n * only ever *publish* \u2014 accepting this narrow interface (rather than importing the module\n * singleton) lets a headless/server or unit-test host omit the bus entirely, so no live\n * `BroadcastChannel` is ever opened on that path. See {@link NOOP_ACTIVITY_BUS}.\n *\n * @beta\n */\nexport interface ActivityBus {\n publish<K extends keyof AgenticActivityEvents>(type: K, detail: AgenticActivityEvents[K]): void;\n}\n\n/**\n * No-op {@link ActivityBus}. The default when no bus is injected (Node, tests, headless\n * server use) \u2014 publishing goes nowhere and nothing is left open to tear down.\n *\n * @beta\n */\nexport const NOOP_ACTIVITY_BUS: ActivityBus = { publish: () => {} };\n\n/**\n * Typed in-process event bus for AI assistant activity events.\n *\n * Dispatches events synchronously to all local subscribers in the same JS module instance\n * (i.e. the same browser tab). Events listed in `crossTabEvents` are additionally forwarded\n * via a shared `BroadcastChannel` so that other tabs on the same origin receive them.\n *\n * @remarks\n * The pre-instantiated {@link agenticActivityBus} singleton covers all platform use cases.\n * App developers can extend the event map using TypeScript declaration merging on\n * {@link AgenticActivityEvents} and subscribe/publish custom events without any platform changes.\n *\n * @beta\n */\nexport class AgenticActivityBus {\n private readonly subscribers = new Map<string, Set<AnyHandler>>();\n private readonly crossTabEvents: Set<string>;\n private readonly channelNameFactory?: () => string;\n private channel?: BroadcastChannel;\n private channelInitialised = false;\n\n /**\n * @param config - Optional configuration. Omit to create an in-memory-only bus.\n * @beta\n */\n constructor(config?: AgenticActivityBusConfig) {\n this.crossTabEvents = new Set(config?.crossTabEvents ?? []);\n this.channelNameFactory =\n config?.channelName != null ? () => config.channelName! : config?.channelNameFactory;\n }\n\n /**\n * Lazily open the cross-tab `BroadcastChannel` on first use. Deferred (rather than\n * created in the constructor) so that importing this module, or constructing the bus\n * off-browser (Node, tests, headless server), never opens a live channel or reads\n * `sessionStorage` \u2014 both would keep a Node event loop alive and hang the process.\n * Cross-tab forwarding is inherently browser-only, so channel creation is gated on a\n * browser environment; elsewhere the bus stays purely in-process.\n */\n private ensureChannel(): void {\n if (this.channelInitialised) return;\n this.channelInitialised = true;\n const inBrowser = typeof window !== 'undefined' && typeof BroadcastChannel !== 'undefined';\n if (this.crossTabEvents.size === 0 || !this.channelNameFactory || !inBrowser) return;\n this.channel = new BroadcastChannel(this.channelNameFactory());\n this.channel.onmessage = (ev) => {\n const { type, detail } = (ev.data ?? {}) as { type?: string; detail?: unknown };\n if (type) this.notifyLocal(type, detail);\n };\n }\n\n /**\n * Subscribe to an event. Returns an unsubscribe function \u2014 call it in\n * `disconnectedCallback` to avoid memory leaks.\n *\n * @beta\n */\n subscribe<K extends keyof AgenticActivityEvents>(\n type: K,\n handler: (detail: AgenticActivityEvents[K]) => void,\n ): () => void {\n // Open the cross-tab channel (browser only) so this subscriber receives events\n // forwarded from other tabs; no-op off-browser.\n this.ensureChannel();\n let handlers = this.subscribers.get(type as string);\n if (!handlers) {\n handlers = new Set();\n this.subscribers.set(type as string, handlers);\n }\n const h = handler as AnyHandler;\n handlers.add(h);\n return () => handlers!.delete(h);\n }\n\n /**\n * Publish an event to all local subscribers and, if configured, to other tabs\n * via BroadcastChannel.\n *\n * @beta\n */\n publish<K extends keyof AgenticActivityEvents>(type: K, detail: AgenticActivityEvents[K]): void {\n this.notifyLocal(type as string, detail);\n if (this.crossTabEvents.has(type as string)) {\n this.ensureChannel();\n this.channel?.postMessage({ type, detail });\n }\n }\n\n /**\n * Add an event type to the cross-tab forwarding set at runtime.\n * Must be called before the first {@link AgenticActivityBus.publish} of that event type.\n *\n * @beta\n */\n addCrossTabEvent(type: keyof AgenticActivityEvents): void {\n this.crossTabEvents.add(type as string);\n }\n\n /**\n * Close the underlying BroadcastChannel. Call once on application teardown if needed.\n *\n * @beta\n */\n close(): void {\n this.channel?.close();\n this.channel = undefined;\n }\n\n private notifyLocal(type: string, detail: unknown): void {\n this.subscribers.get(type)?.forEach((handler) => handler(detail));\n }\n}\n\n/**\n * Returns a `BroadcastChannel` name that is scoped to the current tab and any popout windows\n * it opens, while remaining isolated from unrelated tabs on the same origin.\n *\n * **How it works:**\n * A UUID is generated once and stored in `sessionStorage`. `sessionStorage` persists across\n * page refreshes (so the channel name stays stable after an F5), but is cleared when the tab\n * is closed. Crucially, when a page opens a child window via `window.open()`, the browser\n * initialises the new window's `sessionStorage` as a copy of the opener's \u2014 so the child\n * inherits the same UUID and therefore the same channel name.\n *\n * Result:\n * - **Same tab + its `window.open()` popouts** share one channel \u2192 events flow as intended.\n * - **Independent tabs** (opened from the address bar, bookmarks, or links) each get a fresh\n * `sessionStorage` and therefore a distinct channel \u2192 no cross-talk between unrelated app\n * instances on the same origin.\n */\nfunction getTabScopedChannelName(base: string): string {\n // Belt-and-braces: this only runs in a browser (see `ensureChannel`), but guard anyway\n // so a direct call off-browser never throws a `sessionStorage is not defined` ReferenceError.\n if (typeof sessionStorage === 'undefined') return `${base}-nostorage`;\n const key = `${base}-tab-id`;\n let id = sessionStorage.getItem(key);\n if (!id) {\n id = crypto.randomUUID();\n sessionStorage.setItem(key, id);\n }\n return `${base}-${id}`;\n}\n\n/**\n * Pre-instantiated singleton event bus for AI assistant activity.\n *\n * - `halo-start` / `halo-stop` are forwarded via a tab-scoped `BroadcastChannel` so that\n * popout windows opened from this tab show halo animations, while remaining isolated from\n * unrelated tabs on the same origin (tab-scoped channel name).\n * - `tool-loop-start` / `tool-loop-end` are cross-tab for the same reason: they describe the\n * assistant's lifecycle (a turn beginning / ending), and the most common subscribers\n * (workspace transitions, post-turn deferred recomputation, UI gates tied to the assistant\n * being idle) need the event regardless of whether the user is interacting with the chat\n * in the main tab or a popout window. Tab-local-only telemetry can subscribe and filter.\n * - `chat-popout` / `chat-popin` are in-memory only \u2014 they must only affect the tab where the\n * user clicked.\n *\n * @beta\n */\nexport const agenticActivityBus = new AgenticActivityBus({\n crossTabEvents: ['halo-start', 'halo-stop', 'tool-loop-start', 'tool-loop-end'],\n // Lazy: the tab-scoped name (and its `sessionStorage` read) is computed on first\n // cross-tab use in a browser, not at module-eval \u2014 so importing this module is\n // side-effect-free and Node/test-safe.\n channelNameFactory: () => getTabScopedChannelName('foundation-ai-activity'),\n});\n", "import type { AIProvider, AIProviderRegistry } from '@genesislcap/foundation-ai';\nimport type { AgentConfig } from './config';\n\n/**\n * Resolve a provider name against the registry and assert it implements\n * `chat()` \u2014 the capability the chat tool-loop depends on. Throws with a\n * message naming the agent so misconfigured agents are easy to track down.\n *\n * Used by both the up-front static walk in `OrchestratingDriver` and by\n * `ChatDriver`'s per-turn resolver for function-form `provider` values.\n *\n * @internal\n */\nexport function resolveChatProvider(\n registry: AIProviderRegistry,\n providerName: string,\n agentName: string,\n): AIProvider {\n const provider = registry.get(providerName);\n if (!provider) {\n const available = registry.names().join(', ') || '(none)';\n throw new Error(\n `Agent \"${agentName}\" references unknown provider \"${providerName}\". Registered: ${available}`,\n );\n }\n if (!provider.chat) {\n throw new Error(\n `Agent \"${agentName}\" resolved to provider \"${providerName}\" which does not implement chat().`,\n );\n }\n return provider;\n}\n\n/**\n * Walk an agent tree (including nested `subAgents`) and validate every static\n * `provider: string` against the registry. Function-form `provider` values are\n * deferred \u2014 they validate on first resolution inside the driver.\n *\n * Throws on the first failure, with the same message shape produced by\n * {@link resolveChatProvider}.\n *\n * @internal\n */\nexport function validateStaticAgentProviders(\n agents: AgentConfig[],\n registry: AIProviderRegistry,\n): void {\n const visited = new Set<AgentConfig>();\n const walk = (agent: AgentConfig): void => {\n if (visited.has(agent)) return;\n visited.add(agent);\n if (typeof agent.provider === 'string') {\n resolveChatProvider(registry, agent.provider, agent.name);\n }\n for (const sub of agent.subAgents ?? []) walk(sub);\n };\n for (const root of agents) walk(root);\n}\n", "/**\n * Module-level append-only timeline of meta/lifecycle events, keyed by session\n * identity (the same `stateKey` space used by the driver registry and the\n * session store).\n *\n * Why a module registry rather than the redux store or the driver:\n * - **Survives the pop-in/pop-out element churn.** A single session can be\n * emitted from up to two element instances (an `expand` bubble + a `collapse`\n * panel) sharing one driver; keying by `stateKey` unifies them into one\n * timeline.\n * - **Survives driver rebuilds.** The driver is torn down and recreated when the\n * host swaps the agents array (see `agentsChanged` / `deleteDriver`), so a\n * driver-owned buffer would lose the timeline mid-session. The `stateKey`\n * outlives the driver.\n * - **Stays out of redux reactivity.** These appends never drive the UI, so\n * there's no reason to pay immutable-reducer cost or flood the Redux DevTools\n * action log with debug noise.\n *\n * Surfaced in `getDebugLog().timeline`, merged chronologically with messages and\n * turn snapshots. Ring-buffered \u2014 the oldest non-`high` events are evicted first\n * while `high`-importance failure events are retained \u2014 so a long-lived session\n * stays bounded in normal use without ever dropping a failure signal.\n *\n * @internal\n */\n\nimport type { TurnFailureReason } from '@genesislcap/foundation-ai';\n\n/**\n * Catalogue of meta event names. This is the documented surface \u2014 extend it as\n * new events are wired in (Tier 2/3 lifecycle, interaction, provider events).\n */\nexport type MetaEventType =\n // Element lifecycle + window placement\n | 'assistant.connected'\n | 'assistant.disconnected'\n | 'assistant.popout'\n | 'assistant.popin'\n // Driver lifecycle / wiring\n | 'driver.created'\n | 'driver.wired'\n | 'driver.unwired'\n // Turn lifecycle\n | 'state.changed'\n | 'turn.start'\n | 'turn.end'\n | 'turn.retry'\n | 'turn.error'\n | 'tool.failed'\n | 'tool.unresolved'\n | 'subagent.started'\n | 'subagent.completed'\n | 'subagent.failed'\n // Routing / providers\n | 'agent.handoff'\n | 'agent.pinned'\n | 'agent.unpinned'\n | 'provider.selected'\n // Blocking interactions\n | 'interaction.requested'\n | 'interaction.resolved'\n // External / unified diagnostics (GENC-1461) \u2014 an out-of-band engine's log folded into this session\n | 'external-diagnostics.folded'\n // Context / cost\n | 'context.updated'\n | 'context.threshold-crossed'\n | 'context.compacted'\n | 'context.condensed'\n // UI + input\n | 'panel.toggled'\n | 'attachment.added'\n | 'file.read-failed'\n | 'suggestions.failed'\n // Session lifecycle (GENC-1351)\n | 'session.cleared'\n | 'session.switched'\n | 'session.switch-deferred'\n | 'persistence.toggled'\n | 'persistence.saved'\n | 'persistence.suppressed'\n | 'persistence.not-resumable'\n | 'persistence.restored'\n | 'persistence.restore-orphan';\n\n/**\n * How much a reader should care about an event \u2014 lets a consumer (or an AI\n * agent) filter the timeline: skip `low` UI/bookkeeping noise, skim `normal`\n * session flow, or jump straight to `high` problem/limit signals when triaging.\n */\nexport type MetaEventImportance = 'high' | 'normal' | 'low';\n\n/**\n * Importance is intrinsic to the event *type*, not the instance, so it's\n * defined once here and stamped automatically by {@link recordMetaEvent} \u2014 call\n * sites never pass it. The `Record` is exhaustive: adding a `MetaEventType`\n * without a level here is a compile error.\n *\n * - `high` \u2014 failures and hard limits you almost always want to see.\n * - `normal` \u2014 meaningful session flow you read to follow what happened.\n * - `low` \u2014 frequent UI / bookkeeping noise, usually safe to skip.\n */\nexport const META_EVENT_IMPORTANCE: Record<MetaEventType, MetaEventImportance> = {\n 'turn.error': 'high',\n 'tool.failed': 'high',\n 'subagent.failed': 'high',\n 'file.read-failed': 'high',\n 'suggestions.failed': 'high',\n 'context.threshold-crossed': 'high',\n 'context.compacted': 'high',\n 'persistence.restore-orphan': 'high',\n\n 'assistant.connected': 'normal',\n 'assistant.disconnected': 'normal',\n 'assistant.popout': 'normal',\n 'assistant.popin': 'normal',\n 'driver.created': 'normal',\n 'state.changed': 'normal',\n 'turn.start': 'normal',\n 'turn.end': 'normal',\n 'turn.retry': 'normal',\n 'tool.unresolved': 'normal',\n 'subagent.started': 'normal',\n 'subagent.completed': 'normal',\n 'agent.handoff': 'normal',\n 'agent.pinned': 'normal',\n 'agent.unpinned': 'normal',\n 'provider.selected': 'normal',\n 'interaction.requested': 'normal',\n 'interaction.resolved': 'normal',\n 'external-diagnostics.folded': 'normal',\n 'session.cleared': 'normal',\n 'session.switched': 'low',\n 'session.switch-deferred': 'low',\n 'persistence.restored': 'normal',\n 'persistence.suppressed': 'normal',\n 'persistence.not-resumable': 'normal',\n\n 'driver.wired': 'low',\n 'driver.unwired': 'low',\n 'context.updated': 'low',\n 'context.condensed': 'low',\n 'panel.toggled': 'low',\n 'persistence.toggled': 'low',\n 'persistence.saved': 'low',\n 'attachment.added': 'low',\n};\n\n/** One entry in the meta-event timeline. */\nexport interface MetaEvent {\n /** Monotonic counter across the session's lifetime (does not reset on driver rebuild). */\n index: number;\n /** ISO timestamp, matching the format used elsewhere in the debug log. */\n timestamp: string;\n /** Event name \u2014 see {@link MetaEventType}. */\n type: MetaEventType;\n /** How much to care about this event \u2014 see {@link META_EVENT_IMPORTANCE}. */\n importance: MetaEventImportance;\n /** Optional structured payload. */\n detail?: Record<string, unknown>;\n}\n\n/**\n * Soft ring-buffer cap. Once exceeded, the oldest *non-`high`* event is evicted;\n * `high`-importance events (failures and hard limits) are never dropped \u2014 they're\n * the whole reason the log exists. So a buffer dominated by `high` events is\n * allowed to float above this cap rather than lose a failure signal; in normal\n * use the frequent `low`/`normal` events keep it near the cap. Entries are cheap.\n */\nconst DEFAULT_MAX_META_EVENTS = 800;\n\ninterface MetaEventBuffer {\n events: MetaEvent[];\n /** Next index to assign \u2014 kept separate from `events.length` so it stays monotonic after eviction. */\n next: number;\n}\n\nconst registry = new Map<string, MetaEventBuffer>();\n\n/**\n * Append a meta event to the timeline for `key`. Once the buffer exceeds\n * {@link DEFAULT_MAX_META_EVENTS}, evicts the oldest *non-`high`* event;\n * `high`-importance events are never evicted. An empty `key` is bucketed under\n * `''`, matching how drivers/stores handle an absent session identity, so\n * callers never need to guard.\n */\nexport function recordMetaEvent(\n key: string,\n type: MetaEventType,\n detail?: Record<string, unknown>,\n): void {\n let buffer = registry.get(key);\n if (!buffer) {\n buffer = { events: [], next: 0 };\n registry.set(key, buffer);\n }\n buffer.events.push({\n index: buffer.next,\n timestamp: new Date().toISOString(),\n type,\n importance: META_EVENT_IMPORTANCE[type],\n detail,\n });\n buffer.next += 1;\n if (buffer.events.length > DEFAULT_MAX_META_EVENTS) {\n // Drop the oldest event that isn't `high` importance. `high` events\n // (failures/limits) are retained even past the cap \u2014 losing a failure\n // signal is worse than briefly exceeding the buffer size. If every retained\n // event is `high` (all-failures session), nothing is evicted and the buffer\n // grows; in practice frequent `low`/`normal` events keep it bounded.\n const evictAt = buffer.events.findIndex((e) => e.importance !== 'high');\n if (evictAt !== -1) {\n buffer.events.splice(evictAt, 1);\n }\n }\n}\n\n/**\n * Why a turn failed or was retried \u2014 stamped as `detail.reason` on `turn.error`\n * and `turn.retry` events, and (since PTC-0) surfaced at the driver's loop\n * boundary via {@link ChatDriverResult.failureReason}. Re-exported from\n * `@genesislcap/foundation-ai` \u2014 where it lives alongside `ChatDriverResult` so\n * the boundary field and this log surface can never drift apart \u2014 under its\n * historical name so existing importers are unaffected. Enumerated so the set\n * stays in sync with the README and call sites can't drift to ad-hoc strings.\n */\nexport type { TurnFailureReason };\n\n/**\n * Record a turn-ending failure (`turn.error`, importance `high`). The `reason`\n * is typed so the high-importance triage surface stays consistent; pass any\n * diagnostic specifics (attempt counts, offending tool names, etc.) in `detail`.\n */\nexport function recordTurnError(\n key: string,\n reason: TurnFailureReason,\n detail?: Record<string, unknown>,\n): void {\n recordMetaEvent(key, 'turn.error', { reason, ...detail });\n}\n\n/**\n * Record a recoverable retry *within* a turn (`turn.retry`, importance `normal`)\n * \u2014 e.g. one malformed/empty attempt that will be retried, as distinct from the\n * final attempt that bails out as a `turn.error`. Include `attempt`/`maxAttempts`\n * in `detail` so the timeline shows which try this was.\n */\nexport function recordTurnRetry(\n key: string,\n reason: TurnFailureReason,\n detail?: Record<string, unknown>,\n): void {\n recordMetaEvent(key, 'turn.retry', { reason, ...detail });\n}\n\n/** Returns the meta-event timeline for `key`, or an empty array if none recorded. */\nexport function getMetaEvents(key: string): ReadonlyArray<MetaEvent> {\n return registry.get(key)?.events ?? [];\n}\n\n/**\n * Merge pre-built meta events into the timeline for `targetKey`, **preserving each\n * event's original `timestamp`** (so it interleaves chronologically on export)\n * while re-indexing onto the target buffer's monotonic counter. Used to fold a\n * sub-agent's harvested events into the parent session \u2014 see\n * `ChatDriver.invokeSubAgent`. Unlike {@link recordMetaEvent} it does not stamp a\n * fresh timestamp; the same non-`high` eviction policy is applied once after the\n * batch so the buffer stays bounded.\n */\nexport function mergeMetaEvents(targetKey: string, events: readonly MetaEvent[]): void {\n if (events.length === 0) return;\n let buffer = registry.get(targetKey);\n if (!buffer) {\n buffer = { events: [], next: 0 };\n registry.set(targetKey, buffer);\n }\n for (const event of events) {\n buffer.events.push({ ...event, index: buffer.next });\n buffer.next += 1;\n }\n // Evict oldest non-`high` events until back under the cap \u2014 same policy as\n // recordMetaEvent; `high` events (failures/limits) are never dropped. Single\n // pass: take the overflow count, then drop that many of the oldest non-`high`\n // events in order (if there aren't enough non-`high`, the buffer floats above\n // the cap rather than losing a failure signal).\n let toEvict = buffer.events.length - DEFAULT_MAX_META_EVENTS;\n if (toEvict > 0) {\n buffer.events = buffer.events.filter((e) => {\n if (toEvict > 0 && e.importance !== 'high') {\n toEvict -= 1;\n return false;\n }\n return true;\n });\n }\n}\n\n/**\n * Drop the entire timeline for `key`. Used to discard a sub-agent's transient\n * per-invocation session once its events have been harvested into the parent, so\n * the module registry doesn't accumulate one orphaned bucket per sub-agent run.\n */\nexport function clearSession(key: string): void {\n registry.delete(key);\n}\n\n/**\n * Human/agent-facing guide emitted as the first key of the exported debug log,\n * so whoever opens the JSON (often an AI agent) knows how to read it without\n * reverse-engineering the shape. Kept here next to the event catalogue it\n * describes \u2014 but proximity alone demonstrably did NOT keep the two in sync\n * (`refusal` was missing from both reason lists for a whole release), so\n * `debug-event-log.test.ts` now asserts that every `TurnFailureReason` and every\n * `SubAgentFailureReason` is named here, and fails the build when one is added\n * without a matching sentence. Enumerations below read as exhaustive and WILL be\n * trusted by an agent reading the JSON \u2014 keep them so.\n */\nexport const DEBUG_LOG_README: readonly string[] = [\n 'This is an exported debug log for the Genesis AI assistant. Read it top-to-bottom.',\n '`timeline` is the entire session as one array, already sorted chronologically by `timestamp` (ISO 8601). Every entry has a `kind`.',\n 'Timestamps are millisecond-resolution; entries that share the same millisecond are ordered by a fixed kind rank (event, then turn, then message), which is a heuristic and may not reflect exact causal order within that millisecond \u2014 e.g. a user message and the turn it triggered, or a final assistant message and its turn.end event, can appear in either order depending on whether they landed in the same millisecond. Read the logical structure of a turn rather than over-interpreting the micro-ordering of co-timestamped entries of different kinds.',\n \"kind:'message' \u2014 the conversation. `role` is user/assistant/tool/system-event/synthetic-user; `agentName` says which agent produced it; `toolCalls`/`toolResult`/`interaction` carry tool and widget activity; `inputTokens`/`outputTokens`/`cost` are per-message LLM usage, where `inputTokens` is the WHOLE prompt for that request and `cacheReadTokens`/`cacheWriteTokens` BREAK IT DOWN rather than add to it \u2014 uncached input is `inputTokens` minus those two, and adding the cache fields to `inputTokens` counts the prompt twice. The cache fields are absent on providers that report no cache split (Gemini reports reads only, since implicit caching bills no write) and on messages persisted before they existed, so read them as 0 when missing. Each bucket bills at a different rate \u2014 cache reads a fraction of uncached input, cache writes a premium, output highest \u2014 so a large token count at a small cost means the prompt was mostly cache hits. `externalCostUsd` is any non-LLM cost a widget reported for its own external service calls (folded into the session cost total alongside `cost`). On model-produced assistant messages, `model` is the concrete model id that generated it (e.g. 'gemini-2.5-flash-lite') and `providerName` is the registry slot it resolved under (e.g. a tier name like 'high'/'low', or the default); together they attribute the message \u2014 and any tool calls it carries \u2014 to an exact model even across a mid-session vendor/tier switch, where one slot name can map to different models before and after the switch. Both are undefined on any entry that is NOT an LLM response: non-assistant roles (user/tool/system-event) and 'synthetic-user' echoes; assistant interaction/widget entries (empty content carrying an `interaction` \u2014 a rendered widget, not a model turn); driver-authored assistant fallbacks (the timeout, repeated-malformed-call, and empty-response apology messages); and messages restored from a session persisted before these fields existed. One partial case: on a genuine model turn whose provider exposes no `getStatus` (or reports no model), `providerName` is still set but `model` alone is undefined. A 'synthetic-user' message is a display-only echo of an interaction outcome (e.g. the answer a widget reported): it renders on the user's side of the chat and `agentName` is the agent that created it, but it is never sent to the LLM \u2014 so it has no matching 'turn' and the model learns the outcome only from the corresponding tool result.\",\n \"Sub-agent messages appear inline. When a tool delegates to a sub-agent (via `requestSubAgent`), the sub-agent's whole conversation \u2014 its own assistant/tool messages, each with their own `content`/`thinking`/`toolCalls`/`toolResult` and per-message `model`/`providerName`/`inputTokens`/`outputTokens`/`cacheReadTokens`/`cacheWriteTokens`/`cost` \u2014 is hoisted into the timeline as ordinary kind:'message' entries, interleaved by timestamp right after the tool call that spawned them (so you read the delegation top-to-bottom). A hoisted entry is marked: `subAgentDepth` is its delegation depth (1 for a sub-agent, 2 for a sub-agent's sub-agent, \u2026), `subAgentOf` is the id of the parent tool call that spawned it (correlates it back even when two sub-agents run in one parent turn), `subAgentName` is the sub-agent's own name, and `agentName` is rewritten to a `\\\"<parent> \u203A <sub-agent>\\\"` breadcrumb (composing when nested, e.g. `\\\"UI Builder \u203A Planner \u203A Grounding\\\"`). The sub-agent's per-LLM-call snapshots also surface as kind:'turn' entries with an N-M `turnIndex`, and subagent.started/completed (or subagent.failed) events bracket the run. Per-message `cost` on hoisted entries is already part of the session total (it is summed from the un-flattened history), so summing the top-level timeline does NOT double-count.\",\n \"kind:'turn' \u2014 one LLM call. `turnIndex` is a string: a top-level turn is the bare counter ('0', '1', \u2026); a sub-agent's turns are numbered under the parent turn that activated them ('3-1', '3-2', \u2026, and a nested sub-agent contributes '3-2-1', \u2026), and `agentName` names the agent that ran the turn. `systemPrompt` and `toolNames` are what the model saw. A systemPrompt of '<repeated \u2014 identical to turn N>' was byte-identical to turn N and de-duplicated; the full prompt is shown whenever it changes (often because a stateful agent advanced), so prompt evolution is visible.\",\n \"kind:'turn'.`agentSnapshot` \u2014 the active agent's own view of its internal state, captured at that turn. An agent opts into this by exposing a `getDebugSnapshot()` that returns JSON-serializable per-state info; stateful/flow agents wire it automatically, so you can watch a flow advance turn-by-turn (e.g. current step, cursor, collected fields, pending changes). Absent for agents that don't expose one.\",\n \"kind:'event' \u2014 a meta/lifecycle event. `type` names it (see below); `detail` carries structured data. `detail.placement` is the emitting UI instance: 'bubble' (collapsed), 'panel' (popped-out), or 'standalone'.\",\n \"Each 'event' also has an `importance`: 'high' (failures/limits \u2014 turn.error, tool.failed, subagent.failed, file.read-failed, suggestions.failed, context.threshold-crossed), 'normal' (session flow \u2014 connects, turns, retries, handoffs, agent/provider changes, interactions, sub-agent start/complete), or 'low' (skippable UI/bookkeeping noise \u2014 panel.toggled, attachment.added, driver.wired/unwired, context.updated, context.condensed). To skim, ignore importance:'low'; to triage a failure, filter to importance:'high' then read the nearby messages and turns. A 'high' turn.error is often preceded by one or more 'normal' turn.retry events for the same reason \u2014 read them together to see how many attempts were made before bailing. 'message' and 'turn' entries carry no importance \u2014 they are the substance, always read them.\",\n 'Event types: assistant.connected/disconnected (mount + placement + whether the session was created or restored), assistant.popout/popin (window placement), driver.created/wired/unwired (which driver is live and why it stops/starts responding across a popout), state.changed (idle\u2194loading), turn.start/turn.end (turn boundary; turn.end carries durationMs), turn.retry (a recoverable in-turn retry \u2014 detail.reason plus attempt/maxAttempts; for malformed calls also finishMessage; for empty responses also the provider finishReason + thoughtsTokens + parts breakdown), turn.error (a turn failed or hit a guardrail \u2014 detail.reason is one of exception/malformed-function-call/empty-response/unknown-tool-limit/max-iterations/response-truncated/refusal/budget-exhausted, plus reason-specific diagnostics: attempts (for empty-response also finishReason + thoughtsTokens + a parts breakdown, distinguishing a thinking-only STOP from a truly empty turn), finishMessage, for response-truncated the model + maxTokens + outputTokens + tools, unknownTools (split into staleTools \u2014 real earlier this activation but retired by the current state or hidden behind an open exclusive fold \u2014 and hallucinatedTools \u2014 never advertised) + availableTools, iterations + limit, for budget-exhausted the budgetUsd + spentUsd figures reported by the proxy plus the resolved vendor, or name + message for exceptions), tool.failed (a tool threw), tool.unresolved (the model called a tool that could not be dispatched \u2014 detail.kind is folded/fold-hidden/stale/unknown, plus tool + agent and, for the counted kinds, the consecutive streak; the recurring lead-up to an unknown-tool-limit turn.error), subagent.started/completed/failed (the lifecycle of a `requestSubAgent` delegation \u2014 detail.agent names the sub-agent; these bracket the sub-agent turns that appear as kind:turn entries with an N-M `turnIndex`; subagent.failed also carries detail.reason, one of max_iterations/malformed_tool_call/empty_response/unknown_tool_limit/timeout/response_truncated/refusal/budget_exhausted; budget_exhausted is terminal for the PARENT turn too \u2014 the parent stops rather than calling the model again into the same wall), agent.handoff (routing; from=null is the initial activation), agent.pinned/unpinned (forced routing), provider.selected (model/provider for the upcoming turns), interaction.requested/resolved (blocking user widgets \u2014 explain quiet gaps; note that when a sub-agent opens a widget, detail.agent \u2014 and the agentName on the interaction message \u2014 is the HOST agent that owns the widget, NOT the sub-agent that asked, because widgets render and resolve on the host driver), context.updated/threshold-crossed (token + cost), context.condensed (a stale tool payload was collapsed out of the model-bound history by a `condenseWhen` declaration on the tool \u2014 detail.tool + toolCallId, target args|response, trigger (superseded:<key> or age:<n>), stubLen, and an estimated tokensSaved; stored history and this log keep the FULL payload, so the model-visible slice at any point is the full history minus the condensations recorded up to then), panel.toggled, attachment.added, file.read-failed, suggestions.failed.',\n 'Sub-agent meta events: a sub-agent\\'s own turn.retry/turn.error/tool.failed/tool.unresolved events are merged into this same timeline, tagged with `detail.subAgent` \u2014 a `\"<parent> \u203A <sub-agent>\"` breadcrumb that composes when nested (e.g. `\"UI Builder \u203A Planner \u203A Grounding\"`) \u2014 and interleaved by their original timestamps within the subagent.started\u2192completed/failed bracket. These are the per-attempt/per-failure signals that do NOT appear among the sub-agent\\'s (hoisted) messages: a malformed/empty attempt that gets retried produces no message, and the stale-vs-hallucinated split and streak counts live only on the event. A sub-agent\\'s high-volume, message-derivable events (turn.start/turn.end, provider.selected, context.updated) are intentionally NOT merged \u2014 read its hoisted messages for model/tokens/cost and turn-by-turn activity, and the bracketing subagent.* events for the run\\'s span.',\n \"`meta` holds context captured at export time: agentSummary (full agent configs), context (active model, token usage, session cost), activeDebugSnapshot (the active agent's `getDebugSnapshot()` taken fresh at export \u2014 reflects state NOW, which may have advanced beyond the last turn's agentSnapshot), debug (optional host-supplied debug state), host, and the export timestamp.\",\n 'To debug a failure: find the last turn.error or tool.failed, then read upward for the user message, the turn(s), and the agent/provider/state events that led into it.',\n];\n\n/**\n * Removes all entries. Exposed for test isolation only \u2014 not part of the\n * public API.\n *\n * @internal\n */\nexport function clearMetaEventRegistry(): void {\n registry.clear();\n}\n", "import { createLogger } from '@genesislcap/foundation-logger';\n\nexport const logger = createLogger('ai-assistant');\n", "import type { InteractionContext } from '../types/interaction-context';\nimport { logger } from '../utils/logger';\n\n/**\n * A created {@link InteractionContext} plus the host-only `dispose` handle. The\n * driver keeps the handle (so it can tear the context down on resolve/evict) and\n * hands only `context` to the widget \u2014 widgets must not dispose their own context.\n *\n * @internal\n */\nexport interface InteractionContextHandle {\n readonly context: InteractionContext;\n /**\n * Run every registered `onDispose` callback once (in registration order), then\n * clear listeners. Idempotent. Called by the driver from `resolveInteraction`\n * and on driver teardown \u2014 never on element unmount.\n */\n dispose(): void;\n}\n\n/**\n * Create a live, per-interaction context (GENC-1390). Framework-agnostic: the\n * `subscribe`/`notify` pair is a plain observer set, not FAST reactivity. See\n * {@link InteractionContext} for the lifetime/semantics contract.\n *\n * @internal\n */\nexport function createInteractionContext(interactionId: string): InteractionContextHandle {\n const state: Record<string, unknown> = {};\n const onceCache = new Map<string, unknown>();\n const listeners = new Set<() => void>();\n const disposers = new Set<() => void>();\n let disposed = false;\n\n const context: InteractionContext = {\n interactionId,\n state,\n once<T>(key: string, factory: () => T): T | null {\n if (onceCache.has(key)) return onceCache.get(key) as T;\n // Interaction already ended (resolve/timeout/evict): refuse to run the factory.\n // A resource created here would leak \u2014 dispose has already run every `onDispose`\n // and won't run again. Return null so a stray late call (e.g. an async callback\n // that lands after a `timeoutMs` timeout) degrades instead of crashing or leaking.\n if (disposed) {\n logger.warn(\n `InteractionContext.once(\"${key}\") called after dispose; not creating a resource on an ended interaction.`,\n );\n return null;\n }\n const value = factory();\n onceCache.set(key, value);\n return value;\n },\n notify(): void {\n // A Set tolerates a listener unsubscribing mid-walk (matches\n // interaction-panel-session's forEach); a throwing subscriber must not stop the rest.\n for (const listener of listeners) {\n try {\n listener();\n } catch (e) {\n logger.error('InteractionContext subscriber threw during notify()', e);\n }\n }\n },\n subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n onDispose(fn: () => void): void {\n // Late registration after the interaction already ended: run immediately so\n // callers never leak a resource by registering a beat too late.\n if (disposed) {\n fn();\n return;\n }\n disposers.add(fn);\n },\n };\n\n return {\n context,\n dispose(): void {\n if (disposed) return;\n disposed = true;\n for (const fn of disposers) {\n try {\n fn();\n } catch (e) {\n logger.error('InteractionContext onDispose callback threw', e);\n }\n }\n disposers.clear();\n listeners.clear();\n // Release memoised `once` values (sockets, timers, service handles) for GC \u2014 the resources\n // themselves are closed via their `onDispose`, but drop the references too.\n onceCache.clear();\n },\n };\n}\n", "import type { ChatMessage, CondensePolicy, CondenseTrigger } from '@genesislcap/foundation-ai';\n\n/**\n * Tool-context condensation: collapse stale tool payloads out of the history\n * sent to the model, while leaving stored history untouched.\n *\n * The driver owns the registry (tool handlers populate it via `condenseWhen`)\n * and the cadence (this runs before every provider call). This module owns the\n * pure application: given the registry + the current loop iteration, produce a\n * rewritten copy of the history with stale args/results replaced by stubs. Kept\n * pure (no driver/session state, no logging) so it unit-tests in isolation \u2014\n * the one-time `context.condensed` signal is delivered via an `onCondensed`\n * callback rather than reaching into the debug-event log directly.\n *\n * @packageDocumentation\n */\n\n/**\n * Below this serialized size a tool payload isn't worth condensing \u2014 the stub\n * would save little and cost a breadcrumb. A driver-level floor so the public\n * `condenseWhen` API needs no per-policy threshold field.\n */\nexport const CONDENSE_MIN_CHARS = 1000;\n\n/** Key the collapsed args are stored under \u2014 a tool-call's args must stay a Record. */\nexport const CONDENSED_ARGS_KEY = 'condensed';\n\n/**\n * Rough chars-per-token divisor for the `tokensSaved` estimate. No tokenizer is\n * available in this stack; ~4 chars/token is the usual English approximation.\n */\nconst APPROX_CHARS_PER_TOKEN = 4;\n\n/**\n * A `condenseWhen` policy registered against a tool-call id, with its age clock\n * and report-once flags. The driver holds these in a `Map<toolCallId, \u2026>`;\n * {@link applyCondensation} reads them and flips the `reported*` flags so the\n * `context.condensed` signal fires once per payload, not once per provider call.\n */\nexport interface RegisteredCondensePolicy {\n policy: CondensePolicy;\n /**\n * Monotonic model-call sequence (`modelCallSeq`) when `condenseWhen` was called\n * \u2014 the origin of the age clock. Driver-lifetime and NOT reset per turn, so age\n * is measured consistently across turn boundaries (the field name is historical;\n * it is not the per-turn loop iteration).\n */\n iteration: number;\n /** Turn (`sendMessage`) sequence when the call was made \u2014 the `turnEnd` clock. */\n turn: number;\n /** Agent-activation sequence when the call was made \u2014 the `agentEnd` clock. */\n activation: number;\n /** App-controlled phase epoch when the call was made \u2014 the `phaseEnd` clock. */\n phaseEpoch: number;\n /** `context.condensed` already emitted for the args payload (fire-once). */\n reportedArgs?: boolean;\n /** `context.condensed` already emitted for the response payload (fire-once). */\n reportedResponse?: boolean;\n}\n\n/**\n * The driver's live state at the moment of a provider call \u2014 the clocks every\n * trigger is evaluated against. Passed by the driver; kept as an interface so the\n * transform stays a pure function of (history, policies, clocks).\n */\nexport interface CondenseContext {\n /** Monotonic model-call sequence now \u2014 the `age` clock. */\n modelCall: number;\n /** Monotonic turn (`sendMessage`) sequence now \u2014 the `turnEnd` clock. */\n turn: number;\n /** Whether the agent activation that made a call has since ended \u2014 the `agentEnd` clock. */\n activationEnded: (activation: number) => boolean;\n /**\n * Whether a later phase epoch is current than the one a call was made in \u2014 the\n * `phaseEnd` clock. True once `endPhase()` has been called since the call.\n */\n phaseEnded: (phaseEpoch: number) => boolean;\n /**\n * Collapse in batches of this many model-calls instead of continuously. A positive\n * integer; decimals are floored and anything below `1` becomes `1`. Omit (or `1`) to\n * collapse as soon as a trigger fires, which is the historical behaviour.\n *\n * Condensation rewrites a payload *in place*, so the model-bound history is not\n * append-only and every prompt-cache entry written before the rewrite is invalidated\n * from that position on. Collapsing the moment each trigger fires therefore breaks the\n * cache on nearly every call of a re-read loop \u2014 the case condensation exists to\n * contain. Batching holds the collapse set still between boundaries so the prefix is\n * append-only in between, trading up to `batchCalls` calls' worth of extra context for\n * one cache break per batch instead of one per call.\n *\n * `agentEnd` and `phaseEnd` are exempt and still collapse as they fire: they mark a\n * discontinuity that invalidates the cached prefix anyway, so deferring them would hold\n * stale payloads longer for nothing.\n */\n batchCalls?: number;\n}\n\n/**\n * Structured detail for a `context.condensed` meta-event. The index signature\n * lets it satisfy `recordMetaEvent`'s `Record<string, unknown>` detail param\n * while the named fields stay strictly typed.\n */\nexport interface CondensedEventDetail {\n [key: string]: unknown;\n /** Tool-loop iteration the collapsed call was made on. */\n turn: number;\n toolCallId: string;\n tool: string;\n target: 'args' | 'response';\n /** Human-readable trigger, e.g. `superseded:Foo.tsx` or `age:3`. */\n trigger: string;\n /** Length of the replacement stub. */\n stubLen: number;\n /** Estimated input tokens saved this collapse (char/4 \u2014 no tokenizer in-stack). */\n tokensSaved: number;\n}\n\n/** Short human-readable reason for the stub text, per fired trigger. */\nfunction triggerReason(trigger: CondenseTrigger): string {\n switch (trigger.kind) {\n case 'age':\n return 'aged out';\n case 'turnEnd':\n return 'turn ended';\n case 'agentEnd':\n return 'agent finished';\n case 'phaseEnd':\n return 'phase ended';\n default:\n return 'superseded';\n }\n}\n\n/** Framework-generated `pointer` stub \u2014 advertises that re-calling restores the content. */\nfunction condenseStub(\n target: 'args' | 'response',\n tool: string,\n trigger: CondenseTrigger,\n origLen: number,\n): string {\n const what = target === 'args' ? 'args' : 'result';\n const key = trigger.kind === 'superseded' ? ` ${trigger.by}` : '';\n return `[${tool}${key} \u2014 ${what} elided, ~${origLen} chars (${triggerReason(trigger)}); re-call to restore]`;\n}\n\n/** Stable label for the `context.condensed` meta-event's `trigger` field. */\nfunction triggerLabel(trigger: CondenseTrigger): string {\n switch (trigger.kind) {\n case 'age':\n return `age:${trigger.turns}`;\n case 'superseded':\n return `superseded:${trigger.by}`;\n default:\n return trigger.kind; // 'turnEnd' | 'agentEnd' | 'phaseEnd'\n }\n}\n\nfunction estimateTokensSaved(origLen: number, stubLen: number): number {\n return Math.max(0, Math.ceil((origLen - stubLen) / APPROX_CHARS_PER_TOKEN));\n}\n\n/**\n * Whether a trigger marks a genuine discontinuity rather than firing continuously, and so is\n * exempt from batching.\n *\n * `agentEnd` advances only when the active agent's name changes (or a sub-agent completes /\n * the agent is released), which swaps the system prompt and tool definitions \u2014 those render\n * before the messages, so the cached prefix is invalidated at that point regardless. `phaseEnd`\n * is the app declaring the same kind of boundary explicitly, and falls back to `agentEnd`.\n * Deferring either to the next batch would buy no cache and only hold stale payloads longer.\n *\n * The rest fire continuously (`superseded`, `age`) or at a point where the history is otherwise\n * append-only (`turnEnd` \u2014 a new turn appends a user message, leaving the previous entry live),\n * so batching them is exactly where the cache is won.\n */\nfunction marksDiscontinuity(kind: CondenseTrigger['kind']): boolean {\n return kind === 'agentEnd' || kind === 'phaseEnd';\n}\n\n/**\n * Collapse stale tool payloads (declared via `condenseWhen`) out of the\n * model-bound history. Pure over the `history` array \u2014 it emits new message\n * objects and never mutates the input messages (mirroring the agent-masking\n * transform). It DOES, however, flip the `reported*` flag on the matching\n * `policies` entry the first time a payload collapses \u2014 the report-once gate that\n * keeps `onCondensed` firing once per (tool call, payload) even though the\n * collapse itself re-runs before every provider call.\n *\n * Triggers (a policy may list several via `on: Trigger[]` \u2014 the FIRST to fire\n * collapses the payload; all are monotonic, so the collapse never reverts):\n * - `superseded` \u2014 among all registered calls sharing a `by` key, the LAST in\n * history order survives; every earlier one's targeted payload collapses. A\n * re-call with the same key becomes the new survivor and re-arms the rest.\n * - `age` \u2014 the result is first visible one model-call after the call, so `turns`\n * is how many model-calls may see the full result before it collapses\n * (fires when `modelCall \u2212 callModelCall > turns`): `turns: 1` is seen once,\n * then collapses. The clock is monotonic across turns.\n * - `turnEnd` \u2014 collapses once the turn (`sendMessage`) that made the call has\n * ended (fires when `turn > callTurn`): full for the rest of that request,\n * gone on every later one.\n * - `agentEnd` \u2014 collapses once the agent activation that made the call has ended\n * (a swap to another agent, or `releaseAgent`/`completeSubAgent`): kept across\n * all of the agent's turns, dropped when its flow finishes.\n * - `phaseEnd` \u2014 collapses once the app advances its phase epoch via `endPhase()`\n * after the call (a sub-`agentEnd` boundary the author declares), OR at\n * `agentEnd` as a backstop if no boundary is ever declared.\n *\n * The tool-call/result envelope is never removed (providers reject orphaned\n * calls/results) \u2014 only the args object or the result content is replaced.\n *\n * @param history - The to-model history copy to rewrite (not mutated).\n * @param policies - The driver's registry, keyed by tool-call id. Its entries'\n * `reported*` flags are flipped as payloads first collapse.\n * @param ctx - The driver's live clocks (model-call / turn / agent-activation).\n * @param onCondensed - Invoked once per payload at its full\u2192stub transition.\n */\nexport function applyCondensation(\n history: ChatMessage[],\n policies: Map<string, RegisteredCondensePolicy>,\n ctx: CondenseContext,\n onCondensed: (detail: CondensedEventDetail) => void,\n): ChatMessage[] {\n if (policies.size === 0) return history;\n\n const triggersOf = (entry: RegisteredCondensePolicy): CondenseTrigger[] =>\n Array.isArray(entry.policy.on) ? entry.policy.on : [entry.policy.on];\n\n // One pass: resolve supersession survivors and a toolCallId \u2192 tool-name\n // lookup. For each `superseded` key the LAST call in history order survives.\n // The name lookup lets a tool message (which carries only an id) name its tool\n // in stubs and events.\n // Batch boundary: the collapse set is resolved as of this model-call and stays put\n // until the next boundary, so the prefix is append-only in between. `batchCalls` of 1\n // (the default) makes this `ctx.modelCall` \u2014 i.e. no batching.\n const batchCalls = Math.max(1, Math.floor(ctx.batchCalls ?? 1));\n const asOf =\n batchCalls === 1 ? ctx.modelCall : Math.floor(ctx.modelCall / batchCalls) * batchCalls;\n // A call made after the boundary is invisible to this pass in BOTH directions: it\n // cannot supersede an older call (which would collapse the older payload early), and\n // it cannot itself collapse (which would elide the very result just fetched). Unbatched,\n // the boundary is the live clock and this gate is off entirely \u2014 a call registered on\n // the current model-call is still eligible, as it always was.\n const withinBatch = (entry: RegisteredCondensePolicy): boolean =>\n batchCalls === 1 || entry.iteration <= asOf;\n\n const latestByKey = new Map<string, string>();\n const nameById = new Map<string, string>();\n for (const msg of history) {\n if (!msg.toolCalls?.length) continue;\n for (const tc of msg.toolCalls) {\n nameById.set(tc.id, tc.name);\n const entry = policies.get(tc.id);\n if (!entry || !withinBatch(entry)) continue;\n for (const t of triggersOf(entry)) {\n if (t.kind === 'superseded') latestByKey.set(t.by, tc.id);\n }\n }\n }\n\n const triggerFires = (\n toolCallId: string,\n entry: RegisteredCondensePolicy,\n trig: CondenseTrigger,\n ): boolean => {\n switch (trig.kind) {\n // Result first visible one model-call after the call, so collapse one call\n // past the last allowed view: turns:1 \u2192 seen once, then gone. Monotonic\n // clock, so this holds across turn boundaries too.\n case 'age':\n return asOf - entry.iteration > trig.turns;\n case 'turnEnd':\n return ctx.turn > entry.turn;\n case 'agentEnd':\n return ctx.activationEnded(entry.activation);\n // Fires when the app advanced the phase epoch since the call \u2014 OR, as a\n // backstop, when the whole activation has ended, so a phase boundary that\n // is never declared still collapses at `agentEnd` rather than never.\n case 'phaseEnd':\n return ctx.phaseEnded(entry.phaseEpoch) || ctx.activationEnded(entry.activation);\n default:\n return latestByKey.get(trig.by) !== toolCallId; // superseded by a newer call\n }\n };\n\n // The first listed trigger that fires \u2014 drives the collapse, the stub reason,\n // and the event label. `undefined` means the payload stays full.\n const firstFired = (\n toolCallId: string,\n entry: RegisteredCondensePolicy,\n ): CondenseTrigger | undefined =>\n triggersOf(entry).find(\n (t) =>\n (marksDiscontinuity(t.kind) || withinBatch(entry)) && triggerFires(toolCallId, entry, t),\n );\n\n return history.map((msg) => {\n // Tool-call ARGS live on the assistant message.\n if (msg.toolCalls?.length) {\n let changed = false;\n const toolCalls = msg.toolCalls.map((tc) => {\n const entry = policies.get(tc.id);\n if (!entry?.policy.args) return tc;\n const fired = firstFired(tc.id, entry);\n if (!fired) return tc;\n const origLen = JSON.stringify(tc.args ?? {}).length;\n if (origLen < CONDENSE_MIN_CHARS) return tc;\n changed = true;\n const result = entry.policy.args;\n // Args must stay a Record; `drop` is an empty object, otherwise stash the\n // stub under a single key. Spread `tc` so providerMetadata (e.g. the\n // Gemini reasoning signature that must round-trip) and UI fields survive.\n const args: Record<string, unknown> =\n result === 'drop'\n ? {}\n : {\n [CONDENSED_ARGS_KEY]:\n result === 'pointer'\n ? condenseStub('args', tc.name, fired, origLen)\n : result.replaceWith,\n };\n if (!entry.reportedArgs) {\n entry.reportedArgs = true;\n const stubLen = JSON.stringify(args).length;\n onCondensed({\n turn: entry.iteration,\n toolCallId: tc.id,\n tool: tc.name,\n target: 'args',\n trigger: triggerLabel(fired),\n stubLen,\n tokensSaved: estimateTokensSaved(origLen, stubLen),\n });\n }\n return { ...tc, args };\n });\n return changed ? { ...msg, toolCalls } : msg;\n }\n\n // The tool RESULT lives on the tool message.\n if (msg.toolResult) {\n const entry = policies.get(msg.toolResult.toolCallId);\n // Defensive `?? 0` for restored/malformed history \u2014 `content` is typed\n // `string`, but a 0-length payload is simply below the floor and skipped.\n const origLen = msg.toolResult.content?.length ?? 0;\n const fired = entry?.policy.response\n ? firstFired(msg.toolResult.toolCallId, entry)\n : undefined;\n if (entry && fired && origLen >= CONDENSE_MIN_CHARS) {\n const tool = nameById.get(msg.toolResult.toolCallId) ?? msg.toolResult.toolCallId;\n const result = entry.policy.response!; // `fired` is only set when response is declared\n // Kept non-empty \u2014 Anthropic rejects empty tool_result content.\n const content =\n result === 'drop'\n ? '[elided]'\n : result === 'pointer'\n ? condenseStub('response', tool, fired, origLen)\n : result.replaceWith;\n if (!entry.reportedResponse) {\n entry.reportedResponse = true;\n onCondensed({\n turn: entry.iteration,\n toolCallId: msg.toolResult.toolCallId,\n tool,\n target: 'response',\n trigger: triggerLabel(fired),\n stubLen: content.length,\n tokensSaved: estimateTokensSaved(origLen, content.length),\n });\n }\n return { ...msg, toolResult: { ...msg.toolResult, content } };\n }\n }\n\n return msg;\n });\n}\n", "import type { ChatMessage } from '@genesislcap/foundation-ai';\n\n/**\n * Masks the tool-specific payload of a single message \u2014 clears tool call args\n * and replaces tool result content with a placeholder. Used when passing history\n * to an agent that should not see another agent's implementation detail.\n */\nfunction maskToolPayload(msg: ChatMessage): ChatMessage {\n if (msg.toolCalls?.length) {\n return { ...msg, toolCalls: msg.toolCalls.map((tc) => ({ ...tc, args: {} })) };\n }\n if (msg.toolResult) {\n return {\n ...msg,\n toolResult: { ...msg.toolResult, content: \"[other agent's tool result omitted]\" },\n };\n }\n return msg;\n}\n\n/**\n * Prepares history for the LLM only: masks tool call args and results from other\n * agents so the active specialist is not confused by tools it does not have.\n * Canonical history in `ChatDriver` stays unmasked for UI and logging.\n */\nexport function transformHistoryForAgent(history: ChatMessage[], agentName: string): ChatMessage[] {\n return history.map((msg) => {\n if (!msg.agentName || msg.agentName === agentName) return msg;\n return maskToolPayload(msg);\n });\n}\n\n/**\n * Applies a history cap for sub-agent context: the last `cap` messages are passed\n * verbatim; older messages have their tool payloads masked.\n */\nexport function applyHistoryCap(history: readonly ChatMessage[], cap: number): ChatMessage[] {\n const cutoff = history.length - cap;\n return history.map((msg, i) => (i < cutoff ? maskToolPayload(msg) : msg));\n}\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Compaction (GENC-1351 \u00A75.7) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Recent messages kept verbatim when compacting; everything earlier is summarized. */\nexport const COMPACT_KEEP_RECENT_MESSAGES = 4;\n\n/** Don't bother compacting unless at least this many messages would be summarized. */\nexport const COMPACT_MIN_MESSAGES_TO_COMPACT = 4;\n\n/**\n * Index at which the verbatim tail begins \u2014 everything before it gets summarized.\n * The tail starts on a clean turn boundary (a `user` message): a user message\n * never appears between a `tool_use` and its `tool_result`, so cutting there\n * guarantees the summarized region is tool-pair-balanced (compaction only runs\n * when idle, so history is turn-complete). Returns `null` when there is nothing\n * worth compacting (too short, or no earlier user boundary) \u2014 e.g. a freshly\n * restored session whose only user turn is the current one.\n */\nexport function findCompactionCut(history: readonly ChatMessage[]): number | null {\n if (history.length < COMPACT_KEEP_RECENT_MESSAGES + COMPACT_MIN_MESSAGES_TO_COMPACT) {\n return null;\n }\n const target = history.length - COMPACT_KEEP_RECENT_MESSAGES;\n for (let i = target; i > 0; i -= 1) {\n if (history[i].role === 'user') {\n return i >= COMPACT_MIN_MESSAGES_TO_COMPACT ? i : null;\n }\n }\n return null;\n}\n\n/** One-line rendering of a message for the summarizer transcript. */\nfunction renderMessageForSummary(m: ChatMessage): string {\n switch (m.role) {\n case 'compacted-summary':\n return `[Earlier summary] ${m.content}`;\n case 'user':\n return m.content ? `User: ${m.content}` : '';\n case 'assistant': {\n // Reasoning (\"Thinking\") and narration (\"Working\") are display-only assistant splits\n // (GENC-1410) with no tool calls of their own \u2014 fold them into the summary too, labelled\n // the same as the UI so the summarizer knows they were internal, not a final answer.\n if (m.category === 'reasoning') {\n return m.content ? `Thinking: ${m.content}` : '';\n }\n if (m.category === 'narration') {\n return m.content ? `Working: ${m.content}` : '';\n }\n if (m.toolCalls?.length) {\n const calls = m.toolCalls.map((t) => t.name).join(', ');\n return m.content\n ? `Assistant: ${m.content} (called: ${calls})`\n : `Assistant called: ${calls}`;\n }\n return m.content ? `Assistant: ${m.content}` : '';\n }\n case 'tool':\n return m.toolResult ? `Tool result: ${m.toolResult.content}` : '';\n default:\n return ''; // system-event / synthetic-user \u2014 not part of the model transcript\n }\n}\n\n/**\n * Build the one-shot summarizer prompt for a run of older messages (used with\n * `AIProvider.prompt`). Mirrors the `<conversation_history>` block convention\n * that suggestions use. Any existing `compacted-summary` at the head is folded\n * in (rendered as prior-summary context), so rolling re-compaction produces one\n * combined summary.\n */\nexport function buildCompactionSummaryPrompt(toCompact: readonly ChatMessage[]): {\n systemPrompt: string;\n userMessage: string;\n} {\n const transcript = toCompact.map(renderMessageForSummary).filter(Boolean).join('\\n');\n const systemPrompt =\n 'You compress a conversation transcript into a concise summary that lets an AI ' +\n 'assistant continue the conversation seamlessly. Preserve key facts, decisions, ' +\n 'what the user wants, entity names and IDs, and any unresolved threads. Write ' +\n 'plain prose. Never roleplay or continue the conversation.';\n const userMessage =\n `<conversation_history>\\n${transcript}\\n</conversation_history>\\n\\n` +\n 'Summarize the conversation above so it can be dropped from context while ' +\n 'preserving everything needed to continue. Output only the summary prose.';\n return { systemPrompt, userMessage };\n}\n\n/**\n * Normalize history for a provider request (GENC-1351 \u00A75.7): translate each\n * `compacted-summary` message into a `user` message that wraps its summary in a\n * `<conversation_summary>` block, so the raw display-only role never reaches a\n * transport. Other roles pass through untouched. Pure \u2014 returns a new array.\n *\n * Applied at the request-build chokepoint *before* per-agent masking, so the\n * guarantee holds for every provider/transport regardless of any optional\n * per-agent history transform.\n */\nexport function normalizeForProvider(history: readonly ChatMessage[]): ChatMessage[] {\n return history.map((m) => {\n if (m.role !== 'compacted-summary') return m;\n return {\n ...m,\n role: 'user',\n content:\n `<conversation_summary>\\n${m.content}\\n</conversation_summary>\\n\\n` +\n 'The above summarizes earlier parts of this conversation that were compacted. ' +\n 'Continue naturally from it.',\n compaction: undefined,\n };\n });\n}\n\n/** Human-facing divider label for a `compacted-summary` message. */\nexport function compactionDividerLabel(m: ChatMessage): string {\n const n = m.compaction?.compactedCount ?? 0;\n return `Compacted ${n} earlier message${n === 1 ? '' : 's'}`;\n}\n", "import type { AggregateUsage, ChatMessage } from '@genesislcap/foundation-ai';\n\n/**\n * Zeroed {@link AggregateUsage}. A factory, not a shared const, because callers\n * accumulate into the returned object.\n *\n * @internal\n */\nexport function emptyUsage(): AggregateUsage {\n return {\n costUsd: 0,\n uncachedInputTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n outputTokens: 0,\n };\n}\n\n/**\n * Total tokens processed \u2014 the four buckets added up. Safe to sum because the\n * buckets are disjoint (see {@link AggregateUsage}); the equivalent sum over\n * per-message fields would double-count the prompt.\n *\n * Bear in mind what this number is: because every turn resends the conversation,\n * a turn's prompt is counted again in the next turn's. It is billed throughput,\n * NOT the count of distinct tokens in the conversation, so it grows\n * super-linearly with turn count and is expected to dwarf the context size.\n *\n * @internal\n */\nexport function totalTokens(usage: AggregateUsage): number {\n return (\n usage.uncachedInputTokens + usage.cacheReadTokens + usage.cacheWriteTokens + usage.outputTokens\n );\n}\n\n/**\n * `a + b`, per bucket, as a new object.\n *\n * Used to lay a row's banked (pre-transcript) spend over what the live transcript\n * proves. Pure rather than in-place because both operands are live state a caller\n * must not mutate.\n *\n * @internal\n */\nexport function addUsage(a: AggregateUsage, b: AggregateUsage): AggregateUsage {\n return {\n costUsd: a.costUsd + b.costUsd,\n uncachedInputTokens: a.uncachedInputTokens + b.uncachedInputTokens,\n cacheReadTokens: a.cacheReadTokens + b.cacheReadTokens,\n cacheWriteTokens: a.cacheWriteTokens + b.cacheWriteTokens,\n outputTokens: a.outputTokens + b.outputTokens,\n };\n}\n\n/**\n * Sum cost and per-bucket token usage across a message list.\n *\n * One walk produces everything a usage display needs, replacing separate cost and\n * token passes over the same (potentially deep) transcript. Recurses into each\n * tool call's `subAgentTrace`, so LLM work a sub-agent did \u2014 possibly on another\n * provider at other rates \u2014 lands in the total; the driver embeds a whole\n * sub-agent conversation in the parent's tool result, so this is the only place\n * that spend is visible.\n *\n * Splitting the prompt into buckets is the point: `cost` already has the cache\n * discount applied, but a single token total cannot show that a session was cheap\n * because most of its prompt was a cache hit. The three input buckets are derived\n * from the per-message fields, where `inputTokens` is the whole prompt and the\n * cache fields break it down \u2014 so uncached input is the remainder, never an\n * addition.\n *\n * Also counts `compaction.rolledUpUsage`: compaction destroys the messages it\n * summarises, and without their banked usage every total re-derived from the\n * transcript would drop by whatever those turns had already spent.\n *\n * Returns a zeroed total when no message carries usage \u2014 providers that report\n * none (e.g. Chrome built-in) are skipped silently rather than guessed at.\n *\n * @internal\n */\nexport function sumUsage(messages: readonly ChatMessage[]): AggregateUsage {\n const total = emptyUsage();\n accumulate(messages, total);\n return total;\n}\n\n/** Add `from` into `into`, in place. */\nfunction addInto(into: AggregateUsage, from: AggregateUsage): void {\n into.costUsd += from.costUsd;\n into.uncachedInputTokens += from.uncachedInputTokens;\n into.cacheReadTokens += from.cacheReadTokens;\n into.cacheWriteTokens += from.cacheWriteTokens;\n into.outputTokens += from.outputTokens;\n}\n\n/**\n * Walk `messages`, accumulating into `into`. Mutates a single accumulator rather\n * than merging returned objects \u2014 this runs on every transcript change, so the\n * per-message allocation is worth avoiding.\n */\nfunction accumulate(messages: readonly ChatMessage[], into: AggregateUsage): void {\n for (const m of messages) {\n // Provider/LLM cost plus any non-LLM cost a widget reported for its own\n // external service calls. Both are real spend on this session.\n if (m.cost != null) into.costUsd += m.cost;\n if (m.externalCostUsd != null) into.costUsd += m.externalCostUsd;\n\n const cacheRead = m.cacheReadTokens ?? 0;\n const cacheWrite = m.cacheWriteTokens ?? 0;\n into.cacheReadTokens += cacheRead;\n into.cacheWriteTokens += cacheWrite;\n // The uncached remainder of the prompt. Clamped at zero so malformed or\n // hand-edited history whose buckets exceed the prompt total can't drive the\n // session total negative \u2014 a wrong-but-plausible number is worse than a\n // conservative one here, since this feeds a cost display.\n into.uncachedInputTokens += Math.max(0, (m.inputTokens ?? 0) - cacheRead - cacheWrite);\n into.outputTokens += m.outputTokens ?? 0;\n\n // Spend banked by a compaction on this summary's behalf. NOTE: deliberately\n // not `compaction.tokensBefore` \u2014 that is a one-turn context-window reading,\n // not cumulative spend, and counting it here would inflate the total.\n const rolled = m.compaction?.rolledUpUsage;\n if (rolled) addInto(into, rolled);\n\n for (const tc of m.toolCalls ?? []) {\n if (tc.subAgentTrace) accumulate(tc.subAgentTrace, into);\n }\n }\n}\n", "import type { ChatToolDefinition, ChatToolHandlers } from '@genesislcap/foundation-ai';\n\n/**\n * Symbol used to attach ToolFold metadata to a facade handler function.\n * The ChatDriver inspects this to detect fold facades at runtime.\n *\n * @internal\n */\nexport const TOOL_FOLD_SYMBOL = Symbol('toolFold');\n\n/**\n * Internal metadata for a tool fold. Attached to the facade handler via TOOL_FOLD_SYMBOL.\n *\n * @internal\n */\nexport interface ToolFold {\n /** Facade tool name. */\n name: string;\n /** Description shown to the model. */\n description: string;\n /** Optional guidance injected in the fold-open response. */\n usageNotes?: string;\n /** Tool definitions inside this fold. */\n tools: ChatToolDefinition[];\n /** Handlers for the inner tools (keyed by tool name). */\n handlers: ChatToolHandlers;\n /**\n * When true (default), all other tools are removed when this fold opens \u2014\n * the model can only see this fold's tools until it closes.\n * When false, sibling tools remain alongside the inner tools.\n */\n exclusive: boolean;\n}\n\n/**\n * The value returned by `createToolFold`.\n *\n * @beta\n */\nexport interface ToolFoldResult {\n /**\n * The facade tool definition. Add this to your agent's `toolDefinitions`.\n * It is a regular `ChatToolDefinition` with an empty parameter schema.\n */\n definition: ChatToolDefinition;\n /**\n * The facade handler \u2014 a single-entry map keyed by the fold name.\n * Spread this into your agent's `toolHandlers`.\n * Inner tool handlers are NOT included here \u2014 they are encapsulated inside\n * the fold metadata and installed by the driver only when the fold opens.\n */\n handler: ChatToolHandlers;\n}\n\n/**\n * Creates a tool fold \u2014 a facade that hides a group of related tools behind a single\n * named entry, revealing them progressively when the model invokes the facade.\n *\n * The `tools` and `handlers` parameters accept the exact same types as `AgentConfig.toolDefinitions`\n * and `AgentConfig.toolHandlers`, so existing tool creation functions can be passed in unchanged.\n *\n * @example\n * ```typescript\n * const tradingTools = createToolFold({\n * name: 'trading_tools',\n * tools: createTradesToolDefinitions(),\n * handlers: createTradesToolHandlers(connect),\n * });\n *\n * const agent: AgentConfig = {\n * name: 'Trades',\n * systemPrompt: '...',\n * toolDefinitions: [getCurrentDateDef, tradingTools.definition],\n * toolHandlers: { get_current_date: handler, ...tradingTools.handler },\n * };\n * ```\n *\n * @example Nesting folds\n * ```typescript\n * const insertFold = createToolFold({\n * name: 'trade_insertion',\n * tools: [validateDef, insertDef],\n * handlers: { validate_trade: vHandler, insert_trade: iHandler },\n * });\n *\n * const tradingFold = createToolFold({\n * name: 'trading_tools',\n * tools: [searchDef, insertFold.definition],\n * handlers: { search_trades: sHandler, ...insertFold.handler },\n * });\n * ```\n *\n * @beta\n */\nexport function createToolFold(config: {\n /** Facade tool name \u2014 used as the tool name the model calls to open this fold. */\n name: string;\n /**\n * Description shown to the model for the facade tool.\n * If omitted, auto-generated from the inner tool names:\n * \"Contains: tool_a, tool_b. Invoke to access these tools.\"\n */\n description?: string;\n /**\n * Optional usage guidance injected into the fold-open response message.\n * Not included in the facade description \u2014 only visible once the fold is open.\n */\n usageNotes?: string;\n /** Inner tool definitions. Same type as `AgentConfig.toolDefinitions`. */\n tools: ChatToolDefinition[];\n /** Inner tool handlers. Same type as `AgentConfig.toolHandlers`. */\n handlers: ChatToolHandlers;\n /**\n * When true (default), all other tools are removed when this fold opens.\n * When false, sibling tools remain available alongside the inner tools.\n */\n exclusive?: boolean;\n}): ToolFoldResult {\n const description =\n config.description ??\n `Contains: ${config.tools.map((t) => t.name).join(', ')}. Invoke to access these tools.`;\n\n const fold: ToolFold = {\n name: config.name,\n description,\n usageNotes: config.usageNotes,\n tools: config.tools,\n handlers: config.handlers,\n exclusive: config.exclusive ?? true,\n };\n\n const definition: ChatToolDefinition = {\n name: config.name,\n description,\n parameters: { type: 'object', properties: {} },\n };\n\n // The facade handler body is never actually called \u2014 the driver intercepts it\n // via TOOL_FOLD_SYMBOL before dispatch. The body is a no-op fallback.\n const facadeHandler = async (): Promise<string> => `Fold: ${config.name}`;\n (facadeHandler as any)[TOOL_FOLD_SYMBOL] = fold;\n\n return {\n definition,\n handler: {\n [config.name]: facadeHandler,\n },\n };\n}\n\n/**\n * A tool entry in the expanded debug tree.\n * Folds are represented as nodes with a `tools` array; regular tools have none.\n *\n * @beta\n */\nexport interface ToolTreeNode extends ChatToolDefinition {\n /** Present when this tool is a fold \u2014 contains its inner tools recursively expanded. */\n tools?: ToolTreeNode[];\n}\n\n/**\n * Expands a flat list of tool definitions into a nested tree by resolving fold\n * metadata from the corresponding handlers. Use this for debug output so the\n * full tool hierarchy is visible rather than just the top-level facade names.\n *\n * @beta\n */\nexport function expandToolTree(\n definitions: ChatToolDefinition[],\n handlers: ChatToolHandlers,\n): ToolTreeNode[] {\n return definitions.map((def) => {\n const handler = handlers[def.name];\n const fold: ToolFold | undefined = handler ? (handler as any)[TOOL_FOLD_SYMBOL] : undefined;\n if (fold) {\n return { ...def, tools: expandToolTree(fold.tools, fold.handlers) };\n }\n return { ...def };\n });\n}\n", "import type {\n AIProvider,\n AIProviderRegistry,\n AIProviderType,\n CachePolicy,\n ChatAttachment,\n ChatDriverResult,\n ChatFallback,\n ChatMessage,\n ChatRequestOptions,\n ChatToolCall,\n ChatToolChoice,\n ChatToolDefinition,\n ChatToolHandlers,\n CondensePolicy,\n CondenseTrigger,\n InteractionRequestOptions,\n InteractionResult,\n SubAgentFailureReason,\n SubAgentRequestOptions,\n TurnFailureReason,\n} from '@genesislcap/foundation-ai';\nimport {\n BudgetExhaustedError,\n DEFAULT_BUDGET_EXHAUSTED_MESSAGE,\n isObservableAIProviderRegistry,\n MalformedFunctionCallError,\n ResponseTruncatedError,\n vendorTypeOfLabel,\n} from '@genesislcap/foundation-ai';\nimport { type ActivityBus, NOOP_ACTIVITY_BUS } from '../../channel/ai-activity-bus';\nimport type {\n AgentConfig,\n CachePolicyInput,\n ProviderInput,\n ResponseSchemaInput,\n SystemPromptContext,\n SystemPromptInput,\n TailContextInput,\n TemperatureInput,\n ToolChoiceInput,\n ToolDefinitionsInput,\n ToolHandlersInput,\n UnresolvedToolInput,\n} from '../../config/config';\nimport { resolveChatProvider } from '../../config/validate-providers';\nimport {\n clearSession,\n getMetaEvents,\n type MetaEvent,\n mergeMetaEvents,\n type MetaEventType,\n recordMetaEvent,\n recordTurnError,\n recordTurnRetry,\n} from '../../state/debug-event-log';\nimport {\n createInteractionContext,\n type InteractionContextHandle,\n} from '../../state/interaction-context';\nimport type { DiagnosticEntry } from '../../state/persistence/diagnostics';\nimport type { InteractionContext } from '../../types/interaction-context';\nimport { applyCondensation, type RegisteredCondensePolicy } from '../../utils/condense-history';\nimport {\n applyHistoryCap,\n buildCompactionSummaryPrompt,\n findCompactionCut,\n normalizeForProvider,\n} from '../../utils/history-transform';\nimport { logger } from '../../utils/logger';\nimport { sumUsage } from '../../utils/sum-usage';\nimport { TOOL_FOLD_SYMBOL, type ToolFold } from '../../utils/tool-fold';\nimport type { AiDriver, AllAgentSummary } from '../ai-driver/ai-driver';\n\n/**\n * The `budget` payload carried on a `'budget-exhausted'` {@link ChatDriverResult}.\n * Derived from the type rather than restated so the two cannot drift.\n */\ntype BudgetDetail = NonNullable<Extract<ChatDriverResult, { reason: 'done' }>['budget']>;\n\n/**\n * Lift the reportable facts off a {@link BudgetExhaustedError}, or `undefined`\n * when it carries none.\n *\n * \"None\" means **no figures AND no attributable vendor** \u2014 not merely no\n * figures. Dropping the whole object on a figure-less 402 also dropped\n * `vendorLabel`, which is the authoritative attribution source, and left the\n * element's latch falling back to the driver's last-resolved provider, i.e. the\n * PREVIOUS turn's vendor. A turn-1 Gemini call followed by a turn-2 classifier\n * refused by Anthropic with a figure-less 402 then walled *Gemini* and advised\n * switching to the vendor that had actually run out. Three live shapes reach\n * here with no figures \u2014 a bare gateway 402, a code-only body, and the framed\n * err frame whose figures are `null` (which the proxy now prefers over a\n * misleading `0`, so this path is getting more common, not less).\n *\n * The figures alone still decide whether banner copy is composed \u2014 see\n * `formatBlockedReason`, which returns `undefined` for a figure-less budget so a\n * host-set explanation survives the latch.\n */\nconst budgetDetailOf = (e: BudgetExhaustedError): BudgetDetail | undefined => {\n // The typed vendor is derived from the LABEL, not from `lastResolvedProvider`:\n // the label comes from the transport that was actually refused, whereas the\n // last-resolved provider is stale on the classification seam (an orchestrated\n // turn classifies against the registry default, which this driver may never\n // have resolved). The proxy's own `vendor` is the fallback for a transport\n // whose static label no vendor claims (a multiplexing or white-labelled\n // gateway). Omitted rather than set to `undefined` when neither resolves, so\n // \"we know the vendor\" stays testable by presence alone.\n const vendor = vendorTypeOfLabel(e.vendorLabel) ?? vendorTypeOfLabel(e.serverVendor);\n if (e.budgetUsd == null && e.spentUsd == null && !vendor) return undefined;\n return {\n budgetUsd: e.budgetUsd,\n spentUsd: e.spentUsd,\n vendorLabel: e.vendorLabel,\n ...(vendor ? { vendor } : {}),\n // Server-known truth the client cannot re-derive, so it rides all the way to\n // the banner rather than being re-guessed there from registry membership.\n ...(e.otherVendorAvailable != null ? { otherVendorAvailable: e.otherVendorAvailable } : {}),\n };\n};\n\nconst DEFAULT_MAX_TOOL_ITERATIONS = 50;\nconst DEFAULT_MAX_FOLD_OPERATIONS = 5;\n// TODO: dedup system prompts in-memory to allow raising this cap much higher.\n// Each TurnSnapshot stores the full resolved `systemPrompt`, so the buffer's\n// memory cost scales with cap \u00D7 prompt size \u2014 a stable agent repeats a multi-KB\n// prompt every turn. `getDebugLog` already dedups identical consecutive prompts\n// at export time (`<repeated \u2014 identical to turn N>`); applying the same dedup\n// at capture time (store the prompt only when it changes, back-reference\n// otherwise) would make snapshots nearly as cheap as meta events and let this\n// cap reach thousands for full-session capture without the memory blowup.\nconst DEFAULT_MAX_TURN_SNAPSHOTS = 400;\nconst DEFAULT_MAX_UNKNOWN_TOOL_CALLS = 5;\n// Stale tools (advertised in an earlier state, retired now) and fold-hidden tools are\n// self-correcting \u2014 the model drops them once guided \u2014 so they get a higher loop-protection\n// ceiling than hallucinated names: a few legitimate stale calls across state transitions must\n// not prematurely end the turn. Still bounded so a genuinely stuck loop terminates.\nconst MAX_STALE_TOOL_CALLS = DEFAULT_MAX_UNKNOWN_TOOL_CALLS * 2;\n// Gemini in particular emits short bursts of MALFORMED_FUNCTION_CALL; allow more CONSECUTIVE\n// retries. These counters reset on any productive response, so this is a consecutive-failure\n// ceiling, not a per-turn total.\nconst MAX_MALFORMED_RETRIES = 5;\nconst MAX_EMPTY_RESPONSE_RETRIES = 3;\n// Transient throws while building the per-turn tool surface or calling the provider retry the\n// SAME iteration up to this many times before propagating, rather than tearing down the turn.\nconst MAX_SETUP_TRANSPORT_RETRIES = 3;\nconst SUGGESTIONS_HISTORY_WINDOW = 8;\n\n/**\n * Sub-agent meta events worth folding into the parent's debug timeline: the\n * per-attempt and per-failure signals that do NOT otherwise surface in the\n * sub-agent's (now hoisted) messages \u2014 a retried-away malformed/empty attempt\n * produces no message, and the stale-vs-hallucinated/streak diagnostics live only\n * on the event. High-volume, message-derivable events (turn.start/turn.end,\n * provider.selected, context.updated) are intentionally excluded: read the\n * sub-agent's hoisted messages for model/tokens/cost and turn-by-turn activity.\n * See `ChatDriver.invokeSubAgent`.\n */\nconst HARVESTED_SUBAGENT_EVENTS: ReadonlySet<MetaEventType> = new Set([\n 'turn.retry',\n 'turn.error',\n 'tool.failed',\n 'tool.unresolved',\n]);\n\n/** Name reserved for the cross-agent handoff tool \u2014 injected by OrchestratingDriver. */\nexport const REQUEST_CONTINUATION_TOOL = 'request_continuation';\n\n/** Paired in history for each `request_continuation` so tool_calls stay balanced for the provider. */\nconst HANDOFF_TOOL_RESULT_PLACEHOLDER =\n 'Handoff to another specialist \u2014 routing continues on the next turn.';\n\n/**\n * Event emitted when the chat history is updated (new message appended).\n *\n * @beta\n */\nexport type ChatHistoryUpdatedEvent = CustomEvent<ReadonlyArray<ChatMessage>>;\n\n/**\n * One captured frame of what the LLM saw on a single tool-loop iteration.\n * The driver records these as a ring buffer (cap: configurable via\n * `chatConfig.agent.maxTurnSnapshots`, default 400) so the export log can show,\n * per turn: which agent was active, the resolved system prompt, the tool names\n * visible to the LLM, and any agent-supplied debug snapshot (e.g. machine\n * state for stateful agents).\n *\n * @beta\n */\nexport interface TurnSnapshot {\n /**\n * Turn identifier, always a string. A driver's own turns are the bare counter\n * (`\"0\"`, `\"1\"`, \u2026 \u2014 monotonic, does not reset on agent swap). Turns forwarded\n * up from a sub-agent are re-labelled under the parent turn that activated them\n * \u2014 a sub-agent invoked on parent turn 5 contributes `\"5-1\"`, `\"5-2\"`, \u2026, and a\n * nested sub-agent on `\"5-2\"` contributes `\"5-2-1\"`, \u2026. See\n * `forwardSubAgentSnapshots`.\n */\n turnIndex: string;\n /** ISO timestamp captured just before the LLM call. */\n timestamp: string;\n /** Name of the agent active when this LLM call ran. */\n agentName?: string;\n /**\n * The agent's resolved system prompt sent to the LLM, verbatim. NOTE: this is\n * now the *bare* prompt \u2014 the fold-surface suffix and the malformed/empty retry\n * nudge no longer mutate it (they kept it byte-unstable and busted prompt\n * caching), so they moved to {@link TurnSnapshot.tailContext}. To reconstruct\n * exactly what the model saw, read both fields.\n */\n systemPrompt?: string;\n /**\n * The framed `<system-reminder>` tail appended to the final user turn for this\n * call, verbatim \u2014 never part of stored history, so this snapshot is the only\n * record of it. Carries the framework's volatile additions (fold suffix, retry\n * nudge) and the agent's per-turn `tailContext` (e.g. current file spec, live\n * diagnostics). Undefined when the tail was empty (the normal case).\n */\n tailContext?: string;\n /** Tool names sent to the LLM, in order \u2014 definitions are static per name so names alone suffice. */\n toolNames: string[];\n /**\n * Normalized `0`\u2013`1` sampling temperature in effect for this call, if the\n * agent (or its current state) configured one. Undefined \u2192 provider/model\n * default. Mirrors the value resolved from `BaseAgentConfig.temperature`.\n */\n temperature?: number;\n /**\n * Tool-call mode actually sent to the provider this call \u2014 the effective\n * value, including the sub-agent `'required'` default. Undefined \u2192 `'auto'`.\n * Mirrors the value resolved from `BaseAgentConfig.toolChoice`.\n */\n toolChoice?: ChatToolChoice;\n /**\n * Per-turn display label resolved from the agent's `displayName`, e.g.\n * \"Guided Booking (Counterparties)\". `agentName` stays as the canonical\n * identity used for routing/filtering.\n */\n agentLabel?: string;\n /** Agent-supplied snapshot \u2014 machine state/context for stateful agents, undefined otherwise. */\n agentSnapshot?: unknown;\n}\n\ninterface FoldStackFrame {\n foldName: string;\n previousDefinitions: ChatToolDefinition[];\n previousHandlers: ChatToolHandlers;\n}\n\n/**\n * Construction-time configuration for {@link ChatDriver}. Everything except the provider\n * registry is optional \u2014 most fields are also settable per-agent via `applyAgent`, so a\n * bare `new ChatDriver(registry)` is valid. Mirrors the `(registry, options)` shape of\n * `OrchestratingDriver`.\n *\n * @beta\n */\nexport interface ChatDriverConfig {\n /** Initial tool handlers (static map or per-turn factory). Default `{}`. */\n toolHandlers?: ToolHandlersInput;\n /** Initial tool definitions (static array or per-turn factory). Default `[]`. */\n toolDefinitions?: ToolDefinitionsInput;\n /** Initial system prompt (string or per-turn resolver). */\n systemPrompt?: SystemPromptInput;\n /** Primer history prepended to the conversation. */\n primerHistory?: ChatMessage[];\n /** Hard cap on tool-loop iterations. Default `50`. */\n maxToolIterations?: number;\n /** Hard cap on fold operations. Default `5`. */\n maxFoldOperations?: number;\n /**\n * Collapse `condenseWhen` payloads in batches of this many model-calls rather than as\n * soon as each trigger fires. A positive integer; decimals are floored and anything\n * below `1` becomes `1`. Default `1` \u2014 collapse immediately, the historical behaviour.\n *\n * Condensation rewrites history in place, so collapsing continuously breaks the\n * provider's prompt cache on nearly every call of a re-read loop. Raising this trades\n * up to that many calls' worth of extra context for one cache break per batch.\n */\n condenseBatchCalls?: number;\n /** Ring-buffer size for per-turn snapshots. Default `400`. */\n maxTurnSnapshots?: number;\n /** Session identity used to file meta events onto the shared debug-log timeline. */\n sessionKey?: string;\n /**\n * Activity bus for lifecycle/halo/tool-loop events. Injected by the browser host\n * (the shared cross-tab singleton); omitted off-browser (Node, tests, headless), where\n * it defaults to {@link NOOP_ACTIVITY_BUS} so no `BroadcastChannel` is ever opened.\n */\n activityBus?: ActivityBus;\n /**\n * Transcript copy appended when the AI-spend budget wall is hit (GENC-1464).\n * Defaults to `DEFAULT_BUDGET_EXHAUSTED_MESSAGE`.\n *\n * The assistant element already lets a host override the blocked **banner**\n * via `setBlocked(true, reason)`; without this the transcript **bubble** stayed\n * on the default, so a white-labelled host got its own copy in the banner and\n * the shipped default directly below it. Passing the same effective copy here\n * keeps the two surfaces saying one thing.\n *\n * Deliberately a driver-config field rather than something read off a chat\n * config: `ChatDriver` has no `chatConfig` and is used standalone (see\n * `chat-driver-node`), so threading one in would be a much larger and less\n * reversible change.\n */\n budgetExhaustedMessage?: string;\n}\n\n/**\n * Plain TS class that drives a multi-turn chat conversation, including the tool-call loop.\n * Owned by `FoundationAiAssistant` \u2014 created in `connectedCallback`, torn down in `disconnectedCallback`.\n *\n * Dispatches `'history-updated'` events on itself so the owning element can observe changes.\n *\n * @fires history-updated - Fired whenever the in-memory chat history changes (append, tool loop, interaction resolution) with the full history snapshot. detail: `ReadonlyArray<ChatMessage>`\n *\n * @beta\n */\nexport class ChatDriver extends EventTarget implements AiDriver {\n private history: ChatMessage[] = [];\n private busy = false;\n /** Epoch ms when the current turn loop began \u2014 drives the `turn.end` duration. */\n private turnStartedAt = 0;\n private pendingInteractions = new Map<\n string,\n {\n resolve: (value: any) => void;\n reject: (reason?: any) => void;\n /** Present when the call requested a chat-input override. */\n overrideId?: string;\n /** Present when the call set `timeoutMs`; cleared on resolution. */\n timeoutHandle?: ReturnType<typeof setTimeout>;\n }\n >();\n /**\n * Live per-interaction contexts (GENC-1390), keyed by interactionId. Created in\n * `requestInteraction` alongside the pending entry, disposed + removed in\n * `resolveInteraction`. Non-serialisable (sockets, timers, subscriber sets), so\n * they live here on the driver \u2014 not on the DOM, not in the persisted store \u2014 and\n * therefore survive the element remounts (layout reflow/drag, transcript\n * re-render) that this feature exists to make harmless. At most one is live at a\n * time (see the one-interaction-at-a-time guard in `requestInteraction`).\n */\n private interactionContexts = new Map<string, InteractionContextHandle>();\n\n private systemPrompt?: SystemPromptInput;\n /**\n * Resolved tool definitions visible to the LLM. Folds mutate this in place\n * (push/pop on open/close). When `toolDefinitionsFactory` is set, this is\n * overwritten each tool-loop iteration with the factory's output.\n */\n private toolDefinitions: ChatToolDefinition[];\n /**\n * Optional dynamic-tools source. When set, called each tool-loop iteration\n * to recompute `toolDefinitions` before the LLM call. `defineStatefulAgent`\n * forbids folds when this is set, so the fold-mutation path is unreachable\n * in that case.\n */\n private toolDefinitionsFactory?: (\n ctx: SystemPromptContext,\n ) => ChatToolDefinition[] | Promise<ChatToolDefinition[]>;\n /**\n * Resolved tool handler map used for dispatch. When `toolHandlersFactory` is\n * set, this is overwritten each tool-loop iteration with the factory's output\n * \u2014 keeping it in lockstep with `toolDefinitions` so handlers don't have to\n * defend themselves against being dispatched in states where their tool\n * isn't advertised. Folds mutate this in place; `defineStatefulAgent`\n * forbids folds when a factory is set, so the fold-mutation path is\n * unreachable in that case.\n */\n private toolHandlers: ChatToolHandlers;\n /**\n * Optional per-turn handler-map source. Mirrors `toolDefinitionsFactory` so\n * the LLM-visible tools and the dispatchable handlers can be narrowed in\n * lockstep. Resolved each tool-loop iteration before the LLM call.\n */\n private toolHandlersFactory?: (\n ctx: SystemPromptContext,\n ) => ChatToolHandlers | Promise<ChatToolHandlers>;\n private primerHistory?: ChatMessage[];\n private activeAgentName?: string;\n /**\n * Per-turn display label resolved from the agent's `displayName`. Stamped\n * onto outgoing messages and turn snapshots for UX; `activeAgentName` stays\n * stable for routing/history-transform identity matching.\n */\n private activeAgentLabel?: string;\n private displayName?: SystemPromptInput;\n /**\n * When set, `requestInteraction` delegates to this callback instead of using\n * this driver's own pending map. Wired by `invokeSubAgent` so a sub-agent's\n * widget renders in \u2014 and resolves through \u2014 the parent (ultimately the\n * root) driver, where the main UI is listening.\n */\n private hostInteractionRequester?: <T>(\n componentName: string,\n data: any,\n options?: InteractionRequestOptions,\n ) => Promise<T>;\n /**\n * When set (e.g. by OrchestratingDriver), applied only to the conversation slice\n * sent to the model \u2014 stored `history` stays unchanged for UI and logging.\n */\n private providerHistoryTransform?: (history: ChatMessage[]) => ChatMessage[];\n /**\n * Tool-declared condensation policies, keyed by tool-call id. Populated by\n * `condenseWhen` (first-wins per call); read by `applyCondensation` before each\n * provider call to collapse stale payloads from the model-bound history only.\n * Accumulates across agents on a shared driver (a superseded read collapses no\n * matter which agent made it) and is never cleared \u2014 it dies with the driver.\n */\n private readonly condensePolicies = new Map<string, RegisteredCondensePolicy>();\n /**\n * Monotonic model-call counter for the driver's whole lifetime \u2014 the age clock\n * for `condenseWhen({ on: { kind: 'age' } })`. The per-`sendMessage` `iterations`\n * loop counter resets to 0 every turn, so it can only measure age WITHIN a\n * single turn; this never resets, so `age` counts model-calls since the result\n * appeared across turn boundaries (each short turn still advances it \u2265 1).\n * Bumped once per tool-loop iteration (provider call).\n */\n private modelCallSeq = 0;\n /**\n * Monotonic turn counter \u2014 the `turnEnd` clock. Bumped once per `sendMessage`\n * (a user turn; NOT per handoff continuation, which is the same request), never\n * reset. `turnEnd` collapses a payload once `turnSeq` exceeds the turn it was\n * created in.\n */\n private turnSeq = 0;\n /**\n * Monotonic agent-activation counter \u2014 the `agentEnd` clock. Advances when the\n * active flow ends: a swap to a different-named agent (`applyAgent`) OR an\n * explicit `releaseAgent` / `completeSubAgent`. A stateful agent re-resolving\n * the same name across turns keeps one activation. `agentEnd` fires for a\n * payload once a LATER activation is current (`callActivation < currentActivation`)\n * \u2014 so a re-run of a released agent gets a fresh activation and is NOT\n * collapsed until IT ends.\n */\n private currentActivation = 0;\n /**\n * Monotonic phase-epoch counter \u2014 the `phaseEnd` clock. Advanced by the\n * handler-context `endPhase()` (an app-declared phase boundary within one\n * activation), never reset. Unlike `currentActivation` it is NOT tied to agent\n * swaps or releases \u2014 it ticks only when the agent itself declares a phase\n * done. `phaseEnd` fires for a payload once a LATER epoch is current\n * (`callPhaseEpoch < currentPhaseEpoch`), with an `agentEnd` backstop.\n */\n private currentPhaseEpoch = 0;\n\n /** Stack of fold frames \u2014 grows when a fold opens, shrinks when it closes. */\n private foldStack: FoldStackFrame[] = [];\n /** Consecutive fold open/close ops without a real tool call. Reset on real tool execution. */\n private consecutiveFoldOps = 0;\n /** Consecutive unknown-tool calls without a real tool call. Reset on real tool execution. */\n private consecutiveUnknownToolCalls = 0;\n /**\n * Distinct unknown-tool names seen in the current consecutive streak \u2014 stamped\n * onto the `unknown-tool-limit` turn.error so a triager knows which tools were\n * hallucinated. Reset alongside `consecutiveUnknownToolCalls`.\n */\n private readonly recentUnknownToolNames = new Set<string>();\n /**\n * Union of every tool name advertised at any point during the current agent\n * activation. Lets the unknown-tool path tell a *stale* call (a real tool from\n * an earlier state, now retired \u2014 or one an open exclusive fold is hiding)\n * apart from a *hallucinated* one. Reset on agent swap in `applyAgent`.\n */\n private readonly everSeenToolNames = new Set<string>();\n /**\n * Subset of the current unknown-tool streak that was stale (previously\n * available) rather than hallucinated \u2014 surfaced separately on the\n * `unknown-tool-limit` turn.error so triage can tell a state/prompt-design\n * problem from a model that's inventing tools. Reset alongside\n * `recentUnknownToolNames`.\n */\n private readonly recentStaleToolNames = new Set<string>();\n private readonly maxFoldOperations: number;\n\n /** Sub-agents declared on the active agent config, keyed by name. */\n private subAgentsMap: Map<string, AgentConfig> = new Map();\n /**\n * Set by `completeSubAgent` inside a sub-agent tool handler. Checked at the\n * same point in the loop as `REQUEST_CONTINUATION_TOOL` \u2014 after tool results\n * are appended \u2014 so the exit path mirrors the system-call pattern.\n * `undefined` means the loop has not been stopped early.\n */\n private subAgentCompletion: { result: unknown } | undefined;\n /**\n * True when this driver runs as a child sub-agent (created by a parent\n * driver's `invokeSubAgent`). Sub-agents force tool use every turn so a turn\n * can only end via their completion tool, and on any non-completion exit they\n * record a typed `SubAgentFailureReason` instead of appending a\n * user-facing message \u2014 the parent decides how to surface the failure.\n */\n private isSubAgent = false;\n /**\n * Set when a sub-agent's tool loop ends without `completeSubAgent` being\n * called. Read by the parent's `invokeSubAgent` to build the `{ ok: false }`\n * branch of `requestSubAgent`. Only ever set when `isSubAgent` is true.\n *\n * `budget` rides along on a `'budget_exhausted'` failure so the parent inherits\n * the child's ATTRIBUTION, not just the fact of a wall \u2014 see\n * `budgetWallDetail`.\n */\n private subAgentFailure: { reason: SubAgentFailureReason; budget?: BudgetDetail } | undefined;\n /**\n * Set by `releaseAgent` inside a top-level tool handler \u2014 typically a stateful\n * agent's terminal-state handler signalling that its flow is complete and the\n * auto-pin lock can release. Checked by the orchestrator after `sendMessage`\n * returns; the orchestrator fires `onDeactivate` and clears the pin.\n *\n * Reset at the start of each `sendMessage` so a release from a previous turn\n * doesn't leak forward.\n */\n private agentReleaseRequested = false;\n /**\n * Ring buffer of per-LLM-call snapshots. Cap is configurable via\n * `chatConfig.agent.maxTurnSnapshots`; older entries drop off as new ones\n * arrive. See {@link TurnSnapshot} for the captured shape.\n */\n private turnSnapshots: TurnSnapshot[] = [];\n /**\n * `turn` + `message` diagnostic-log entries harvested from an out-of-band source (a resolved\n * interaction whose widget returned `InteractionResult.diagnostics` \u2014 e.g. a server-side\n * ChatDriver's debug log). `event` entries are NOT kept here \u2014 they're folded into the session's\n * meta-event registry via `mergeMetaEvents` (see `resolveInteraction`) so they inherit fresh host\n * indices, and reach the log through `getMetaEvents`. Append-only; the host folds these into its\n * debug log alongside this driver's own timeline. Not cleared here \u2014 it lives with the driver\n * instance, like `turnSnapshots`, so a new chat (fresh driver) starts empty while a compaction\n * (same instance) keeps it. (GENC-1461.)\n */\n private readonly externalDiagnostics: DiagnosticEntry[] = [];\n /**\n * Monotonic count of external-diagnostics batches harvested this driver-lifetime. Namespaces each\n * batch's re-keyed `turn` entries so distinct server generations in one chat session can't collide\n * on `turnIndex` in the forward-capture persister (which dedups turns by that key). (GENC-1461.)\n */\n private externalDiagnosticsBatches = 0;\n /** Monotonic counter that survives agent swaps \u2014 useful for cross-referencing with history. */\n private globalTurnIndex = 0;\n /** Captured from `applyAgent` so we don't store the whole `AgentConfig`. */\n private debugSnapshotter?: () => unknown;\n private readonly maxTurnSnapshots: number;\n\n /**\n * Aborted by `dispose()` on driver teardown (e.g. an agent-config swap).\n * Threaded into every provider call as `ChatRequestOptions.signal`, so a\n * disposed driver's in-flight LLM request is cancelled instead of running on\n * to completion or the transport timeout. Also passed to prompt/tool\n * factories via `SystemPromptContext.signal`.\n */\n private readonly lifecycleController = new AbortController();\n\n /**\n * Per-turn abort controller, reset at the start of every turn by `beginTurn`.\n * Aborted by `cancel()` (user stop) and chained to `lifecycleController` so a\n * driver dispose also ends the current turn. Its signal \u2014 not the lifecycle\n * one \u2014 is what reaches the provider call, so a turn can be cancelled without\n * bricking the driver for the next message.\n */\n private turnController = new AbortController();\n /** True when the current turn was stopped via `cancel()` (vs a dispose). Drives the \"Stopped.\" marker. */\n private turnCancelled = false;\n /** Detaches the lifecycle\u2192turn abort link at turn end; set by `beginTurn`. */\n private unlinkLifecycleFromTurn?: () => void;\n\n /**\n * Active agent's provider selector (static name or per-turn resolver).\n * `undefined` means \"use the registry default\".\n */\n private activeProviderInput?: ProviderInput;\n /**\n * Active agent's temperature selector (static number or per-turn resolver),\n * normalized to `0`\u2013`1`. `undefined` means \"use the provider/model default\".\n */\n private activeTemperatureInput?: TemperatureInput;\n /**\n * Active agent's tool-call mode selector (static value or per-turn resolver).\n * `undefined` falls back to the per-turn default (sub-agents force a tool\n * call; top-level turns are `'auto'`).\n */\n private activeToolChoiceInput?: ToolChoiceInput;\n /**\n * Active agent's prompt-cache policy selector (static value or per-turn resolver).\n * `undefined` requests no caching (equivalent to `{ scope: 'default' }`).\n */\n private activeCachePolicyInput?: CachePolicyInput;\n /**\n * Active agent's tail-context selector (static value or per-turn resolver). The driver frames\n * the resolved string in a `<system-reminder>` marker and injects it at the message tail.\n */\n private activeTailContextInput?: TailContextInput;\n /**\n * Active agent's structured-output schema selector (static value or per-turn resolver).\n * When it resolves to a schema, the model's final answer is constrained to it this turn.\n */\n private activeResponseSchemaInput?: ResponseSchemaInput;\n /**\n * Active agent's refusal-fallback chain (static). Passed through to the provider so a refused\n * turn (e.g. Fable 5) is re-run on the next model server-side.\n */\n private activeFallbacks?: ChatFallback[];\n /**\n * Active agent's unresolved-tool hook, captured from `applyAgent`. Consulted\n * only when a tool call cannot be dispatched (a stale or hallucinated name);\n * `undefined` keeps the framework's default messages. See\n * `resolveUnresolvedToolContent`.\n */\n private activeOnUnresolvedTool?: UnresolvedToolInput;\n /**\n * Caches validated provider lookups per name within the current agent. Cleared\n * by `applyAgent` so each new agent's static/function-resolved names are\n * validated fresh.\n */\n private resolvedProviderCache = new Map<string, AIProvider>();\n /** Last successfully resolved provider name \u2014 drives `getActiveProviderName`. */\n private lastResolvedProviderName?: string;\n /** Last dispatched `provider-changed` name; avoids duplicate events on stable turns. */\n private lastDispatchedProviderName?: string;\n /**\n * Concrete model id of the provider resolved for the current turn, read from\n * its `getStatus()` and stamped onto the resulting assistant message so the\n * debug log carries per-message model lineage. Re-resolved each turn in\n * `resolveProviderForTurn`.\n */\n private lastResolvedModel?: string;\n /**\n * Vendor id from the provider's `getStatus()` for the current turn (e.g.\n * `'anthropic'`, `'gemini'`). Stamped onto assistant messages alongside\n * `lastResolvedModel`.\n */\n private lastResolvedProvider?: AIProviderType;\n /**\n * Memoised `name \u2192 getStatus()` lookups, so per-turn resolution doesn't\n * re-await `getStatus()` every turn. Cleared (with `resolvedProviderCache`) on\n * an observable-registry change, so a model swapped behind a stable name is\n * picked up on the next turn.\n */\n private resolvedStatusCache = new Map<string, { model?: string; provider?: AIProviderType }>();\n /**\n * Unsubscribe handle for the provider-registry change listener (only set when\n * the injected registry is observable). Called in `dispose` so the long-lived\n * registry doesn't retain this driver \u2014 see the constructor and the sub-agent\n * teardown in `runSubAgent`.\n */\n private unsubscribeRegistry?: () => void;\n\n /** Hard cap on tool-loop iterations. */\n private readonly maxToolIterations: number;\n /** Model-calls per condensation batch; `1` collapses as soon as a trigger fires. */\n private readonly condenseBatchCalls: number;\n /** Session identity used to file meta events onto the shared debug-log timeline. */\n private readonly sessionKey: string;\n /** Injected activity bus; defaults to a no-op off-browser (Node/tests/headless). */\n private readonly activityBus: ActivityBus;\n /** Transcript copy for a budget wall \u2014 see `ChatDriverConfig.budgetExhaustedMessage`. */\n private readonly budgetExhaustedMessage: string;\n /**\n * Set the moment a budget wall is observed anywhere in this turn \u2014 this\n * driver's own 402, or a sub-agent's (which surfaces here only as a\n * `'budget_exhausted'` tool result). Read at the top of the tool loop to end\n * the turn before issuing another model call that would hit the same wall.\n * Reset per turn alongside the other per-turn counters.\n */\n private budgetExhaustedThisTurn = false;\n /**\n * The refusing vendor's own attribution for the wall `budgetExhaustedThisTurn`\n * records, when it was knowable. Kept SEPARATE from the flag rather than\n * replacing it: a figure-less 402 from a transport no vendor claims yields no\n * detail at all (`budgetDetailOf` returns `undefined`), and folding the two\n * would make that case stop ending the turn.\n *\n * It matters most for a sub-agent's wall. The child can sit on a different\n * vendor from its parent \u2014 `applyAgent` reads `config.provider` \u2014 so without\n * this the parent's short-circuit reports `lastResolvedProvider`, i.e. the one\n * vendor that did NOT refuse. Under a mixed registry that walls Gemini because\n * an Anthropic child 402'd, and if those are the only two reachable vendors the\n * host then derives `blocked` and locks a composer that still had headroom.\n */\n private budgetWallDetail?: BudgetDetail;\n /**\n * Whether this turn's budget wall came from a SUB-AGENT rather than this\n * driver's own request. Decides whether `lastResolvedProvider` is a valid\n * attribution fallback: for an own wall it is the refusing vendor, for a\n * child's wall it is the parent's vendor \u2014 the one known NOT to have refused.\n * Reset per turn alongside `budgetWallDetail`.\n */\n private budgetWallViaSubAgent = false;\n\n constructor(\n private readonly providerRegistry: AIProviderRegistry,\n config: ChatDriverConfig = {},\n ) {\n super();\n const {\n toolHandlers = {},\n toolDefinitions = [],\n systemPrompt,\n primerHistory,\n maxToolIterations = DEFAULT_MAX_TOOL_ITERATIONS,\n maxFoldOperations = DEFAULT_MAX_FOLD_OPERATIONS,\n condenseBatchCalls = 1,\n maxTurnSnapshots = DEFAULT_MAX_TURN_SNAPSHOTS,\n sessionKey = '',\n activityBus = NOOP_ACTIVITY_BUS,\n budgetExhaustedMessage = DEFAULT_BUDGET_EXHAUSTED_MESSAGE,\n } = config;\n this.maxToolIterations = maxToolIterations;\n this.condenseBatchCalls = condenseBatchCalls;\n this.sessionKey = sessionKey;\n this.activityBus = activityBus;\n this.budgetExhaustedMessage = budgetExhaustedMessage;\n if (typeof toolHandlers === 'function') {\n this.toolHandlersFactory = toolHandlers;\n this.toolHandlers = {};\n } else {\n this.toolHandlersFactory = undefined;\n this.toolHandlers = toolHandlers;\n }\n if (typeof toolDefinitions === 'function') {\n this.toolDefinitionsFactory = toolDefinitions;\n this.toolDefinitions = [];\n } else {\n this.toolDefinitionsFactory = undefined;\n this.toolDefinitions = toolDefinitions;\n }\n this.systemPrompt = systemPrompt;\n this.primerHistory = primerHistory;\n this.maxFoldOperations = maxFoldOperations;\n this.maxTurnSnapshots = maxTurnSnapshots;\n // Runtime provider switching: when the host registered an observable\n // registry, drop our memoised provider lookups whenever its mapping/default\n // changes so the next turn re-resolves against the new providers. Resetting\n // `lastDispatchedProviderName` forces the next `resolveProviderForTurn` to\n // re-emit `provider-changed` even when the resolved *name* is unchanged\n // (e.g. a tier name like 'high' kept, but the vendor underneath swapped) \u2014\n // that's what lets status UI refresh on a same-name switch. Feature-detect\n // means immutable/empty registries are a no-op. Child sub-agent drivers get\n // the same registry and so subscribe here too; each cleans up in `dispose`.\n if (isObservableAIProviderRegistry(this.providerRegistry)) {\n this.unsubscribeRegistry = this.providerRegistry.subscribe(() => {\n this.resolvedProviderCache.clear();\n this.resolvedStatusCache.clear();\n this.lastResolvedProviderName = undefined;\n this.lastResolvedModel = undefined;\n this.lastResolvedProvider = undefined;\n this.lastDispatchedProviderName = undefined;\n });\n }\n }\n\n /**\n * Tear down the driver: aborts the lifecycle signal so any in-flight provider\n * request (and prompt/tool factories awaiting it) cancels instead of running\n * on to completion or the transport timeout. Called by the host on driver\n * swap and by `OrchestratingDriver.dispose()`. Idempotent.\n *\n * Deliberately does NOT settle `pendingInteractions` here: dispose is never\n * reached while one is pending. The only host-level dispose is the agent-swap\n * rebuild, which is guarded by `isBusy()` \u2014 a pending interaction keeps the\n * tool loop suspended (`busy === true`), so the swap is deferred until the\n * widget resolves. Sub-agent child disposes always have an empty pending map\n * (widgets park on the parent via `setHostInteractionRequester`). A pending\n * interaction is instead settled by `resolveInteraction` (user response or\n * timeout), which also stamps history and reverts the chat-input override.\n */\n dispose(): void {\n this.lifecycleController.abort(new DOMException('AI assistant driver disposed', 'AbortError'));\n // Drop any live interaction contexts (GENC-1390). Normally empty at teardown\n // (a context is created and destroyed with its pending interaction, and dispose\n // is not reached mid-interaction); disposed defensively so a stray context can\n // never leak an open socket/timer.\n for (const handle of this.interactionContexts.values()) handle.dispose();\n this.interactionContexts.clear();\n // Detach from the provider registry so the long-lived registry doesn't pin\n // this driver (and its closure) after teardown. Guard-cleared so a second\n // dispose is a no-op, matching this method's idempotent contract.\n this.unsubscribeRegistry?.();\n this.unsubscribeRegistry = undefined;\n }\n\n /**\n * Stop the current turn (user \"stop\" button). Aborts the in-flight provider\n * request immediately; if a tool is mid-execution it runs to completion and\n * the loop bails at the next boundary (tools are atomic). No-op when idle.\n * The driver stays usable for the next message.\n */\n cancel(): void {\n if (!this.busy) return;\n this.turnCancelled = true;\n this.turnController.abort(new DOMException('Cancelled by user', 'AbortError'));\n }\n\n /**\n * Start a fresh per-turn abort scope. Chains `lifecycleController` into the\n * new `turnController` so a dispose mid-turn also aborts the request.\n */\n private beginTurn(): void {\n this.turnCancelled = false;\n this.turnController = new AbortController();\n const lifecycle = this.lifecycleController.signal;\n if (lifecycle.aborted) {\n this.turnController.abort(lifecycle.reason);\n this.unlinkLifecycleFromTurn = undefined;\n return;\n }\n const onDispose = () => this.turnController.abort(lifecycle.reason);\n lifecycle.addEventListener('abort', onDispose, { once: true });\n this.unlinkLifecycleFromTurn = () => lifecycle.removeEventListener('abort', onDispose);\n }\n\n /** Detach the lifecycle\u2192turn link so a long-lived lifecycle signal doesn't accumulate listeners. */\n private endTurn(): void {\n this.unlinkLifecycleFromTurn?.();\n this.unlinkLifecycleFromTurn = undefined;\n }\n\n /**\n * Finish a turn whose signal aborted. A user cancel adds a subtle \"Stopped.\"\n * marker; a dispose-driven abort stops quietly (the widget is gone and the\n * cached history would otherwise gain a stray marker on remount).\n */\n private completeAbortedTurn(): ChatDriverResult {\n if (this.turnCancelled) {\n logger.warn('ChatDriver: turn cancelled by user');\n this.appendToHistory({ role: 'system-event', content: 'Stopped.' });\n } else {\n logger.warn('ChatDriver: turn aborted (driver disposed)');\n }\n return { reason: 'done' };\n }\n\n /**\n * Build the `done` loop result, carrying the typed failure reason when the turn\n * bailed (PTC-0). The discriminant stays `'done'` either way \u2014 the same value a\n * clean turn returns \u2014 so consumers matching on `reason === 'done'` are unchanged;\n * `failureReason` is simply present on a failure and absent on success. Omitted\n * (rather than set to `undefined`) so a happy-path result stays byte-identical to\n * the historical `{ reason: 'done' }`.\n */\n private turnDone(failureReason?: TurnFailureReason, budget?: BudgetDetail): ChatDriverResult {\n if (!failureReason) return { reason: 'done' };\n // `budget` is likewise omitted rather than set to `undefined`, so a non-budget\n // failure's shape is unchanged for a consumer that structurally compares it.\n return budget ? { reason: 'done', failureReason, budget } : { reason: 'done', failureReason };\n }\n\n /**\n * Terminal budget outcome for a wall hit **outside** the tool loop \u2014 today,\n * `OrchestratingDriver`'s classification phase, which calls the provider\n * directly and so never enters `runToolLoop`.\n *\n * Does **not** publish `tool-loop-end`: no `tool-loop-start` was published for\n * the classify phase, and an unbalanced end would break start/end pairing for\n * subscribers that rely on it. The driver **return value** is what reports this\n * case \u2014 see `FoundationAiAssistant`'s latch, which reads both seams for\n * exactly this reason.\n *\n * The non-sub-agent tail of the in-loop `BudgetExhaustedError` branch lives\n * here so there is one copy of the log line, the debug-log entry, the\n * transcript bubble and the result shape rather than two that can drift.\n *\n * @param pendingUserMessage - a user message that has NOT yet been appended,\n * appended first so the answer does not end up replying to nothing. Only the\n * classification seam passes it: `OrchestratingDriver` dispatches the user's\n * text as an optimistic `history-updated` detail and leaves the real append\n * to `chatDriver.sendMessage`, which never runs when `classify()` throws \u2014 so\n * the bubble below would re-dispatch a history the user's own message was\n * never in, and it would vanish from the transcript on the next render. The\n * in-loop caller has already appended it and passes nothing.\n *\n * @internal\n */\n reportBudgetExhausted(\n e: BudgetExhaustedError,\n pendingUserMessage?: ChatMessage,\n ): ChatDriverResult {\n if (pendingUserMessage) this.appendToHistory(pendingUserMessage);\n this.budgetExhaustedThisTurn = true;\n logger.error('ChatDriver: AI budget exhausted', e);\n recordTurnError(this.sessionKey, 'budget-exhausted', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n // The registry ALIAS (e.g. 'high') is what `provider` records; the vendor\n // is the thing a per-vendor budget is actually scoped to, and it was known\n // at both ends and discarded in the middle until now. Taken from the\n // refusing transport's label first \u2014 this method also serves the\n // classification seam, where `lastResolvedProvider` is the PREVIOUS turn's\n // vendor (or nothing), because classify runs against the registry default.\n vendor:\n vendorTypeOfLabel(e.vendorLabel) ??\n vendorTypeOfLabel(e.serverVendor) ??\n this.lastResolvedProvider,\n budgetUsd: e.budgetUsd,\n spentUsd: e.spentUsd,\n isSubAgent: this.isSubAgent,\n });\n this.appendToHistory({ role: 'assistant', content: this.budgetExhaustedMessage });\n return this.turnDone('budget-exhausted', budgetDetailOf(e));\n }\n\n /** The typed failure reason on a loop result, or `undefined` for a clean turn / handoff. */\n private static failureReasonOf(result: ChatDriverResult): TurnFailureReason | undefined {\n return result.reason === 'done' ? result.failureReason : undefined;\n }\n\n /**\n * Build the `tool-loop-end` event detail for a turn's result. A failure carries a\n * `{ failureReason }` detail; a clean turn emits `undefined` \u2014 the historical shape,\n * kept byte-identical so subscribers see exactly what they always have.\n *\n * A budget failure additionally carries `vendor` \u2014 the concrete vendor\n * (`'anthropic'`/`'gemini'`) the walled turn resolved to, which the driver knows\n * and used to discard. Optional and additive: a subscriber reading only\n * `failureReason` is unaffected, a non-budget failure still emits the historical\n * `{ failureReason }` with no `vendor` key, and the value is a plain string so\n * the detail stays structured-cloneable for the cross-tab hop. It is the field a\n * per-vendor budget model needs and the one that would be awkward to retrofit.\n */\n private loopEndDetail(result: ChatDriverResult):\n | {\n failureReason: TurnFailureReason;\n vendor?: AIProviderType;\n budget?: BudgetDetail;\n }\n | undefined {\n const failureReason = ChatDriver.failureReasonOf(result);\n if (!failureReason) return undefined;\n if (failureReason !== 'budget-exhausted') {\n return { failureReason };\n }\n // The figures ride the event, not just the return value: this publish happens in\n // sendMessage's `finally`, so for an in-loop wall it reaches the host's latch FIRST\n // and the return-value seam is then a no-op (the latch is idempotent). Omitted\n // entirely \u2014 never set to undefined \u2014 when the proxy sent no figures.\n const budget = result.reason === 'done' ? result.budget : undefined;\n // Prefer the refusing transport's own attribution over the driver's\n // last-resolved provider, for the same staleness reason as `budgetDetailOf`.\n //\n // The fallback is legitimate ONLY for this driver's own wall \u2014 its resolved\n // provider IS the refuser then. When the wall came from a SUB-AGENT\n // (`budgetWallViaSubAgent`), the refuser is the child's vendor, and on a\n // mixed registry `lastResolvedProvider` is the one vendor known NOT to have\n // refused; an unattributable child wall degrades to the vendor-agnostic\n // event instead, which the host's latch handles fail-safe.\n const vendor =\n budget?.vendor ?? (this.budgetWallViaSubAgent ? undefined : this.lastResolvedProvider);\n return {\n failureReason,\n ...(vendor ? { vendor } : {}),\n ...(budget ? { budget } : {}),\n };\n }\n\n /**\n * Swap in a new agent's configuration. Called by OrchestratingDriver before\n * each specialist turn so the shared driver runs with the right tools and prompt.\n */\n applyAgent(config: AgentConfig): void {\n // A real swap to a different agent begins a NEW activation \u2014 the prior agent's\n // flow is over, so its `agentEnd`-tagged payloads become collapsible. Guarded\n // on a name change so re-applying the same agent (e.g. a per-turn re-resolve)\n // does not spuriously advance the clock and prematurely drop its payloads.\n if (config.name !== this.activeAgentName) this.currentActivation += 1;\n this.systemPrompt = config.systemPrompt;\n if (typeof config.toolDefinitions === 'function') {\n this.toolDefinitionsFactory = config.toolDefinitions;\n // Cleared each turn by the factory in runToolLoop; empty is safe in the\n // meantime (no LLM call happens before resolution).\n this.toolDefinitions = [];\n } else {\n this.toolDefinitionsFactory = undefined;\n this.toolDefinitions = config.toolDefinitions ?? [];\n }\n if (typeof config.toolHandlers === 'function') {\n this.toolHandlersFactory = config.toolHandlers;\n // Cleared each turn by the factory in runToolLoop; empty is safe in the\n // meantime (no LLM call happens before resolution).\n this.toolHandlers = {};\n } else {\n this.toolHandlersFactory = undefined;\n this.toolHandlers = config.toolHandlers ?? {};\n }\n this.primerHistory = config.primerHistory;\n this.activeAgentName = config.name;\n this.displayName = config.displayName;\n // Static string form resolves to a stable label up-front; the function\n // form gets re-resolved each tool-loop iteration. Falls back to the\n // canonical name when displayName is unset.\n this.activeAgentLabel =\n typeof config.displayName === 'string' ? config.displayName : config.name;\n this.debugSnapshotter = config.getDebugSnapshot;\n this.subAgentsMap = new Map((config.subAgents ?? []).map((s) => [s.name, s]));\n this.activeProviderInput = config.provider;\n this.activeTemperatureInput = config.temperature;\n this.activeToolChoiceInput = config.toolChoice;\n this.activeCachePolicyInput = config.cachePolicy;\n this.activeTailContextInput = config.tailContext;\n this.activeResponseSchemaInput = config.responseSchema;\n this.activeFallbacks = config.fallbacks;\n this.activeOnUnresolvedTool = config.onUnresolvedTool;\n this.resolvedProviderCache.clear();\n this.lastResolvedProviderName = undefined;\n // Static validation: resolve the name now so unknown-provider and missing-\n // capability errors fire at agent swap rather than on the first LLM call.\n // Function-form `provider` is validated lazily inside `resolveProviderForTurn`.\n if (typeof config.provider === 'string') {\n this.resolveProviderByName(config.provider, config.name);\n }\n // Reset fold state when agent changes \u2014 each specialist starts fresh\n this.foldStack = [];\n this.consecutiveFoldOps = 0;\n // Forget the previous agent's tools \u2014 \"previously available\" is scoped to\n // the current activation, so a stateful agent accumulates its tools across\n // states while a swap to a different specialist starts clean.\n this.everSeenToolNames.clear();\n }\n\n /**\n * Resolve the tool-result content for an unresolved tool call. Consults the\n * active agent's `onUnresolvedTool` hook (if any) with the attempted tool\n * name, the failure `kind`, and the currently dispatchable tools, and returns\n * the hook's non-empty string. Falls back to `fallback` when no hook is set,\n * the hook returns nothing/empty, or the hook throws \u2014 so a misbehaving hook\n * can never break tool dispatch.\n */\n private async resolveUnresolvedToolContent(\n toolName: string,\n kind: 'stale' | 'unknown',\n fallback: string,\n ): Promise<string> {\n if (typeof this.activeOnUnresolvedTool !== 'function') {\n return fallback;\n }\n try {\n const custom = await this.activeOnUnresolvedTool({\n toolName,\n kind,\n availableTools: Object.keys(this.toolHandlers),\n });\n return typeof custom === 'string' && custom.trim().length > 0 ? custom : fallback;\n } catch (e) {\n logger.warn(\n `ChatDriver: onUnresolvedTool threw for \"${toolName}\" \u2014 using default message`,\n e,\n );\n return fallback;\n }\n }\n\n /**\n * Returns the most recently resolved provider name. Falls back to the\n * registry's default when no per-turn resolution has happened yet.\n */\n getActiveProviderName(): string {\n return this.lastResolvedProviderName ?? this.providerRegistry.defaultName();\n }\n\n /**\n * Resolve a named provider against the registry. Cached per-agent so\n * repeated lookups during one agent's lifetime don't re-validate.\n * Validation lives in `resolveChatProvider`; this wrapper just adds the\n * cache.\n */\n private resolveProviderByName(name: string, agentName: string): AIProvider {\n const cached = this.resolvedProviderCache.get(name);\n if (cached) return cached;\n const provider = resolveChatProvider(this.providerRegistry, name, agentName);\n this.resolvedProviderCache.set(name, provider);\n return provider;\n }\n\n /**\n * Resolve the provider to use for the current turn. Walks the agent's\n * `provider` selector (static or function form) or falls back to the\n * registry default. Dispatches `provider-changed` when the resolved name\n * differs from the last dispatched value.\n */\n private async resolveProviderForTurn(ctx: SystemPromptContext): Promise<AIProvider> {\n let provider: AIProvider;\n let resolvedName: string;\n if (this.activeProviderInput === undefined) {\n provider = this.providerRegistry.default();\n resolvedName = this.providerRegistry.defaultName();\n } else {\n const name =\n typeof this.activeProviderInput === 'function'\n ? await this.activeProviderInput(ctx)\n : this.activeProviderInput;\n provider = this.resolveProviderByName(name, this.activeAgentName ?? '<unknown>');\n resolvedName = name;\n }\n this.lastResolvedProviderName = resolvedName;\n const status = await this.resolveStatusForProvider(resolvedName, provider);\n this.lastResolvedModel = status.model;\n this.lastResolvedProvider = status.provider;\n if (resolvedName !== this.lastDispatchedProviderName) {\n this.lastDispatchedProviderName = resolvedName;\n recordMetaEvent(this.sessionKey, 'provider.selected', {\n provider: resolvedName,\n agent: this.activeAgentName,\n });\n this.dispatchEvent(\n new CustomEvent<{ name: string }>('provider-changed', { detail: { name: resolvedName } }),\n );\n }\n return provider;\n }\n\n /**\n * Resolve model id and vendor from a provider via its optional `getStatus()`,\n * memoised by registry name. Used to stamp `model` and `provider` onto outgoing\n * messages. Best-effort: a provider without `getStatus`, a null status, or a\n * throw all yield empty fields \u2014 attribution is diagnostic, never load-bearing.\n */\n private async resolveStatusForProvider(\n name: string,\n provider: AIProvider,\n ): Promise<{ model?: string; provider?: AIProviderType }> {\n if (this.resolvedStatusCache.has(name)) return this.resolvedStatusCache.get(name)!;\n let status: { model?: string; provider?: AIProviderType } = {};\n try {\n const resolved = await provider.getStatus?.();\n if (resolved) {\n status = { model: resolved.model, provider: resolved.provider };\n }\n } catch {\n status = {};\n }\n this.resolvedStatusCache.set(name, status);\n return status;\n }\n\n /**\n * Resolve a per-turn config input that is either a static value or a function\n * of the turn context \u2014 the value-or-resolver shape shared by `provider`,\n * `temperature`, and `toolChoice`. Returns undefined when the input is unset.\n */\n private async resolveTurnInput<T>(\n input: T | ((ctx: SystemPromptContext) => T | Promise<T>) | undefined,\n ctx: SystemPromptContext,\n ): Promise<T | undefined> {\n if (input === undefined) return undefined;\n return typeof input === 'function'\n ? (input as (ctx: SystemPromptContext) => T | Promise<T>)(ctx)\n : input;\n }\n\n /**\n * Returns the early-stop result set by `completeSubAgent`, if any.\n * Called by a parent `ChatDriver` after running this instance as a sub-agent.\n */\n getSubAgentCompletion(): { result: unknown } | undefined {\n return this.subAgentCompletion;\n }\n\n /**\n * Mark this driver as running as a sub-agent. Called by a parent driver's\n * `invokeSubAgent` immediately after construction, before the first turn.\n * Enables forced tool use and typed failure reporting (see `isSubAgent`).\n */\n markAsSubAgent(): void {\n this.isSubAgent = true;\n }\n\n /**\n * Returns the typed failure recorded when a sub-agent run ended without\n * `completeSubAgent`, if any. Called by a parent `ChatDriver` after running\n * this instance as a sub-agent.\n */\n getSubAgentFailure(): { reason: SubAgentFailureReason; budget?: BudgetDetail } | undefined {\n return this.subAgentFailure;\n }\n\n /**\n * Record a sub-agent failure reason (first one wins). No-op for top-level\n * agents, so loop-exit sites can call it unconditionally. The parent reads\n * this via `getSubAgentFailure()` and emits the `subagent.failed` meta event\n * under its *own* session \u2014 see `invokeSubAgent`. (A child sub-agent runs\n * under a separate session key, so recording here would orphan the event off\n * the user-visible debug-log timeline.)\n */\n private failSubAgent(reason: SubAgentFailureReason, budget?: BudgetDetail): void {\n if (!this.isSubAgent || this.subAgentFailure) return;\n // Omitted rather than set to `undefined` so a non-budget failure's shape is\n // unchanged for a structural comparison, matching `turnDone`.\n this.subAgentFailure = budget ? { reason, budget } : { reason };\n }\n\n /**\n * Returns true if `releaseAgent` was called during the most recent turn.\n * Consumed by the orchestrator to trigger the auto-pin release path.\n */\n getAgentReleaseRequested(): boolean {\n return this.agentReleaseRequested;\n }\n\n /**\n * Return the per-turn snapshots captured so far. Used by the host's debug\n * log exporter to show what the LLM saw on each turn \u2014 system prompt, tool\n * surface, and agent-supplied state (e.g. a machine snapshot).\n *\n * Ring-buffered at `MAX_TURN_SNAPSHOTS`; older entries are dropped.\n */\n getTurnSnapshots(): ReadonlyArray<TurnSnapshot> {\n return this.turnSnapshots;\n }\n\n /**\n * The `turn` + `message` diagnostic-log entries harvested from resolved interactions'\n * `InteractionResult.diagnostics` (e.g. a server-side ChatDriver's collated debug log). The host\n * concatenates these into its own debug log so `downloadDebugLog`/the persisted diagnostics stream\n * include external-engine logs; `event` entries are excluded here because they're merged into the\n * session's meta-event registry instead (see `resolveInteraction`) and reach the log via\n * `getMetaEvents`. Opaque, chronologically sorted by the host at assemble time. (GENC-1461.)\n */\n getExternalDiagnostics(): ReadonlyArray<DiagnosticEntry> {\n return this.externalDiagnostics;\n }\n\n /**\n * Merge a sub-agent's turn snapshots into this driver's buffer so they surface\n * as `kind:'turn'` entries in the exported debug log. The child runs as a\n * separate, discarded driver, so its snapshots would otherwise be lost. Each is\n * re-labelled under the parent turn that activated the sub-agent: the child's\n * own (numeric) turns become `\"<parentTurn>-1\"`, `\"-2\"`, \u2026 (1-based, in order);\n * any already-forwarded grand-child labels (strings) have their leading segment\n * remapped the same way, so nesting composes (`\"5-2\"` \u2192 `\"5-2-1\"`).\n *\n * Note: two sub-agents invoked in the *same* parent turn share the prefix, so\n * their labels can repeat \u2014 `agentName` on each snapshot disambiguates them.\n */\n private forwardSubAgentSnapshots(childSnapshots: ReadonlyArray<TurnSnapshot>): void {\n if (childSnapshots.length === 0) return;\n // The activating parent turn = the most recent snapshot this driver recorded\n // before entering the tool handler that invoked the sub-agent.\n const parentTurn = Math.max(0, this.globalTurnIndex - 1);\n const ownTurnLabel = new Map<string, string>();\n let ownPos = 0;\n for (const snap of childSnapshots) {\n let turnIndex: string;\n if (!snap.turnIndex.includes('-')) {\n // The child's own turn (a bare counter) \u2192 number it under the parent turn.\n ownPos += 1;\n turnIndex = `${parentTurn}-${ownPos}`;\n ownTurnLabel.set(snap.turnIndex, turnIndex);\n } else {\n // An already-forwarded grand-child label \u2014 remap its leading segment.\n const [lead, ...rest] = snap.turnIndex.split('-');\n const leadLabel = ownTurnLabel.get(lead) ?? `${parentTurn}-${lead}`;\n turnIndex = [leadLabel, ...rest].join('-');\n }\n this.turnSnapshots.push({ ...snap, turnIndex });\n }\n while (this.turnSnapshots.length > this.maxTurnSnapshots) {\n this.turnSnapshots.shift();\n }\n }\n\n /**\n * Push one snapshot to the ring buffer. Called inside `runToolLoop` just\n * before each LLM call \u2014 that's the latest point where the prompt, tool\n * surface, and agent state line up with what the model is about to see.\n */\n private recordTurnSnapshot(\n resolvedSystemPrompt: string | undefined,\n temperature: number | undefined,\n toolChoice: ChatToolChoice | undefined,\n tailContext: string | undefined,\n ): void {\n let agentSnapshot: unknown;\n if (this.debugSnapshotter) {\n try {\n agentSnapshot = this.debugSnapshotter();\n } catch (e) {\n // A snapshotter throwing must not derail the LLM call \u2014 capture the\n // error string in place of the snapshot so the export still shows\n // *something* happened.\n agentSnapshot = `<getDebugSnapshot threw: ${e instanceof Error ? e.message : String(e)}>`;\n }\n }\n const turnIndex = String(this.globalTurnIndex);\n this.globalTurnIndex += 1;\n this.turnSnapshots.push({\n turnIndex,\n timestamp: new Date().toISOString(),\n agentName: this.activeAgentName,\n agentLabel: this.activeAgentLabel,\n systemPrompt: resolvedSystemPrompt,\n tailContext,\n toolNames: this.toolDefinitions.map((t) => t.name),\n temperature,\n toolChoice,\n agentSnapshot,\n });\n if (this.turnSnapshots.length > this.maxTurnSnapshots) {\n this.turnSnapshots.shift();\n }\n }\n\n /**\n * Optional transform applied to conversation history immediately before each LLM request.\n * Cleared when `undefined`. Does not alter stored history.\n */\n setProviderHistoryTransform(transform?: (history: ChatMessage[]) => ChatMessage[]): void {\n this.providerHistoryTransform = transform;\n }\n\n getHistory(): ReadonlyArray<ChatMessage> {\n return this.history;\n }\n\n getRawHistory(): readonly ChatMessage[] {\n return this.history;\n }\n\n /** Returns the current fold stack names for debugging. */\n getActiveFoldNames(): string[] {\n return this.foldStack.map((f) => f.foldName);\n }\n\n async getSuggestions(\n history: ChatMessage[],\n prompt: string,\n count: number,\n allAgentInfo?: AllAgentSummary[],\n ): Promise<string[]> {\n // Suggestions are an out-of-turn UI helper, not bound to any single agent \u2014\n // always run against the registry default. Best-effort: a default with no\n // `prompt()` just means no suggestions, not a hard error.\n const defaultProvider = this.providerRegistry.default();\n if (!defaultProvider.prompt) {\n logger.warn('ChatDriver: default AI provider does not implement prompt()');\n return [];\n }\n\n let agentContext = '';\n let toolContext = '';\n\n if (allAgentInfo?.length) {\n const agentDescriptions = allAgentInfo\n .map((agent) => {\n const tools = agent.tools.map((t) => t.name).join(', ');\n return `- ${agent.name} (${agent.description}): ${tools ? `(Tools: ${tools})` : 'No tools'}`;\n })\n .join('\\n');\n agentContext = `The assistant has the following capabilities:\\n${agentDescriptions}`;\n\n const allToolNames = allAgentInfo\n .flatMap((agent) => agent.tools.map((t) => t.name))\n .filter((value, index, self) => self.indexOf(value) === index)\n .join(', ');\n toolContext = allToolNames\n ? `You have access to the following tools across all agents: ${allToolNames}.`\n : '';\n } else if (this.activeAgentName) {\n const toolNames = this.toolDefinitions.map((tool) => tool.name).join(', ');\n agentContext = `You are currently acting as the \"${this.activeAgentName}\" agent.`;\n toolContext = toolNames ? `You have access to the following tools: ${toolNames}.` : '';\n }\n\n // System prompt is intentionally short: it sets the role only. Concrete\n // instructions live in the user message *after* the transcript so the\n // immediately-preceding context for the model is \"here is data, now do X\"\n // rather than \"here is a dialogue, continue it\". This matters for Anthropic\n // \u2014 without it, Claude reads the transcript as an in-progress conversation\n // and produces a normal assistant turn instead of a list of suggestions.\n const systemPrompt =\n 'You generate suggested prompts that a user could send to an AI assistant. ' +\n 'You never continue the conversation or roleplay as the assistant.';\n\n const capabilitiesBlock =\n agentContext || toolContext\n ? `\\n\\n<capabilities>\\n${[agentContext, toolContext].filter(Boolean).join('\\n')}\\n</capabilities>\\nSuggestions must only cover what the agent is capable of. Do not suggest anything outside these capabilities.`\n : '';\n\n const guidanceBlock = prompt ? `\\n\\nAdditional guidance: \"${prompt}\"` : '';\n\n let userMessage: string;\n if (history.length === 0) {\n userMessage =\n `Generate exactly ${count} brief starter prompts to show a user what an AI assistant can do. ` +\n `Phrase each one as the user would write it. Keep them short and generic \u2014 do not invent specific names, IDs, or data (e.g. prefer \"Search for a trade\" over \"Find all trades with Client A\").` +\n capabilitiesBlock +\n guidanceBlock +\n `\\n\\nOutput format (strict):\\n` +\n `- Exactly ${count} lines.\\n` +\n `- One suggestion per line.\\n` +\n `- No numbering, bullets, markdown, emojis, code blocks, or quotes around the suggestion.\\n` +\n `- No preamble, headings, summary, or commentary before or after the list.`;\n } else {\n const conversationContext = history\n .filter(\n (m) =>\n (m.role === 'user' || m.role === 'assistant') &&\n !m.toolCalls?.length &&\n !m.thinking &&\n !!m.content?.trim(),\n )\n .slice(-SUGGESTIONS_HISTORY_WINDOW)\n .map((m) => `${m.role === 'user' ? 'User' : 'Assistant'}: ${m.content}`)\n .join('\\n');\n\n userMessage =\n `<conversation_history>\\n${conversationContext}\\n</conversation_history>\\n\\n` +\n `The conversation above has ended. Do not continue it or respond as the assistant. ` +\n `Generate exactly ${count} follow-up prompts the *user* might send next, phrased in first person as the user would write them. ` +\n `The first ${Math.max(0, count - 1)} should be natural follow-ups to the last turn. ` +\n `Do not invent specific names, IDs, or data values that do not appear in <conversation_history>.` +\n capabilitiesBlock +\n guidanceBlock +\n `\\n\\nOutput format (strict):\\n` +\n `- Exactly ${count} lines.\\n` +\n `- One suggestion per line.\\n` +\n `- No numbering, bullets, markdown, emojis, code blocks, or quotes around the suggestion.\\n` +\n `- No preamble, headings, summary, or commentary before or after the list.`;\n }\n\n const text = await defaultProvider.prompt!(userMessage, { systemPrompt });\n\n // Lenient parsing as a defensive backstop: even with the strict prompt,\n // models occasionally slip in numbering, bullets, or surrounding markdown.\n return (\n text\n .split('\\n')\n .map((s) => s.trim())\n // strip leading bullets/numbers (\"- \", \"* \", \"\u2022 \", \"1. \", \"1) \")\n .map((s) => s.replace(/^([-*\u2022]|\\d+[.)])\\s+/, ''))\n // strip surrounding bold/italic markers\n .map((s) => s.replace(/^[*_]{1,3}|[*_]{1,3}$/g, '').trim())\n // drop empty lines, separators, and obvious preamble lines\n .filter((s) => s.length > 0)\n .filter((s) => !/^[-=]{2,}$/.test(s))\n .filter((s) => !/^here (are|is) /i.test(s))\n .filter((s) => !s.endsWith(':'))\n .slice(0, count)\n );\n }\n\n /**\n * Whether `compact()` would do anything right now \u2014 a summarizable run of older\n * turns exists behind a clean boundary. Uses the same `history` `compact()`\n * acts on, so the UI's gate can't disagree with the action (GENC-1351 follow-up).\n */\n canCompact(): boolean {\n return findCompactionCut(this.history) != null;\n }\n\n /**\n * Destructively compact older turns into a single `compacted-summary` message\n * (GENC-1351 \u00A75.7). Summarizes everything before a clean recent-tail boundary\n * via the registry-default provider's one-shot `prompt()`, then **atomically**\n * replaces the covered turns with one summary message at the head \u2014 history is\n * mutated only on success. Rolling: any existing head summary is folded into\n * the new one. Returns the created summary message, or `null` when there is\n * nothing worth compacting or the default provider cannot summarize.\n */\n async compact(): Promise<ChatMessage | null> {\n if (this.busy) return null;\n const defaultProvider = this.providerRegistry.default();\n if (!defaultProvider.prompt) {\n logger.warn('ChatDriver: default AI provider has no prompt(); cannot compact');\n return null;\n }\n\n const history = this.history;\n const cut = findCompactionCut(history);\n if (cut == null) return null;\n\n const toCompact = history.slice(0, cut);\n const tail = history.slice(cut);\n\n // Summarize BEFORE mutating history \u2014 a failed/empty call leaves the\n // transcript untouched (atomic generate-then-replace).\n const { systemPrompt, userMessage } = buildCompactionSummaryPrompt(toCompact);\n // Surface a failure the way turn errors are surfaced \u2014 a brief \"sorry\" agent\n // message \u2014 while leaving the transcript itself untouched (atomic). Retrying\n // is safe (nothing was spliced).\n const failMessage =\n \"Sorry, I couldn't compact the conversation just now. Nothing was changed \u2014 please try again.\";\n let summaryText: string;\n try {\n summaryText = (await defaultProvider.prompt!(userMessage, { systemPrompt }))?.trim() ?? '';\n } catch (e) {\n logger.warn(`ChatDriver: compaction summary failed: ${e instanceof Error ? e.message : e}`);\n this.appendToHistory({ role: 'assistant', content: failMessage });\n return null;\n }\n if (!summaryText) {\n logger.warn('ChatDriver: compaction summary was empty; leaving history untouched');\n this.appendToHistory({ role: 'assistant', content: failMessage });\n return null;\n }\n\n let tokensBefore: number | undefined;\n for (let i = history.length - 1; i >= 0; i -= 1) {\n if (history[i].inputTokens != null) {\n tokensBefore = history[i].inputTokens;\n break;\n }\n }\n const status = await defaultProvider.getStatus?.();\n const createdAt = new Date().toISOString();\n const summaryMessage: ChatMessage = {\n role: 'compacted-summary',\n content: summaryText,\n // Stamp with the covered region's start, not \"now\": the summary stands in\n // for the oldest messages and sits at the head of history, so this keeps it\n // sorted to the head in any timestamp-ordered view (the debug timeline) and\n // history time-monotonic. Its true creation time is in compaction.createdAt.\n timestamp: toCompact[0]?.timestamp ?? createdAt,\n compaction: {\n compactedCount: toCompact.length,\n coveredThroughTimestamp: toCompact[toCompact.length - 1]?.timestamp,\n tokensBefore,\n model: status?.model,\n createdAt,\n // Bank what the replaced turns spent. `toCompact` is dropped from history\n // below, taking its per-message cost/token fields with it \u2014 so a host total\n // re-derived from the transcript would otherwise fall by exactly this much\n // on every compaction. Summarising a turn does not refund what it cost.\n rolledUpUsage: sumUsage(toCompact),\n },\n };\n\n this.loadHistory([summaryMessage, ...tail]);\n return summaryMessage;\n }\n\n isBusy(): boolean {\n return this.busy;\n }\n\n /**\n * Wire a parent driver as the host for this driver's interactions. When set,\n * `requestInteraction` delegates upward so the widget renders in (and\n * resolves through) the parent's history and pending map. Calls chain\n * naturally: a grandchild \u2192 child \u2192 root.\n */\n public setHostInteractionRequester(\n fn: <T>(componentName: string, data: any, options?: InteractionRequestOptions) => Promise<T>,\n ): void {\n this.hostInteractionRequester = fn;\n }\n\n /**\n * Request a custom UI interaction. Emits a new message with the interaction.\n * Tool handlers can call this to pause execution until the user completes the UI interaction.\n *\n * If a host requester is wired (sub-agent case), the call delegates upward\n * so the interaction lives on the parent \u2014 the main UI is only listening to\n * the root driver. Only one interaction may be in flight at any time on a\n * given root: concurrent calls (e.g. two parallel sub-agents both spawning a\n * widget) throw. Parallel sub-agents are for parallel work, not for user\n * interaction, which is inherently sequential.\n *\n * @param componentName - The custom element name to render.\n * @param data - Data to pass to the component.\n * @param options - Optional per-call overrides, including\n * `chatInputDuringExecution` to hide or disable the main chat input while\n * the widget is awaiting user input (reverts when the interaction resolves),\n * and `presentation` to control whether the host wraps the widget in a chat\n * bubble and/or shows the \"Assistant\" label.\n */\n public async requestInteraction<T>(\n componentName: string,\n data: any,\n options?: InteractionRequestOptions,\n ): Promise<T> {\n if (this.hostInteractionRequester) {\n return this.hostInteractionRequester<T>(componentName, data, options);\n }\n if (this.pendingInteractions.size > 0) {\n throw new Error(\n 'requestInteraction: another user interaction is already in flight. ' +\n 'Only one interaction may be active at a time \u2014 sequence them in a single tool handler ' +\n 'rather than spawning widgets from parallel sub-agents or parallel tool calls.',\n );\n }\n const interactionId = crypto.randomUUID();\n const chatInputDuringExecution = options?.chatInputDuringExecution;\n const timeoutMs = options?.timeoutMs;\n const presentation = options?.presentation;\n return new Promise((resolve, reject) => {\n this.pendingInteractions.set(interactionId, {\n resolve,\n reject,\n overrideId: chatInputDuringExecution ? interactionId : undefined,\n // Resolve the interaction with a timeout result if the user does not\n // respond in time. `resolveInteraction` runs the same teardown a normal\n // resolution does (marks the widget read-only, reverts any input\n // override) and clears any still-pending handle.\n timeoutHandle:\n timeoutMs != null\n ? setTimeout(() => {\n this.resolveInteraction(interactionId, {\n status: 'timeout',\n message: `Interaction timed out after ${timeoutMs}ms.`,\n } satisfies InteractionResult);\n }, timeoutMs)\n : undefined,\n });\n recordMetaEvent(this.sessionKey, 'interaction.requested', {\n interactionId,\n component: componentName,\n agent: this.activeAgentName,\n });\n // Signal the park boundary on the activity bus so turn-aware UI can tell\n // \"actively computing\" from \"parked awaiting the user\" \u2014 the latter is a\n // safe window for actions disallowed mid-request (e.g. switching provider\n // during a long journey step). Paired with `interaction-resolved`.\n this.activityBus.publish('interaction-requested', undefined);\n if (chatInputDuringExecution) {\n this.dispatchEvent(\n new CustomEvent('interaction-start', {\n detail: { interactionId, chatInputDuringExecution },\n }),\n );\n }\n // Create the live context (GENC-1390) BEFORE the widget can mount, so the\n // wrapper finds it when it builds the pending `interaction` descriptor.\n this.interactionContexts.set(interactionId, createInteractionContext(interactionId));\n this.appendToHistory({\n role: 'assistant',\n content: '',\n interaction: {\n interactionId,\n componentName,\n data,\n ...(presentation ? { presentation } : {}),\n },\n });\n });\n }\n\n /**\n * Resolve a pending interaction. The wrapper component calls this on completion.\n * Marks the interaction message as resolved so it renders read-only on re-render.\n */\n public resolveInteraction(interactionId: string, result: any): void {\n const interaction = this.pendingInteractions.get(interactionId);\n if (interaction) {\n // Clear the timeout so a user resolution doesn't later fire a stale\n // timeout (and a timeout firing here clears its own already-fired handle).\n if (interaction.timeoutHandle) clearTimeout(interaction.timeoutHandle);\n // Harvest any out-of-band diagnostic entries the widget collated (e.g. from a server-side\n // ChatDriver) so the host's debug log + persisted diagnostics include them. Independent of the\n // message `idx` below \u2014 they describe the widget's own work, not this message.\n //\n // The harvested entries carry the SOURCE engine's own index space (0-based turns/events), which\n // would collide with this host's cursors in the forward-capture persister \u2014 turns dedup by\n // `turnIndex`, events by an `index` high-water mark \u2014 so foreign entries get silently dropped\n // from the persisted stream. Route each kind through the host's own collision-safe machinery,\n // mirroring how a sub-agent's log is folded in (see `invokeSubAgent`):\n // \u2022 `event` \u2192 `mergeMetaEvents`, which re-indexes them onto this session's monotonic event\n // counter (clearing the high-water) while preserving their timestamps; they then\n // reach the log via `getMetaEvents` in `buildTimelineEntries`, not this buffer.\n // \u2022 `turn` \u2192 re-key `turnIndex` to the turn's local position within a per-batch namespace,\n // so turns stay unique even when one interaction folds in several independent\n // server runs that each number their own turns from 0 (a consolidator carries a\n // consolidator-code run AND a table-code run), and never collide with the host's\n // own bare-integer turn keys.\n // \u2022 `message` \u2192 kept as-is; the persister already keys messages by content, so they survive.\n // TODO(GENC-1461, option 2 / streaming): expose an imperative `appendDiagnostics(entries)` on\n // the handler context (see buildHandlerContext) that runs this same decomposition as SSE ticks\n // arrive, so a streaming widget can surface its external engine's log live rather than only at\n // resolve time. Batch-at-resolve (here) is the current, non-streaming path.\n const harvestedDiagnostics = (result as { diagnostics?: readonly unknown[] } | undefined)\n ?.diagnostics;\n if (Array.isArray(harvestedDiagnostics) && harvestedDiagnostics.length) {\n const batch = (this.externalDiagnosticsBatches += 1);\n const externalEvents: MetaEvent[] = [];\n let turnCount = 0;\n let messageCount = 0;\n for (const raw of harvestedDiagnostics) {\n // The harvest is external and typed `unknown[]`, so an element could be a primitive, null,\n // or an object without a string `kind`. Guard before reading `.kind` so a malformed entry\n // can't throw here (and gets skipped rather than derailing the whole fold).\n if (\n !raw ||\n typeof raw !== 'object' ||\n typeof (raw as { kind?: unknown }).kind !== 'string'\n ) {\n continue;\n }\n const entry = raw as DiagnosticEntry;\n if (entry.kind === 'event') {\n const { kind: _kind, ...event } = entry;\n externalEvents.push(event as unknown as MetaEvent);\n } else if (entry.kind === 'turn') {\n // Local position within THIS harvest, not the source engine's own `turnIndex`: one\n // interaction can carry several independent server runs (a consolidator folds in its\n // consolidator-code run and its table-code run), each numbering its turns from 0, so\n // keying by the source index would collide them. The local position keeps every turn key\n // distinct within the batch, so the persister's per-`turnIndex` dedup keeps them all.\n this.externalDiagnostics.push({\n ...entry,\n turnIndex: `server-generation.${batch}:${turnCount}`,\n });\n turnCount += 1;\n } else if (entry.kind === 'message') {\n messageCount += 1;\n this.externalDiagnostics.push(entry);\n }\n // Any other kind is intentionally dropped, not folded. A sibling's `buildTimelineEntries`\n // only ever emits message/turn/event; `meta-snapshot` is host/DOM-owned (latest-wins on\n // reassembly, plus its own persister dedup), so folding a foreign one would pollute this\n // host's timeline and meta cursor. Restricting to the three real kinds also keeps the\n // manifest counts accurate (nothing miscounted as a `message`).\n }\n if (externalEvents.length) mergeMetaEvents(this.sessionKey, externalEvents);\n // Manifest: one provenance marker for the fold itself \u2014 records that an out-of-band engine's\n // log crossed into this session and how much of each kind, so a regression that silently\n // drops a generation's diagnostics (e.g. a new path that forgets to thread them across the\n // boundary) surfaces as a zero/absent manifest rather than only by diffing a download. Also\n // the natural seed for the streaming PR's open/close bracket. Stamped at resolve, so it\n // closes the block on the sorted timeline. (GENC-1461.)\n recordMetaEvent(this.sessionKey, 'external-diagnostics.folded', {\n interactionId,\n batch,\n counts: { turn: turnCount, event: externalEvents.length, message: messageCount },\n });\n }\n const idx = this.history.findIndex((m) => m.interaction?.interactionId === interactionId);\n if (idx !== -1) {\n // Fold any widget-reported external (non-LLM) cost onto the message, so\n // the host's `sumCosts` recompute includes it in the session total.\n // Accumulates defensively in case a widget reports more than once.\n const costUsd =\n typeof result?.costUsd === 'number' &&\n Number.isFinite(result.costUsd) &&\n result.costUsd > 0\n ? result.costUsd\n : undefined;\n this.history[idx] = {\n ...this.history[idx],\n interaction: { ...this.history[idx].interaction!, resolved: result },\n ...(costUsd != null\n ? { externalCostUsd: (this.history[idx].externalCostUsd ?? 0) + costUsd }\n : {}),\n };\n this.dispatchEvent(\n new CustomEvent<ReadonlyArray<ChatMessage>>('history-updated', {\n detail: this.history,\n }),\n );\n }\n // A widget may opt into echoing its outcome on the user's side of the\n // chat by returning `userMessage`. Appended as a display-only\n // `'synthetic-user'` message: it is tracked in history (and the debug log)\n // and rendered like a user message, but transports never serialize it \u2014\n // the model already learns the outcome from this handler's return value.\n // Appended before `interaction.resolve` so it precedes the tool result and\n // any follow-up turn the resumed handler produces.\n if (typeof result?.userMessage === 'string' && result.userMessage.trim()) {\n this.appendToHistory({ role: 'synthetic-user', content: result.userMessage });\n }\n if (interaction.overrideId) {\n this.dispatchEvent(new CustomEvent('interaction-stop', { detail: { interactionId } }));\n }\n recordMetaEvent(this.sessionKey, 'interaction.resolved', { interactionId });\n // The park is ending and the loop is about to resume computing \u2014 paired\n // with `interaction-requested`. Fires for every resolution path (user\n // completion, timeout, cancellation), since all route through here.\n this.activityBus.publish('interaction-resolved', undefined);\n interaction.resolve(result);\n this.pendingInteractions.delete(interactionId);\n // Tear down the live context on RESOLVE (not on element unmount) \u2014 this closes\n // any sockets/timers the widget parked on it via `onDispose`. (GENC-1390)\n this.interactionContexts.get(interactionId)?.dispose();\n this.interactionContexts.delete(interactionId);\n } else {\n logger.warn(`Interaction with ID ${interactionId} not found.`);\n }\n }\n\n /**\n * The live {@link InteractionContext} for a pending interaction (GENC-1390), or\n * `undefined` once resolved/evicted. Read by `AiChatInteractionWrapper` (via the\n * host) to build the widget's pending `interaction` descriptor.\n */\n public getInteractionContext(interactionId: string): InteractionContext | undefined {\n return this.interactionContexts.get(interactionId)?.context;\n }\n\n /**\n * Resolve every in-flight interaction with a `'timeout'` result, closing its\n * widget read-only. Used when a sub-agent that owns the open widget times out:\n * the widget is parked in *this* driver's map (interactions resolve on the\n * host, not the child), so cancelling it here unblocks the sub-agent handler\n * awaiting it. The \"one interaction at a time\" invariant means there is at\n * most one.\n */\n private cancelPendingInteractions(message: string): void {\n for (const interactionId of [...this.pendingInteractions.keys()]) {\n this.resolveInteraction(interactionId, {\n status: 'timeout',\n message,\n } satisfies InteractionResult);\n }\n }\n\n /**\n * Seeds the driver with a prior conversation history so a new component instance\n * can continue an existing conversation. Call this before the first user message.\n */\n public loadHistory(messages: ChatMessage[]): void {\n this.history = [...messages];\n this.dispatchEvent(\n new CustomEvent<ReadonlyArray<ChatMessage>>('history-updated', {\n detail: this.history,\n }),\n );\n }\n\n async sendMessage(userInput: string, attachments?: ChatAttachment[]): Promise<ChatDriverResult> {\n if (this.busy || (!userInput.trim() && !attachments?.length)) return { reason: 'done' };\n\n this.busy = true;\n this.beginTurn();\n // A new user turn \u2014 advances the `turnEnd` clock (continuations after a\n // handoff stay on the same turn; they go through `continueFromHistory`).\n this.turnSeq += 1;\n this.subAgentCompletion = undefined;\n this.subAgentFailure = undefined;\n this.agentReleaseRequested = false;\n this.budgetExhaustedThisTurn = false;\n this.budgetWallDetail = undefined;\n this.budgetWallViaSubAgent = false;\n this.appendToHistory({ role: 'user', content: userInput, attachments });\n this.turnStartedAt = Date.now();\n recordMetaEvent(this.sessionKey, 'turn.start', {\n phase: 'sendMessage',\n agent: this.activeAgentName,\n });\n this.activityBus.publish('tool-loop-start', undefined);\n\n // Captured so the `finally` can carry the turn's outcome onto `tool-loop-end`.\n let result: ChatDriverResult = { reason: 'done' };\n try {\n result = await this.runToolLoop(userInput, attachments);\n return result;\n } catch (e) {\n logger.error('ChatDriver error:', e);\n recordTurnError(this.sessionKey, 'exception', {\n phase: 'sendMessage',\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n name: e instanceof Error ? e.name : undefined,\n message: e instanceof Error ? e.message : String(e),\n });\n this.appendToHistory({\n role: 'assistant',\n content: 'Sorry, something went wrong on my end. Please try again in a moment.',\n });\n result = this.turnDone('exception');\n return result;\n } finally {\n recordMetaEvent(this.sessionKey, 'turn.end', {\n phase: 'sendMessage',\n agent: this.activeAgentName,\n durationMs: Date.now() - this.turnStartedAt,\n });\n this.busy = false;\n this.endTurn();\n this.activityBus.publish('tool-loop-end', this.loopEndDetail(result));\n }\n }\n\n /**\n * Builds the context object passed to every tool handler call.\n * Centralised here so fold shortcut dispatch and the main tool loop use the\n * same context without duplication.\n *\n * @param activeToolCallId - The id of the tool call this context belongs to, so\n * `condenseWhen` can register against the right call (it stamps the clocks\n * straight off the driver). Absent for dispatch paths with no addressable tool\n * call (e.g. the fold-close handler), where `condenseWhen` is a no-op.\n * @param traceCapture - Optional per-invocation slot. When provided, the trace\n * from any sub-agent call is written here rather than to shared instance state,\n * so parallel tool calls each capture their own trace independently.\n */\n private buildHandlerContext(activeToolCallId?: string, traceCapture?: { trace?: ChatMessage[] }) {\n return {\n requestInteraction: <T>(\n componentName: string,\n data: any,\n options?: InteractionRequestOptions,\n ): Promise<T> => this.requestInteraction(componentName, data, options),\n ...(this.subAgentsMap.size > 0 && {\n requestSubAgent: <T = never>(\n name: string,\n options?: SubAgentRequestOptions,\n ): Promise<\n | { ok: true; result: T; reason?: never }\n | { ok: false; result?: never; reason: SubAgentFailureReason }\n > =>\n this.invokeSubAgent<T>(name, options).then(({ outcome, trace }) => {\n if (traceCapture) traceCapture.trace = trace;\n return outcome;\n }),\n }),\n completeSubAgent: (result: unknown): void => {\n if (this.subAgentCompletion) {\n logger.warn(\n `ChatDriver(${this.activeAgentName ?? 'unknown'}): completeSubAgent called more than once \u2014 ignoring`,\n );\n return;\n }\n this.subAgentCompletion = { result };\n // This activation's flow has ended \u2014 advance the clock so its\n // `agentEnd` payloads collapse and a re-run starts a fresh activation.\n this.currentActivation += 1;\n },\n releaseAgent: (): void => {\n if (this.agentReleaseRequested) {\n logger.warn(\n `ChatDriver(${this.activeAgentName ?? 'unknown'}): releaseAgent called more than once \u2014 ignoring`,\n );\n return;\n }\n this.agentReleaseRequested = true;\n // The stateful flow has wrapped up \u2014 advance the clock so its `agentEnd`\n // payloads collapse and a re-run starts a fresh activation.\n this.currentActivation += 1;\n },\n endPhase: (): void => {\n // Advance the phase epoch so payloads registered with `{ on: phaseEnd }`\n // during the phase that just ended collapse on the next provider call.\n // Repeatable (no once-only guard, unlike releaseAgent/completeSubAgent):\n // each call opens a fresh phase for subsequent reads to accumulate in.\n this.currentPhaseEpoch += 1;\n },\n condenseWhen: (policy: CondensePolicy): void => {\n // No addressable tool call (e.g. fold-close handler) \u2014 nothing to attach to.\n if (!activeToolCallId) return;\n if (!policy?.args && !policy?.response) {\n logger.warn(\n `ChatDriver(${this.activeAgentName ?? 'unknown'}): condenseWhen called with neither args nor response \u2014 ignoring`,\n );\n return;\n }\n const triggers = Array.isArray(policy.on) ? policy.on : [policy.on];\n const validTrigger = (t: CondenseTrigger | undefined): boolean =>\n t?.kind === 'superseded'\n ? typeof t.by === 'string' && t.by.length > 0\n : t?.kind === 'age'\n ? typeof t.turns === 'number' && t.turns >= 1\n : t?.kind === 'turnEnd' || t?.kind === 'agentEnd' || t?.kind === 'phaseEnd';\n if (triggers.length === 0 || !triggers.every(validTrigger)) {\n logger.warn(\n `ChatDriver(${this.activeAgentName ?? 'unknown'}): condenseWhen called with an invalid trigger \u2014 ignoring`,\n );\n return;\n }\n // First-wins: a handler declares its policy once per call. A second\n // declaration for the same tool call is a handler bug, not a refinement.\n if (this.condensePolicies.has(activeToolCallId)) {\n logger.error(\n `ChatDriver(${this.activeAgentName ?? 'unknown'}): condenseWhen called more than once for the same tool call \u2014 keeping the first policy, ignoring this one`,\n );\n return;\n }\n // Stamp the three clocks NOW (read straight off the driver \u2014 the handler\n // runs during the current model-call's tool batch).\n this.condensePolicies.set(activeToolCallId, {\n policy,\n iteration: this.modelCallSeq,\n turn: this.turnSeq,\n activation: this.currentActivation,\n phaseEpoch: this.currentPhaseEpoch,\n });\n },\n };\n }\n\n /**\n * Creates a child `ChatDriver` for the named sub-agent, runs it to completion,\n * and returns its structured result (or final text fallback) together with the\n * full child conversation trace. Callers receive both values so each parallel\n * invocation can capture its own trace without touching shared instance state.\n */\n private async invokeSubAgent<T = never>(\n name: string,\n options?: SubAgentRequestOptions,\n ): Promise<{\n // Closed union (see ChatToolHandlers.requestSubAgent) \u2014 keeps `result`/`reason`\n // accessible for consumers compiled without strictNullChecks.\n outcome:\n | { ok: true; result: T; reason?: never }\n | { ok: false; result?: never; reason: SubAgentFailureReason };\n trace: ChatMessage[];\n }> {\n const subConfig = this.subAgentsMap.get(name);\n if (!subConfig) {\n const available = [...this.subAgentsMap.keys()].join(', ') || '(none)';\n throw new Error(\n `Sub-agent \"${name}\" not found on agent \"${this.activeAgentName}\". Available: ${available}`,\n );\n }\n\n const { task, historyCap, context, timeoutMs } = options ?? {};\n\n // Exclude the current in-flight assistant message (the one with tool calls that\n // triggered this invocation) \u2014 it has unresolved tool calls that would confuse\n // the sub-agent into thinking it needs to handle tools it doesn't own.\n const lastMsg = this.history[this.history.length - 1];\n const baseHistory =\n lastMsg?.role === 'assistant' && lastMsg.toolCalls?.length\n ? this.history.slice(0, -1)\n : this.history;\n\n const snapshotHistory =\n historyCap != null ? applyHistoryCap(baseHistory, historyCap) : [...baseHistory];\n\n const contextMessages: ChatMessage[] = context\n ? [{ role: 'user', content: `[Sub-agent context]: ${JSON.stringify(context)}` }]\n : [];\n\n const effectivePrimer: ChatMessage[] = [\n ...snapshotHistory,\n ...contextMessages,\n ...(subConfig.primerHistory ?? []),\n ];\n\n // Unique per-invocation id \u2014 reused for the lifecycle event bracket below \u2014\n // and a child session key derived from it. The child files its meta events\n // under this own bucket (rather than the shared empty-key sink), so they can\n // be harvested into THIS session on completion and then discarded.\n const invocationId = crypto.randomUUID();\n const childSessionKey = `${this.sessionKey}::sub:${invocationId}`;\n const child = new ChatDriver(this.providerRegistry, {\n sessionKey: childSessionKey,\n // Inherit the parent's bus so the sub-agent's tool-loop events still surface\n // (off-browser this is the shared no-op).\n activityBus: this.activityBus,\n });\n // Mark before the first turn so the child forces tool use and reports a\n // typed failure (rather than user-facing text) if it never completes.\n child.markAsSubAgent();\n // Propagate disposal: if this (parent) driver is torn down while the\n // sub-agent is mid-flight, dispose the child too so its in-flight request\n // aborts. Detached in the `finally` below once the sub-agent completes.\n const disposeChild = () => child.dispose();\n if (this.lifecycleController.signal.aborted) {\n disposeChild();\n } else {\n this.lifecycleController.signal.addEventListener('abort', disposeChild, { once: true });\n }\n child.applyAgent({ ...subConfig, primerHistory: effectivePrimer });\n // Route interactions back through this driver so widgets render in the\n // parent's (ultimately the root's) history and resolve via the same\n // pending map the main UI is wired to. Recurses naturally for nested\n // sub-agents.\n child.setHostInteractionRequester(\n <R>(componentName: string, data: any, opts?: InteractionRequestOptions): Promise<R> =>\n this.requestInteraction<R>(componentName, data, opts),\n );\n\n const forwardTrace = (e: Event) => {\n this.dispatchEvent(\n new CustomEvent('sub-agent-history-updated', {\n detail: { agentName: subConfig.name, history: (e as CustomEvent<ChatMessage[]>).detail },\n }),\n );\n };\n // Re-dispatch the child's `provider-changed` so the UI reflects whichever\n // provider is *actually* running right now (the sub-agent may use a\n // different provider than the parent). Restoration of the parent's\n // provider on `sub-agent-stop` is handled by the listener in main.ts.\n const forwardProviderChanged = (e: Event) => {\n this.dispatchEvent(\n new CustomEvent('provider-changed', { detail: (e as CustomEvent).detail }),\n );\n };\n child.addEventListener('history-updated', forwardTrace);\n child.addEventListener('provider-changed', forwardProviderChanged);\n\n const chatInputDuringExecution = options?.chatInputDuringExecution;\n const lifecycleDetail = { name, invocationId, chatInputDuringExecution };\n\n this.dispatchEvent(new CustomEvent('sub-agent-start', { detail: lifecycleDetail }));\n // Bracket the run on the timeline (mirrors turn.start/turn.end). Recorded\n // under THIS (parent) session \u2014 like subagent.completed/failed below \u2014 so the\n // sub-agent's span is visible on the user-facing timeline, not the child's.\n recordMetaEvent(this.sessionKey, 'subagent.started', { agent: name });\n let timedOut = false;\n const runPromise = child.sendMessage(task ?? '');\n try {\n if (timeoutMs == null) {\n await runPromise;\n } else {\n // Race the run against the deadline. On timeout, abort the child (which\n // cancels its in-flight provider request) and let the aborted run settle\n // before we tear down and return the timeout outcome.\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n try {\n const timeoutSignal = new Promise<'timeout'>((resolveTimeout) => {\n timeoutHandle = setTimeout(() => resolveTimeout('timeout'), timeoutMs);\n });\n const winner = await Promise.race([\n runPromise.then(() => 'done' as const),\n timeoutSignal,\n ]);\n if (winner === 'timeout') {\n timedOut = true;\n child.dispose();\n // The sub-agent may be parked awaiting a user interaction, which is\n // routed up to this driver and parked in *this* pending map (widgets\n // resolve on the host, not the child). Disposing the child does not\n // settle that promise, so the child stays suspended \u2014 cancel the\n // interaction to close the widget and unblock the child. Without this,\n // `await runPromise` below would hang forever and the timeout would\n // never complete (or record `subagent.failed`).\n this.cancelPendingInteractions(`Sub-agent \"${name}\" timed out after ${timeoutMs}ms.`);\n await runPromise.catch(() => undefined);\n }\n } finally {\n // Always clear the timer \u2014 even if the race rejects \u2014 so it never leaks.\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n }\n } finally {\n this.lifecycleController.signal.removeEventListener('abort', disposeChild);\n child.removeEventListener('history-updated', forwardTrace);\n child.removeEventListener('provider-changed', forwardProviderChanged);\n // Tear the child down on every exit path, not just timeout/parent-abort.\n // A child that completes normally is otherwise never disposed, so its\n // provider-registry subscription (wired in the ChatDriver constructor)\n // would leak \u2014 the long-lived registry would retain every completed\n // sub-agent driver. dispose() is idempotent and only aborts the (already\n // settled) lifecycle, so the snapshot/completion reads below still work.\n child.dispose();\n this.dispatchEvent(new CustomEvent('sub-agent-stop', { detail: lifecycleDetail }));\n // Capture the child's diagnostics into THIS session, then ALWAYS discard its\n // transient bucket \u2014 done in the `finally` so an unexpected `sendMessage`\n // rejection (which propagates out of this method) can't orphan the bucket in\n // the registry, and a crashed sub-agent still leaves its turns/events behind.\n // Forward the child's per-LLM-call snapshots so they show as `kind:'turn'`\n // entries in the exported debug log, re-numbered under the activating parent turn.\n this.forwardSubAgentSnapshots(child.getTurnSnapshots());\n // Fold the sub-agent's high-value meta events (retries/errors/tool failures \u2014\n // see HARVESTED_SUBAGENT_EVENTS) into THIS session, preserving their original\n // timestamps so they interleave within the subagent.started\u2192completed/failed\n // bracket. Each is breadcrumbed `\"<parent> \u203A <sub-agent>\"`, composing for a\n // nested sub-agent whose own breadcrumb the child already merged.\n const parentName = this.activeAgentName ?? '?';\n const harvested = getMetaEvents(childSessionKey)\n .filter((e) => HARVESTED_SUBAGENT_EVENTS.has(e.type))\n .map((e) => {\n const existing = e.detail?.subAgent as string | undefined;\n return { ...e, detail: { ...e.detail, subAgent: `${parentName} \u203A ${existing ?? name}` } };\n });\n mergeMetaEvents(this.sessionKey, harvested);\n clearSession(childSessionKey);\n }\n\n const trace = child.getHistory() as ChatMessage[];\n\n if (timedOut) {\n // Same failure shape as any other non-completion \u2014 the parent handler\n // recovers on its existing `{ ok: false }` branch. Recorded under THIS\n // (parent) session so it lands on the user-visible debug-log timeline.\n recordMetaEvent(this.sessionKey, 'subagent.failed', { agent: name, reason: 'timeout' });\n return { outcome: { ok: false, reason: 'timeout' }, trace };\n }\n\n const completion = child.getSubAgentCompletion();\n\n if (completion) {\n recordMetaEvent(this.sessionKey, 'subagent.completed', { agent: name });\n return { outcome: { ok: true, result: completion.result as T }, trace };\n }\n\n // No completion \u2192 the sub-agent's loop ended without calling its completion\n // tool. Surface the typed reason it recorded; default to 'max_iterations'\n // for the defensive case where the loop ended with no reason set (e.g. a\n // provider ignored forced tool use and returned text). The previous\n // final-text fallback is intentionally gone \u2014 sub-agents return a\n // structured outcome only, and the parent handler decides how to recover.\n const failure = child.getSubAgentFailure();\n const reason = failure?.reason ?? 'max_iterations';\n // Record under THIS (parent) driver's session so the failure lands on the\n // user-visible debug-log timeline \u2014 the child ran under its own session key.\n // This is also the only telemetry for the defensive default above, where the\n // child's loop ended without recording an explicit failure reason.\n recordMetaEvent(this.sessionKey, 'subagent.failed', { agent: name, reason });\n // A child that hit the budget wall walls this driver too \u2014 the cap is shared,\n // and the parent's very next model call would 402 as well. Flagged (not\n // thrown) because the handler's return value is still appended as a tool\n // result: the loop reads the flag before the next provider call and ends the\n // turn there, which is what makes the `'budget_exhausted'` doc's \"terminal\n // for the parent too\" actually true.\n //\n // The child's attribution is inherited with it: the vendor that refused is\n // the child's, which under a mixed registry is not this driver's. See\n // `budgetWallDetail` for what mis-attributing it costs.\n //\n // FIRST attribution wins (`??=`). With batched delegations, child A walling\n // WITH attribution can be followed by child B walling WITHOUT one (a\n // figure-less 402 behind a transport label no vendor claims); a plain\n // assignment reset the field to `undefined` and the short-circuit's\n // fallback then named the parent's own vendor \u2014 the one known NOT to have\n // refused.\n if (reason === 'budget_exhausted') {\n this.budgetExhaustedThisTurn = true;\n this.budgetWallViaSubAgent = true;\n this.budgetWallDetail ??= failure?.budget;\n }\n return { outcome: { ok: false, reason }, trace };\n }\n\n /**\n * Continue the tool loop from current history without appending a new user message.\n * Used by OrchestratingDriver after an agent handoff.\n */\n async continueFromHistory(transientPrimer?: ChatMessage[]): Promise<ChatDriverResult> {\n if (this.busy) return { reason: 'done' };\n\n this.busy = true;\n this.beginTurn();\n this.subAgentCompletion = undefined;\n this.subAgentFailure = undefined;\n this.budgetExhaustedThisTurn = false;\n this.budgetWallDetail = undefined;\n this.budgetWallViaSubAgent = false;\n this.turnStartedAt = Date.now();\n recordMetaEvent(this.sessionKey, 'turn.start', {\n phase: 'continueFromHistory',\n agent: this.activeAgentName,\n });\n this.activityBus.publish('tool-loop-start', undefined);\n // Captured so the `finally` can carry the turn's outcome onto `tool-loop-end`.\n let result: ChatDriverResult = { reason: 'done' };\n try {\n result = await this.runToolLoop('', undefined, transientPrimer);\n return result;\n } catch (e) {\n logger.error('ChatDriver error:', e);\n recordTurnError(this.sessionKey, 'exception', {\n phase: 'continueFromHistory',\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n name: e instanceof Error ? e.name : undefined,\n message: e instanceof Error ? e.message : String(e),\n });\n this.appendToHistory({\n role: 'assistant',\n content: 'Sorry, something went wrong on my end. Please try again in a moment.',\n });\n result = this.turnDone('exception');\n return result;\n } finally {\n recordMetaEvent(this.sessionKey, 'turn.end', {\n phase: 'continueFromHistory',\n agent: this.activeAgentName,\n durationMs: Date.now() - this.turnStartedAt,\n });\n this.busy = false;\n this.endTurn();\n this.activityBus.publish('tool-loop-end', this.loopEndDetail(result));\n }\n }\n\n // ---------------------------------------------------------------------------\n // Fold mechanics\n // ---------------------------------------------------------------------------\n\n /** Extract ToolFold metadata from a handler, or undefined if it isn't a fold facade. */\n private getFold(toolName: string): ToolFold | undefined {\n const handler = this.toolHandlers[toolName];\n return handler ? ((handler as any)[TOOL_FOLD_SYMBOL] as ToolFold | undefined) : undefined;\n }\n\n /**\n * Search all currently registered fold facades (and their nested folds recursively)\n * to find which fold contains a given tool name. Returns the immediate parent fold name.\n */\n private findFoldContaining(toolName: string, handlers?: ChatToolHandlers): string | null {\n const source = handlers ?? this.toolHandlers;\n for (const [, handler] of Object.entries(source)) {\n const fold = (handler as any)[TOOL_FOLD_SYMBOL] as ToolFold | undefined;\n if (!fold) continue;\n // Direct inner tool match\n if (fold.handlers[toolName]) return fold.name;\n // Recurse into nested folds\n const nested = this.findFoldContaining(toolName, fold.handlers);\n if (nested) return fold.name;\n }\n return null;\n }\n\n /**\n * If an open fold is hiding a previously-available tool, return the name of\n * the fold to close to start getting it back. Only exclusive folds hide tools\n * (they replace the tool set on open rather than extending it), so a base tool\n * that was visible before the fold opened now sits in a fold-stack frame's\n * `previousHandlers` but not in the live handler map. Only the top fold's\n * `close_` tool is active, so that's always the actionable next step \u2014 even\n * when the tool lives further down the stack, closing repeatedly walks back to\n * it. Returns null when no open fold accounts for the tool.\n */\n private foldHidingTool(toolName: string): string | null {\n if (this.foldStack.length === 0) return null;\n const hidden = this.foldStack.some((f) => f.previousHandlers[toolName]);\n return hidden ? this.foldStack[this.foldStack.length - 1].foldName : null;\n }\n\n /**\n * Install the fold's inner tool set, replacing (exclusive) or extending (non-exclusive)\n * the current tool set. Also injects the close tool. Does NOT touch the fold stack.\n */\n private applyFoldToolSet(fold: ToolFold, foldName: string): void {\n const closeToolName = `close_${foldName}`;\n const newDefs: ChatToolDefinition[] = [];\n const newHandlers: ChatToolHandlers = {};\n\n if (!fold.exclusive) {\n // Non-exclusive: keep existing tools minus the facade we just opened\n for (const def of this.toolDefinitions) {\n if (def.name !== foldName) newDefs.push(def);\n }\n for (const [name, handler] of Object.entries(this.toolHandlers)) {\n if (name !== foldName) newHandlers[name] = handler;\n }\n }\n\n // Install inner tools from fold metadata\n newDefs.push(...fold.tools);\n Object.assign(newHandlers, fold.handlers);\n\n // Inject the close tool\n newDefs.push({\n name: closeToolName,\n description: `Close the ${foldName} fold and return to the previous set of tools.`,\n parameters: { type: 'object', properties: {} },\n });\n newHandlers[closeToolName] = async (): Promise<string> => this.closeFold();\n\n this.toolDefinitions = newDefs;\n this.toolHandlers = newHandlers;\n }\n\n /** Open a fold: push a stack frame, swap the tool set, return the response message. */\n private openFold(\n foldName: string,\n fold: ToolFold,\n args: Record<string, unknown>,\n activeToolCallId?: string,\n ): Promise<string> {\n // Shortcut dispatch: model passed inner tool args directly, e.g.\n // trading_tools({ search_trades: { side: \"BUY\" } })\n for (const key of Object.keys(args)) {\n const innerHandler = fold.handlers[key];\n if (innerHandler) {\n logger.debug(`ChatDriver: fold shortcut dispatch \"${foldName}\" \u2192 \"${key}\"`);\n // Open the fold first so the tool set is correct for subsequent calls\n this.pushFoldFrame(foldName);\n this.applyFoldToolSet(fold, foldName);\n this.consecutiveFoldOps = 0; // shortcut dispatch counts as real work\n const innerArgs =\n typeof args[key] === 'object' && args[key] !== null\n ? (args[key] as Record<string, unknown>)\n : {};\n return innerHandler(innerArgs, this.buildHandlerContext(activeToolCallId)).then((r) =>\n typeof r === 'string' ? r : JSON.stringify(r),\n );\n }\n }\n\n // Normal two-step open\n this.pushFoldFrame(foldName);\n this.applyFoldToolSet(fold, foldName);\n\n const innerToolNames = fold.tools.map((t) => t.name);\n const closeToolName = `close_${foldName}`;\n let message = `Fold opened: ${foldName}. Tools now available: ${[...innerToolNames, closeToolName].join(', ')}.`;\n if (fold.usageNotes) message += ` Notes: ${fold.usageNotes}`;\n message += ` Call ${closeToolName} when done to return to the previous tools.`;\n return Promise.resolve(message);\n }\n\n private pushFoldFrame(foldName: string): void {\n this.foldStack.push({\n foldName,\n previousDefinitions: [...this.toolDefinitions],\n previousHandlers: { ...this.toolHandlers },\n });\n }\n\n /** Close the top fold: pop the stack frame, restore the previous tool set. */\n private closeFold(): string {\n const frame = this.foldStack.pop();\n if (!frame) return 'No fold is currently open.';\n\n this.toolDefinitions = frame.previousDefinitions;\n this.toolHandlers = frame.previousHandlers;\n\n const toolNames = this.toolDefinitions.map((t) => t.name);\n return `Fold closed: ${frame.foldName}. Tools now available: ${toolNames.join(', ')}.`;\n }\n\n /** Build the fold-awareness suffix appended to the system prompt each LLM call. */\n private buildFoldSystemPromptSuffix(): string {\n // Collect fold facades from the current handler map\n const activeFolds: ToolFold[] = [];\n for (const handler of Object.values(this.toolHandlers)) {\n const fold = (handler as any)[TOOL_FOLD_SYMBOL] as ToolFold | undefined;\n if (fold) activeFolds.push(fold);\n }\n\n if (activeFolds.length === 0 && this.foldStack.length === 0) return '';\n\n const parts: string[] = ['\\n\\n--- Tool Folds ---'];\n parts.push(\n 'Some tools are grouped into folds. You may see tool calls in the conversation history for tools that are not currently available \u2014 they are inside a fold. To access them, invoke the fold tool first.',\n );\n\n if (this.foldStack.length > 0) {\n const current = this.foldStack[this.foldStack.length - 1];\n parts.push(\n `You are currently inside the \"${current.foldName}\" fold. Call close_${current.foldName} when you are done with these tools.`,\n );\n }\n\n for (const fold of activeFolds) {\n parts.push(`\u2022 ${fold.name}: ${fold.description}`);\n }\n\n return parts.join('\\n');\n }\n\n // ---------------------------------------------------------------------------\n // Tool loop\n // ---------------------------------------------------------------------------\n\n // oxlint-disable-next-line complexity\n private async runToolLoop(\n userInput: string,\n attachments?: ChatAttachment[],\n transientPrimer?: ChatMessage[],\n ): Promise<ChatDriverResult> {\n if (!this.systemPrompt) {\n logger.warn(\n 'ChatDriver: no systemPrompt set. The assistant will have no instructions \u2014 provide a systemPrompt via agents config or the foundation-ai-assistant property.',\n );\n }\n\n let currentInput = userInput;\n let currentAttachments: ChatAttachment[] | undefined = attachments;\n let iterations = 0;\n let malformedAttempts = 0;\n let emptyResponseAttempts = 0;\n // Bounded retries for transient throws while resolving the per-turn tool surface or\n // calling the provider. Without this, a single transient throw tears down the whole turn\n // and strands the agent's unflushed work behind an opaque error.\n let setupTransportAttempts = 0;\n // True only for the very first LLM call. Used to exclude the pending user message\n // from history (it is passed separately as currentInput). Must not be derived from\n // `iterations` because fold operations decrement iterations, which would incorrectly\n // re-trigger the slice on subsequent calls after a fold open/close.\n let firstLlmCall = !!currentInput;\n\n while (iterations < this.maxToolIterations) {\n iterations += 1;\n // Monotonic across the driver's life \u2014 the age clock. Unlike `iterations`,\n // it is NOT reset per turn and NOT decremented for folds, so `age` keeps\n // counting model-calls once a turn ends. (See the `modelCallSeq` field.)\n this.modelCallSeq += 1;\n\n // A cancel (or dispose) that landed while the previous iteration's tool\n // batch was running takes effect here \u2014 before issuing another LLM call.\n // An abort during the call itself is handled by the catch below.\n if (this.turnController.signal.aborted) {\n return this.completeAbortedTurn();\n }\n\n // A budget wall observed earlier this turn ends it HERE, before another\n // model call. Reachable only via a sub-agent (this driver's own 402\n // returns straight out of the catch below) \u2014 `invokeSubAgent` sets the\n // flag, its `{ ok: false, reason: 'budget_exhausted' }` outcome is\n // appended as a tool result, and without this the loop would call the\n // provider again into the same wall: N batched sub-agent calls otherwise\n // cost N doomed children AND a doomed parent call.\n //\n // Scoped strictly to the budget reason: every other SubAgentFailureReason\n // is something the parent can legitimately recover from, so those still\n // let the loop continue.\n if (this.budgetExhaustedThisTurn) {\n logger.error('ChatDriver: ending the turn \u2014 a sub-agent hit the AI budget wall');\n recordTurnError(this.sessionKey, 'budget-exhausted', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n // The CHILD's vendor when it knew one, and NOTHING otherwise. On this\n // path the wall is definitionally the child's, and on a mixed registry\n // `lastResolvedProvider` is this driver's own vendor \u2014 the one known\n // NOT to have refused. An unattributable child wall must degrade to\n // the vendor-agnostic block (which `latchBlockedFrom` handles\n // fail-safe), never to a vendor that is known to be wrong: naming the\n // parent's vendor here walled BOTH \u2014 the child's via its own\n // tool-loop-end, the parent's via this event \u2014 and derived `blocked`\n // over headroom that still existed.\n vendor: this.budgetWallDetail?.vendor,\n via: 'sub-agent',\n isSubAgent: this.isSubAgent,\n });\n if (this.isSubAgent) {\n this.failSubAgent('budget_exhausted', this.budgetWallDetail);\n } else {\n this.appendToHistory({ role: 'assistant', content: this.budgetExhaustedMessage });\n }\n // Carried onto the result so `loopEndDetail` publishes the refusing\n // vendor rather than falling through to `lastResolvedProvider`, and the\n // host's latch walls the vendor that actually ran out.\n return this.turnDone('budget-exhausted', this.budgetWallDetail);\n }\n\n const promptCtx: SystemPromptContext = {\n agentName: this.activeAgentName ?? '',\n history: this.history,\n turnIndex: iterations - 1,\n signal: this.turnController.signal,\n };\n\n // Re-resolve dynamic tool definitions before each LLM call. The static\n // case is a no-op (factory is undefined and `this.toolDefinitions` was\n // set by applyAgent). Folds operate on `this.toolDefinitions` and are\n // forbidden when a factory is set, so the array form is always valid.\n // Sequential await is required \u2014 each iteration must see fresh values\n // before constructing the LLM request.\n // A transient throw while building the tool surface should retry the iteration, not\n // tear down the whole turn and strand the agent's unflushed buffer behind an opaque\n // error. The handler-map factory re-resolves in lockstep so dispatch sees only the\n // handlers valid for the current state, in step with the tool definitions exposed\n // above. Folds are forbidden when either factory is set, so the fold-mutation paths\n // on `this.toolDefinitions` / `this.toolHandlers` are unreachable.\n try {\n if (this.toolDefinitionsFactory) {\n // oxlint-disable-next-line no-await-in-loop\n this.toolDefinitions = await this.toolDefinitionsFactory(promptCtx);\n }\n if (this.toolHandlersFactory) {\n // oxlint-disable-next-line no-await-in-loop\n this.toolHandlers = await this.toolHandlersFactory(promptCtx);\n }\n } catch (e) {\n setupTransportAttempts += 1;\n if (setupTransportAttempts < MAX_SETUP_TRANSPORT_RETRIES) {\n logger.warn(\n `ChatDriver: tool-surface resolution failed, retrying (${setupTransportAttempts}/${MAX_SETUP_TRANSPORT_RETRIES})`,\n );\n iterations -= 1;\n continue;\n }\n throw e;\n }\n\n // Record everything advertised this turn so the unknown-tool path can tell\n // a stale tool (real earlier, retired now) from a hallucinated one. Runs\n // for both the static and factory cases; folds also flow through here as\n // their inner tools become visible on the iteration after they open.\n for (const def of this.toolDefinitions) this.everSeenToolNames.add(def.name);\n\n const resolvedSystemPrompt =\n typeof this.systemPrompt === 'function'\n ? // oxlint-disable-next-line no-await-in-loop\n await this.systemPrompt(promptCtx)\n : this.systemPrompt;\n\n // Re-resolve the per-turn display label. Falls back to the canonical\n // agent name when displayName is unset. Stamped onto outgoing messages\n // and turn snapshots for UX only; routing/history-transform continues\n // to read `activeAgentName`.\n if (typeof this.displayName === 'function') {\n // oxlint-disable-next-line no-await-in-loop\n this.activeAgentLabel = await this.displayName(promptCtx);\n }\n\n // Volatile framework additions \u2014 the fold-surface suffix and the per-attempt malformed/empty\n // retry nudge \u2014 that would otherwise destabilize a cached system prompt. They are routed to\n // the framed tail (below), never appended to the system string, so the system prompt stays\n // byte-stable for every agent.\n const foldSuffix = this.buildFoldSystemPromptSuffix();\n const retryNudge =\n malformedAttempts > 0\n ? '\\n\\nIMPORTANT: Use only the structured function-call API to invoke tools. Do not write Python code or use Python-style syntax to call tools.'\n : emptyResponseAttempts > 0\n ? \"\\n\\nIMPORTANT: You must respond to the user's message. Call the appropriate tool or provide a text response \u2014 do not return an empty response.\"\n : '';\n const frameworkSystemSuffix = `${foldSuffix}${retryNudge}`;\n\n // Normalize the primer at the same chokepoint as the driver's own history\n // (GENC-1351 \u00A75.7): a parent's `compacted-summary` message rides into a\n // sub-agent's primer (`requestSubAgent` snapshots the parent's raw history),\n // and it must be translated to a `<conversation_summary>` user message here \u2014\n // otherwise the transports' role filter silently drops it and the sub-agent\n // loses all summarized context. `normalizeForProvider` only touches\n // `compacted-summary`, so it's a safe pass-through for everything else.\n const primer = normalizeForProvider([\n ...(this.primerHistory ?? []),\n ...(transientPrimer ?? []),\n ]);\n const baseHistory = firstLlmCall ? this.history.slice(0, -1) : this.history;\n firstLlmCall = false;\n // Collapse stale tool payloads this agent declared via `condenseWhen`\n // (GENC-1369), then translate any compacted-summary \u2192 a\n // <conversation_summary> user message (GENC-1351 \u00A75.7) before any per-agent\n // masking, so the raw display-only role can never reach a transport. Each\n // step runs on a copy \u2014 stored history is untouched.\n const condensedHistory = applyCondensation(\n [...baseHistory],\n this.condensePolicies,\n {\n modelCall: this.modelCallSeq,\n turn: this.turnSeq,\n // A call's activation has ended once a later activation is current \u2014 a\n // swap or release/complete both advance the counter.\n activationEnded: (activation) => activation < this.currentActivation,\n // A call's phase has ended once the app declared a later phase epoch\n // current via `endPhase()`.\n phaseEnded: (phaseEpoch) => phaseEpoch < this.currentPhaseEpoch,\n batchCalls: this.condenseBatchCalls,\n },\n (detail) => recordMetaEvent(this.sessionKey, 'context.condensed', detail),\n );\n const normalizedHistory = normalizeForProvider(condensedHistory);\n const historyForProvider = this.providerHistoryTransform\n ? this.providerHistoryTransform(normalizedHistory)\n : normalizedHistory;\n const historyForCall = [...primer, ...historyForProvider];\n\n // Resolve the per-turn temperature and tool-call mode the same way the\n // provider is resolved \u2014 static value or a function of the turn context\n // (which carries the live state for stateful agents). Resolved before the\n // snapshot so the debug log records the exact request config the model saw.\n const [\n resolvedTemperature,\n resolvedToolChoice,\n resolvedCachePolicy,\n resolvedTailContext,\n resolvedResponseSchema,\n ] =\n // oxlint-disable-next-line no-await-in-loop\n await Promise.all([\n this.resolveTurnInput<number>(this.activeTemperatureInput, promptCtx),\n this.resolveTurnInput<ChatToolChoice>(this.activeToolChoiceInput, promptCtx),\n this.resolveTurnInput<CachePolicy>(this.activeCachePolicyInput, promptCtx),\n this.resolveTurnInput<string>(this.activeTailContextInput, promptCtx),\n this.resolveTurnInput<object | undefined>(this.activeResponseSchemaInput, promptCtx),\n ]);\n // The system prompt is always just the agent's resolved prompt \u2014 byte-stable, so it can be\n // cached. The framework's volatile additions (fold suffix, retry nudge) and the agent's tail\n // context all go to the framed tail: one uniform channel, no cache-scope branch. On a normal\n // turn `frameworkSystemSuffix` is empty, so the tail is empty too \u2014 a no-op. The framework\n // owns the framing; the corrective retry nudge lands last (recency).\n const systemPrompt = resolvedSystemPrompt || undefined;\n const tailBody = [resolvedTailContext, frameworkSystemSuffix]\n .map((part) => (part ?? '').trim())\n .filter((part) => part.length > 0)\n .join('\\n\\n');\n const tailContext = tailBody\n ? `<system-reminder>\\n${tailBody}\\n</system-reminder>`\n : undefined;\n // An agent/state-configured tool-call mode wins. Otherwise sub-agents must\n // finish by calling a tool (their completion tool) so the turn can't end\n // on a free-text answer; top-level agents stay 'auto'. (Transports no-op a\n // force when no tools are advertised.)\n const effectiveToolChoice = resolvedToolChoice ?? (this.isSubAgent ? 'required' : undefined);\n\n this.recordTurnSnapshot(systemPrompt, resolvedTemperature, effectiveToolChoice, tailContext);\n\n // Capture the pending user input, then clear the slots BEFORE the chat\n // call. `sendMessage` already appended the user message to `this.history`,\n // so on retries (empty / malformed) we must rely on history alone \u2014\n // otherwise the message gets sent twice (once via history, once via\n // `currentInput`), which Gemini answers with an empty response and then\n // we retry forever.\n const userInputForCall = currentInput;\n const attachmentsForCall = currentAttachments;\n currentInput = '';\n currentAttachments = undefined;\n\n const options: ChatRequestOptions = {\n systemPrompt,\n // Strip fold-only properties (foldEvent, foldPath) before sending to provider\n tools: this.toolDefinitions.length ? this.toolDefinitions : undefined,\n attachments: attachmentsForCall,\n // Per-turn signal: aborts on user cancel, and (via beginTurn's chain)\n // on driver dispose. Cancels the in-flight request either way.\n signal: this.turnController.signal,\n toolChoice: effectiveToolChoice,\n // Agent/state-configured sampling temperature (normalized 0\u20131); each\n // transport translates it to its native range. Undefined \u2192 provider default.\n temperature: resolvedTemperature,\n // Prompt-cache policy for this turn (Anthropic places breakpoints per scope; Gemini\n // caches implicitly regardless). Undefined \u2192 no caching requested.\n cachePolicy: resolvedCachePolicy,\n // Framed volatile context injected at the message tail (never stored). Undefined \u2192 none.\n tailContext,\n // Structured-output schema for this turn (agent/state-resolved). When set, the transport\n // constrains the final answer to it natively where the model supports it. Undefined \u2192 free text.\n responseSchema: resolvedResponseSchema,\n // Refusal-fallback chain (e.g. Fable 5 \u2192 Opus 4.8). Passed to the provider; applied\n // server-side where supported. Undefined \u2192 no fallback.\n fallbacks: this.activeFallbacks,\n };\n\n // Resolve the active provider for this turn. Static names were validated\n // in `applyAgent`; function-form names are validated on first resolution\n // here and cached for the agent's lifetime.\n // oxlint-disable-next-line no-await-in-loop\n const activeProvider = await this.resolveProviderForTurn(promptCtx);\n\n let response: ChatMessage;\n try {\n // oxlint-disable-next-line no-await-in-loop\n response = await activeProvider.chat!(historyForCall, userInputForCall, options);\n } catch (e) {\n if (e instanceof MalformedFunctionCallError) {\n malformedAttempts += 1;\n if (malformedAttempts < MAX_MALFORMED_RETRIES) {\n logger.warn(\n `ChatDriver: MALFORMED_FUNCTION_CALL, retrying (${malformedAttempts}/${MAX_MALFORMED_RETRIES})`,\n );\n recordTurnRetry(this.sessionKey, 'malformed-function-call', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n attempt: malformedAttempts,\n maxAttempts: MAX_MALFORMED_RETRIES,\n finishMessage: e.finishMessage,\n });\n iterations -= 1;\n continue;\n }\n logger.error('ChatDriver: MALFORMED_FUNCTION_CALL, max retries reached');\n recordTurnError(this.sessionKey, 'malformed-function-call', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n attempts: malformedAttempts,\n finishMessage: e.finishMessage,\n isSubAgent: this.isSubAgent,\n });\n if (this.isSubAgent) {\n // Bubble a typed failure to the parent instead of speaking to the user.\n this.failSubAgent('malformed_tool_call');\n } else {\n this.appendToHistory({\n role: 'assistant',\n content:\n 'While working on your request, I repeatedly called my tools incorrectly. This often works on a second try \u2014 would you like me to try again? If it happens again, try breaking your request into smaller steps.',\n });\n }\n return this.turnDone('malformed-function-call');\n }\n // The response was truncated at the provider's output-token cap while it\n // still carried a tool call \u2014 its arguments are incomplete and unusable.\n // Unlike a malformed call this is DETERMINISTIC: re-issuing the same\n // request hits the same cap, so a silent retry just loops. Bail with a\n // clear, actionable signal instead. The remedy is config (raise the\n // provider maxTokens) or a smaller step \u2014 neither is fixed by retrying.\n if (e instanceof ResponseTruncatedError) {\n logger.error('ChatDriver: response truncated at the output-token cap', e);\n recordTurnError(this.sessionKey, 'response-truncated', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n model: e.model,\n maxTokens: e.maxTokens,\n outputTokens: e.outputTokens,\n tools: e.toolNames,\n isSubAgent: this.isSubAgent,\n });\n if (this.isSubAgent) {\n // Bubble a typed failure to the parent instead of speaking to the user.\n this.failSubAgent('response_truncated');\n } else {\n this.appendToHistory({\n role: 'assistant',\n content:\n 'My response was cut off because a single step reached the model output limit. This usually means one step tried to produce too much at once \u2014 try breaking your request into smaller steps.',\n });\n }\n return this.turnDone('response-truncated');\n }\n // The AI-spend budget is gone and the proxy refused the request (HTTP\n // 402). Terminal in the strongest sense available to us: unlike a\n // truncation \u2014 which a smaller request would get past \u2014 *no* request\n // succeeds until someone raises the budget out of band. So there is no\n // retry here and no \"try again\" in the copy; the turn ends and the host\n // locks the composer off the `'budget-exhausted'` failure reason (see\n // `FoundationAiAssistant.blocked`).\n if (e instanceof BudgetExhaustedError) {\n // Flagged as well as returned: a sub-agent's wall reaches the PARENT\n // only as a tool result, and the parent must not issue another model\n // call after it (see the short-circuit at the top of this loop).\n this.budgetExhaustedThisTurn = true;\n this.budgetWallDetail = budgetDetailOf(e);\n // Paired with the detail everywhere it is written: this is the\n // driver's OWN wall, so the sub-agent marker must not survive from an\n // earlier child and suppress the `lastResolvedProvider` fallback that\n // is legitimate here. Unreachable today (the short-circuit fires\n // before a second wall can land in one turn) \u2014 kept structural so the\n // pairing does not depend on that ordering staying true.\n this.budgetWallViaSubAgent = false;\n if (this.isSubAgent) {\n logger.error('ChatDriver: AI budget exhausted', e);\n recordTurnError(this.sessionKey, 'budget-exhausted', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n vendor:\n vendorTypeOfLabel(e.vendorLabel) ??\n vendorTypeOfLabel(e.serverVendor) ??\n this.lastResolvedProvider,\n budgetUsd: e.budgetUsd,\n spentUsd: e.spentUsd,\n isSubAgent: true,\n });\n // Bubble a typed failure to the parent instead of speaking to the\n // user, carrying the attribution so the parent walls the vendor that\n // actually refused rather than its own.\n this.failSubAgent('budget_exhausted', this.budgetWallDetail);\n return this.turnDone('budget-exhausted', this.budgetWallDetail);\n }\n return this.reportBudgetExhausted(e);\n }\n // A request timeout from the transport (tagged `TimeoutError`) is not a\n // bug on our end \u2014 surface it distinctly instead of letting it fall\n // through to the generic \"something went wrong\" catch. No auto-retry:\n // the timeout ceiling is already minutes long, so a silent retry would\n // just make the user wait again.\n if (e instanceof DOMException && e.name === 'TimeoutError') {\n logger.error('ChatDriver: request timed out', e);\n recordTurnError(this.sessionKey, 'exception', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n name: e.name,\n message: e.message,\n isSubAgent: this.isSubAgent,\n });\n if (this.isSubAgent) {\n // Bubble a typed failure to the parent instead of speaking to the user.\n this.failSubAgent('timeout');\n } else {\n this.appendToHistory({\n role: 'assistant',\n content:\n 'The request timed out. You can ask me to try again, or break this into a smaller step.',\n });\n }\n // Recorded as `exception` above (there is no separate `timeout` member of\n // TurnFailureReason for the main turn); surface the same reason here.\n return this.turnDone('exception');\n }\n // The request was aborted: either a user cancel (turnController) or a\n // driver dispose (lifecycleController, chained into the turn). A user\n // cancel adds a \"Stopped.\" marker; a dispose stops quietly. Handled\n // before the transient-retry below so an intentional abort/timeout is\n // never retried.\n if (e instanceof DOMException && e.name === 'AbortError') {\n return this.completeAbortedTurn();\n }\n // A transient provider/transport error should retry the SAME iteration a bounded\n // number of times rather than tearing down the whole turn (which strands the\n // agent's unflushed buffer behind an opaque error message).\n setupTransportAttempts += 1;\n if (setupTransportAttempts < MAX_SETUP_TRANSPORT_RETRIES) {\n logger.warn(\n `ChatDriver: provider/transport error, retrying (${setupTransportAttempts}/${MAX_SETUP_TRANSPORT_RETRIES})`,\n );\n iterations -= 1;\n continue;\n }\n throw e;\n }\n\n // Attribute the response to the concrete model + registry slot that\n // produced it (resolved for this turn in `resolveProviderForTurn`). Carried\n // on the assistant message so the debug-log timeline shows per-message\n // model lineage \u2014 and thus per-tool-call, since tool calls ride on the\n // assistant message that requests them. Harmless on a response later\n // discarded as empty/retried; only kept copies reach history.\n //\n // Attach each key only when resolved: a provider with no `getStatus` (etc.)\n // leaves the key off entirely rather than carrying it as `undefined`.\n // JSON.stringify already drops undefined from the exported log, so this is\n // chiefly about keeping the in-memory message shape honest.\n if (this.lastResolvedModel !== undefined) response.model = this.lastResolvedModel;\n if (this.lastResolvedProvider !== undefined) response.provider = this.lastResolvedProvider;\n if (this.lastResolvedProviderName !== undefined) {\n response.providerName = this.lastResolvedProviderName;\n }\n\n const isThinkingStep = response.content && response.toolCalls?.length;\n const isEmptyResponse = !response.content?.trim() && !response.toolCalls?.length;\n // A pre-output refusal (safety-classifier decline, e.g. Fable 5 `stop_reason: 'refusal'`)\n // comes back with empty content, so it looks like a blank response \u2014 but it is deterministic:\n // retrying re-sends the identical request and refuses again, burning up to\n // MAX_EMPTY_RESPONSE_RETRIES turns on the most expensive models for the same outcome, ending\n // in the misleading \"blank response\" message. Treat it as a terminal, non-retried failure with\n // its own reason and message. (GENC-1461)\n const isRefusal = response.responseMeta?.finishReason === 'refusal';\n\n if (isEmptyResponse) {\n emptyResponseAttempts += 1;\n if (!isRefusal && emptyResponseAttempts < MAX_EMPTY_RESPONSE_RETRIES) {\n logger.warn(\n `ChatDriver: empty model response, retrying (${emptyResponseAttempts}/${MAX_EMPTY_RESPONSE_RETRIES})`,\n );\n recordTurnRetry(this.sessionKey, 'empty-response', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n attempt: emptyResponseAttempts,\n maxAttempts: MAX_EMPTY_RESPONSE_RETRIES,\n // Provider diagnostic (Gemini: finishReason, thoughtsTokens, parts,\n // blockReason) so the timeline shows *why* the turn came back blank \u2014\n // e.g. a high thoughtsTokens with a 'STOP' finish is \"thought, then\n // stopped without answering\".\n ...response.responseMeta,\n });\n iterations -= 1;\n continue;\n }\n const failureReason = isRefusal ? 'refusal' : 'empty-response';\n logger.error(\n isRefusal\n ? 'ChatDriver: model refused the request (safety decline) \u2014 not retrying'\n : 'ChatDriver: empty model response after all retries',\n );\n recordTurnError(this.sessionKey, failureReason, {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n attempts: emptyResponseAttempts,\n isSubAgent: this.isSubAgent,\n ...response.responseMeta,\n });\n if (this.isSubAgent) {\n this.failSubAgent(isRefusal ? 'refusal' : 'empty_response');\n } else {\n this.appendToHistory({\n role: 'assistant',\n content: isRefusal\n ? 'This request was declined. Try rephrasing it, or breaking it into smaller steps.'\n : 'While working on your request, I repeatedly generated a blank response. This often works on a second try \u2014 would you like me to try again? If it happens again, try breaking your request into smaller steps.',\n });\n }\n return this.turnDone(failureReason);\n } else {\n // Split one model response into separate, individually-toggleable messages so each has its\n // own visibility toggle and debug-log category:\n // - reasoning (chain-of-thought summary) \u2192 category 'reasoning', hidden unless showThinkingSteps\n // - narration (interstitial prose emitted alongside a tool call) \u2192 category 'narration',\n // hidden unless showNarration\n // - the answer / tool-call message \u2192 always shown; carries this turn's usage.\n // Cost invariant (GENC-1410): exactly ONE message carries cost/tokens and is appended LAST, so\n // `sumCosts`/`sumTokens` don't double-count and `contextTokens` reads it. Reasoning/narration are\n // display-only (usage undefined) and are skipped when building the provider request. `model` /\n // `provider` / `providerName` stay on every split message so each is still attributed.\n const { reasoning, ...rest } = response;\n const displayOnly = { cost: undefined, inputTokens: undefined, outputTokens: undefined };\n if (reasoning) {\n this.appendToHistory({\n ...rest,\n ...displayOnly,\n content: reasoning,\n toolCalls: undefined,\n category: 'reasoning',\n });\n }\n if (isThinkingStep) {\n // content + tool call \u2192 the content is interstitial narration, not the final answer.\n this.appendToHistory({\n ...rest,\n ...displayOnly,\n toolCalls: undefined,\n category: 'narration',\n });\n this.appendToHistory({ ...rest, content: '' });\n } else {\n // No tool call \u2192 `content` is the final answer (always shown), or this is a bare tool-call\n // turn with no narration. Either way it carries this turn's usage; append it last.\n this.appendToHistory(rest);\n }\n }\n\n // Reset retry budgets on any productive (non-empty) response, so the caps mean\n // \"N CONSECUTIVE failures\" not \"N total per turn\".\n emptyResponseAttempts = 0;\n malformedAttempts = 0;\n setupTransportAttempts = 0;\n\n if (!response.toolCalls?.length) {\n break;\n }\n\n const [toolCalls, systemCalls] = response.toolCalls.reduce<[ChatToolCall[], ChatToolCall[]]>(\n (acc, tc) => {\n if (tc.name === REQUEST_CONTINUATION_TOOL) acc[1].push(tc);\n else acc[0].push(tc);\n return acc;\n },\n [[], []],\n );\n\n const executedById = new Map<\n string,\n { toolCallId: string; content: string; subAgentTrace?: ChatMessage[] }\n >();\n const unknownToolIds = new Set<string>();\n // Subset of unknownToolIds that were stale (previously available) rather\n // than hallucinated \u2014 drives the `stale` UI flag back-patched below.\n const staleToolIds = new Set<string>();\n let anyRealToolExecuted = false;\n let hitUnknownToolLimit = false;\n\n if (toolCalls.length > 0) {\n // oxlint-disable-next-line no-await-in-loop -- Promise.all is correct parallelism, not sequential loop awaiting\n await Promise.all(\n toolCalls.map(async (tc) => {\n // Check for fold facade\n const fold = this.getFold(tc.name);\n if (fold) {\n this.consecutiveFoldOps += 1;\n if (this.consecutiveFoldOps > this.maxFoldOperations) {\n logger.warn(\n `ChatDriver: fold operation limit (${this.maxFoldOperations}) reached \u2014 injecting guidance`,\n );\n executedById.set(tc.id, {\n toolCallId: tc.id,\n content: `You have opened and closed folds ${this.consecutiveFoldOps} times without calling any tools. Please call a specific tool to make progress, or respond to the user.`,\n });\n return;\n }\n const content = await this.openFold(tc.name, fold, tc.args, tc.id);\n executedById.set(tc.id, { toolCallId: tc.id, content });\n // Fold open/close does NOT count as a real iteration \u2014 decrement to compensate\n iterations -= 1;\n return;\n }\n\n // Check for close-fold tool\n if (tc.name.startsWith('close_') && this.foldStack.length > 0) {\n const topFoldName = this.foldStack[this.foldStack.length - 1].foldName;\n if (tc.name === `close_${topFoldName}`) {\n this.consecutiveFoldOps += 1;\n if (this.consecutiveFoldOps > this.maxFoldOperations) {\n executedById.set(tc.id, {\n toolCallId: tc.id,\n content: `You have opened and closed folds ${this.consecutiveFoldOps} times without calling any tools. Please call a specific tool to make progress, or respond to the user.`,\n });\n return;\n }\n const content = this.closeFold();\n executedById.set(tc.id, { toolCallId: tc.id, content });\n iterations -= 1;\n return;\n }\n }\n\n // Regular tool \u2014 check if it's inside a fold and guide the model\n const handler = this.toolHandlers[tc.name];\n if (!handler) {\n const containingFold = this.findFoldContaining(tc.name);\n if (containingFold) {\n logger.debug(\n `ChatDriver: model called folded tool \"${tc.name}\" \u2014 guiding to open \"${containingFold}\"`,\n );\n recordMetaEvent(this.sessionKey, 'tool.unresolved', {\n tool: tc.name,\n agent: this.activeAgentName,\n kind: 'folded',\n fold: containingFold,\n });\n executedById.set(tc.id, {\n toolCallId: tc.id,\n content: `\"${tc.name}\" is not directly available. It is inside the \"${containingFold}\" fold. Call ${containingFold} first to access it.`,\n });\n // Guidance does not count as a real iteration or fold op\n iterations -= 1;\n return;\n }\n\n // Not in any registered fold. If the tool was advertised earlier\n // in this agent's lifetime it's *stale* (a stateful agent moved on,\n // or an exclusive fold is hiding it) rather than hallucinated \u2014 a\n // distinction worth making, because the model should stop retrying\n // a retired tool rather than treat the failure as a typo. Stale\n // calls still trip loop protection, but at a higher ceiling than\n // hallucinated tools (see below) \u2014 they are self-correcting, so the\n // guidance, telemetry, and limit differ.\n if (this.everSeenToolNames.has(tc.name)) {\n this.consecutiveUnknownToolCalls += 1;\n const hidingFold = this.foldHidingTool(tc.name);\n let content: string;\n if (hidingFold) {\n content = `\"${tc.name}\" is not available while the \"${hidingFold}\" fold is open. Call close_${hidingFold} to return to the previous set of tools, then call ${tc.name}.`;\n logger.warn(\n `ChatDriver: tool \"${tc.name}\" is hidden behind open fold \"${hidingFold}\" (${this.consecutiveUnknownToolCalls}/${MAX_STALE_TOOL_CALLS})`,\n );\n } else {\n content = `\"${tc.name}\" was available earlier but is not part of the current step \u2014 that step is complete, so do not call it again. Continue with the tools available now: ${Object.keys(this.toolHandlers).join(', ') || '(none)'}.`;\n logger.warn(\n `ChatDriver: stale tool \"${tc.name}\" \u2014 advertised earlier this activation but retired in the current state (${this.consecutiveUnknownToolCalls}/${MAX_STALE_TOOL_CALLS})`,\n );\n }\n recordMetaEvent(this.sessionKey, 'tool.unresolved', {\n tool: tc.name,\n agent: this.activeAgentName,\n kind: hidingFold ? 'fold-hidden' : 'stale',\n fold: hidingFold ?? undefined,\n consecutive: this.consecutiveUnknownToolCalls,\n max: MAX_STALE_TOOL_CALLS,\n });\n // Fold-hidden tools keep their fold-specific guidance; a plain\n // stale tool is a step-ordering miss, so offer the agent's\n // redirect when it supplies one.\n const staleContent = hidingFold\n ? content\n : await this.resolveUnresolvedToolContent(tc.name, 'stale', content);\n executedById.set(tc.id, { toolCallId: tc.id, content: staleContent });\n unknownToolIds.add(tc.id);\n staleToolIds.add(tc.id);\n this.recentUnknownToolNames.add(tc.name);\n this.recentStaleToolNames.add(tc.name);\n if (this.consecutiveUnknownToolCalls >= MAX_STALE_TOOL_CALLS) {\n hitUnknownToolLimit = true;\n }\n return;\n }\n\n // Never advertised \u2014 a hallucinated tool name.\n this.consecutiveUnknownToolCalls += 1;\n logger.warn(\n `ChatDriver: no handler registered for tool \"${tc.name}\" (${this.consecutiveUnknownToolCalls}/${DEFAULT_MAX_UNKNOWN_TOOL_CALLS}). Available tools: ${Object.keys(this.toolHandlers).join(', ') || '(none)'}`,\n );\n recordMetaEvent(this.sessionKey, 'tool.unresolved', {\n tool: tc.name,\n agent: this.activeAgentName,\n kind: 'unknown',\n consecutive: this.consecutiveUnknownToolCalls,\n max: DEFAULT_MAX_UNKNOWN_TOOL_CALLS,\n availableTools: Object.keys(this.toolHandlers),\n });\n const unknownContent = await this.resolveUnresolvedToolContent(\n tc.name,\n 'unknown',\n `Unknown tool: ${tc.name}`,\n );\n executedById.set(tc.id, { toolCallId: tc.id, content: unknownContent });\n unknownToolIds.add(tc.id);\n this.recentUnknownToolNames.add(tc.name);\n if (this.consecutiveUnknownToolCalls >= DEFAULT_MAX_UNKNOWN_TOOL_CALLS) {\n hitUnknownToolLimit = true;\n }\n return;\n }\n\n // Real tool execution\n try {\n const traceCapture: { trace?: ChatMessage[] } = {};\n const result = await handler(tc.args, this.buildHandlerContext(tc.id, traceCapture));\n const content = typeof result === 'string' ? result : JSON.stringify(result);\n executedById.set(tc.id, {\n toolCallId: tc.id,\n content,\n subAgentTrace: traceCapture.trace,\n });\n anyRealToolExecuted = true;\n } catch (e) {\n logger.error(`ChatDriver tool \"${tc.name}\" failed:`, e);\n recordMetaEvent(this.sessionKey, 'tool.failed', {\n tool: tc.name,\n agent: this.activeAgentName,\n message: e instanceof Error ? e.message : String(e),\n });\n executedById.set(tc.id, {\n toolCallId: tc.id,\n // Structured recovery hint so the model retries or routes around a tool\n // failure instead of apologising and giving up.\n content: `Tool error: ${(e as Error).message}\\nRECOVERY: this tool failed once \u2014 you may retry it, or take a different valid action to make progress. Do NOT abandon the task, ask the user to rephrase, or claim you cannot make changes. If a planning tool failed, retry it or proceed with the information you already have.`,\n });\n anyRealToolExecuted = true; // treat errors as real work for fold op counting\n }\n }),\n );\n }\n\n // Reset counters whenever a real tool executes\n if (anyRealToolExecuted) {\n this.consecutiveFoldOps = 0;\n this.consecutiveUnknownToolCalls = 0;\n this.recentUnknownToolNames.clear();\n this.recentStaleToolNames.clear();\n }\n\n // Tag tool calls with fold UI metadata before appending results\n const foldPath = this.foldStack.map((f) => f.foldName);\n\n for (const tc of response.toolCalls) {\n if (tc.name === REQUEST_CONTINUATION_TOOL) {\n this.appendToHistory({\n role: 'tool',\n content: '',\n toolResult: { toolCallId: tc.id, content: HANDOFF_TOOL_RESULT_PLACEHOLDER },\n });\n } else {\n const r = executedById.get(tc.id);\n if (r) {\n // Persist only `toolCallId`/`content` on the tool result \u2014 the sub-agent\n // trace lives on the tool *call* (back-patched below from `executedById`),\n // which is what the UI's trace panel and `sumCosts` read. Appending the\n // trace here too would duplicate the entire child conversation in history\n // (and the exported debug log) for no reader.\n this.appendToHistory({\n role: 'tool',\n content: '',\n toolResult: { toolCallId: r.toolCallId, content: r.content },\n });\n }\n }\n }\n\n // Back-patch foldEvent and foldPath onto the tool call message we just appended.\n // The response was appended before execution \u2014 find it and annotate.\n let tcMsgIdx = -1;\n for (let i = this.history.length - 1; i >= 0; i -= 1) {\n if (this.history[i].role === 'assistant' && this.history[i].toolCalls?.length) {\n tcMsgIdx = i;\n break;\n }\n }\n if (tcMsgIdx !== -1) {\n const tcMsg = this.history[tcMsgIdx];\n const availableToolNames = Object.keys(this.toolHandlers);\n const annotatedCalls = tcMsg.toolCalls!.map((tc) => {\n const isFoldOpen =\n !!this.getFold(tc.name) ||\n // Was a fold facade at time of the call (now the tool set has changed)\n // \u2014 detect by checking if the result message indicated a fold open\n executedById.get(tc.id)?.content?.startsWith('Fold opened:');\n const isFoldClose = executedById.get(tc.id)?.content?.startsWith('Fold closed:');\n const isUnknown = unknownToolIds.has(tc.id);\n return {\n ...tc,\n foldEvent: isFoldOpen\n ? ('open' as const)\n : isFoldClose\n ? ('close' as const)\n : undefined,\n // Use the fold path that was active at the START of this iteration (before any opens/closes)\n foldPath: !isFoldOpen && !isFoldClose && foldPath.length > 0 ? foldPath : undefined,\n unknown: isUnknown || undefined,\n availableTools: isUnknown ? availableToolNames : undefined,\n // Distinguish a retired tool from a hallucinated one so the UI can\n // say \"no longer available here\" rather than \"does not exist\".\n stale: staleToolIds.has(tc.id) || undefined,\n subAgentTrace: executedById.get(tc.id)?.subAgentTrace,\n };\n });\n this.history[tcMsgIdx] = { ...tcMsg, toolCalls: annotatedCalls };\n this.dispatchEvent(\n new CustomEvent<ReadonlyArray<ChatMessage>>('history-updated', {\n detail: this.history,\n }),\n );\n }\n\n if (hitUnknownToolLimit) {\n logger.error(\n `ChatDriver: unknown-tool limit (${DEFAULT_MAX_UNKNOWN_TOOL_CALLS}) reached \u2014 stopping`,\n );\n const unknownTools = [\n ...new Set([\n ...this.recentUnknownToolNames,\n ...(response.toolCalls ?? [])\n .filter((tc) => unknownToolIds.has(tc.id))\n .map((tc) => tc.name),\n ]),\n ];\n // Stale tools were real earlier this activation; hallucinated tools\n // never existed. The hard stop counts both the same way, but the split\n // tells a triager whether the cause is a state/prompt-design problem\n // (stale) or a model inventing tool names (hallucinated).\n const staleTools = [\n ...new Set([\n ...this.recentStaleToolNames,\n ...(response.toolCalls ?? [])\n .filter((tc) => staleToolIds.has(tc.id))\n .map((tc) => tc.name),\n ]),\n ];\n const hallucinatedTools = unknownTools.filter((t) => !staleTools.includes(t));\n recordTurnError(this.sessionKey, 'unknown-tool-limit', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n unknownTools,\n staleTools,\n hallucinatedTools,\n availableTools: Object.keys(this.toolHandlers),\n isSubAgent: this.isSubAgent,\n });\n if (this.isSubAgent) {\n this.failSubAgent('unknown_tool_limit');\n } else {\n this.appendToHistory({\n role: 'assistant',\n content:\n \"I'm sorry, I repeatedly tried to use tools that aren't available to me, so I couldn't complete that. If a 'Download agent log' option appears in the Settings (cog) menu, you can download the log and share it with whoever set up this assistant to help fix the issue.\",\n });\n }\n return this.turnDone('unknown-tool-limit');\n }\n\n const firstContinuation = systemCalls[0];\n if (firstContinuation) {\n const { summary, remaining_task: remainingTask } = firstContinuation.args as {\n summary: string;\n remaining_task: string;\n };\n return { reason: 'agent-handoff', summary, remainingTask };\n }\n\n // Sub-agent early exit \u2014 checked here so the exit point mirrors the\n // system-call pattern above. Set by completeSubAgent() in a tool handler.\n if (this.subAgentCompletion) {\n return this.turnDone();\n }\n }\n\n // The loop fell through: either it hit the iteration cap (a failure) or it\n // broke on a clean final answer (success). Only the former carries a reason.\n let failureReason: TurnFailureReason | undefined;\n if (iterations >= this.maxToolIterations) {\n logger.warn('ChatDriver: reached max tool iterations, stopping');\n recordTurnError(this.sessionKey, 'max-iterations', {\n agent: this.activeAgentName,\n provider: this.lastResolvedProviderName,\n iterations,\n limit: this.maxToolIterations,\n isSubAgent: this.isSubAgent,\n });\n if (this.isSubAgent) {\n this.failSubAgent('max_iterations');\n } else {\n this.appendToHistory({\n role: 'assistant',\n content:\n \"I've reached my limit for this response. You can ask me to continue and I'll pick up where I left off.\",\n });\n }\n failureReason = 'max-iterations';\n }\n\n return this.turnDone(failureReason);\n }\n\n private appendToHistory(message: ChatMessage): void {\n const tagged: ChatMessage = {\n ...message,\n // Stamp on first append; preserve any caller-supplied timestamp.\n timestamp: message.timestamp ?? new Date().toISOString(),\n ...(this.activeAgentName\n ? {\n agentName: this.activeAgentName,\n // Display-only \u2014 falls back to agentName in renderers when unset.\n agentLabel: this.activeAgentLabel,\n }\n : {}),\n };\n this.history = [...this.history, tagged];\n this.dispatchEvent(\n new CustomEvent<ReadonlyArray<ChatMessage>>('history-updated', {\n detail: this.history,\n }),\n );\n }\n}\n", "import type {\n AIProviderRegistry,\n ChatAttachment,\n ChatDriverResult,\n ChatMessage,\n ChatRequestOptions,\n} from '@genesislcap/foundation-ai';\nimport { BudgetExhaustedError } from '@genesislcap/foundation-ai';\nimport type { ActivityBus } from '../../channel/ai-activity-bus';\nimport type {\n AgentConfig,\n FallbackAgentConfig,\n SpecialistAgentConfig,\n SystemPromptContext,\n SystemPromptInput,\n} from '../../config/config';\nimport { validateStaticAgentProviders } from '../../config/validate-providers';\nimport { recordMetaEvent } from '../../state/debug-event-log';\nimport type { DiagnosticEntry } from '../../state/persistence/diagnostics';\nimport type { InteractionContext } from '../../types/interaction-context';\nimport { transformHistoryForAgent } from '../../utils/history-transform';\nimport { logger } from '../../utils/logger';\nimport type { AiDriver, AllAgentSummary } from '../ai-driver/ai-driver';\nimport {\n ChatDriver,\n REQUEST_CONTINUATION_TOOL,\n type TurnSnapshot,\n} from '../chat-driver/chat-driver';\n\nconst DEFAULT_MAX_HANDOFFS = 3;\nconst DEFAULT_CLASSIFIER_HISTORY_LENGTH = 4;\nconst DEFAULT_CLASSIFIER_RETRIES = 2;\n\nconst REQUEST_CONTINUATION_DEFINITION = {\n name: REQUEST_CONTINUATION_TOOL,\n description:\n \"Call this when you have completed your part of the task but fulfilling the user's full request requires capabilities outside your domain. Do not call this if you can complete the request yourself. Pass a plain-language description of what still needs to be done \u2014 another specialist will be selected automatically.\",\n parameters: {\n type: 'object',\n required: ['summary', 'remaining_task'],\n properties: {\n summary: {\n type: 'string',\n description: 'What you found or did \u2014 passed as context to the next specialist.',\n },\n remaining_task: {\n type: 'string',\n description:\n 'What still needs to be done, in plain language. Used to route to the right specialist.',\n },\n },\n },\n};\n\nfunction isSpecialist(agent: AgentConfig): agent is SpecialistAgentConfig {\n return !agent.fallback;\n}\n\nfunction isFallback(agent: AgentConfig): agent is FallbackAgentConfig {\n return agent.fallback === true;\n}\n\nfunction buildFallbackSystemPrompt(\n fallback: FallbackAgentConfig,\n specialists: SpecialistAgentConfig[],\n): SystemPromptInput | undefined {\n const agentList = specialists.map((s) => `- ${s.name}: ${s.description}`).join('\\n');\n if (typeof fallback.systemPrompt === 'string') {\n return fallback.systemPrompt.replace('{{agents}}', agentList);\n }\n if (typeof fallback.systemPrompt === 'function') {\n // Function-form fallback prompt \u2014 pass through unchanged. The `{{agents}}`\n // substitution is a string-template convenience; consumers using the\n // function form can compose the agent list themselves if they want it.\n return fallback.systemPrompt;\n }\n return `You are a helpful assistant. You cannot directly help with the user's request, but the following specialists are available:\\n\\n${agentList}\\n\\nPolitely let the user know what you can help with and invite them to rephrase their request.`;\n}\n\n/**\n * Orchestrates multiple specialist agents. Sits between `FoundationAiAssistant`\n * and `ChatDriver`, classifying each user message and routing it to the right\n * specialist \u2014 each with its own focused system prompt, tools, and primer.\n *\n * @beta\n */\nexport class OrchestratingDriver extends EventTarget implements AiDriver {\n private readonly chatDriver: ChatDriver;\n private readonly specialists: SpecialistAgentConfig[];\n private readonly fallback?: FallbackAgentConfig;\n private readonly maxHandoffs: number;\n private readonly classifierHistoryLength: number;\n private readonly classifierRetries: number;\n private readonly sessionKey: string;\n /**\n * Aborted on driver disposal. Threaded into `AgentLifecycleContext.signal`\n * so long-running `onActivate` work can bail if the session disconnects.\n */\n private readonly lifecycleAbortController = new AbortController();\n /**\n * Set by `cancel()` for the duration of a `sendMessage` run. Breaks the\n * handoff loop so we don't classify or start another agent turn after the\n * user stops. Reset at the start of each `sendMessage`.\n */\n private cancelled = false;\n /**\n * Whether the CURRENT turn's user message has reached the inner driver's\n * history. False through the pre-first-turn classify (where the only echo of\n * the message is an optimistic `history-updated` dispatch), true from the\n * moment `chatDriver.sendMessage` is entered \u2014 including through every later\n * handoff classify. Read by the budget-wall catch in `sendMessage` to decide\n * whether `reportBudgetExhausted` must append the message itself: appending\n * it when already appended duplicated it; not appending it when unappended\n * made it vanish. Reset at the top of each `runOrchestratedTurn`.\n */\n private userMessageAppended = false;\n /**\n * Sticky user pick from the picker (or the host's `setAgent` API). Only\n * changes on explicit user action. Survives flow completion: when a stateful\n * agent releases, the user-pin stays put and routing falls back to it on\n * the next turn.\n */\n private pinnedAgentName: string | null = null;\n /**\n * Transient flow lock \u2014 set when a stateful agent's `onActivate` fires,\n * cleared by `releaseActiveAgent`. While non-null, routing precedence goes\n * to this agent and the picker is locked. Independent of\n * `pinnedAgentName` so completing a flow doesn't wipe the user's sticky\n * choice.\n */\n private flowOwnerAgentName: string | null = null;\n\n /**\n * Per-agent restored state for a rehydrated session, keyed by agent name.\n * Primed by the host on restore; each entry is passed to that agent's\n * `onActivate` as `ctx.restored` on its next activation, then deleted so a\n * later re-activation starts fresh.\n */\n private restoredAgentStates: Record<string, unknown> = {};\n\n activeAgent?: AgentConfig;\n\n constructor(\n private readonly providerRegistry: AIProviderRegistry,\n private readonly agents: AgentConfig[],\n options: {\n sessionKey?: string;\n maxHandoffs?: number;\n classifierHistoryLength?: number;\n classifierRetries?: number;\n maxToolIterations?: number;\n maxFoldOperations?: number;\n maxTurnSnapshots?: number;\n /** Activity bus passed through to the inner ChatDriver (browser host injects the singleton). */\n activityBus?: ActivityBus;\n /** Budget-wall transcript copy, passed through to the inner ChatDriver (GENC-1464). */\n budgetExhaustedMessage?: string;\n } = {},\n ) {\n super();\n this.sessionKey = options.sessionKey ?? '';\n this.maxHandoffs = options.maxHandoffs ?? DEFAULT_MAX_HANDOFFS;\n this.classifierHistoryLength =\n options.classifierHistoryLength ?? DEFAULT_CLASSIFIER_HISTORY_LENGTH;\n this.classifierRetries = options.classifierRetries ?? DEFAULT_CLASSIFIER_RETRIES;\n\n // Static-name validation: walk every agent (and nested sub-agents). Any\n // `provider: '<name>'` that isn't registered, or resolves to a provider\n // without `chat()`, throws now rather than at first turn.\n validateStaticAgentProviders(agents, providerRegistry);\n\n // Specialists drive the classifier. `excludeFromClassifier` agents are still\n // resolvable by name (so manual pinning works) but never auto-routed.\n this.specialists = agents.filter(isSpecialist).filter((a) => !a.excludeFromClassifier);\n const fallbacks = agents.filter(isFallback);\n if (fallbacks.length > 1) {\n logger.warn(\n 'OrchestratingDriver: multiple fallback agents found \u2014 only the first will be used.',\n );\n }\n\n const rawFallback = fallbacks[0];\n this.fallback = rawFallback\n ? { ...rawFallback, systemPrompt: buildFallbackSystemPrompt(rawFallback, this.specialists) }\n : undefined;\n\n this.chatDriver = new ChatDriver(providerRegistry, {\n maxToolIterations: options.maxToolIterations,\n maxFoldOperations: options.maxFoldOperations,\n maxTurnSnapshots: options.maxTurnSnapshots,\n sessionKey: this.sessionKey,\n activityBus: options.activityBus,\n budgetExhaustedMessage: options.budgetExhaustedMessage,\n });\n\n // Proxy events from the shared driver\n this.chatDriver.addEventListener('history-updated', (e: Event) => {\n this.dispatchEvent(new CustomEvent('history-updated', { detail: (e as CustomEvent).detail }));\n });\n this.chatDriver.addEventListener('sub-agent-history-updated', (e: Event) => {\n this.dispatchEvent(\n new CustomEvent('sub-agent-history-updated', { detail: (e as CustomEvent).detail }),\n );\n });\n this.chatDriver.addEventListener('sub-agent-start', (e: Event) => {\n this.dispatchEvent(new CustomEvent('sub-agent-start', { detail: (e as CustomEvent).detail }));\n });\n this.chatDriver.addEventListener('sub-agent-stop', (e: Event) => {\n this.dispatchEvent(new CustomEvent('sub-agent-stop', { detail: (e as CustomEvent).detail }));\n });\n this.chatDriver.addEventListener('interaction-start', (e: Event) => {\n this.dispatchEvent(\n new CustomEvent('interaction-start', { detail: (e as CustomEvent).detail }),\n );\n });\n this.chatDriver.addEventListener('interaction-stop', (e: Event) => {\n this.dispatchEvent(\n new CustomEvent('interaction-stop', { detail: (e as CustomEvent).detail }),\n );\n });\n this.chatDriver.addEventListener('provider-changed', (e: Event) => {\n this.dispatchEvent(\n new CustomEvent('provider-changed', { detail: (e as CustomEvent).detail }),\n );\n });\n }\n\n resolveInteraction(interactionId: string, result: unknown): void {\n this.chatDriver.resolveInteraction(interactionId, result);\n }\n\n getInteractionContext(interactionId: string): InteractionContext | undefined {\n return this.chatDriver.getInteractionContext(interactionId);\n }\n\n isBusy(): boolean {\n return this.chatDriver.isBusy();\n }\n\n /** Currently active provider name from the underlying ChatDriver. */\n getActiveProviderName(): string {\n return this.chatDriver.getActiveProviderName();\n }\n\n /**\n * Pins routing to a specific agent by name. While pinned, the classifier is\n * skipped and the continuation tool is hidden from the agent's tool list, so\n * the agent cannot quietly hand back to the orchestrator. Pass `null` to\n * return to automatic routing.\n */\n setPinnedAgent(name: string | null): void {\n this.pinnedAgentName = name;\n }\n\n /**\n * Set the flow-owner lock \u2014 used to restore state from Redux on driver\n * reconstruction (agents-array changes, pop-in/pop-out). Not intended for\n * external callers to manipulate routing; that's what `setPinnedAgent` is\n * for.\n */\n setFlowOwner(name: string | null): void {\n this.flowOwnerAgentName = name;\n }\n\n loadHistory(messages: ChatMessage[]): void {\n this.chatDriver.loadHistory(messages);\n }\n\n getRawHistory(): readonly ChatMessage[] {\n return this.chatDriver.getHistory();\n }\n\n /** {@inheritDoc AiDriver.compact} */\n compact(): Promise<ChatMessage | null> {\n return this.chatDriver.compact();\n }\n\n /** {@inheritDoc AiDriver.canCompact} */\n canCompact(): boolean {\n return this.chatDriver.canCompact();\n }\n\n /** Delegates to the inner {@link ChatDriver} \u2014 turns are captured there. */\n getTurnSnapshots(): ReadonlyArray<TurnSnapshot> {\n return this.chatDriver.getTurnSnapshots();\n }\n\n /** Delegates to the inner {@link ChatDriver} \u2014 interactions resolve there, so it holds the buffer. */\n getExternalDiagnostics(): ReadonlyArray<DiagnosticEntry> {\n return this.chatDriver.getExternalDiagnostics();\n }\n\n async getSuggestions(\n history: ChatMessage[],\n prompt: string,\n count: number,\n allAgentInfo?: AllAgentSummary[],\n ): Promise<string[]> {\n // When pinned to a specialist, scope suggestions to that agent so the\n // proposed prompts reflect the active routing instead of the full panel.\n const pinned = this.resolvePinnedAgent();\n const candidates = pinned && isSpecialist(pinned) ? [pinned] : this.specialists;\n const agentInfo = candidates.map((s) => ({\n name: s.name,\n description: s.description,\n // Suggestions use tool names for prompt hints. Dynamic agents resolve\n // their tools per-turn against a SystemPromptContext we don't have here\n // \u2014 pass an empty list rather than invoke the factory with a fake one.\n tools: Array.isArray(s.toolDefinitions) ? s.toolDefinitions : [],\n }));\n return this.chatDriver.getSuggestions(history, prompt, count, agentInfo);\n }\n\n async sendMessage(input: string, attachments?: ChatAttachment[]): Promise<ChatDriverResult> {\n try {\n return await this.runOrchestratedTurn(input, attachments);\n } catch (e) {\n // The classifier calls the provider directly, outside any ChatDriver turn,\n // so a budget wall raised there would escape as an unhandled rejection \u2014\n // `FoundationAiAssistant.send()` has a `finally` but no `catch`. Land it on\n // the driver that owns the transcript, which appends the user-facing copy\n // and returns the same terminal result an in-loop wall would.\n //\n // The user's message rides along ONLY while it is genuinely unappended.\n // `classify()` runs at two seams: before the first agent turn \u2014 where the\n // `history-updated` dispatch in `runOrchestratedTurn` is optimistic only\n // and the real append lives inside `chatDriver.sendMessage`, which the\n // wall prevents from ever running \u2014 and again at the END of every handoff\n // iteration, by which point `chatDriver.sendMessage` HAS appended it.\n // Passing the message unconditionally duplicated it on the handoff seam:\n // `['user','assistant','tool','user','assistant']` in the transcript, the\n // snapshot, and the history sent to the model once the budget is raised.\n if (e instanceof BudgetExhaustedError) {\n return this.chatDriver.reportBudgetExhausted(\n e,\n this.userMessageAppended\n ? undefined\n : {\n role: 'user',\n content: input,\n ...(attachments ? { attachments } : {}),\n },\n );\n }\n throw e;\n }\n }\n\n private async runOrchestratedTurn(\n input: string,\n attachments?: ChatAttachment[],\n ): Promise<ChatDriverResult> {\n this.cancelled = false;\n this.userMessageAppended = false;\n const history = this.chatDriver.getHistory() as ChatMessage[];\n\n // Emit the user message immediately so the UI reflects it during the classify\n // round-trip \u2014 without this the chat appears frozen until classify returns.\n this.dispatchEvent(\n new CustomEvent('history-updated', {\n detail: [...history, { role: 'user', content: input, attachments }],\n }),\n );\n\n const pinned = this.resolvePinnedAgent();\n if (!pinned) this.dispatchEvent(new CustomEvent('orchestrating-start'));\n let currentAgent = pinned ?? (await this.classify(input, history, this.activeAgent));\n let isHandoff = false;\n let handoffs = 0;\n let handoffSummary = '';\n let remainingTask = '';\n // The outcome of the agent turn that ENDS the loop \u2014 see the return below.\n let lastResult: ChatDriverResult | undefined;\n\n while (true) {\n // Cancelled before a (next) agent turn started \u2014 e.g. during classify.\n // The chat driver appends its own \"Stopped.\" marker when a turn it was\n // running is cancelled, so we just stop here without a duplicate.\n if (this.cancelled) break;\n\n // oxlint-disable-next-line no-await-in-loop\n await this.applyAgent(currentAgent);\n\n let result: ChatDriverResult;\n if (isHandoff) {\n const contextPrimer: ChatMessage[] = handoffSummary\n ? [{ role: 'user', content: `[Context from previous agent]: ${handoffSummary}` }]\n : [];\n // oxlint-disable-next-line no-await-in-loop\n result = await this.chatDriver.continueFromHistory(contextPrimer);\n } else {\n // From here the inner driver owns the user message \u2014 it appends it as\n // its first act, before any provider call can throw. Set BEFORE the\n // await so a wall raised anywhere inside the turn (or on a later\n // handoff classify) sees the append as done.\n this.userMessageAppended = true;\n // oxlint-disable-next-line no-await-in-loop\n result = await this.chatDriver.sendMessage(input, attachments);\n }\n lastResult = result;\n\n // Release check: a stateful agent called `releaseAgent` from a terminal\n // tool handler. Fire onDeactivate, clear the pin, drop the user back to\n // classifier-mode. The LLM has already emitted its final wrap-up message\n // by the time we get here \u2014 release is purely a teardown.\n if (this.chatDriver.getAgentReleaseRequested()) {\n // oxlint-disable-next-line no-await-in-loop\n await this.releaseActiveAgent();\n break;\n }\n\n // Pinned agents never hand off \u2014 the continuation tool is filtered out in\n // applyAgent, but this guards against a model hallucinating a handoff result.\n if (result.reason !== 'agent-handoff' || isFallback(currentAgent) || pinned) {\n break;\n }\n\n handoffs += 1;\n if (handoffs > this.maxHandoffs) {\n this.appendInlineMessage(\n `I wasn't able to fully complete your request \u2014 the task required more hand-offs between specialists than allowed. Please try breaking your request into smaller steps.`,\n );\n break;\n }\n\n handoffSummary = result.summary;\n remainingTask = result.remainingTask;\n isHandoff = true;\n\n const updatedHistory = this.chatDriver.getHistory() as ChatMessage[];\n this.dispatchEvent(new CustomEvent('orchestrating-start'));\n // oxlint-disable-next-line no-await-in-loop\n currentAgent = await this.classify(remainingTask, updatedHistory);\n }\n\n // The orchestrated turn reports the outcome of the agent turn that ENDED it.\n // The hardcoded `{ reason: 'done' }` that used to live here made every\n // typed failure unreachable for an agents-configured host \u2014 including\n // `'budget-exhausted'`, which the element latches its blocked state off.\n //\n // \"Last wins\" cannot hide an earlier failure behind a later success: a\n // failing inner turn always ends the loop, because the loop only continues\n // on `reason === 'agent-handoff'`. The two breaks that hold a non-'done'\n // result (the handoff cap, and the pinned/fallback break) both carry\n // `'agent-handoff'`, which is an internal routing protocol that must never\n // escape to the host \u2014 the collapse below strips it. A cancel before the\n // first turn leaves `lastResult` undefined; the release break returns the\n // inner turn's real result, which is correct, because that turn ran.\n return lastResult?.reason === 'done' ? lastResult : { reason: 'done' };\n }\n\n async continueFromHistory(transientPrimer?: ChatMessage[]): Promise<ChatDriverResult> {\n return this.chatDriver.continueFromHistory(transientPrimer);\n }\n\n /** {@inheritDoc AiDriver.primeRestoredAgentState} */\n primeRestoredAgentState(snapshots: Record<string, unknown>): void {\n this.restoredAgentStates = { ...snapshots };\n }\n\n /** {@inheritDoc AiDriver.getActiveAgent} */\n getActiveAgent(): AgentConfig | undefined {\n return this.activeAgent;\n }\n\n private async applyAgent(agent: AgentConfig): Promise<void> {\n const previousAgent = this.activeAgent;\n const isSwitch = !previousAgent || previousAgent.name !== agent.name;\n\n // Record the agent transition on the debug-log timeline. A `null` `from`\n // marks the initial activation; a named `from` is a handoff between agents.\n if (isSwitch) {\n recordMetaEvent(this.sessionKey, 'agent.handoff', {\n from: previousAgent?.name ?? null,\n to: agent.name,\n // GENC-1351: was a restored snapshot waiting for this agent at activation?\n restored: this.restoredAgentStates[agent.name] !== undefined,\n });\n }\n\n // Fire lifecycle hooks around the swap \u2014 outgoing first, then incoming.\n // Both are awaited so a heavy `onActivate` (e.g. machine restore) completes\n // before the agent's first turn runs.\n if (isSwitch && previousAgent?.onDeactivate) {\n try {\n await previousAgent.onDeactivate({\n agentName: previousAgent.name,\n sessionKey: this.sessionKey,\n signal: this.lifecycleAbortController.signal,\n });\n } catch (e) {\n logger.warn(`OrchestratingDriver: onDeactivate(\"${previousAgent.name}\") threw:`, e);\n }\n }\n if (isSwitch && agent.onActivate) {\n // On a session restore, hand this agent its persisted state exactly once\n // (consumed here) so a stateful machine resumes at the right step; a later\n // re-activation of the same agent then starts fresh.\n const restored = this.restoredAgentStates[agent.name];\n if (restored !== undefined) delete this.restoredAgentStates[agent.name];\n try {\n await agent.onActivate({\n agentName: agent.name,\n sessionKey: this.sessionKey,\n previousAgentName: previousAgent?.name,\n signal: this.lifecycleAbortController.signal,\n restored,\n });\n } catch (e) {\n logger.warn(`OrchestratingDriver: onActivate(\"${agent.name}\") threw:`, e);\n }\n }\n\n const hasLifecycleHooks = !!(agent.onActivate || agent.onDeactivate);\n\n // Stateful agents auto-lock the flow on activation. The lock guarantees\n // the machine survives subsequent turns (the classifier would otherwise be\n // free to route away mid-flow, tearing the machine down). Release happens\n // when the agent calls `releaseAgent` from a terminal-state tool handler\n // \u2014 see the post-sendMessage check below. We write `flowOwnerAgentName`\n // rather than `pinnedAgentName` so completing a flow doesn't wipe the\n // user's sticky picker choice.\n if (isSwitch && hasLifecycleHooks && this.flowOwnerAgentName !== agent.name) {\n this.flowOwnerAgentName = agent.name;\n this.dispatchEvent(new CustomEvent('flow-owner-changed', { detail: agent.name }));\n }\n\n // Terminal agents do not get the cross-agent handoff tool. Four cases:\n // \u2022 fallback \u2014 already a leaf; handoff would loop\n // \u2022 user-pinned \u2014 user explicitly selected this agent; do not auto-route away\n // \u2022 flow-owner \u2014 a stateful flow is mid-stream; do not auto-route away\n // \u2022 stateful \u2014 agents with lifecycle hooks own state for the duration of\n // their flow. Initiating a handoff mid-flow would abandon\n // that state with no clean exit and dump the user into the\n // classifier mid-machine. Capture the tool loop until the\n // user (or the agent itself, via `releaseAgent`) releases.\n const isTerminal =\n isFallback(agent) ||\n this.pinnedAgentName !== null ||\n this.flowOwnerAgentName !== null ||\n hasLifecycleHooks;\n\n let agentToApply: AgentConfig = agent;\n if (!isTerminal) {\n const declaredTools = agent.toolDefinitions;\n agentToApply = {\n ...agent,\n toolDefinitions:\n typeof declaredTools === 'function'\n ? async (ctx: SystemPromptContext) => [\n ...(await declaredTools(ctx)),\n REQUEST_CONTINUATION_DEFINITION,\n ]\n : [...(declaredTools ?? []), REQUEST_CONTINUATION_DEFINITION],\n };\n }\n\n if (previousAgent && previousAgent.name !== agent.name) {\n const rawHistory = this.chatDriver.getHistory() as ChatMessage[];\n this.chatDriver.loadHistory([\n ...rawHistory,\n { role: 'system-event', content: agent.name, timestamp: new Date().toISOString() },\n ]);\n }\n\n this.chatDriver.setProviderHistoryTransform((h) => transformHistoryForAgent(h, agent.name));\n this.chatDriver.applyAgent(agentToApply);\n this.activeAgent = agent;\n this.dispatchEvent(new CustomEvent('orchestrating-stop'));\n this.dispatchEvent(new CustomEvent('agent-changed', { detail: agent }));\n }\n\n /**\n * Release the current stateful agent: fire `onDeactivate`, clear the\n * flow-owner lock, dispatch events so the host (and Redux) reflect the\n * unlocked state. Called automatically when a tool handler invokes\n * `context.releaseAgent`.\n *\n * The user-pin (`pinnedAgentName`) is intentionally *not* cleared \u2014 a user\n * who explicitly picked this agent should stay on it after the flow ends,\n * so the next message starts a fresh flow on the same agent rather than\n * routing through the classifier.\n */\n private async releaseActiveAgent(): Promise<void> {\n const agent = this.activeAgent;\n if (!agent) return;\n if (agent.onDeactivate) {\n try {\n await agent.onDeactivate({\n agentName: agent.name,\n sessionKey: this.sessionKey,\n signal: this.lifecycleAbortController.signal,\n });\n } catch (e) {\n logger.warn(`OrchestratingDriver: release onDeactivate(\"${agent.name}\") threw:`, e);\n }\n }\n this.activeAgent = undefined;\n if (this.flowOwnerAgentName !== null) {\n this.flowOwnerAgentName = null;\n this.dispatchEvent(new CustomEvent('flow-owner-changed', { detail: null }));\n }\n this.dispatchEvent(new CustomEvent('agent-released', { detail: agent }));\n this.dispatchEvent(new CustomEvent('agent-changed', { detail: undefined }));\n }\n\n /**\n * Stop the current turn (user \"stop\" button). Cancels the inner chat driver's\n * in-flight request and breaks the handoff loop so no further agent turn or\n * classify runs. The driver stays usable for the next message.\n */\n cancel(): void {\n this.cancelled = true;\n this.chatDriver.cancel();\n }\n\n /**\n * Fire `onDeactivate` on the current active agent and abort any pending\n * lifecycle work. Called by the host on session teardown so machines can\n * release resources cleanly.\n */\n async dispose(): Promise<void> {\n const previousAgent = this.activeAgent;\n if (previousAgent?.onDeactivate) {\n try {\n await previousAgent.onDeactivate({\n agentName: previousAgent.name,\n sessionKey: this.sessionKey,\n signal: this.lifecycleAbortController.signal,\n });\n } catch (e) {\n logger.warn(`OrchestratingDriver: dispose onDeactivate(\"${previousAgent.name}\") threw:`, e);\n }\n }\n this.lifecycleAbortController.abort();\n // Tear down the inner driver too, so any in-flight provider request aborts.\n this.chatDriver.dispose();\n this.activeAgent = undefined;\n }\n\n private async classify(\n input: string,\n history: ChatMessage[],\n contextAgent?: AgentConfig,\n ): Promise<AgentConfig> {\n // Single-candidate short-circuits. No point asking the LLM to route\n // when there's only one viable choice. Skipped if a fallback is\n // configured \u2014 that's an explicit \"escape hatch\" signal from the\n // consumer, and we preserve the LLM's ability to send unrelated\n // messages there by returning -1 from select_agent.\n if (this.specialists.length === 1 && !this.fallback) {\n return this.specialists[0];\n }\n if (this.specialists.length === 0) {\n // No classifier-eligible specialists. If exactly one non-fallback\n // agent exists (typically a stateful agent flagged\n // `excludeFromClassifier`) and there's no fallback to preserve as an\n // escape hatch, route to it \u2014 this is what fixes the previously-\n // silent single-stateful-agent case. Otherwise drop to the fallback;\n // excluded specialists remain reachable via manual pin.\n if (!this.fallback) {\n const routable = this.agents.filter((a) => !isFallback(a));\n if (routable.length === 1) {\n return routable[0];\n }\n }\n return this.fallback ?? { name: 'Assistant', fallback: true };\n }\n\n const agentList = this.specialists\n .map((a, i) => `${i}: ${a.name} \u2014 ${a.description}`)\n .join('\\n');\n\n const recentMessages = history\n .filter((m) => m.role === 'user' || m.role === 'assistant')\n .slice(-this.classifierHistoryLength)\n .map((m) => `${m.role === 'user' ? 'User' : 'Assistant'}: ${m.content}`)\n .join('\\n');\n\n const continuationHint =\n contextAgent && isSpecialist(contextAgent)\n ? `\\n\\nThe previous turn was handled by \"${contextAgent.name}\". If the new message is a refinement, correction, or continuation of that work, prefer \"${contextAgent.name}\" \u2014 unless the topic has clearly shifted to another specialist's domain.`\n : '';\n\n const classifierPrompt = `You are a routing classifier. Call select_agent with the index of the best matching agent for the user message. Use -1 only if the request is entirely unrelated to every agent listed \u2014 prefer the closest match when in doubt. If the request spans multiple agents, pick the one that should act first; I will re-classify and route again once that agent is done.\\n\\nAgents:\\n${agentList}${continuationHint}${recentMessages ? `\\n\\nRecent conversation:\\n${recentMessages}` : ''}`;\n\n const routingTool = {\n name: 'select_agent',\n description: 'Select the most appropriate agent for the user message.',\n parameters: {\n type: 'object',\n required: ['agent_index'],\n properties: {\n agent_index: {\n type: 'integer',\n description: 'Zero-based index of the matching agent, or -1 if no agent matches.',\n },\n },\n },\n };\n\n // True only when the classifier RAN and answered \"no match\" (index -1). The\n // no-fallback apology below is gated on it: an exhausted-retries exit never\n // earned that apology, and emitting it there put a routing excuse ahead of\n // the real error the routed turn is about to produce.\n let routedNoMatch = false;\n\n for (let attempt = 0; attempt <= this.classifierRetries; attempt += 1) {\n try {\n const options: ChatRequestOptions = {\n systemPrompt: classifierPrompt,\n tools: [routingTool],\n };\n // Classification is orchestrator-level, not bound to any single agent \u2014\n // always run against the registry default.\n const classifierProvider = this.providerRegistry.default();\n if (!classifierProvider.chat) {\n logger.warn(\n 'OrchestratingDriver: default AI provider does not implement chat() \u2014 cannot classify.',\n );\n break;\n }\n // oxlint-disable-next-line no-await-in-loop\n const response = await classifierProvider.chat([], input, options);\n const tc = response.toolCalls?.[0];\n const index = tc?.name === 'select_agent' ? (tc.args.agent_index as number) : -1;\n\n if (index >= 0 && index < this.specialists.length) {\n return this.specialists[index];\n }\n // index === -1 \u2014 fall through to fallback\n routedNoMatch = true;\n break;\n } catch (e) {\n // Terminal: no ladder clears a budget wall. Short-circuit the\n // classifier's own retries the same way 402 short-circuits the\n // transport's \u2014 this loop is a SECOND retry ladder stacked on that one,\n // so without this a single wall costs `classifierRetries + 1` doomed\n // classifier calls and then a doomed fallback turn on top. Deliberately\n // narrow: a generic classifier failure must still retry and fall back.\n if (e instanceof BudgetExhaustedError) throw e;\n logger.warn(`OrchestratingDriver: classifier attempt ${attempt + 1} failed:`, e);\n if (attempt === this.classifierRetries) {\n logger.error('OrchestratingDriver: classifier failed after all retries, using fallback');\n }\n }\n }\n\n if (this.fallback) return this.fallback;\n\n // No fallback configured. Route to the first specialist as a no-op \u2014 but\n // only APOLOGISE when the classifier actually said \"none of these\". On an\n // exhausted-retries exit the classifier never expressed an opinion, so the\n // apology would be a routing excuse the user reads immediately above the\n // real error that turn is about to produce.\n if (routedNoMatch) {\n const specialistNames = this.specialists.map((s) => s.name).join(', ');\n this.appendInlineMessage(\n `I'm not sure how to help with that. I can assist with: ${specialistNames}.`,\n );\n }\n return this.specialists[0];\n }\n\n /**\n * Returns the agent that the current turn is locked to, if any. Flow-owner\n * (transient, set by stateful-agent activation) wins over user-pin (sticky,\n * set by picker click). `undefined` falls back to the classifier.\n *\n * Logs and returns `undefined` if a name no longer matches the agents array\n * \u2014 protects against stale state after an agents-array reassignment.\n */\n private resolvePinnedAgent(): AgentConfig | undefined {\n const name = this.flowOwnerAgentName ?? this.pinnedAgentName;\n if (name === null) return undefined;\n const match = this.agents.find((a) => a.name === name);\n if (!match) {\n logger.warn(\n `OrchestratingDriver: pinned agent \"${name}\" not found in agents array \u2014 falling back to classifier.`,\n );\n return undefined;\n }\n return match;\n }\n\n private appendInlineMessage(content: string): void {\n const history = this.chatDriver.getHistory() as ChatMessage[];\n this.chatDriver.loadHistory([\n ...history,\n { role: 'assistant', content, timestamp: new Date().toISOString() },\n ]);\n this.dispatchEvent(\n new CustomEvent('history-updated', { detail: this.chatDriver.getHistory() }),\n );\n }\n}\n", "import type {\n CachePolicy,\n ChatFallback,\n ChatInputDuringExecutionMode,\n ChatMessage,\n ChatToolChoice,\n ChatToolDefinition,\n ChatToolHandlers,\n} from '@genesislcap/foundation-ai';\n\nexport type { CachePolicy, ChatFallback, ChatInputDuringExecutionMode, ChatToolChoice };\n\n/**\n * Context passed to `onActivate` / `onDeactivate` lifecycle hooks on an agent.\n *\n * @beta\n */\nexport interface AgentLifecycleContext {\n /** The agent the hook is firing for. */\n agentName: string;\n /** The assistant session key \u2014 stable across reloads, unique per assistant instance. */\n sessionKey: string;\n /** The agent that was active immediately before this one, if any. Only set on `onActivate`. */\n previousAgentName?: string;\n /** Aborted if the session disconnects mid-activation. */\n signal: AbortSignal;\n /**\n * A previously-serialized state image for this agent (from the agent's\n * `serialize`), passed only on `onActivate` when resuming a persisted\n * session. A stateful\n * agent's `init` rebuilds from it \u2014 e.g. via `restoreMachine` \u2014 or starts\n * fresh when it is `undefined`.\n */\n restored?: unknown;\n}\n\n/**\n * Context passed to an agent's `resumable` predicate (GENC-1351 \u00A75.9), evaluated\n * at session-save time on the active agent (which, for a locked guided flow, is\n * the flow-owner).\n *\n * @beta\n */\nexport interface AgentPersistenceContext {\n /** The agent being consulted. */\n agentName: string;\n /** The assistant session key \u2014 stable across reloads. */\n sessionKey: string;\n /**\n * This agent's just-serialized state image \u2014 the value its `serialize()`\n * returned for this save (or the carried-forward image). Inspect the machine\n * step here. Derive the decision from this (not live closure state): the\n * predicate must be a pure function of the state so a resumable snapshot stays\n * resumable when re-evaluated on restore.\n */\n state: unknown;\n /** Full conversation transcript at save time. */\n messages: ReadonlyArray<ChatMessage>;\n /** True when this agent currently owns the guided flow (`name === flowOwnerAgentName`). */\n isFlowOwner: boolean;\n}\n\n/**\n * Context passed to the function form of `systemPrompt` / `toolDefinitions`.\n * Resolved each tool-loop iteration so the agent can vary what the LLM sees per turn.\n *\n * @beta\n */\nexport interface SystemPromptContext {\n /** The active agent's name. */\n agentName: string;\n /** Full conversation history up to (but not including) the message being processed. */\n history: ReadonlyArray<ChatMessage>;\n /** 0 = first LLM call this turn; > 0 = retry or subsequent tool-loop iteration. */\n turnIndex: number;\n /** Aborted if the turn is cancelled. */\n signal: AbortSignal;\n}\n\n/**\n * System prompt for an agent. Either a static string (resolved once) or a function\n * resolved each tool-loop iteration. The function form lets the agent compute the\n * prompt from external state \u2014 e.g. a state machine's current step.\n *\n * @beta\n */\nexport type SystemPromptInput = string | ((ctx: SystemPromptContext) => string | Promise<string>);\n\n/**\n * Tool definitions for an agent. Either a static array (the conventional shape) or\n * a function resolved each tool-loop iteration. The function form lets the agent\n * narrow the tool surface per turn \u2014 e.g. expose only the tools valid in the\n * current state of a state machine.\n *\n * @beta\n */\nexport type ToolDefinitionsInput =\n | ChatToolDefinition[]\n | ((ctx: SystemPromptContext) => ChatToolDefinition[] | Promise<ChatToolDefinition[]>);\n\n/**\n * Tool handlers for an agent. Either a static map (the conventional shape) or a\n * function resolved each tool-loop iteration. The function form lets the agent\n * narrow the dispatchable handler set per turn \u2014 pair it with the function form\n * of `toolDefinitions` so the LLM-visible tools and the dispatchable handlers\n * stay in lockstep, and handlers don't have to defend themselves against being\n * dispatched in states where their tool isn't advertised.\n *\n * @beta\n */\nexport type ToolHandlersInput =\n | ChatToolHandlers\n | ((ctx: SystemPromptContext) => ChatToolHandlers | Promise<ChatToolHandlers>);\n\n/**\n * Names which registered `AIProviderRegistry` entry an agent uses. Either\n * a static string (resolved once at agent registration) or a function resolved\n * each tool-loop iteration \u2014 pick the function form to vary the provider by\n * current state (e.g. a stateful agent that switches providers between\n * machine states).\n *\n * Unknown provider names hard-error: static names at agent registration time,\n * function-resolved names on first resolution.\n *\n * @beta\n */\nexport type ProviderInput = string | ((ctx: SystemPromptContext) => string | Promise<string>);\n\n/**\n * Sampling temperature for an agent, normalized to `0`\u2013`1` (`0` = deterministic,\n * `1` = the most random the active provider allows). Either a static number\n * (resolved once) or a function resolved each tool-loop iteration \u2014 pick the\n * function form to vary it by current state (e.g. a lower temperature for a\n * precise extraction step, higher for brainstorming). Each transport translates\n * the normalized value into its own native range. Omit to use the\n * provider/model default. See `ChatRequestOptions.temperature`.\n *\n * @beta\n */\nexport type TemperatureInput = number | ((ctx: SystemPromptContext) => number | Promise<number>);\n\n/**\n * Tool-call mode for an agent. Either a static `ChatToolChoice` (resolved\n * once) or a function resolved each tool-loop iteration \u2014 pick the function form\n * to vary it by current state (e.g. force a classifier tool in an intake step,\n * then `'auto'` everywhere multi-step work happens). Omit to use the default\n * (`'auto'`, except sub-agent turns which force `'required'`).\n *\n * @beta\n */\nexport type ToolChoiceInput =\n | ChatToolChoice\n | ((ctx: SystemPromptContext) => ChatToolChoice | Promise<ChatToolChoice>);\n\n/**\n * Prompt-cache policy for an agent. Either a static `CachePolicy` (resolved once) or a\n * function resolved each tool-loop iteration \u2014 pick the function form to vary it by current state\n * (e.g. cache `'history'` in a long generating phase, `'default'` in short low-touch ones). Omit\n * to request no caching. Resolved and applied the same way as {@link TemperatureInput}.\n *\n * @beta\n */\nexport type CachePolicyInput =\n | CachePolicy\n | ((ctx: SystemPromptContext) => CachePolicy | Promise<CachePolicy>);\n\n/**\n * Per-turn tail context for an agent \u2014 volatile content (current file/spec, diagnostics, live\n * state) injected at the tail of every model-call so the model sees it without invalidating the\n * cached prefix. Either a static string or a function resolved each tool-loop iteration. **Provide\n * raw content** \u2014 the framework frames it (wraps it in a `<system-reminder>` marker) so the model\n * reads it as ambient context, not user input. Omit, or return an empty string, for none.\n *\n * @beta\n */\nexport type TailContextInput = string | ((ctx: SystemPromptContext) => string | Promise<string>);\n\n/**\n * Structured-output schema for an agent. When set, the model's final (non-tool) answer is\n * constrained to this JSON Schema instead of free text. Either a static schema or a function\n * resolved each tool-loop iteration \u2014 return the schema on the turn(s) it should apply and\n * `undefined` otherwise, so \"whole-loop\" vs \"finalize-turn\" enforcement is just what the\n * resolver returns (e.g. `({ state }) => state.machine.matches('finalizing') ? schema : undefined`).\n *\n * Orthogonal to {@link ToolChoiceInput}: an agent can carry both `tools` and a `responseSchema`.\n * Each provider applies it natively where possible (Anthropic `output_config.format`, Gemini\n * JSON mode) and degrades gracefully otherwise. The schema is a plain JSON Schema object; keep to\n * the portable subset providers share (`additionalProperties: false`, explicit `required`, enums,\n * `anyOf` for nullables \u2014 no numeric/string constraints or recursion).\n *\n * @beta\n */\nexport type ResponseSchemaInput =\n | object\n | ((ctx: SystemPromptContext) => object | undefined | Promise<object | undefined>);\n\n/**\n * Context passed to an agent's `onUnresolvedTool` hook when the model calls a\n * tool the driver cannot dispatch.\n *\n * @beta\n */\nexport interface UnresolvedToolContext {\n /** The tool name the model attempted to call. */\n toolName: string;\n /**\n * Why the call could not be dispatched:\n * - `'stale'` \u2014 the tool was advertised earlier this activation but is not\n * part of the current step (e.g. a stateful agent has moved on).\n * - `'unknown'` \u2014 the tool was never advertised this activation (a\n * hallucinated name).\n */\n kind: 'stale' | 'unknown';\n /**\n * The tool names dispatchable right now, so the hook can steer the model\n * back to a valid call.\n */\n availableTools: string[];\n}\n\n/**\n * Optional per-agent hook consulted only on the already-failing unresolved-tool\n * path \u2014 when the model calls a tool the driver cannot dispatch. Lets the agent\n * replace the framework's default message with a context-aware redirect.\n *\n * Return a non-empty string to override the default tool-result message; return\n * `undefined` (or an empty/whitespace string, or throw) to fall back to the\n * framework default. The happy path is never affected. See\n * {@link UnresolvedToolContext}.\n *\n * @beta\n */\nexport type UnresolvedToolInput = (\n ctx: UnresolvedToolContext,\n) => string | undefined | Promise<string | undefined>;\n\n/**\n * Opts an agent in to manual selection from the assistant's agent picker.\n *\n * Only applies to top-level agents \u2014 sub-agents are never user-selectable.\n * Has no effect unless the assistant's `agentPicker` is also enabled.\n *\n * @beta\n */\nexport interface ManualSelectionConfig {\n /**\n * Whether this agent appears in the picker.\n */\n enabled: boolean;\n /**\n * Optional short description shown as a tooltip on the picker entry, and as\n * a secondary line in the dropdown variant.\n */\n hint?: string;\n}\n\ninterface BaseAgentConfig {\n /**\n * Stable identity for this agent. Used for classifier routing, manual\n * pinning, and history filtering \u2014 must not vary per turn. For a per-turn\n * display label (e.g. \"Guided Booking (Counterparties)\"), supply\n * {@link BaseAgentConfig.displayName}.\n */\n name: string;\n /**\n * Optional per-turn display label. Resolved each tool-loop iteration and\n * stamped onto outgoing messages (`agentLabel`) and the debug-log timeline.\n * Renderers fall back to `name` when this is unset. Use the function form\n * to vary the label by current state (e.g. a state machine's step).\n *\n * Identity stays on `name` \u2014 this is for UX only.\n */\n displayName?: SystemPromptInput;\n /**\n * System prompt injected into every conversation turn for this agent.\n *\n * Either a string (resolved once) or a function resolved each tool-loop\n * iteration \u2014 pick the function form when the prompt depends on per-turn state\n * (e.g. a state machine's current step). See {@link SystemPromptInput}.\n */\n systemPrompt?: SystemPromptInput;\n /**\n * Tool definitions (JSON Schema) passed to the AI provider for this agent.\n *\n * Either a static array or a function resolved each tool-loop iteration \u2014\n * pick the function form to narrow the tool surface per turn (e.g. expose\n * only the tools valid in the current state of a state machine).\n * See {@link ToolDefinitionsInput}.\n */\n toolDefinitions?: ToolDefinitionsInput;\n /**\n * Tool handler implementations for this agent.\n *\n * Either a static map or a function resolved each tool-loop iteration \u2014\n * pick the function form to narrow the dispatchable handler set per turn,\n * matching the function form of `toolDefinitions`.\n * See {@link ToolHandlersInput}.\n */\n toolHandlers?: ToolHandlersInput;\n /**\n * Which registered AI provider this agent uses, by name. Either a static\n * string (resolved once at agent registration) or a function resolved each\n * tool-loop iteration \u2014 pick the function form to vary the provider by\n * current state (e.g. a stateful agent that switches providers between\n * machine states).\n *\n * Omit to use the registry's default provider. Unknown names hard-error:\n * static names at registration time, function-resolved names on first\n * resolution.\n *\n * Known limitation: switching provider mid-conversation can blow the\n * smaller provider's context window if history accumulated under a\n * larger one. No automatic trimming is performed.\n *\n * @beta\n */\n provider?: ProviderInput;\n /**\n * Sampling temperature for this agent, normalized to `0`\u2013`1`. Either a static\n * number or a function resolved each tool-loop iteration \u2014 pick the function\n * form to vary it by current state. Omit to use the provider/model default.\n * Resolved and applied the same way as {@link BaseAgentConfig.provider}.\n * See {@link TemperatureInput}.\n *\n * @beta\n */\n temperature?: TemperatureInput;\n /**\n * Tool-call mode for this agent \u2014 whether the model may, must, or must not\n * call a tool this turn (and optionally which one). Either a static value or\n * a function resolved each tool-loop iteration \u2014 pick the function form to\n * vary it by current state (e.g. force a single tool at a known juncture).\n * Omit to use the default (`'auto'`, except sub-agent turns which force\n * `'required'`). See {@link ToolChoiceInput}.\n *\n * @beta\n */\n toolChoice?: ToolChoiceInput;\n /**\n * Prompt-cache policy for this agent \u2014 whether to emit cache breakpoints and how far up the\n * prefix. Either a static value or a function resolved each tool-loop iteration (vary by state).\n * Resolved and applied the same way as {@link BaseAgentConfig.temperature}. Omit to request no\n * caching. Provider-neutral \u2014 see {@link CachePolicyInput} / `CachePolicy` for the\n * Anthropic-vs-Gemini behaviour. See {@link CachePolicyInput}.\n *\n * @beta\n */\n cachePolicy?: CachePolicyInput;\n /**\n * Volatile per-turn context injected at the tail of every model-call (after the history and any\n * cache breakpoint), so it is seen each turn without busting the cached prefix \u2014 the place to put\n * the changing parts (current file/spec, diagnostics, live state) that would otherwise\n * destabilize a cached system prompt. Provide *raw* content; the framework frames it (wraps it in\n * a `<system-reminder>` marker). Resolved per turn like {@link BaseAgentConfig.temperature}. See\n * {@link TailContextInput}.\n *\n * @beta\n */\n tailContext?: TailContextInput;\n /**\n * Structured-output schema for this agent. When resolved to a schema on a turn, the model's\n * final (non-tool) answer is constrained to it instead of free text. Composes with `tools`;\n * resolved per turn like {@link BaseAgentConfig.cachePolicy}, so returning `undefined` on\n * working turns and the schema on the finalize turn gives finalize-turn enforcement for free.\n * See {@link ResponseSchemaInput}.\n *\n * @beta\n */\n responseSchema?: ResponseSchemaInput;\n /**\n * Refusal-fallback chain for this agent (provider-neutral). If the model declines a turn\n * (`stop_reason: 'refusal'` \u2014 e.g. Fable 5 safety classifiers), the provider re-runs it on the\n * next listed model. Typical use: a Fable 5 agent with `[{ model: 'claude-opus-4-8' }]`. Static\n * (not per-turn); providers that support it apply it server-side, others ignore it.\n *\n * @beta\n */\n fallbacks?: ChatFallback[];\n /**\n * Optional hook consulted when the model calls a tool the driver cannot\n * dispatch \u2014 either a *stale* tool (advertised earlier this activation but\n * not part of the current step) or an *unknown* one (never advertised this\n * activation). Return a context-aware redirect string to replace the\n * framework's default message, or `undefined` to keep it. Consulted only on\n * the already-failing unresolved-tool path; the happy path is unaffected.\n * See {@link UnresolvedToolInput}.\n *\n * @beta\n */\n onUnresolvedTool?: UnresolvedToolInput;\n /**\n * Optional primer history prepended to every call (not visible to the user).\n * Used to establish agent identity and behavioural rules.\n */\n primerHistory?: ChatMessage[];\n /**\n * Sub-agents available to this agent's tool handlers via `requestSubAgent`.\n */\n subAgents?: AgentConfig[];\n /**\n * How the main chat input area behaves while this agent is executing.\n * Defaults to `'disabled'`. See {@link ChatInputDuringExecutionMode}.\n */\n chatInputDuringExecution?: ChatInputDuringExecutionMode;\n /**\n * Opts this agent in to manual selection from the assistant's agent picker.\n * Has no effect on sub-agents or when the assistant's `agentPicker` is\n * disabled. See {@link ManualSelectionConfig}.\n */\n manualSelection?: ManualSelectionConfig;\n /**\n * Fires when this agent becomes the active specialist (including being pinned).\n * Use to instantiate per-agent state that should outlive a single turn \u2014 e.g.\n * a state machine the agent owns across the conversation. Awaited before the\n * agent's first turn runs.\n *\n * Capture dependencies (services, redux store refs, etc.) via closure on the\n * host element rather than expecting them on the context.\n *\n * @beta\n */\n onActivate?: (ctx: AgentLifecycleContext) => void | Promise<void>;\n /**\n * Fires when this agent is being deactivated (the user switches to another\n * agent, the session is torn down, or the agent is unpinned and replaced).\n * Use to dispose per-agent state created in `onActivate`. Awaited before the\n * incoming agent's `onActivate` runs.\n *\n * @beta\n */\n onDeactivate?: (ctx: AgentLifecycleContext) => void | Promise<void>;\n /**\n * Returns an agent-supplied debug payload for the export log. Called once per\n * LLM call by the driver (alongside the resolved prompt and tool list) and\n * once at log-export time for the latest snapshot. Stateful agents should\n * return their machine state and captured context so the exported timeline\n * captures what drove each turn.\n *\n * Return value must be JSON-serializable. {@link defineStatefulAgent} wires a\n * sensible default that snapshots any machine-shaped state automatically.\n *\n * @beta\n */\n getDebugSnapshot?: () => unknown;\n /**\n * Returns a lossless, JSON-serializable image of the agent's state for session\n * persistence \u2014 distinct from `getDebugSnapshot`, which may abbreviate for\n * readability. Pass the value back to the agent on restore (as\n * `ctx.restored` in its `init`) to resume. {@link defineStatefulAgent} wires a\n * default that snapshots any machine-shaped state via `getPersistedSnapshot()`\n * and returns plain state as-is.\n *\n * @beta\n */\n serialize?: () => unknown;\n /**\n * Whether the agent's current state is resumable \u2014 i.e. worth persisting so the\n * session can be restored mid-flow (GENC-1351 \u00A75.9). Consulted at save time on\n * the active agent (the flow-owner during a locked flow). Return `true`\n * (or leave the field absent) to persist and resume normally; return `false`\n * for a point that shouldn't be resumed \u2014 the session is not persisted, and on\n * return the assistant shows {@link AgentConfig.notResumableMessage} (or a\n * default) and pre-fills the composer with the prompt that started the flow so\n * the user can re-run it.\n *\n * Only consulted when the user has persistence enabled. Must be a **pure\n * function of `ctx.state`** \u2014 it may be re-evaluated on a restored snapshot, so\n * a resumable state must stay resumable. A thrown error is treated as `true`\n * (fail-safe: never drop a resumable chat on a predicate bug).\n *\n * @beta\n */\n resumable?: (ctx: AgentPersistenceContext) => boolean | Promise<boolean>;\n /**\n * Message shown on return when {@link AgentConfig.resumable} returned `false`\n * and the user comes back to a non-resumable session (GENC-1351 \u00A75.9). Falls\n * back to a built-in default when omitted.\n *\n * @beta\n */\n notResumableMessage?: string;\n}\n\n/**\n * Configuration for a specialist agent.\n *\n * Specialist agents are offered to the classifier for intent routing. The\n * `description` is used to auto-generate the classifier prompt \u2014 no manual\n * routing prompt authoring required.\n *\n * @beta\n */\nexport interface SpecialistAgentConfig extends BaseAgentConfig {\n /**\n * Plain-language description of what this agent handles.\n * Used by the classifier to auto-generate its routing prompt.\n */\n description: string;\n fallback?: never;\n /**\n * When `true`, the classifier never auto-routes to this agent. The user can\n * still select it manually via the picker, provided both prerequisites are\n * met: this agent has `manualSelection.enabled` set to `true`, *and* the\n * assistant has the picker enabled via `chatConfig.picker.mode`.\n *\n * Use this for agents that overlap heavily with a sibling (e.g. a guided\n * wizard sitting next to a free-form agent in the same domain) and should\n * only be reached intentionally rather than via classifier routing.\n *\n * @beta\n */\n excludeFromClassifier?: boolean;\n}\n\n/**\n * Configuration for a fallback agent.\n *\n * Invoked when the classifier returns no match. Excluded from the classifier\n * prompt. Only one fallback is permitted per agents array.\n *\n * @beta\n */\nexport interface FallbackAgentConfig extends BaseAgentConfig {\n /**\n * Marks this agent as the fallback for unrecognised requests.\n */\n fallback: true;\n description?: never;\n}\n\n/**\n * Configuration for an agent passed to `FoundationAiAssistant`.\n *\n * Either a specialist (requires `description`) or a fallback (requires\n * `fallback: true`). Passing both or neither is a compile error.\n *\n * @beta\n */\nexport type AgentConfig = SpecialistAgentConfig | FallbackAgentConfig;\n\n/**\n * Identity helper that infers the narrowest possible type for an agent config,\n * preserving string literal types (including `name`) without requiring `as const`.\n *\n * Use this when you need `typeof myAgent` to carry the literal `name` type \u2014\n * for example, when wiring `ChatToolHandlers<typeof myAgent>`.\n *\n * ```ts\n * const myAgent = defineAgent({ name: 'my_agent', ... });\n * type Handlers = ChatToolHandlers<typeof myAgent>;\n * // requestSubAgent name param is now typed as 'my_agent'\n * ```\n *\n * @beta\n */\n\nexport function defineAgent<const T extends AgentConfig>(config: T): T {\n return config;\n}\n", "import type {\n CachePolicy,\n ChatMessage,\n ChatToolChoice,\n ChatToolDefinition,\n ChatToolHandlers,\n} from '@genesislcap/foundation-ai';\nimport { TOOL_FOLD_SYMBOL } from '../utils/tool-fold';\nimport type {\n AgentConfig,\n AgentLifecycleContext,\n AgentPersistenceContext,\n CachePolicyInput,\n ChatInputDuringExecutionMode,\n ManualSelectionConfig,\n ProviderInput,\n SystemPromptContext,\n SystemPromptInput,\n TailContextInput,\n TemperatureInput,\n ToolChoiceInput,\n ToolDefinitionsInput,\n ToolHandlersInput,\n UnresolvedToolContext,\n UnresolvedToolInput,\n} from './config';\n\n/**\n * Context passed to per-turn resolvers on a stateful agent \u2014 the standard\n * {@link SystemPromptContext} plus the live `state` value. Used by\n * `systemPrompt`, `displayName`, and the function form of `toolDefinitions`.\n *\n * Exported so consumers can lift resolvers into separate files without\n * re-deriving the shape.\n *\n * @beta\n */\nexport type StatefulAgentContext<S> = SystemPromptContext & { state: S };\n\n/**\n * Context passed to a stateful agent's `resumable` predicate (GENC-1351 \u00A75.9) \u2014\n * the standard {@link AgentPersistenceContext} but with `state` as the **live**\n * state bag `S` (not the serialized image), so a machine agent can gate on its\n * current step directly.\n *\n * @beta\n */\nexport type StatefulAgentPersistenceContext<S> = Omit<AgentPersistenceContext, 'state'> & {\n state: S;\n};\n\n/**\n * Init options for {@link defineStatefulAgent}. Generic over the state shape `S`\n * the agent owns (a state machine, an observable controller, anything).\n *\n * The helper threads `state` through `systemPrompt`, `toolDefinitions`, and the\n * `toolHandlers` factory so consumer code never has to reach for a closure or\n * a module-level mutable.\n *\n * @beta\n */\nexport interface StatefulAgentInit<S> {\n /** Display name \u2014 must be unique within the agents array. */\n name: string;\n /** Plain-language description used by the classifier. Required: stateful agents are always specialists. */\n description: string;\n /**\n * Hide this agent from the classifier \u2014 only reachable via manual pinning.\n * Stateful agents are always specialists; they cannot be the fallback (a\n * fallback is a leaf invoked when no specialist matches, with no flow to\n * own state for).\n */\n excludeFromClassifier?: boolean;\n /** Static primer history prepended to every call (not visible to the user). */\n primerHistory?: ChatMessage[];\n /** Sub-agents available to this agent's tool handlers via `requestSubAgent`. */\n subAgents?: AgentConfig[];\n /** Opt this agent in to manual picker selection. */\n manualSelection?: ManualSelectionConfig;\n /** How the main chat input behaves while this agent is executing. */\n chatInputDuringExecution?: ChatInputDuringExecutionMode;\n\n /**\n * Construct the agent-scoped state. Called by the framework when this agent\n * becomes active (`onActivate`). Awaited before the agent's first turn runs.\n *\n * On a persisted-session restore, `ctx.restored` carries this agent's previous\n * `serialize` output \u2014 rebuild from it (e.g. via `restoreMachine`), or start\n * fresh when it is `undefined`.\n */\n init: (ctx: AgentLifecycleContext) => S | Promise<S>;\n\n /**\n * Tear down the agent-scoped state. Called when the agent is being replaced.\n * Awaited before the incoming agent's `init` runs.\n */\n dispose?: (ctx: AgentLifecycleContext & { state: S }) => void | Promise<void>;\n\n /**\n * System prompt composed from current state. Resolved each tool-loop\n * iteration. Use this to feed the LLM whatever the current state implies\n * (e.g. a state machine's `meta.systemPrompt` plus captured context).\n */\n systemPrompt?: (ctx: StatefulAgentContext<S>) => string | Promise<string>;\n\n /**\n * Per-turn display label, e.g. \"Guided Booking (Counterparties)\". Resolved\n * each tool-loop iteration and stamped onto outgoing messages and the\n * debug-log timeline \u2014 display only. The agent's `name` stays as the\n * canonical identity used for routing/history filtering.\n */\n displayName?: (ctx: StatefulAgentContext<S>) => string | Promise<string>;\n\n /**\n * Tool definitions the LLM sees. Either a static array (resolved once) or a\n * function resolved each tool-loop iteration. The function form is how a\n * machine-driven agent narrows the surface per state.\n *\n * **Constraint:** the resolved handlers (returned from {@link StatefulAgentInit.toolHandlers})\n * must not include fold facades. Folds are an LLM-driven UX optimisation\n * that competes with the machine for control of the tool view; one of them\n * has to be in charge. Helper throws at init time if a fold-tagged handler\n * is detected.\n */\n toolDefinitions?:\n | ChatToolDefinition[]\n | ((ctx: StatefulAgentContext<S>) => ChatToolDefinition[] | Promise<ChatToolDefinition[]>);\n\n /**\n * Factory returning the handler map for the **current state**. Called each\n * tool-loop iteration with the live `state` value, so the handler set the\n * driver dispatches against matches what `toolDefinitions` exposes to the\n * LLM that turn. Return only the handlers valid right now \u2014 no need to\n * advertise every handler the agent might ever expose, and no defensive\n * `if (!machine.matches(...))` guards inside each handler.\n *\n * Pair with the function form of `toolDefinitions` so the visible tools and\n * the dispatchable handlers stay in lockstep.\n *\n * **Constraint:** resolved handlers must not include fold facades. Folds and\n * state-machine-driven tool filtering both try to control the LLM's tool\n * view \u2014 pick one. Helper samples once on activation (init state) and\n * throws if a fold-tagged handler is detected; subsequent resolves also\n * validate, so misuse on a non-init state surfaces when that state is\n * reached.\n */\n toolHandlers?: (state: S) => ChatToolHandlers | Promise<ChatToolHandlers>;\n\n /**\n * Which registered AI provider this agent uses, by name. Either a static\n * string or a function resolved each tool-loop iteration with the current\n * `state` \u2014 pick the function form to vary provider per machine state\n * (e.g. swap to a heavier model only for the planning step).\n *\n * Omit to use the registry's default provider. Unknown names hard-error.\n */\n provider?: string | ((ctx: StatefulAgentContext<S>) => string | Promise<string>);\n\n /**\n * Sampling temperature, normalized to `0`\u2013`1`. Either a static number or a\n * function resolved each tool-loop iteration with the current `state` \u2014 pick\n * the function form to vary it per machine state (e.g. low for a precise\n * extraction step, higher for free-form drafting). Omit for the default.\n */\n temperature?: number | ((ctx: StatefulAgentContext<S>) => number | Promise<number>);\n\n /**\n * Tool-call mode. Either a static `ChatToolChoice` or a function\n * resolved each tool-loop iteration with the current `state` \u2014 pick the\n * function form to force a specific tool in one state (e.g. a classifier in\n * intake) and leave `'auto'` in states where multi-step work happens. Omit\n * for the default.\n */\n toolChoice?:\n | ChatToolChoice\n | ((ctx: StatefulAgentContext<S>) => ChatToolChoice | Promise<ChatToolChoice>);\n\n /**\n * Prompt-cache policy. Either a static `CachePolicy` or a function resolved each tool-loop\n * iteration with the current `state` \u2014 pick the function form to vary it per machine state\n * (e.g. `'history'` in a long generating phase, `'default'` in short low-touch ones). Omit to\n * request no caching.\n */\n cachePolicy?:\n | CachePolicy\n | ((ctx: StatefulAgentContext<S>) => CachePolicy | Promise<CachePolicy>);\n\n /**\n * Volatile per-turn tail context (current file/spec, diagnostics, live state). Either a static\n * string or a function resolved each tool-loop iteration with the current `state`. Provide raw\n * content; the framework frames it. Omit, or return an empty string, for none.\n */\n tailContext?: string | ((ctx: StatefulAgentContext<S>) => string | Promise<string>);\n\n /**\n * Hook consulted when the model calls a tool that isn't dispatchable in the\n * current state \u2014 a *stale* tool (valid in an earlier state of this agent) or\n * an *unknown* one. Receives the current `state` alongside the attempted tool\n * name and the currently dispatchable tools, so a machine-driven agent can\n * return a step-aware redirect (e.g. \"that belongs to a later step \u2014 finish\n * this one first\"). Return `undefined` to keep the framework default; a\n * pre-init call also degrades to the default rather than throwing.\n * See {@link UnresolvedToolContext}.\n */\n onUnresolvedTool?: (\n ctx: UnresolvedToolContext & { state: S },\n ) => string | undefined | Promise<string | undefined>;\n\n /**\n * Optional getter for the debug-log snapshot. Defaults to auto-snapshotting\n * any property on `state` that looks like a foundation-state-machine\n * instance (has `state`, `context`, and `complete` fields). Override when\n * the default doesn't capture what you need \u2014 e.g. multiple machines, or\n * non-machine state worth recording.\n *\n * Return value must be JSON-serializable.\n */\n getDebugSnapshot?: (state: S) => unknown;\n\n /**\n * Lossless serializer for session persistence \u2014 infra-agnostic. Return any\n * JSON/structured-clone-safe image of `state`.\n * \u2022 Machine agents (`{ machine }`): omit \u2014 the default snapshots every\n * machine-shaped property via `getPersistedSnapshot()`.\n * \u2022 Plain-data agents (e.g. `{ plan, cursor }`): omit too \u2014 the default\n * returns plain state as-is. Provide one only when the state holds\n * something the default can't capture.\n * Distinct from `getDebugSnapshot` (which may be lossy by design). Pair with\n * `init` reading `ctx.restored` to rebuild.\n */\n serialize?: (state: S) => unknown;\n\n /**\n * Whether the agent's current state is resumable \u2014 worth persisting so the\n * session restores mid-flow (GENC-1351 \u00A75.9). Receives the **live** state bag\n * `S` (like the other per-turn resolvers), so a machine agent gates on its step\n * directly: `resumable: ({ state }) => state.machine.state !== 'confirm'`.\n * Return `false` for a point that shouldn't resume \u2014 the session isn't persisted,\n * and on return the assistant shows {@link StatefulAgentInit.notResumableMessage}\n * (or a default) and pre-fills the composer with the prompt that started the flow.\n * Only consulted with persistence enabled; a thrown error is treated as `true`\n * (fail-safe \u2014 never drop a resumable chat on a predicate bug).\n */\n resumable?: (ctx: StatefulAgentPersistenceContext<S>) => boolean | Promise<boolean>;\n /**\n * Message shown on return when {@link StatefulAgentInit.resumable} returned\n * `false`. Falls back to a built-in default when omitted.\n */\n notResumableMessage?: string;\n}\n\n/**\n * Walk a state object and snapshot any machine-shaped values found on it.\n * Recognises foundation-state-machine instances by structural shape rather\n * than `instanceof`, so the helper stays free of a runtime dep on\n * foundation-state-machine.\n *\n * Strips the `errors`/`error` framework noise from each machine's context \u2014\n * these are foundation-state-machine internals (an ErrorMap instance and its\n * last-error pointer) that bloat the debug payload without aiding debugging.\n */\nfunction defaultStatefulDebugSnapshot(state: unknown): unknown {\n if (!state || typeof state !== 'object') return state;\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(state as Record<string, unknown>)) {\n if (val && typeof val === 'object' && 'state' in val && 'context' in val && 'complete' in val) {\n const m = val as {\n state: unknown;\n context: Record<string, unknown>;\n complete: unknown;\n output?: unknown;\n };\n const ctx = m.context ?? {};\n const { errors: _e, error: _err, ...userContext } = ctx;\n result[key] = {\n state: m.state,\n context: userContext,\n complete: m.complete,\n output: m.output,\n };\n }\n }\n return Object.keys(result).length\n ? result\n : '<no auto-snapshot \u2014 state has no machine-shaped properties; provide getDebugSnapshot>';\n}\n\n/**\n * Build a restore-ready snapshot of agent state. Each property exposing a\n * `getPersistedSnapshot()` method (a foundation-state-machine `AbstractMachine`)\n * is replaced by its persisted snapshot \u2014 the lossless, JSON-safe image\n * {@link restoreMachine} feeds back via `start({ state })`. Every other property\n * is kept as-is, so plain serializable state (e.g. a planner's `{ plan, cursor }`)\n * round-trips directly with no per-agent `serialize`.\n *\n * Distinct from `defaultStatefulDebugSnapshot`, which abbreviates for the debug\n * log and is not guaranteed lossless.\n */\nfunction defaultStatefulSerialize(state: unknown): unknown {\n if (!state || typeof state !== 'object') return state;\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(state as Record<string, unknown>)) {\n result[key] =\n val &&\n typeof val === 'object' &&\n typeof (val as { getPersistedSnapshot?: unknown }).getPersistedSnapshot === 'function'\n ? (val as { getPersistedSnapshot: () => unknown }).getPersistedSnapshot()\n : val;\n }\n return result;\n}\n\n/**\n * Restore a foundation-state-machine instance from a snapshot produced by the\n * default serializer (or `machine.getPersistedSnapshot()`). Call inside a\n * stateful agent's `init` to resume the machine in its exact prior place:\n *\n * ```ts\n * init: ({ restored }) => {\n * const machine = new MyMachine();\n * restoreMachine(machine, restored); // resume, or no-op on a fresh start\n * return { machine };\n * }\n * ```\n *\n * No-ops when there is nothing to restore (a fresh session), leaving the\n * freshly-constructed machine in its initial state.\n *\n * @param machine - the machine to restore (already constructed/started).\n * @param restored - the agent's serialized image (`ctx.restored` in `init`).\n * @param key - the property the machine occupies in the snapshot; defaults to\n * `'machine'` to match the conventional `{ machine }` state bag.\n * @beta\n */\nexport function restoreMachine(\n machine: { stop: () => void; start: (options?: { state?: unknown }) => void },\n restored: unknown,\n key = 'machine',\n): void {\n const snapshot = (restored as Record<string, unknown> | undefined)?.[key];\n if (snapshot === undefined || snapshot === null) {\n return;\n }\n machine.stop();\n machine.start({ state: snapshot });\n}\n\n/**\n * Build an `AgentConfig` whose `systemPrompt`, `toolDefinitions`, and tool\n * handlers all close over a long-lived state object created on activation.\n *\n * The framework wires the lifecycle: `init` on `onActivate`, `dispose` on\n * `onDeactivate`. State is held inside the helper's closure \u2014 never exposed on\n * the resulting `AgentConfig` \u2014 so the redux serializer doesn't see it.\n *\n * @example\n * ```ts\n * const guidedBooking = defineStatefulAgent<{ machine: GuidedBookingMachine }>({\n * name: 'Guided Booking',\n * description: 'Books a trade via a guided wizard.',\n * excludeFromClassifier: true,\n * manualSelection: { enabled: true, hint: 'Step-by-step trade booking' },\n * init: () => ({ machine: new GuidedBookingMachine() }),\n * dispose: ({ state }) => state.machine.stop(),\n * systemPrompt: ({ state }) => composeFromMachine(state.machine),\n * toolDefinitions: ({ state }) => toolsForState(state.machine.state),\n * toolHandlers: ({ machine }) => ({ ... }),\n * });\n * ```\n *\n * @beta\n */\nexport function defineStatefulAgent<S>(opts: StatefulAgentInit<S>): AgentConfig {\n let state: S | undefined;\n\n const assertNoFolds = (handlers: ChatToolHandlers): void => {\n for (const [name, handler] of Object.entries(handlers)) {\n if ((handler as any)[TOOL_FOLD_SYMBOL]) {\n throw new Error(\n `Stateful agent \"${opts.name}\" tool \"${name}\" carries fold metadata. ` +\n `Folds and state-machine-driven tool filtering both try to control the ` +\n `LLM's tool view \u2014 pick one. Remove the fold or migrate this agent to ` +\n `a non-stateful AgentConfig.`,\n );\n }\n }\n };\n\n // Wrap the optional dynamic-tools factory so it threads `state` in and asserts\n // we never accidentally resolved a fold-tagged tool. Static arrays are passed\n // through unchanged.\n const wrappedTools: ToolDefinitionsInput | undefined = (() => {\n const td = opts.toolDefinitions;\n if (typeof td === 'function') {\n return async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" tools called before init`);\n }\n return td({ ...ctx, state });\n };\n }\n return td;\n })();\n\n // Wrap the handler factory into the ctx-shaped form the driver expects, and\n // validate folds on each resolve. The driver re-resolves this per tool-loop\n // iteration, so the handler set the driver dispatches against always\n // matches the LLM-visible tools for the current state \u2014 handlers don't need\n // defensive `if (!machine.matches(...))` guards.\n const wrappedHandlers: ToolHandlersInput | undefined = opts.toolHandlers\n ? async () => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" handlers called before init`);\n }\n const handlers = await opts.toolHandlers!(state);\n assertNoFolds(handlers);\n return handlers;\n }\n : undefined;\n\n const wrappedDisplayName: SystemPromptInput | undefined = opts.displayName\n ? async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" displayName called before init`);\n }\n return opts.displayName!({ ...ctx, state });\n }\n : undefined;\n\n // Function-form `provider` needs `state` injected the same way the other\n // per-turn resolvers do; the static-string form is passed through unchanged\n // and validated up-front by OrchestratingDriver.\n const wrappedProvider: ProviderInput | undefined =\n typeof opts.provider === 'function'\n ? async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" provider called before init`);\n }\n return (opts.provider as (ctx: StatefulAgentContext<S>) => string | Promise<string>)({\n ...ctx,\n state,\n });\n }\n : opts.provider;\n\n // `temperature` and `toolChoice` thread `state` in exactly like `provider`;\n // static values pass through unchanged.\n const wrappedTemperature: TemperatureInput | undefined =\n typeof opts.temperature === 'function'\n ? async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" temperature called before init`);\n }\n return (opts.temperature as (ctx: StatefulAgentContext<S>) => number | Promise<number>)({\n ...ctx,\n state,\n });\n }\n : opts.temperature;\n\n const wrappedToolChoice: ToolChoiceInput | undefined =\n typeof opts.toolChoice === 'function'\n ? async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" toolChoice called before init`);\n }\n return (\n opts.toolChoice as (\n ctx: StatefulAgentContext<S>,\n ) => ChatToolChoice | Promise<ChatToolChoice>\n )({ ...ctx, state });\n }\n : opts.toolChoice;\n\n const wrappedCachePolicy: CachePolicyInput | undefined =\n typeof opts.cachePolicy === 'function'\n ? async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" cachePolicy called before init`);\n }\n return (\n opts.cachePolicy as (ctx: StatefulAgentContext<S>) => CachePolicy | Promise<CachePolicy>\n )({ ...ctx, state });\n }\n : opts.cachePolicy;\n\n const wrappedTailContext: TailContextInput | undefined =\n typeof opts.tailContext === 'function'\n ? async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" tailContext called before init`);\n }\n return (opts.tailContext as (ctx: StatefulAgentContext<S>) => string | Promise<string>)({\n ...ctx,\n state,\n });\n }\n : opts.tailContext;\n\n // `onUnresolvedTool` threads `state` in like the resolvers above, but unlike\n // them returns `undefined` before init rather than throwing: it fires on the\n // tool-dispatch path, so a pre-init call must degrade to the framework\n // default instead of breaking dispatch.\n const wrappedOnUnresolvedTool: UnresolvedToolInput | undefined =\n typeof opts.onUnresolvedTool === 'function'\n ? async (ctx) => {\n if (!state) {\n return undefined;\n }\n return opts.onUnresolvedTool!({ ...ctx, state });\n }\n : opts.onUnresolvedTool;\n\n // `resumable` threads the LIVE state bag in (like the resolvers above) rather\n // than the serialized image the raw `AgentConfig` form receives \u2014 so a machine\n // agent gates on `state.machine.state` directly. Consulted only while active\n // (state is set); a pre-init call degrades to `true` (resumable, fail-safe).\n const wrappedResumable: AgentConfig['resumable'] | undefined = opts.resumable\n ? async (ctx: AgentPersistenceContext): Promise<boolean> => {\n if (state === undefined) return true;\n return opts.resumable!({\n agentName: ctx.agentName,\n sessionKey: ctx.sessionKey,\n messages: ctx.messages,\n isFlowOwner: ctx.isFlowOwner,\n state,\n });\n }\n : undefined;\n\n const base = {\n name: opts.name,\n displayName: wrappedDisplayName,\n primerHistory: opts.primerHistory,\n subAgents: opts.subAgents,\n manualSelection: opts.manualSelection,\n chatInputDuringExecution: opts.chatInputDuringExecution,\n toolDefinitions: wrappedTools,\n toolHandlers: wrappedHandlers,\n provider: wrappedProvider,\n temperature: wrappedTemperature,\n toolChoice: wrappedToolChoice,\n cachePolicy: wrappedCachePolicy,\n tailContext: wrappedTailContext,\n onUnresolvedTool: wrappedOnUnresolvedTool,\n resumable: wrappedResumable,\n notResumableMessage: opts.notResumableMessage,\n\n onActivate: async (ctx: AgentLifecycleContext) => {\n state = await opts.init(ctx);\n // Sample once with the init state to fail loud on fold misuse at the\n // agent-switch boundary instead of waiting for the first tool call.\n // The driver re-resolves the factory each iteration, so misuse on\n // handlers gated behind a non-init state surfaces when that state is\n // reached \u2014 same loud failure mode, narrower coverage.\n if (opts.toolHandlers) {\n const sampled = await opts.toolHandlers(state);\n assertNoFolds(sampled);\n }\n },\n\n onDeactivate: async (ctx: AgentLifecycleContext) => {\n if (state !== undefined && opts.dispose) {\n await opts.dispose({ ...ctx, state });\n }\n // Orchestrator serializes onActivate/onDeactivate; concurrent calls\n // cannot interleave the read-then-write of `state`.\n // eslint-disable-next-line require-atomic-updates\n state = undefined;\n },\n\n systemPrompt: opts.systemPrompt\n ? async (ctx: SystemPromptContext) => {\n if (!state) {\n throw new Error(`Stateful agent \"${opts.name}\" systemPrompt called before init`);\n }\n return opts.systemPrompt!({ ...ctx, state });\n }\n : undefined,\n\n // Called per LLM call by ChatDriver, and once at debug-log export time.\n // Returns `undefined` before activation (state hasn't been built yet) and\n // after deactivation (state was disposed) \u2014 the snapshotter is best-effort\n // and the driver tolerates undefined.\n getDebugSnapshot: () => {\n if (!state) return undefined;\n return opts.getDebugSnapshot\n ? opts.getDebugSnapshot(state)\n : defaultStatefulDebugSnapshot(state);\n },\n\n // Lossless restore image for session persistence (see `serialize` on the\n // config). Returns undefined before activation / after disposal.\n serialize: () => {\n if (state === undefined) return undefined;\n return opts.serialize ? opts.serialize(state) : defaultStatefulSerialize(state);\n },\n };\n\n return {\n ...base,\n description: opts.description,\n excludeFromClassifier: opts.excludeFromClassifier,\n } as AgentConfig;\n}\n", "import type { FallbackAgentConfig } from './config';\n\n/**\n * A warm, conversational fallback agent. Acknowledges it can't help directly,\n * explains what the available specialists can do, and invites the user to retry.\n *\n * The system prompt is generated at runtime by `OrchestratingDriver` from the\n * specialist list \u2014 no manual authoring required.\n *\n * @beta\n */\nexport const friendlyFallbackAgent: FallbackAgentConfig = {\n name: 'Assistant',\n fallback: true,\n systemPrompt: `You are a warm, friendly assistant. For general conversation like \"Hi\" or \"How are you\", you can have a friendly chat. For anything more complex, you cannot directly help, but you can explain what specialists are available. The available specialists are:\\n\\n{{agents}}\\n\\nPolitely let the user know what you can help with and invite them to rephrase their request if it is outside your scope.`,\n};\n\n/**\n * A brief, professional fallback agent. States what is available without\n * elaboration. The `{{agents}}` placeholder is replaced at runtime by\n * `OrchestratingDriver` with the generated specialist list.\n *\n * @beta\n */\nexport const strictFallbackAgent: FallbackAgentConfig = {\n name: 'Assistant',\n fallback: true,\n systemPrompt: `You are a concise assistant. The user's request is outside your scope. Respond with a single short sentence stating what you can assist with. Do not elaborate. The available specialists are: {{agents}}.`,\n};\n", "import type { ChatMessage } from '@genesislcap/foundation-ai';\n\n/**\n * A chat message lifted into the debug-log timeline as a `kind: 'message'` entry.\n *\n * @beta\n */\nexport type TimelineMessage = ChatMessage & {\n kind: 'message';\n /**\n * Set only on entries hoisted out of a `subAgentTrace`: the sub-agent's own\n * (un-breadcrumbed) `agentName`, kept for filtering since the displayed\n * `agentName` is rewritten to a `\"<parent> \u203A <sub-agent>\"` breadcrumb.\n */\n subAgentName?: string;\n /** Delegation depth \u2014 absent/0 for top-level, 1 for a sub-agent, 2 for a sub-agent's sub-agent, \u2026 */\n subAgentDepth?: number;\n /** Id of the parent tool call that spawned this run \u2014 correlates a hoisted message back to its delegation. */\n subAgentOf?: string;\n};\n\n/**\n * Flatten sub-agent conversations into a single top-level message stream for the\n * debug-log timeline.\n *\n * A tool call that delegates to a sub-agent carries the sub-agent's entire\n * conversation on `toolCall.subAgentTrace`. The live UI reads that nested shape,\n * but a top-to-bottom timeline reads far better with those messages inline next to\n * the turn that produced them. This walks the list and, for every tool call with a\n * `subAgentTrace`, hoists the sub-agent's messages up as their own timeline\n * entries while **removing** the nested copy from the emitted parent tool call \u2014 a\n * move, not a copy. The data is relocated, never duplicated: the export stays the\n * same size and a naive `sum(timeline[].cost)` does not double-count (the\n * canonical `sumCosts` total still reads the un-flattened history).\n *\n * Hoisted entries are:\n * - **breadcrumbed**: `agentName` becomes `\"<parent> \u203A <sub-agent>\"`, composing for\n * nested sub-agents (`\"<parent> \u203A <sub> \u203A <subsub>\"`); the raw sub-agent name is\n * preserved on `subAgentName`.\n * - **depth-tagged** (`subAgentDepth`) and **correlated** to the spawning tool call\n * (`subAgentOf`), so the delegation tree is reconstructable even when two\n * sub-agents run within the same parent turn.\n *\n * Top-level messages (depth 0) are emitted unchanged apart from the trace strip.\n * Order is preserved within each list; the caller sorts the whole timeline by\n * timestamp afterwards, and every sub-agent message carries its own timestamp, so\n * hoisted entries interleave chronologically between the parent's tool-call and\n * tool-result messages.\n *\n * @internal\n */\nexport function flattenSubAgentMessages(\n messages: readonly ChatMessage[],\n prefix = '',\n depth = 0,\n subAgentOf?: string,\n): TimelineMessage[] {\n return messages.flatMap((m) => {\n const breadcrumb = prefix ? `${prefix} \u203A ${m.agentName ?? '?'}` : m.agentName;\n const traceCalls = m.toolCalls?.filter((tc) => tc.subAgentTrace?.length) ?? [];\n\n const entry: TimelineMessage = {\n kind: 'message',\n ...m,\n // Move the (about-to-be-hoisted) child conversations out of the emitted tool\n // calls. Setting it to `undefined` drops the key from the serialized export.\n ...(traceCalls.length > 0 && {\n toolCalls: m.toolCalls!.map((tc) =>\n tc.subAgentTrace ? { ...tc, subAgentTrace: undefined } : tc,\n ),\n }),\n // Mark + breadcrumb hoisted sub-agent messages; top-level (depth 0) stays as-is.\n ...(depth > 0 && {\n agentName: breadcrumb,\n subAgentName: m.agentName,\n subAgentDepth: depth,\n subAgentOf,\n }),\n };\n\n if (traceCalls.length === 0) return [entry];\n\n const hoisted = traceCalls.flatMap((tc) =>\n flattenSubAgentMessages(tc.subAgentTrace!, breadcrumb ?? '', depth + 1, tc.id),\n );\n return [entry, ...hoisted];\n });\n}\n", "/**\n * Shared, pure builder for the debug-log timeline entries (`message` / `turn` / `event`) \u2014 the\n * common core of the host element's `buildDiagnosticEntries` and any HEADLESS consumer that drives\n * a `ChatDriver` of its own (e.g. `ai-service` running the engine server-side) and needs to harvest\n * that engine's debug log for the client to fold into its own download / persisted stream\n * (GENC-1461 unified diagnostics). DOM-clean and dependency-light so it works in bare Node.\n *\n * It deliberately excludes the `meta-snapshot` entry: that block is host/DOM-specific (it reads\n * `window.location.host`, the element's agent list, live context/cost), and a merged log keeps only\n * the newest snapshot anyway \u2014 a headless source's agent/prompt/tools are already captured in its\n * `turn` entries.\n *\n * @packageDocumentation\n */\n\nimport type { ChatMessage } from '@genesislcap/foundation-ai';\nimport { flattenSubAgentMessages } from '../../utils/flatten-sub-agent-messages';\nimport type { MetaEvent } from '../debug-event-log';\nimport type { DiagnosticEntry } from './diagnostics';\n\n/**\n * The minimal shape this builder reads off a turn snapshot. The driver's full `TurnSnapshot` is a\n * structural superset, so it assigns to this without the builder depending on the component layer.\n */\nexport interface TurnSnapshotLike {\n turnIndex: string;\n systemPrompt?: string;\n}\n\n/**\n * Build the `message` / `turn` / `event` timeline entries from a driver's pull surfaces\n * (`getRawHistory()` / `getTurnSnapshots()` / `getMetaEvents(sessionKey)`). Order within the array\n * is message \u2192 turn \u2192 event; the caller (`assembleDebugLog`) sorts the whole timeline by timestamp,\n * so this ordering only sets the co-timestamp tie-break. Pure.\n */\nexport function buildTimelineEntries(input: {\n turnSnapshots: readonly TurnSnapshotLike[];\n messages: readonly ChatMessage[];\n metaEvents: readonly MetaEvent[];\n}): DiagnosticEntry[] {\n const { turnSnapshots, messages, metaEvents } = input;\n\n // Collapse a turn's systemPrompt when byte-identical to the previous turn's \u2014 a stable agent\n // repeats the same (often multi-KB) prompt every turn, while a stateful agent's changes. The\n // prompt is shown in full whenever it changes, so prompt evolution stays visible.\n let lastFullPrompt: string | undefined;\n let lastFullIndex = '';\n const turns = turnSnapshots.map((t) => {\n let { systemPrompt } = t;\n if (systemPrompt != null && systemPrompt === lastFullPrompt) {\n systemPrompt = `<repeated \u2014 identical to turn ${lastFullIndex}>`;\n } else if (systemPrompt != null) {\n lastFullPrompt = systemPrompt;\n lastFullIndex = t.turnIndex;\n }\n return { kind: 'turn' as const, ...t, systemPrompt };\n });\n\n // Sub-agent conversations are stored nested on the parent tool call's `subAgentTrace`;\n // `flattenSubAgentMessages` hoists them to top-level `kind: 'message'` entries (breadcrumbed +\n // correlated, the nested copy moved out \u2014 not duplicated) so the timeline reads chronologically.\n const messageEntries = flattenSubAgentMessages(messages);\n const eventEntries = metaEvents.map((e) => ({ kind: 'event' as const, ...e }));\n\n return [...messageEntries, ...turns, ...eventEntries] as DiagnosticEntry[];\n}\n", "/**\n * Server-saved diagnostics (GENC-1351 \u00A75.8) \u2014 the forward-only stream that lets\n * the debug log persist across a whole session lifetime, not just the current\n * page load. This module owns the *pure* pieces: the entry type and the\n * reassembly back into the `{ readme, timeline, meta }` debug-log shape. The\n * element owns capture/cadence; the provider owns storage layout.\n *\n * @packageDocumentation\n */\n\n/**\n * One entry in the diagnostics stream \u2014 the debug-log timeline-entry union\n * (`message` / `turn` / `event`, as `getDebugLog()` builds) plus a point-in-time\n * **`meta-snapshot`** carrying the export-time `meta` block (agent summary,\n * context, active debug snapshot, \u2026). Kept permissive: a provider stores and\n * returns these opaquely, and reassembly reads only `kind`, `timestamp` (for\n * ordering), and `meta` (on a snapshot).\n *\n * @public\n */\nexport interface DiagnosticEntry {\n kind: 'message' | 'turn' | 'event' | 'meta-snapshot';\n /** ISO timestamp \u2014 string-comparable, so it orders the stream chronologically. */\n timestamp?: string;\n /** Present on `meta-snapshot` entries: the export-time `meta` block. */\n meta?: unknown;\n /**\n * Present on `meta-snapshot` entries: a stable signature of the near-static config\n * (excludes volatile timestamp/context/debug-snapshot), used by the forward-capture\n * delta to skip re-appending an unchanged block (GENC-1351 \u00A75.8). Absent on other\n * kinds and on pre-signature entries (the delta falls back to the full `meta` then).\n */\n dedupSignature?: string;\n [key: string]: unknown;\n}\n\n/** The reassembled debug log \u2014 the exact shape `getDebugLog()` returns. @public */\nexport interface DebugLog {\n readme: readonly string[];\n timeline: DiagnosticEntry[];\n meta: unknown;\n}\n\n/**\n * Stable identity for a message diagnostic entry \u2014 `timestamp::role::subAgentOf::category`.\n * Used by the forward-capture delta (skip already-emitted messages) and by the\n * restore watermark (skip messages already present in a prior load's stream).\n * `null` when the entry has no timestamp \u2192 treat as always-new. Shared so the\n * element's diagnostics capture and the `SessionPersister`'s restore watermark\n * compute identity identically (GENC-1351 \u00A75.8/\u00A75.10).\n *\n * `category` is part of the key because the reasoning/narration/answer split (GENC-1411) emits\n * SEVERAL messages from one model response \u2014 the thought summary, any interstitial narration, and\n * the answer/tool-call message \u2014 which share `timestamp` + `role` + `subAgentOf`. Keying on those\n * alone collapsed them to one, so the forward-capture dropped all but the first: a server\n * generation's answer message vanished from the persisted debug log while its reasoning survived\n * (GENC-1461). `category` is stable across a message's in-place annotation (only `toolCalls` change,\n * which is deliberately excluded), so a genuine re-append of the same message still dedups.\n *\n * @internal\n */\nexport function diagnosticsMessageKey(entry: DiagnosticEntry): string | null {\n return typeof entry.timestamp === 'string'\n ? `${entry.timestamp}::${(entry.role as string) ?? ''}::${(entry.subAgentOf as string) ?? ''}::${(entry.category as string) ?? ''}`\n : null;\n}\n\n// Tie-break co-timestamped entries by cause \u2192 call \u2192 output (event, turn, message),\n// matching the original in-place `getDebugLog` sort.\nconst KIND_RANK: Record<string, number> = { event: 0, turn: 1, message: 2 };\n// Any non-{event,turn,message} kind (shouldn't reach the timeline \u2014 meta-snapshots\n// are filtered out first) sorts last.\nconst UNKNOWN_KIND_RANK = 99;\n\n/**\n * Reassemble diagnostic entries into the `{ readme, timeline, meta }` debug-log\n * shape (GENC-1351 \u00A75.8). `timeline` = the `message`/`turn`/`event` entries sorted\n * by ISO `timestamp` (kind-rank tie-break). `meta` = the **newest** `meta-snapshot`'s\n * block only \u2014 a \"state at export\" photo, matching the single-page log. The older\n * snapshots are intentionally dropped: the per-turn evolution they would show is\n * already in the timeline (`turn.agentSnapshot` + `context.updated` events), so\n * keeping them would just repeat the bulky, near-static `agentSummary`. `readme` =\n * the passed (current) constant. Pure \u2014 reused for both the live current-page log\n * and the reassembled lifetime log stitched from the persisted stream, so both\n * come out shape-identical.\n */\nexport function assembleDebugLog(entries: DiagnosticEntry[], readme: readonly string[]): DebugLog {\n // Safety net for exact-duplicate entries: two element instances sharing one\n // session (bubble + popped-out panel) can each append the same entry, and a\n // reload's second instance can re-append restored history. Such copies are\n // byte-identical, so collapse by serialized identity \u2014 genuinely-distinct entries\n // (e.g. two real `assistant.connected` from two instances) differ in index /\n // placement and are kept. (The shared cursor store prevents most of this at\n // write time; this guards the read path regardless of what's in the stream.)\n const seen = new Set<string>();\n let latestMeta: DiagnosticEntry | undefined;\n const timeline: DiagnosticEntry[] = [];\n for (const entry of entries) {\n const id = JSON.stringify(entry);\n if (seen.has(id)) continue;\n seen.add(id);\n if (entry.kind === 'meta-snapshot') {\n if (!latestMeta || (entry.timestamp ?? '') >= (latestMeta.timestamp ?? '')) {\n latestMeta = entry;\n }\n } else {\n timeline.push(entry);\n }\n }\n timeline.sort((a, b) => {\n const ta = a.timestamp ?? '';\n const tb = b.timestamp ?? '';\n if (ta < tb) return -1;\n if (ta > tb) return 1;\n return (KIND_RANK[a.kind] ?? UNKNOWN_KIND_RANK) - (KIND_RANK[b.kind] ?? UNKNOWN_KIND_RANK);\n });\n return { readme, timeline, meta: latestMeta?.meta };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["v", "createConsola", "createConsola", "logger", "frame", "DEFAULT_MODEL", "DEFAULT_TIMEOUT", "DEFAULT_STALL_TIMEOUT", "_a", "registry", "logger", "logger", "logger", "prompt", "failureReason", "logger", "prompt"]
7
7
  }