@athenaintel/react 0.54.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/dist/agent-runtime/src/edit-command.cjs +9 -3
- package/dist/agent-runtime/src/edit-command.cjs.map +1 -1
- package/dist/agent-runtime/src/edit-command.js +9 -3
- package/dist/agent-runtime/src/edit-command.js.map +1 -1
- package/dist/agent-runtime/src/generated/runconfig-contract.cjs +4 -0
- package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
- package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +12 -1
- package/dist/agent-runtime/src/generated/runconfig-contract.js +4 -0
- package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
- package/dist/agent-runtime/src/history-pages.cjs +279 -0
- package/dist/agent-runtime/src/history-pages.cjs.map +1 -0
- package/dist/agent-runtime/src/history-pages.d.ts +252 -0
- package/dist/agent-runtime/src/history-pages.js +279 -0
- package/dist/agent-runtime/src/history-pages.js.map +1 -0
- package/dist/agent-runtime/src/index.d.ts +2 -1
- package/dist/agent-runtime/src/offline-status.cjs.map +1 -1
- package/dist/agent-runtime/src/offline-status.d.ts +31 -2
- package/dist/agent-runtime/src/offline-status.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.cjs +16 -2
- package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.d.ts +9 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.js +16 -2
- package/dist/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs +71 -19
- package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-window-sync.d.ts +27 -2
- package/dist/agent-runtime/src/use-deep-agent-window-sync.js +73 -21
- package/dist/agent-runtime/src/use-deep-agent-window-sync.js.map +1 -1
- package/dist/chat/super-grouping/SuperGroupingCard.cjs +51 -43
- package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
- package/dist/chat/super-grouping/SuperGroupingCard.js +51 -43
- package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
- package/dist/chat/super-grouping/SuperGroupingTranscript.cjs +9 -4
- package/dist/chat/super-grouping/SuperGroupingTranscript.cjs.map +1 -1
- package/dist/chat/super-grouping/SuperGroupingTranscript.js +9 -4
- package/dist/chat/super-grouping/SuperGroupingTranscript.js.map +1 -1
- package/dist/chat/super-grouping/activity-timeline.cjs +7 -4
- package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
- package/dist/chat/super-grouping/activity-timeline.d.ts +10 -1
- package/dist/chat/super-grouping/activity-timeline.js +7 -4
- package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
- package/dist/chat/super-grouping/earlier-steps-button.cjs +50 -0
- package/dist/chat/super-grouping/earlier-steps-button.cjs.map +1 -0
- package/dist/chat/super-grouping/earlier-steps-button.d.ts +11 -0
- package/dist/chat/super-grouping/earlier-steps-button.js +50 -0
- package/dist/chat/super-grouping/earlier-steps-button.js.map +1 -0
- package/dist/chat/super-grouping/use-turn-steps.cjs +28 -0
- package/dist/chat/super-grouping/use-turn-steps.cjs.map +1 -0
- package/dist/chat/super-grouping/use-turn-steps.d.ts +23 -0
- package/dist/chat/super-grouping/use-turn-steps.js +28 -0
- package/dist/chat/super-grouping/use-turn-steps.js.map +1 -0
- package/dist/chat-ui/statewire.cjs +6 -0
- package/dist/chat-ui/statewire.cjs.map +1 -1
- package/dist/chat-ui/statewire.d.ts +3 -1
- package/dist/chat-ui/statewire.js +7 -1
- package/dist/chat-ui/statewire.js.map +1 -1
- package/dist/chat-ui/thread/statewire-history-edge.cjs +4 -0
- package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
- package/dist/chat-ui/thread/statewire-history-edge.d.ts +11 -1
- package/dist/chat-ui/thread/statewire-history-edge.js +5 -1
- package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
- package/dist/collab/client.cjs +40 -1
- package/dist/collab/client.cjs.map +1 -1
- package/dist/collab/client.d.ts +17 -0
- package/dist/collab/client.js +40 -1
- package/dist/collab/client.js.map +1 -1
- package/dist/composer/QuoteContext.cjs +3 -3
- package/dist/composer/QuoteContext.cjs.map +1 -1
- package/dist/composer/QuoteContext.js +3 -3
- package/dist/composer/QuoteContext.js.map +1 -1
- package/dist/provider/AthenaProvider.cjs +11 -3
- package/dist/provider/AthenaProvider.cjs.map +1 -1
- package/dist/provider/AthenaProvider.js +12 -4
- package/dist/provider/AthenaProvider.js.map +1 -1
- package/dist/provider/statewire-window-context.cjs +6 -0
- package/dist/provider/statewire-window-context.cjs.map +1 -1
- package/dist/provider/statewire-window-context.d.ts +10 -1
- package/dist/provider/statewire-window-context.js +6 -0
- package/dist/provider/statewire-window-context.js.map +1 -1
- package/dist/react/package.json.cjs +1 -1
- package/dist/react/package.json.js +1 -1
- package/dist/runtime/useAthenaStatewireRuntime.cjs +2 -0
- package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
- package/dist/runtime/useAthenaStatewireRuntime.d.ts +7 -1
- package/dist/runtime/useAthenaStatewireRuntime.js +2 -0
- package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/threads/sessions-query.cjs +2 -0
- package/dist/threads/sessions-query.cjs.map +1 -1
- package/dist/threads/sessions-query.js +2 -0
- package/dist/threads/sessions-query.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runconfig-contract.js","sources":["../../../../../agent-runtime/src/generated/runconfig-contract.ts"],"sourcesContent":["// GENERATED FILE — DO NOT EDIT BY HAND.\n//\n// Source of truth (agora):\n// agora/agora/graphs/athena_deep_agent/run_config.py (_PARSED_CUSTOM_KEYS / _COMPANION_CUSTOM_KEYS / PER_SEND_CUSTOM_KEYS)\n// agora/agora/graphs/athena_deep_agent/thread_config.py (server config lane + config/* command names)\n// agora/agora/graphs/athena_deep_agent/session_asset.py (KNOWN_START_CHANNELS / DEEP_AGENT_RUNTIME_MARKER)\n// agora/agora/graphs/athena_deep_agent/client_tools.py (client-tool interrupt + result-envelope literals)\n// agora/agora/graphs/athena_deep_agent/protocol_version.py (wire-contract version negotiation)\n// agora/agora/graphs/athena_deep_agent/message_window.py (interest windows + history commands)\n// agora/agora/type_definitions/collab_agent.py (CAPABILITIES ladder: absent mode + new-agent default)\n//\n// Regenerate:\n// cd agora && mise exec -- infisical run --command 'uv run python scripts/export_runconfig_contract.py'\n//\n// CI verifies this file matches the Python source (agora-check runs the\n// exporter with --check), so hand edits and un-regenerated key changes fail.\n\n/** `runConfig.custom` keys parsed by agora's `parse_deep_agent_run_config`. */\nexport const RUN_CONFIG_PARSED_CUSTOM_KEYS = [\n \"agent_catalog_asset_ids\",\n \"approve_changes\",\n \"catalog_asset_ids\",\n \"channel_reply_turn\",\n \"coding_worker_asset_id\",\n \"coding_workers\",\n \"compiled_subagents\",\n \"declined_toolkit_ids\",\n \"drive_mounts\",\n \"enable_interpreter\",\n \"enable_persistent_fs\",\n \"enable_sandbox\",\n \"enable_skills\",\n \"enabled_tools\",\n \"environment\",\n \"environment_id\",\n \"environment_name\",\n \"excluded_middleware\",\n \"excluded_tools\",\n \"extra_middleware\",\n \"include_citation_instructions\",\n \"interpreter_max_ptc_calls\",\n \"interpreter_mode\",\n \"interpreter_ptc\",\n \"interpreter_ptc_exclusive\",\n \"interpreter_runtime\",\n \"interpreter_subagents\",\n \"interpreter_timeout_seconds\",\n \"interrupt_on\",\n \"knowledge_base\",\n \"mcp_server_configs\",\n \"mcp_servers\",\n \"memory\",\n \"outbound_approval_allowlist\",\n \"permissions\",\n \"pre_approved_tools\",\n \"project_id\",\n \"read_only\",\n \"recursion_limit\",\n \"run_label\",\n \"sandbox_runtime\",\n \"secret_asset_ids\",\n \"session_computer\",\n \"session_machine\",\n \"session_vm_retention\",\n \"skill_asset_ids\",\n \"skills\",\n \"subagents\",\n \"system_prompt\",\n \"tool_description_overrides\",\n \"voice_update_handle\",\n \"workbench\",\n] as const;\n\n/** `runConfig.custom` keys consumed by the surrounding deep-agent request machinery rather than the capability parser. */\nexport const RUN_CONFIG_COMPANION_CUSTOM_KEYS = [\n \"addressed_agents\",\n \"agent\",\n \"agent_available_toolkits\",\n \"allowed_tab_ids\",\n \"app_id\",\n \"channel\",\n \"channel_router\",\n \"client_tools\",\n \"collab_agent_id\",\n \"collab_channel_id\",\n \"collab_entry_channel_id\",\n \"custom_tool_configs\",\n \"deterministic\",\n \"device_id\",\n \"device_toolkits\",\n \"dry_run\",\n \"enabled_toolkits\",\n \"entry_point\",\n \"from_stored_config\",\n \"frontend_available\",\n \"generative_frame_inline\",\n \"github_identity\",\n \"max_tokens\",\n \"middleware\",\n \"model\",\n \"muses_enabled\",\n \"muses_recall_enabled\",\n \"office_context\",\n \"panel_config\",\n \"posthog_session_id\",\n \"run_budget\",\n \"runtime\",\n \"session_id\",\n \"session_origin_kind\",\n \"session_tab_id\",\n \"skip_title_generation\",\n \"source_aop_id\",\n \"start_channel\",\n \"structured_output\",\n \"temperature\",\n \"tool_limit_override\",\n \"trigger_type\",\n \"workspace_id\",\n] as const;\n\n/** Every `runConfig.custom` key some deep-agent request consumer reads. A key outside this set is invisible to the run and trips agora's unknown-key telemetry. */\nexport const RUN_CONFIG_CUSTOM_KEYS = [\n \"addressed_agents\",\n \"agent\",\n \"agent_available_toolkits\",\n \"agent_catalog_asset_ids\",\n \"allowed_tab_ids\",\n \"app_id\",\n \"approve_changes\",\n \"catalog_asset_ids\",\n \"channel\",\n \"channel_reply_turn\",\n \"channel_router\",\n \"client_tools\",\n \"coding_worker_asset_id\",\n \"coding_workers\",\n \"collab_agent_id\",\n \"collab_channel_id\",\n \"collab_entry_channel_id\",\n \"compiled_subagents\",\n \"custom_tool_configs\",\n \"declined_toolkit_ids\",\n \"deterministic\",\n \"device_id\",\n \"device_toolkits\",\n \"drive_mounts\",\n \"dry_run\",\n \"enable_interpreter\",\n \"enable_persistent_fs\",\n \"enable_sandbox\",\n \"enable_skills\",\n \"enabled_toolkits\",\n \"enabled_tools\",\n \"entry_point\",\n \"environment\",\n \"environment_id\",\n \"environment_name\",\n \"excluded_middleware\",\n \"excluded_tools\",\n \"extra_middleware\",\n \"from_stored_config\",\n \"frontend_available\",\n \"generative_frame_inline\",\n \"github_identity\",\n \"include_citation_instructions\",\n \"interpreter_max_ptc_calls\",\n \"interpreter_mode\",\n \"interpreter_ptc\",\n \"interpreter_ptc_exclusive\",\n \"interpreter_runtime\",\n \"interpreter_subagents\",\n \"interpreter_timeout_seconds\",\n \"interrupt_on\",\n \"knowledge_base\",\n \"max_tokens\",\n \"mcp_server_configs\",\n \"mcp_servers\",\n \"memory\",\n \"middleware\",\n \"model\",\n \"muses_enabled\",\n \"muses_recall_enabled\",\n \"office_context\",\n \"outbound_approval_allowlist\",\n \"panel_config\",\n \"permissions\",\n \"posthog_session_id\",\n \"pre_approved_tools\",\n \"project_id\",\n \"read_only\",\n \"recursion_limit\",\n \"run_budget\",\n \"run_label\",\n \"runtime\",\n \"sandbox_runtime\",\n \"secret_asset_ids\",\n \"session_computer\",\n \"session_id\",\n \"session_machine\",\n \"session_origin_kind\",\n \"session_tab_id\",\n \"session_vm_retention\",\n \"skill_asset_ids\",\n \"skills\",\n \"skip_title_generation\",\n \"source_aop_id\",\n \"start_channel\",\n \"structured_output\",\n \"subagents\",\n \"system_prompt\",\n \"temperature\",\n \"tool_description_overrides\",\n \"tool_limit_override\",\n \"trigger_type\",\n \"voice_update_handle\",\n \"workbench\",\n \"workspace_id\",\n] as const;\n\nexport type RunConfigCustomKey = (typeof RUN_CONFIG_CUSTOM_KEYS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const RUN_CONFIG_CUSTOM_KEY_SET: ReadonlySet<string> = new Set(\n RUN_CONFIG_CUSTOM_KEYS,\n);\n\n/** `runConfig.custom` keys a client still carries per send on a thread with server config; every other key is dropped at dispatch. */\nexport const RUN_CONFIG_PER_SEND_CUSTOM_KEYS = [\n \"addressed_agents\",\n \"agent\",\n \"agent_available_toolkits\",\n \"allowed_tab_ids\",\n \"app_id\",\n \"channel\",\n \"channel_reply_turn\",\n \"channel_router\",\n \"client_tools\",\n \"collab_channel_id\",\n \"collab_entry_channel_id\",\n \"deterministic\",\n \"device_id\",\n \"device_toolkits\",\n \"dry_run\",\n \"entry_point\",\n \"from_stored_config\",\n \"frontend_available\",\n \"generative_frame_inline\",\n \"github_identity\",\n \"muses_enabled\",\n \"muses_recall_enabled\",\n \"office_context\",\n \"posthog_session_id\",\n \"project_id\",\n \"read_only\",\n \"run_budget\",\n \"runtime\",\n \"session_id\",\n \"session_origin_kind\",\n \"session_tab_id\",\n \"skip_title_generation\",\n \"source_aop_id\",\n \"start_channel\",\n \"structured_output\",\n \"tool_limit_override\",\n \"trigger_type\",\n \"voice_update_handle\",\n \"workspace_id\",\n] as const;\n\nexport type RunConfigPerSendCustomKey =\n (typeof RUN_CONFIG_PER_SEND_CUSTOM_KEYS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const RUN_CONFIG_PER_SEND_CUSTOM_KEY_SET: ReadonlySet<string> = new Set(\n RUN_CONFIG_PER_SEND_CUSTOM_KEYS,\n);\n\n/** Keys the thread's server config lane owns — changed only through the `config/*` commands, never per send. */\nexport const THREAD_CONFIG_CUSTOM_KEYS = [\n \"agent_catalog_asset_ids\",\n \"approve_changes\",\n \"catalog_asset_ids\",\n \"coding_worker_asset_id\",\n \"coding_workers\",\n \"collab_agent_id\",\n \"compiled_subagents\",\n \"custom_tool_configs\",\n \"declined_toolkit_ids\",\n \"drive_mounts\",\n \"enable_interpreter\",\n \"enable_persistent_fs\",\n \"enable_sandbox\",\n \"enable_skills\",\n \"enabled_toolkits\",\n \"enabled_tools\",\n \"environment\",\n \"environment_id\",\n \"environment_name\",\n \"excluded_middleware\",\n \"excluded_tools\",\n \"extra_middleware\",\n \"include_citation_instructions\",\n \"interpreter_max_ptc_calls\",\n \"interpreter_mode\",\n \"interpreter_ptc\",\n \"interpreter_ptc_exclusive\",\n \"interpreter_runtime\",\n \"interpreter_subagents\",\n \"interpreter_timeout_seconds\",\n \"interrupt_on\",\n \"knowledge_base\",\n \"max_tokens\",\n \"mcp_server_configs\",\n \"mcp_servers\",\n \"memory\",\n \"middleware\",\n \"model\",\n \"outbound_approval_allowlist\",\n \"permissions\",\n \"pre_approved_tools\",\n \"recursion_limit\",\n \"run_label\",\n \"sandbox_runtime\",\n \"secret_asset_ids\",\n \"session_computer\",\n \"session_machine\",\n \"session_vm_retention\",\n \"skill_asset_ids\",\n \"skills\",\n \"subagents\",\n \"system_prompt\",\n \"temperature\",\n \"tool_description_overrides\",\n \"workbench\",\n] as const;\n\nexport type ThreadConfigCustomKey = (typeof THREAD_CONFIG_CUSTOM_KEYS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const THREAD_CONFIG_CUSTOM_KEY_SET: ReadonlySet<string> = new Set(\n THREAD_CONFIG_CUSTOM_KEYS,\n);\n\n/** Replicated-state key of the server config lane (`{ version, custom }`). */\nexport const DEEP_AGENT_CONFIG_STATE_KEY = \"config\";\n\n/** The statewire commands that mutate the server config lane. */\nexport const DEEP_AGENT_CONFIG_COMMANDS = {\n patch: \"config/patch\",\n toolsEnable: \"config/tools/enable\",\n toolsDisable: \"config/tools/disable\",\n} as const;\n\n/** `start_channel` values the session substrate stamps as provenance; anything else clamps to \"web\". */\nexport const KNOWN_START_CHANNELS = [\n \"agent_orchestration\",\n \"api\",\n \"automation\",\n \"chrome_extension\",\n \"cli\",\n \"comment_agent\",\n \"default_voice\",\n \"desktop_app\",\n \"email\",\n \"meetings\",\n \"mobile_app\",\n \"mobile_app_voice\",\n \"office_addin\",\n \"orchestration\",\n \"programmatic\",\n \"slack\",\n \"sms\",\n \"task\",\n \"teams\",\n \"voice\",\n \"voice_memo\",\n \"web\",\n] as const;\n\nexport type KnownStartChannel = (typeof KNOWN_START_CHANNELS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const KNOWN_START_CHANNEL_SET: ReadonlySet<string> = new Set(\n KNOWN_START_CHANNELS,\n);\n\n/** `runConfig.custom.runtime` marker selecting the deep-agent runtime. */\nexport const DEEP_AGENT_RUNTIME_MARKER = \"athena_deep_agent\";\n\n/**\n * Collab-agent capability ladder (agent schema v3): per explicit\n * capability field, what an ABSENT value means and the value stamped on\n * a new agent. Resolved by agora's `capability_decoder` and the one agent\n * compiler on every run: `passthrough` — explicit only, absent means off;\n * `off` — absent means off under every `runtime` marker; `runtime` —\n * absent derives from the `runtime` marker (`athena_deep_agent` on, any\n * other or missing marker off).\n */\nexport const COLLAB_AGENT_CAPABILITIES = {\n deepAgentBuiltinsEnabled: { absent: \"runtime\", default: true },\n interpreterEnabled: { absent: \"off\", default: false },\n sandboxEnabled: { absent: \"passthrough\", default: false },\n skillsEnabled: { absent: \"runtime\", default: true },\n} as const;\n\nexport type CollabAgentCapabilityField = keyof typeof COLLAB_AGENT_CAPABILITIES;\n\nexport type CollabAgentCapabilityAbsentMode =\n (typeof COLLAB_AGENT_CAPABILITIES)[CollabAgentCapabilityField][\"absent\"];\n\n/** `source`/`type` stamped on client-tool interrupt payloads by agora. */\nexport const CLIENT_TOOL_INTERRUPT_SOURCE = \"client_tool\";\n\n/** `status` literals of the result envelope a client resumes a parked client-tool call with. */\nexport const CLIENT_TOOL_RESULT_STATUSES = [\"error\", \"success\"] as const;\n\nexport type ClientToolResultStatus =\n (typeof CLIENT_TOOL_RESULT_STATUSES)[number];\n\nexport const CLIENT_TOOL_RESULT_STATUS_SUCCESS = \"success\";\n\nexport const CLIENT_TOOL_RESULT_STATUS_ERROR = \"error\";\n\n/**\n * Result envelope a client resumes a parked client-tool call with,\n * keyed by interrupt id:\n * `{ client_tool_results: { <interrupt_id>: <envelope> } }`.\n * Agora relays the envelope to the model verbatim.\n */\nexport type ClientToolResultEnvelopeContract =\n | { status: typeof CLIENT_TOOL_RESULT_STATUS_SUCCESS; result: unknown }\n | { status: typeof CLIENT_TOOL_RESULT_STATUS_ERROR; error: string };\n\n/**\n * The deep-agent wire-contract version this client build speaks,\n * declared on every attach. The host records it for attach telemetry\n * and per-version behaviour; it has no minimum client version, so no\n * build is refused for the version it declares (the `protocol` state\n * lane's `minClientVersion` is the constant 1).\n */\nexport const DEEP_AGENT_PROTOCOL_VERSION = 2;\n\n/**\n * The first contract version whose host a client states `follow` to (a\n * subagent lane's steps, each its own document): a client follows a\n * lane only on a host whose `protocol` lane advertises at least this\n * version. A host that predates `follow` refuses it with\n * `invalid-interest`.\n */\nexport const DEEP_AGENT_LANE_FOLLOW_PROTOCOL_VERSION = 2;\n\n/** Attach header carrying the client's declared contract version. */\nexport const DEEP_AGENT_PROTOCOL_VERSION_HEADER =\n \"x-athena-deep-agent-protocol-version\";\n\n/** Attach header declaring the head window a fresh client wants in its hello (host-clamped). */\nexport const DEEP_AGENT_MESSAGE_WINDOW_HEADER = \"x-athena-deep-agent-window\";\n\n/**\n * Attach header carrying the view a re-attaching client holds (JSON:\n * requests, head floor, lane floors): its hello carries that view on\n * any host instance.\n */\nexport const DEEP_AGENT_MESSAGE_INTERESTS_HEADER =\n \"x-athena-deep-agent-interests\";\n\n/** The largest interests header the host reads; larger is undeclared. */\nexport const DEEP_AGENT_MAX_MESSAGE_INTERESTS_HEADER_BYTES = 8192;\n\n/** Replicated-state key of the server-advertised version lane. */\nexport const DEEP_AGENT_PROTOCOL_STATE_KEY = \"protocol\";\n\n/** Ephemeral subprotocol carrying a client's message-window interests. */\nexport const DEEP_AGENT_INTEREST_PROTOCOL = \"athena/interest\";\n\n/** Ephemeral subprotocol carrying a client's synced context document. */\nexport const DEEP_AGENT_CONTEXT_PROTOCOL = \"athena/context\";\n\n/** The only interest namespace the host resolves (the linear transcript). */\nexport const DEEP_AGENT_MAIN_NS = \"main\";\n\n/** Window size (interest `before`) a client asks for by default. */\nexport const DEEP_AGENT_DEFAULT_MESSAGE_WINDOW = 40;\n\n/** Bounds on a window size. */\nexport const DEEP_AGENT_MIN_MESSAGE_WINDOW = 8;\n\nexport const DEEP_AGENT_MAX_MESSAGE_WINDOW = 200;\n\n/** Interests one attach may hold at once (the head plus its pages). */\nexport const DEEP_AGENT_MAX_INTERESTS = 16;\n\n/**\n * Rejection code of an interest `set` whose windows resolve past the\n * attach's interest document budget: the view is as deep as one attach holds.\n */\nexport const DEEP_AGENT_OVERSIZED_INTEREST_CODE = \"oversized-interest\";\n\n/** Command returning a truncated tool output whole. */\nexport const DEEP_AGENT_HISTORY_TOOL_OUTPUT_COMMAND = \"history/tool_output\";\n\n/** Command returning one stored message whole (provenance and full tool output included). */\nexport const DEEP_AGENT_HISTORY_MESSAGE_COMMAND = \"history/message\";\n\n/** Wire key marking a tool message whose content was truncated. */\nexport const DEEP_AGENT_TRUNCATED_CONTENT_KEY = \"athena_content_truncated\";\n\n/**\n * Wire key on a running `task` card whose nested transcript rides cut to its\n * newest steps: `{ messages, tool_calls }` over the whole stored transcript.\n */\nexport const DEEP_AGENT_TRUNCATED_LANE_KEY = \"athena_lane_truncated\";\n\n/**\n * Wire key on a `task` card, and on an in-eval lane's `ptc_subagents` entry,\n * carrying the whole lane's token use however much of the lane the wire\n * carries: `{ input_tokens, output_tokens, cache_read_input_tokens,\n * cache_creation_input_tokens }`, the input counting its cache reads and\n * writes. Absent while the lane's steps report no usage.\n */\nexport const DEEP_AGENT_LANE_USAGE_KEY = \"athena_lane_usage\";\n\n/**\n * The newest nested messages a cut card carries whole; the entries ahead\n * of them are the older assistant turns that requested results among\n * them, cut to those calls.\n */\nexport const DEEP_AGENT_RUNNING_LANE_WIRE_MESSAGES = 8;\n\n/**\n * Key of a followed lane's window (`follows[ns]` on a resolution whose\n * request added `follow: {before}`) naming the `task` call whose card\n * holds the lane.\n */\nexport const DEEP_AGENT_FOLLOW_TOOL_CALL_ID_KEY = \"toolCallId\";\n\n/** The most lane steps one attach follows, across every lane. */\nexport const DEEP_AGENT_MAX_FOLLOWED_STEPS = 200;\n\n/**\n * The first contract version a client declares to see a finished card cut\n * like a running one (and to follow lanes and page them through\n * `history/lane`). Below it, or declaring nothing, finished cards ride whole.\n */\nexport const DEEP_AGENT_LANE_CUT_PROTOCOL_VERSION = 2;\n\n/**\n * Last element of the key a cut finished card's document rides under:\n * `[threadId, \"main\", messageId, \"cut\"]`. A view holds that key or the\n * card's own, never both.\n */\nexport const DEEP_AGENT_CUT_LANE_DOCUMENT = \"cut\";\n\n/**\n * Command returning one page of a card's nested transcript, oldest first:\n * `{ messageId, before, at? }` answers\n * `{ messageId, toolCallId, ns, steps, more: { before }, total }`; the page\n * holds the newest `before` entries, or those strictly older than `at`.\n */\nexport const DEEP_AGENT_HISTORY_LANE_COMMAND = \"history/lane\";\n\n/** The most entries one `history/lane` page asks for. */\nexport const DEEP_AGENT_MAX_LANE_PAGE = 200;\n\n/** The most encoded characters one `history/lane` page carries (at least one entry). */\nexport const DEEP_AGENT_HISTORY_LANE_PAGE_CHARS = 1048576;\n\n/**\n * Set on the last step of a cut finished card whose text is the card's own\n * `content` (the subagent's report): the step rides with empty content, and\n * the card's `content` is its text.\n */\nexport const DEEP_AGENT_REPEATS_RESULT_KEY = \"athena_content_repeats_result\";\n\n/** Most inline-image payload characters one message carries whole on the wire. */\nexport const DEEP_AGENT_INLINE_IMAGE_WIRE_BUDGET = 4194304;\n\n/** Wire key on an image block left off the wire: `{ index, chars, mediaType }`. */\nexport const DEEP_AGENT_OMITTED_IMAGE_KEY = \"athena_image_omitted\";\n\n/** The image an omitted block carries instead of its own (a neutral PNG tile). */\nexport const DEEP_AGENT_OMITTED_IMAGE_PLACEHOLDER_URL =\n \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAB4AQMAAABPbGssAAAABlBMVEXi6PCUo7jao11HAAAA6ElEQVR42u2UyW3DMBBF3wxogEd2EJbCElKQDRCwC3MpSRc5eLuYokgNLEUxctK/CHyanQts2vRO3QdlALVsXsBvecqxxr1ob0A5GlDJU+hICxN54p/qXAx/+FpoeeE8hTerzfvByn7ifzpaBtWCOwv6bMVMBgzRgNGKmUL9McDs4XOSyEHuoKCI76AiqOugg+y0gx6SN+YQg3QwALGk19pQSKV/reOocyoww27oU5sxhAbKUNgIqrVxrvnovJ80MFgxYy23wtTss44tmL+bAuOE2p2o0fJa3iW/6iR/lEfx8kv3TZtW6AFk5Sf3k+GTswAAAABJRU5ErkJggg==\";\n\n/**\n * Command returning one inline image of a stored message in chunks:\n * `{ messageId, index, offset? }` answers\n * `{ messageId, index, mediaType, offset, total, chunk, next }`; the\n * chunks joined in order are the image's `data:` URL, and `next` is\n * the offset to ask for next (`null` after the last chunk).\n */\nexport const DEEP_AGENT_HISTORY_IMAGE_COMMAND = \"history/image\";\n\n/**\n * Command returning one inline image of a lane step in chunks, as\n * `history/image` does a stored message's: `{ messageId | lane, step,\n * index, offset? }` answers `{ messageId, lane, step, index, mediaType,\n * offset, total, chunk, next }`, with `messageId` null for an in-eval\n * lane and `lane` null for a card.\n */\nexport const DEEP_AGENT_HISTORY_LANE_IMAGE_COMMAND = \"history/lane_image\";\n"],"names":[],"mappings":"AAyHO,MAAM,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAK8D,IAAI;AAAA,EAChE;AACF;AAGO,MAAM,kCAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMuE,IAAI;AAAA,EACzE;AACF;AAGO,MAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKiE,IAAI;AAAA,EACnE;AACF;AAMO,MAAM,6BAA6B;AAAA,EACxC,OAAO;AAAA,EACP,aAAa;AAAA,EACb,cAAc;AAChB;AAGO,MAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAK4D,IAAI;AAAA,EAC9D;AACF;AA2BO,MAAM,+BAA+B;AAQrC,MAAM,oCAAoC;AAE1C,MAAM,kCAAkC;AA+BxC,MAAM,qCACX;AAGK,MAAM,mCAAmC;AAOzC,MAAM,sCACX;AAGK,MAAM,gDAAgD;AAGtD,MAAM,gCAAgC;AAGtC,MAAM,+BAA+B;AAMrC,MAAM,qBAAqB;AAG3B,MAAM,oCAAoC;AAG1C,MAAM,gCAAgC;AAEtC,MAAM,gCAAgC;AAGtC,MAAM,2BAA2B;AAMjC,MAAM,qCAAqC;AAG3C,MAAM,yCAAyC;AAG/C,MAAM,qCAAqC;AAG3C,MAAM,mCAAmC;AAMzC,MAAM,gCAAgC;AAStC,MAAM,4BAA4B;AAwBlC,MAAM,uCAAuC;AAO7C,MAAM,+BAA+B;AAQrC,MAAM,kCAAkC;AAGxC,MAAM,2BAA2B;AAUjC,MAAM,gCAAgC;"}
|
|
1
|
+
{"version":3,"file":"runconfig-contract.js","sources":["../../../../../agent-runtime/src/generated/runconfig-contract.ts"],"sourcesContent":["// GENERATED FILE — DO NOT EDIT BY HAND.\n//\n// Source of truth (agora):\n// agora/agora/graphs/athena_deep_agent/run_config.py (_PARSED_CUSTOM_KEYS / _COMPANION_CUSTOM_KEYS / PER_SEND_CUSTOM_KEYS)\n// agora/agora/graphs/athena_deep_agent/thread_config.py (server config lane + config/* command names)\n// agora/agora/graphs/athena_deep_agent/session_asset.py (KNOWN_START_CHANNELS / DEEP_AGENT_RUNTIME_MARKER)\n// agora/agora/graphs/athena_deep_agent/client_tools.py (client-tool interrupt + result-envelope literals)\n// agora/agora/graphs/athena_deep_agent/protocol_version.py (wire-contract version negotiation)\n// agora/agora/graphs/athena_deep_agent/message_window.py (interest windows + history commands)\n// agora/agora/graphs/athena_deep_agent/history_page.py (older history by command)\n// agora/agora/type_definitions/collab_agent.py (CAPABILITIES ladder: absent mode + new-agent default)\n//\n// Regenerate:\n// cd agora && mise exec -- infisical run --command 'uv run python scripts/export_runconfig_contract.py'\n//\n// CI verifies this file matches the Python source (agora-check runs the\n// exporter with --check), so hand edits and un-regenerated key changes fail.\n\n/** `runConfig.custom` keys parsed by agora's `parse_deep_agent_run_config`. */\nexport const RUN_CONFIG_PARSED_CUSTOM_KEYS = [\n \"agent_catalog_asset_ids\",\n \"approve_changes\",\n \"catalog_asset_ids\",\n \"channel_reply_turn\",\n \"coding_worker_asset_id\",\n \"coding_workers\",\n \"compiled_subagents\",\n \"declined_toolkit_ids\",\n \"drive_mounts\",\n \"enable_interpreter\",\n \"enable_persistent_fs\",\n \"enable_sandbox\",\n \"enable_skills\",\n \"enabled_tools\",\n \"environment\",\n \"environment_id\",\n \"environment_name\",\n \"excluded_middleware\",\n \"excluded_tools\",\n \"extra_middleware\",\n \"include_citation_instructions\",\n \"interpreter_max_ptc_calls\",\n \"interpreter_mode\",\n \"interpreter_ptc\",\n \"interpreter_ptc_exclusive\",\n \"interpreter_runtime\",\n \"interpreter_subagents\",\n \"interpreter_timeout_seconds\",\n \"interrupt_on\",\n \"knowledge_base\",\n \"mcp_server_configs\",\n \"mcp_servers\",\n \"memory\",\n \"outbound_approval_allowlist\",\n \"permissions\",\n \"pre_approved_tools\",\n \"project_id\",\n \"read_only\",\n \"recursion_limit\",\n \"run_label\",\n \"sandbox_runtime\",\n \"secret_asset_ids\",\n \"session_computer\",\n \"session_machine\",\n \"session_vm_retention\",\n \"skill_asset_ids\",\n \"skills\",\n \"subagents\",\n \"system_prompt\",\n \"tool_description_overrides\",\n \"voice_update_handle\",\n \"workbench\",\n] as const;\n\n/** `runConfig.custom` keys consumed by the surrounding deep-agent request machinery rather than the capability parser. */\nexport const RUN_CONFIG_COMPANION_CUSTOM_KEYS = [\n \"addressed_agents\",\n \"agent\",\n \"agent_available_toolkits\",\n \"allowed_tab_ids\",\n \"app_id\",\n \"channel\",\n \"channel_router\",\n \"client_tools\",\n \"collab_agent_id\",\n \"collab_channel_id\",\n \"collab_entry_channel_id\",\n \"custom_tool_configs\",\n \"deterministic\",\n \"device_id\",\n \"device_toolkits\",\n \"dry_run\",\n \"enabled_toolkits\",\n \"entry_point\",\n \"from_stored_config\",\n \"frontend_available\",\n \"generative_frame_inline\",\n \"github_identity\",\n \"max_tokens\",\n \"middleware\",\n \"model\",\n \"muses_enabled\",\n \"muses_recall_enabled\",\n \"office_context\",\n \"panel_config\",\n \"posthog_session_id\",\n \"run_budget\",\n \"runtime\",\n \"session_id\",\n \"session_origin_kind\",\n \"session_tab_id\",\n \"skip_title_generation\",\n \"source_aop_id\",\n \"start_channel\",\n \"structured_output\",\n \"temperature\",\n \"tool_limit_override\",\n \"trigger_type\",\n \"workspace_id\",\n] as const;\n\n/** Every `runConfig.custom` key some deep-agent request consumer reads. A key outside this set is invisible to the run and trips agora's unknown-key telemetry. */\nexport const RUN_CONFIG_CUSTOM_KEYS = [\n \"addressed_agents\",\n \"agent\",\n \"agent_available_toolkits\",\n \"agent_catalog_asset_ids\",\n \"allowed_tab_ids\",\n \"app_id\",\n \"approve_changes\",\n \"catalog_asset_ids\",\n \"channel\",\n \"channel_reply_turn\",\n \"channel_router\",\n \"client_tools\",\n \"coding_worker_asset_id\",\n \"coding_workers\",\n \"collab_agent_id\",\n \"collab_channel_id\",\n \"collab_entry_channel_id\",\n \"compiled_subagents\",\n \"custom_tool_configs\",\n \"declined_toolkit_ids\",\n \"deterministic\",\n \"device_id\",\n \"device_toolkits\",\n \"drive_mounts\",\n \"dry_run\",\n \"enable_interpreter\",\n \"enable_persistent_fs\",\n \"enable_sandbox\",\n \"enable_skills\",\n \"enabled_toolkits\",\n \"enabled_tools\",\n \"entry_point\",\n \"environment\",\n \"environment_id\",\n \"environment_name\",\n \"excluded_middleware\",\n \"excluded_tools\",\n \"extra_middleware\",\n \"from_stored_config\",\n \"frontend_available\",\n \"generative_frame_inline\",\n \"github_identity\",\n \"include_citation_instructions\",\n \"interpreter_max_ptc_calls\",\n \"interpreter_mode\",\n \"interpreter_ptc\",\n \"interpreter_ptc_exclusive\",\n \"interpreter_runtime\",\n \"interpreter_subagents\",\n \"interpreter_timeout_seconds\",\n \"interrupt_on\",\n \"knowledge_base\",\n \"max_tokens\",\n \"mcp_server_configs\",\n \"mcp_servers\",\n \"memory\",\n \"middleware\",\n \"model\",\n \"muses_enabled\",\n \"muses_recall_enabled\",\n \"office_context\",\n \"outbound_approval_allowlist\",\n \"panel_config\",\n \"permissions\",\n \"posthog_session_id\",\n \"pre_approved_tools\",\n \"project_id\",\n \"read_only\",\n \"recursion_limit\",\n \"run_budget\",\n \"run_label\",\n \"runtime\",\n \"sandbox_runtime\",\n \"secret_asset_ids\",\n \"session_computer\",\n \"session_id\",\n \"session_machine\",\n \"session_origin_kind\",\n \"session_tab_id\",\n \"session_vm_retention\",\n \"skill_asset_ids\",\n \"skills\",\n \"skip_title_generation\",\n \"source_aop_id\",\n \"start_channel\",\n \"structured_output\",\n \"subagents\",\n \"system_prompt\",\n \"temperature\",\n \"tool_description_overrides\",\n \"tool_limit_override\",\n \"trigger_type\",\n \"voice_update_handle\",\n \"workbench\",\n \"workspace_id\",\n] as const;\n\nexport type RunConfigCustomKey = (typeof RUN_CONFIG_CUSTOM_KEYS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const RUN_CONFIG_CUSTOM_KEY_SET: ReadonlySet<string> = new Set(\n RUN_CONFIG_CUSTOM_KEYS,\n);\n\n/** `runConfig.custom` keys a client still carries per send on a thread with server config; every other key is dropped at dispatch. */\nexport const RUN_CONFIG_PER_SEND_CUSTOM_KEYS = [\n \"addressed_agents\",\n \"agent\",\n \"agent_available_toolkits\",\n \"allowed_tab_ids\",\n \"app_id\",\n \"channel\",\n \"channel_reply_turn\",\n \"channel_router\",\n \"client_tools\",\n \"collab_channel_id\",\n \"collab_entry_channel_id\",\n \"deterministic\",\n \"device_id\",\n \"device_toolkits\",\n \"dry_run\",\n \"entry_point\",\n \"from_stored_config\",\n \"frontend_available\",\n \"generative_frame_inline\",\n \"github_identity\",\n \"muses_enabled\",\n \"muses_recall_enabled\",\n \"office_context\",\n \"posthog_session_id\",\n \"project_id\",\n \"read_only\",\n \"run_budget\",\n \"runtime\",\n \"session_id\",\n \"session_origin_kind\",\n \"session_tab_id\",\n \"skip_title_generation\",\n \"source_aop_id\",\n \"start_channel\",\n \"structured_output\",\n \"tool_limit_override\",\n \"trigger_type\",\n \"voice_update_handle\",\n \"workspace_id\",\n] as const;\n\nexport type RunConfigPerSendCustomKey =\n (typeof RUN_CONFIG_PER_SEND_CUSTOM_KEYS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const RUN_CONFIG_PER_SEND_CUSTOM_KEY_SET: ReadonlySet<string> = new Set(\n RUN_CONFIG_PER_SEND_CUSTOM_KEYS,\n);\n\n/** Keys the thread's server config lane owns — changed only through the `config/*` commands, never per send. */\nexport const THREAD_CONFIG_CUSTOM_KEYS = [\n \"agent_catalog_asset_ids\",\n \"approve_changes\",\n \"catalog_asset_ids\",\n \"coding_worker_asset_id\",\n \"coding_workers\",\n \"collab_agent_id\",\n \"compiled_subagents\",\n \"custom_tool_configs\",\n \"declined_toolkit_ids\",\n \"drive_mounts\",\n \"enable_interpreter\",\n \"enable_persistent_fs\",\n \"enable_sandbox\",\n \"enable_skills\",\n \"enabled_toolkits\",\n \"enabled_tools\",\n \"environment\",\n \"environment_id\",\n \"environment_name\",\n \"excluded_middleware\",\n \"excluded_tools\",\n \"extra_middleware\",\n \"include_citation_instructions\",\n \"interpreter_max_ptc_calls\",\n \"interpreter_mode\",\n \"interpreter_ptc\",\n \"interpreter_ptc_exclusive\",\n \"interpreter_runtime\",\n \"interpreter_subagents\",\n \"interpreter_timeout_seconds\",\n \"interrupt_on\",\n \"knowledge_base\",\n \"max_tokens\",\n \"mcp_server_configs\",\n \"mcp_servers\",\n \"memory\",\n \"middleware\",\n \"model\",\n \"outbound_approval_allowlist\",\n \"permissions\",\n \"pre_approved_tools\",\n \"recursion_limit\",\n \"run_label\",\n \"sandbox_runtime\",\n \"secret_asset_ids\",\n \"session_computer\",\n \"session_machine\",\n \"session_vm_retention\",\n \"skill_asset_ids\",\n \"skills\",\n \"subagents\",\n \"system_prompt\",\n \"temperature\",\n \"tool_description_overrides\",\n \"workbench\",\n] as const;\n\nexport type ThreadConfigCustomKey = (typeof THREAD_CONFIG_CUSTOM_KEYS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const THREAD_CONFIG_CUSTOM_KEY_SET: ReadonlySet<string> = new Set(\n THREAD_CONFIG_CUSTOM_KEYS,\n);\n\n/** Replicated-state key of the server config lane (`{ version, custom }`). */\nexport const DEEP_AGENT_CONFIG_STATE_KEY = \"config\";\n\n/** The statewire commands that mutate the server config lane. */\nexport const DEEP_AGENT_CONFIG_COMMANDS = {\n patch: \"config/patch\",\n toolsEnable: \"config/tools/enable\",\n toolsDisable: \"config/tools/disable\",\n} as const;\n\n/** `start_channel` values the session substrate stamps as provenance; anything else clamps to \"web\". */\nexport const KNOWN_START_CHANNELS = [\n \"agent_orchestration\",\n \"api\",\n \"automation\",\n \"chrome_extension\",\n \"cli\",\n \"comment_agent\",\n \"default_voice\",\n \"desktop_app\",\n \"email\",\n \"meetings\",\n \"mobile_app\",\n \"mobile_app_voice\",\n \"office_addin\",\n \"orchestration\",\n \"programmatic\",\n \"slack\",\n \"sms\",\n \"task\",\n \"teams\",\n \"voice\",\n \"voice_memo\",\n \"web\",\n] as const;\n\nexport type KnownStartChannel = (typeof KNOWN_START_CHANNELS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const KNOWN_START_CHANNEL_SET: ReadonlySet<string> = new Set(\n KNOWN_START_CHANNELS,\n);\n\n/** `runConfig.custom.runtime` marker selecting the deep-agent runtime. */\nexport const DEEP_AGENT_RUNTIME_MARKER = \"athena_deep_agent\";\n\n/**\n * Collab-agent capability ladder (agent schema v3): per explicit\n * capability field, what an ABSENT value means and the value stamped on\n * a new agent. Resolved by agora's `capability_decoder` and the one agent\n * compiler on every run: `passthrough` — explicit only, absent means off;\n * `off` — absent means off under every `runtime` marker; `runtime` —\n * absent derives from the `runtime` marker (`athena_deep_agent` on, any\n * other or missing marker off).\n */\nexport const COLLAB_AGENT_CAPABILITIES = {\n deepAgentBuiltinsEnabled: { absent: \"runtime\", default: true },\n interpreterEnabled: { absent: \"off\", default: false },\n sandboxEnabled: { absent: \"passthrough\", default: false },\n skillsEnabled: { absent: \"runtime\", default: true },\n} as const;\n\nexport type CollabAgentCapabilityField = keyof typeof COLLAB_AGENT_CAPABILITIES;\n\nexport type CollabAgentCapabilityAbsentMode =\n (typeof COLLAB_AGENT_CAPABILITIES)[CollabAgentCapabilityField][\"absent\"];\n\n/** `source`/`type` stamped on client-tool interrupt payloads by agora. */\nexport const CLIENT_TOOL_INTERRUPT_SOURCE = \"client_tool\";\n\n/** `status` literals of the result envelope a client resumes a parked client-tool call with. */\nexport const CLIENT_TOOL_RESULT_STATUSES = [\"error\", \"success\"] as const;\n\nexport type ClientToolResultStatus =\n (typeof CLIENT_TOOL_RESULT_STATUSES)[number];\n\nexport const CLIENT_TOOL_RESULT_STATUS_SUCCESS = \"success\";\n\nexport const CLIENT_TOOL_RESULT_STATUS_ERROR = \"error\";\n\n/**\n * Result envelope a client resumes a parked client-tool call with,\n * keyed by interrupt id:\n * `{ client_tool_results: { <interrupt_id>: <envelope> } }`.\n * Agora relays the envelope to the model verbatim.\n */\nexport type ClientToolResultEnvelopeContract =\n | { status: typeof CLIENT_TOOL_RESULT_STATUS_SUCCESS; result: unknown }\n | { status: typeof CLIENT_TOOL_RESULT_STATUS_ERROR; error: string };\n\n/**\n * The deep-agent wire-contract version this client build speaks,\n * declared on every attach. The host records it for attach telemetry\n * and per-version behaviour; it has no minimum client version, so no\n * build is refused for the version it declares (the `protocol` state\n * lane's `minClientVersion` is the constant 1).\n */\nexport const DEEP_AGENT_PROTOCOL_VERSION = 3;\n\n/**\n * The first contract version whose host a client states `follow` to (a\n * subagent lane's steps, each its own document): a client follows a\n * lane only on a host whose `protocol` lane advertises at least this\n * version. A host that predates `follow` refuses it with\n * `invalid-interest`.\n */\nexport const DEEP_AGENT_LANE_FOLLOW_PROTOCOL_VERSION = 2;\n\n/** Attach header carrying the client's declared contract version. */\nexport const DEEP_AGENT_PROTOCOL_VERSION_HEADER =\n \"x-athena-deep-agent-protocol-version\";\n\n/** Attach header declaring the head window a fresh client wants in its hello (host-clamped). */\nexport const DEEP_AGENT_MESSAGE_WINDOW_HEADER = \"x-athena-deep-agent-window\";\n\n/**\n * Attach header carrying the view a re-attaching client holds (JSON:\n * requests, head floor, lane floors): its hello carries that view on\n * any host instance.\n */\nexport const DEEP_AGENT_MESSAGE_INTERESTS_HEADER =\n \"x-athena-deep-agent-interests\";\n\n/** The largest interests header the host reads; larger is undeclared. */\nexport const DEEP_AGENT_MAX_MESSAGE_INTERESTS_HEADER_BYTES = 8192;\n\n/** Replicated-state key of the server-advertised version lane. */\nexport const DEEP_AGENT_PROTOCOL_STATE_KEY = \"protocol\";\n\n/** Ephemeral subprotocol carrying a client's message-window interests. */\nexport const DEEP_AGENT_INTEREST_PROTOCOL = \"athena/interest\";\n\n/** Ephemeral subprotocol carrying a client's synced context document. */\nexport const DEEP_AGENT_CONTEXT_PROTOCOL = \"athena/context\";\n\n/** The only interest namespace the host resolves (the linear transcript). */\nexport const DEEP_AGENT_MAIN_NS = \"main\";\n\n/** Window size (interest `before`) a client asks for by default. */\nexport const DEEP_AGENT_DEFAULT_MESSAGE_WINDOW = 40;\n\n/** Bounds on a window size. */\nexport const DEEP_AGENT_MIN_MESSAGE_WINDOW = 8;\n\nexport const DEEP_AGENT_MAX_MESSAGE_WINDOW = 200;\n\n/** Interests one attach may hold at once (the head plus its pages). */\nexport const DEEP_AGENT_MAX_INTERESTS = 16;\n\n/**\n * Rejection code of an interest `set` whose windows resolve past the\n * attach's interest document budget: the view is as deep as one attach holds.\n */\nexport const DEEP_AGENT_OVERSIZED_INTEREST_CODE = \"oversized-interest\";\n\n/** Command returning a truncated tool output whole. */\nexport const DEEP_AGENT_HISTORY_TOOL_OUTPUT_COMMAND = \"history/tool_output\";\n\n/**\n * Command answering older history as whole turns (`{before, turns}`) or\n * one turn's steps (`{turn, before?, steps}`), outside the attach's view.\n */\nexport const DEEP_AGENT_HISTORY_PAGE_COMMAND = \"history/page\";\n\n/** The first host contract version that answers `DEEP_AGENT_HISTORY_PAGE_COMMAND`. */\nexport const DEEP_AGENT_HISTORY_PAGE_PROTOCOL_VERSION = 3;\n\n/** Turns one history page answers at most. */\nexport const DEEP_AGENT_MAX_HISTORY_PAGE_TURNS = 50;\n\n/** Steps of one turn one history page answers at most. */\nexport const DEEP_AGENT_MAX_HISTORY_PAGE_STEPS = 200;\n\n/** Command returning one stored message whole (provenance and full tool output included). */\nexport const DEEP_AGENT_HISTORY_MESSAGE_COMMAND = \"history/message\";\n\n/** Wire key marking a tool message whose content was truncated. */\nexport const DEEP_AGENT_TRUNCATED_CONTENT_KEY = \"athena_content_truncated\";\n\n/**\n * Wire key on a running `task` card whose nested transcript rides cut to its\n * newest steps: `{ messages, tool_calls }` over the whole stored transcript.\n */\nexport const DEEP_AGENT_TRUNCATED_LANE_KEY = \"athena_lane_truncated\";\n\n/**\n * Wire key on a `task` card, and on an in-eval lane's `ptc_subagents` entry,\n * carrying the whole lane's token use however much of the lane the wire\n * carries: `{ input_tokens, output_tokens, cache_read_input_tokens,\n * cache_creation_input_tokens }`, the input counting its cache reads and\n * writes. Absent while the lane's steps report no usage.\n */\nexport const DEEP_AGENT_LANE_USAGE_KEY = \"athena_lane_usage\";\n\n/**\n * The newest nested messages a cut card carries whole; the entries ahead\n * of them are the older assistant turns that requested results among\n * them, cut to those calls.\n */\nexport const DEEP_AGENT_RUNNING_LANE_WIRE_MESSAGES = 8;\n\n/**\n * Key of a followed lane's window (`follows[ns]` on a resolution whose\n * request added `follow: {before}`) naming the `task` call whose card\n * holds the lane.\n */\nexport const DEEP_AGENT_FOLLOW_TOOL_CALL_ID_KEY = \"toolCallId\";\n\n/** The most lane steps one attach follows, across every lane. */\nexport const DEEP_AGENT_MAX_FOLLOWED_STEPS = 200;\n\n/**\n * The first contract version a client declares to see a finished card cut\n * like a running one (and to follow lanes and page them through\n * `history/lane`). Below it, or declaring nothing, finished cards ride whole.\n */\nexport const DEEP_AGENT_LANE_CUT_PROTOCOL_VERSION = 2;\n\n/**\n * Last element of the key a cut finished card's document rides under:\n * `[threadId, \"main\", messageId, \"cut\"]`. A view holds that key or the\n * card's own, never both.\n */\nexport const DEEP_AGENT_CUT_LANE_DOCUMENT = \"cut\";\n\n/**\n * Command returning one page of a card's nested transcript, oldest first:\n * `{ messageId, before, at? }` answers\n * `{ messageId, toolCallId, ns, steps, more: { before }, total }`; the page\n * holds the newest `before` entries, or those strictly older than `at`.\n */\nexport const DEEP_AGENT_HISTORY_LANE_COMMAND = \"history/lane\";\n\n/** The most entries one `history/lane` page asks for. */\nexport const DEEP_AGENT_MAX_LANE_PAGE = 200;\n\n/** The most encoded characters one `history/lane` page carries (at least one entry). */\nexport const DEEP_AGENT_HISTORY_LANE_PAGE_CHARS = 1048576;\n\n/**\n * Set on the last step of a cut finished card whose text is the card's own\n * `content` (the subagent's report): the step rides with empty content, and\n * the card's `content` is its text.\n */\nexport const DEEP_AGENT_REPEATS_RESULT_KEY = \"athena_content_repeats_result\";\n\n/** Most inline-image payload characters one message carries whole on the wire. */\nexport const DEEP_AGENT_INLINE_IMAGE_WIRE_BUDGET = 4194304;\n\n/** Wire key on an image block left off the wire: `{ index, chars, mediaType }`. */\nexport const DEEP_AGENT_OMITTED_IMAGE_KEY = \"athena_image_omitted\";\n\n/** The image an omitted block carries instead of its own (a neutral PNG tile). */\nexport const DEEP_AGENT_OMITTED_IMAGE_PLACEHOLDER_URL =\n \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAB4AQMAAABPbGssAAAABlBMVEXi6PCUo7jao11HAAAA6ElEQVR42u2UyW3DMBBF3wxogEd2EJbCElKQDRCwC3MpSRc5eLuYokgNLEUxctK/CHyanQts2vRO3QdlALVsXsBvecqxxr1ob0A5GlDJU+hICxN54p/qXAx/+FpoeeE8hTerzfvByn7ifzpaBtWCOwv6bMVMBgzRgNGKmUL9McDs4XOSyEHuoKCI76AiqOugg+y0gx6SN+YQg3QwALGk19pQSKV/reOocyoww27oU5sxhAbKUNgIqrVxrvnovJ80MFgxYy23wtTss44tmL+bAuOE2p2o0fJa3iW/6iR/lEfx8kv3TZtW6AFk5Sf3k+GTswAAAABJRU5ErkJggg==\";\n\n/**\n * Command returning one inline image of a stored message in chunks:\n * `{ messageId, index, offset? }` answers\n * `{ messageId, index, mediaType, offset, total, chunk, next }`; the\n * chunks joined in order are the image's `data:` URL, and `next` is\n * the offset to ask for next (`null` after the last chunk).\n */\nexport const DEEP_AGENT_HISTORY_IMAGE_COMMAND = \"history/image\";\n\n/**\n * Command returning one inline image of a lane step in chunks, as\n * `history/image` does a stored message's: `{ messageId | lane, step,\n * index, offset? }` answers `{ messageId, lane, step, index, mediaType,\n * offset, total, chunk, next }`, with `messageId` null for an in-eval\n * lane and `lane` null for a card.\n */\nexport const DEEP_AGENT_HISTORY_LANE_IMAGE_COMMAND = \"history/lane_image\";\n"],"names":[],"mappings":"AA0HO,MAAM,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAK8D,IAAI;AAAA,EAChE;AACF;AAGO,MAAM,kCAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMuE,IAAI;AAAA,EACzE;AACF;AAGO,MAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKiE,IAAI;AAAA,EACnE;AACF;AAMO,MAAM,6BAA6B;AAAA,EACxC,OAAO;AAAA,EACP,aAAa;AAAA,EACb,cAAc;AAChB;AAGO,MAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAK4D,IAAI;AAAA,EAC9D;AACF;AA2BO,MAAM,+BAA+B;AAQrC,MAAM,oCAAoC;AAE1C,MAAM,kCAAkC;AA+BxC,MAAM,qCACX;AAGK,MAAM,mCAAmC;AAOzC,MAAM,sCACX;AAGK,MAAM,gDAAgD;AAGtD,MAAM,gCAAgC;AAGtC,MAAM,+BAA+B;AAMrC,MAAM,qBAAqB;AAG3B,MAAM,oCAAoC;AAG1C,MAAM,gCAAgC;AAEtC,MAAM,gCAAgC;AAGtC,MAAM,2BAA2B;AAMjC,MAAM,qCAAqC;AAG3C,MAAM,yCAAyC;AAM/C,MAAM,kCAAkC;AAGxC,MAAM,2CAA2C;AASjD,MAAM,qCAAqC;AAG3C,MAAM,mCAAmC;AAMzC,MAAM,gCAAgC;AAStC,MAAM,4BAA4B;AAwBlC,MAAM,uCAAuC;AAO7C,MAAM,+BAA+B;AAQrC,MAAM,kCAAkC;AAGxC,MAAM,2BAA2B;AAUjC,MAAM,gCAAgC;"}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const runconfigContract = require("./generated/runconfig-contract.cjs");
|
|
4
|
+
const toolNames = require("./tool-names.cjs");
|
|
5
|
+
const DEEP_AGENT_HISTORY_PAGE_TURNS = 10;
|
|
6
|
+
const DEEP_AGENT_TURN_STEPS_PAGE = 100;
|
|
7
|
+
const DEEP_AGENT_TURN_STEPS_KEY = "athena_turn_steps";
|
|
8
|
+
const DEEP_AGENT_HISTORY_START_KEY = "athenaHistoryStart";
|
|
9
|
+
function isDeepAgentHistoryAtStart(state) {
|
|
10
|
+
return isRecord(state) && state[DEEP_AGENT_HISTORY_START_KEY] === true;
|
|
11
|
+
}
|
|
12
|
+
function buildHistoryPageCommand({
|
|
13
|
+
before,
|
|
14
|
+
turns = DEEP_AGENT_HISTORY_PAGE_TURNS
|
|
15
|
+
}) {
|
|
16
|
+
return { type: runconfigContract.DEEP_AGENT_HISTORY_PAGE_COMMAND, before, turns };
|
|
17
|
+
}
|
|
18
|
+
function buildTurnStepsCommand({
|
|
19
|
+
turn,
|
|
20
|
+
before,
|
|
21
|
+
steps = DEEP_AGENT_TURN_STEPS_PAGE
|
|
22
|
+
}) {
|
|
23
|
+
return {
|
|
24
|
+
type: runconfigContract.DEEP_AGENT_HISTORY_PAGE_COMMAND,
|
|
25
|
+
turn,
|
|
26
|
+
...before !== void 0 && { before },
|
|
27
|
+
steps
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
31
|
+
const isCount = (value) => typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
32
|
+
const isId = (value) => typeof value === "string" && value.length > 0;
|
|
33
|
+
function readMessages(value) {
|
|
34
|
+
if (!Array.isArray(value)) return null;
|
|
35
|
+
for (const message of value) {
|
|
36
|
+
if (!isRecord(message) || !isId(message.id) || typeof message.type !== "string") return null;
|
|
37
|
+
}
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
function readMore(value) {
|
|
41
|
+
return isRecord(value) && typeof value.before === "boolean" ? { before: value.before } : null;
|
|
42
|
+
}
|
|
43
|
+
function readSteps(value) {
|
|
44
|
+
if (value === null) return null;
|
|
45
|
+
if (!isRecord(value)) return void 0;
|
|
46
|
+
const { count, tools, delegations, first, last } = value;
|
|
47
|
+
if (!isCount(count) || !isCount(tools) || !isCount(delegations)) return void 0;
|
|
48
|
+
if (first !== null && !isId(first) || last !== null && !isId(last)) return void 0;
|
|
49
|
+
return { count, tools, delegations, first, last };
|
|
50
|
+
}
|
|
51
|
+
function readHistoryPageAnswer(payload) {
|
|
52
|
+
if (!isRecord(payload) || !Array.isArray(payload.turns)) return null;
|
|
53
|
+
const more = readMore(payload.more);
|
|
54
|
+
if (more === null) return null;
|
|
55
|
+
const turns = [];
|
|
56
|
+
for (const turn of payload.turns) {
|
|
57
|
+
if (!isRecord(turn) || !isId(turn.id)) return null;
|
|
58
|
+
const messages = readMessages(turn.messages);
|
|
59
|
+
const steps = readSteps(turn.steps);
|
|
60
|
+
if (messages === null || steps === void 0) return null;
|
|
61
|
+
turns.push({ id: turn.id, messages, steps });
|
|
62
|
+
}
|
|
63
|
+
return { turns, more };
|
|
64
|
+
}
|
|
65
|
+
function readTurnStepsAnswer(payload) {
|
|
66
|
+
if (!isRecord(payload) || !isId(payload.turn)) return null;
|
|
67
|
+
const messages = readMessages(payload.messages);
|
|
68
|
+
const more = readMore(payload.more);
|
|
69
|
+
if (messages === null || more === null) return null;
|
|
70
|
+
return { turn: payload.turn, messages, more };
|
|
71
|
+
}
|
|
72
|
+
function createDeepAgentHistoryStore() {
|
|
73
|
+
let snapshot = null;
|
|
74
|
+
const loadingSteps = /* @__PURE__ */ new Set();
|
|
75
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
76
|
+
const publish = (next) => {
|
|
77
|
+
snapshot = next;
|
|
78
|
+
for (const listener of listeners) listener();
|
|
79
|
+
};
|
|
80
|
+
const store = {
|
|
81
|
+
getSnapshot: () => snapshot,
|
|
82
|
+
subscribe(listener) {
|
|
83
|
+
listeners.add(listener);
|
|
84
|
+
return () => {
|
|
85
|
+
listeners.delete(listener);
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
addPage({ threadId, before, beforeIsPrompt, answer }) {
|
|
89
|
+
var _a;
|
|
90
|
+
const current = snapshot;
|
|
91
|
+
const continues = current !== null && current.threadId === threadId && ((_a = current.turns[0]) == null ? void 0 : _a.id) === before;
|
|
92
|
+
if (!continues) {
|
|
93
|
+
loadingSteps.clear();
|
|
94
|
+
publish({
|
|
95
|
+
threadId,
|
|
96
|
+
anchor: before,
|
|
97
|
+
anchorInsideTurn: !beforeIsPrompt,
|
|
98
|
+
turns: answer.turns,
|
|
99
|
+
more: answer.more.before,
|
|
100
|
+
steps: /* @__PURE__ */ new Map()
|
|
101
|
+
});
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const held = new Set(current.turns.map((turn) => turn.id));
|
|
105
|
+
publish({
|
|
106
|
+
...current,
|
|
107
|
+
turns: [...answer.turns.filter((turn) => !held.has(turn.id)), ...current.turns],
|
|
108
|
+
more: answer.more.before
|
|
109
|
+
});
|
|
110
|
+
},
|
|
111
|
+
addSteps({ threadId, answer }) {
|
|
112
|
+
const current = snapshot;
|
|
113
|
+
if (current === null || current.threadId !== threadId) return;
|
|
114
|
+
if (!current.turns.some((turn) => turn.id === answer.turn)) return;
|
|
115
|
+
const loaded = current.steps.get(answer.turn);
|
|
116
|
+
const held = new Set(loaded == null ? void 0 : loaded.messages.map((message) => message.id));
|
|
117
|
+
const steps = new Map(current.steps);
|
|
118
|
+
steps.set(answer.turn, {
|
|
119
|
+
messages: [
|
|
120
|
+
...answer.messages.filter((message) => !held.has(message.id)),
|
|
121
|
+
...(loaded == null ? void 0 : loaded.messages) ?? []
|
|
122
|
+
],
|
|
123
|
+
more: answer.more.before
|
|
124
|
+
});
|
|
125
|
+
publish({ ...current, steps });
|
|
126
|
+
},
|
|
127
|
+
isLoadingSteps: (turn) => loadingSteps.has(turn),
|
|
128
|
+
setLoadingSteps(turn, loading) {
|
|
129
|
+
if (loading) loadingSteps.add(turn);
|
|
130
|
+
else loadingSteps.delete(turn);
|
|
131
|
+
},
|
|
132
|
+
clear() {
|
|
133
|
+
loadingSteps.clear();
|
|
134
|
+
if (snapshot !== null) publish(null);
|
|
135
|
+
},
|
|
136
|
+
join({ threadId, live, liveIds }) {
|
|
137
|
+
const history = snapshot;
|
|
138
|
+
if (history === null || history.turns.length === 0 || isDeepAgentHistoryDetached({ history, threadId, liveIds })) {
|
|
139
|
+
return { messages: live, atStart: false };
|
|
140
|
+
}
|
|
141
|
+
return { messages: joinDeepAgentHistory({ history, threadId, live, liveIds }), atStart: !history.more };
|
|
142
|
+
},
|
|
143
|
+
isDetached: ({ threadId, liveIds }) => snapshot !== null && isDeepAgentHistoryDetached({ history: snapshot, threadId, liveIds }),
|
|
144
|
+
async requestOlder({ send, threadId, before, beforeIsPrompt, turns }) {
|
|
145
|
+
const answer = readHistoryPageAnswer(await send(buildHistoryPageCommand({ before, turns })));
|
|
146
|
+
if (answer === null) throw new Error("history/page answered in a shape this client cannot read");
|
|
147
|
+
store.addPage({ threadId, before, beforeIsPrompt, answer });
|
|
148
|
+
return answer.turns.length;
|
|
149
|
+
},
|
|
150
|
+
async loadSteps({ send, marker }) {
|
|
151
|
+
var _a;
|
|
152
|
+
const current = snapshot;
|
|
153
|
+
if (current === null || marker.hiddenSteps === 0 || loadingSteps.has(marker.turn)) return;
|
|
154
|
+
const newestInsideTurn = current.anchorInsideTurn && ((_a = current.turns.at(-1)) == null ? void 0 : _a.id) === marker.turn;
|
|
155
|
+
const before = marker.before ?? (newestInsideTurn ? current.anchor : void 0);
|
|
156
|
+
loadingSteps.add(marker.turn);
|
|
157
|
+
try {
|
|
158
|
+
const answer = readTurnStepsAnswer(await send(buildTurnStepsCommand({ turn: marker.turn, before })));
|
|
159
|
+
if (answer === null) {
|
|
160
|
+
throw new Error("history/page answered steps in a shape this client cannot read");
|
|
161
|
+
}
|
|
162
|
+
store.addSteps({ threadId: current.threadId, answer });
|
|
163
|
+
} finally {
|
|
164
|
+
loadingSteps.delete(marker.turn);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
return store;
|
|
169
|
+
}
|
|
170
|
+
function toolCalls(messages) {
|
|
171
|
+
let tools = 0;
|
|
172
|
+
let delegations = 0;
|
|
173
|
+
for (const message of messages) {
|
|
174
|
+
if (message.type !== "ai") continue;
|
|
175
|
+
for (const call of message.tool_calls ?? []) {
|
|
176
|
+
if (toolNames.QUIET_TOOL_NAMES.has(call.name)) continue;
|
|
177
|
+
tools += 1;
|
|
178
|
+
if (call.name === "task") delegations += 1;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return { tools, delegations };
|
|
182
|
+
}
|
|
183
|
+
function readTurnStepsMarker(message) {
|
|
184
|
+
if (!isRecord(message) || !isRecord(message.additional_kwargs)) return void 0;
|
|
185
|
+
const marker = message.additional_kwargs[DEEP_AGENT_TURN_STEPS_KEY];
|
|
186
|
+
if (!isRecord(marker) || !isId(marker.turn)) return void 0;
|
|
187
|
+
const { hiddenSteps, hiddenTools, hiddenDelegations, before } = marker;
|
|
188
|
+
if (!isCount(hiddenSteps) || !isCount(hiddenTools) || !isCount(hiddenDelegations)) return void 0;
|
|
189
|
+
return {
|
|
190
|
+
turn: marker.turn,
|
|
191
|
+
hiddenSteps,
|
|
192
|
+
hiddenTools,
|
|
193
|
+
hiddenDelegations,
|
|
194
|
+
before: isId(before) ? before : void 0
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
const markedCopies = /* @__PURE__ */ new WeakMap();
|
|
198
|
+
function withMarker(message, marker) {
|
|
199
|
+
const key = JSON.stringify(marker);
|
|
200
|
+
const cached = markedCopies.get(message);
|
|
201
|
+
if ((cached == null ? void 0 : cached.key) === key) return cached.message;
|
|
202
|
+
const kwargs = message.additional_kwargs;
|
|
203
|
+
const marked = {
|
|
204
|
+
...message,
|
|
205
|
+
additional_kwargs: { ...kwargs ?? {}, [DEEP_AGENT_TURN_STEPS_KEY]: marker }
|
|
206
|
+
};
|
|
207
|
+
markedCopies.set(message, { key, message: marked });
|
|
208
|
+
return marked;
|
|
209
|
+
}
|
|
210
|
+
function joinDeepAgentHistory({
|
|
211
|
+
history,
|
|
212
|
+
threadId,
|
|
213
|
+
live,
|
|
214
|
+
liveIds
|
|
215
|
+
}) {
|
|
216
|
+
var _a, _b;
|
|
217
|
+
if (history === null || history.turns.length === 0 || isDeepAgentHistoryDetached({ history, threadId, liveIds })) {
|
|
218
|
+
return live;
|
|
219
|
+
}
|
|
220
|
+
const joined = [];
|
|
221
|
+
let pendingMarker = null;
|
|
222
|
+
const markNext = (message) => {
|
|
223
|
+
if (pendingMarker === null || message.type !== "ai") return message;
|
|
224
|
+
const marked = withMarker(message, pendingMarker);
|
|
225
|
+
pendingMarker = null;
|
|
226
|
+
return marked;
|
|
227
|
+
};
|
|
228
|
+
for (const turn of history.turns) {
|
|
229
|
+
if (turn.steps === null) {
|
|
230
|
+
for (const message of turn.messages) {
|
|
231
|
+
if (!liveIds.has(message.id ?? "")) joined.push(message);
|
|
232
|
+
}
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
const loaded = ((_a = history.steps.get(turn.id)) == null ? void 0 : _a.messages) ?? [];
|
|
236
|
+
const [first, ...rest] = turn.messages;
|
|
237
|
+
const prompt = (first == null ? void 0 : first.type) === "human" ? first : void 0;
|
|
238
|
+
const answer = prompt === void 0 ? turn.messages : rest;
|
|
239
|
+
const paged = toolCalls(loaded);
|
|
240
|
+
pendingMarker = {
|
|
241
|
+
turn: turn.id,
|
|
242
|
+
hiddenSteps: Math.max(0, turn.steps.count - loaded.length),
|
|
243
|
+
hiddenTools: Math.max(0, turn.steps.tools - paged.tools),
|
|
244
|
+
hiddenDelegations: Math.max(0, turn.steps.delegations - paged.delegations),
|
|
245
|
+
before: (_b = loaded[0]) == null ? void 0 : _b.id
|
|
246
|
+
};
|
|
247
|
+
for (const message of [...prompt ? [prompt] : [], ...loaded, ...answer]) {
|
|
248
|
+
if (liveIds.has(message.id ?? "")) continue;
|
|
249
|
+
joined.push(markNext(message));
|
|
250
|
+
}
|
|
251
|
+
if (pendingMarker !== null && (turn !== history.turns.at(-1) || !history.anchorInsideTurn)) {
|
|
252
|
+
pendingMarker = null;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
for (const message of live) joined.push(markNext(message));
|
|
256
|
+
return joined;
|
|
257
|
+
}
|
|
258
|
+
function isDeepAgentHistoryDetached({
|
|
259
|
+
history,
|
|
260
|
+
threadId,
|
|
261
|
+
liveIds
|
|
262
|
+
}) {
|
|
263
|
+
if (threadId !== void 0 && history.threadId !== threadId) return true;
|
|
264
|
+
return liveIds.size > 0 && !liveIds.has(history.anchor);
|
|
265
|
+
}
|
|
266
|
+
exports.DEEP_AGENT_HISTORY_PAGE_TURNS = DEEP_AGENT_HISTORY_PAGE_TURNS;
|
|
267
|
+
exports.DEEP_AGENT_HISTORY_START_KEY = DEEP_AGENT_HISTORY_START_KEY;
|
|
268
|
+
exports.DEEP_AGENT_TURN_STEPS_KEY = DEEP_AGENT_TURN_STEPS_KEY;
|
|
269
|
+
exports.DEEP_AGENT_TURN_STEPS_PAGE = DEEP_AGENT_TURN_STEPS_PAGE;
|
|
270
|
+
exports.buildHistoryPageCommand = buildHistoryPageCommand;
|
|
271
|
+
exports.buildTurnStepsCommand = buildTurnStepsCommand;
|
|
272
|
+
exports.createDeepAgentHistoryStore = createDeepAgentHistoryStore;
|
|
273
|
+
exports.isDeepAgentHistoryAtStart = isDeepAgentHistoryAtStart;
|
|
274
|
+
exports.isDeepAgentHistoryDetached = isDeepAgentHistoryDetached;
|
|
275
|
+
exports.joinDeepAgentHistory = joinDeepAgentHistory;
|
|
276
|
+
exports.readHistoryPageAnswer = readHistoryPageAnswer;
|
|
277
|
+
exports.readTurnStepsAnswer = readTurnStepsAnswer;
|
|
278
|
+
exports.readTurnStepsMarker = readTurnStepsMarker;
|
|
279
|
+
//# sourceMappingURL=history-pages.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history-pages.cjs","sources":["../../../../agent-runtime/src/history-pages.ts"],"sourcesContent":["import type { LangChainMessage } from '@assistant-ui/react-langgraph';\nimport { DEEP_AGENT_HISTORY_PAGE_COMMAND } from './generated/runconfig-contract';\nimport { QUIET_TOOL_NAMES } from './tool-names';\n\n/**\n * Older history by command, a turn at a time — the client half of agora's\n * `history_page.py` (protocol 3, `docs/plans/2026-11-03-history-by-command-plan.md`).\n *\n * A host advertising `DEEP_AGENT_HISTORY_PAGE_PROTOCOL_VERSION` answers\n * `history/page` with whole turns older than a message the client holds, as a\n * command result: nothing is mounted in the attach's view, so no interest\n * document grows with how far back a reader goes, and a re-attach restates\n * nothing it paged. The client keeps the answers in a\n * {@link DeepAgentHistoryStore} and joins them in front of the live window\n * ({@link joinDeepAgentHistory}).\n *\n * A turn longer than the host's whole-turn limit rides as its prompt and its\n * answer, with `steps` counting what it left out; `history/page` with a\n * `turn` pages those steps newest first. The join marks each summarized turn\n * on a source message ({@link DEEP_AGENT_TURN_STEPS_KEY}) so a renderer reads\n * the turn's exact counts, and inserts the steps fetched so far between the\n * prompt and the answer.\n */\n\n/** Turns one `history/page` asks for. */\nexport const DEEP_AGENT_HISTORY_PAGE_TURNS = 10;\n/** Steps of one turn one `history/page` asks for. */\nexport const DEEP_AGENT_TURN_STEPS_PAGE = 100;\n/** `additional_kwargs` key the join marks a summarized turn's first reply message with. */\nexport const DEEP_AGENT_TURN_STEPS_KEY = 'athena_turn_steps';\n/**\n * Key on the composed thread state (`useDeepAgentThread`'s converter) set when\n * the paged turns joined in front of the window reach the transcript's start:\n * the live window's own `hasOlder` still says older messages exist, so an\n * edit's anchor search reads this to know the first message has no parent.\n */\nexport const DEEP_AGENT_HISTORY_START_KEY = 'athenaHistoryStart';\n\n/** Whether a composed thread state says its messages start at the transcript's start. */\nexport function isDeepAgentHistoryAtStart(state: unknown): boolean {\n return isRecord(state) && state[DEEP_AGENT_HISTORY_START_KEY] === true;\n}\n\n/** What a summarized turn's page left out (the host's `steps`). */\nexport interface DeepAgentHistoryTurnSteps {\n /** Messages left out. */\n count: number;\n /** Tool calls among the messages left out (a renderer adds the ones it holds). */\n tools: number;\n /** Of which `task` delegations. */\n delegations: number;\n first: string | null;\n last: string | null;\n}\n\n/** One turn of a `history/page` answer. */\nexport interface DeepAgentHistoryTurn {\n /** The turn's first message (its prompt), the id its steps are paged by. */\n id: string;\n /** What the page shows of it, oldest first: the prompt and the answer, or the whole turn. */\n messages: LangChainMessage[];\n /** What it left out, or `null` when the turn rides whole. */\n steps: DeepAgentHistoryTurnSteps | null;\n}\n\nexport interface DeepAgentHistoryPageAnswer {\n turns: DeepAgentHistoryTurn[];\n more: { before: boolean };\n}\n\nexport interface DeepAgentTurnStepsAnswer {\n turn: string;\n /** Steps, oldest first. */\n messages: LangChainMessage[];\n more: { before: boolean };\n}\n\n/** The `history/page` command asking for turns older than `before`. */\nexport interface HistoryPageCommand {\n readonly type: typeof DEEP_AGENT_HISTORY_PAGE_COMMAND;\n readonly before: string;\n readonly turns: number;\n}\n\n/** The `history/page` command asking for one turn's steps older than `before`. */\nexport interface TurnStepsCommand {\n readonly type: typeof DEEP_AGENT_HISTORY_PAGE_COMMAND;\n readonly turn: string;\n readonly before?: string;\n readonly steps: number;\n}\n\ndeclare module '@assistant-ui/core' {\n namespace Assistant {\n interface Commands {\n /** Older turns, outside the attach's view. */\n historyPage: HistoryPageCommand;\n /** One summarized turn's steps. */\n historyTurnSteps: TurnStepsCommand;\n }\n }\n}\n\nexport function buildHistoryPageCommand({\n before,\n turns = DEEP_AGENT_HISTORY_PAGE_TURNS,\n}: {\n before: string;\n turns?: number;\n}): HistoryPageCommand {\n return { type: DEEP_AGENT_HISTORY_PAGE_COMMAND, before, turns };\n}\n\nexport function buildTurnStepsCommand({\n turn,\n before,\n steps = DEEP_AGENT_TURN_STEPS_PAGE,\n}: {\n turn: string;\n before?: string | undefined;\n steps?: number;\n}): TurnStepsCommand {\n return {\n type: DEEP_AGENT_HISTORY_PAGE_COMMAND,\n turn,\n ...(before !== undefined && { before }),\n steps,\n };\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\nconst isCount = (value: unknown): value is number =>\n typeof value === 'number' && Number.isInteger(value) && value >= 0;\nconst isId = (value: unknown): value is string => typeof value === 'string' && value.length > 0;\n\nfunction readMessages(value: unknown): LangChainMessage[] | null {\n if (!Array.isArray(value)) return null;\n for (const message of value) {\n if (!isRecord(message) || !isId(message.id) || typeof message.type !== 'string') return null;\n }\n return value as LangChainMessage[];\n}\n\nfunction readMore(value: unknown): { before: boolean } | null {\n return isRecord(value) && typeof value.before === 'boolean' ? { before: value.before } : null;\n}\n\nfunction readSteps(value: unknown): DeepAgentHistoryTurnSteps | null | undefined {\n if (value === null) return null;\n if (!isRecord(value)) return undefined;\n const { count, tools, delegations, first, last } = value;\n if (!isCount(count) || !isCount(tools) || !isCount(delegations)) return undefined;\n if ((first !== null && !isId(first)) || (last !== null && !isId(last))) return undefined;\n return { count, tools, delegations, first, last };\n}\n\n/** A `history/page` answer to `{before, turns}`, or `null` when it is malformed. */\nexport function readHistoryPageAnswer(payload: unknown): DeepAgentHistoryPageAnswer | null {\n if (!isRecord(payload) || !Array.isArray(payload.turns)) return null;\n const more = readMore(payload.more);\n if (more === null) return null;\n const turns: DeepAgentHistoryTurn[] = [];\n for (const turn of payload.turns) {\n if (!isRecord(turn) || !isId(turn.id)) return null;\n const messages = readMessages(turn.messages);\n const steps = readSteps(turn.steps);\n if (messages === null || steps === undefined) return null;\n turns.push({ id: turn.id, messages, steps });\n }\n return { turns, more };\n}\n\n/** A `history/page` answer to `{turn, before?, steps}`, or `null` when it is malformed. */\nexport function readTurnStepsAnswer(payload: unknown): DeepAgentTurnStepsAnswer | null {\n if (!isRecord(payload) || !isId(payload.turn)) return null;\n const messages = readMessages(payload.messages);\n const more = readMore(payload.more);\n if (messages === null || more === null) return null;\n return { turn: payload.turn, messages, more };\n}\n\n/** The steps of one summarized turn fetched so far, oldest first. */\nexport interface DeepAgentHistoryTurnStepsLoaded {\n messages: LangChainMessage[];\n /** Older steps of the turn remain. */\n more: boolean;\n}\n\n/** The turns one conversation has paged in, in front of its live window. */\nexport interface DeepAgentHistorySnapshot {\n /** The conversation they belong to. */\n threadId: string;\n /** The message the first page was asked `before`: the live window's first message then. */\n anchor: string;\n /** Whether the anchor is a reply rather than a prompt: the newest turn's rest is in the live window. */\n anchorInsideTurn: boolean;\n /** Turns, oldest first. */\n turns: DeepAgentHistoryTurn[];\n /** Older turns remain beyond the first. */\n more: boolean;\n /** Steps fetched per summarized turn id. */\n steps: ReadonlyMap<string, DeepAgentHistoryTurnStepsLoaded>;\n}\n\n/** How a store asks the host: the thread's `sendCommand` (its answer, the command's payload). */\nexport type DeepAgentHistorySend = (command: HistoryPageCommand | TurnStepsCommand) => unknown;\n\n/**\n * The history paged in for the open conversation: a subscribable store the\n * thread's converter joins in front of its live window and the window sync\n * fills. One per provider, like the tool-output store; it holds one\n * conversation at a time and resets when another one pages.\n *\n * Everything history pages do runs through the store's methods, so a surface\n * that creates no store (it never pages by command) bundles none of it: the\n * shared thread and window sync only call `historyPages?.…`.\n */\nexport interface DeepAgentHistoryStore {\n /** The current snapshot (a new object on every change), or `null` when empty. */\n getSnapshot(): DeepAgentHistorySnapshot | null;\n subscribe(listener: () => void): () => void;\n /**\n * Adds a page asked `before` a message. A page for another conversation, or\n * asked before a message other than the oldest turn held, starts over.\n */\n addPage(page: {\n threadId: string;\n before: string;\n beforeIsPrompt: boolean;\n answer: DeepAgentHistoryPageAnswer;\n }): void;\n /** Adds one summarized turn's older steps. */\n addSteps(steps: { threadId: string; answer: DeepAgentTurnStepsAnswer }): void;\n /** Whether a steps request for the turn is in flight — the loader's dedupe. */\n isLoadingSteps(turn: string): boolean;\n setLoadingSteps(turn: string, loading: boolean): void;\n clear(): void;\n /**\n * The transcript to render: the held turns joined in front of the live\n * window ({@link joinDeepAgentHistory}), and whether they reach the\n * transcript's start (`more.before` false). `live` alone, `atStart` false,\n * while nothing held meets the window.\n */\n join(options: {\n threadId: string | undefined;\n live: LangChainMessage[];\n liveIds: ReadonlySet<string>;\n }): { messages: LangChainMessage[]; atStart: boolean };\n /** Whether the held turns no longer meet the live window ({@link isDeepAgentHistoryDetached}). */\n isDetached(options: { threadId: string | undefined; liveIds: ReadonlySet<string> }): boolean;\n /**\n * Asks the host for the turns before `before` and adds them; resolves how\n * many it answered. Rejects with the host's refusal, or when the answer is\n * not a page this client reads.\n */\n requestOlder(options: {\n send: DeepAgentHistorySend;\n threadId: string;\n before: string;\n beforeIsPrompt: boolean;\n turns?: number;\n }): Promise<number>;\n /**\n * Fetches a summarized turn's next older steps (`history/page` with its\n * `turn`) into the store, newest first. A turn already loading, or with no\n * steps left, is a no-op. Rejects with the host's refusal.\n */\n loadSteps(options: { send: DeepAgentHistorySend; marker: DeepAgentTurnStepsMarker }): Promise<void>;\n}\n\nexport function createDeepAgentHistoryStore(): DeepAgentHistoryStore {\n let snapshot: DeepAgentHistorySnapshot | null = null;\n const loadingSteps = new Set<string>();\n const listeners = new Set<() => void>();\n const publish = (next: DeepAgentHistorySnapshot | null) => {\n snapshot = next;\n for (const listener of listeners) listener();\n };\n const store: DeepAgentHistoryStore = {\n getSnapshot: () => snapshot,\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n addPage({ threadId, before, beforeIsPrompt, answer }) {\n const current = snapshot;\n const continues =\n current !== null && current.threadId === threadId && current.turns[0]?.id === before;\n if (!continues) {\n loadingSteps.clear();\n publish({\n threadId,\n anchor: before,\n anchorInsideTurn: !beforeIsPrompt,\n turns: answer.turns,\n more: answer.more.before,\n steps: new Map(),\n });\n return;\n }\n const held = new Set(current.turns.map((turn) => turn.id));\n publish({\n ...current,\n turns: [...answer.turns.filter((turn) => !held.has(turn.id)), ...current.turns],\n more: answer.more.before,\n });\n },\n addSteps({ threadId, answer }) {\n const current = snapshot;\n if (current === null || current.threadId !== threadId) return;\n if (!current.turns.some((turn) => turn.id === answer.turn)) return;\n const loaded = current.steps.get(answer.turn);\n const held = new Set(loaded?.messages.map((message) => message.id));\n const steps = new Map(current.steps);\n steps.set(answer.turn, {\n messages: [\n ...answer.messages.filter((message) => !held.has(message.id)),\n ...(loaded?.messages ?? []),\n ],\n more: answer.more.before,\n });\n publish({ ...current, steps });\n },\n isLoadingSteps: (turn) => loadingSteps.has(turn),\n setLoadingSteps(turn, loading) {\n if (loading) loadingSteps.add(turn);\n else loadingSteps.delete(turn);\n },\n clear() {\n loadingSteps.clear();\n if (snapshot !== null) publish(null);\n },\n join({ threadId, live, liveIds }) {\n const history = snapshot;\n if (history === null || history.turns.length === 0 || isDeepAgentHistoryDetached({ history, threadId, liveIds })) {\n return { messages: live, atStart: false };\n }\n return { messages: joinDeepAgentHistory({ history, threadId, live, liveIds }), atStart: !history.more };\n },\n isDetached: ({ threadId, liveIds }) =>\n snapshot !== null && isDeepAgentHistoryDetached({ history: snapshot, threadId, liveIds }),\n async requestOlder({ send, threadId, before, beforeIsPrompt, turns }) {\n const answer = readHistoryPageAnswer(await send(buildHistoryPageCommand({ before, turns })));\n if (answer === null) throw new Error('history/page answered in a shape this client cannot read');\n store.addPage({ threadId, before, beforeIsPrompt, answer });\n return answer.turns.length;\n },\n async loadSteps({ send, marker }) {\n const current = snapshot;\n if (current === null || marker.hiddenSteps === 0 || loadingSteps.has(marker.turn)) return;\n // The newest turn of a page asked inside a turn: its later steps are in\n // the live window, so the steps it left out end at the page's anchor.\n const newestInsideTurn = current.anchorInsideTurn && current.turns.at(-1)?.id === marker.turn;\n const before = marker.before ?? (newestInsideTurn ? current.anchor : undefined);\n loadingSteps.add(marker.turn);\n try {\n const answer = readTurnStepsAnswer(await send(buildTurnStepsCommand({ turn: marker.turn, before })));\n if (answer === null) {\n throw new Error('history/page answered steps in a shape this client cannot read');\n }\n store.addSteps({ threadId: current.threadId, answer });\n } finally {\n loadingSteps.delete(marker.turn);\n }\n },\n };\n return store;\n}\n\n/**\n * The marker the join puts on a summarized turn's first reply message: the\n * turn's steps it has not shown yet, so a renderer reads exact counts (\"Used\n * 313 tools\") and knows whether opening it has steps to fetch.\n */\nexport interface DeepAgentTurnStepsMarker {\n /** The turn's first message: the id its steps are paged by. */\n turn: string;\n /** Steps not loaded yet. */\n hiddenSteps: number;\n /** Tool calls among them. */\n hiddenTools: number;\n /** Of which `task` delegations. */\n hiddenDelegations: number;\n /** The oldest step loaded, the next steps request's `before`. */\n before: string | undefined;\n}\n\n/**\n * The tool calls among `messages` the converter shows. The host counts every\n * call of a turn; a quiet call (`QUIET_TOOL_NAMES`) never renders, so it stays\n * in the hidden count once loaded and the turn's total holds still as its\n * steps load.\n */\nfunction toolCalls(messages: readonly LangChainMessage[]): { tools: number; delegations: number } {\n let tools = 0;\n let delegations = 0;\n for (const message of messages) {\n if (message.type !== 'ai') continue;\n for (const call of message.tool_calls ?? []) {\n if (QUIET_TOOL_NAMES.has(call.name)) continue;\n tools += 1;\n if (call.name === 'task') delegations += 1;\n }\n }\n return { tools, delegations };\n}\n\n/** The marker a join put on a source message, or `undefined`. */\nexport function readTurnStepsMarker(message: unknown): DeepAgentTurnStepsMarker | undefined {\n if (!isRecord(message) || !isRecord(message.additional_kwargs)) return undefined;\n const marker = message.additional_kwargs[DEEP_AGENT_TURN_STEPS_KEY];\n if (!isRecord(marker) || !isId(marker.turn)) return undefined;\n const { hiddenSteps, hiddenTools, hiddenDelegations, before } = marker;\n if (!isCount(hiddenSteps) || !isCount(hiddenTools) || !isCount(hiddenDelegations)) return undefined;\n return {\n turn: marker.turn,\n hiddenSteps,\n hiddenTools,\n hiddenDelegations,\n before: isId(before) ? before : undefined,\n };\n}\n\n/** The marked copy of a message, reused while the message and its marker are the same. */\nconst markedCopies = new WeakMap<object, { key: string; message: LangChainMessage }>();\n\nfunction withMarker(message: LangChainMessage, marker: DeepAgentTurnStepsMarker): LangChainMessage {\n const key = JSON.stringify(marker);\n const cached = markedCopies.get(message);\n if (cached?.key === key) return cached.message;\n // Every wire message carries `additional_kwargs` in practice; the upstream\n // type leaves it off tool messages.\n const kwargs = (message as { additional_kwargs?: Record<string, unknown> }).additional_kwargs;\n const marked = {\n ...message,\n additional_kwargs: { ...(kwargs ?? {}), [DEEP_AGENT_TURN_STEPS_KEY]: marker },\n } as LangChainMessage;\n markedCopies.set(message, { key, message: marked });\n return marked;\n}\n\n/**\n * The transcript a converter renders: the paged turns in front of the live\n * window, when they still meet it.\n *\n * The paged turns end just before the snapshot's anchor. While the anchor is\n * in `live`, they are joined in front of it, minus any message `live` already\n * holds (a reveal or an edit paged an interest page over the same range). When\n * the anchor has left the live window (an edit rewound past it, a branch\n * switch), the pages describe another transcript: `live` is returned alone,\n * and {@link isDeepAgentHistoryDetached} tells the window sync to clear them.\n *\n * Each summarized turn gets its fetched steps between its prompt and its\n * answer, and its first reply message the {@link DeepAgentTurnStepsMarker}.\n * The newest turn of a page asked inside a turn has its rest in `live`, so its\n * marker lands on the first live message after its prompt.\n */\nexport function joinDeepAgentHistory({\n history,\n threadId,\n live,\n liveIds,\n}: {\n history: DeepAgentHistorySnapshot | null;\n threadId: string | undefined;\n live: LangChainMessage[];\n /** The live window's chain ids; the anchor must be among them. */\n liveIds: ReadonlySet<string>;\n}): LangChainMessage[] {\n if (history === null || history.turns.length === 0 || isDeepAgentHistoryDetached({ history, threadId, liveIds })) {\n return live;\n }\n const joined: LangChainMessage[] = [];\n let pendingMarker: DeepAgentTurnStepsMarker | null = null;\n // The marker rides an assistant message: a tool result whose call is older\n // than what is loaded (a head that starts on one) converts to no row.\n const markNext = (message: LangChainMessage): LangChainMessage => {\n if (pendingMarker === null || message.type !== 'ai') return message;\n const marked = withMarker(message, pendingMarker);\n pendingMarker = null;\n return marked;\n };\n for (const turn of history.turns) {\n if (turn.steps === null) {\n for (const message of turn.messages) {\n if (!liveIds.has(message.id ?? '')) joined.push(message);\n }\n continue;\n }\n const loaded = history.steps.get(turn.id)?.messages ?? [];\n const [first, ...rest] = turn.messages;\n const prompt = first?.type === 'human' ? first : undefined;\n const answer = prompt === undefined ? turn.messages : rest;\n // The host counts only the messages the page left out; of those, the\n // steps paged in since render on their own, so they leave the hidden count.\n const paged = toolCalls(loaded);\n pendingMarker = {\n turn: turn.id,\n hiddenSteps: Math.max(0, turn.steps.count - loaded.length),\n hiddenTools: Math.max(0, turn.steps.tools - paged.tools),\n hiddenDelegations: Math.max(0, turn.steps.delegations - paged.delegations),\n before: loaded[0]?.id,\n };\n for (const message of [...(prompt ? [prompt] : []), ...loaded, ...answer]) {\n if (liveIds.has(message.id ?? '')) continue;\n joined.push(markNext(message));\n }\n // A summarized turn with no reply shown carries its marker no further,\n // except the newest one of a page asked inside a turn: its rest is live.\n if (pendingMarker !== null && (turn !== history.turns.at(-1) || !history.anchorInsideTurn)) {\n pendingMarker = null;\n }\n }\n for (const message of live) joined.push(markNext(message));\n return joined;\n}\n\n/** Whether the paged turns no longer meet the live window: another conversation, or the anchor left it. */\nexport function isDeepAgentHistoryDetached({\n history,\n threadId,\n liveIds,\n}: {\n history: DeepAgentHistorySnapshot;\n threadId: string | undefined;\n liveIds: ReadonlySet<string>;\n}): boolean {\n if (threadId !== undefined && history.threadId !== threadId) return true;\n return liveIds.size > 0 && !liveIds.has(history.anchor);\n}\n"],"names":["DEEP_AGENT_HISTORY_PAGE_COMMAND","QUIET_TOOL_NAMES"],"mappings":";;;;AAyBO,MAAM,gCAAgC;AAEtC,MAAM,6BAA6B;AAEnC,MAAM,4BAA4B;AAOlC,MAAM,+BAA+B;AAGrC,SAAS,0BAA0B,OAAyB;AACjE,SAAO,SAAS,KAAK,KAAK,MAAM,4BAA4B,MAAM;AACpE;AA8DO,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA,QAAQ;AACV,GAGuB;AACrB,SAAO,EAAE,MAAMA,mDAAiC,QAAQ,MAAA;AAC1D;AAEO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA,QAAQ;AACV,GAIqB;AACnB,SAAO;AAAA,IACL,MAAMA,kBAAAA;AAAAA,IACN;AAAA,IACA,GAAI,WAAW,UAAa,EAAE,OAAA;AAAA,IAC9B;AAAA,EAAA;AAEJ;AAEA,MAAM,WAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AACrE,MAAM,UAAU,CAAC,UACf,OAAO,UAAU,YAAY,OAAO,UAAU,KAAK,KAAK,SAAS;AACnE,MAAM,OAAO,CAAC,UAAoC,OAAO,UAAU,YAAY,MAAM,SAAS;AAE9F,SAAS,aAAa,OAA2C;AAC/D,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO;AAClC,aAAW,WAAW,OAAO;AAC3B,QAAI,CAAC,SAAS,OAAO,KAAK,CAAC,KAAK,QAAQ,EAAE,KAAK,OAAO,QAAQ,SAAS,SAAU,QAAO;AAAA,EAC1F;AACA,SAAO;AACT;AAEA,SAAS,SAAS,OAA4C;AAC5D,SAAO,SAAS,KAAK,KAAK,OAAO,MAAM,WAAW,YAAY,EAAE,QAAQ,MAAM,OAAA,IAAW;AAC3F;AAEA,SAAS,UAAU,OAA8D;AAC/E,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,EAAE,OAAO,OAAO,aAAa,OAAO,SAAS;AACnD,MAAI,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,WAAW,EAAG,QAAO;AACxE,MAAK,UAAU,QAAQ,CAAC,KAAK,KAAK,KAAO,SAAS,QAAQ,CAAC,KAAK,IAAI,EAAI,QAAO;AAC/E,SAAO,EAAE,OAAO,OAAO,aAAa,OAAO,KAAA;AAC7C;AAGO,SAAS,sBAAsB,SAAqD;AACzF,MAAI,CAAC,SAAS,OAAO,KAAK,CAAC,MAAM,QAAQ,QAAQ,KAAK,EAAG,QAAO;AAChE,QAAM,OAAO,SAAS,QAAQ,IAAI;AAClC,MAAI,SAAS,KAAM,QAAO;AAC1B,QAAM,QAAgC,CAAA;AACtC,aAAW,QAAQ,QAAQ,OAAO;AAChC,QAAI,CAAC,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,EAAE,EAAG,QAAO;AAC9C,UAAM,WAAW,aAAa,KAAK,QAAQ;AAC3C,UAAM,QAAQ,UAAU,KAAK,KAAK;AAClC,QAAI,aAAa,QAAQ,UAAU,OAAW,QAAO;AACrD,UAAM,KAAK,EAAE,IAAI,KAAK,IAAI,UAAU,OAAO;AAAA,EAC7C;AACA,SAAO,EAAE,OAAO,KAAA;AAClB;AAGO,SAAS,oBAAoB,SAAmD;AACrF,MAAI,CAAC,SAAS,OAAO,KAAK,CAAC,KAAK,QAAQ,IAAI,EAAG,QAAO;AACtD,QAAM,WAAW,aAAa,QAAQ,QAAQ;AAC9C,QAAM,OAAO,SAAS,QAAQ,IAAI;AAClC,MAAI,aAAa,QAAQ,SAAS,KAAM,QAAO;AAC/C,SAAO,EAAE,MAAM,QAAQ,MAAM,UAAU,KAAA;AACzC;AA2FO,SAAS,8BAAqD;AACnE,MAAI,WAA4C;AAChD,QAAM,mCAAmB,IAAA;AACzB,QAAM,gCAAgB,IAAA;AACtB,QAAM,UAAU,CAAC,SAA0C;AACzD,eAAW;AACX,eAAW,YAAY,UAAW,UAAA;AAAA,EACpC;AACA,QAAM,QAA+B;AAAA,IACnC,aAAa,MAAM;AAAA,IACnB,UAAU,UAAU;AAClB,gBAAU,IAAI,QAAQ;AACtB,aAAO,MAAM;AACX,kBAAU,OAAO,QAAQ;AAAA,MAC3B;AAAA,IACF;AAAA,IACA,QAAQ,EAAE,UAAU,QAAQ,gBAAgB,UAAU;;AACpD,YAAM,UAAU;AAChB,YAAM,YACJ,YAAY,QAAQ,QAAQ,aAAa,cAAY,aAAQ,MAAM,CAAC,MAAf,mBAAkB,QAAO;AAChF,UAAI,CAAC,WAAW;AACd,qBAAa,MAAA;AACb,gBAAQ;AAAA,UACN;AAAA,UACA,QAAQ;AAAA,UACR,kBAAkB,CAAC;AAAA,UACnB,OAAO,OAAO;AAAA,UACd,MAAM,OAAO,KAAK;AAAA,UAClB,2BAAW,IAAA;AAAA,QAAI,CAChB;AACD;AAAA,MACF;AACA,YAAM,OAAO,IAAI,IAAI,QAAQ,MAAM,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC;AACzD,cAAQ;AAAA,QACN,GAAG;AAAA,QACH,OAAO,CAAC,GAAG,OAAO,MAAM,OAAO,CAAC,SAAS,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC,GAAG,GAAG,QAAQ,KAAK;AAAA,QAC9E,MAAM,OAAO,KAAK;AAAA,MAAA,CACnB;AAAA,IACH;AAAA,IACA,SAAS,EAAE,UAAU,UAAU;AAC7B,YAAM,UAAU;AAChB,UAAI,YAAY,QAAQ,QAAQ,aAAa,SAAU;AACvD,UAAI,CAAC,QAAQ,MAAM,KAAK,CAAC,SAAS,KAAK,OAAO,OAAO,IAAI,EAAG;AAC5D,YAAM,SAAS,QAAQ,MAAM,IAAI,OAAO,IAAI;AAC5C,YAAM,OAAO,IAAI,IAAI,iCAAQ,SAAS,IAAI,CAAC,YAAY,QAAQ,GAAG;AAClE,YAAM,QAAQ,IAAI,IAAI,QAAQ,KAAK;AACnC,YAAM,IAAI,OAAO,MAAM;AAAA,QACrB,UAAU;AAAA,UACR,GAAG,OAAO,SAAS,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,QAAQ,EAAE,CAAC;AAAA,UAC5D,IAAI,iCAAQ,aAAY,CAAA;AAAA,QAAC;AAAA,QAE3B,MAAM,OAAO,KAAK;AAAA,MAAA,CACnB;AACD,cAAQ,EAAE,GAAG,SAAS,OAAO;AAAA,IAC/B;AAAA,IACA,gBAAgB,CAAC,SAAS,aAAa,IAAI,IAAI;AAAA,IAC/C,gBAAgB,MAAM,SAAS;AAC7B,UAAI,QAAS,cAAa,IAAI,IAAI;AAAA,UAC7B,cAAa,OAAO,IAAI;AAAA,IAC/B;AAAA,IACA,QAAQ;AACN,mBAAa,MAAA;AACb,UAAI,aAAa,KAAM,SAAQ,IAAI;AAAA,IACrC;AAAA,IACA,KAAK,EAAE,UAAU,MAAM,WAAW;AAChC,YAAM,UAAU;AAChB,UAAI,YAAY,QAAQ,QAAQ,MAAM,WAAW,KAAK,2BAA2B,EAAE,SAAS,UAAU,QAAA,CAAS,GAAG;AAChH,eAAO,EAAE,UAAU,MAAM,SAAS,MAAA;AAAA,MACpC;AACA,aAAO,EAAE,UAAU,qBAAqB,EAAE,SAAS,UAAU,MAAM,QAAA,CAAS,GAAG,SAAS,CAAC,QAAQ,KAAA;AAAA,IACnG;AAAA,IACA,YAAY,CAAC,EAAE,UAAU,cACvB,aAAa,QAAQ,2BAA2B,EAAE,SAAS,UAAU,UAAU,SAAS;AAAA,IAC1F,MAAM,aAAa,EAAE,MAAM,UAAU,QAAQ,gBAAgB,SAAS;AACpE,YAAM,SAAS,sBAAsB,MAAM,KAAK,wBAAwB,EAAE,QAAQ,MAAA,CAAO,CAAC,CAAC;AAC3F,UAAI,WAAW,KAAM,OAAM,IAAI,MAAM,0DAA0D;AAC/F,YAAM,QAAQ,EAAE,UAAU,QAAQ,gBAAgB,QAAQ;AAC1D,aAAO,OAAO,MAAM;AAAA,IACtB;AAAA,IACA,MAAM,UAAU,EAAE,MAAM,UAAU;;AAChC,YAAM,UAAU;AAChB,UAAI,YAAY,QAAQ,OAAO,gBAAgB,KAAK,aAAa,IAAI,OAAO,IAAI,EAAG;AAGnF,YAAM,mBAAmB,QAAQ,sBAAoB,aAAQ,MAAM,GAAG,EAAE,MAAnB,mBAAsB,QAAO,OAAO;AACzF,YAAM,SAAS,OAAO,WAAW,mBAAmB,QAAQ,SAAS;AACrE,mBAAa,IAAI,OAAO,IAAI;AAC5B,UAAI;AACF,cAAM,SAAS,oBAAoB,MAAM,KAAK,sBAAsB,EAAE,MAAM,OAAO,MAAM,OAAA,CAAQ,CAAC,CAAC;AACnG,YAAI,WAAW,MAAM;AACnB,gBAAM,IAAI,MAAM,gEAAgE;AAAA,QAClF;AACA,cAAM,SAAS,EAAE,UAAU,QAAQ,UAAU,QAAQ;AAAA,MACvD,UAAA;AACE,qBAAa,OAAO,OAAO,IAAI;AAAA,MACjC;AAAA,IACF;AAAA,EAAA;AAEF,SAAO;AACT;AA0BA,SAAS,UAAU,UAA+E;AAChG,MAAI,QAAQ;AACZ,MAAI,cAAc;AAClB,aAAW,WAAW,UAAU;AAC9B,QAAI,QAAQ,SAAS,KAAM;AAC3B,eAAW,QAAQ,QAAQ,cAAc,CAAA,GAAI;AAC3C,UAAIC,2BAAiB,IAAI,KAAK,IAAI,EAAG;AACrC,eAAS;AACT,UAAI,KAAK,SAAS,OAAQ,gBAAe;AAAA,IAC3C;AAAA,EACF;AACA,SAAO,EAAE,OAAO,YAAA;AAClB;AAGO,SAAS,oBAAoB,SAAwD;AAC1F,MAAI,CAAC,SAAS,OAAO,KAAK,CAAC,SAAS,QAAQ,iBAAiB,EAAG,QAAO;AACvE,QAAM,SAAS,QAAQ,kBAAkB,yBAAyB;AAClE,MAAI,CAAC,SAAS,MAAM,KAAK,CAAC,KAAK,OAAO,IAAI,EAAG,QAAO;AACpD,QAAM,EAAE,aAAa,aAAa,mBAAmB,WAAW;AAChE,MAAI,CAAC,QAAQ,WAAW,KAAK,CAAC,QAAQ,WAAW,KAAK,CAAC,QAAQ,iBAAiB,EAAG,QAAO;AAC1F,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,KAAK,MAAM,IAAI,SAAS;AAAA,EAAA;AAEpC;AAGA,MAAM,mCAAmB,QAAA;AAEzB,SAAS,WAAW,SAA2B,QAAoD;AACjG,QAAM,MAAM,KAAK,UAAU,MAAM;AACjC,QAAM,SAAS,aAAa,IAAI,OAAO;AACvC,OAAI,iCAAQ,SAAQ,IAAK,QAAO,OAAO;AAGvC,QAAM,SAAU,QAA4D;AAC5E,QAAM,SAAS;AAAA,IACb,GAAG;AAAA,IACH,mBAAmB,EAAE,GAAI,UAAU,CAAA,GAAK,CAAC,yBAAyB,GAAG,OAAA;AAAA,EAAO;AAE9E,eAAa,IAAI,SAAS,EAAE,KAAK,SAAS,QAAQ;AAClD,SAAO;AACT;AAkBO,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMuB;;AACrB,MAAI,YAAY,QAAQ,QAAQ,MAAM,WAAW,KAAK,2BAA2B,EAAE,SAAS,UAAU,QAAA,CAAS,GAAG;AAChH,WAAO;AAAA,EACT;AACA,QAAM,SAA6B,CAAA;AACnC,MAAI,gBAAiD;AAGrD,QAAM,WAAW,CAAC,YAAgD;AAChE,QAAI,kBAAkB,QAAQ,QAAQ,SAAS,KAAM,QAAO;AAC5D,UAAM,SAAS,WAAW,SAAS,aAAa;AAChD,oBAAgB;AAChB,WAAO;AAAA,EACT;AACA,aAAW,QAAQ,QAAQ,OAAO;AAChC,QAAI,KAAK,UAAU,MAAM;AACvB,iBAAW,WAAW,KAAK,UAAU;AACnC,YAAI,CAAC,QAAQ,IAAI,QAAQ,MAAM,EAAE,EAAG,QAAO,KAAK,OAAO;AAAA,MACzD;AACA;AAAA,IACF;AACA,UAAM,WAAS,aAAQ,MAAM,IAAI,KAAK,EAAE,MAAzB,mBAA4B,aAAY,CAAA;AACvD,UAAM,CAAC,OAAO,GAAG,IAAI,IAAI,KAAK;AAC9B,UAAM,UAAS,+BAAO,UAAS,UAAU,QAAQ;AACjD,UAAM,SAAS,WAAW,SAAY,KAAK,WAAW;AAGtD,UAAM,QAAQ,UAAU,MAAM;AAC9B,oBAAgB;AAAA,MACd,MAAM,KAAK;AAAA,MACX,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,OAAO,MAAM;AAAA,MACzD,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,MAAM,KAAK;AAAA,MACvD,mBAAmB,KAAK,IAAI,GAAG,KAAK,MAAM,cAAc,MAAM,WAAW;AAAA,MACzE,SAAQ,YAAO,CAAC,MAAR,mBAAW;AAAA,IAAA;AAErB,eAAW,WAAW,CAAC,GAAI,SAAS,CAAC,MAAM,IAAI,CAAA,GAAK,GAAG,QAAQ,GAAG,MAAM,GAAG;AACzE,UAAI,QAAQ,IAAI,QAAQ,MAAM,EAAE,EAAG;AACnC,aAAO,KAAK,SAAS,OAAO,CAAC;AAAA,IAC/B;AAGA,QAAI,kBAAkB,SAAS,SAAS,QAAQ,MAAM,GAAG,EAAE,KAAK,CAAC,QAAQ,mBAAmB;AAC1F,sBAAgB;AAAA,IAClB;AAAA,EACF;AACA,aAAW,WAAW,KAAM,QAAO,KAAK,SAAS,OAAO,CAAC;AACzD,SAAO;AACT;AAGO,SAAS,2BAA2B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AACF,GAIY;AACV,MAAI,aAAa,UAAa,QAAQ,aAAa,SAAU,QAAO;AACpE,SAAO,QAAQ,OAAO,KAAK,CAAC,QAAQ,IAAI,QAAQ,MAAM;AACxD;;;;;;;;;;;;;;"}
|