{"version":3,"sources":["../src/errors.ts","../src/json-validation.ts","../src/primitives.ts","../src/agent-loop.ts","../src/tool-proposal-internal.ts"],"names":["DOCS_BASE","formatError","code","message","hint","docsUrl","lines","AgentsKitError","options","ToolError","ErrorCodes","cloneJsonRecord","input","invalid","maxStringLength","preflight","assertJson","root","active","stack","nodes","item","value","isArray","prototype","array","index","keys","key","descriptor","snapshot","nextId","generateId","prefix","buildMessage","params","auth","fn","call","context","m","pending","withAuthority","controller","proposal","resolve","identifier","existing","calls","operation","invalidArgs","args","tool","validateArgs","onToolCall","authorize","validation","error","current"],"mappings":"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","file":"tool-proposal-internal.cjs","sourcesContent":["// ---------------------------------------------------------------------------\n// AgentsKit didactic error system — Rust-compiler-style helpful errors\n// ---------------------------------------------------------------------------\n\nconst DOCS_BASE = 'https://www.agentskit.io/docs'\n\n/**\n * Format an error for display, Rust-compiler style.\n *\n * Example output:\n * ```\n * error[AK_ADAPTER_MISSING]: No adapter provided\n *   --> Hint: Pass an adapter when creating the chat controller, e.g.\n *             createChatController({ adapter: openai({ apiKey, model: 'gpt-4o' }) })\n *   --> Docs: https://www.agentskit.io/docs/data/providers\n * ```\n */\nfunction formatError(code: string, message: string, hint?: string, docsUrl?: string): string {\n  const lines: string[] = [`error[${code}]: ${message}`]\n  if (hint) lines.push(`  --> Hint: ${hint}`)\n  if (docsUrl) lines.push(`  --> Docs: ${docsUrl}`)\n  return lines.join('\\n')\n}\n\n// ---------------------------------------------------------------------------\n// Base class\n// ---------------------------------------------------------------------------\n\nexport class AgentsKitError extends Error {\n  readonly code: string\n  readonly hint: string | undefined\n  readonly docsUrl: string | undefined\n  readonly cause: unknown\n\n  constructor(options: {\n    code: string\n    message: string\n    hint?: string\n    docsUrl?: string\n    cause?: unknown\n  }) {\n    super(options.message)\n    this.name = 'AgentsKitError'\n    this.code = options.code\n    this.hint = options.hint\n    this.docsUrl = options.docsUrl\n    this.cause = options.cause\n  }\n\n  override toString(): string {\n    return formatError(this.code, this.message, this.hint, this.docsUrl)\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Subclasses\n// ---------------------------------------------------------------------------\n\nexport class AdapterError extends AgentsKitError {\n  constructor(options: {\n    code: string\n    message: string\n    hint?: string\n    docsUrl?: string\n    cause?: unknown\n  }) {\n    super({ docsUrl: `${DOCS_BASE}/data/providers`, ...options })\n    this.name = 'AdapterError'\n  }\n}\n\nexport class ToolError extends AgentsKitError {\n  constructor(options: {\n    code: string\n    message: string\n    hint?: string\n    docsUrl?: string\n    cause?: unknown\n  }) {\n    super({ docsUrl: `${DOCS_BASE}/agents/tools`, ...options })\n    this.name = 'ToolError'\n  }\n}\n\nexport class MemoryError extends AgentsKitError {\n  constructor(options: {\n    code: string\n    message: string\n    hint?: string\n    docsUrl?: string\n    cause?: unknown\n  }) {\n    super({ docsUrl: `${DOCS_BASE}/data/memory`, ...options })\n    this.name = 'MemoryError'\n  }\n}\n\nexport class ConfigError extends AgentsKitError {\n  constructor(options: {\n    code: string\n    message: string\n    hint?: string\n    docsUrl?: string\n    cause?: unknown\n  }) {\n    super({ docsUrl: `${DOCS_BASE}/get-started/concepts/errors`, ...options })\n    this.name = 'ConfigError'\n  }\n}\n\nexport class RuntimeError extends AgentsKitError {\n  constructor(options: {\n    code: string\n    message: string\n    hint?: string\n    docsUrl?: string\n    cause?: unknown\n  }) {\n    super({ docsUrl: `${DOCS_BASE}/agents/runtime`, ...options })\n    this.name = 'RuntimeError'\n  }\n}\n\nexport class SandboxError extends AgentsKitError {\n  constructor(options: {\n    code: string\n    message: string\n    hint?: string\n    docsUrl?: string\n    cause?: unknown\n  }) {\n    super({ docsUrl: `${DOCS_BASE}/production/security/mandatory-sandbox`, ...options })\n    this.name = 'SandboxError'\n  }\n}\n\nexport class SkillError extends AgentsKitError {\n  constructor(options: {\n    code: string\n    message: string\n    hint?: string\n    docsUrl?: string\n    cause?: unknown\n  }) {\n    super({ docsUrl: `${DOCS_BASE}/agents/skills`, ...options })\n    this.name = 'SkillError'\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Error code constants\n// ---------------------------------------------------------------------------\n\nexport const ErrorCodes = {\n  // Adapter errors\n  AK_ADAPTER_MISSING: 'AK_ADAPTER_MISSING',\n  AK_ADAPTER_STREAM_FAILED: 'AK_ADAPTER_STREAM_FAILED',\n\n  // Tool errors\n  AK_TOOL_NOT_FOUND: 'AK_TOOL_NOT_FOUND',\n  AK_TOOL_EXEC_FAILED: 'AK_TOOL_EXEC_FAILED',\n  AK_TOOL_PEER_MISSING: 'AK_TOOL_PEER_MISSING',\n  AK_TOOL_INVALID_INPUT: 'AK_TOOL_INVALID_INPUT',\n  AK_TOOL_QUOTA_EXCEEDED: 'AK_TOOL_QUOTA_EXCEEDED',\n  AK_TOOL_FORBIDDEN: 'AK_TOOL_FORBIDDEN',\n\n  // Memory errors\n  AK_MEMORY_LOAD_FAILED: 'AK_MEMORY_LOAD_FAILED',\n  AK_MEMORY_SAVE_FAILED: 'AK_MEMORY_SAVE_FAILED',\n  AK_MEMORY_DESERIALIZE_FAILED: 'AK_MEMORY_DESERIALIZE_FAILED',\n  AK_MEMORY_PEER_MISSING: 'AK_MEMORY_PEER_MISSING',\n  AK_MEMORY_REMOTE_HTTP: 'AK_MEMORY_REMOTE_HTTP',\n\n  // Config errors\n  AK_CONFIG_INVALID: 'AK_CONFIG_INVALID',\n\n  // Runtime errors\n  AK_RUNTIME_INVALID_INPUT: 'AK_RUNTIME_INVALID_INPUT',\n  AK_RUNTIME_STEP_FAILED: 'AK_RUNTIME_STEP_FAILED',\n  AK_RUNTIME_DELEGATE_FAILED: 'AK_RUNTIME_DELEGATE_FAILED',\n\n  // Sandbox errors\n  AK_SANDBOX_DENIED: 'AK_SANDBOX_DENIED',\n  AK_SANDBOX_INVALID_TOOL: 'AK_SANDBOX_INVALID_TOOL',\n  AK_SANDBOX_PEER_MISSING: 'AK_SANDBOX_PEER_MISSING',\n  AK_SANDBOX_BACKEND_FAILED: 'AK_SANDBOX_BACKEND_FAILED',\n\n  // Skill errors\n  AK_SKILL_INVALID: 'AK_SKILL_INVALID',\n  AK_SKILL_DUPLICATE: 'AK_SKILL_DUPLICATE',\n} as const\n","export function cloneJsonRecord(\n  input: unknown,\n  invalid: () => never,\n  maxStringLength = Infinity,\n  preflight = true,\n): Record<string, unknown> {\n  const assertJson = (root: unknown): void => {\n    const active = new WeakSet<object>()\n    const stack: Array<{ value: unknown; depth: number; exit?: boolean }> = [{ value: root, depth: 0 }]\n    let nodes = 0\n    while (stack.length > 0) {\n      const item = stack.pop()!\n      const value = item.value\n      if (item.exit) { active.delete(value as object); continue }\n      if (++nodes > 10_000 || item.depth > 32) invalid()\n      if (value === null || typeof value === 'boolean') continue\n      if (typeof value === 'string') { if (value.length > maxStringLength) invalid(); continue }\n      if (typeof value === 'number') { if (!Number.isFinite(value)) invalid(); continue }\n      if (typeof value !== 'object') invalid()\n      const isArray = Array.isArray(value)\n      const prototype = isArray ? Array.prototype : Object.getPrototypeOf(value) as unknown\n      if (!isArray && prototype !== Object.prototype && prototype !== null) invalid()\n      if (active.has(value)) invalid()\n      active.add(value)\n      stack.push({ value, depth: item.depth, exit: true })\n      if (isArray) {\n        const array = value as unknown[]\n        if (array.length > 10_000) invalid()\n        for (let index = array.length - 1; index >= 0; index--) {\n          stack.push({ value: array[index], depth: item.depth + 1 })\n        }\n        continue\n      }\n      const keys = Object.keys(value)\n      if (keys.length > 10_000) invalid()\n      for (let index = keys.length - 1; index >= 0; index--) {\n        const key = keys[index]!\n        if (key.length > 256) invalid()\n        const descriptor = Object.getOwnPropertyDescriptor(value, key)\n        if (!descriptor || descriptor.get || descriptor.set) invalid()\n        stack.push({ value: descriptor.value, depth: item.depth + 1 })\n      }\n    }\n  }\n  try {\n    if (preflight) assertJson(input)\n    const snapshot = structuredClone(input) as unknown\n    assertJson(snapshot)\n    if (typeof snapshot !== 'object' || snapshot === null || Array.isArray(snapshot)) invalid()\n    return snapshot as Record<string, unknown>\n  } catch {\n    return invalid()\n  }\n}\n","import { AdapterError, AgentsKitError, ErrorCodes } from './errors'\nimport type {\n  AgentEvent,\n  Message,\n  MessageRole,\n  MessageStatus,\n  Observer,\n  StreamChunk,\n  StreamSource,\n  ToolDefinition,\n  ToolExecutionContext,\n} from './types'\nimport type { TokenUsage } from './types/stream'\n\nlet nextId = 0\n\nexport function generateId(prefix: string): string {\n  return `${prefix}-${Date.now()}-${nextId++}`\n}\n\nexport function createEventEmitter() {\n  const observers = new Set<Observer>()\n\n  return {\n    addObserver(observer: Observer): () => void {\n      observers.add(observer)\n      return () => { observers.delete(observer) }\n    },\n    emit(event: AgentEvent): void {\n      for (const observer of observers) {\n        try {\n          const result = observer.on(event)\n          if (result && typeof (result as Promise<void>).catch === 'function') {\n            (result as Promise<void>).catch(() => {})\n          }\n        } catch {\n          // Observer errors must never break the main loop.\n        }\n      }\n    },\n  }\n}\n\nexport function buildMessage(params: {\n  role: MessageRole\n  content: string\n  status?: MessageStatus\n  metadata?: Record<string, unknown>\n  toolCallId?: string\n}): Message {\n  return {\n    id: generateId('msg'),\n    role: params.role,\n    content: params.content,\n    status: params.status ?? 'complete',\n    metadata: params.metadata,\n    toolCallId: params.toolCallId,\n    createdAt: new Date(),\n  }\n}\n\nfunction isAsyncIterable(value: unknown): value is AsyncIterable<unknown> {\n  return value != null && typeof value === 'object' && Symbol.asyncIterator in value\n}\n\nfunction serializeToolResult(result: unknown): string {\n  if (result == null) return ''\n  if (typeof result === 'string' || result instanceof Error) return String(result)\n\n  try {\n    return JSON.stringify(result) ?? String(result)\n  } catch {\n    return String(result)\n  }\n}\n\nexport async function executeToolCall(\n  tool: ToolDefinition,\n  args: Record<string, unknown>,\n  context: ToolExecutionContext,\n  onPartialResult?: (accumulated: string) => void,\n): Promise<string> {\n  const raw = tool.execute?.(args, context)\n\n  if (isAsyncIterable(raw)) {\n    let accumulated = ''\n    for await (const chunk of raw) {\n      accumulated += String(chunk)\n      onPartialResult?.(accumulated)\n    }\n    return accumulated\n  }\n\n  const result = await raw\n  return serializeToolResult(result)\n}\n\nexport function safeParseArgs(args: string): Record<string, unknown> {\n  try {\n    const parsed = JSON.parse(args)\n    return parsed && typeof parsed === 'object' ? (parsed as Record<string, unknown>) : {}\n  } catch {\n    return {}\n  }\n}\n\ninterface ToolLifecycleState {\n  initialized: Set<string>\n  initializing: Map<string, Promise<void>>\n  activeExecutions: number\n  retired: boolean\n  disposal: Promise<void> | undefined\n  retirement: Promise<void> | undefined\n  resolveRetirement: (() => void) | undefined\n  tools: Map<string, ToolDefinition>\n}\n\nconst lifecycleStates = new WeakMap<object, ToolLifecycleState>()\n\nfunction retirementPromise(state: ToolLifecycleState): Promise<void> {\n  if (!state.retirement) {\n    state.retirement = new Promise<void>(resolve => {\n      state.resolveRetirement = resolve\n    })\n  }\n  return state.retirement\n}\n\nfunction scheduleLifecycleDisposal(state: ToolLifecycleState): void {\n  if (\n    !state.retired\n    || state.activeExecutions > 0\n    || state.initializing.size > 0\n    || state.disposal\n  ) return\n\n  state.disposal = (async () => {\n    const names = [...state.initialized]\n    state.initialized.clear()\n    for (const name of names) {\n      try {\n        await state.tools.get(name)?.dispose?.()\n      } catch {\n        // Dispose errors should not propagate.\n      }\n    }\n  })().finally(() => {\n    state.disposal = undefined\n    state.resolveRetirement?.()\n    state.resolveRetirement = undefined\n  })\n}\n\nexport function createToolLifecycle(tools: Map<string, ToolDefinition>) {\n  const state: ToolLifecycleState = {\n    initialized: new Set<string>(),\n    initializing: new Map<string, Promise<void>>(),\n    activeExecutions: 0,\n    retired: false,\n    disposal: undefined,\n    retirement: undefined,\n    resolveRetirement: undefined,\n    tools,\n  }\n\n  const lifecycle = {\n    async init(tool: ToolDefinition): Promise<void> {\n      // A retired lifecycle cannot start new work. An execution that acquired\n      // it before retirement may still finish initialization safely.\n      if (state.retired && state.activeExecutions === 0) return\n      if (!tool.init || state.initialized.has(tool.name)) return\n\n      const pending = state.initializing.get(tool.name)\n      if (pending) {\n        await pending\n        return\n      }\n\n      const initialization = (async () => {\n        await tool.init?.()\n        state.initialized.add(tool.name)\n      })()\n      state.initializing.set(tool.name, initialization)\n      try {\n        await initialization\n      } finally {\n        state.initializing.delete(tool.name)\n        scheduleLifecycleDisposal(state)\n      }\n    },\n    async disposeAll(): Promise<void> {\n      state.retired = true\n      const completion = retirementPromise(state)\n      scheduleLifecycleDisposal(state)\n      await completion\n    },\n  }\n\n  lifecycleStates.set(lifecycle, state)\n  return lifecycle\n}\n\n/** Hold a lifecycle open for one tool execution without changing its public shape. */\nexport function acquireToolLifecycle(\n  lifecycle: ReturnType<typeof createToolLifecycle>,\n): (() => Promise<void>) | undefined {\n  const state = lifecycleStates.get(lifecycle)\n  if (!state || state.retired) return undefined\n\n  state.activeExecutions++\n  let released = false\n  return async () => {\n    if (released) return\n    released = true\n    state.activeExecutions--\n    scheduleLifecycleDisposal(state)\n    if (state.retirement) await state.retirement\n  }\n}\n\nexport interface ConsumeStreamHandlers {\n  onText?: (accumulated: string) => void\n  onReasoning?: (accumulated: string) => void\n  onToolCall?: (chunk: StreamChunk) => Promise<void> | void\n  onToolResult?: (content: string) => void\n  onUsage?: (usage: TokenUsage) => void\n  onError?: (error: Error) => void\n  onDone: (accumulatedText: string) => void\n}\n\nexport async function consumeStream(\n  source: StreamSource,\n  handlers: ConsumeStreamHandlers,\n): Promise<void> {\n  let accumulatedText = ''\n  let accumulatedReasoning = ''\n\n  try {\n    const iterator = source.stream()\n    for await (const chunk of iterator) {\n      if (chunk.type === 'text' && chunk.content) {\n        accumulatedText += chunk.content\n        handlers.onText?.(accumulatedText)\n      } else if (chunk.type === 'reasoning' && chunk.content) {\n        accumulatedReasoning += chunk.content\n        handlers.onReasoning?.(accumulatedReasoning)\n      } else if (chunk.type === 'tool_call') {\n        await handlers.onToolCall?.(chunk)\n      } else if (chunk.type === 'tool_result' && chunk.content) {\n        handlers.onToolResult?.(chunk.content)\n      } else if (chunk.type === 'usage' && chunk.usage) {\n        handlers.onUsage?.(chunk.usage)\n      } else if (chunk.type === 'error') {\n        handlers.onError?.(new AdapterError({\n          code: ErrorCodes.AK_ADAPTER_STREAM_FAILED,\n          message: chunk.content ?? 'Stream error',\n          hint: 'Key/network/model/provider',\n        }))\n        return\n      } else if (chunk.type === 'done') {\n        break\n      }\n    }\n    handlers.onDone(accumulatedText)\n  } catch (error) {\n    const detail = error instanceof Error ? error.message : String(error)\n    const err = error instanceof AgentsKitError\n      ? error\n      : new AdapterError({\n          code: ErrorCodes.AK_ADAPTER_STREAM_FAILED,\n          message: `Stream failed: ${detail}`,\n          hint: 'Adapter/provider',\n          cause: error,\n        })\n    handlers.onError?.(err)\n  }\n}\n","import { ToolError, ErrorCodes } from './errors'\nimport { acquireToolLifecycle, executeToolCall, createToolLifecycle, createEventEmitter } from './primitives'\nimport type {\n  ArgsValidator,\n  MaybePromise,\n  SkillDefinition,\n  ToolCall,\n  ToolAuthorizationContext,\n  ToolAuthorizer,\n  ToolDefinition,\n  ToolExecutionContext,\n} from './types'\n\n// --- buildToolMap ---\n\nexport function buildToolMap(\n  ...sources: Array<ToolDefinition[] | undefined>\n): Map<string, ToolDefinition> {\n  const map = new Map<string, ToolDefinition>()\n  for (const source of sources) {\n    if (!source) continue\n    for (const tool of source) map.set(tool.name, tool)\n  }\n  return map\n}\n\n// --- activateSkills ---\n\nexport interface ActivateSkillsResult {\n  systemPrompt: string | undefined\n  skillTools: ToolDefinition[]\n}\n\nexport async function activateSkills(\n  skills: SkillDefinition[],\n  prompt?: string,\n): Promise<ActivateSkillsResult> {\n  if (skills.length === 0) {\n    return { systemPrompt: prompt, skillTools: [] }\n  }\n\n  const prompts = skills.map(s => `--- ${s.name} ---\\n${s.systemPrompt}`)\n  const base = prompt ? `${prompt}\\n\\n` : ''\n  const system = `${base}${prompts.join('\\n\\n')}`\n\n  const tools: ToolDefinition[] = []\n  for (const skill of skills) {\n    if (skill.onActivate) {\n      const a = await skill.onActivate()\n      tools.push(...(a.tools ?? []))\n    }\n  }\n\n  return { systemPrompt: system, skillTools: tools }\n}\n\n// --- executeSafeTool ---\n\nexport interface ToolExecResult {\n  status: 'complete' | 'error' | 'skipped'\n  result?: string\n  error?: string\n  durationMs: number\n}\n\nexport interface ExecuteSafeToolOptions {\n  tool: ToolDefinition | undefined\n  toolCall: ToolCall\n  context: ToolExecutionContext\n  emitter: ReturnType<typeof createEventEmitter>\n  lifecycle: ReturnType<typeof createToolLifecycle>\n  onPartial?: (result: string) => void\n  onConfirm?: (toolCall: ToolCall) => MaybePromise<boolean>\n  /** Opt-in arg validation against `tool.schema` (ADR-0008). */\n  validate?: ArgsValidator\n  authorize?: ToolAuthorizer\n}\n\nexport async function auth(fn: ToolAuthorizer | undefined, call: ToolCall, context: ToolAuthorizationContext): Promise<void> {\n  if (!fn) return\n  await import('./tool-authorization-internal.js').then(m => m.authorize(fn, call, context))\n}\n\n\nexport async function executeSafeTool(\n  options: ExecuteSafeToolOptions,\n): Promise<ToolExecResult> {\n  const { tool, toolCall, context, emitter, lifecycle, onPartial, onConfirm, validate, authorize } = options\n  const began = Date.now()\n\n  // Missing tool\n  if (!tool?.execute) {\n    const err = new ToolError({\n      code: ErrorCodes.AK_TOOL_NOT_FOUND,\n      message: `Tool \"${toolCall.name}\" not found or has no execute function`,\n      hint: 'Register an executable tool in ChatConfig, e.g. { tools: [myTool] }.',\n    })\n    emitter.emit({ type: 'error', error: err })\n    return { status: 'error', error: err.toString(), durationMs: Date.now() - began }\n  }\n\n  if (validate && tool.schema) {\n    const v = validate(tool.schema, toolCall.args)\n    if (!v.valid) {\n      const err = new ToolError({\n        code: ErrorCodes.AK_TOOL_INVALID_INPUT,\n        message: v.message ?? `Tool \"${toolCall.name}\" received invalid arguments`,\n      })\n      emitter.emit({ type: 'error', error: err })\n      return { status: 'error', error: err.toString(), durationMs: Date.now() - began }\n    }\n  }\n\n  // Requires confirmation — refuse by default when no approver is configured (RT6)\n  if (tool.requiresConfirmation) {\n    if (!onConfirm) {\n      return {\n        status: 'skipped',\n        result: 'No confirmation handler',\n        durationMs: Date.now() - began,\n      }\n    }\n    const confirmed = await onConfirm(toolCall)\n    if (!confirmed) {\n      return { status: 'skipped', result: 'Tool execution declined by confirmation handler', durationMs: Date.now() - began }\n    }\n  }\n\n  try {\n    await auth(authorize, toolCall, { ...context, tool, phase: 'execute' })\n  } catch (error) {\n    const err = error as ToolError\n    emitter.emit({ type: 'error', error: err })\n    return { status: 'error', error: err.toString(), durationMs: Date.now() - began }\n  }\n\n  const releaseLifecycle = acquireToolLifecycle(lifecycle)\n  if (!releaseLifecycle) {\n    return {\n      status: 'skipped',\n      result: 'Tool execution superseded by a configuration update',\n      durationMs: Date.now() - began,\n    }\n  }\n\n  try {\n    await lifecycle.init(tool)\n  } catch (error) {\n    await releaseLifecycle()\n    throw error\n  }\n\n  emitter.emit({ type: 'tool:start', name: toolCall.name, args: toolCall.args })\n\n  try {\n    const result = await executeToolCall(\n      tool,\n      toolCall.args,\n      context,\n      onPartial,\n    )\n    emitter.emit({\n      type: 'tool:end',\n      name: toolCall.name,\n      result,\n      durationMs: Date.now() - began,\n    })\n    return { status: 'complete', result, durationMs: Date.now() - began }\n  } catch (error) {\n    const detail = error instanceof Error ? error.message : String(error)\n    const err = error instanceof ToolError\n      ? error\n      : new ToolError({\n          code: ErrorCodes.AK_TOOL_EXEC_FAILED,\n          message: `Tool \"${toolCall.name}\" threw during execution: ${detail}`,\n          hint: 'Check the tool execute() implementation.',\n          cause: error,\n        })\n    // Emit error before tool:end so trackers can mark the active tool span.\n    emitter.emit({ type: 'error', error: err })\n    emitter.emit({\n      type: 'tool:end',\n      name: toolCall.name,\n      result: `Error: ${err.message}`,\n      durationMs: Date.now() - began,\n    })\n    return { status: 'error', error: err.toString(), durationMs: Date.now() - began }\n  } finally {\n    await releaseLifecycle()\n  }\n}\n","import { ErrorCodes, ToolError } from './errors'\nimport { cloneJsonRecord } from './json-validation'\nimport { buildMessage } from './primitives'\nimport { auth } from './agent-loop'\nimport type { ArgsValidator, ChatController, MaybePromise, ToolAuthorizer, ToolCall, ToolCallHandlerContext, ToolDefinition } from './types'\n\ntype Proposal = Pick<ToolCall, 'id' | 'name' | 'args'>\ntype Authority = readonly [\n  ToolDefinition | undefined,\n  ArgsValidator | undefined,\n  ((toolCall: ToolCall, context: ToolCallHandlerContext) => MaybePromise<void>) | undefined,\n  ToolAuthorizer | undefined,\n]\nconst pending = new WeakMap<ChatController, Map<string, Promise<ToolCall>>>()\n\nexport async function withAuthority(\n  controller: ChatController,\n  proposal: Proposal,\n  resolve: (name: string) => Authority,\n): Promise<ToolCall> {\n  const identifier = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/\n  if (!identifier.test(proposal.id)) {\n    throw new ToolError({ code: ErrorCodes.AK_TOOL_INVALID_INPUT, message: 'Invalid tool proposal identity' })\n  }\n  for (const message of controller.getState().messages) {\n    const existing = message.toolCalls?.find(call => call.id === proposal.id)\n    if (existing) return existing\n  }\n  let calls = pending.get(controller)\n  if (!calls) { calls = new Map(); pending.set(controller, calls) }\n  const active = calls.get(proposal.id)\n  if (active) return active\n  const operation = (async () => {\n  if (!identifier.test(proposal.name)) {\n    throw new ToolError({ code: ErrorCodes.AK_TOOL_INVALID_INPUT, message: 'Invalid tool proposal identity' })\n  }\n  const invalidArgs = (): never => {\n    throw new ToolError({ code: ErrorCodes.AK_TOOL_INVALID_INPUT, message: 'Invalid tool proposal arguments' })\n  }\n  const args = cloneJsonRecord(proposal.args, invalidArgs, 16_384)\n  const [tool, validateArgs, onToolCall, authorize] = resolve(proposal.name)\n  if (!tool?.requiresConfirmation || !tool.execute) {\n    throw new ToolError({\n      code: tool ? ErrorCodes.AK_CONFIG_INVALID : ErrorCodes.AK_TOOL_NOT_FOUND,\n      message: 'Tool is not registered for confirmation',\n    })\n  }\n  if (validateArgs && tool.schema) {\n    const validation = validateArgs(tool.schema, args)\n    if (!validation.valid) {\n      throw new ToolError({\n        code: ErrorCodes.AK_TOOL_INVALID_INPUT,\n        message: validation.message ?? 'Invalid tool arguments',\n      })\n    }\n  }\n  const call: ToolCall = { ...proposal, args, status: 'requires_confirmation' }\n  await auth(authorize, call, { messages: controller.getState().messages, tool, phase: 'propose' })\n  const message = { ...buildMessage({ role: 'assistant', content: '' }), toolCalls: [call] }\n  controller.setMessages([...controller.getState().messages, message])\n  try {\n    await onToolCall?.(call, { messages: controller.getState().messages, tool })\n  } catch (error) {\n    controller.setMessages(controller.getState().messages.map(current => current.id !== message.id ? current : {\n      ...current,\n      toolCalls: current.toolCalls?.map(existing => existing.id !== call.id ? existing : {\n        ...existing,\n        status: 'error',\n        error: error instanceof Error ? error.message : 'Tool proposal rejected',\n      }),\n    }))\n    throw error\n  }\n  return call\n  })()\n  calls.set(proposal.id, operation)\n  try { return await operation } finally { calls.delete(proposal.id) }\n}\n"]}