{"version":3,"sources":["../src/index.ts","../src/tools.ts","../src/json-extract.ts","../src/schema.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport {\n  Middleware,\n  RunAgentInput,\n  AbstractAgent,\n  BaseEvent,\n  EventType,\n  Message,\n  AssistantMessage,\n  ToolMessage,\n  ToolCall,\n  ActivitySnapshotEvent,\n  ToolCallResultEvent,\n  ToolCallStartEvent,\n  ToolCallArgsEvent,\n  Tool,\n} from \"@ag-ui/client\";\nimport { Observable } from \"rxjs\";\n\nimport {\n  A2UIMiddlewareConfig,\n  A2UIForwardedProps,\n  A2UIUserAction,\n} from \"./types\";\nimport { RENDER_A2UI_TOOL, RENDER_A2UI_TOOL_NAME, RENDER_A2UI_TOOL_GUIDELINES, LOG_A2UI_EVENT_TOOL_NAME } from \"./tools\";\nimport { getOperationSurfaceId, tryParseA2UIOperations, A2UI_OPERATIONS_KEY, extractCompleteItemsWithStatus, extractCompleteObject, extractDataArrayItems, extractStringField } from \"./schema\";\nimport { validateA2UIComponents, MAX_A2UI_ATTEMPTS, type A2UIValidationCatalog } from \"@ag-ui/a2ui-toolkit\";\n\n/**\n * Detect a structured hard-failure envelope produced by the toolkit's recovery\n * loop when it exhausts its retries, so the middleware can surface a (client-\n * rendered) failure instead of silently dropping it.\n */\nfunction tryParseRecoveryFailure(content: unknown): { error: string; attempts: unknown } | null {\n  if (typeof content !== \"string\") return null;\n  try {\n    const parsed = JSON.parse(content);\n    if (parsed && typeof parsed === \"object\" && (parsed as any).code === \"a2ui_recovery_exhausted\") {\n      return { error: String((parsed as any).error ?? \"A2UI generation failed\"), attempts: (parsed as any).attempts ?? [] };\n    }\n  } catch {\n    // not JSON — nothing to surface\n  }\n  return null;\n}\n\n// Re-exports\nexport * from \"./types\";\nexport * from \"./tools\";\nexport * from \"./schema\";\n\n/**\n * Activity type for A2UI surface events\n */\nexport const A2UIActivityType = \"a2ui-surface\";\n\n/**\n * Context description used to identify the A2UI component schema in RunAgentInput.context.\n * The LangGraph connector uses this to extract the schema from context and inject it\n * into the agent's key/value state instead of the system prompt.\n */\nexport const A2UI_SCHEMA_CONTEXT_DESCRIPTION = \"A2UI Component Schema — available components for generating UI surfaces. Use these component names and properties when creating A2UI operations.\";\n\n/**\n * Read the catalog id the frontend registered, from the A2UI schema context\n * entry it ships on every run.\n *\n * The renderer sends `{ description: A2UI_SCHEMA_CONTEXT_DESCRIPTION, value:\n * JSON.stringify({ catalogId, components }) }` as agent context (so the model\n * knows the available components). The `catalogId` in that payload is, by\n * construction, the id of the catalog the renderer actually registered — so a\n * `createSurface` stamped with it provably resolves on the client.\n *\n * Used as the catalog fallback when the host did NOT configure an explicit\n * `defaultCatalogId`, so a zero-config app whose only catalog declaration is the\n * frontend `<CopilotKit a2ui={{ catalog }}>` never hits \"Catalog not found\".\n *\n * Returns undefined when the entry is absent or unparseable (the caller then\n * falls back to the streamed/basic catalog as before).\n */\nfunction extractFrontendCatalogId(input: RunAgentInput): string | undefined {\n  const entry = (input.context || []).find(\n    (c) => c.description === A2UI_SCHEMA_CONTEXT_DESCRIPTION,\n  );\n  if (!entry || typeof entry.value !== \"string\") return undefined;\n  try {\n    const parsed = JSON.parse(entry.value);\n    const id = (parsed as { catalogId?: unknown } | null)?.catalogId;\n    return typeof id === \"string\" && id.length > 0 ? id : undefined;\n  } catch {\n    return undefined;\n  }\n}\n\n/**\n * Extract EventWithState type from Middleware.runNextWithState return type\n */\ntype ExtractObservableType<T> = T extends Observable<infer U> ? U : never;\ntype RunNextWithStateReturn = ReturnType<Middleware[\"runNextWithState\"]>;\ntype EventWithState = ExtractObservableType<RunNextWithStateReturn>;\n\n/**\n * Derive the repeated-data array key from a component set.\n *\n * A2UI \"list\" surfaces repeat one template component over an array in the data\n * model via structural children: `children: { componentId, path: \"/items\" }`.\n * The data key is that path with its leading slash stripped (e.g. \"items\").\n *\n * Returns the first such key found, or null when no structural repeat exists\n * (e.g. a form or static composition), in which case the caller falls back to\n * a sensible default and/or the final whole-object data emit.\n */\nfunction deriveRepeatedDataKey(components: Array<Record<string, unknown>>): string | null {\n  for (const comp of components) {\n    const children = (comp as any)?.children;\n    if (\n      children &&\n      typeof children === \"object\" &&\n      !Array.isArray(children) &&\n      typeof children.path === \"string\" &&\n      children.path.length > 0\n    ) {\n      return children.path.replace(/^\\//, \"\");\n    }\n  }\n  return null;\n}\n\n/**\n * A2UI Middleware - Enables AG-UI agents to render A2UI surfaces\n * and handles bidirectional communication of user actions.\n */\nexport class A2UIMiddleware extends Middleware {\n  private config: A2UIMiddlewareConfig;\n\n  constructor(config: A2UIMiddlewareConfig = {}) {\n    super();\n    this.config = config;\n  }\n\n  /**\n   * Extract the inline catalog (component name → JSON Schema with `required`)\n   * for semantic validation, when one is configured. Returns undefined for the\n   * legacy array form or no schema — validation then degrades to structural-only.\n   */\n  private getValidationCatalog(): A2UIValidationCatalog | undefined {\n    const schema = this.config.schema;\n    if (\n      schema &&\n      !Array.isArray(schema) &&\n      schema.components &&\n      Object.keys(schema.components).length > 0\n    ) {\n      return { components: schema.components as A2UIValidationCatalog[\"components\"] };\n    }\n    return undefined;\n  }\n\n  /**\n   * Build a pre-paint lifecycle snapshot for the `a2ui-surface` activity (OSS-162).\n   *\n   * The WHOLE generative-UI lifecycle rides ONE stable messageId\n   * (`a2ui-surface-${key}`, key = outer call): `status: \"building\" | \"retrying\" |\n   * \"failed\"` pre-paint, then `a2ui_operations` on paint. Because every state\n   * `replace`s the same messageId, the painted surface supersedes the skeleton in\n   * place — no separate \"resolved\" signal, and never more than one loader.\n   *\n   * The lifecycle metadata lives on the AG-UI activity-content WRAPPER, never\n   * inside an A2UI envelope (the `a2ui_operations` elements stay strictly\n   * `{ version, <one op> }`, per the v0.9 envelope spec).\n   *\n   * `debugExposure` is stamped from server config so the client renderer honors\n   * it; applies to all wrapped agents (Python + TS) since this middleware is the\n   * single emitter.\n   */\n  private buildLifecycleActivity(key: string, content: Record<string, unknown>): ActivitySnapshotEvent {\n    const debugExposure = this.config.recovery?.debugExposure;\n    return {\n      type: EventType.ACTIVITY_SNAPSHOT,\n      messageId: `a2ui-surface-${key}`,\n      activityType: A2UIActivityType,\n      content: debugExposure ? { ...content, debugExposure } : content,\n      replace: true,\n    };\n  }\n\n  /**\n   * Main middleware run method\n   */\n  run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n    // Capture the frontend-registered catalog id BEFORE injectSchemaContext may\n    // replace the frontend schema entry with a server-side one — we want the id\n    // of the catalog the renderer actually registered, used as the zero-config\n    // catalog fallback when no `defaultCatalogId` is configured (see\n    // extractFrontendCatalogId and the catalogId resolution in processStream).\n    const frontendCatalogId = extractFrontendCatalogId(input);\n\n    // Process user action from forwardedProps (append synthetic messages)\n    const enhancedInput = this.processUserAction(input);\n\n    // Inject A2UI component schema as context so agents know what components are available\n    const withSchema = this.injectSchemaContext(enhancedInput);\n\n    // Conditionally inject the render_a2ui tool and its usage guidelines\n    const finalInput = this.config.injectA2UITool\n      ? this.injectToolGuidelines(this.injectToolAndFlag(withSchema))\n      : withSchema;\n\n    // Process the event stream using runNextWithState for automatic message tracking\n    return this.processStream(this.runNextWithState(finalInput, next), frontendCatalogId);\n  }\n\n  /**\n   * Inject the A2UI component schema into RunAgentInput.context.\n   * This makes the schema available to agents as a context entry,\n   * similar to how useAgentContext propagates application context.\n   *\n   * If the frontend already provided a schema context entry (via includeSchema),\n   * the server-side schema replaces it.\n   */\n  private injectSchemaContext(input: RunAgentInput): RunAgentInput {\n    if (!this.config.schema) {\n      return input;\n    }\n    // Empty check: array → length, inline catalog → no components\n    const isEmpty = Array.isArray(this.config.schema)\n      ? this.config.schema.length === 0\n      : Object.keys(this.config.schema.components ?? {}).length === 0;\n    if (isEmpty) {\n      return input;\n    }\n\n    const schemaContext = {\n      description: A2UI_SCHEMA_CONTEXT_DESCRIPTION,\n      value: JSON.stringify(this.config.schema),\n    };\n\n    // Replace any existing entry with the same description (e.g. from the frontend)\n    const filtered = (input.context || []).filter(\n      (c) => c.description !== A2UI_SCHEMA_CONTEXT_DESCRIPTION,\n    );\n\n    return {\n      ...input,\n      context: [...filtered, schemaContext],\n    };\n  }\n\n  /**\n   * Check forwardedProps for a2uiAction and append synthetic tool call messages\n   */\n  private processUserAction(input: RunAgentInput): RunAgentInput {\n    const forwardedProps = input.forwardedProps as A2UIForwardedProps | undefined;\n    const userAction = forwardedProps?.a2uiAction?.userAction;\n\n    if (!userAction) {\n      return input;\n    }\n\n    // Generate IDs for the synthetic messages\n    const assistantMessageId = randomUUID();\n    const toolCallId = randomUUID();\n    const toolMessageId = randomUUID();\n\n    // Create synthetic assistant message with tool call\n    const syntheticAssistantMessage: AssistantMessage = {\n      id: assistantMessageId,\n      role: \"assistant\",\n      content: \"\",\n      toolCalls: [\n        {\n          id: toolCallId,\n          type: \"function\",\n          function: {\n            name: LOG_A2UI_EVENT_TOOL_NAME,\n            arguments: JSON.stringify(userAction),\n          },\n        },\n      ],\n    };\n\n    // Create synthetic tool result message\n    const resultContent = this.formatUserActionResult(userAction);\n    const syntheticToolMessage: ToolMessage = {\n      id: toolMessageId,\n      role: \"tool\",\n      toolCallId: toolCallId,\n      content: resultContent,\n    };\n\n    // Append synthetic messages to existing messages (so they appear as the latest action)\n    const messages: Message[] = [\n      ...(input.messages || []),\n      syntheticAssistantMessage,\n      syntheticToolMessage,\n    ];\n\n    return {\n      ...input,\n      messages,\n    };\n  }\n\n  /**\n   * Format the user action result message for the agent\n   */\n  private formatUserActionResult(action: A2UIUserAction): string {\n    const actionName = action.name ?? \"unknown_action\";\n    const surfaceId = action.surfaceId ?? \"unknown_surface\";\n    const componentId = action.sourceComponentId;\n    const contextStr = action.context ? JSON.stringify(action.context) : \"{}\";\n\n    let message = `User performed action \"${actionName}\" on surface \"${surfaceId}\"`;\n    if (componentId) {\n      message += ` (component: ${componentId})`;\n    }\n    message += `. Context: ${contextStr}`;\n    return message;\n  }\n\n  /**\n   * Inject the A2UI rendering tool + the \"injectA2UITool\" flag into the input.\n   * Uses the configured name from `injectA2UITool` (string) or defaults to \"render_a2ui\".\n   * Always replaces the tool if it already exists to ensure the correct parameter schema.\n   */\n  private injectToolAndFlag(input: RunAgentInput): RunAgentInput {\n    const toolName = typeof this.config.injectA2UITool === \"string\"\n      ? this.config.injectA2UITool\n      : RENDER_A2UI_TOOL_NAME;\n    const tool: Tool = { ...RENDER_A2UI_TOOL, name: toolName };\n    // Guard against undefined ``input.tools`` — the AG-UI shape allows it.\n    const filteredTools = (input.tools ?? []).filter((t) => t.name !== toolName);\n    return {\n      ...input,\n      forwardedProps: {\n        ...(input.forwardedProps ?? {}),\n        injectA2UITool: this.config.injectA2UITool,\n      },\n      tools: [...filteredTools, tool],\n    };\n  }\n\n  /**\n   * Inject usage guidelines for the render_a2ui tool as a context entry.\n   * Provides the LLM with protocol instructions and a minimal example so it\n   * can produce valid A2UI without agent-specific prompting.\n   */\n  private injectToolGuidelines(input: RunAgentInput): RunAgentInput {\n    const toolName = typeof this.config.injectA2UITool === \"string\"\n      ? this.config.injectA2UITool\n      : RENDER_A2UI_TOOL_NAME;\n\n    const guidelinesDescription =\n      `A2UI render tool usage guide — how to call ${toolName} with valid arguments.`;\n\n    // Remove any existing guidelines entry to avoid duplication\n    const filtered = (input.context || []).filter(\n      (c) => c.description !== guidelinesDescription,\n    );\n\n    return {\n      ...input,\n      context: [...filtered, {\n        description: guidelinesDescription,\n        value: RENDER_A2UI_TOOL_GUIDELINES(toolName),\n      }],\n    };\n  }\n\n  /**\n   * Process the event stream, holding back RUN_FINISHED to process pending A2UI tool calls.\n   * Uses runNextWithState for automatic message tracking.\n   */\n  private processStream(source: Observable<EventWithState>, frontendCatalogId?: string): Observable<BaseEvent> {\n    // Tool names recognized as A2UI rendering tools. When the middleware also\n    // INJECTS the rendering tool (config.injectA2UITool truthy), the injected\n    // name MUST be part of the intercept set — otherwise TOOL_CALL_START for\n    // it wouldn't open a streaming entry and the progressive-render path\n    // would silently degrade to result-only.\n    //\n    // Two cases to cover:\n    //   - `injectA2UITool: true`       → injected under the default\n    //     RENDER_A2UI_TOOL_NAME (matches the default `a2uiToolNames`, but a\n    //     host that ALSO overrides `a2uiToolNames` to something like\n    //     `[\"foo\"]` would lose the default — explicitly re-add).\n    //   - `injectA2UITool: \"myName\"`   → injected under that custom name.\n    const a2uiToolNames = new Set(this.config.a2uiToolNames ?? [RENDER_A2UI_TOOL_NAME]);\n    if (this.config.injectA2UITool) {\n      const injectedName =\n        typeof this.config.injectA2UITool === \"string\" && this.config.injectA2UITool.length > 0\n          ? this.config.injectA2UITool\n          : RENDER_A2UI_TOOL_NAME;\n      a2uiToolNames.add(injectedName);\n    }\n\n    return new Observable<BaseEvent>((subscriber) => {\n      let heldRunFinished: EventWithState | null = null;\n\n      // Streaming tracker for dynamic render_a2ui tool calls.\n      //\n      // Progressive emission strategy (\"components atomic, data incremental\"):\n      //  1. createSurface rides into the FIRST snapshot together with components\n      //     (never on its own — an empty surface makes the renderer try to\n      //     resolve a not-yet-present root component and throw).\n      //  2. updateComponents is computed ONCE, only after the components array\n      //     is fully closed and every component carries a `component` type. It\n      //     IS re-included in every subsequent cumulative snapshot for\n      //     idempotency (the host filters duplicates by component id), but the\n      //     components payload is the same byte-for-byte across snapshots.\n      //  3. updateDataModel is emitted INCREMENTALLY: as each item in the\n      //     repeated data array (e.g. `data.items`) closes, a new snapshot\n      //     carries the items-so-far. Because the repeated card reuses one\n      //     already-emitted template component, growing the data array adds no\n      //     new component references — so cards paint one-by-one with no throw.\n      //\n      // Each emitted snapshot is cumulative (createSurface + updateComponents +\n      // updateDataModel-so-far) with replace:true, so any single snapshot is\n      // self-sufficient even if the frontend coalesces renders.\n      const streamingToolCalls = new Map<string, {\n        schema: { surfaceId: string; catalogId: string; components: Array<Record<string, unknown>> } | null;\n        args: string;\n        outerCallId: string | null; // the outer tool call this streaming inner was started inside (null if direct)\n        componentsEmitted: boolean; // updateComponents sent (atomic)\n        componentsRejected: boolean; // components closed but failed semantic validation (OSS-162) — never paint\n        dataItemsKey: string;      // repeated-array key derived from components\n        dataItemsCount: number;    // number of data items emitted so far\n        dataComplete: boolean;     // full (closed) data model emitted\n      }>();\n\n      // OSS-162 generation-lifecycle config (server-side; covers Python + TS).\n      const showProgressTokens = this.config.recovery?.showProgressTokens !== false; // default true\n      const maxAttempts = this.config.recovery?.maxAttempts ?? MAX_A2UI_ATTEMPTS;\n      const TOKEN_EMIT_STEP = 20; // throttle: re-emit progressTokens per ~20 tokens of growth\n\n      // Per outer-call lifecycle bookkeeping, keyed by `outerCallId ?? toolCallId`\n      // (the same key the surface messageId uses, so states swap in place):\n      //  - retriedOuterKeys: keys that have entered \"retrying\" (a prior attempt's\n      //    components were rejected) — so the building skeleton becomes the\n      //    retrying skeleton and stays there until paint or hard-failure.\n      //  - attemptCountByKey: number of render attempts seen (1 per render_a2ui call).\n      //  - lastTokenEmitByKey: token count at the last throttled progress emit.\n      const retriedOuterKeys = new Set<string>();\n      const attemptCountByKey = new Map<string, number>();\n      const lastTokenEmitByKey = new Map<string, number>();\n      const estimateTokens = (args: string) => Math.round(args.length / 4);\n\n      // Surfaces already painted via the streaming/progressive path this run,\n      // tracked by surfaceId. The final-envelope (TOOL_CALL_RESULT carrying\n      // ``a2ui_operations``) commonly re-wraps the SAME surface that an inner\n      // ``render_a2ui`` already streamed. The call-id linkage dedup below only\n      // catches that when the streamed entry's outerCallId equals the result's\n      // toolCallId — which breaks with ``injectA2UITool``, where ``generate_a2ui``\n      // is itself an A2UI tool name so it never becomes the tracked outer call\n      // (the inner entry's outerCallId stays null). This surfaceId guard kills the\n      // redundant re-paint for ANY adapter: any final-envelope operation whose\n      // target surface is already in this set is dropped. Surfaces NOT in this\n      // set (unrelated tools in the same run) still paint normally.\n      const streamedSurfaceIds = new Set<string>();\n\n      // Outer tool call context. Any non-A2UI tool call (e.g. ``generate_a2ui``\n      // wrapping a subagent that emits ``render_a2ui`` calls) is treated as\n      // the \"outer\" call. The outer id becomes the activity messageId\n      // discriminator so multiple inner ``render_a2ui`` attempts within the\n      // same outer call (e.g. validate-then-retry) supersede each other on\n      // the frontend instead of stacking as distinct chat entries.\n      //\n      // When no outer call is active (the agent calls ``render_a2ui``\n      // directly), behaviour falls back to the inner tool_call_id, matching\n      // the pre-existing scheme.\n      const nonOuterToolNames = new Set<string>([\n        ...a2uiToolNames,\n        LOG_A2UI_EVENT_TOOL_NAME,\n      ]);\n      let currentOuterCallId: string | null = null;\n\n      const subscription = source.subscribe({\n        next: (eventWithState) => {\n          const event = eventWithState.event;\n\n          if (event.type === EventType.TOOL_CALL_START) {\n            const startEvent = event as ToolCallStartEvent;\n\n            // render_a2ui: dynamic streaming. Track streaming args to\n            // extract schema (components) first, then data.\n            // If streaming extraction fails, auto-detect on the outer\n            // tool's TOOL_CALL_RESULT still works as a fallback.\n            if (a2uiToolNames.has(startEvent.toolCallName)) {\n              streamingToolCalls.set(startEvent.toolCallId, {\n                schema: null, args: \"\",\n                outerCallId: currentOuterCallId,\n                componentsEmitted: false,\n                componentsRejected: false,\n                dataItemsKey: \"items\", dataItemsCount: 0, dataComplete: false,\n              });\n\n              // OSS-162: this render attempt begins. Emit the pre-paint state on\n              // the surface activity so the skeleton shows immediately (the\n              // per-tool-call skeleton was retired). The FIRST attempt is\n              // \"building\"; a subsequent attempt means we're already \"retrying\"\n              // (a prior attempt's components were rejected), so keep that state.\n              const key = currentOuterCallId ?? startEvent.toolCallId;\n              const attempt = (attemptCountByKey.get(key) ?? 0) + 1;\n              attemptCountByKey.set(key, attempt);\n              lastTokenEmitByKey.set(key, 0);\n              if (!retriedOuterKeys.has(key)) {\n                subscriber.next(this.buildLifecycleActivity(key, { status: \"building\" }));\n              }\n            } else if (!nonOuterToolNames.has(startEvent.toolCallName)) {\n              // Any other tool call becomes the active outer-call context.\n              // ``render_a2ui`` events that follow will dedup against this id.\n              currentOuterCallId = startEvent.toolCallId;\n            }\n          }\n\n          // Stream data updates as tool args come in\n          if (event.type === EventType.TOOL_CALL_ARGS) {\n            const argsEvent = event as ToolCallArgsEvent;\n\n            // ── Streaming handler for render_a2ui ──\n            const streaming = streamingToolCalls.get(argsEvent.toolCallId);\n            if (streaming) {\n              streaming.args += argsEvent.delta;\n\n              // OSS-162: throttled live token estimate on the BUILDING skeleton.\n              // Only while still building this call's first attempt — once a prior\n              // attempt has been rejected (retrying) we must NOT emit here: doing so\n              // would overwrite the reject's rich \"retrying\" snapshot (correct\n              // attempt number + validation errors) with a counter-only one, which\n              // both reset the count to the wrong attempt and flickered the dev\n              // detail away. The retry snapshot owns the screen until paint / next\n              // reject / hard-failure. Throttled by token growth to avoid flooding.\n              const tokenKey = streaming.outerCallId ?? argsEvent.toolCallId;\n              if (\n                showProgressTokens &&\n                !streaming.componentsEmitted &&\n                !streaming.componentsRejected &&\n                !streaming.dataComplete &&\n                !retriedOuterKeys.has(tokenKey)\n              ) {\n                const tokens = estimateTokens(streaming.args);\n                if (tokens - (lastTokenEmitByKey.get(tokenKey) ?? 0) >= TOKEN_EMIT_STEP) {\n                  lastTokenEmitByKey.set(tokenKey, tokens);\n                  subscriber.next(\n                    this.buildLifecycleActivity(tokenKey, {\n                      status: \"building\",\n                      progressTokens: tokens,\n                    }),\n                  );\n                }\n              }\n\n              // Performance: only attempt extraction when the delta contains\n              // characters that could complete a JSON structure. Most deltas\n              // are mid-string/mid-number and can't change parse results.\n              const deltaHasClosingBrace = argsEvent.delta.includes(\"}\");\n              const deltaHasClosingBracket = argsEvent.delta.includes(\"]\");\n              const deltaHasStructuralChar = deltaHasClosingBrace || deltaHasClosingBracket;\n              // surfaceId completes as a string value (closing quote), not a\n              // brace/bracket — so also probe when the delta closes a string.\n              const deltaHasQuote = argsEvent.delta.includes('\"');\n\n              if (deltaHasStructuralChar || deltaHasQuote) {\n                const surfaceId = extractStringField(streaming.args, \"surfaceId\");\n\n                // Nothing actionable until we know which surface we're building.\n                if (surfaceId) {\n                  // Catalog ownership: the host/factory decides the catalog, not\n                  // the subagent. Resolution order:\n                  //   1. configured defaultCatalogId — explicit host override.\n                  //   2. frontendCatalogId — the id of the catalog the renderer\n                  //      actually registered (shipped on the run as the A2UI\n                  //      schema context entry). Zero-config: an app whose only\n                  //      catalog declaration is `<CopilotKit a2ui={{ catalog }}>`\n                  //      gets the right id with no server-side setting.\n                  //   3. a streamed catalogId (legacy) or the basic catalog.\n                  // This keeps the streamed createSurface from referencing a\n                  // catalog the frontend never registered (e.g. \"basic\" when the\n                  // app uses a custom catalog) — which throws \"Catalog not found\".\n                  //\n                  // Treat an empty-string defaultCatalogId as unset: a `??`\n                  // alone would propagate \"\" into the emitted createSurface and\n                  // surface as \"Catalog not found: \" in the renderer, hiding\n                  // the real cause (misconfiguration).\n                  const configCatalogId =\n                    this.config.defaultCatalogId && this.config.defaultCatalogId.length > 0\n                      ? this.config.defaultCatalogId\n                      : undefined;\n                  const streamedCatalogId = extractStringField(streaming.args, \"catalogId\");\n                  const catalogId =\n                    configCatalogId ??\n                    frontendCatalogId ??\n                    (streamedCatalogId && streamedCatalogId !== \"basic\"\n                      ? streamedCatalogId\n                      : \"https://a2ui.org/specification/v0_9/basic_catalog.json\");\n\n                  // (2) Components — emit ONCE, only when the array is fully\n                  // closed and every component has a `component` type. Partial\n                  // or type-less components would throw in @a2ui/web_core.\n                  if (!streaming.componentsEmitted && !streaming.componentsRejected) {\n                    const result = extractCompleteItemsWithStatus(streaming.args, \"components\");\n                    if (\n                      result &&\n                      result.arrayClosed &&\n                      result.items.length > 0 &&\n                      result.items.every(\n                        (c) => c && typeof c === \"object\" && typeof (c as any).component === \"string\",\n                      )\n                    ) {\n                      const components = result.items as Array<Record<string, unknown>>;\n                      // Semantic gate (OSS-162): never paint an UNVALIDATED\n                      // component tree. The structural check above only proves\n                      // the array closed with typed items; here we enforce\n                      // root/catalog/required-prop/child-ref validity against the\n                      // catalog. Bindings are DEFERRED (validateBindings: false) —\n                      // the data model has not streamed yet, so resolving them\n                      // would false-positive; the adapter re-validates with\n                      // bindings on the full args to drive the retry decision.\n                      const validation = validateA2UIComponents({\n                        components,\n                        catalog: this.getValidationCatalog(),\n                        validateBindings: false,\n                      });\n                      if (validation.valid) {\n                        streaming.schema = { surfaceId, catalogId, components };\n                        streaming.dataItemsKey = deriveRepeatedDataKey(components) ?? \"items\";\n                      } else {\n                        // Suppress: the faulty attempt never reaches the surface\n                        // (no wipe). Surface a client-gated \"retrying\" status; the\n                        // adapter's recovery loop regenerates and a later valid\n                        // attempt supersedes via the outer-call-keyed messageId.\n                        streaming.componentsRejected = true;\n                        const recoveryKey = streaming.outerCallId ?? argsEvent.toolCallId;\n                        retriedOuterKeys.add(recoveryKey);\n                        // Show the attempt we're about to retry into (the failed\n                        // one + 1), capped at the configured cap. Folds onto the\n                        // surface activity so it replaces the building skeleton in\n                        // place (same messageId) — no separate recovery activity.\n                        const nextAttempt = Math.min(\n                          (attemptCountByKey.get(recoveryKey) ?? 1) + 1,\n                          maxAttempts,\n                        );\n                        lastTokenEmitByKey.set(recoveryKey, 0);\n                        subscriber.next(\n                          this.buildLifecycleActivity(recoveryKey, {\n                            status: \"retrying\",\n                            attempt: nextAttempt,\n                            maxAttempts,\n                            errors: validation.errors,\n                          }),\n                        );\n                      }\n                    }\n                  }\n\n                  // (3) Data — incrementally surface complete items from the\n                  // repeated data array (e.g. data.items) once components exist.\n                  let dataItems: unknown[] | null = null;\n                  let dataItemsAdvanced = false;\n                  if (streaming.schema && !streaming.dataComplete) {\n                    const itemsResult = extractDataArrayItems(streaming.args, streaming.dataItemsKey);\n                    if (itemsResult && itemsResult.items.length > streaming.dataItemsCount) {\n                      dataItems = itemsResult.items;\n                      dataItemsAdvanced = true;\n                    }\n                  }\n\n                  // Decide whether this delta advanced any emittable state.\n                  //\n                  // We deliberately do NOT emit createSurface on its own: an\n                  // empty surface makes the renderer try to resolve the root\n                  // component immediately, which throws \"Component not found:\n                  // root\" until updateComponents arrives (a visible error\n                  // flash). So the first snapshot always carries components.\n                  // The loading skeleton during this window is provided by the\n                  // render_a2ui tool-call progress indicator, not an empty surface.\n                  const componentsAdvanced = !!streaming.schema && !streaming.componentsEmitted;\n\n                  if (componentsAdvanced || dataItemsAdvanced) {\n                    const ops: Array<Record<string, unknown>> = [];\n                    // Always include createSurface — the frontend filters it out\n                    // if the surface already exists, so snapshots stay self-sufficient.\n                    ops.push({ version: \"v0.9\", createSurface: { surfaceId, catalogId } });\n\n                    if (streaming.schema) {\n                      ops.push({ version: \"v0.9\", updateComponents: { surfaceId, components: streaming.schema.components } });\n                      streaming.componentsEmitted = true;\n                      // Record the surfaceId so the final envelope doesn't re-paint it.\n                      streamedSurfaceIds.add(streaming.schema.surfaceId);\n                    }\n\n                    if (dataItems && dataItems.length > 0) {\n                      streaming.dataItemsCount = dataItems.length;\n                      ops.push({\n                        version: \"v0.9\",\n                        updateDataModel: { surfaceId, path: \"/\", value: { [streaming.dataItemsKey]: dataItems } },\n                      });\n                    }\n\n                    const content: Record<string, unknown> = { [A2UI_OPERATIONS_KEY]: ops };\n                    // OSS-162: key by the outer call only (no surfaceId), so this\n                    // painted surface shares the messageId of the building/retrying\n                    // skeleton and REPLACES it in place. The client groups ops by\n                    // surfaceId from the content, so dropping it from the id is safe.\n                    const snapshotEvent: ActivitySnapshotEvent = {\n                      type: EventType.ACTIVITY_SNAPSHOT,\n                      messageId: `a2ui-surface-${streaming.outerCallId ?? argsEvent.toolCallId}`,\n                      activityType: A2UIActivityType,\n                      content,\n                      replace: true,\n                    };\n                    subscriber.next(snapshotEvent);\n                    // A valid surface painted → it supersedes any building/retrying\n                    // skeleton on this same messageId. No separate \"resolved\" needed.\n                    retriedOuterKeys.delete(streaming.outerCallId ?? argsEvent.toolCallId);\n                  }\n\n                  // Final authoritative data emit once the whole data object\n                  // closes. Covers non-array data keys (e.g. form objects) and\n                  // guarantees the data model exactly matches the model's intent.\n                  if (streaming.componentsEmitted && !streaming.dataComplete && deltaHasStructuralChar) {\n                    const data = extractCompleteObject(streaming.args, \"data\");\n                    if (data) {\n                      streaming.dataComplete = true;\n                      const ops: Array<Record<string, unknown>> = [\n                        { version: \"v0.9\", createSurface: { surfaceId, catalogId } },\n                        { version: \"v0.9\", updateComponents: { surfaceId, components: streaming.schema!.components } },\n                        { version: \"v0.9\", updateDataModel: { surfaceId, path: \"/\", value: data } },\n                      ];\n                      const content: Record<string, unknown> = { [A2UI_OPERATIONS_KEY]: ops };\n                      const snapshotEvent: ActivitySnapshotEvent = {\n                        type: EventType.ACTIVITY_SNAPSHOT,\n                        messageId: `a2ui-surface-${streaming.outerCallId ?? argsEvent.toolCallId}`,\n                        activityType: A2UIActivityType,\n                        content,\n                        replace: true,\n                      };\n                      subscriber.next(snapshotEvent);\n                    }\n                  }\n                }\n              }\n            }\n\n          }\n\n          // If we have a held RUN_FINISHED and a new event comes, flush it first\n          if (heldRunFinished) {\n            subscriber.next(heldRunFinished.event);\n            heldRunFinished = null;\n          }\n\n          // If this is a RUN_FINISHED event, hold it back\n          if (event.type === EventType.RUN_FINISHED) {\n            heldRunFinished = eventWithState;\n          } else {\n            subscriber.next(event);\n\n            // Auto-detect A2UI JSON in tool call results from other tools\n            if (event.type === EventType.TOOL_CALL_RESULT) {\n              const resultEvent = event as ToolCallResultEvent;\n              const isStreaming = streamingToolCalls.has(resultEvent.toolCallId);\n\n              // Fallback: if a streaming tool call never emitted its components\n              // (e.g. args didn't parse), fall through to auto-detection on the\n              // final result.\n              const streamingEntry = streamingToolCalls.get(resultEvent.toolCallId);\n              const streamingHandled = isStreaming && streamingEntry?.componentsEmitted;\n\n              // Also dedup against the SPECIFIC outer call this result belongs\n              // to: if an inner ``render_a2ui`` started inside the same outer\n              // call already streamed its surface, the outer's result (which\n              // typically wraps the same envelope) would re-emit the same\n              // surface. Earlier we used a blanket \"any streaming entry handled\"\n              // check, but that wrongly suppressed legitimate later\n              // ``a2ui_operations`` payloads from unrelated tools in the same\n              // run. Scope the dedup to entries whose outerCallId matches the\n              // result's tool-call id.\n              let outerHasStreamedSurface = !!streamingHandled;\n              if (!outerHasStreamedSurface) {\n                for (const entry of streamingToolCalls.values()) {\n                  if (entry.componentsEmitted && entry.outerCallId === resultEvent.toolCallId) {\n                    outerHasStreamedSurface = true;\n                    break;\n                  }\n                }\n              }\n\n              if (!outerHasStreamedSurface) {\n                const parsed = tryParseA2UIOperations(resultEvent.content);\n                if (parsed) {\n                  // surfaceId-based dedup (framework-agnostic): drop any\n                  // operation whose target surface was already painted via the\n                  // streaming path this run. This kills the redundant final\n                  // re-paint even when the call-id linkage above misses (e.g.\n                  // injectA2UITool, where the inner render entry has a null\n                  // outerCallId). Operations for surfaces NOT yet streamed\n                  // (unrelated tools) pass through untouched.\n                  const operationsToEmit =\n                    streamedSurfaceIds.size > 0\n                      ? parsed.operations.filter((op) => {\n                          const opSurfaceId = getOperationSurfaceId(op);\n                          // Keep ops with no resolvable surface (can't be a dup)\n                          // and ops targeting surfaces not yet streamed.\n                          return opSurfaceId == null || !streamedSurfaceIds.has(opSurfaceId);\n                        })\n                      : parsed.operations;\n\n                  // If filtering removed everything, the final envelope was\n                  // entirely a re-paint of already-streamed surfaces — emit\n                  // nothing. Otherwise emit the surviving operations.\n                  if (operationsToEmit.length > 0) {\n                    // Emit all operations at once. Unlike the streaming path\n                    // (render_a2ui), explicit a2ui_operations arrive complete —\n                    // splitting schema and data would cause the renderer to\n                    // crash on unresolved path bindings before data exists.\n                    for (const activityEvent of this.createA2UIActivityEvents(\n                      operationsToEmit,\n                      currentOuterCallId ?? resultEvent.toolCallId,\n                    )) {\n                      subscriber.next(activityEvent);\n                    }\n                  }\n                } else {\n                  // Hard-failure path (OSS-162): an exhausted recovery loop\n                  // returns a structured error envelope (no a2ui_operations).\n                  // Surface it as a client-rendered failure rather than dropping\n                  // it silently — the conversation stays usable.\n                  const failure = tryParseRecoveryFailure(resultEvent.content);\n                  if (failure) {\n                    // Hard failure replaces the building/retrying skeleton in\n                    // place (same surface messageId). `attempts.length` is the\n                    // true cap reached; fall back to the configured cap.\n                    const failKey = currentOuterCallId ?? resultEvent.toolCallId;\n                    subscriber.next(\n                      this.buildLifecycleActivity(failKey, {\n                        status: \"failed\",\n                        error: failure.error,\n                        attempts: failure.attempts,\n                        maxAttempts: Array.isArray(failure.attempts)\n                          ? failure.attempts.length || maxAttempts\n                          : maxAttempts,\n                      }),\n                    );\n                    retriedOuterKeys.delete(failKey);\n                  }\n                }\n              }\n\n              // Clear outer-call context when its TOOL_CALL_RESULT arrives.\n              if (currentOuterCallId === resultEvent.toolCallId) {\n                currentOuterCallId = null;\n              }\n            }\n          }\n        },\n        error: (err) => {\n          // On error, flush any held event and propagate error\n          if (heldRunFinished) {\n            subscriber.next(heldRunFinished.event);\n            heldRunFinished = null;\n          }\n          subscriber.error(err);\n        },\n        complete: () => {\n          if (heldRunFinished) {\n            // Emit synthetic TOOL_CALL_RESULT for pending render_a2ui calls.\n            // The streaming handler already emitted activity events during\n            // TOOL_CALL_ARGS, so we just need to close the tool call.\n            const pendingToolCalls = this.findPendingToolCalls(heldRunFinished.messages);\n            const pendingRenderCalls = pendingToolCalls.filter(\n              (tc) => a2uiToolNames.has(tc.function.name)\n            );\n            for (const toolCall of pendingRenderCalls) {\n              const resultEvent: ToolCallResultEvent = {\n                type: EventType.TOOL_CALL_RESULT,\n                messageId: randomUUID(),\n                toolCallId: toolCall.id,\n                content: JSON.stringify({ status: \"rendered\" }),\n              };\n              subscriber.next(resultEvent);\n            }\n            subscriber.next(heldRunFinished.event);\n            heldRunFinished = null;\n          }\n          subscriber.complete();\n        },\n      });\n\n      return () => subscription.unsubscribe();\n    });\n  }\n\n  /**\n   * Find tool calls that don't have a corresponding result (role: \"tool\") message\n   */\n  private findPendingToolCalls(messages: Message[]): ToolCall[] {\n    // Collect all tool calls from assistant messages\n    const allToolCalls: ToolCall[] = [];\n    for (const message of messages) {\n      if (\n        message.role === \"assistant\" &&\n        \"toolCalls\" in message &&\n        message.toolCalls\n      ) {\n        allToolCalls.push(...message.toolCalls);\n      }\n    }\n\n    // Collect all tool call IDs that have results\n    const resolvedToolCallIds = new Set<string>();\n    for (const message of messages) {\n      if (message.role === \"tool\" && \"toolCallId\" in message) {\n        resolvedToolCallIds.add(message.toolCallId);\n      }\n    }\n\n    // Return tool calls that don't have results\n    return allToolCalls.filter((tc) => !resolvedToolCallIds.has(tc.id));\n  }\n\n  /**\n   * Create ACTIVITY_SNAPSHOT events from A2UI operations, grouped by surfaceId.\n   *\n   * @param operations - A2UI operations to emit\n   * @param toolCallId - Unique tool call ID to isolate surfaces between invocations\n   */\n  private createA2UIActivityEvents(\n    operations: Array<Record<string, unknown>>,\n    toolCallId?: string,\n  ): BaseEvent[] {\n    const events: BaseEvent[] = [];\n\n    // Group operations by surfaceId\n    const operationsBySurface = new Map<string, Array<Record<string, unknown>>>();\n    for (const op of operations) {\n      const surfaceId = getOperationSurfaceId(op) ?? \"default\";\n      if (!operationsBySurface.has(surfaceId)) {\n        operationsBySurface.set(surfaceId, []);\n      }\n      operationsBySurface.get(surfaceId)!.push(op);\n    }\n\n    // Emit a single ACTIVITY_SNAPSHOT per surface with replace: true.\n    // Using replace: true ensures all operations (createSurface + updateComponents\n    // + updateDataModel) are delivered atomically, preventing intermediate renders\n    // with partial operations that can break data binding resolution.\n    for (const [surfaceId, surfaceOps] of operationsBySurface) {\n      // Include toolCallId in messageId to ensure each tool invocation\n      // creates a distinct activity message, even for the same surfaceId.\n      // OSS-162: for the common single-surface case, key by the outer call ONLY\n      // (no surfaceId) so this paint shares the messageId of any building/retrying\n      // skeleton emitted for the same call and replaces it in place. Multi-surface\n      // results keep the per-surface id (they never had a single lifecycle slot).\n      const singleSurface = operationsBySurface.size === 1;\n      const messageId = toolCallId\n        ? singleSurface\n          ? `a2ui-surface-${toolCallId}`\n          : `a2ui-surface-${surfaceId}-${toolCallId}`\n        : `a2ui-surface-${surfaceId}`;\n\n      const content: Record<string, unknown> = { [A2UI_OPERATIONS_KEY]: surfaceOps };\n\n      const snapshotEvent: ActivitySnapshotEvent = {\n        type: EventType.ACTIVITY_SNAPSHOT,\n        messageId,\n        activityType: A2UIActivityType,\n        content,\n        replace: true,\n      };\n      events.push(snapshotEvent);\n    }\n\n    return events;\n  }\n}\n","import { Tool } from \"@ag-ui/client\";\n\n/**\n * Tool name for the structured render_a2ui tool\n */\nexport const RENDER_A2UI_TOOL_NAME = \"render_a2ui\";\n\n/**\n * Tool name for logging A2UI events (synthetic, used for context)\n */\nexport const LOG_A2UI_EVENT_TOOL_NAME = \"log_a2ui_event\";\n\n/**\n * Tool definition for rendering A2UI surfaces.\n * This tool is injected into the agent's available tools when injectA2UITool is true.\n * Uses structured parameters (surfaceId, components, data) — the catalog id\n * is owned by the middleware config, not chosen by the model.\n */\nexport const RENDER_A2UI_TOOL: Tool = {\n  name: RENDER_A2UI_TOOL_NAME,\n  description:\n    \"Render a dynamic A2UI v0.9 surface with structured parameters. \" +\n    \"Follow the A2UI render tool usage guide provided in context.\",\n  parameters: {\n    type: \"object\",\n    properties: {\n      surfaceId: {\n        type: \"string\",\n        description: \"Unique surface identifier.\",\n      },\n      components: {\n        type: \"array\",\n        description:\n          \"A2UI v0.9 component array (flat format). The root component must have id \\\"root\\\".\",\n        items: { type: \"object\" },\n      },\n      data: {\n        type: \"object\",\n        description:\n          \"Initial data model for the surface. Written to the root path. \" +\n          \"Use for pre-filling form values (e.g. {\\\"form\\\": {\\\"name\\\": \\\"Alice\\\"}}) \" +\n          \"or providing data for components bound to data model paths.\",\n      },\n    },\n    required: [\"surfaceId\", \"components\"],\n  },\n};\n\n/**\n * Usage guidelines injected as context when injectA2UITool is enabled.\n * Provides the LLM with protocol instructions and a minimal example\n * for calling render_a2ui correctly.\n */\nexport const RENDER_A2UI_TOOL_GUIDELINES = (toolName: string) => `\\\n## How to call ${toolName}\n\nYou MUST provide ALL required arguments when calling ${toolName}:\n\n- **surfaceId** (string, required): Unique ID for the surface (e.g. \"sales-dashboard\").\n- **components** (array, REQUIRED): A2UI v0.9 flat component array. NEVER omit this.\n- **data** (object, optional): Initial data model for path-bound component values.\n\nNote: the catalog id is set by the host, not by you. Do not include a catalogId argument.\n\n### Component format (v0.9 flat)\n\nComponents are a flat array — children are referenced by ID, not nested:\n- Every component has \\`id\\` (unique) and \\`component\\` (type name from the available catalog).\n- The root component MUST have \\`id: \"root\"\\`.\n- Properties go directly on the component object.\n- Use \\`children: [\"id1\", \"id2\"]\\` for multiple children, \\`child: \"id\"\\` for a single child.\n\n### Minimal example\n\n\\`\\`\\`json\n{\n  \"surfaceId\": \"my-dashboard\",\n  \"components\": [\n    { \"id\": \"root\", \"component\": \"Column\", \"children\": [\"title\", \"row1\"] },\n    { \"id\": \"title\", \"component\": \"Title\", \"text\": \"Overview\" },\n    { \"id\": \"row1\", \"component\": \"Row\", \"children\": [\"m1\", \"m2\"], \"gap\": 16 },\n    { \"id\": \"m1\", \"component\": \"Metric\", \"label\": \"Users\", \"value\": \"1,200\" },\n    { \"id\": \"m2\", \"component\": \"Metric\", \"label\": \"Revenue\", \"value\": \"$50K\" }\n  ]\n}\n\\`\\`\\`\n\n### Key rules\n\n1. NEVER call ${toolName} without the \\`components\\` array — the UI will be empty.\n2. Root must be a layout component (Column, Row, Card) — not Text or Button.\n3. Component IDs must be unique. A component must NOT reference itself as child.\n4. Only use component names from the Available Components schema in context.\n5. For data binding use \\`{ \"path\": \"/key\" }\\` (absolute) or \\`{ \"path\": \"key\" }\\` (relative inside templates).\n6. For repeating content: \\`children: { componentId: \"card-id\", path: \"/items\" }\\` repeats per array item.\n7. Button actions: \\`\"action\": { \"event\": { \"name\": \"action_name\", \"context\": { ... } } }\\` — event must be an object.\n8. No placeholder images — only use real URLs or Icon components.`;\n","import clarinet from \"clarinet\";\n\n// Clarinet's CParser type doesn't include the `error` property that exists at runtime.\n// We use this to clear errors and allow parsing to continue on partial JSON.\ntype CParserWithError = ReturnType<typeof clarinet.parser> & { error: unknown };\n\n/**\n * Extract complete items from a partially-streamed JSON object.\n * Given partial JSON like `{\"flights\": [{\"id\":\"1\",...}, {\"id\":\"2\"` and dataKey \"flights\",\n * returns an array of all complete objects parsed so far, or null if none found.\n */\nexport function extractCompleteItems(partial: string, dataKey: string): unknown[] | null {\n  const result = extractCompleteItemsWithStatus(partial, dataKey);\n  return result?.items ?? null;\n}\n\n/**\n * Locate the start of the value for a TOP-LEVEL (root-depth=1) key in partial JSON.\n *\n * Returns the byte index of the first non-whitespace character AFTER the\n * key's colon, or -1 if the key hasn't been seen at the root level yet.\n *\n * This is JSON-aware (driven by clarinet, not raw `indexOf`), so a key with\n * the same name nested inside a component object (e.g. a component carrying\n * its own `data` field) is correctly ignored — only the top-level key at\n * `{\"<key>\": ...}` is matched.\n */\nfunction findTopLevelValueStart(partial: string, key: string): number {\n  const target = `\"${key}\"`;\n  let i = 0;\n  let objectDepth = 0;\n  let arrayDepth = 0;\n  let inString = false;\n  let escape = false;\n\n  while (i < partial.length) {\n    const ch = partial[i];\n\n    if (escape) {\n      escape = false;\n      i++;\n      continue;\n    }\n\n    if (inString) {\n      if (ch === \"\\\\\") {\n        escape = true;\n      } else if (ch === '\"') {\n        inString = false;\n      }\n      i++;\n      continue;\n    }\n\n    if (ch === '\"') {\n      // Opening quote of a string token. Only at the root level\n      // (objectDepth === 1, no enclosing array) can this be the top-level\n      // key we're looking for. We confirm by:\n      //   1. The substring at `i` equals `\"<key>\"`.\n      //   2. The next non-whitespace character after the closing quote is\n      //      ':' — distinguishing this from a value string that happens to\n      //      equal the key spelling.\n      if (objectDepth === 1 && arrayDepth === 0 && partial.startsWith(target, i)) {\n        let j = i + target.length;\n        while (j < partial.length && (partial[j] === \" \" || partial[j] === \"\\n\" || partial[j] === \"\\r\" || partial[j] === \"\\t\")) {\n          j++;\n        }\n        if (j < partial.length && partial[j] === \":\") {\n          // Skip the colon and any whitespace to land on the value's first\n          // non-whitespace character.\n          j++;\n          while (j < partial.length && (partial[j] === \" \" || partial[j] === \"\\n\" || partial[j] === \"\\r\" || partial[j] === \"\\t\")) {\n            j++;\n          }\n          return j < partial.length ? j : -1;\n        }\n      }\n      inString = true;\n      i++;\n      continue;\n    }\n\n    if (ch === \"{\") objectDepth++;\n    else if (ch === \"}\") objectDepth--;\n    else if (ch === \"[\") arrayDepth++;\n    else if (ch === \"]\") arrayDepth--;\n\n    i++;\n  }\n\n  return -1;\n}\n\n/**\n * Extract a complete JSON object value for a given key from partially-streamed JSON.\n * Given partial JSON like `{\"surfaceId\": \"s1\", \"data\": {\"form\": {\"name\": \"Alice\"}}, \"other\":`\n * and dataKey \"data\", returns the parsed object `{\"form\": {\"name\": \"Alice\"}}` or null if\n * the object value is not yet fully closed.\n *\n * Only matches the key at the TOP LEVEL — a nested object that happens to\n * carry the same key (e.g. a component with its own `data` property) is\n * ignored. This keeps the streaming intercept correct even when component\n * payloads contain JSON keys that overlap with the render_a2ui arg names.\n */\nexport function extractCompleteObject(partial: string, dataKey: string): Record<string, unknown> | null {\n  const braceStart = findTopLevelValueStart(partial, dataKey);\n  if (braceStart === -1) return null;\n  // findTopLevelValueStart returns the index of the value's opening token.\n  // For object values that's the '{' character.\n  if (partial[braceStart] !== \"{\") return null;\n\n  // Use clarinet to find where the top-level object closes\n  const substr = partial.substring(braceStart);\n  const parser = clarinet.parser() as CParserWithError;\n\n  let objectDepth = 0;\n  let objectClosed = false;\n  let closePosition = -1;\n\n  parser.onerror = () => {\n    parser.error = null;\n  };\n\n  parser.onopenobject = () => {\n    objectDepth++;\n  };\n\n  parser.oncloseobject = () => {\n    objectDepth--;\n    if (objectDepth === 0 && !objectClosed) {\n      objectClosed = true;\n      closePosition = parser.position;\n    }\n  };\n\n  // Need array tracking to handle nested arrays within the object\n  parser.onopenarray = () => {};\n  parser.onclosearray = () => {};\n  parser.onvalue = () => {};\n  parser.onkey = () => {};\n\n  try {\n    parser.write(substr);\n  } catch {\n    // Partial JSON will throw; that's expected\n  }\n\n  if (!objectClosed) return null;\n\n  const objStr = substr.substring(0, closePosition);\n  try {\n    return JSON.parse(objStr) as Record<string, unknown>;\n  } catch {\n    return null;\n  }\n}\n\n/**\n * Extended version of extractCompleteItems that also reports whether the\n * array has been fully closed in the stream (i.e., the closing `]` has\n * been received).\n */\nexport function extractCompleteItemsWithStatus(\n  partial: string,\n  dataKey: string,\n): { items: unknown[]; arrayClosed: boolean } | null {\n  // Locate the opening '[' of the target array via a JSON-aware scan rather\n  // than raw indexOf — a component object that happens to contain a key with\n  // the same name (e.g. `\"items\"` deep in a component) must NOT be mistaken\n  // for the top-level array.\n  const bracketStart = findTopLevelValueStart(partial, dataKey);\n  if (bracketStart === -1) return null;\n  if (partial[bracketStart] !== \"[\") return null;\n\n  // Feed only the array portion to clarinet, so parser.position is relative to bracketStart\n  const substr = partial.substring(bracketStart);\n  const parser = clarinet.parser() as CParserWithError;\n\n  let objectDepth = 0;\n  let arrayDepth = 0;\n  let lastCompleteEnd = -1;\n  let arrayClosed = false;\n\n  parser.onerror = () => {\n    parser.error = null;\n  };\n\n  parser.onopenarray = () => {\n    arrayDepth++;\n  };\n\n  parser.onclosearray = () => {\n    if (arrayDepth === 1) {\n      arrayClosed = true;\n    }\n    arrayDepth--;\n  };\n\n  parser.onopenobject = () => {\n    objectDepth++;\n  };\n\n  parser.oncloseobject = () => {\n    if (objectDepth === 1 && arrayDepth === 1) {\n      // Completed a top-level item in the target array.\n      // parser.position is the 0-based index of the character AFTER the '}'.\n      lastCompleteEnd = parser.position;\n    }\n    objectDepth--;\n  };\n\n  parser.onvalue = () => {\n    // Primitive value at array top-level (number, string, bool, null)\n    if (objectDepth === 0 && arrayDepth === 1) {\n      lastCompleteEnd = parser.position;\n    }\n  };\n\n  try {\n    parser.write(substr);\n  } catch {\n    // Partial JSON will throw; that's expected\n  }\n\n  if (lastCompleteEnd === -1) return null;\n\n  // substr.substring(0, lastCompleteEnd) gives everything from '[' up to and including '}'\n  const arrayStr = substr.substring(0, lastCompleteEnd) + \"]\";\n  try {\n    const items = JSON.parse(arrayStr);\n    return { items, arrayClosed };\n  } catch {\n    return null;\n  }\n}\n\n/**\n * Incrementally extract complete items from the array at `data.<itemsKey>`\n * inside partially-streamed render_a2ui args.\n *\n * The render_a2ui args look like:\n *   `{\"surfaceId\":\"s\",\"components\":[...],\"data\":{\"items\":[{...},{...}` (still streaming)\n *\n * We scope the search to the `data` object region first (so a `\"items\"` token\n * that appears inside a component's `path` string — e.g. `\"path\":\"/items\"` —\n * is never mistaken for the data array), then reuse the array-item extractor\n * to return every fully-closed item parsed so far.\n *\n * Returns `{ items, arrayClosed }` or null when the data array hasn't started\n * or no complete item exists yet.\n */\nexport function extractDataArrayItems(\n  partial: string,\n  itemsKey: string,\n): { items: unknown[]; arrayClosed: boolean } | null {\n  // Locate the TOP-LEVEL `data` object via clarinet so a component that\n  // carries its own `data` field (e.g. a Chart component with\n  // `{\"id\":\"c\",\"component\":\"Chart\",\"data\":{...}}`) doesn't get mis-scoped.\n  const dataBraceStart = findTopLevelValueStart(partial, \"data\");\n  if (dataBraceStart === -1) return null;\n  if (partial[dataBraceStart] !== \"{\") return null;\n\n  // Scope extraction to the data object substring so the items-array search\n  // (now also clarinet-driven for top-level keys) is rooted at the data\n  // object, never elsewhere in the args.\n  const dataSubstr = partial.substring(dataBraceStart);\n  return extractCompleteItemsWithStatus(dataSubstr, itemsKey);\n}\n\n/**\n * Extract a simple string field value from partial JSON.\n * Looks for `\"key\": \"value\"` and returns the value, or null if incomplete.\n */\nexport function extractStringField(partialJson: string, key: string): string | null {\n  const parser = clarinet.parser() as CParserWithError;\n  let result: string | null = null;\n  let rootDepth = 0;\n  let currentKey: string | null = null;\n  let found = false;\n\n  parser.onerror = () => {\n    parser.error = null;\n  };\n\n  parser.onopenobject = (firstKey?: string) => {\n    rootDepth++;\n    if (firstKey !== undefined && rootDepth === 1) {\n      currentKey = firstKey;\n    }\n  };\n\n  parser.oncloseobject = () => {\n    rootDepth--;\n  };\n\n  parser.onkey = (k: string) => {\n    if (rootDepth === 1) {\n      currentKey = k;\n    }\n  };\n\n  parser.onvalue = (value: unknown) => {\n    if (!found && rootDepth === 1 && currentKey === key && typeof value === \"string\") {\n      result = value;\n      found = true;\n    }\n  };\n\n  try {\n    parser.write(partialJson);\n  } catch {\n    // partial JSON\n  }\n\n  return result;\n}\n\n/**\n * Extract complete A2UI operation objects from the partially-streamed tool call args\n * for `send_a2ui_json_to_client`.\n *\n * The tool call args JSON looks like: `{\"a2ui_json\": \"[{\\\"surfaceUpdate\\\":...}, ...]\"}`\n * The `a2ui_json` value is a JSON-encoded string containing an array of operations.\n *\n * This function:\n * 1. Extracts the partial string value of `a2ui_json` from the partial outer JSON\n * 2. Unescapes JSON escape sequences to recover the inner JSON\n * 3. Finds complete top-level objects in the inner partial array\n */\nexport function extractCompleteA2UIOperations(partialArgs: string): Array<Record<string, unknown>> | null {\n  // Phase 1: Find the start of the a2ui_json string value and unescape it.\n  // We use manual parsing here because clarinet only emits complete string values,\n  // but we need to work with the partial string as it streams in.\n  const keyPattern = '\"a2ui_json\"';\n  const keyIdx = partialArgs.indexOf(keyPattern);\n  if (keyIdx === -1) return null;\n\n  const afterKey = partialArgs.indexOf(\":\", keyIdx + keyPattern.length);\n  if (afterKey === -1) return null;\n\n  let valueStart = -1;\n  for (let i = afterKey + 1; i < partialArgs.length; i++) {\n    if (partialArgs[i] === '\"') {\n      valueStart = i + 1;\n      break;\n    }\n    if (partialArgs[i] !== ' ' && partialArgs[i] !== '\\n' && partialArgs[i] !== '\\r' && partialArgs[i] !== '\\t') {\n      return null;\n    }\n  }\n  if (valueStart === -1) return null;\n\n  const innerJson = unescapeJsonString(partialArgs, valueStart);\n\n  // Phase 2: Find complete top-level objects in the inner JSON array using clarinet.\n  return extractTopLevelArrayItems(innerJson);\n}\n\n/**\n * Unescape a JSON string starting at the given position.\n * Handles all standard JSON escape sequences.\n * Stops at an unescaped `\"` (end of string) or end of input (partial string).\n */\nfunction unescapeJsonString(str: string, startIdx: number): string {\n  let result = \"\";\n  let i = startIdx;\n  while (i < str.length) {\n    const ch = str[i];\n    if (ch === '\\\\') {\n      if (i + 1 >= str.length) break;\n      const next = str[i + 1];\n      switch (next) {\n        case '\"': result += '\"'; i += 2; break;\n        case '\\\\': result += '\\\\'; i += 2; break;\n        case '/': result += '/'; i += 2; break;\n        case 'n': result += '\\n'; i += 2; break;\n        case 'r': result += '\\r'; i += 2; break;\n        case 't': result += '\\t'; i += 2; break;\n        case 'b': result += '\\b'; i += 2; break;\n        case 'f': result += '\\f'; i += 2; break;\n        case 'u': {\n          if (i + 5 < str.length) {\n            const hex = str.substring(i + 2, i + 6);\n            result += String.fromCharCode(parseInt(hex, 16));\n            i += 6;\n          } else {\n            return result;\n          }\n          break;\n        }\n        default:\n          result += next;\n          i += 2;\n          break;\n      }\n    } else if (ch === '\"') {\n      break;\n    } else {\n      result += ch;\n      i++;\n    }\n  }\n  return result;\n}\n\n/**\n * Parse a partial JSON array string and return all complete top-level objects.\n * Uses clarinet for structural parsing.\n */\nfunction extractTopLevelArrayItems(innerJson: string): Array<Record<string, unknown>> | null {\n  const bracketStart = innerJson.indexOf(\"[\");\n  if (bracketStart === -1) return null;\n\n  const substr = innerJson.substring(bracketStart);\n  const parser = clarinet.parser() as CParserWithError;\n  let objectDepth = 0;\n  let arrayDepth = 0;\n  let lastCompleteEnd = -1;\n\n  parser.onerror = () => {\n    parser.error = null;\n  };\n\n  parser.onopenarray = () => {\n    arrayDepth++;\n  };\n\n  parser.onclosearray = () => {\n    arrayDepth--;\n  };\n\n  parser.onopenobject = () => {\n    objectDepth++;\n  };\n\n  parser.oncloseobject = () => {\n    if (objectDepth === 1 && arrayDepth === 1) {\n      lastCompleteEnd = parser.position;\n    }\n    objectDepth--;\n  };\n\n  try {\n    parser.write(substr);\n  } catch {\n    // partial JSON\n  }\n\n  if (lastCompleteEnd === -1) return null;\n\n  const arrayStr = substr.substring(0, lastCompleteEnd) + \"]\";\n  try {\n    return JSON.parse(arrayStr) as Array<Record<string, unknown>>;\n  } catch {\n    return null;\n  }\n}\n","/**\n * A2UI JSON Schema\n * Full specification for A2UI (Agent to UI) messages.\n * Source: https://github.com/anthropics/A2UI\n *\n * This schema is designed to be added to system prompts between the markers:\n * ---BEGIN A2UI JSON SCHEMA---\n * <schema>\n * ---END A2UI JSON SCHEMA---\n */\n\n/**\n * @deprecated Do not use built-in schemas. Component schemas must be passed\n * explicitly from application code via CopilotRuntime's `a2ui.schema` config.\n * The middleware injects these as context for agents automatically.\n */\nexport const A2UI_PROMPT = `---BEGIN A2UI JSON SCHEMA---\n\n## A2UI v0.9 Protocol Instructions\n\nA2UI (Agent to UI) is a protocol for rendering rich UI surfaces from agent responses.\nWhen using the send_a2ui_json_to_client tool, you MUST follow these rules:\n\n### CRITICAL: Required Message Sequence\n\nTo render a surface, you MUST send ALL messages in a SINGLE tool call, in this order:\n1. **createSurface** - Create the surface (REQUIRED, only for initial render)\n2. **updateComponents** - Define all UI components (REQUIRED)\n3. **updateDataModel** - Set any data values (OPTIONAL)\n\n**IMPORTANT**:\n- The \\`createSurface\\` message is MANDATORY for the first render. Without it, the client has no surface to render into.\n- ALL messages MUST be in the SAME a2ui_json array in ONE tool call.\n- Every message MUST include \\`\"version\": \"v0.9\"\\`.\n- The root component MUST have \\`\"id\": \"root\"\\`.\n\n### Minimal Working Example\n\nHere is the simplest possible A2UI surface - a button:\n\n\\`\\`\\`json\n[\n  {\n    \"version\": \"v0.9\",\n    \"createSurface\": {\n      \"surfaceId\": \"my-surface\",\n      \"catalogId\": \"https://a2ui.org/specification/v0_9/basic_catalog.json\"\n    }\n  },\n  {\n    \"version\": \"v0.9\",\n    \"updateComponents\": {\n      \"surfaceId\": \"my-surface\",\n      \"components\": [\n        {\n          \"id\": \"root\",\n          \"component\": \"Button\",\n          \"child\": \"btn-text\",\n          \"action\": { \"event\": { \"name\": \"button_clicked\" } }\n        },\n        {\n          \"id\": \"btn-text\",\n          \"component\": \"Text\",\n          \"text\": \"Click Me\"\n        }\n      ]\n    }\n  }\n]\n\\`\\`\\`\n\n### Key Rules\n\n1. **Always include createSurface** for new surfaces - This tells the client to create the surface.\n2. **Use unique surfaceId values** - Each surface must have a unique ID.\n3. **Root component must have id \"root\"** - The root component is always the one with \\`\"id\": \"root\"\\`.\n4. **Flat component structure** - Components reference children by ID, not by nesting.\n5. **v0.9 flat format** - Component type is a string: \\`\"component\": \"Text\"\\`, not \\`\"component\": { \"Text\": {...} }\\`.\n6. **Properties are top-level** - Properties go directly on the component object: \\`{ \"id\": \"t\", \"component\": \"Text\", \"text\": \"Hello\" }\\`.\n7. **Children are arrays** - Use \\`\"children\": [\"child1\", \"child2\"]\\` not \\`\"children\": { \"explicitList\": [...] }\\`.\n8. **Plain data model** - Use \\`\"value\"\\` with plain JSON, not typed \\`contents\\` arrays.\n9. **Actions use event wrapper** - Button actions use \\`{ \"event\": { \"name\": \"...\", \"context\": {...} } }\\` with context as a plain object.\n10. **Production ready** - The UI you generate will be shown to real users. It must be complete, polished, and functional.\n11. **No placeholder images** - NEVER use fake or placeholder image URLs. Only use real, valid image URLs. If unavailable, use an Icon component instead.\n12. **Root must be a layout component** - The root should be Column, Row, Card, or similar. Do NOT use Modal, Button, Text as root.\n13. **Button uses child** - Use \\`\"child\": \"text-id\"\\` for the button's label component.\n14. **Button variant** - Use \\`\"variant\": \"primary\"\\` instead of \\`\"primary\": true\\`.\n15. **Layout uses justify/align** - Use \\`\"justify\"\\` (not \\`\"distribution\"\\`) and \\`\"align\"\\` (not \\`\"alignment\"\\`).\n16. **Text variant** - Use \\`\"variant\"\\` (not \\`\"usageHint\"\\`) for text style: h1, h2, h3, h4, h5, caption, body.\n\n### Updating Surfaces After Initial Render\n\nOnce a surface has been created, you can update it in later turns WITHOUT sending another \\`createSurface\\`. Just send updates directly:\n\n**To update UI components** - Send an \\`updateComponents\\` with the same surfaceId:\n- To modify a component: send it with the same \\`id\\` - it replaces the old definition\n- To add new components: include them in the components array\n\n**To update data values** - Send an \\`updateDataModel\\`:\n- Components bound to data paths (using \\`{ \"path\": \"/some/value\" }\\`) update automatically\n- Use \\`\"path\"\\` to target a specific location, and \\`\"value\"\\` for the plain JSON value\n\n**Example: Updating an existing surface**\n\n\\`\\`\\`json\n[\n  {\n    \"version\": \"v0.9\",\n    \"updateComponents\": {\n      \"surfaceId\": \"my-surface\",\n      \"components\": [\n        {\n          \"id\": \"status-text\",\n          \"component\": \"Text\",\n          \"text\": \"Updated status!\"\n        }\n      ]\n    }\n  }\n]\n\\`\\`\\`\n\nOr update data-bound values:\n\n\\`\\`\\`json\n[\n  {\n    \"version\": \"v0.9\",\n    \"updateDataModel\": {\n      \"surfaceId\": \"my-surface\",\n      \"path\": \"/status\",\n      \"value\": \"Complete\"\n    }\n  }\n]\n\\`\\`\\`\n\n**IMPORTANT**: Do NOT send \\`createSurface\\` again for updates to an existing surface.\n\n### Working with Forms and Data Binding\n\nA2UI supports forms where user input is stored in a data model and retrieved when buttons are clicked.\n\n**How it works:**\n1. **TextField binds to a path**: Use \\`\"text\": { \"path\": \"/form/fieldName\" }\\` to bind input to the data model\n2. **Initialize the data model**: Send an \\`updateDataModel\\` to set initial values\n3. **Button retrieves values**: Use \\`action.event.context\\` with path references to include form values when clicked\n4. **Agent receives resolved values**: The context in the action will contain the actual values the user entered\n\n**Form Example:**\n\n\\`\\`\\`json\n[\n  { \"version\": \"v0.9\", \"createSurface\": { \"surfaceId\": \"my-form\", \"catalogId\": \"https://a2ui.org/specification/v0_9/basic_catalog.json\" } },\n  {\n    \"version\": \"v0.9\",\n    \"updateComponents\": {\n      \"surfaceId\": \"my-form\",\n      \"components\": [\n        { \"id\": \"root\", \"component\": \"Card\", \"child\": \"form-col\" },\n        { \"id\": \"form-col\", \"component\": \"Column\", \"children\": [\"name-field\", \"submit-btn\"] },\n        { \"id\": \"name-field\", \"component\": \"TextField\", \"label\": \"Name\", \"text\": { \"path\": \"/form/name\" } },\n        { \"id\": \"submit-btn\", \"component\": \"Button\", \"child\": \"btn-text\", \"action\": { \"event\": { \"name\": \"submit\", \"context\": { \"userName\": { \"path\": \"/form/name\" } } } } },\n        { \"id\": \"btn-text\", \"component\": \"Text\", \"text\": \"Submit\" }\n      ]\n    }\n  },\n  { \"version\": \"v0.9\", \"updateDataModel\": { \"surfaceId\": \"my-form\", \"value\": { \"form\": { \"name\": \"\" } } } }\n]\n\\`\\`\\`\n\nWhen the user types \"Alice\" and clicks Submit, you'll receive: \\`Context: {\"userName\": \"Alice\"}\\`\n\n### Handling User Interactions\n\nWhen a user interacts with a UI surface you rendered (clicks a button, submits a form, etc.),\nyou will see a \\`log_a2ui_event\\` tool call in your conversation history followed by a tool result.\n\nCRITICAL: If the conversation ends with a \\`log_a2ui_event\\` tool call followed by its tool result,\nthis means THE USER JUST PERFORMED AN ACTION and you MUST respond to it immediately.\n\nThe \\`log_a2ui_event\\` tool call is NOT something you initiated - it is automatically injected into\nthe conversation to represent a real user interaction (like clicking a button) that just happened.\n\nWhen the last messages are a \\`log_a2ui_event\\` tool call + result:\n1. The user JUST performed the action described (e.g., clicked a button)\n2. You MUST acknowledge their action and respond appropriately\n3. Look at the action name to understand what they did\n4. Take the appropriate next step based on what that action means in context\n5. Do NOT simply describe what buttons exist - respond to what they clicked!\n\n## JSON Schema Reference\n\nEach message is an object with \\`\"version\": \"v0.9\"\\` and exactly ONE operation key.\n\n### Message Types\n\n**createSurface** - Create a new surface:\n\\`\\`\\`json\n{ \"version\": \"v0.9\", \"createSurface\": { \"surfaceId\": \"my-surface\", \"catalogId\": \"https://a2ui.org/specification/v0_9/basic_catalog.json\" } }\n\\`\\`\\`\n\n**updateComponents** - Set/update components on a surface:\n\\`\\`\\`json\n{ \"version\": \"v0.9\", \"updateComponents\": { \"surfaceId\": \"my-surface\", \"components\": [...] } }\n\\`\\`\\`\n\n**updateDataModel** - Set/update data on a surface (plain JSON):\n\\`\\`\\`json\n{ \"version\": \"v0.9\", \"updateDataModel\": { \"surfaceId\": \"my-surface\", \"path\": \"/\", \"value\": { \"name\": \"Alice\" } } }\n\\`\\`\\`\n\n**deleteSurface** - Delete a surface:\n\\`\\`\\`json\n{ \"version\": \"v0.9\", \"deleteSurface\": { \"surfaceId\": \"my-surface\" } }\n\\`\\`\\`\n\n### Component Format (v0.9 flat)\n\nEach component is a flat object with \\`id\\`, \\`component\\` (type name as string), and properties at top level:\n\\`\\`\\`json\n{ \"id\": \"title\", \"component\": \"Text\", \"text\": \"Hello World\", \"variant\": \"h2\" }\n\\`\\`\\`\n\n### Component Reference\n\n**Content Components:**\n- **Text**: \\`{ component: \"Text\", text: \"string\" | { path: \"/data/key\" }, variant?: \"h1\"|\"h2\"|\"h3\"|\"h4\"|\"h5\"|\"caption\"|\"body\" }\\`\n- **Image**: \\`{ component: \"Image\", url: \"string\" | { path }, fit?: \"contain\"|\"cover\"|\"fill\", variant?: \"icon\"|\"avatar\"|\"smallFeature\"|\"mediumFeature\"|\"largeFeature\"|\"header\" }\\`\n- **Icon**: \\`{ component: \"Icon\", name: \"string\" | { path } }\\` — names: accountCircle, add, arrowBack, arrowForward, attachFile, calendarToday, call, camera, check, close, delete, download, edit, event, error, favorite, favoriteOff, folder, help, home, info, locationOn, lock, lockOpen, mail, menu, moreVert, moreHoriz, notificationsOff, notifications, payment, person, phone, photo, print, refresh, search, send, settings, share, shoppingCart, star, starHalf, starOff, upload, visibility, visibilityOff, warning\n- **Video**: \\`{ component: \"Video\", url: \"string\" | { path } }\\`\n- **AudioPlayer**: \\`{ component: \"AudioPlayer\", url: \"string\" | { path }, description?: \"string\" | { path } }\\`\n- **Divider**: \\`{ component: \"Divider\", axis?: \"horizontal\"|\"vertical\" }\\`\n\n**Layout Components:**\n- **Row**: \\`{ component: \"Row\", children: [\"id1\", \"id2\"] | { componentId, path }, justify?: \"start\"|\"center\"|\"end\"|\"spaceBetween\"|\"spaceAround\"|\"spaceEvenly\", align?: \"start\"|\"center\"|\"end\"|\"stretch\" }\\`\n- **Column**: \\`{ component: \"Column\", children: [\"id1\", \"id2\"] | { componentId, path }, justify?: \"start\"|\"center\"|\"end\"|\"spaceBetween\"|\"spaceAround\"|\"spaceEvenly\", align?: \"start\"|\"center\"|\"end\"|\"stretch\" }\\`\n- **List**: \\`{ component: \"List\", children: [\"id1\"] | { componentId, path }, direction?: \"vertical\"|\"horizontal\", align?: \"start\"|\"center\"|\"end\"|\"stretch\" }\\`\n- **Card**: \\`{ component: \"Card\", child: \"content-id\" }\\`\n- **Tabs**: \\`{ component: \"Tabs\", tabItems: [{ title: \"string\" | { path }, child: \"id\" }] }\\`\n- **Modal**: \\`{ component: \"Modal\", entryPointChild: \"trigger-id\", contentChild: \"content-id\" }\\`\n\n**Interactive Components:**\n- **Button**: \\`{ component: \"Button\", child: \"text-id\", action: { event: { name: \"action_name\", context?: { key: value | { path } } } }, variant?: \"primary\"|\"secondary\"|\"text\" }\\`\n- **TextField**: \\`{ component: \"TextField\", label: \"string\" | { path }, text?: \"string\" | { path }, textFieldType?: \"shortText\"|\"longText\"|\"number\"|\"date\"|\"obscured\" }\\`\n- **CheckBox**: \\`{ component: \"CheckBox\", label: \"string\" | { path }, checked?: boolean | { path } }\\`\n- **Slider**: \\`{ component: \"Slider\", value: number | { path }, minValue?: number, maxValue?: number }\\`\n- **DateTimeInput**: \\`{ component: \"DateTimeInput\", value: \"string\" | { path }, enableDate?: boolean, enableTime?: boolean }\\`\n- **ChoicePicker**: \\`{ component: \"ChoicePicker\", selections: [\"a\"] | { path }, options: [{ label: \"string\" | { path }, value: \"string\" }], maxAllowedSelections?: number }\\`\n---END A2UI JSON SCHEMA---`;\n\n/* v0.8 schema removed */\nconst _REMOVED_V08_SCHEMA = `\"accountCircle\",\"warning\"\n                            ]\n                          },\n                          \"path\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      }\n                    },\n                    \"required\": [\"name\"]\n                  },\n                  \"Video\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"url\": {\n                        \"type\": \"object\",\n                        \"description\": \"The URL of the video to display. This can be a literal string or a reference to a value in the data model ('path', e.g. '/video/url').\",\n                        \"properties\": {\n                          \"literalString\": {\n                            \"type\": \"string\"\n                          },\n                          \"path\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      }\n                    },\n                    \"required\": [\"url\"]\n                  },\n                  \"AudioPlayer\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"url\": {\n                        \"type\": \"object\",\n                        \"description\": \"The URL of the audio to be played. This can be a literal string ('literal') or a reference to a value in the data model ('path', e.g. '/song/url').\",\n                        \"properties\": {\n                          \"literalString\": {\n                            \"type\": \"string\"\n                          },\n                          \"path\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"description\": {\n                        \"type\": \"object\",\n                        \"description\": \"A description of the audio, such as a title or summary. This can be a literal string or a reference to a value in the data model ('path', e.g. '/song/title').\",\n                        \"properties\": {\n                          \"literalString\": {\n                            \"type\": \"string\"\n                          },\n                          \"path\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      }\n                    },\n                    \"required\": [\"url\"]\n                  },\n                  \"Row\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"children\": {\n                        \"type\": \"object\",\n                        \"description\": \"Defines the children. Use 'explicitList' for a fixed set of children, or 'template' to generate children from a data list.\",\n                        \"properties\": {\n                          \"explicitList\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"template\": {\n                            \"type\": \"object\",\n                            \"description\": \"A template for generating a dynamic list of children from a data model list. \\`componentId\\` is the component to use as a template, and \\`dataBinding\\` is the path to the map of components in the data model. Values in the map will define the list of children.\",\n                            \"properties\": {\n                              \"componentId\": {\n                                \"type\": \"string\"\n                              },\n                              \"dataBinding\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"required\": [\"componentId\", \"dataBinding\"]\n                          }\n                        }\n                      },\n                      \"distribution\": {\n                        \"type\": \"string\",\n                        \"description\": \"Defines the arrangement of children along the main axis (horizontally). This corresponds to the CSS 'justify-content' property.\",\n                        \"enum\": [\n                          \"center\",\n                          \"end\",\n                          \"spaceAround\",\n                          \"spaceBetween\",\n                          \"spaceEvenly\",\n                          \"start\"\n                        ]\n                      },\n                      \"alignment\": {\n                        \"type\": \"string\",\n                        \"description\": \"Defines the alignment of children along the cross axis (vertically). This corresponds to the CSS 'align-items' property.\",\n                        \"enum\": [\"start\", \"center\", \"end\", \"stretch\"]\n                      }\n                    },\n                    \"required\": [\"children\"]\n                  },\n                  \"Column\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"children\": {\n                        \"type\": \"object\",\n                        \"description\": \"Defines the children. Use 'explicitList' for a fixed set of children, or 'template' to generate children from a data list.\",\n                        \"properties\": {\n                          \"explicitList\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"template\": {\n                            \"type\": \"object\",\n                            \"description\": \"A template for generating a dynamic list of children from a data model list. \\`componentId\\` is the component to use as a template, and \\`dataBinding\\` is the path to the map of components in the data model. Values in the map will define the list of children.\",\n                            \"properties\": {\n                              \"componentId\": {\n                                \"type\": \"string\"\n                              },\n                              \"dataBinding\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"required\": [\"componentId\", \"dataBinding\"]\n                          }\n                        }\n                      },\n                      \"distribution\": {\n                        \"type\": \"string\",\n                        \"description\": \"Defines the arrangement of children along the main axis (vertically). This corresponds to the CSS 'justify-content' property.\",\n                        \"enum\": [\n                          \"start\",\n                          \"center\",\n                          \"end\",\n                          \"spaceBetween\",\n                          \"spaceAround\",\n                          \"spaceEvenly\"\n                        ]\n                      },\n                      \"alignment\": {\n                        \"type\": \"string\",\n                        \"description\": \"Defines the alignment of children along the cross axis (horizontally). This corresponds to the CSS 'align-items' property.\",\n                        \"enum\": [\"center\", \"end\", \"start\", \"stretch\"]\n                      }\n                    },\n                    \"required\": [\"children\"]\n                  },\n                  \"List\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"children\": {\n                        \"type\": \"object\",\n                        \"description\": \"Defines the children. Use 'explicitList' for a fixed set of children, or 'template' to generate children from a data list.\",\n                        \"properties\": {\n                          \"explicitList\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"template\": {\n                            \"type\": \"object\",\n                            \"description\": \"A template for generating a dynamic list of children from a data model list. \\`componentId\\` is the component to use as a template, and \\`dataBinding\\` is the path to the map of components in the data model. Values in the map will define the list of children.\",\n                            \"properties\": {\n                              \"componentId\": {\n                                \"type\": \"string\"\n                              },\n                              \"dataBinding\": {\n                                \"type\": \"string\"\n                              }\n                            },\n                            \"required\": [\"componentId\", \"dataBinding\"]\n                          }\n                        }\n                      },\n                      \"direction\": {\n                        \"type\": \"string\",\n                        \"description\": \"The direction in which the list items are laid out.\",\n                        \"enum\": [\"vertical\", \"horizontal\"]\n                      },\n                      \"alignment\": {\n                        \"type\": \"string\",\n                        \"description\": \"Defines the alignment of children along the cross axis.\",\n                        \"enum\": [\"start\", \"center\", \"end\", \"stretch\"]\n                      }\n                    },\n                    \"required\": [\"children\"]\n                  },\n                  \"Card\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"child\": {\n                        \"type\": \"string\",\n                        \"description\": \"The ID of the component to be rendered inside the card.\"\n                      }\n                    },\n                    \"required\": [\"child\"]\n                  },\n                  \"Tabs\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"tabItems\": {\n                        \"type\": \"array\",\n                        \"description\": \"An array of objects, where each object defines a tab with a title and a child component.\",\n                        \"items\": {\n                          \"type\": \"object\",\n                          \"properties\": {\n                            \"title\": {\n                              \"type\": \"object\",\n                              \"description\": \"The tab title. Defines the value as either a literal value or a path to data model value (e.g. '/options/title').\",\n                              \"properties\": {\n                                \"literalString\": {\n                                  \"type\": \"string\"\n                                },\n                                \"path\": {\n                                  \"type\": \"string\"\n                                }\n                              }\n                            },\n                            \"child\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"required\": [\"title\", \"child\"]\n                        }\n                      }\n                    },\n                    \"required\": [\"tabItems\"]\n                  },\n                  \"Divider\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"axis\": {\n                        \"type\": \"string\",\n                        \"description\": \"The orientation of the divider.\",\n                        \"enum\": [\"horizontal\", \"vertical\"]\n                      }\n                    }\n                  },\n                  \"Modal\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"entryPointChild\": {\n                        \"type\": \"string\",\n                        \"description\": \"The ID of the component that opens the modal when interacted with (e.g., a button).\"\n                      },\n                      \"contentChild\": {\n                        \"type\": \"string\",\n                        \"description\": \"The ID of the component to be displayed inside the modal.\"\n                      }\n                    },\n                    \"required\": [\"entryPointChild\", \"contentChild\"]\n                  },\n                  \"Button\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"child\": {\n                        \"type\": \"string\",\n                        \"description\": \"The ID of the component to display in the button, typically a Text component.\"\n                      },\n                      \"primary\": {\n                        \"type\": \"boolean\",\n                        \"description\": \"Indicates if this button should be styled as the primary action.\"\n                      },\n                      \"action\": {\n                        \"type\": \"object\",\n                        \"description\": \"The client-side action to be dispatched when the button is clicked. It includes the action's name and an optional context payload.\",\n                        \"properties\": {\n                          \"name\": {\n                            \"type\": \"string\"\n                          },\n                          \"context\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"object\",\n                              \"properties\": {\n                                \"key\": {\n                                  \"type\": \"string\"\n                                },\n                                \"value\": {\n                                  \"type\": \"object\",\n                                  \"description\": \"Defines the value to be included in the context as either a literal value or a path to a data model value (e.g. '/user/name').\",\n                                  \"properties\": {\n                                    \"path\": {\n                                      \"type\": \"string\"\n                                    },\n                                    \"literalString\": {\n                                      \"type\": \"string\"\n                                    },\n                                    \"literalNumber\": {\n                                      \"type\": \"number\"\n                                    },\n                                    \"literalBoolean\": {\n                                      \"type\": \"boolean\"\n                                    }\n                                  }\n                                }\n                              },\n                              \"required\": [\"key\", \"value\"]\n                            }\n                          }\n                        },\n                        \"required\": [\"name\"]\n                      }\n                    },\n                    \"required\": [\"child\", \"action\"]\n                  },\n                  \"CheckBox\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"label\": {\n                        \"type\": \"object\",\n                        \"description\": \"The text to display next to the checkbox. Defines the value as either a literal value or a path to data model ('path', e.g. '/option/label').\",\n                        \"properties\": {\n                          \"literalString\": {\n                            \"type\": \"string\"\n                          },\n                          \"path\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"value\": {\n                        \"type\": \"object\",\n                        \"description\": \"The current state of the checkbox (true for checked, false for unchecked). This can be a literal boolean ('literalBoolean') or a reference to a value in the data model ('path', e.g. '/filter/open').\",\n                        \"properties\": {\n                          \"literalBoolean\": {\n                            \"type\": \"boolean\"\n                          },\n                          \"path\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      }\n                    },\n                    \"required\": [\"label\", \"value\"]\n                  },\n                  \"TextField\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"label\": {\n                        \"type\": \"object\",\n                        \"description\": \"The text label for the input field. This can be a literal string or a reference to a value in the data model ('path, e.g. '/user/name').\",\n                        \"properties\": {\n                          \"literalString\": {\n                            \"type\": \"string\"\n                          },\n                          \"path\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"text\": {\n                        \"type\": \"object\",\n                        \"description\": \"The value of the text field. This can be a literal string or a reference to a value in the data model ('path', e.g. '/user/name').\",\n                        \"properties\": {\n                          \"literalString\": {\n                            \"type\": \"string\"\n                          },\n                          \"path\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"textFieldType\": {\n                        \"type\": \"string\",\n                        \"description\": \"The type of input field to display.\",\n                        \"enum\": [\n                          \"date\",\n                          \"longText\",\n                          \"number\",\n                          \"shortText\",\n                          \"obscured\"\n                        ]\n                      },\n                      \"validationRegexp\": {\n                        \"type\": \"string\",\n                        \"description\": \"A regular expression used for client-side validation of the input.\"\n                      }\n                    },\n                    \"required\": [\"label\"]\n                  },\n                  \"DateTimeInput\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"value\": {\n                        \"type\": \"object\",\n                        \"description\": \"The selected date and/or time value in ISO 8601 format. This can be a literal string ('literalString') or a reference to a value in the data model ('path', e.g. '/user/dob').\",\n                        \"properties\": {\n                          \"literalString\": {\n                            \"type\": \"string\"\n                          },\n                          \"path\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"enableDate\": {\n                        \"type\": \"boolean\",\n                        \"description\": \"If true, allows the user to select a date.\"\n                      },\n                      \"enableTime\": {\n                        \"type\": \"boolean\",\n                        \"description\": \"If true, allows the user to select a time.\"\n                      }\n                    },\n                    \"required\": [\"value\"]\n                  },\n                  \"MultipleChoice\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"selections\": {\n                        \"type\": \"object\",\n                        \"description\": \"The currently selected values for the component. This can be a literal array of strings or a path to an array in the data model('path', e.g. '/hotel/options').\",\n                        \"properties\": {\n                          \"literalArray\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"path\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"options\": {\n                        \"type\": \"array\",\n                        \"description\": \"An array of available options for the user to choose from.\",\n                        \"items\": {\n                          \"type\": \"object\",\n                          \"properties\": {\n                            \"label\": {\n                              \"type\": \"object\",\n                              \"description\": \"The text to display for this option. This can be a literal string or a reference to a value in the data model (e.g. '/option/label').\",\n                              \"properties\": {\n                                \"literalString\": {\n                                  \"type\": \"string\"\n                                },\n                                \"path\": {\n                                  \"type\": \"string\"\n                                }\n                              }\n                            },\n                            \"value\": {\n                              \"type\": \"string\",\n                              \"description\": \"The value to be associated with this option when selected.\"\n                            }\n                          },\n                          \"required\": [\"label\", \"value\"]\n                        }\n                      },\n                      \"maxAllowedSelections\": {\n                        \"type\": \"integer\",\n                        \"description\": \"The maximum number of options that the user is allowed to select.\"\n                      }\n                    },\n                    \"required\": [\"selections\", \"options\"]\n                  },\n                  \"Slider\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"value\": {\n                        \"type\": \"object\",\n                        \"description\": \"The current value of the slider. This can be a literal number ('literalNumber') or a reference to a value in the data model ('path', e.g. '/restaurant/cost').\",\n                        \"properties\": {\n                          \"literalNumber\": {\n                            \"type\": \"number\"\n                          },\n                          \"path\": {\n                            \"type\": \"string\"\n                          }\n                        }\n                      },\n                      \"minValue\": {\n                        \"type\": \"number\",\n                        \"description\": \"The minimum value of the slider.\"\n                      },\n                      \"maxValue\": {\n                        \"type\": \"number\",\n                        \"description\": \"The maximum value of the slider.\"\n                      }\n                    },\n                    \"required\": [\"value\"]\n                  }\n                }\n              }\n            },\n            \"required\": [\"id\", \"component\"]\n          }\n        }\n      },\n      \"required\": [\"surfaceId\", \"components\"]\n    },\n    \"dataModelUpdate\": {\n      \"type\": \"object\",\n      \"description\": \"Updates the data model for a surface.\",\n      \"properties\": {\n        \"surfaceId\": {\n          \"type\": \"string\",\n          \"description\": \"The unique identifier for the UI surface this data model update applies to.\"\n        },\n        \"path\": {\n          \"type\": \"string\",\n          \"description\": \"An optional path to a location within the data model (e.g., '/user/name'). If omitted, or set to '/', the entire data model will be replaced.\"\n        },\n        \"contents\": {\n          \"type\": \"array\",\n          \"description\": \"An array of data entries. Each entry must contain a 'key' and exactly one corresponding typed 'value*' property.\",\n          \"items\": {\n            \"type\": \"object\",\n            \"description\": \"A single data entry. Exactly one 'value*' property should be provided alongside the key.\",\n            \"properties\": {\n              \"key\": {\n                \"type\": \"string\",\n                \"description\": \"The key for this data entry.\"\n              },\n              \"valueString\": {\n                \"type\": \"string\"\n              },\n              \"valueNumber\": {\n                \"type\": \"number\"\n              },\n              \"valueBoolean\": {\n                \"type\": \"boolean\"\n              },\n              \"valueMap\": {\n                \"description\": \"Represents a map as an adjacency list.\",\n                \"type\": \"array\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"description\": \"One entry in the map. Exactly one 'value*' property should be provided alongside the key.\",\n                  \"properties\": {\n                    \"key\": {\n                      \"type\": \"string\"\n                    },\n                    \"valueString\": {\n                      \"type\": \"string\"\n                    },\n                    \"valueNumber\": {\n                      \"type\": \"number\"\n                    },\n                    \"valueBoolean\": {\n                      \"type\": \"boolean\"\n                    }\n                  },\n                  \"required\": [\"key\"]\n                }\n              }\n            },\n            \"required\": [\"key\"]\n          }\n        }\n      },\n      \"required\": [\"contents\", \"surfaceId\"]\n    },\n    \"deleteSurface\": {\n      \"type\": \"object\",\n      \"description\": \"Signals the client to delete the surface identified by 'surfaceId'.\",\n      \"properties\": {\n        \"surfaceId\": {\n          \"type\": \"string\",\n          \"description\": \"The unique identifier for the UI surface to be deleted.\"\n        }\n      },\n---END_REMOVED---`;\n\n/**\n * The container key used to wrap A2UI operations for explicit detection.\n * Must match the key used by copilotkit.a2ui.render() (Python SDK)\n * and A2UIMessageRenderer (React).\n */\nexport const A2UI_OPERATIONS_KEY = \"a2ui_operations\";\n\n/**\n * Parsed A2UI container result.\n */\nexport interface A2UIParseResult {\n  operations: Array<Record<string, unknown>>;\n}\n\n/**\n * Try to parse text as an A2UI container.\n * Returns operations if the text contains a valid { a2ui_operations: [...] }\n * container, or null otherwise.\n */\nexport function tryParseA2UIOperations(text: string): A2UIParseResult | null {\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(text);\n  } catch {\n    // Not valid JSON at all. The legitimate \"double-encoded\" case is handled\n    // below — when ``parsed`` is a string after one successful JSON.parse, we\n    // try parsing it again. A second nested parse in this catch is dead code:\n    // ``JSON.parse(text)`` just threw, so calling it again on the same input\n    // throws the same way.\n    return null;\n  }\n\n  if (\n    typeof parsed === \"object\" &&\n    parsed !== null &&\n    !Array.isArray(parsed) &&\n    Array.isArray((parsed as Record<string, unknown>)[A2UI_OPERATIONS_KEY])\n  ) {\n    const obj = parsed as Record<string, unknown>;\n    // Filter non-object entries — downstream consumers (getOperationSurfaceId,\n    // createA2UIActivityEvents) read properties off each op and would crash on\n    // ``null``, primitives, or arrays sitting in the array.\n    const rawOps = obj[A2UI_OPERATIONS_KEY] as Array<unknown>;\n    const operations = rawOps.filter(\n      (op): op is Record<string, unknown> =>\n        typeof op === \"object\" && op !== null && !Array.isArray(op),\n    );\n    const result: A2UIParseResult = { operations };\n\n    return result;\n  }\n\n  // Check if it's a string that needs another parse (double-serialized)\n  if (typeof parsed === \"string\") {\n    try {\n      const inner = JSON.parse(parsed);\n      if (\n        typeof inner === \"object\" &&\n        inner !== null &&\n        !Array.isArray(inner) &&\n        Array.isArray((inner as Record<string, unknown>)[A2UI_OPERATIONS_KEY])\n      ) {\n        const obj = inner as Record<string, unknown>;\n        const rawOps = obj[A2UI_OPERATIONS_KEY] as Array<unknown>;\n        const operations = rawOps.filter(\n          (op): op is Record<string, unknown> =>\n            typeof op === \"object\" && op !== null && !Array.isArray(op),\n        );\n        const result: A2UIParseResult = { operations };\n        return result;\n      }\n    } catch {\n      // Not double-encoded either\n    }\n  }\n\n  return null;\n}\n\n/**\n * Extract surfaceId from a single A2UI operation (v0.9 keys)\n */\nexport function getOperationSurfaceId(\n  operation: Record<string, unknown>,\n): string | undefined {\n  // v0.9 message types\n  const createSurface = operation.createSurface as\n    | { surfaceId?: string }\n    | undefined;\n  const updateComponents = operation.updateComponents as\n    | { surfaceId?: string }\n    | undefined;\n  const updateDataModel = operation.updateDataModel as\n    | { surfaceId?: string }\n    | undefined;\n  const deleteSurface = operation.deleteSurface as\n    | { surfaceId?: string }\n    | undefined;\n\n  return (\n    createSurface?.surfaceId ??\n    updateComponents?.surfaceId ??\n    updateDataModel?.surfaceId ??\n    deleteSurface?.surfaceId\n  );\n}\n\n/**\n * Extract surface IDs from A2UI messages\n */\nexport function extractSurfaceIds(\n  messages: Array<{ [key: string]: unknown }>,\n): string[] {\n  const surfaceIds = new Set<string>();\n  for (const msg of messages) {\n    const surfaceId = getOperationSurfaceId(msg);\n    if (surfaceId) {\n      surfaceIds.add(surfaceId);\n    }\n  }\n  return Array.from(surfaceIds);\n}\n\nexport {\n  extractCompleteItems,\n  extractCompleteItemsWithStatus,\n  extractCompleteObject,\n  extractCompleteA2UIOperations,\n  extractDataArrayItems,\n  extractStringField,\n} from \"./json-extract\";\n"],"mappings":"6bAAA,OAAS,cAAAA,MAAkB,SAC3B,OACE,cAAAC,GAIA,aAAAC,MAUK,gBACP,OAAS,cAAAC,OAAkB,OCZpB,IAAMC,EAAwB,cAKxBC,EAA2B,iBAQ3BC,GAAyB,CACpC,KAAMF,EACN,YACE,8HAEF,WAAY,CACV,KAAM,SACN,WAAY,CACV,UAAW,CACT,KAAM,SACN,YAAa,4BACf,EACA,WAAY,CACV,KAAM,QACN,YACE,mFACF,MAAO,CAAE,KAAM,QAAS,CAC1B,EACA,KAAM,CACJ,KAAM,SACN,YACE,8LAGJ,CACF,EACA,SAAU,CAAC,YAAa,YAAY,CACtC,CACF,EAOaG,GAA+BC,GAAqB,kBAChDA,CAAQ;AAAA;AAAA,uDAE8BA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAiC/CA,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;wECzFxB,OAAOC,MAAc,WAWd,SAASC,GAAqBC,EAAiBC,EAAmC,CAXzF,IAAAC,EAYE,IAAMC,EAASC,EAA+BJ,EAASC,CAAO,EAC9D,OAAOC,EAAAC,GAAA,YAAAA,EAAQ,QAAR,KAAAD,EAAiB,IAC1B,CAaA,SAASG,EAAuBL,EAAiBM,EAAqB,CACpE,IAAMC,EAAS,IAAID,CAAG,IAClBE,EAAI,EACJC,EAAc,EACdC,EAAa,EACbC,EAAW,GACXC,EAAS,GAEb,KAAOJ,EAAIR,EAAQ,QAAQ,CACzB,IAAMa,EAAKb,EAAQQ,CAAC,EAEpB,GAAII,EAAQ,CACVA,EAAS,GACTJ,IACA,QACF,CAEA,GAAIG,EAAU,CACRE,IAAO,KACTD,EAAS,GACAC,IAAO,MAChBF,EAAW,IAEbH,IACA,QACF,CAEA,GAAIK,IAAO,IAAK,CAQd,GAAIJ,IAAgB,GAAKC,IAAe,GAAKV,EAAQ,WAAWO,EAAQC,CAAC,EAAG,CAC1E,IAAIM,EAAIN,EAAID,EAAO,OACnB,KAAOO,EAAId,EAAQ,SAAWA,EAAQc,CAAC,IAAM,KAAOd,EAAQc,CAAC,IAAM;AAAA,GAAQd,EAAQc,CAAC,IAAM,MAAQd,EAAQc,CAAC,IAAM,MAC/GA,IAEF,GAAIA,EAAId,EAAQ,QAAUA,EAAQc,CAAC,IAAM,IAAK,CAI5C,IADAA,IACOA,EAAId,EAAQ,SAAWA,EAAQc,CAAC,IAAM,KAAOd,EAAQc,CAAC,IAAM;AAAA,GAAQd,EAAQc,CAAC,IAAM,MAAQd,EAAQc,CAAC,IAAM,MAC/GA,IAEF,OAAOA,EAAId,EAAQ,OAASc,EAAI,EAClC,CACF,CACAH,EAAW,GACXH,IACA,QACF,CAEIK,IAAO,IAAKJ,IACPI,IAAO,IAAKJ,IACZI,IAAO,IAAKH,IACZG,IAAO,KAAKH,IAErBF,GACF,CAEA,MAAO,EACT,CAaO,SAASO,EAAsBf,EAAiBC,EAAiD,CACtG,IAAMe,EAAaX,EAAuBL,EAASC,CAAO,EAI1D,GAHIe,IAAe,IAGfhB,EAAQgB,CAAU,IAAM,IAAK,OAAO,KAGxC,IAAMC,EAASjB,EAAQ,UAAUgB,CAAU,EACrCE,EAASpB,EAAS,OAAO,EAE3BW,EAAc,EACdU,EAAe,GACfC,EAAgB,GAEpBF,EAAO,QAAU,IAAM,CACrBA,EAAO,MAAQ,IACjB,EAEAA,EAAO,aAAe,IAAM,CAC1BT,GACF,EAEAS,EAAO,cAAgB,IAAM,CAC3BT,IACIA,IAAgB,GAAK,CAACU,IACxBA,EAAe,GACfC,EAAgBF,EAAO,SAE3B,EAGAA,EAAO,YAAc,IAAM,CAAC,EAC5BA,EAAO,aAAe,IAAM,CAAC,EAC7BA,EAAO,QAAU,IAAM,CAAC,EACxBA,EAAO,MAAQ,IAAM,CAAC,EAEtB,GAAI,CACFA,EAAO,MAAMD,CAAM,CACrB,OAAQI,EAAA,CAER,CAEA,GAAI,CAACF,EAAc,OAAO,KAE1B,IAAMG,EAASL,EAAO,UAAU,EAAGG,CAAa,EAChD,GAAI,CACF,OAAO,KAAK,MAAME,CAAM,CAC1B,OAAQD,EAAA,CACN,OAAO,IACT,CACF,CAOO,SAASjB,EACdJ,EACAC,EACmD,CAKnD,IAAMsB,EAAelB,EAAuBL,EAASC,CAAO,EAE5D,GADIsB,IAAiB,IACjBvB,EAAQuB,CAAY,IAAM,IAAK,OAAO,KAG1C,IAAMN,EAASjB,EAAQ,UAAUuB,CAAY,EACvCL,EAASpB,EAAS,OAAO,EAE3BW,EAAc,EACdC,EAAa,EACbc,EAAkB,GAClBC,EAAc,GAElBP,EAAO,QAAU,IAAM,CACrBA,EAAO,MAAQ,IACjB,EAEAA,EAAO,YAAc,IAAM,CACzBR,GACF,EAEAQ,EAAO,aAAe,IAAM,CACtBR,IAAe,IACjBe,EAAc,IAEhBf,GACF,EAEAQ,EAAO,aAAe,IAAM,CAC1BT,GACF,EAEAS,EAAO,cAAgB,IAAM,CACvBT,IAAgB,GAAKC,IAAe,IAGtCc,EAAkBN,EAAO,UAE3BT,GACF,EAEAS,EAAO,QAAU,IAAM,CAEjBT,IAAgB,GAAKC,IAAe,IACtCc,EAAkBN,EAAO,SAE7B,EAEA,GAAI,CACFA,EAAO,MAAMD,CAAM,CACrB,OAAQI,EAAA,CAER,CAEA,GAAIG,IAAoB,GAAI,OAAO,KAGnC,IAAME,EAAWT,EAAO,UAAU,EAAGO,CAAe,EAAI,IACxD,GAAI,CAEF,MAAO,CAAE,MADK,KAAK,MAAME,CAAQ,EACjB,YAAAD,CAAY,CAC9B,OAAQJ,EAAA,CACN,OAAO,IACT,CACF,CAiBO,SAASM,EACd3B,EACA4B,EACmD,CAInD,IAAMC,EAAiBxB,EAAuBL,EAAS,MAAM,EAE7D,GADI6B,IAAmB,IACnB7B,EAAQ6B,CAAc,IAAM,IAAK,OAAO,KAK5C,IAAMC,EAAa9B,EAAQ,UAAU6B,CAAc,EACnD,OAAOzB,EAA+B0B,EAAYF,CAAQ,CAC5D,CAMO,SAASG,EAAmBC,EAAqB1B,EAA4B,CAClF,IAAMY,EAASpB,EAAS,OAAO,EAC3BK,EAAwB,KACxB8B,EAAY,EACZC,EAA4B,KAC5BC,EAAQ,GAEZjB,EAAO,QAAU,IAAM,CACrBA,EAAO,MAAQ,IACjB,EAEAA,EAAO,aAAgBkB,GAAsB,CAC3CH,IACIG,IAAa,QAAaH,IAAc,IAC1CC,EAAaE,EAEjB,EAEAlB,EAAO,cAAgB,IAAM,CAC3Be,GACF,EAEAf,EAAO,MAASmB,GAAc,CACxBJ,IAAc,IAChBC,EAAaG,EAEjB,EAEAnB,EAAO,QAAWoB,GAAmB,CAC/B,CAACH,GAASF,IAAc,GAAKC,IAAe5B,GAAO,OAAOgC,GAAU,WACtEnC,EAASmC,EACTH,EAAQ,GAEZ,EAEA,GAAI,CACFjB,EAAO,MAAMc,CAAW,CAC1B,OAAQX,EAAA,CAER,CAEA,OAAOlB,CACT,CAcO,SAASoC,GAA8BC,EAA4D,CAIxG,IAAMC,EAAa,cACbC,EAASF,EAAY,QAAQC,CAAU,EAC7C,GAAIC,IAAW,GAAI,OAAO,KAE1B,IAAMC,EAAWH,EAAY,QAAQ,IAAKE,EAASD,EAAW,MAAM,EACpE,GAAIE,IAAa,GAAI,OAAO,KAE5B,IAAIC,EAAa,GACjB,QAASpC,EAAImC,EAAW,EAAGnC,EAAIgC,EAAY,OAAQhC,IAAK,CACtD,GAAIgC,EAAYhC,CAAC,IAAM,IAAK,CAC1BoC,EAAapC,EAAI,EACjB,KACF,CACA,GAAIgC,EAAYhC,CAAC,IAAM,KAAOgC,EAAYhC,CAAC,IAAM;AAAA,GAAQgC,EAAYhC,CAAC,IAAM,MAAQgC,EAAYhC,CAAC,IAAM,IACrG,OAAO,IAEX,CACA,GAAIoC,IAAe,GAAI,OAAO,KAE9B,IAAMC,EAAYC,GAAmBN,EAAaI,CAAU,EAG5D,OAAOG,GAA0BF,CAAS,CAC5C,CAOA,SAASC,GAAmBE,EAAaC,EAA0B,CACjE,IAAI9C,EAAS,GACTK,EAAIyC,EACR,KAAOzC,EAAIwC,EAAI,QAAQ,CACrB,IAAMnC,EAAKmC,EAAIxC,CAAC,EAChB,GAAIK,IAAO,KAAM,CACf,GAAIL,EAAI,GAAKwC,EAAI,OAAQ,MACzB,IAAME,EAAOF,EAAIxC,EAAI,CAAC,EACtB,OAAQ0C,EAAM,CACZ,IAAK,IAAK/C,GAAU,IAAKK,GAAK,EAAG,MACjC,IAAK,KAAML,GAAU,KAAMK,GAAK,EAAG,MACnC,IAAK,IAAKL,GAAU,IAAKK,GAAK,EAAG,MACjC,IAAK,IAAKL,GAAU;AAAA,EAAMK,GAAK,EAAG,MAClC,IAAK,IAAKL,GAAU,KAAMK,GAAK,EAAG,MAClC,IAAK,IAAKL,GAAU,IAAMK,GAAK,EAAG,MAClC,IAAK,IAAKL,GAAU,KAAMK,GAAK,EAAG,MAClC,IAAK,IAAKL,GAAU,KAAMK,GAAK,EAAG,MAClC,IAAK,IAAK,CACR,GAAIA,EAAI,EAAIwC,EAAI,OAAQ,CACtB,IAAMG,EAAMH,EAAI,UAAUxC,EAAI,EAAGA,EAAI,CAAC,EACtCL,GAAU,OAAO,aAAa,SAASgD,EAAK,EAAE,CAAC,EAC/C3C,GAAK,CACP,KACE,QAAOL,EAET,KACF,CACA,QACEA,GAAU+C,EACV1C,GAAK,EACL,KACJ,CACF,KAAO,IAAIK,IAAO,IAChB,MAEAV,GAAUU,EACVL,IAEJ,CACA,OAAOL,CACT,CAMA,SAAS4C,GAA0BF,EAA0D,CAC3F,IAAMtB,EAAesB,EAAU,QAAQ,GAAG,EAC1C,GAAItB,IAAiB,GAAI,OAAO,KAEhC,IAAMN,EAAS4B,EAAU,UAAUtB,CAAY,EACzCL,EAASpB,EAAS,OAAO,EAC3BW,EAAc,EACdC,EAAa,EACbc,EAAkB,GAEtBN,EAAO,QAAU,IAAM,CACrBA,EAAO,MAAQ,IACjB,EAEAA,EAAO,YAAc,IAAM,CACzBR,GACF,EAEAQ,EAAO,aAAe,IAAM,CAC1BR,GACF,EAEAQ,EAAO,aAAe,IAAM,CAC1BT,GACF,EAEAS,EAAO,cAAgB,IAAM,CACvBT,IAAgB,GAAKC,IAAe,IACtCc,EAAkBN,EAAO,UAE3BT,GACF,EAEA,GAAI,CACFS,EAAO,MAAMD,CAAM,CACrB,OAAQI,EAAA,CAER,CAEA,GAAIG,IAAoB,GAAI,OAAO,KAEnC,IAAME,EAAWT,EAAO,UAAU,EAAGO,CAAe,EAAI,IACxD,GAAI,CACF,OAAO,KAAK,MAAME,CAAQ,CAC5B,OAAQL,EAAA,CACN,OAAO,IACT,CACF,CCxbO,IAAM+B,GAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;4BAgzBpB,IAAMC,EAAsB,kBAc5B,SAASC,GAAuBC,EAAsC,CAC3E,IAAIC,EACJ,GAAI,CACFA,EAAS,KAAK,MAAMD,CAAI,CAC1B,OAAQ,GAMN,OAAO,IACT,CAEA,GACE,OAAOC,GAAW,UAClBA,IAAW,MACX,CAAC,MAAM,QAAQA,CAAM,GACrB,MAAM,QAASA,EAAmCH,CAAmB,CAAC,EAatE,MAFgC,CAAE,WATtBG,EAIOH,CAAmB,EACZ,OACvBI,GACC,OAAOA,GAAO,UAAYA,IAAO,MAAQ,CAAC,MAAM,QAAQA,CAAE,CAC9D,CAC6C,EAM/C,GAAI,OAAOD,GAAW,SACpB,GAAI,CACF,IAAME,EAAQ,KAAK,MAAMF,CAAM,EAC/B,GACE,OAAOE,GAAU,UACjBA,IAAU,MACV,CAAC,MAAM,QAAQA,CAAK,GACpB,MAAM,QAASA,EAAkCL,CAAmB,CAAC,EASrE,MADgC,CAAE,WANtBK,EACOL,CAAmB,EACZ,OACvBI,GACC,OAAOA,GAAO,UAAYA,IAAO,MAAQ,CAAC,MAAM,QAAQA,CAAE,CAC9D,CAC6C,CAGjD,OAAQ,GAER,CAGF,OAAO,IACT,CAKO,SAASE,EACdC,EACoB,CA/4BtB,IAAAC,EAAAC,EAAAC,EAi5BE,IAAMC,EAAgBJ,EAAU,cAG1BK,EAAmBL,EAAU,iBAG7BM,EAAkBN,EAAU,gBAG5BO,EAAgBP,EAAU,cAIhC,OACEG,GAAAD,GAAAD,EAAAG,GAAA,YAAAA,EAAe,YAAf,KAAAH,EACAI,GAAA,YAAAA,EAAkB,YADlB,KAAAH,EAEAI,GAAA,YAAAA,EAAiB,YAFjB,KAAAH,EAGAI,GAAA,YAAAA,EAAe,SAEnB,CAKO,SAASC,GACdC,EACU,CACV,IAAMC,EAAa,IAAI,IACvB,QAAWC,KAAOF,EAAU,CAC1B,IAAMG,EAAYb,EAAsBY,CAAG,EACvCC,GACFF,EAAW,IAAIE,CAAS,CAE5B,CACA,OAAO,MAAM,KAAKF,CAAU,CAC9B,CH15BA,OAAS,0BAAAG,GAAwB,qBAAAC,OAAqD,sBAOtF,SAASC,GAAwBC,EAA+D,CAjChG,IAAAC,EAAAC,EAkCE,GAAI,OAAOF,GAAY,SAAU,OAAO,KACxC,GAAI,CACF,IAAMG,EAAS,KAAK,MAAMH,CAAO,EACjC,GAAIG,GAAU,OAAOA,GAAW,UAAaA,EAAe,OAAS,0BACnE,MAAO,CAAE,MAAO,QAAQF,EAAAE,EAAe,QAAf,KAAAF,EAAwB,wBAAwB,EAAG,UAAWC,EAAAC,EAAe,WAAf,KAAAD,EAA2B,CAAC,CAAE,CAExH,OAAQE,EAAA,CAER,CACA,OAAO,IACT,CAUO,IAAMC,EAAmB,eAOnBC,EAAkC,wJAmB/C,SAASC,GAAyBC,EAA0C,CAC1E,IAAMC,GAASD,EAAM,SAAW,CAAC,GAAG,KACjCE,GAAMA,EAAE,cAAgBJ,CAC3B,EACA,GAAI,GAACG,GAAS,OAAOA,EAAM,OAAU,UACrC,GAAI,CACF,IAAMN,EAAS,KAAK,MAAMM,EAAM,KAAK,EAC/BE,EAAMR,GAAA,YAAAA,EAA2C,UACvD,OAAO,OAAOQ,GAAO,UAAYA,EAAG,OAAS,EAAIA,EAAK,MACxD,OAAQ,GACN,MACF,CACF,CAoBA,SAASC,GAAsBC,EAA2D,CACxF,QAAWC,KAAQD,EAAY,CAC7B,IAAME,EAAYD,GAAA,YAAAA,EAAc,SAChC,GACEC,GACA,OAAOA,GAAa,UACpB,CAAC,MAAM,QAAQA,CAAQ,GACvB,OAAOA,EAAS,MAAS,UACzBA,EAAS,KAAK,OAAS,EAEvB,OAAOA,EAAS,KAAK,QAAQ,MAAO,EAAE,CAE1C,CACA,OAAO,IACT,CAMO,IAAMC,GAAN,cAA6BC,EAAW,CAG7C,YAAYC,EAA+B,CAAC,EAAG,CAC7C,MAAM,EACN,KAAK,OAASA,CAChB,CAOQ,sBAA0D,CAChE,IAAMC,EAAS,KAAK,OAAO,OAC3B,GACEA,GACA,CAAC,MAAM,QAAQA,CAAM,GACrBA,EAAO,YACP,OAAO,KAAKA,EAAO,UAAU,EAAE,OAAS,EAExC,MAAO,CAAE,WAAYA,EAAO,UAAkD,CAGlF,CAmBQ,uBAAuBC,EAAapB,EAAyD,CA/KvG,IAAAC,EAgLI,IAAMoB,GAAgBpB,EAAA,KAAK,OAAO,WAAZ,YAAAA,EAAsB,cAC5C,MAAO,CACL,KAAMqB,EAAU,kBAChB,UAAW,gBAAgBF,CAAG,GAC9B,aAAcf,EACd,QAASgB,EAAgBE,EAAAC,EAAA,GAAKxB,GAAL,CAAc,cAAAqB,CAAc,GAAIrB,EACzD,QAAS,EACX,CACF,CAKA,IAAIQ,EAAsBiB,EAA4C,CAMpE,IAAMC,EAAoBnB,GAAyBC,CAAK,EAGlDmB,EAAgB,KAAK,kBAAkBnB,CAAK,EAG5CoB,EAAa,KAAK,oBAAoBD,CAAa,EAGnDE,EAAa,KAAK,OAAO,eAC3B,KAAK,qBAAqB,KAAK,kBAAkBD,CAAU,CAAC,EAC5DA,EAGJ,OAAO,KAAK,cAAc,KAAK,iBAAiBC,EAAYJ,CAAI,EAAGC,CAAiB,CACtF,CAUQ,oBAAoBlB,EAAqC,CA5NnE,IAAAP,EAoOI,GAPI,CAAC,KAAK,OAAO,SAID,MAAM,QAAQ,KAAK,OAAO,MAAM,EAC5C,KAAK,OAAO,OAAO,SAAW,EAC9B,OAAO,MAAKA,EAAA,KAAK,OAAO,OAAO,aAAnB,KAAAA,EAAiC,CAAC,CAAC,EAAE,SAAW,GAE9D,OAAOO,EAGT,IAAMsB,EAAgB,CACpB,YAAaxB,EACb,MAAO,KAAK,UAAU,KAAK,OAAO,MAAM,CAC1C,EAGMyB,GAAYvB,EAAM,SAAW,CAAC,GAAG,OACpCE,GAAMA,EAAE,cAAgBJ,CAC3B,EAEA,OAAOiB,EAAAC,EAAA,GACFhB,GADE,CAEL,QAAS,CAAC,GAAGuB,EAAUD,CAAa,CACtC,EACF,CAKQ,kBAAkBtB,EAAqC,CA3PjE,IAAAP,EA4PI,IAAM+B,EAAiBxB,EAAM,eACvByB,GAAahC,EAAA+B,GAAA,YAAAA,EAAgB,aAAhB,YAAA/B,EAA4B,WAE/C,GAAI,CAACgC,EACH,OAAOzB,EAIT,IAAM0B,EAAqBC,EAAW,EAChCC,EAAaD,EAAW,EACxBE,EAAgBF,EAAW,EAG3BG,EAA8C,CAClD,GAAIJ,EACJ,KAAM,YACN,QAAS,GACT,UAAW,CACT,CACE,GAAIE,EACJ,KAAM,WACN,SAAU,CACR,KAAMG,EACN,UAAW,KAAK,UAAUN,CAAU,CACtC,CACF,CACF,CACF,EAGMO,EAAgB,KAAK,uBAAuBP,CAAU,EACtDQ,EAAoC,CACxC,GAAIJ,EACJ,KAAM,OACN,WAAYD,EACZ,QAASI,CACX,EAGME,EAAsB,CAC1B,GAAIlC,EAAM,UAAY,CAAC,EACvB8B,EACAG,CACF,EAEA,OAAOlB,EAAAC,EAAA,GACFhB,GADE,CAEL,SAAAkC,CACF,EACF,CAKQ,uBAAuBC,EAAgC,CAlTjE,IAAA1C,EAAAC,EAmTI,IAAM0C,GAAa3C,EAAA0C,EAAO,OAAP,KAAA1C,EAAe,iBAC5B4C,GAAY3C,EAAAyC,EAAO,YAAP,KAAAzC,EAAoB,kBAChC4C,EAAcH,EAAO,kBACrBI,EAAaJ,EAAO,QAAU,KAAK,UAAUA,EAAO,OAAO,EAAI,KAEjEK,EAAU,0BAA0BJ,CAAU,iBAAiBC,CAAS,IAC5E,OAAIC,IACFE,GAAW,gBAAgBF,CAAW,KAExCE,GAAW,cAAcD,CAAU,GAC5BC,CACT,CAOQ,kBAAkBxC,EAAqC,CArUjE,IAAAP,EAAAC,EAsUI,IAAM+C,EAAW,OAAO,KAAK,OAAO,gBAAmB,SACnD,KAAK,OAAO,eACZC,EACEC,EAAa5B,EAAAC,EAAA,GAAK4B,IAAL,CAAuB,KAAMH,CAAS,GAEnDI,IAAiBpD,EAAAO,EAAM,QAAN,KAAAP,EAAe,CAAC,GAAG,OAAQqD,GAAMA,EAAE,OAASL,CAAQ,EAC3E,OAAO1B,EAAAC,EAAA,GACFhB,GADE,CAEL,eAAgBe,EAAAC,EAAA,IACVtB,EAAAM,EAAM,iBAAN,KAAAN,EAAwB,CAAC,GADf,CAEd,eAAgB,KAAK,OAAO,cAC9B,GACA,MAAO,CAAC,GAAGmD,EAAeF,CAAI,CAChC,EACF,CAOQ,qBAAqB3C,EAAqC,CAChE,IAAMyC,EAAW,OAAO,KAAK,OAAO,gBAAmB,SACnD,KAAK,OAAO,eACZC,EAEEK,EACJ,mDAA8CN,CAAQ,yBAGlDlB,GAAYvB,EAAM,SAAW,CAAC,GAAG,OACpCE,GAAMA,EAAE,cAAgB6C,CAC3B,EAEA,OAAOhC,EAAAC,EAAA,GACFhB,GADE,CAEL,QAAS,CAAC,GAAGuB,EAAU,CACrB,YAAawB,EACb,MAAOC,GAA4BP,CAAQ,CAC7C,CAAC,CACH,EACF,CAMQ,cAAcQ,EAAoC/B,EAAmD,CArX/G,IAAAzB,EAkYI,IAAMyD,EAAgB,IAAI,KAAIzD,EAAA,KAAK,OAAO,gBAAZ,KAAAA,EAA6B,CAACiD,CAAqB,CAAC,EAClF,GAAI,KAAK,OAAO,eAAgB,CAC9B,IAAMS,EACJ,OAAO,KAAK,OAAO,gBAAmB,UAAY,KAAK,OAAO,eAAe,OAAS,EAClF,KAAK,OAAO,eACZT,EACNQ,EAAc,IAAIC,CAAY,CAChC,CAEA,OAAO,IAAIC,GAAuBC,GAAe,CA3YrD,IAAA5D,EAAAC,EAAA4D,EA4YM,IAAIC,EAAyC,KAsBvCC,EAAqB,IAAI,IAYzBC,IAAqBhE,EAAA,KAAK,OAAO,WAAZ,YAAAA,EAAsB,sBAAuB,GAClEiE,GAAcJ,GAAA5D,EAAA,KAAK,OAAO,WAAZ,YAAAA,EAAsB,cAAtB,KAAA4D,EAAqCK,GACnDC,EAAkB,GASlBC,EAAmB,IAAI,IACvBC,EAAoB,IAAI,IACxBC,EAAqB,IAAI,IACzBC,GAAkBC,GAAiB,KAAK,MAAMA,EAAK,OAAS,CAAC,EAa7DC,EAAqB,IAAI,IAYzBC,GAAoB,IAAI,IAAY,CACxC,GAAGjB,EACHnB,CACF,CAAC,EACGqC,EAAoC,KAElCC,GAAepB,EAAO,UAAU,CACpC,KAAOqB,GAAmB,CA5dlC,IAAA7E,EAAAC,EAAA4D,GAAAiB,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GA6dU,IAAMC,EAAQR,EAAe,MAE7B,GAAIQ,EAAM,OAAShE,EAAU,gBAAiB,CAC5C,IAAMiE,EAAaD,EAMnB,GAAI5B,EAAc,IAAI6B,EAAW,YAAY,EAAG,CAC9CvB,EAAmB,IAAIuB,EAAW,WAAY,CAC5C,OAAQ,KAAM,KAAM,GACpB,YAAaX,EACb,kBAAmB,GACnB,mBAAoB,GACpB,aAAc,QAAS,eAAgB,EAAG,aAAc,EAC1D,CAAC,EAOD,IAAMxD,EAAMwD,GAAA,KAAAA,EAAsBW,EAAW,WACvCC,IAAWvF,EAAAqE,EAAkB,IAAIlD,CAAG,IAAzB,KAAAnB,EAA8B,GAAK,EACpDqE,EAAkB,IAAIlD,EAAKoE,CAAO,EAClCjB,EAAmB,IAAInD,EAAK,CAAC,EACxBiD,EAAiB,IAAIjD,CAAG,GAC3ByC,EAAW,KAAK,KAAK,uBAAuBzC,EAAK,CAAE,OAAQ,UAAW,CAAC,CAAC,CAE5E,MAAYuD,GAAkB,IAAIY,EAAW,YAAY,IAGvDX,EAAqBW,EAAW,WAEpC,CAGA,GAAID,EAAM,OAAShE,EAAU,eAAgB,CAC3C,IAAMmE,EAAYH,EAGZI,EAAY1B,EAAmB,IAAIyB,EAAU,UAAU,EAC7D,GAAIC,EAAW,CACbA,EAAU,MAAQD,EAAU,MAU5B,IAAME,GAAWzF,EAAAwF,EAAU,cAAV,KAAAxF,EAAyBuF,EAAU,WACpD,GACExB,GACA,CAACyB,EAAU,mBACX,CAACA,EAAU,oBACX,CAACA,EAAU,cACX,CAACrB,EAAiB,IAAIsB,CAAQ,EAC9B,CACA,IAAMC,EAASpB,GAAekB,EAAU,IAAI,EACxCE,IAAU9B,GAAAS,EAAmB,IAAIoB,CAAQ,IAA/B,KAAA7B,GAAoC,IAAMM,IACtDG,EAAmB,IAAIoB,EAAUC,CAAM,EACvC/B,EAAW,KACT,KAAK,uBAAuB8B,EAAU,CACpC,OAAQ,WACR,eAAgBC,CAClB,CAAC,CACH,EAEJ,CAKA,IAAMC,GAAuBJ,EAAU,MAAM,SAAS,GAAG,EACnDK,EAAyBL,EAAU,MAAM,SAAS,GAAG,EACrDM,EAAyBF,IAAwBC,EAGjDE,EAAgBP,EAAU,MAAM,SAAS,GAAG,EAElD,GAAIM,GAA0BC,EAAe,CAC3C,IAAMnD,EAAYoD,EAAmBP,EAAU,KAAM,WAAW,EAGhE,GAAI7C,EAAW,CAkBb,IAAMqD,EACJ,KAAK,OAAO,kBAAoB,KAAK,OAAO,iBAAiB,OAAS,EAClE,KAAK,OAAO,iBACZ,OACAC,EAAoBF,EAAmBP,EAAU,KAAM,WAAW,EAClEU,GACJrB,GAAAmB,GAAA,KAAAA,EACAxE,IADA,KAAAqD,GAECoB,GAAqBA,IAAsB,QACxCA,EACA,yDAKN,GAAI,CAACT,EAAU,mBAAqB,CAACA,EAAU,mBAAoB,CACjE,IAAMW,EAASC,EAA+BZ,EAAU,KAAM,YAAY,EAC1E,GACEW,GACAA,EAAO,aACPA,EAAO,MAAM,OAAS,GACtBA,EAAO,MAAM,MACV3F,GAAMA,GAAK,OAAOA,GAAM,UAAY,OAAQA,EAAU,WAAc,QACvE,EACA,CACA,IAAMG,EAAawF,EAAO,MASpBE,EAAaC,GAAuB,CACxC,WAAA3F,EACA,QAAS,KAAK,qBAAqB,EACnC,iBAAkB,EACpB,CAAC,EACD,GAAI0F,EAAW,MACbb,EAAU,OAAS,CAAE,UAAA7C,EAAW,UAAAuD,EAAW,WAAAvF,CAAW,EACtD6E,EAAU,cAAeV,GAAApE,GAAsBC,CAAU,IAAhC,KAAAmE,GAAqC,YACzD,CAKLU,EAAU,mBAAqB,GAC/B,IAAMe,GAAcxB,GAAAS,EAAU,cAAV,KAAAT,GAAyBQ,EAAU,WACvDpB,EAAiB,IAAIoC,CAAW,EAKhC,IAAMC,GAAc,KAAK,MACtBxB,GAAAZ,EAAkB,IAAImC,CAAW,IAAjC,KAAAvB,GAAsC,GAAK,EAC5ChB,CACF,EACAK,EAAmB,IAAIkC,EAAa,CAAC,EACrC5C,EAAW,KACT,KAAK,uBAAuB4C,EAAa,CACvC,OAAQ,WACR,QAASC,GACT,YAAAxC,EACA,OAAQqC,EAAW,MACrB,CAAC,CACH,CACF,CACF,CACF,CAIA,IAAII,EAA8B,KAC9BC,GAAoB,GACxB,GAAIlB,EAAU,QAAU,CAACA,EAAU,aAAc,CAC/C,IAAMmB,EAAcC,EAAsBpB,EAAU,KAAMA,EAAU,YAAY,EAC5EmB,GAAeA,EAAY,MAAM,OAASnB,EAAU,iBACtDiB,EAAYE,EAAY,MACxBD,GAAoB,GAExB,CAaA,GAF2B,CAAC,CAAClB,EAAU,QAAU,CAACA,EAAU,mBAElCkB,GAAmB,CAC3C,IAAMG,EAAsC,CAAC,EAG7CA,EAAI,KAAK,CAAE,QAAS,OAAQ,cAAe,CAAE,UAAAlE,EAAW,UAAAuD,CAAU,CAAE,CAAC,EAEjEV,EAAU,SACZqB,EAAI,KAAK,CAAE,QAAS,OAAQ,iBAAkB,CAAE,UAAAlE,EAAW,WAAY6C,EAAU,OAAO,UAAW,CAAE,CAAC,EACtGA,EAAU,kBAAoB,GAE9BhB,EAAmB,IAAIgB,EAAU,OAAO,SAAS,GAG/CiB,GAAaA,EAAU,OAAS,IAClCjB,EAAU,eAAiBiB,EAAU,OACrCI,EAAI,KAAK,CACP,QAAS,OACT,gBAAiB,CAAE,UAAAlE,EAAW,KAAM,IAAK,MAAO,CAAE,CAAC6C,EAAU,YAAY,EAAGiB,CAAU,CAAE,CAC1F,CAAC,GAGH,IAAM3G,EAAmC,CAAE,CAACgH,CAAmB,EAAGD,CAAI,EAKhEE,EAAuC,CAC3C,KAAM3F,EAAU,kBAChB,UAAW,iBAAgB6D,GAAAO,EAAU,cAAV,KAAAP,GAAyBM,EAAU,UAAU,GACxE,aAAcpF,EACd,QAAAL,EACA,QAAS,EACX,EACA6D,EAAW,KAAKoD,CAAa,EAG7B5C,EAAiB,QAAOe,GAAAM,EAAU,cAAV,KAAAN,GAAyBK,EAAU,UAAU,CACvE,CAKA,GAAIC,EAAU,mBAAqB,CAACA,EAAU,cAAgBK,EAAwB,CACpF,IAAMmB,EAAOC,EAAsBzB,EAAU,KAAM,MAAM,EACzD,GAAIwB,EAAM,CACRxB,EAAU,aAAe,GACzB,IAAMqB,EAAsC,CAC1C,CAAE,QAAS,OAAQ,cAAe,CAAE,UAAAlE,EAAW,UAAAuD,CAAU,CAAE,EAC3D,CAAE,QAAS,OAAQ,iBAAkB,CAAE,UAAAvD,EAAW,WAAY6C,EAAU,OAAQ,UAAW,CAAE,EAC7F,CAAE,QAAS,OAAQ,gBAAiB,CAAE,UAAA7C,EAAW,KAAM,IAAK,MAAOqE,CAAK,CAAE,CAC5E,EACMlH,EAAmC,CAAE,CAACgH,CAAmB,EAAGD,CAAI,EAChEE,EAAuC,CAC3C,KAAM3F,EAAU,kBAChB,UAAW,iBAAgB+D,GAAAK,EAAU,cAAV,KAAAL,GAAyBI,EAAU,UAAU,GACxE,aAAcpF,EACd,QAAAL,EACA,QAAS,EACX,EACA6D,EAAW,KAAKoD,CAAa,CAC/B,CACF,CACF,CACF,CACF,CAEF,CASA,GANIlD,IACFF,EAAW,KAAKE,EAAgB,KAAK,EACrCA,EAAkB,MAIhBuB,EAAM,OAAShE,EAAU,aAC3ByC,EAAkBe,UAElBjB,EAAW,KAAKyB,CAAK,EAGjBA,EAAM,OAAShE,EAAU,iBAAkB,CAC7C,IAAM8F,EAAc9B,EACd+B,EAAcrD,EAAmB,IAAIoD,EAAY,UAAU,EAK3DE,EAAiBtD,EAAmB,IAAIoD,EAAY,UAAU,EAYhEG,EAA0B,CAAC,EAXNF,IAAeC,GAAA,YAAAA,EAAgB,oBAYxD,GAAI,CAACC,GACH,QAAW9G,KAASuD,EAAmB,OAAO,EAC5C,GAAIvD,EAAM,mBAAqBA,EAAM,cAAgB2G,EAAY,WAAY,CAC3EG,EAA0B,GAC1B,KACF,EAIJ,GAAI,CAACA,EAAyB,CAC5B,IAAMpH,EAASqH,GAAuBJ,EAAY,OAAO,EACzD,GAAIjH,EAAQ,CAQV,IAAMsH,EACJ/C,EAAmB,KAAO,EACtBvE,EAAO,WAAW,OAAQuH,GAAO,CAC/B,IAAMC,EAAcC,EAAsBF,CAAE,EAG5C,OAAOC,GAAe,MAAQ,CAACjD,EAAmB,IAAIiD,CAAW,CACnE,CAAC,EACDxH,EAAO,WAKb,GAAIsH,EAAiB,OAAS,EAK5B,QAAWI,KAAiB,KAAK,yBAC/BJ,EACA7C,GAAA,KAAAA,EAAsBwC,EAAY,UACpC,EACEvD,EAAW,KAAKgE,CAAa,CAGnC,KAAO,CAKL,IAAMC,EAAU/H,GAAwBqH,EAAY,OAAO,EAC3D,GAAIU,EAAS,CAIX,IAAMC,EAAUnD,GAAA,KAAAA,EAAsBwC,EAAY,WAClDvD,EAAW,KACT,KAAK,uBAAuBkE,EAAS,CACnC,OAAQ,SACR,MAAOD,EAAQ,MACf,SAAUA,EAAQ,SAClB,YAAa,MAAM,QAAQA,EAAQ,QAAQ,GACvCA,EAAQ,SAAS,QAAU5D,CAEjC,CAAC,CACH,EACAG,EAAiB,OAAO0D,CAAO,CACjC,CACF,CACF,CAGInD,IAAuBwC,EAAY,aACrCxC,EAAqB,KAEzB,CAEJ,EACA,MAAQoD,GAAQ,CAEVjE,IACFF,EAAW,KAAKE,EAAgB,KAAK,EACrCA,EAAkB,MAEpBF,EAAW,MAAMmE,CAAG,CACtB,EACA,SAAU,IAAM,CACd,GAAIjE,EAAiB,CAKnB,IAAMkE,EADmB,KAAK,qBAAqBlE,EAAgB,QAAQ,EAC/B,OACzCmE,GAAOxE,EAAc,IAAIwE,EAAG,SAAS,IAAI,CAC5C,EACA,QAAWC,KAAYF,EAAoB,CACzC,IAAMb,EAAmC,CACvC,KAAM9F,EAAU,iBAChB,UAAWa,EAAW,EACtB,WAAYgG,EAAS,GACrB,QAAS,KAAK,UAAU,CAAE,OAAQ,UAAW,CAAC,CAChD,EACAtE,EAAW,KAAKuD,CAAW,CAC7B,CACAvD,EAAW,KAAKE,EAAgB,KAAK,EACrCA,EAAkB,IACpB,CACAF,EAAW,SAAS,CACtB,CACF,CAAC,EAED,MAAO,IAAMgB,GAAa,YAAY,CACxC,CAAC,CACH,CAKQ,qBAAqBnC,EAAiC,CAE5D,IAAM0F,EAA2B,CAAC,EAClC,QAAWpF,KAAWN,EAElBM,EAAQ,OAAS,aACjB,cAAeA,GACfA,EAAQ,WAERoF,EAAa,KAAK,GAAGpF,EAAQ,SAAS,EAK1C,IAAMqF,EAAsB,IAAI,IAChC,QAAWrF,KAAWN,EAChBM,EAAQ,OAAS,QAAU,eAAgBA,GAC7CqF,EAAoB,IAAIrF,EAAQ,UAAU,EAK9C,OAAOoF,EAAa,OAAQF,GAAO,CAACG,EAAoB,IAAIH,EAAG,EAAE,CAAC,CACpE,CAQQ,yBACNI,EACAlG,EACa,CAj6BjB,IAAAnC,EAk6BI,IAAMsI,EAAsB,CAAC,EAGvBC,EAAsB,IAAI,IAChC,QAAWd,KAAMY,EAAY,CAC3B,IAAMzF,GAAY5C,EAAA2H,EAAsBF,CAAE,IAAxB,KAAAzH,EAA6B,UAC1CuI,EAAoB,IAAI3F,CAAS,GACpC2F,EAAoB,IAAI3F,EAAW,CAAC,CAAC,EAEvC2F,EAAoB,IAAI3F,CAAS,EAAG,KAAK6E,CAAE,CAC7C,CAMA,OAAW,CAAC7E,EAAW4F,CAAU,IAAKD,EAAqB,CAOzD,IAAME,EAAgBF,EAAoB,OAAS,EAC7CG,EAAYvG,EACdsG,EACE,gBAAgBtG,CAAU,GAC1B,gBAAgBS,CAAS,IAAIT,CAAU,GACzC,gBAAgBS,CAAS,GAEvB7C,EAAmC,CAAE,CAACgH,CAAmB,EAAGyB,CAAW,EAEvExB,EAAuC,CAC3C,KAAM3F,EAAU,kBAChB,UAAAqH,EACA,aAActI,EACd,QAAAL,EACA,QAAS,EACX,EACAuI,EAAO,KAAKtB,CAAa,CAC3B,CAEA,OAAOsB,CACT,CACF","names":["randomUUID","Middleware","EventType","Observable","RENDER_A2UI_TOOL_NAME","LOG_A2UI_EVENT_TOOL_NAME","RENDER_A2UI_TOOL","RENDER_A2UI_TOOL_GUIDELINES","toolName","clarinet","extractCompleteItems","partial","dataKey","_a","result","extractCompleteItemsWithStatus","findTopLevelValueStart","key","target","i","objectDepth","arrayDepth","inString","escape","ch","j","extractCompleteObject","braceStart","substr","parser","objectClosed","closePosition","e","objStr","bracketStart","lastCompleteEnd","arrayClosed","arrayStr","extractDataArrayItems","itemsKey","dataBraceStart","dataSubstr","extractStringField","partialJson","rootDepth","currentKey","found","firstKey","k","value","extractCompleteA2UIOperations","partialArgs","keyPattern","keyIdx","afterKey","valueStart","innerJson","unescapeJsonString","extractTopLevelArrayItems","str","startIdx","next","hex","A2UI_PROMPT","A2UI_OPERATIONS_KEY","tryParseA2UIOperations","text","parsed","op","inner","getOperationSurfaceId","operation","_a","_b","_c","createSurface","updateComponents","updateDataModel","deleteSurface","extractSurfaceIds","messages","surfaceIds","msg","surfaceId","validateA2UIComponents","MAX_A2UI_ATTEMPTS","tryParseRecoveryFailure","content","_a","_b","parsed","e","A2UIActivityType","A2UI_SCHEMA_CONTEXT_DESCRIPTION","extractFrontendCatalogId","input","entry","c","id","deriveRepeatedDataKey","components","comp","children","A2UIMiddleware","Middleware","config","schema","key","debugExposure","EventType","__spreadProps","__spreadValues","next","frontendCatalogId","enhancedInput","withSchema","finalInput","schemaContext","filtered","forwardedProps","userAction","assistantMessageId","randomUUID","toolCallId","toolMessageId","syntheticAssistantMessage","LOG_A2UI_EVENT_TOOL_NAME","resultContent","syntheticToolMessage","messages","action","actionName","surfaceId","componentId","contextStr","message","toolName","RENDER_A2UI_TOOL_NAME","tool","RENDER_A2UI_TOOL","filteredTools","t","guidelinesDescription","RENDER_A2UI_TOOL_GUIDELINES","source","a2uiToolNames","injectedName","Observable","subscriber","_c","heldRunFinished","streamingToolCalls","showProgressTokens","maxAttempts","MAX_A2UI_ATTEMPTS","TOKEN_EMIT_STEP","retriedOuterKeys","attemptCountByKey","lastTokenEmitByKey","estimateTokens","args","streamedSurfaceIds","nonOuterToolNames","currentOuterCallId","subscription","eventWithState","_d","_e","_f","_g","_h","_i","_j","event","startEvent","attempt","argsEvent","streaming","tokenKey","tokens","deltaHasClosingBrace","deltaHasClosingBracket","deltaHasStructuralChar","deltaHasQuote","extractStringField","configCatalogId","streamedCatalogId","catalogId","result","extractCompleteItemsWithStatus","validation","validateA2UIComponents","recoveryKey","nextAttempt","dataItems","dataItemsAdvanced","itemsResult","extractDataArrayItems","ops","A2UI_OPERATIONS_KEY","snapshotEvent","data","extractCompleteObject","resultEvent","isStreaming","streamingEntry","outerHasStreamedSurface","tryParseA2UIOperations","operationsToEmit","op","opSurfaceId","getOperationSurfaceId","activityEvent","failure","failKey","err","pendingRenderCalls","tc","toolCall","allToolCalls","resolvedToolCallIds","operations","events","operationsBySurface","surfaceOps","singleSurface","messageId"]}