From a33ad0d1b9a37d8836b9e4bae5b103a6bdf94b46 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Wed, 20 May 2026 18:23:36 +0100 Subject: [PATCH 01/58] test a2a jsonrpc and http transports --- plan/05-20-a2a-connect-streaming-files.md | 395 ++++++++++++++++++ tests/integration/a2a/conftest.py | 146 +++++++ .../a2a/test_remote_agent_runtime.py | 50 +++ 3 files changed, 591 insertions(+) create mode 100644 plan/05-20-a2a-connect-streaming-files.md create mode 100644 tests/integration/a2a/conftest.py create mode 100644 tests/integration/a2a/test_remote_agent_runtime.py diff --git a/plan/05-20-a2a-connect-streaming-files.md b/plan/05-20-a2a-connect-streaming-files.md new file mode 100644 index 000000000..e13a007ea --- /dev/null +++ b/plan/05-20-a2a-connect-streaming-files.md @@ -0,0 +1,395 @@ +# A2A connect, transport, streaming, and file handling plan + +Date: 2026-05-20 +Owner: fast-agent A2A client work +Recording folder: `/home/ssmith/plan/records/` + +## Goal + +Make remote A2A agents easy to connect to, prove each supported transport works, +and support the happy path for streaming and file-capable A2A messages from both +CLI and TUI flows. + +The feature should be demonstrable against both the A2A SDK sample server and a +small fast-agent-owned fake A2A server fixture that deterministically exercises +streaming, artifacts, and file/data parts. + +## Working rules + +- Keep diffs small and commit at natural checkpoints. +- Before each commit, run at minimum: + + ```bash + uv run scripts/lint.py + uv run scripts/typecheck.py + ``` + +- For focused changes, also run the relevant pytest target before committing. +- Do not rewrite unrelated files or existing user changes. +- Store terminal captures and asciinema recordings under: + + ```text + /home/ssmith/plan/records/ + ``` + +- Prefer SDK/server fixtures over monkeypatching A2A clients. + +## Outcomes + +1. A user can test a remote A2A endpoint interactively with `/a2a connect`. +2. JSON-RPC and HTTP+JSON are covered by SDK-backed integration tests. +3. gRPC is covered when optional dependencies/environment are available, and is + skipped clearly otherwise. +4. A2A streaming updates render without duplicate/blank headers and settle into a + normal assistant turn in the TUI. +5. A2A file/data happy paths are implemented and tested: + - outbound fast-agent attachment or URL -> A2A `Part(raw=...)`/`Part(url=...)`; + - inbound A2A `Part(url=...)`/`Part(data=...)`/text artifact -> readable + fast-agent assistant content; + - raw inbound bytes are at least detected and represented safely. +6. The same scenarios are testable through non-interactive CLI and through the TUI. + +## URL and transport semantics + +### Accepted connect URLs + +`/a2a connect` should accept: + +```text +/a2a connect http://127.0.0.1:41241 +/a2a connect https://agent.example.com +/a2a connect https://agent.example.com/base --card-path /.well-known/agent-card.json +/a2a connect http://127.0.0.1:41241/.well-known/agent-card.json +``` + +Preferred input is the A2A agent base URL. Direct agent-card URLs may be accepted +as a convenience by normalizing to base URL plus `relative_card_path`. + +Endpoint URLs such as `/a2a/jsonrpc` are not the preferred user input. If they are +provided, emit a clear diagnostic explaining that fast-agent expects the base URL +or card URL. + +### Accepted transports + +Canonical transport names passed to the SDK: + +```text +JSONRPC +HTTP+JSON +GRPC +``` + +Friendly command aliases should normalize as follows: + +```text +jsonrpc, json-rpc, rpc -> JSONRPC +http, http+json, rest -> HTTP+JSON +grpc -> GRPC +``` + +If no transport is provided, let the SDK choose from the remote AgentCard and show +what was selected. + +## Step 1 — Baseline transport integration tests + +### Implementation + +- Add an integration test fixture that starts an A2A SDK-compatible test server. +- Cover creation through normal fast-agent card/factory/runtime paths. +- Test JSON-RPC text request/response. +- Test HTTP+JSON text request/response. +- Add optional gRPC coverage guarded by dependency/port availability. + +### Test commands + +```bash +uv run pytest tests/integration/a2a -q +uv run scripts/lint.py +uv run scripts/typecheck.py +``` + +### CLI check + +```bash +uv run fast-agent -x --agent-cards /tmp/a2a-card.yaml --agent hello_remote --message hello --quiet +``` + +Expected: text response from the remote server. + +### TUI check + +Use tmux to start fast-agent, send `hello`, capture pane text, and verify the +assistant response appears under an `A2A` assistant header. + +### Commit + +Commit after tests/lint/typecheck pass. + +## Step 2 — Fake A2A server fixture for deterministic behavior + +### Implementation + +Build a small local test server under tests/support or tests/integration/a2a that +uses SDK server primitives and exposes: + +- text echo response; +- delayed streaming status updates; +- artifact text updates; +- outbound file/data response modes; +- JSON-RPC and HTTP+JSON routes; +- gRPC only if available without making CI brittle. + +Avoid coupling tests to the external SDK sample process where possible. Keep the +external sample useful for manual smoke tests and recordings. + +### Test commands + +```bash +uv run pytest tests/integration/a2a -q +uv run scripts/lint.py +uv run scripts/typecheck.py +``` + +### Commit + +Commit after the fixture and baseline tests pass. + +## Step 3 — `/a2a status`, `/a2a card`, `/a2a reset` + +### Implementation + +Add the diagnostic commands before connect so connect has reusable reporting +helpers. + +Expected surfaces: + +```text +/a2a status [agent] +/a2a card [agent] +/a2a reset [agent] +``` + +`status` should show URL, remote card name, selected/requested transport, +streaming/polling flags, context id, current task id, last task state, and output +modes where available. + +`card` should show the resolved remote AgentCard summary and supported +interfaces. + +`reset` should clear `context_id`, `current_task_id`, and `last_task_state`. + +### Test commands + +```bash +uv run pytest tests/unit/fast_agent/ui tests/integration/a2a -q +uv run scripts/lint.py +uv run scripts/typecheck.py +``` + +### CLI/TUI checks + +- TUI: run `/a2a status`, `/a2a card`, `/a2a reset`, then send `hello`. +- CLI if slash-command execution is available non-interactively: run equivalent + command dispatch tests or documented command invocation. + +### Commit + +Commit after command behavior is tested. + +## Step 4 — `/a2a connect` + +### Implementation + +Add: + +```text +/a2a connect [--transport JSONRPC|HTTP+JSON|GRPC] [--name NAME] [--card-path PATH] +``` + +Behavior: + +1. Normalize URL/card path. +2. Resolve remote AgentCard. +3. Display remote card summary and supported interfaces. +4. Validate requested transport if supplied. +5. Create a runtime A2A agent or update/switch to a temporary connected agent. +6. Show selected transport and next action. + +Persistent save/write-back is deferred unless trivial. If deferred, print the +YAML snippet the user can save. + +### Test commands + +```bash +uv run pytest tests/unit/fast_agent/ui tests/integration/a2a -q +uv run scripts/lint.py +uv run scripts/typecheck.py +``` + +### CLI check + +```bash +uv run fast-agent -x --agent-cards /tmp/minimal-local-card.yaml --agent passthrough_or_default +``` + +Then in TUI: + +```text +/a2a connect http://127.0.0.1:41241 --transport JSONRPC --name hello_remote +hello +``` + +Expected: active/connected A2A agent responds. + +### Recording + +Save an asciinema capture: + +```text +/home/ssmith/plan/records/a2a-connect-jsonrpc.cast +``` + +### Commit + +Commit after `/a2a connect` works and recordings are captured. + +## Step 5 — Streaming display + +### Implementation + +Route A2A streaming events into the existing streaming/progress display rather +than only aggregating final text. + +Requirements: + +- task status updates should update progress without corrupting the transcript; +- artifact/direct-message text should appear as streaming assistant content; +- final render should match local LLM assistant turn behavior; +- full-snapshot artifact servers should not duplicate text excessively; +- progress board should pause before the final assistant message. + +### Test commands + +```bash +uv run pytest tests/integration/a2a -q +uv run scripts/lint.py +uv run scripts/typecheck.py +``` + +### CLI check + +```bash +uv run fast-agent -x --agent-cards /tmp/a2a-stream-card.yaml --agent stream_remote --message "stream please" --quiet +``` + +Expected: final aggregated text is correct. + +### TUI check + +Use tmux to verify visible streaming/progress shape. Capture text to: + +```text +/home/ssmith/plan/records/a2a-streaming-tui.txt +``` + +Record asciinema: + +```text +/home/ssmith/plan/records/a2a-streaming.cast +``` + +### Commit + +Commit after tests, lint, typecheck, and TUI capture. + +## Step 6 — File/data happy path + +### Implementation + +Outbound: + +- map user text to `Part(text=...)` as today; +- map local file attachments to `Part(raw=..., media_type=..., filename=...)`; +- map URL/resource attachments to `Part(url=..., media_type=..., filename=...)`; +- preserve plain text fallback when unsupported. + +Inbound: + +- render `Part(text=...)` as assistant text; +- render `Part(url=...)` as markdown links with media type/filename when present; +- render `Part(data=...)` as fenced JSON; +- represent `Part(raw=...)` safely with filename/media type/byte count, and save + bytes only if there is an established artifact storage path. + +### Test commands + +```bash +uv run pytest tests/integration/a2a tests/e2e/multimodal -q +uv run scripts/lint.py +uv run scripts/typecheck.py +``` + +### CLI checks + +Use a local sample file and the fake server: + +```bash +uv run fast-agent -x --agent-cards /tmp/a2a-file-card.yaml --agent file_remote --message "summarize attached file" --quiet +``` + +If the current CLI has an attachment flag, include it; otherwise record the gap +and test through TUI/resource input. + +### TUI checks + +- Attach or reference a local file/resource. +- Send to A2A fake server. +- Verify server receives file metadata/content. +- Verify inbound URL/data response renders readably. + +Save captures: + +```text +/home/ssmith/plan/records/a2a-file-cli.txt +/home/ssmith/plan/records/a2a-file-tui.txt +/home/ssmith/plan/records/a2a-file.cast +``` + +### Commit + +Commit after file/data happy path is tested and recorded. + +## Step 7 — Documentation and final verification + +### Implementation + +- Update user docs/examples for `type: a2a` cards. +- Document `/a2a connect` URL and transport semantics. +- Document known limitations for binary inbound data and persistence. +- Add short demo recording links if the docs pipeline supports asciinema assets. + +### Final validation + +```bash +uv run pytest tests/integration/a2a -q +uv run pytest tests/unit/fast_agent/core/test_agent_card_loader.py -q +uv run pytest tests/unit/fast_agent/ui/test_enhanced_prompt_toolbar.py tests/unit/fast_agent/ui/test_input_toolbar.py -q +uv run scripts/lint.py +uv run scripts/typecheck.py +``` + +Manual smoke matrix: + +| Scenario | CLI | TUI | Recording | +|---|---:|---:|---:| +| JSON-RPC text | yes | yes | optional | +| HTTP+JSON text | yes | yes | optional | +| gRPC text | optional | optional | optional | +| `/a2a status/card/reset` | command tests | yes | optional | +| `/a2a connect` | n/a or command test | yes | yes | +| Streaming artifact/direct text | yes final text | yes live display | yes | +| File/data happy path | yes if attachment path exists | yes | yes | + +### Final commit + +Commit docs and final verification notes. diff --git a/tests/integration/a2a/conftest.py b/tests/integration/a2a/conftest.py new file mode 100644 index 000000000..7374057db --- /dev/null +++ b/tests/integration/a2a/conftest.py @@ -0,0 +1,146 @@ +from __future__ import annotations + +import asyncio +from dataclasses import dataclass +from typing import TYPE_CHECKING + +import pytest_asyncio +import uvicorn +from a2a.server.agent_execution.agent_executor import AgentExecutor +from a2a.server.request_handlers import DefaultRequestHandler +from a2a.server.routes import ( + create_agent_card_routes, + create_jsonrpc_routes, + create_rest_routes, +) +from a2a.server.tasks.inmemory_task_store import InMemoryTaskStore +from a2a.server.tasks.task_updater import TaskUpdater +from a2a.types import ( + AgentCapabilities, + AgentCard, + AgentInterface, + AgentProvider, + AgentSkill, + Part, + Task, + TaskState, + TaskStatus, +) +from fastapi import FastAPI + +if TYPE_CHECKING: + from collections.abc import AsyncIterator + + from a2a.server.agent_execution.context import RequestContext + from a2a.server.events.event_queue import EventQueue + +@dataclass(frozen=True) +class A2ATestServer: + base_url: str + card: AgentCard + + +class EchoAgentExecutor(AgentExecutor): + def __init__(self) -> None: + self.seen_queries: list[str] = [] + + async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None: + updater = TaskUpdater( + event_queue=event_queue, + task_id=context.task_id or "", + context_id=context.context_id or "", + ) + await updater.cancel() + + async def execute(self, context: RequestContext, event_queue: EventQueue) -> None: + if not context.message or not context.task_id or not context.context_id: + return + + await event_queue.enqueue_event( + Task( + id=context.task_id, + context_id=context.context_id, + status=TaskStatus(state=TaskState.TASK_STATE_SUBMITTED), + history=[context.message], + ) + ) + + updater = TaskUpdater( + event_queue=event_queue, + task_id=context.task_id, + context_id=context.context_id, + ) + await updater.start_work( + message=updater.new_agent_message(parts=[Part(text="working")]) + ) + + query = context.get_user_input() + self.seen_queries.append(query) + await asyncio.sleep(0.01) + await updater.add_artifact( + parts=[Part(text=f"echo: {query}")], + name="response", + last_chunk=True, + ) + await updater.complete() + + +@pytest_asyncio.fixture +async def a2a_test_server(unused_tcp_port: int, wait_for_port) -> AsyncIterator[A2ATestServer]: + host = "127.0.0.1" + port = unused_tcp_port + base_url = f"http://{host}:{port}" + card = AgentCard( + name="fast-agent test A2A server", + description="Deterministic A2A test server.", + provider=AgentProvider(organization="fast-agent", url="https://fast-agent.ai"), + version="1.0.0", + capabilities=AgentCapabilities(streaming=True, push_notifications=False), + default_input_modes=["text"], + default_output_modes=["text", "task-status"], + skills=[ + AgentSkill( + id="echo", + name="Echo", + description="Echo user input.", + tags=["test"], + examples=["hello"], + input_modes=["text"], + output_modes=["text", "task-status"], + ) + ], + supported_interfaces=[ + AgentInterface( + protocol_binding="JSONRPC", + protocol_version="1.0", + url=f"{base_url}/a2a/jsonrpc", + ), + AgentInterface( + protocol_binding="HTTP+JSON", + protocol_version="1.0", + url=f"{base_url}/a2a/rest", + ), + ], + ) + request_handler = DefaultRequestHandler( + agent_executor=EchoAgentExecutor(), + task_store=InMemoryTaskStore(), + agent_card=card, + ) + + app = FastAPI() + app.routes.extend(create_agent_card_routes(agent_card=card)) + app.routes.extend( + create_jsonrpc_routes(request_handler=request_handler, rpc_url="/a2a/jsonrpc") + ) + app.routes.extend(create_rest_routes(request_handler=request_handler, path_prefix="/a2a/rest")) + + server = uvicorn.Server(uvicorn.Config(app, host=host, port=port, log_level="warning")) + task = asyncio.create_task(server.serve()) + await wait_for_port(host, port, timeout=5.0) + + try: + yield A2ATestServer(base_url=base_url, card=card) + finally: + server.should_exit = True + await asyncio.wait_for(task, timeout=5.0) diff --git a/tests/integration/a2a/test_remote_agent_runtime.py b/tests/integration/a2a/test_remote_agent_runtime.py new file mode 100644 index 000000000..672c02d4d --- /dev/null +++ b/tests/integration/a2a/test_remote_agent_runtime.py @@ -0,0 +1,50 @@ +from __future__ import annotations + +import pytest +from mcp.types import TextContent + +from fast_agent.a2a.config import A2AAgentConfig +from fast_agent.a2a.remote_agent import A2ARemoteAgent +from fast_agent.agents.agent_types import AgentConfig, AgentType +from fast_agent.types import PromptMessageExtended + + +async def _send_text(base_url: str, transport: str) -> A2ARemoteAgent: + agent = A2ARemoteAgent( + config=AgentConfig( + name=f"remote_{transport.lower().replace('+', '_')}", + agent_type=AgentType.A2A, + use_history=False, + ), + a2a_config=A2AAgentConfig(url=base_url, transport=transport), + ) + await agent.initialize() + try: + response = await agent.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[TextContent(type="text", text=f"hello over {transport}")], + ) + ] + ) + assert f"echo: hello over {transport}" in response.all_text() + assert agent.remote_card is not None + assert agent.remote_card.name == "fast-agent test A2A server" + assert agent.context_id + assert agent.last_task_state == "TASK_STATE_COMPLETED" + assert agent.current_task_id is None + return agent + except Exception: + await agent.shutdown() + raise + + +@pytest.mark.integration +@pytest.mark.asyncio +@pytest.mark.parametrize("transport", ["JSONRPC", "HTTP+JSON"]) +async def test_a2a_remote_agent_sends_text_over_supported_transports( + a2a_test_server, transport: str +) -> None: + agent = await _send_text(a2a_test_server.base_url, transport) + await agent.shutdown() From e8867e12b1533f7dfa35e151234e1433c3377643 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Wed, 20 May 2026 18:26:53 +0100 Subject: [PATCH 02/58] support a2a streaming and file parts --- src/fast_agent/a2a/__init__.py | 2 + src/fast_agent/a2a/config.py | 15 + src/fast_agent/a2a/remote_agent.py | 387 ++++++++++++++++++ tests/integration/a2a/conftest.py | 52 ++- .../a2a/test_remote_agent_runtime.py | 91 ++++ 5 files changed, 544 insertions(+), 3 deletions(-) create mode 100644 src/fast_agent/a2a/__init__.py create mode 100644 src/fast_agent/a2a/config.py create mode 100644 src/fast_agent/a2a/remote_agent.py diff --git a/src/fast_agent/a2a/__init__.py b/src/fast_agent/a2a/__init__.py new file mode 100644 index 000000000..3cdb10b2d --- /dev/null +++ b/src/fast_agent/a2a/__init__.py @@ -0,0 +1,2 @@ +"""A2A client integration.""" + diff --git a/src/fast_agent/a2a/config.py b/src/fast_agent/a2a/config.py new file mode 100644 index 000000000..9cb1baec7 --- /dev/null +++ b/src/fast_agent/a2a/config.py @@ -0,0 +1,15 @@ +"""Configuration for remote A2A agents.""" + +from dataclasses import dataclass, field + + +@dataclass(frozen=True) +class A2AAgentConfig: + url: str + transport: str | None = None + streaming: bool = True + polling: bool = False + accepted_output_modes: list[str] = field(default_factory=list) + headers: dict[str, str] = field(default_factory=dict) + relative_card_path: str | None = None + diff --git a/src/fast_agent/a2a/remote_agent.py b/src/fast_agent/a2a/remote_agent.py new file mode 100644 index 000000000..3f8a27de6 --- /dev/null +++ b/src/fast_agent/a2a/remote_agent.py @@ -0,0 +1,387 @@ +"""Remote A2A agent implementation.""" + +from __future__ import annotations + +import base64 +import json +import uuid +from dataclasses import dataclass +from pathlib import PurePosixPath +from typing import TYPE_CHECKING, Any + +import httpx +from a2a.client import A2ACardResolver, ClientConfig, create_client +from a2a.types import Message, Part, Role, SendMessageRequest, TaskState +from google.protobuf.json_format import MessageToDict +from mcp.types import ( + AudioContent, + BlobResourceContents, + EmbeddedResource, + ImageContent, + ResourceLink, + TextContent, + TextResourceContents, +) + +from fast_agent.agents.agent_types import AgentConfig, AgentType +from fast_agent.agents.llm_decorator import LlmDecorator +from fast_agent.core.logging.logger import get_logger +from fast_agent.event_progress import ProgressAction +from fast_agent.llm.stream_types import StreamChunk +from fast_agent.types import PromptMessageExtended, RequestParams +from fast_agent.ui import console +from fast_agent.ui.console_display import ConsoleDisplay +from fast_agent.ui.message_display_helpers import build_user_message_display +from fast_agent.ui.progress_display import progress_display + +if TYPE_CHECKING: + from collections.abc import Callable, Sequence + + from a2a.types import AgentCard + from mcp import Tool + + from fast_agent.a2a.config import A2AAgentConfig + from fast_agent.context import Context + +_TERMINAL_STATES = { + "TASK_STATE_COMPLETED", + "TASK_STATE_FAILED", + "TASK_STATE_CANCELED", + "TASK_STATE_CANCELLED", + "TASK_STATE_REJECTED", + "TASK_STATE_INPUT_REQUIRED", + "TASK_STATE_AUTH_REQUIRED", +} + +_ERROR_STATES = { + "TASK_STATE_FAILED", + "TASK_STATE_CANCELED", + "TASK_STATE_CANCELLED", + "TASK_STATE_REJECTED", + "TASK_STATE_INPUT_REQUIRED", + "TASK_STATE_AUTH_REQUIRED", +} + +logger = get_logger(__name__) + + +@dataclass(frozen=True) +class A2ADiagnostics: + url: str + transport: str | None + remote_name: str | None + context_id: str + current_task_id: str | None + last_task_state: str | None + + +class A2ARemoteAgent(LlmDecorator): + """A fast-agent AgentProtocol adapter for a remote A2A agent.""" + + def __init__( + self, + config: AgentConfig, + a2a_config: A2AAgentConfig, + context: Context | None = None, + ) -> None: + super().__init__(config=config, context=context) + self.a2a_config = a2a_config + self.context_id = str(uuid.uuid4()) + self.current_task_id: str | None = None + self.last_task_state: str | None = None + self.remote_card: AgentCard | None = None + self.display = ConsoleDisplay(config=context.config if context else None) + self._client: Any | None = None + self._httpx_client: httpx.AsyncClient | None = None + self._stream_listeners: list[Callable[[StreamChunk], None]] = [] + + @property + def agent_type(self) -> AgentType: + return AgentType.A2A + + async def initialize(self) -> None: + await super().initialize() + self._httpx_client = httpx.AsyncClient(headers=self.a2a_config.headers or None) + client_config = ClientConfig( + streaming=self.a2a_config.streaming, + polling=self.a2a_config.polling, + httpx_client=self._httpx_client, + accepted_output_modes=list(self.a2a_config.accepted_output_modes), + ) + if self.a2a_config.transport: + client_config.supported_protocol_bindings = [self.a2a_config.transport] + + resolver = A2ACardResolver( + self._httpx_client, + self.a2a_config.url, + self.a2a_config.relative_card_path or "/.well-known/agent-card.json", + ) + self.remote_card = await resolver.get_agent_card() + self._client = await create_client( + self.remote_card, + client_config=client_config, + ) + + async def shutdown(self) -> None: + client = self._client + if client is not None: + await client.close() + self._client = None + if self._httpx_client is not None: + await self._httpx_client.aclose() + self._httpx_client = None + await super().shutdown() + + def add_stream_listener(self, listener: Callable[[StreamChunk], None]) -> Callable[[], None]: + self._stream_listeners.append(listener) + + def remove_listener() -> None: + try: + self._stream_listeners.remove(listener) + except ValueError: + return + + return remove_listener + + def reset_a2a_state(self) -> None: + self.context_id = str(uuid.uuid4()) + self.current_task_id = None + self.last_task_state = None + + def diagnostics(self) -> A2ADiagnostics: + return A2ADiagnostics( + url=self.a2a_config.url, + transport=self.a2a_config.transport, + remote_name=self.remote_card.name if self.remote_card else None, + context_id=self.context_id, + current_task_id=self.current_task_id, + last_task_state=self.last_task_state, + ) + + async def generate_impl( + self, + messages: list[PromptMessageExtended], + request_params: RequestParams | None = None, + tools: list[Tool] | None = None, + ) -> PromptMessageExtended: + del tools + if self._client is None: + raise RuntimeError("A2A remote agent is not initialized") + + use_history = request_params.use_history if request_params else self.config.use_history + self._timestamp_messages(messages) + self._display_user_messages(messages) + user_text = _latest_text(messages) + request = SendMessageRequest( + message=Message( + role=Role.ROLE_USER, + message_id=str(uuid.uuid4()), + context_id=self.context_id, + task_id=self.current_task_id, + parts=_parts_from_messages(messages) or [Part(text=user_text)], + ) + ) + + self._log_a2a_progress(ProgressAction.SENDING, details=self._transport_label()) + result = await self._consume_events(self._client.send_message(request)) + self._log_a2a_progress(ProgressAction.READY, details=result.state or "completed") + response_text = result.text or _state_message(result.state) + if result.state in _ERROR_STATES: + response_text = f"A2A task {result.state}: {response_text}" + assistant_message = PromptMessageExtended( + role="assistant", + content=[TextContent(type="text", text=response_text)], + ) + progress_display.pause(cancel_deferred_on_noop=True) + await self.display.show_assistant_message( + assistant_message, + name=self.name, + model="A2A", + bottom_items=[self._transport_label()], + ) + console.console.print() + if use_history: + self._persist_history(messages, assistant_message) + return assistant_message + + def _display_user_messages(self, messages: list[PromptMessageExtended]) -> None: + display_messages = [message for message in messages if message.role == "user"] + if not display_messages: + return + message_text, attachments = build_user_message_display(display_messages) + self.display.show_user_message( + message_text, + chat_turn=0, + name=self.name, + attachments=attachments if attachments else None, + part_count=len(display_messages) if len(display_messages) > 1 else None, + ) + + def _transport_label(self) -> str: + return f"A2A · {self.a2a_config.transport}" if self.a2a_config.transport else "A2A" + + def _log_a2a_progress(self, action: ProgressAction, *, details: str = "") -> None: + logger.debug( + "A2A request progress", + data={ + "progress_action": action, + "agent_name": self.name, + "target": self.remote_card.name if self.remote_card else self.name, + "details": details, + }, + ) + + async def _consume_events(self, events: Any) -> "_A2AResult": + chunks: list[str] = [] + seen_chunks: set[str] = set() + state: str | None = None + + async for event in events: + if event.HasField("message"): + text = _parts_text(event.message.parts) + _append_text(chunks, seen_chunks, text) + self._emit_stream(text) + continue + + if event.HasField("task"): + self.current_task_id = event.task.id + self.context_id = event.task.context_id + state = TaskState.Name(event.task.status.state) + self.last_task_state = state + for artifact in event.task.artifacts: + text = _parts_text(artifact.parts) + _append_text(chunks, seen_chunks, text) + continue + + if event.HasField("status_update"): + status = event.status_update.status + state = TaskState.Name(status.state) + self.last_task_state = state + if state in _TERMINAL_STATES and state != "TASK_STATE_INPUT_REQUIRED": + self.current_task_id = None + continue + + if event.HasField("artifact_update"): + artifact = event.artifact_update.artifact + text = _parts_text(artifact.parts) + if text and text not in seen_chunks: + _append_text(chunks, seen_chunks, text) + self._emit_stream(text) + + return _A2AResult(text="\n".join(chunk for chunk in chunks if chunk), state=state) + + def _emit_stream(self, text: str) -> None: + if not text: + return + chunk = StreamChunk(text=text) + for listener in list(self._stream_listeners): + listener(chunk) + + +@dataclass(frozen=True) +class _A2AResult: + text: str + state: str | None + + + +def _parts_from_messages(messages: Sequence[PromptMessageExtended]) -> list[Part]: + parts: list[Part] = [] + for message in messages: + if message.role != "user": + continue + for content in message.content: + if isinstance(content, TextContent): + if content.text: + parts.append(Part(text=content.text)) + continue + if isinstance(content, ImageContent | AudioContent): + parts.append( + Part( + raw=base64.b64decode(content.data), + media_type=content.mimeType, + ) + ) + continue + if isinstance(content, ResourceLink): + parts.append( + Part( + url=str(content.uri), + media_type=content.mimeType or "", + filename=content.name, + ) + ) + continue + if isinstance(content, EmbeddedResource): + resource = content.resource + if isinstance(resource, BlobResourceContents): + parts.append( + Part( + raw=base64.b64decode(resource.blob), + media_type=resource.mimeType or "", + filename=_filename_from_uri(str(resource.uri)), + ) + ) + continue + if isinstance(resource, TextResourceContents): + parts.append( + Part( + text=resource.text, + media_type=resource.mimeType or "text/plain", + filename=_filename_from_uri(str(resource.uri)), + ) + ) + return parts + + +def _filename_from_uri(uri: str) -> str: + path = PurePosixPath(uri.split("?", 1)[0]) + return path.name or "attachment" + + +def _parts_text(parts: Sequence[Part]) -> str: + rendered: list[str] = [] + for part in parts: + text = _part_text(part) + if text: + rendered.append(text) + return "\n".join(rendered) + + +def _part_text(part: Part) -> str: + if part.HasField("text"): + return part.text + if part.HasField("url"): + label = part.filename or part.url + suffix = f" ({part.media_type})" if part.media_type else "" + return f"[{label}]({part.url}){suffix}" + if part.HasField("data"): + data = MessageToDict(part).get("data", {}) + return f"```json\n{json.dumps(data, indent=2, sort_keys=True)}\n```" + if part.HasField("raw"): + label = part.filename or "attachment" + suffix = f" {part.media_type}" if part.media_type else "" + return f"[{label}: {len(part.raw)} bytes{suffix}]" + return "" + +def _latest_text(messages: Sequence[PromptMessageExtended]) -> str: + for message in reversed(messages): + text = message.all_text() + if text.strip(): + return text + return "" + + +def _append_text(chunks: list[str], seen_chunks: set[str], text: str) -> None: + if not text or text in seen_chunks: + return + chunks.append(text) + seen_chunks.add(text) + + +def _state_message(state: str | None) -> str: + if not state: + return "A2A task completed without text output." + if state == "TASK_STATE_COMPLETED": + return "A2A task completed without text output." + return "A2A task ended without text output." diff --git a/tests/integration/a2a/conftest.py b/tests/integration/a2a/conftest.py index 7374057db..2ebea1ce3 100644 --- a/tests/integration/a2a/conftest.py +++ b/tests/integration/a2a/conftest.py @@ -27,6 +27,7 @@ TaskStatus, ) from fastapi import FastAPI +from google.protobuf.json_format import ParseDict if TYPE_CHECKING: from collections.abc import AsyncIterator @@ -34,15 +35,23 @@ from a2a.server.agent_execution.context import RequestContext from a2a.server.events.event_queue import EventQueue +def _data_part(value: dict[str, object]) -> Part: + part = Part() + ParseDict(value, part.data) + return part + + @dataclass(frozen=True) class A2ATestServer: base_url: str card: AgentCard + executor: EchoAgentExecutor class EchoAgentExecutor(AgentExecutor): def __init__(self) -> None: self.seen_queries: list[str] = [] + self.seen_part_kinds: list[list[str]] = [] async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None: updater = TaskUpdater( @@ -76,9 +85,45 @@ async def execute(self, context: RequestContext, event_queue: EventQueue) -> Non query = context.get_user_input() self.seen_queries.append(query) + self.seen_part_kinds.append([part.WhichOneof("content") or "unknown" for part in context.message.parts]) + + if "stream" in query: + await updater.add_artifact( + parts=[Part(text="stream chunk one")], + name="stream", + last_chunk=False, + ) + await asyncio.sleep(0.01) + await updater.add_artifact( + parts=[Part(text="stream chunk two")], + name="stream", + last_chunk=True, + ) + await updater.complete() + return + + if "respond with files" in query: + await updater.add_artifact( + parts=[ + Part(text="file response"), + Part( + url="https://example.com/report.pdf", + media_type="application/pdf", + filename="report.pdf", + ), + _data_part({"ok": True, "count": 2}), + Part(raw=b"abc", media_type="text/plain", filename="note.txt"), + ], + name="files", + last_chunk=True, + ) + await updater.complete() + return + await asyncio.sleep(0.01) + summary = ",".join(self.seen_part_kinds[-1]) await updater.add_artifact( - parts=[Part(text=f"echo: {query}")], + parts=[Part(text=f"echo: {query} [{summary}]")], name="response", last_chunk=True, ) @@ -122,8 +167,9 @@ async def a2a_test_server(unused_tcp_port: int, wait_for_port) -> AsyncIterator[ ), ], ) + executor = EchoAgentExecutor() request_handler = DefaultRequestHandler( - agent_executor=EchoAgentExecutor(), + agent_executor=executor, task_store=InMemoryTaskStore(), agent_card=card, ) @@ -140,7 +186,7 @@ async def a2a_test_server(unused_tcp_port: int, wait_for_port) -> AsyncIterator[ await wait_for_port(host, port, timeout=5.0) try: - yield A2ATestServer(base_url=base_url, card=card) + yield A2ATestServer(base_url=base_url, card=card, executor=executor) finally: server.should_exit = True await asyncio.wait_for(task, timeout=5.0) diff --git a/tests/integration/a2a/test_remote_agent_runtime.py b/tests/integration/a2a/test_remote_agent_runtime.py index 672c02d4d..67d90496b 100644 --- a/tests/integration/a2a/test_remote_agent_runtime.py +++ b/tests/integration/a2a/test_remote_agent_runtime.py @@ -48,3 +48,94 @@ async def test_a2a_remote_agent_sends_text_over_supported_transports( ) -> None: agent = await _send_text(a2a_test_server.base_url, transport) await agent.shutdown() + + +@pytest.mark.integration +@pytest.mark.asyncio +async def test_a2a_remote_agent_emits_stream_chunks(a2a_test_server) -> None: + agent = A2ARemoteAgent( + config=AgentConfig(name="remote_stream", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig(url=a2a_test_server.base_url, transport="JSONRPC"), + ) + chunks: list[str] = [] + agent.add_stream_listener(lambda chunk: chunks.append(chunk.text)) + await agent.initialize() + try: + response = await agent.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[TextContent(type="text", text="please stream")], + ) + ] + ) + finally: + await agent.shutdown() + + assert "stream chunk one" in response.all_text() + assert "stream chunk two" in response.all_text() + assert chunks == ["stream chunk one", "stream chunk two"] + + +@pytest.mark.integration +@pytest.mark.asyncio +async def test_a2a_remote_agent_renders_file_url_data_and_raw_parts(a2a_test_server) -> None: + agent = A2ARemoteAgent( + config=AgentConfig(name="remote_files", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig(url=a2a_test_server.base_url, transport="JSONRPC"), + ) + await agent.initialize() + try: + response = await agent.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[TextContent(type="text", text="respond with files")], + ) + ] + ) + finally: + await agent.shutdown() + + text = response.all_text() + assert "file response" in text + assert "[report.pdf](https://example.com/report.pdf) (application/pdf)" in text + assert '"ok": true' in text + assert '"count": 2.0' in text + assert "[note.txt: 3 bytes text/plain]" in text + + +@pytest.mark.integration +@pytest.mark.asyncio +async def test_a2a_remote_agent_sends_url_and_raw_parts(a2a_test_server) -> None: + from mcp.types import ImageContent, ResourceLink + from pydantic import AnyUrl + + agent = A2ARemoteAgent( + config=AgentConfig(name="remote_attachments", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig(url=a2a_test_server.base_url, transport="JSONRPC"), + ) + await agent.initialize() + try: + response = await agent.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[ + TextContent(type="text", text="inspect attachment"), + ResourceLink( + type="resource_link", + name="report.pdf", + uri=AnyUrl("https://example.com/report.pdf"), + mimeType="application/pdf", + ), + ImageContent(type="image", data="YWJj", mimeType="image/png"), + ], + ) + ] + ) + finally: + await agent.shutdown() + + assert "echo: inspect attachment [text,url,raw]" in response.all_text() + assert a2a_test_server.executor.seen_part_kinds[-1] == ["text", "url", "raw"] From 13fb9804ad809f66740036aa7ea8404ddcb0e487 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Wed, 20 May 2026 18:29:01 +0100 Subject: [PATCH 03/58] add a2a diagnostic commands --- src/fast_agent/ui/command_payloads.py | 15 +++ .../ui/interactive/command_dispatch.py | 95 +++++++++++++++++++ src/fast_agent/ui/prompt/parser.py | 17 ++++ .../fast_agent/ui/test_parse_a2a_commands.py | 33 +++++++ 4 files changed, 160 insertions(+) create mode 100644 tests/unit/fast_agent/ui/test_parse_a2a_commands.py diff --git a/src/fast_agent/ui/command_payloads.py b/src/fast_agent/ui/command_payloads.py index 388684c44..a12c229f9 100644 --- a/src/fast_agent/ui/command_payloads.py +++ b/src/fast_agent/ui/command_payloads.py @@ -13,6 +13,11 @@ class ShowUsageCommand(CommandBase): kind: Literal["show_usage"] = "show_usage" +@dataclass(frozen=True, slots=True) +class ToggleTraceCommand(CommandBase): + kind: Literal["toggle_trace"] = "toggle_trace" + + @dataclass(frozen=True, slots=True) class ShowSystemCommand(CommandBase): kind: Literal["show_system"] = "show_system" @@ -31,6 +36,14 @@ class ShowMcpStatusCommand(CommandBase): McpConnectMode = Literal["url", "npx", "uvx", "stdio"] +@dataclass(frozen=True, slots=True) +class A2ACommand(CommandBase): + action: str + argument: str | None + error: str | None = None + kind: Literal["a2a_command"] = "a2a_command" + + @dataclass(frozen=True, slots=True) class McpListCommand(CommandBase): kind: Literal["mcp_list"] = "mcp_list" @@ -419,9 +432,11 @@ class UnknownCommand(CommandBase): CommandPayload = ( ShowUsageCommand + | ToggleTraceCommand | ShowSystemCommand | ShowMarkdownCommand | ShowMcpStatusCommand + | A2ACommand | McpListCommand | McpConnectCommand | McpDisconnectCommand diff --git a/src/fast_agent/ui/interactive/command_dispatch.py b/src/fast_agent/ui/interactive/command_dispatch.py index 78422b59d..0bc266a0e 100644 --- a/src/fast_agent/ui/interactive/command_dispatch.py +++ b/src/fast_agent/ui/interactive/command_dispatch.py @@ -7,6 +7,8 @@ from rich import print as rich_print +from fast_agent.a2a.remote_agent import A2ARemoteAgent +from fast_agent.agents.agent_types import AgentType from fast_agent.command_actions import ( PluginCommandActionContext, PluginCommandActionRegistry, @@ -31,8 +33,10 @@ from fast_agent.commands.shared_command_intents import should_default_export_agent from fast_agent.core.exceptions import AgentConfigError from fast_agent.core.logging.logger import get_logger +from fast_agent.llm.trace import toggle_llm_trace from fast_agent.ui import enhanced_prompt from fast_agent.ui.command_payloads import ( + A2ACommand, AgentCommand, AttachCommand, CardsCommand, @@ -85,6 +89,7 @@ SkillsCommand, SwitchAgentCommand, TitleSessionCommand, + ToggleTraceCommand, UnknownCommand, ) from fast_agent.ui.history_display import display_history_show @@ -171,6 +176,12 @@ async def _dispatch_local_ui_payload( match payload: case InterruptCommand(): raise KeyboardInterrupt() + case ToggleTraceCommand(): + enabled = toggle_llm_trace() + state = "enabled" if enabled else "disabled" + style = "red" if enabled else "yellow" + rich_print(f"[{style}]LLM trace {state}[/{style}]") + return result case SwitchAgentCommand(agent_name=new_agent): if new_agent in available_agents_set: result.next_agent = new_agent @@ -347,6 +358,80 @@ async def _dispatch_catalog_payload( return None +async def _dispatch_a2a_payload( + owner: "InteractivePrompt", + payload: CommandPayload, + *, + prompt_provider: "AgentApp", + agent: str, + available_agents_set: set[str], +) -> DispatchResult | None: + if not isinstance(payload, A2ACommand): + return None + + result = DispatchResult(handled=True) + if payload.error: + rich_print(f"[red]{payload.error}[/red]") + return result + + match payload.action: + case "list": + names = sorted( + name + for name in available_agents_set + if owner.agent_types.get(name) == AgentType.A2A + ) + if not names: + rich_print("[yellow]No A2A agents are currently registered.[/yellow]") + return result + rich_print("[bold]A2A agents[/bold]") + for name in names: + rich_print(f" • {name}") + return result + case "status" | "card" | "reset": + target = payload.argument or agent + remote_agent = owner._get_agent_or_warn(prompt_provider, target) + if remote_agent is None: + return result + if not isinstance(remote_agent, A2ARemoteAgent): + rich_print(f"[red]Agent '{target}' is not an A2A agent.[/red]") + return result + if payload.action == "reset": + remote_agent.reset_a2a_state() + rich_print(f"[green]Reset A2A state for {target}.[/green]") + return result + if payload.action == "status": + diagnostics = remote_agent.diagnostics() + rich_print(f"[bold]A2A status: {target}[/bold]") + rich_print(f" URL: {diagnostics.url}") + rich_print(f" Transport: {diagnostics.transport or 'auto'}") + rich_print(f" Remote: {diagnostics.remote_name or 'unresolved'}") + rich_print(f" Context: {diagnostics.context_id}") + rich_print(f" Task: {diagnostics.current_task_id or '-'}") + rich_print(f" Last state: {diagnostics.last_task_state or '-'}") + return result + card = remote_agent.remote_card + if card is None: + rich_print(f"[yellow]Agent '{target}' has not resolved a remote card yet.[/yellow]") + return result + rich_print(f"[bold]A2A card: {card.name}[/bold]") + rich_print(f" Description: {card.description}") + rich_print(f" Version: {card.version}") + rich_print(" Interfaces:") + for interface in card.supported_interfaces: + rich_print( + f" • {interface.protocol_binding} " + f"{interface.protocol_version}: {interface.url}" + ) + return result + case "connect": + rich_print("[yellow]/a2a connect is planned; use an AgentCard for now.[/yellow]") + return result + case _: + rich_print(f"[red]Unknown /a2a action: {payload.action}[/red]") + return result + + async def _dispatch_display_payload( payload: CommandPayload, *, @@ -984,6 +1069,16 @@ async def dispatch_command_payload( if catalog_result is not None: return catalog_result + a2a_result = await _dispatch_a2a_payload( + owner, + payload, + prompt_provider=prompt_provider, + agent=agent, + available_agents_set=available_agents_set, + ) + if a2a_result is not None: + return a2a_result + display_result = await _dispatch_display_payload( payload, prompt_provider=prompt_provider, diff --git a/src/fast_agent/ui/prompt/parser.py b/src/fast_agent/ui/prompt/parser.py index 8e3bc3bf5..fc51a0ad3 100644 --- a/src/fast_agent/ui/prompt/parser.py +++ b/src/fast_agent/ui/prompt/parser.py @@ -19,6 +19,7 @@ ) from fast_agent.mcp.connect_targets import parse_connect_command_text from fast_agent.ui.command_payloads import ( + A2ACommand, AgentCommand, AttachCommand, CardsCommand, @@ -67,6 +68,7 @@ SkillsCommand, SwitchAgentCommand, TitleSessionCommand, + ToggleTraceCommand, UnknownCommand, ) from fast_agent.utils.commandline import split_commandline @@ -606,6 +608,17 @@ def _parse_slash_alias_command( return None +def _parse_a2a_command(remainder: str) -> CommandPayload: + if not remainder: + return A2ACommand(action="status", argument=None) + tokens = remainder.split(maxsplit=1) + action = tokens[0].lower() + argument = tokens[1].strip() if len(tokens) > 1 else None + if action in {"list", "status", "card", "reset", "connect"}: + return A2ACommand(action=action, argument=argument) + return A2ACommand(action=action, argument=argument, error=f"Unknown /a2a action: {action}") + + def _parse_slash_command(cmd_line: str) -> str | CommandPayload: cmd_parts = cmd_line[1:].strip().split(maxsplit=1) cmd = cmd_parts[0].lower() @@ -627,6 +640,7 @@ def _parse_slash_command(cmd_line: str) -> str | CommandPayload: return simple_factory() command_parsers: dict[str, Callable[[str], CommandPayload]] = { + "a2a": _parse_a2a_command, "history": _parse_history_command, "session": _parse_session_command, "card": _parse_card_command, @@ -653,6 +667,9 @@ def parse_special_input(text: str) -> str | CommandPayload: stripped = text.lstrip() cmd_line = stripped.splitlines()[0] if stripped.startswith("/") else text + if text.strip() == "***TRACE": + return ToggleTraceCommand() + if cmd_line and cmd_line.startswith("/"): if cmd_line == "/": return "" diff --git a/tests/unit/fast_agent/ui/test_parse_a2a_commands.py b/tests/unit/fast_agent/ui/test_parse_a2a_commands.py new file mode 100644 index 000000000..5b6379e51 --- /dev/null +++ b/tests/unit/fast_agent/ui/test_parse_a2a_commands.py @@ -0,0 +1,33 @@ +from fast_agent.ui.command_payloads import A2ACommand +from fast_agent.ui.enhanced_prompt import parse_special_input + + +def test_parse_a2a_defaults_to_status() -> None: + result = parse_special_input("/a2a") + assert isinstance(result, A2ACommand) + assert result.action == "status" + assert result.argument is None + assert result.error is None + + +def test_parse_a2a_status_target() -> None: + result = parse_special_input("/a2a status remote") + assert isinstance(result, A2ACommand) + assert result.action == "status" + assert result.argument == "remote" + + +def test_parse_a2a_connect_preserves_arguments() -> None: + result = parse_special_input("/a2a connect http://127.0.0.1:41241 --transport JSONRPC") + assert isinstance(result, A2ACommand) + assert result.action == "connect" + assert result.argument == "http://127.0.0.1:41241 --transport JSONRPC" + assert result.error is None + + +def test_parse_a2a_unknown_action_reports_error() -> None: + result = parse_special_input("/a2a wat remote") + assert isinstance(result, A2ACommand) + assert result.action == "wat" + assert result.argument == "remote" + assert result.error == "Unknown /a2a action: wat" From 94e61939d0c0c975b814a8192a2ec80afd13f0e5 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Wed, 20 May 2026 18:31:15 +0100 Subject: [PATCH 04/58] add interactive a2a connect --- src/fast_agent/a2a/connect.py | 100 ++++++++++++++++++ .../ui/interactive/command_dispatch.py | 51 ++++++++- .../a2a/test_remote_agent_runtime.py | 47 ++++++++ tests/unit/fast_agent/a2a_connect_test.py | 46 ++++++++ 4 files changed, 241 insertions(+), 3 deletions(-) create mode 100644 src/fast_agent/a2a/connect.py create mode 100644 tests/unit/fast_agent/a2a_connect_test.py diff --git a/src/fast_agent/a2a/connect.py b/src/fast_agent/a2a/connect.py new file mode 100644 index 000000000..6194a7a28 --- /dev/null +++ b/src/fast_agent/a2a/connect.py @@ -0,0 +1,100 @@ +"""Helpers for interactive A2A connection requests.""" + +from __future__ import annotations + +import re +import shlex +from dataclasses import dataclass +from urllib.parse import urlsplit, urlunsplit + +_TRANSPORT_ALIASES = { + "jsonrpc": "JSONRPC", + "json-rpc": "JSONRPC", + "rpc": "JSONRPC", + "http": "HTTP+JSON", + "http+json": "HTTP+JSON", + "rest": "HTTP+JSON", + "grpc": "GRPC", +} + + +@dataclass(frozen=True, slots=True) +class A2AConnectRequest: + url: str + name: str | None = None + transport: str | None = None + relative_card_path: str | None = None + + +def parse_a2a_connect_arguments(arguments: str | None) -> tuple[A2AConnectRequest | None, str | None]: + if not arguments: + return None, "Usage: /a2a connect [--transport JSONRPC|HTTP+JSON|GRPC] [--name NAME] [--card-path PATH]" + try: + tokens = shlex.split(arguments) + except ValueError as exc: + return None, str(exc) + + url: str | None = None + name: str | None = None + transport: str | None = None + card_path: str | None = None + index = 0 + while index < len(tokens): + token = tokens[index] + if token in {"--transport", "-t", "--name", "--card-path"}: + if index + 1 >= len(tokens): + return None, f"{token} requires a value" + value = tokens[index + 1] + if token in {"--transport", "-t"}: + transport = normalize_a2a_transport(value) + if transport is None: + return None, f"Unsupported A2A transport: {value}" + elif token == "--name": + name = _normalize_agent_name(value) + if not name: + return None, f"Invalid agent name: {value}" + else: + card_path = value + index += 2 + continue + if token.startswith("-"): + return None, f"Unknown /a2a connect option: {token}" + if url is not None: + return None, f"Unexpected /a2a connect argument: {token}" + url = token + index += 1 + + if url is None: + return None, "A2A base URL or agent-card URL is required" + normalized_url, inferred_card_path, error = normalize_a2a_url(url) + if error: + return None, error + return ( + A2AConnectRequest( + url=normalized_url, + name=name, + transport=transport, + relative_card_path=card_path or inferred_card_path, + ), + None, + ) + + +def normalize_a2a_transport(value: str) -> str | None: + return _TRANSPORT_ALIASES.get(value.strip().lower()) + + +def normalize_a2a_url(url: str) -> tuple[str, str | None, str | None]: + parsed = urlsplit(url) + if parsed.scheme not in {"http", "https"} or not parsed.netloc: + return "", None, "A2A connect expects an http(s) base URL or agent-card URL" + path = parsed.path or "" + if path.endswith("agent-card.json"): + base = urlunsplit((parsed.scheme, parsed.netloc, "", "", "")) + relative_path = path if path.startswith("/") else f"/{path}" + return base, relative_path, None + return url.rstrip("/"), None, None + + +def _normalize_agent_name(value: str) -> str: + return re.sub(r"[^A-Za-z0-9_-]+", "_", value.strip()).strip("_") diff --git a/src/fast_agent/ui/interactive/command_dispatch.py b/src/fast_agent/ui/interactive/command_dispatch.py index 0bc266a0e..5c35b759e 100644 --- a/src/fast_agent/ui/interactive/command_dispatch.py +++ b/src/fast_agent/ui/interactive/command_dispatch.py @@ -3,12 +3,14 @@ from __future__ import annotations from dataclasses import dataclass -from typing import TYPE_CHECKING, Callable, cast +from typing import TYPE_CHECKING, Any, Callable, cast from rich import print as rich_print +from fast_agent.a2a.config import A2AAgentConfig +from fast_agent.a2a.connect import parse_a2a_connect_arguments from fast_agent.a2a.remote_agent import A2ARemoteAgent -from fast_agent.agents.agent_types import AgentType +from fast_agent.agents.agent_types import AgentConfig, AgentType from fast_agent.command_actions import ( PluginCommandActionContext, PluginCommandActionRegistry, @@ -358,6 +360,16 @@ async def _dispatch_catalog_payload( return None +def _default_a2a_agent_name(existing: set[str]) -> str: + base = "a2a_remote" + if base not in existing: + return base + index = 2 + while f"{base}_{index}" in existing: + index += 1 + return f"{base}_{index}" + + async def _dispatch_a2a_payload( owner: "InteractivePrompt", payload: CommandPayload, @@ -425,7 +437,40 @@ async def _dispatch_a2a_payload( ) return result case "connect": - rich_print("[yellow]/a2a connect is planned; use an AgentCard for now.[/yellow]") + request, error = parse_a2a_connect_arguments(payload.argument) + if error or request is None: + rich_print(f"[red]{error}[/red]") + return result + name = request.name or _default_a2a_agent_name(available_agents_set) + if name in available_agents_set: + rich_print(f"[red]Agent '{name}' already exists. Choose --name NAME.[/red]") + return result + remote_agent = A2ARemoteAgent( + config=AgentConfig(name=name, agent_type=AgentType.A2A, use_history=True), + a2a_config=A2AAgentConfig( + url=request.url, + transport=request.transport, + relative_card_path=request.relative_card_path, + ), + ) + try: + await remote_agent.initialize() + except Exception as exc: + await remote_agent.shutdown() + rich_print(f"[red]Unable to connect to A2A agent: {exc}[/red]") + return result + agents = cast("dict[str, Any]", prompt_provider.registered_agents()) + agents[name] = remote_agent + prompt_provider._apply_agent_registry() + owner.agent_types[name] = AgentType.A2A + result.next_agent = name + result.available_agents = prompt_provider.visible_agent_names(force_include=name) + result.available_agents_set = set(result.available_agents) + rich_print(f"[green]Connected A2A agent '{name}'.[/green]") + rich_print(f" URL: {request.url}") + rich_print(f" Transport: {request.transport or 'auto'}") + if remote_agent.remote_card is not None: + rich_print(f" Remote: {remote_agent.remote_card.name}") return result case _: rich_print(f"[red]Unknown /a2a action: {payload.action}[/red]") diff --git a/tests/integration/a2a/test_remote_agent_runtime.py b/tests/integration/a2a/test_remote_agent_runtime.py index 67d90496b..672699f55 100644 --- a/tests/integration/a2a/test_remote_agent_runtime.py +++ b/tests/integration/a2a/test_remote_agent_runtime.py @@ -139,3 +139,50 @@ async def test_a2a_remote_agent_sends_url_and_raw_parts(a2a_test_server) -> None assert "echo: inspect attachment [text,url,raw]" in response.all_text() assert a2a_test_server.executor.seen_part_kinds[-1] == ["text", "url", "raw"] + + +@pytest.mark.integration +@pytest.mark.asyncio +async def test_a2a_connect_command_adds_runtime_agent(a2a_test_server) -> None: + from fast_agent.core.agent_app import AgentApp + from fast_agent.ui.command_payloads import A2ACommand + from fast_agent.ui.interactive.command_dispatch import dispatch_command_payload + from fast_agent.ui.interactive_prompt import InteractivePrompt + + initial = A2ARemoteAgent( + config=AgentConfig(name="initial", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig(url=a2a_test_server.base_url, transport="JSONRPC"), + ) + await initial.initialize() + app = AgentApp({"initial": initial}) + owner = InteractivePrompt(agent_types={"initial": AgentType.A2A}) + try: + result = await dispatch_command_payload( + owner, + A2ACommand( + action="connect", + argument=f"{a2a_test_server.base_url} --transport http --name connected", + ), + prompt_provider=app, + agent="initial", + available_agents=["initial"], + available_agents_set={"initial"}, + merge_pinned_agents=lambda names: names, + ) + assert result.next_agent == "connected" + assert result.available_agents_set == {"initial", "connected"} + connected = app.get_agent("connected") + assert isinstance(connected, A2ARemoteAgent) + response = await connected.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[TextContent(type="text", text="hello connected")], + ) + ] + ) + assert "echo: hello connected" in response.all_text() + finally: + for remote in app.registered_agents().values(): + if isinstance(remote, A2ARemoteAgent): + await remote.shutdown() diff --git a/tests/unit/fast_agent/a2a_connect_test.py b/tests/unit/fast_agent/a2a_connect_test.py new file mode 100644 index 000000000..ab53b9761 --- /dev/null +++ b/tests/unit/fast_agent/a2a_connect_test.py @@ -0,0 +1,46 @@ +from fast_agent.a2a.connect import ( + normalize_a2a_transport, + normalize_a2a_url, + parse_a2a_connect_arguments, +) + + +def test_normalize_a2a_transport_aliases() -> None: + assert normalize_a2a_transport("json-rpc") == "JSONRPC" + assert normalize_a2a_transport("rest") == "HTTP+JSON" + assert normalize_a2a_transport("grpc") == "GRPC" + assert normalize_a2a_transport("bogus") is None + + +def test_normalize_a2a_base_url() -> None: + url, card_path, error = normalize_a2a_url("http://127.0.0.1:41241/") + assert url == "http://127.0.0.1:41241" + assert card_path is None + assert error is None + + +def test_normalize_a2a_agent_card_url() -> None: + url, card_path, error = normalize_a2a_url( + "http://127.0.0.1:41241/.well-known/agent-card.json" + ) + assert url == "http://127.0.0.1:41241" + assert card_path == "/.well-known/agent-card.json" + assert error is None + + +def test_parse_a2a_connect_arguments() -> None: + request, error = parse_a2a_connect_arguments( + 'http://127.0.0.1:41241 --transport rest --name "remote docs" --card-path /card.json' + ) + assert error is None + assert request is not None + assert request.url == "http://127.0.0.1:41241" + assert request.transport == "HTTP+JSON" + assert request.name == "remote_docs" + assert request.relative_card_path == "/card.json" + + +def test_parse_a2a_connect_rejects_endpointless_url() -> None: + request, error = parse_a2a_connect_arguments("127.0.0.1:41241") + assert request is None + assert error == "A2A connect expects an http(s) base URL or agent-card URL" From 59c603dca8694287a34721e1639642a46d7f4e3b Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Wed, 20 May 2026 20:24:15 +0100 Subject: [PATCH 05/58] add a2a cli shortcut and fake server --- src/fast_agent/cli/commands/go.py | 66 ++++++- tests/integration/a2a/fake_server.py | 170 ++++++++++++++++++ .../fast_agent/cli/test_a2a_go_options.py | 28 +++ 3 files changed, 263 insertions(+), 1 deletion(-) create mode 100644 tests/integration/a2a/fake_server.py create mode 100644 tests/unit/fast_agent/cli/test_a2a_go_options.py diff --git a/src/fast_agent/cli/commands/go.py b/src/fast_agent/cli/commands/go.py index 6941d5db7..1c3fe8a19 100644 --- a/src/fast_agent/cli/commands/go.py +++ b/src/fast_agent/cli/commands/go.py @@ -4,11 +4,13 @@ import os import sys +import tempfile from pathlib import Path # noqa: TC003 - typer resolves Path annotations at runtime from typing import Any, Literal import typer +from fast_agent.a2a.connect import normalize_a2a_transport, normalize_a2a_url from fast_agent.cards import service as card_service from fast_agent.cli.command_support import ensure_context_object, get_settings_or_exit from fast_agent.cli.env_helpers import resolve_environment_dir_option @@ -96,6 +98,43 @@ def _merge_card_sources( return merge_card_sources(sources, default_dir) +def _materialize_a2a_agent_cards( + urls: list[str], + *, + transport: str | None, +) -> tuple[tempfile.TemporaryDirectory[str], list[str]]: + normalized_transport = None + if transport: + normalized_transport = normalize_a2a_transport(transport) + if normalized_transport is None: + raise typer.BadParameter( + f"Unsupported A2A transport: {transport}", + param_hint="--a2a-transport", + ) + + tempdir = tempfile.TemporaryDirectory(prefix="fast-agent-a2a-") + paths: list[str] = [] + for index, raw_url in enumerate(urls, start=1): + url, card_path, error = normalize_a2a_url(raw_url) + if error: + tempdir.cleanup() + raise typer.BadParameter(error, param_hint="--a2a") + name = "a2a_remote" if index == 1 else f"a2a_remote_{index}" + lines = [ + "type: a2a", + f"name: {name}", + f"url: {url}", + ] + if normalized_transport: + lines.append(f"transport: {normalized_transport}") + if card_path: + lines.append(f"relative_card_path: {card_path}") + path = Path(tempdir.name) / f"{name}.yaml" + path.write_text("\n".join(lines) + "\n", encoding="utf-8") + paths.append(str(path)) + return tempdir, paths + + def _merge_pack_card_sources( sources: list[str] | None, pack_dir: Path, @@ -330,6 +369,17 @@ def go( config_path: str | None = CommonAgentOptions.config_path(), servers: str | None = CommonAgentOptions.servers(), agent_cards: list[str] | None = CommonAgentOptions.agent_cards(), + a2a: list[str] | None = typer.Option( + None, + "--a2a", + metavar="", + help="Connect to a remote A2A agent by base URL or agent-card URL (repeatable).", + ), + a2a_transport: str | None = typer.Option( + None, + "--a2a-transport", + help="Preferred A2A transport for --a2a: JSONRPC, HTTP+JSON, or GRPC.", + ), card_tools: list[str] | None = CommonAgentOptions.card_tools(), urls: str | None = CommonAgentOptions.urls(), auth: str | None = CommonAgentOptions.auth(), @@ -455,6 +505,16 @@ def go( agent_cards = _merge_pack_card_sources(agent_cards, env_paths.agent_cards) card_tools = _merge_pack_card_sources(card_tools, env_paths.tool_cards) + a2a_tempdir: tempfile.TemporaryDirectory[str] | None = None + if a2a: + a2a_tempdir, a2a_cards = _materialize_a2a_agent_cards( + a2a, + transport=a2a_transport, + ) + agent_cards = [*(agent_cards or []), *a2a_cards] + if agent is None and len(a2a_cards) == 1: + agent = Path(a2a_cards[0]).stem + request = build_command_run_request( name=name, instruction_option=instruction, @@ -500,4 +560,8 @@ def go( queue_startup_notice(update_notice) - run_request(request) + try: + run_request(request) + finally: + if a2a_tempdir is not None: + a2a_tempdir.cleanup() diff --git a/tests/integration/a2a/fake_server.py b/tests/integration/a2a/fake_server.py new file mode 100644 index 000000000..ca642c341 --- /dev/null +++ b/tests/integration/a2a/fake_server.py @@ -0,0 +1,170 @@ +"""Deterministic A2A server for fast-agent CLI/TUI smoke tests. + +Run: + uv run python tests/integration/a2a/fake_server.py --port 41242 + +Useful prompts: + hello + please stream + respond with files +""" + +from __future__ import annotations + +import argparse +import asyncio +import logging +from typing import TYPE_CHECKING + +import uvicorn +from a2a.server.agent_execution.agent_executor import AgentExecutor +from a2a.server.request_handlers import DefaultRequestHandler +from a2a.server.routes import create_agent_card_routes, create_jsonrpc_routes, create_rest_routes +from a2a.server.tasks.inmemory_task_store import InMemoryTaskStore +from a2a.server.tasks.task_updater import TaskUpdater +from a2a.types import ( + AgentCapabilities, + AgentCard, + AgentInterface, + AgentProvider, + AgentSkill, + Part, + Task, + TaskState, + TaskStatus, +) +from fastapi import FastAPI +from google.protobuf.json_format import ParseDict + +if TYPE_CHECKING: + from a2a.server.agent_execution.context import RequestContext + from a2a.server.events.event_queue import EventQueue + +logger = logging.getLogger(__name__) + + +class FakeAgentExecutor(AgentExecutor): + async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None: + updater = TaskUpdater( + event_queue=event_queue, + task_id=context.task_id or "", + context_id=context.context_id or "", + ) + await updater.cancel() + + async def execute(self, context: RequestContext, event_queue: EventQueue) -> None: + if not context.message or not context.task_id or not context.context_id: + return + + await event_queue.enqueue_event( + Task( + id=context.task_id, + context_id=context.context_id, + status=TaskStatus(state=TaskState.TASK_STATE_SUBMITTED), + history=[context.message], + ) + ) + updater = TaskUpdater( + event_queue=event_queue, + task_id=context.task_id, + context_id=context.context_id, + ) + await updater.start_work(message=updater.new_agent_message(parts=[Part(text="working")])) + + query = context.get_user_input() + if "stream" in query.lower(): + await updater.add_artifact(parts=[Part(text="stream chunk one")], name="stream") + await asyncio.sleep(0.4) + await updater.add_artifact( + parts=[Part(text="stream chunk two")], name="stream", last_chunk=True + ) + await updater.complete() + return + + if "files" in query.lower(): + data_part = Part() + ParseDict({"ok": True, "source": "fake-a2a-server"}, data_part.data) + await updater.add_artifact( + parts=[ + Part(text="file response"), + Part( + url="https://example.com/report.pdf", + media_type="application/pdf", + filename="report.pdf", + ), + data_part, + Part(raw=b"abc", media_type="text/plain", filename="note.txt"), + ], + name="files", + last_chunk=True, + ) + await updater.complete() + return + + kinds = ",".join(part.WhichOneof("content") or "unknown" for part in context.message.parts) + await updater.add_artifact( + parts=[Part(text=f"fake echo: {query} [{kinds}]")], + name="response", + last_chunk=True, + ) + await updater.complete() + + +def build_app(host: str, port: int) -> FastAPI: + base_url = f"http://{host}:{port}" + card = AgentCard( + name="fast-agent fake A2A server", + description="Deterministic server for fast-agent A2A demos and tests.", + provider=AgentProvider(organization="fast-agent", url="https://fast-agent.ai"), + version="1.0.0", + capabilities=AgentCapabilities(streaming=True, push_notifications=False), + default_input_modes=["text", "image", "file"], + default_output_modes=["text", "task-status", "application/json"], + skills=[ + AgentSkill( + id="fake_echo_stream_files", + name="Fake echo/stream/files", + description="Echoes text, streams chunks, and returns URL/data/raw parts.", + tags=["test", "streaming", "files"], + examples=["hello", "please stream", "respond with files"], + input_modes=["text", "image", "file"], + output_modes=["text", "task-status", "application/json"], + ) + ], + supported_interfaces=[ + AgentInterface( + protocol_binding="JSONRPC", + protocol_version="1.0", + url=f"{base_url}/a2a/jsonrpc", + ), + AgentInterface( + protocol_binding="HTTP+JSON", + protocol_version="1.0", + url=f"{base_url}/a2a/rest", + ), + ], + ) + request_handler = DefaultRequestHandler( + agent_executor=FakeAgentExecutor(), + task_store=InMemoryTaskStore(), + agent_card=card, + ) + app = FastAPI() + app.routes.extend(create_agent_card_routes(agent_card=card)) + app.routes.extend(create_jsonrpc_routes(request_handler=request_handler, rpc_url="/a2a/jsonrpc")) + app.routes.extend(create_rest_routes(request_handler=request_handler, path_prefix="/a2a/rest")) + return app + + +def main() -> None: + parser = argparse.ArgumentParser(description="fast-agent fake A2A server") + parser.add_argument("--host", default="127.0.0.1") + parser.add_argument("--port", type=int, default=41242) + args = parser.parse_args() + logging.basicConfig(level=logging.INFO) + logger.info("Agent card: http://%s:%s/.well-known/agent-card.json", args.host, args.port) + uvicorn.run(build_app(args.host, args.port), host=args.host, port=args.port, log_level="info") + + +if __name__ == "__main__": + main() diff --git a/tests/unit/fast_agent/cli/test_a2a_go_options.py b/tests/unit/fast_agent/cli/test_a2a_go_options.py new file mode 100644 index 000000000..44831ea6e --- /dev/null +++ b/tests/unit/fast_agent/cli/test_a2a_go_options.py @@ -0,0 +1,28 @@ +from pathlib import Path + +import pytest +import typer + +from fast_agent.cli.commands.go import _materialize_a2a_agent_cards + + +def test_materialize_a2a_agent_card() -> None: + tempdir, paths = _materialize_a2a_agent_cards( + ["http://127.0.0.1:41241/.well-known/agent-card.json"], + transport="rest", + ) + try: + assert len(paths) == 1 + text = Path(paths[0]).read_text(encoding="utf-8") + assert "type: a2a" in text + assert "name: a2a_remote" in text + assert "url: http://127.0.0.1:41241" in text + assert "transport: HTTP+JSON" in text + assert "relative_card_path: /.well-known/agent-card.json" in text + finally: + tempdir.cleanup() + + +def test_materialize_a2a_rejects_bad_transport() -> None: + with pytest.raises(typer.BadParameter): + _materialize_a2a_agent_cards(["http://127.0.0.1:41241"], transport="bogus") From fffa4a90a488dbb645fe9017e0ac0fa0ab6ae618 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Wed, 20 May 2026 20:27:34 +0100 Subject: [PATCH 06/58] document and expose a2a transport diagnostics --- docs/docs/ref/agent_cards.md | 38 +++++++++++++++++++ docs/docs/ref/go_command.md | 30 +++++++++++++++ src/fast_agent/a2a/remote_agent.py | 10 +++++ .../ui/interactive/command_dispatch.py | 17 ++++++++- src/fast_agent/ui/prompt/parser.py | 2 +- .../fast_agent/ui/test_parse_a2a_commands.py | 7 ++++ 6 files changed, 102 insertions(+), 2 deletions(-) diff --git a/docs/docs/ref/agent_cards.md b/docs/docs/ref/agent_cards.md index 81dd6a385..3ea3396de 100644 --- a/docs/docs/ref/agent_cards.md +++ b/docs/docs/ref/agent_cards.md @@ -129,6 +129,44 @@ When both target-derived values and explicit fields are present, explicit fields If an inferred/provided name collides with another server using different settings, startup fails with a collision error. Prefer explicit `name` values for stability. +## Remote A2A AgentCards + +A remote A2A agent can be loaded as a first-class fast-agent agent with +`type: a2a`: + +```yaml +type: a2a +name: hello_remote +url: http://127.0.0.1:41241 +transport: JSONRPC +``` + +`url` is the A2A agent base URL used to resolve the remote card at +`/.well-known/agent-card.json`. If the card is served elsewhere, set +`relative_card_path`: + +```yaml +type: a2a +name: remote_custom_card +url: https://agent.example.com +relative_card_path: /custom/agent-card.json +transport: HTTP+JSON +``` + +Supported transport names are `JSONRPC`, `HTTP+JSON`, and `GRPC`. If `transport` +is omitted, the A2A SDK chooses from the remote AgentCard's advertised +interfaces. The current client maps text, URL resources, structured data, and +raw binary parts into fast-agent messages; inbound raw bytes are represented +safely with filename/media type/byte count. + +For one-off CLI connections, use `--a2a` instead of writing a card: + +```bash +fast-agent go --a2a http://127.0.0.1:41241 --a2a-transport JSONRPC --message hello +``` + +In the TUI, use `/a2a connect http://127.0.0.1:41241 --transport HTTP+JSON --name hello_rest`. + ## Examples ```bash diff --git a/docs/docs/ref/go_command.md b/docs/docs/ref/go_command.md index 4efa62659..4b6ec2fc8 100644 --- a/docs/docs/ref/go_command.md +++ b/docs/docs/ref/go_command.md @@ -34,6 +34,8 @@ fast-agent go [OPTIONS] - `--pack`, `--card-pack `: Ensure a named card pack is installed in the selected environment before starting - `--pack-registry `: Marketplace file path, HTTP(S) URL, `file://` URI, or `hf://` URI used to resolve `--pack` when it is not already installed - `--agent-cards`, `--card `: Load AgentCards as runnable agents from a path, HTTP(S) URL, `file://` URI, or `hf://` URI (repeatable) +- `--a2a `: Connect to a remote A2A agent by base URL or direct AgentCard URL (repeatable); creates temporary `a2a_remote` AgentCards for the run +- `--a2a-transport `: Preferred transport for `--a2a`; accepts `JSONRPC`, `HTTP+JSON`, or `GRPC` plus aliases such as `rest` and `json-rpc` - `--card-tool `: Load AgentCards from a path, HTTP(S) URL, `file://` URI, or `hf://` URI and attach them as tools to the selected/default agent (repeatable) - `--agent `: Target a specific loaded agent by name for `--message`, `--prompt-file`, and initial interactive mode - `--message`, `-m TEXT`: Message to send to the agent (skips interactive mode) @@ -86,6 +88,9 @@ fast-agent go --servers=fetch,filesystem --model=haiku # Directly connecting to HTTP/SSE servers via URLs fast-agent go --url=http://localhost:8001/mcp,http://api.example.com/sse +# Connect to a remote A2A agent without writing an AgentCard +fast-agent go --a2a http://127.0.0.1:41241 --a2a-transport JSONRPC --message hello + # Connecting to an authenticated API endpoint fast-agent go --url=https://api.example.com/mcp --auth=YOUR_API_TOKEN @@ -177,6 +182,31 @@ fast-agent go --models sonnet,gpt-5-mini.low --agent sonnet --message "Summarize for explicit targeting. - Explicit targeting can include tool-only agents when needed for testing. +### A2A quick connect + +Use `--a2a` when you want a temporary client-only connection to a remote A2A +agent without creating an AgentCard file. The value should usually be the remote +agent base URL: + +```bash +fast-agent go --a2a http://127.0.0.1:41241 --a2a-transport HTTP+JSON +``` + +Direct card URLs are also accepted and normalized: + +```bash +fast-agent go --a2a http://127.0.0.1:41241/.well-known/agent-card.json +``` + +The generated temporary agent names are `a2a_remote`, `a2a_remote_2`, and so on. +If a single `--a2a` URL is provided and `--agent` is omitted, fast-agent targets +that temporary A2A agent automatically. For persistent configuration, write an +AgentCard with `type: a2a` instead. + +Inside the TUI, `/a2a connect [--transport ...] [--name ...]` performs the +same kind of runtime connection. `/a2a status`, `/a2a card`, `/a2a list`, and +`/a2a reset` provide diagnostics for connected A2A agents. + ### AgentCards vs ToolCards `tool-cards` are not a separate file format. They are still AgentCards. diff --git a/src/fast_agent/a2a/remote_agent.py b/src/fast_agent/a2a/remote_agent.py index 3f8a27de6..8e252ec64 100644 --- a/src/fast_agent/a2a/remote_agent.py +++ b/src/fast_agent/a2a/remote_agent.py @@ -73,6 +73,7 @@ class A2ADiagnostics: context_id: str current_task_id: str | None last_task_state: str | None + selected_transport_class: str | None class A2ARemoteAgent(LlmDecorator): @@ -156,6 +157,7 @@ def diagnostics(self) -> A2ADiagnostics: context_id=self.context_id, current_task_id=self.current_task_id, last_task_state=self.last_task_state, + selected_transport_class=self._selected_transport_class(), ) async def generate_impl( @@ -220,6 +222,14 @@ def _display_user_messages(self, messages: list[PromptMessageExtended]) -> None: def _transport_label(self) -> str: return f"A2A · {self.a2a_config.transport}" if self.a2a_config.transport else "A2A" + def _selected_transport_class(self) -> str | None: + if self._client is None: + return None + transport = getattr(self._client, "_transport", None) + if transport is None: + return self._client.__class__.__name__ + return transport.__class__.__name__ + def _log_a2a_progress(self, action: ProgressAction, *, details: str = "") -> None: logger.debug( "A2A request progress", diff --git a/src/fast_agent/ui/interactive/command_dispatch.py b/src/fast_agent/ui/interactive/command_dispatch.py index 5c35b759e..1a7aab4af 100644 --- a/src/fast_agent/ui/interactive/command_dispatch.py +++ b/src/fast_agent/ui/interactive/command_dispatch.py @@ -400,7 +400,7 @@ async def _dispatch_a2a_payload( for name in names: rich_print(f" • {name}") return result - case "status" | "card" | "reset": + case "status" | "card" | "reset" | "transport": target = payload.argument or agent remote_agent = owner._get_agent_or_warn(prompt_provider, target) if remote_agent is None: @@ -408,6 +408,20 @@ async def _dispatch_a2a_payload( if not isinstance(remote_agent, A2ARemoteAgent): rich_print(f"[red]Agent '{target}' is not an A2A agent.[/red]") return result + if payload.action == "transport": + diagnostics = remote_agent.diagnostics() + rich_print(f"[bold]A2A transport: {target}[/bold]") + rich_print(f" Requested: {diagnostics.transport or 'auto'}") + rich_print(f" Selected client: {diagnostics.selected_transport_class or 'uninitialized'}") + card = remote_agent.remote_card + if card is not None: + rich_print(" Advertised interfaces:") + for interface in card.supported_interfaces: + rich_print( + f" • {interface.protocol_binding} " + f"{interface.protocol_version}: {interface.url}" + ) + return result if payload.action == "reset": remote_agent.reset_a2a_state() rich_print(f"[green]Reset A2A state for {target}.[/green]") @@ -421,6 +435,7 @@ async def _dispatch_a2a_payload( rich_print(f" Context: {diagnostics.context_id}") rich_print(f" Task: {diagnostics.current_task_id or '-'}") rich_print(f" Last state: {diagnostics.last_task_state or '-'}") + rich_print(f" Client transport: {diagnostics.selected_transport_class or '-'}") return result card = remote_agent.remote_card if card is None: diff --git a/src/fast_agent/ui/prompt/parser.py b/src/fast_agent/ui/prompt/parser.py index fc51a0ad3..9322e8ad6 100644 --- a/src/fast_agent/ui/prompt/parser.py +++ b/src/fast_agent/ui/prompt/parser.py @@ -614,7 +614,7 @@ def _parse_a2a_command(remainder: str) -> CommandPayload: tokens = remainder.split(maxsplit=1) action = tokens[0].lower() argument = tokens[1].strip() if len(tokens) > 1 else None - if action in {"list", "status", "card", "reset", "connect"}: + if action in {"list", "status", "card", "reset", "connect", "transport"}: return A2ACommand(action=action, argument=argument) return A2ACommand(action=action, argument=argument, error=f"Unknown /a2a action: {action}") diff --git a/tests/unit/fast_agent/ui/test_parse_a2a_commands.py b/tests/unit/fast_agent/ui/test_parse_a2a_commands.py index 5b6379e51..1de0b4cd8 100644 --- a/tests/unit/fast_agent/ui/test_parse_a2a_commands.py +++ b/tests/unit/fast_agent/ui/test_parse_a2a_commands.py @@ -31,3 +31,10 @@ def test_parse_a2a_unknown_action_reports_error() -> None: assert result.action == "wat" assert result.argument == "remote" assert result.error == "Unknown /a2a action: wat" + + +def test_parse_a2a_transport_target() -> None: + result = parse_special_input("/a2a transport remote") + assert isinstance(result, A2ACommand) + assert result.action == "transport" + assert result.argument == "remote" From 98273942e16e3430639e3968aa1e2909d49c950d Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Wed, 20 May 2026 20:33:10 +0100 Subject: [PATCH 07/58] handle a2a connection failures gracefully --- src/fast_agent/cli/commands/go.py | 4 ++ src/fast_agent/core/direct_factory.py | 60 +++++++++++++++++++ .../core/test_a2a_error_formatting.py | 19 ++++++ 3 files changed, 83 insertions(+) create mode 100644 tests/unit/fast_agent/core/test_a2a_error_formatting.py diff --git a/src/fast_agent/cli/commands/go.py b/src/fast_agent/cli/commands/go.py index 1c3fe8a19..8e0a4df24 100644 --- a/src/fast_agent/cli/commands/go.py +++ b/src/fast_agent/cli/commands/go.py @@ -46,6 +46,7 @@ from fast_agent.cli.shared_options import CommonAgentOptions from fast_agent.cli.update_check import check_for_update_notice, should_run_update_check from fast_agent.constants import FAST_AGENT_SHELL_CHILD_ENV +from fast_agent.core.exceptions import AgentConfigError from fast_agent.paths import resolve_environment_paths CARD_EXTENSIONS = _CARD_EXTENSIONS @@ -562,6 +563,9 @@ def go( try: run_request(request) + except AgentConfigError as exc: + typer.echo(str(exc), err=True) + raise typer.Exit(1) from exc finally: if a2a_tempdir is not None: a2a_tempdir.cleanup() diff --git a/src/fast_agent/core/direct_factory.py b/src/fast_agent/core/direct_factory.py index 1aed0b135..d3d630947 100644 --- a/src/fast_agent/core/direct_factory.py +++ b/src/fast_agent/core/direct_factory.py @@ -20,6 +20,8 @@ from fastmcp.tools import FunctionTool +from fast_agent.a2a.config import A2AAgentConfig +from fast_agent.a2a.remote_agent import A2ARemoteAgent from fast_agent.agents import McpAgent from fast_agent.agents.agent_types import AgentConfig, AgentType, FunctionToolConfig from fast_agent.agents.llm_agent import LlmAgent @@ -956,6 +958,63 @@ async def _create_maker_agent( result_agents[name] = maker_agent +def _format_a2a_initialization_error( + *, + name: str, + url: str, + transport: str | None, + exc: Exception, +) -> str: + reason = str(exc).strip() + cause = exc.__cause__ + while cause is not None: + cause_text = str(cause).strip() + if cause_text: + reason = cause_text + break + reason = cause.__class__.__name__ + cause = cause.__cause__ + if not reason: + reason = exc.__class__.__name__ + transport_text = f" via {transport}" if transport else "" + return ( + f"Unable to initialize A2A agent '{name}'{transport_text} at {url}: {reason}. " + "Check that the A2A server is running and that the URL points to the agent base " + "URL or agent card." + ) + + +async def _create_a2a_agent( + name: str, + agent_data: Mapping[str, Any], + build_ctx: AgentBuildContext, + result_agents: AgentDict, +) -> None: + config = cast("AgentConfig", agent_data["config"]) + a2a_config = agent_data.get("a2a") + if not isinstance(a2a_config, A2AAgentConfig): + raise AgentConfigError(f"A2A agent '{name}' missing A2A configuration") + + agent = A2ARemoteAgent( + config=config, + a2a_config=a2a_config, + context=build_ctx.app_instance.context, + ) + try: + await agent.initialize() + except Exception as exc: + await agent.shutdown() + raise AgentConfigError( + _format_a2a_initialization_error( + name=name, + url=a2a_config.url, + transport=a2a_config.transport, + exc=exc, + ) + ) from exc + _register_loaded_agent(result_agents, name, agent) + + _AGENT_TYPE_BUILDERS: dict[AgentType, AgentTypeBuilder] = { AgentType.LLM: _create_basic_agent, AgentType.BASIC: _create_basic_agent, @@ -968,6 +1027,7 @@ async def _create_maker_agent( AgentType.CHAIN: _create_chain_workflow_agent, AgentType.EVALUATOR_OPTIMIZER: _create_evaluator_optimizer_agent, AgentType.MAKER: _create_maker_agent, + AgentType.A2A: _create_a2a_agent, } diff --git a/tests/unit/fast_agent/core/test_a2a_error_formatting.py b/tests/unit/fast_agent/core/test_a2a_error_formatting.py new file mode 100644 index 000000000..42f62cbc8 --- /dev/null +++ b/tests/unit/fast_agent/core/test_a2a_error_formatting.py @@ -0,0 +1,19 @@ +from fast_agent.core.direct_factory import _format_a2a_initialization_error + + +def test_format_a2a_initialization_error_uses_cause_chain() -> None: + cause = TimeoutError() + exc = RuntimeError("wrapper") + exc.__cause__ = cause + + message = _format_a2a_initialization_error( + name="a2a_remote", + url="http://127.0.0.1:41242", + transport="JSONRPC", + exc=exc, + ) + + assert "Unable to initialize A2A agent 'a2a_remote' via JSONRPC" in message + assert "http://127.0.0.1:41242" in message + assert "TimeoutError" in message + assert "Check that the A2A server is running" in message From 2767f493aa5680babba1861728adf104ff3ab5d3 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Wed, 20 May 2026 20:40:52 +0100 Subject: [PATCH 08/58] add a2a getting started docs pipeline --- docs/docs/a2a/getting-started.md | 155 ++++++++++++ docs/docs/a2a/snippets/agent-card.yaml | 4 + docs/docs/a2a/snippets/cli-files-command.sh | 5 + docs/docs/a2a/snippets/cli-files-output.txt | 9 + docs/docs/a2a/snippets/cli-stream-command.sh | 5 + docs/docs/a2a/snippets/cli-stream-output.txt | 2 + docs/docs/a2a/snippets/start-fake-server.sh | 1 + docs/docs/a2a/snippets/tui-session.txt | 4 + docs/docs/assets/a2a/a2a-streaming-files.cast | 2 + .../assets/social/a2a/getting-started.png | Bin 0 -> 28009 bytes docs/social_cards/contact-sheet.html | 22 +- docs/zensical.toml | 3 + scripts/a2a_docs_pipeline.py | 237 ++++++++++++++++++ scripts/docs.py | 12 + tests/unit/test_a2a_docs_pipeline.py | 37 +++ 15 files changed, 497 insertions(+), 1 deletion(-) create mode 100644 docs/docs/a2a/getting-started.md create mode 100644 docs/docs/a2a/snippets/agent-card.yaml create mode 100644 docs/docs/a2a/snippets/cli-files-command.sh create mode 100644 docs/docs/a2a/snippets/cli-files-output.txt create mode 100644 docs/docs/a2a/snippets/cli-stream-command.sh create mode 100644 docs/docs/a2a/snippets/cli-stream-output.txt create mode 100644 docs/docs/a2a/snippets/start-fake-server.sh create mode 100644 docs/docs/a2a/snippets/tui-session.txt create mode 100644 docs/docs/assets/a2a/a2a-streaming-files.cast create mode 100644 docs/docs/assets/social/a2a/getting-started.png create mode 100755 scripts/a2a_docs_pipeline.py create mode 100644 tests/unit/test_a2a_docs_pipeline.py diff --git a/docs/docs/a2a/getting-started.md b/docs/docs/a2a/getting-started.md new file mode 100644 index 000000000..d0a7439e9 --- /dev/null +++ b/docs/docs/a2a/getting-started.md @@ -0,0 +1,155 @@ +--- +title: A2A Getting Started +description: Connect fast-agent to a remote Agent2Agent (A2A) server, stream responses, and inspect file/data parts. +--- + +# A2A Getting Started + +fast-agent can connect to remote [Agent2Agent (A2A)](https://a2a-protocol.org/) +agents as first-class agents. The quickest path is the `--a2a` command-line +shortcut, which creates a temporary `type: a2a` AgentCard for the current run. + +This guide uses the deterministic fake A2A server included in the fast-agent test +suite. That keeps the examples copy/pasteable and gives us a repeatable docs + +test pipeline. + +!!! note "Client-only scope" + This page covers fast-agent acting as an A2A **client**. Serving a fast-agent + agent as an A2A server is planned separately. + +## 1. Start the fake A2A server + +From the fast-agent repository root, run: + +```bash +--8<-- "docs/docs/a2a/snippets/start-fake-server.sh" +``` + +The fake server exposes: + +| Endpoint | URL | +|---|---| +| AgentCard | `http://127.0.0.1:41242/.well-known/agent-card.json` | +| JSON-RPC | `http://127.0.0.1:41242/a2a/jsonrpc` | +| HTTP+JSON | `http://127.0.0.1:41242/a2a/rest` | + +Keep this server running in one terminal, then use a second terminal for the +client commands below. + +## 2. Connect from the CLI and stream a response + +```bash +--8<-- "docs/docs/a2a/snippets/cli-stream-command.sh" +``` + +Expected output: + +```text +--8<-- "docs/docs/a2a/snippets/cli-stream-output.txt" +``` + +The `--a2a` value is normally the remote A2A agent's base URL. fast-agent resolves +its AgentCard from `/.well-known/agent-card.json`, selects the requested +transport, sends the message, and prints the final aggregated response. + +Transport names accepted by fast-agent are: + +| Canonical | Useful aliases | +|---|---| +| `JSONRPC` | `jsonrpc`, `json-rpc`, `rpc` | +| `HTTP+JSON` | `http`, `http+json`, `rest` | +| `GRPC` | `grpc` | + +## 3. Receive file, URL, and data parts + +The fake server can also return non-text A2A parts: + +```bash +--8<-- "docs/docs/a2a/snippets/cli-files-command.sh" +``` + +Expected output: + +````text +--8<-- "docs/docs/a2a/snippets/cli-files-output.txt" +```` + +Current rendering behavior: + +- text parts render as normal assistant text; +- URL parts render as Markdown links; +- data parts render as fenced JSON; +- raw bytes render as a safe filename/media-type/byte-count placeholder. + +## 4. Use an AgentCard instead of `--a2a` + +For persistent configuration, create a card like this: + +```yaml +--8<-- "docs/docs/a2a/snippets/agent-card.yaml" +``` + +Then run: + +```bash +uv run fast-agent -x --agent-cards ./fake-a2a.yaml --agent fake_remote +``` + +Use AgentCards when you want the connection checked in, shared, or combined with +other configured agents. + +## 5. Connect inside the TUI + +You can connect to A2A agents after the TUI has started: + +```text +/a2a connect http://127.0.0.1:41242 --transport JSONRPC --name fake_remote +``` + +Useful diagnostics: + +```text +--8<-- "docs/docs/a2a/snippets/tui-session.txt" +``` + +The `/a2a` command group currently includes: + +```text +/a2a list +/a2a status [agent] +/a2a card [agent] +/a2a transport [agent] +/a2a reset [agent] +/a2a connect [--transport JSONRPC|HTTP+JSON|GRPC] [--name NAME] +``` + +## Demo recording + +The repeatable docs pipeline can generate an asciinema recording for the TUI +streaming/files flow. The current committed recording is available as a static +asset: + +[Download the A2A streaming/files cast](../assets/a2a/a2a-streaming-files.cast) + +Replay locally with: + +```bash +asciinema play docs/docs/assets/a2a/a2a-streaming-files.cast +``` + +## Regenerate these examples + +The page snippets and cast are generated from the same fake server used by the +integration tests: + +```bash +uv run scripts/a2a_docs_pipeline.py generate +uv run scripts/a2a_docs_pipeline.py check +``` + +To refresh the terminal recording as well, install `asciinema` and `tmux`, then +run: + +```bash +uv run scripts/a2a_docs_pipeline.py record +``` diff --git a/docs/docs/a2a/snippets/agent-card.yaml b/docs/docs/a2a/snippets/agent-card.yaml new file mode 100644 index 000000000..73d310eea --- /dev/null +++ b/docs/docs/a2a/snippets/agent-card.yaml @@ -0,0 +1,4 @@ +type: a2a +name: fake_remote +url: http://127.0.0.1:41242 +transport: JSONRPC diff --git a/docs/docs/a2a/snippets/cli-files-command.sh b/docs/docs/a2a/snippets/cli-files-command.sh new file mode 100644 index 000000000..52426618a --- /dev/null +++ b/docs/docs/a2a/snippets/cli-files-command.sh @@ -0,0 +1,5 @@ +uv run fast-agent -x \ + --a2a http://127.0.0.1:41242 \ + --a2a-transport HTTP+JSON \ + --message "respond with files" \ + --quiet diff --git a/docs/docs/a2a/snippets/cli-files-output.txt b/docs/docs/a2a/snippets/cli-files-output.txt new file mode 100644 index 000000000..e5aae84dc --- /dev/null +++ b/docs/docs/a2a/snippets/cli-files-output.txt @@ -0,0 +1,9 @@ +file response +[report.pdf](https://example.com/report.pdf) (application/pdf) +```json +{ + "ok": true, + "source": "fake-a2a-server" +} +``` +[note.txt: 3 bytes text/plain] diff --git a/docs/docs/a2a/snippets/cli-stream-command.sh b/docs/docs/a2a/snippets/cli-stream-command.sh new file mode 100644 index 000000000..4b39697b5 --- /dev/null +++ b/docs/docs/a2a/snippets/cli-stream-command.sh @@ -0,0 +1,5 @@ +uv run fast-agent -x \ + --a2a http://127.0.0.1:41242 \ + --a2a-transport JSONRPC \ + --message "please stream" \ + --quiet diff --git a/docs/docs/a2a/snippets/cli-stream-output.txt b/docs/docs/a2a/snippets/cli-stream-output.txt new file mode 100644 index 000000000..13c2f849a --- /dev/null +++ b/docs/docs/a2a/snippets/cli-stream-output.txt @@ -0,0 +1,2 @@ +stream chunk one +stream chunk two diff --git a/docs/docs/a2a/snippets/start-fake-server.sh b/docs/docs/a2a/snippets/start-fake-server.sh new file mode 100644 index 000000000..9efefc2b4 --- /dev/null +++ b/docs/docs/a2a/snippets/start-fake-server.sh @@ -0,0 +1 @@ +uv run python tests/integration/a2a/fake_server.py --port 41242 diff --git a/docs/docs/a2a/snippets/tui-session.txt b/docs/docs/a2a/snippets/tui-session.txt new file mode 100644 index 000000000..e35fce405 --- /dev/null +++ b/docs/docs/a2a/snippets/tui-session.txt @@ -0,0 +1,4 @@ +/a2a status +/a2a transport +please stream +respond with files diff --git a/docs/docs/assets/a2a/a2a-streaming-files.cast b/docs/docs/assets/a2a/a2a-streaming-files.cast new file mode 100644 index 000000000..026e669b6 --- /dev/null +++ b/docs/docs/assets/a2a/a2a-streaming-files.cast @@ -0,0 +1,2 @@ +{"version": 2, "width": 104, "height": 34, "timestamp": 1779305110, "idle_time_limit": 1.3, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}, "title": "fast-agent A2A streaming and files demo"} +[10.025144, "o", "fast-agent is accessing the OS keyring for stored tokens. Some platforms may\r\npause and show a prompt. (loading Codex OAuth tokens)\r\nUse '/' for commands, '!' for shell. '#' to query, '@' to switch agents\r\nCTRL+T multiline, CTRL+Y copy last message, CTRL+E external editor.\r\nCTRL+Space or Tab for path completion. Use /attach, `^file:`, or `^url:` for\r\nattachments. F10 to clear.\r\nfast-agent environment ~/source/fast-agent-pr/.cdx (2 agents, 2 hooks, 8\r\nextensions, 2 modelrefs) via cli\r\n\r\n▎▶ a2a_remote ──────────────────────────────────────────────────────────────────\r\nplease stream\r\n\r\n▎◀ a2a_remote A2A\r\nstream chunk one\r\nstream chunk two\r\n\r\n▎▶ a2a_remote ──────────────────────────────────────────────────────────────────\r\nrespond with files\r\n\r\n▎◀ a2a_remote A2A\r\nfile response report.pdf (application/pdf)\r\n\r\n{\r\n \"ok\": true,\r\n \"source\": \"fake-a2a-server\"\r\n}\r\n\r\n[note.txt: 3 bytes text/plain]\r\n\r\n❯\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n a2a_remote[A2A] ▲ fast-agent fake A2A serv… | 002 | NRML | fast-agent 0.\r\n"] diff --git a/docs/docs/assets/social/a2a/getting-started.png b/docs/docs/assets/social/a2a/getting-started.png new file mode 100644 index 0000000000000000000000000000000000000000..ebf17f8f2230230f6e170fd07bde80be41b82b60 GIT binary patch literal 28009 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

616% zIjZ;qJ&Xf_Ikjo7P_7lr?we_I4utq{ei%Q0sXN4|TuuQ`DRt+sWxg7?>1MRebFkRJ z!Ypxy)$d{e$@KP7v)6uUWdbCr@v62Fo0i3K64@u=e7sSBo+x z?PsPEmw7X`-5g|TTWxk);2h_ieXU))(%;3aw+zW9oy^U3Q54bdb1VUt0d*E1gj|}$ zc!%PCL*-eXThc=Qzl+{03FWFqqBrFw;Wv4t`BB@Yt=TO5?{GyrB2yL2~85 zf4OcMXp!78?5;Ct4WQY0L!od75;mP%;0%PA^Z`U^#QnB(o*Q>M^Zf#*EzDVQhZL9A zQ1qEa>wDnI(fast-agent social cards

Generated review sheet for committed Open Graph/Twitter images.

-
49 cards · 1200×630px target · 1000 KB max
+
50 cards · 1200×630px target · 1000 KB max
+
+

A2A

+
+
+ A2A Getting Started +
+

A2A Getting Started

+
+
Source
a2a/getting-started.md
+
Output
docs/assets/social/a2a/getting-started.png
+
Badge
DOCS
+
Theme
doc / protocol-grid
+
Status
ok
+
Size
1200×630 · 27 KB
+
+
+
+
+
+

Acp

diff --git a/docs/zensical.toml b/docs/zensical.toml index bfec1751d..cfd033ba1 100644 --- a/docs/zensical.toml +++ b/docs/zensical.toml @@ -37,6 +37,9 @@ nav = [ { "Using as an Agent" = "acp/index.md" }, { "Customizing Agents" = "acp/customizing_agents.md" }, ] }, + { "A2A" = [ + { "Getting Started" = "a2a/getting-started.md" }, + ] }, { "MCP" = [ { "Configuring Servers" = "mcp/index.md" }, { "Deploying as an MCP Server" = "mcp/mcp-server.md" }, diff --git a/scripts/a2a_docs_pipeline.py b/scripts/a2a_docs_pipeline.py new file mode 100755 index 000000000..576025eda --- /dev/null +++ b/scripts/a2a_docs_pipeline.py @@ -0,0 +1,237 @@ +#!/usr/bin/env python3 +"""Generate and verify A2A getting-started docs assets. + +This script keeps docs examples, smoke-test commands, and captured output aligned. +It starts the deterministic fake A2A server, runs the documented CLI examples, +and writes the snippets consumed by docs/docs/a2a/getting-started.md. + +Usage: + uv run scripts/a2a_docs_pipeline.py generate + uv run scripts/a2a_docs_pipeline.py check + uv run scripts/a2a_docs_pipeline.py record +""" + +from __future__ import annotations + +import argparse +import shutil +import subprocess +import sys +import time +import urllib.request +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent +DOCS_A2A = ROOT / "docs" / "docs" / "a2a" +SNIPPETS = DOCS_A2A / "snippets" +ASSETS = ROOT / "docs" / "docs" / "assets" / "a2a" +RECORDS = Path.home() / "plan" / "records" +PORT = 41242 +BASE_URL = f"http://127.0.0.1:{PORT}" + +START_FAKE_SERVER = f"uv run python tests/integration/a2a/fake_server.py --port {PORT}\n" +STREAM_COMMAND = f"""uv run fast-agent -x \\ + --a2a {BASE_URL} \\ + --a2a-transport JSONRPC \\ + --message "please stream" \\ + --quiet +""" +FILES_COMMAND = f"""uv run fast-agent -x \\ + --a2a {BASE_URL} \\ + --a2a-transport HTTP+JSON \\ + --message "respond with files" \\ + --quiet +""" +AGENT_CARD = f"""type: a2a +name: fake_remote +url: {BASE_URL} +transport: JSONRPC +""" +TUI_SESSION = "/a2a status\n/a2a transport\nplease stream\nrespond with files\n" + +STATIC_SNIPPETS = { + "start-fake-server.sh": START_FAKE_SERVER, + "cli-stream-command.sh": STREAM_COMMAND, + "cli-files-command.sh": FILES_COMMAND, + "agent-card.yaml": AGENT_CARD, + "tui-session.txt": TUI_SESSION, +} + + +def _write(path: Path, text: str) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(text, encoding="utf-8") + + +def _run(command: str) -> str: + result = subprocess.run( + command, + cwd=ROOT, + shell=True, + text=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + check=False, + ) + if result.returncode != 0: + raise RuntimeError( + f"command failed ({result.returncode}): {command}\nSTDOUT:\n{result.stdout}\nSTDERR:\n{result.stderr}" + ) + return result.stdout.strip() + "\n" + + +def _wait_for_server(process: subprocess.Popen[str]) -> None: + deadline = time.monotonic() + 10 + url = f"{BASE_URL}/.well-known/agent-card.json" + while time.monotonic() < deadline: + if process.poll() is not None: + raise RuntimeError("fake A2A server exited before it was ready") + try: + with urllib.request.urlopen(url, timeout=0.5) as response: # noqa: S310 - local test server + if response.status == 200: + return + except OSError: + time.sleep(0.2) + raise TimeoutError(f"fake A2A server did not become ready at {url}") + + +def _start_server() -> subprocess.Popen[str]: + process = subprocess.Popen( + [ + "uv", + "run", + "python", + "tests/integration/a2a/fake_server.py", + "--port", + str(PORT), + ], + cwd=ROOT, + text=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + _wait_for_server(process) + return process + + +def _stop_server(process: subprocess.Popen[str]) -> None: + process.terminate() + try: + process.wait(timeout=5) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=5) + + +def generate() -> None: + SNIPPETS.mkdir(parents=True, exist_ok=True) + ASSETS.mkdir(parents=True, exist_ok=True) + for filename, text in STATIC_SNIPPETS.items(): + _write(SNIPPETS / filename, text) + + server = _start_server() + try: + _write(SNIPPETS / "cli-stream-output.txt", _run(STREAM_COMMAND)) + _write(SNIPPETS / "cli-files-output.txt", _run(FILES_COMMAND)) + finally: + _stop_server(server) + + source_cast = RECORDS / "a2a-streaming-files.cast" + if source_cast.exists(): + shutil.copyfile(source_cast, ASSETS / "a2a-streaming-files.cast") + + +def check() -> None: + expected = dict(STATIC_SNIPPETS) + expected["cli-stream-output.txt"] = "stream chunk one\nstream chunk two\n" + expected["cli-files-output.txt"] = ( + "file response\n" + "[report.pdf](https://example.com/report.pdf) (application/pdf)\n" + "```json\n" + "{\n" + " \"ok\": true,\n" + " \"source\": \"fake-a2a-server\"\n" + "}\n" + "```\n" + "[note.txt: 3 bytes text/plain]\n" + ) + missing_or_changed: list[str] = [] + for filename, text in expected.items(): + path = SNIPPETS / filename + if not path.exists() or path.read_text(encoding="utf-8") != text: + missing_or_changed.append(str(path.relative_to(ROOT))) + if missing_or_changed: + raise SystemExit( + "A2A docs snippets are stale; run `uv run scripts/a2a_docs_pipeline.py generate`.\n" + + "\n".join(missing_or_changed) + ) + + +def record() -> None: + generate() + if not shutil.which("asciinema"): + print("asciinema is not installed; generated text snippets only", file=sys.stderr) + return + if not shutil.which("tmux"): + print("tmux is not installed; generated text snippets only", file=sys.stderr) + return + + driver = Path("/tmp/a2a-docs-record.sh") + driver.write_text( + f"""#!/usr/bin/env bash +set -euo pipefail +SESSION=a2a_docs_cast +cd {ROOT} +tmux kill-session -t "$SESSION" 2>/dev/null || true +tmux new-session -d -s "$SESSION" 'cd {ROOT} && FAST_AGENT_MODEL=passthrough uv run fast-agent -x --a2a {BASE_URL} --a2a-transport JSONRPC' +sleep 4 +tmux send-keys -t "$SESSION" 'please stream' Enter +sleep 3 +tmux send-keys -t "$SESSION" 'respond with files' Enter +sleep 3 +tmux capture-pane -t "$SESSION" -p -S -3000 +sleep 1 +tmux kill-session -t "$SESSION" 2>/dev/null || true +""", + encoding="utf-8", + ) + driver.chmod(0o755) + + server = _start_server() + try: + command = [ + "asciinema", + "rec", + "--overwrite", + "--cols", + "104", + "--rows", + "34", + "--idle-time-limit", + "1.3", + "-t", + "fast-agent A2A streaming and files demo", + "-c", + str(driver), + str(ASSETS / "a2a-streaming-files.cast"), + ] + subprocess.run(command, cwd=ROOT, check=True) + finally: + _stop_server(server) + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("command", choices=["generate", "check", "record"]) + args = parser.parse_args() + if args.command == "generate": + generate() + elif args.command == "check": + check() + else: + record() + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/docs.py b/scripts/docs.py index c2cfb7af4..91cfcbd04 100755 --- a/scripts/docs.py +++ b/scripts/docs.py @@ -5,6 +5,7 @@ Usage: uv run scripts/docs.py install # Install/sync dev dependencies uv run scripts/docs.py generate # Generate reference docs from source + uv run scripts/docs.py a2a # Regenerate A2A getting-started snippets uv run scripts/docs.py social [--page path.md] # Generate committed Open Graph card PNGs uv run scripts/docs.py social-contact-sheet @@ -55,6 +56,15 @@ def generate() -> int: return 0 +def a2a() -> int: + """Regenerate A2A getting-started snippets and verify them.""" + result = subprocess.run([sys.executable, str(ROOT / "scripts" / "a2a_docs_pipeline.py"), "generate"], cwd=ROOT) + if result.returncode != 0: + return result.returncode + result = subprocess.run([sys.executable, str(ROOT / "scripts" / "a2a_docs_pipeline.py"), "check"], cwd=ROOT) + return result.returncode + + def social(args: list[str]) -> int: """Generate per-page Open Graph card PNGs using google-chrome.""" print("Generating docs social cards...", flush=True) @@ -172,6 +182,8 @@ def main() -> int: return install() elif command == "generate": return generate() + elif command == "a2a": + return a2a() elif command == "social": return social(sys.argv[2:]) elif command == "check-social": diff --git a/tests/unit/test_a2a_docs_pipeline.py b/tests/unit/test_a2a_docs_pipeline.py new file mode 100644 index 000000000..71589f4dc --- /dev/null +++ b/tests/unit/test_a2a_docs_pipeline.py @@ -0,0 +1,37 @@ +import importlib.util +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] +PIPELINE_PATH = ROOT / "scripts" / "a2a_docs_pipeline.py" + +spec = importlib.util.spec_from_file_location("a2a_docs_pipeline", PIPELINE_PATH) +assert spec is not None +assert spec.loader is not None +a2a_docs_pipeline = importlib.util.module_from_spec(spec) +spec.loader.exec_module(a2a_docs_pipeline) + + +def test_a2a_docs_snippets_are_current() -> None: + a2a_docs_pipeline.check() + + +def test_a2a_getting_started_includes_generated_snippets() -> None: + page = ROOT / "docs" / "docs" / "a2a" / "getting-started.md" + text = page.read_text(encoding="utf-8") + for filename in [ + "start-fake-server.sh", + "cli-stream-command.sh", + "cli-stream-output.txt", + "cli-files-command.sh", + "cli-files-output.txt", + "agent-card.yaml", + "tui-session.txt", + ]: + assert f'docs/docs/a2a/snippets/{filename}' in text + + +def test_a2a_cast_asset_is_present() -> None: + asset = ROOT / "docs" / "docs" / "assets" / "a2a" / "a2a-streaming-files.cast" + assert asset.is_file() + first_line = asset.read_text(encoding="utf-8").splitlines()[0] + assert '"version"' in first_line From dc0e62ad72fc9f54f335f4a090e31ba458dc875f Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Wed, 20 May 2026 20:44:59 +0100 Subject: [PATCH 09/58] embed asciinema player in a2a docs --- docs/docs/a2a/getting-started.md | 50 +- .../assets/vendor/asciinema-player/README.md | 8 + .../asciinema-player/asciinema-player.css | 2365 +++++++++++++++++ .../asciinema-player/asciinema-player.min.js | 1 + scripts/a2a_docs_pipeline.py | 22 +- tests/unit/test_a2a_docs_pipeline.py | 19 + 6 files changed, 2458 insertions(+), 7 deletions(-) create mode 100644 docs/docs/assets/vendor/asciinema-player/README.md create mode 100644 docs/docs/assets/vendor/asciinema-player/asciinema-player.css create mode 100644 docs/docs/assets/vendor/asciinema-player/asciinema-player.min.js diff --git a/docs/docs/a2a/getting-started.md b/docs/docs/a2a/getting-started.md index d0a7439e9..635345b09 100644 --- a/docs/docs/a2a/getting-started.md +++ b/docs/docs/a2a/getting-started.md @@ -126,12 +126,50 @@ The `/a2a` command group currently includes: ## Demo recording The repeatable docs pipeline can generate an asciinema recording for the TUI -streaming/files flow. The current committed recording is available as a static -asset: - -[Download the A2A streaming/files cast](../assets/a2a/a2a-streaming-files.cast) - -Replay locally with: +streaming/files flow. The committed `.cast` file is embedded below and can also +be downloaded for local replay. + + + +
+ + + + +If the player does not load, [download the A2A streaming/files cast](../assets/a2a/a2a-streaming-files.cast) +and replay it locally with: ```bash asciinema play docs/docs/assets/a2a/a2a-streaming-files.cast diff --git a/docs/docs/assets/vendor/asciinema-player/README.md b/docs/docs/assets/vendor/asciinema-player/README.md new file mode 100644 index 000000000..6a2e75f68 --- /dev/null +++ b/docs/docs/assets/vendor/asciinema-player/README.md @@ -0,0 +1,8 @@ +# asciinema-player vendored assets + +Vendored from `asciinema-player@3.9.0` via jsDelivr: + +- `dist/bundle/asciinema-player.css` +- `dist/bundle/asciinema-player.min.js` + +Used by the A2A Getting Started guide to replay checked-in `.cast` files without a CDN dependency. diff --git a/docs/docs/assets/vendor/asciinema-player/asciinema-player.css b/docs/docs/assets/vendor/asciinema-player/asciinema-player.css new file mode 100644 index 000000000..db3969d2b --- /dev/null +++ b/docs/docs/assets/vendor/asciinema-player/asciinema-player.css @@ -0,0 +1,2365 @@ +div.ap-wrapper { + outline: none; + height: 100%; + display: flex; + justify-content: center; +} +div.ap-wrapper .title-bar { + display: none; + top: -78px; + transition: top 0.15s linear; + position: absolute; + left: 0; + right: 0; + box-sizing: content-box; + font-size: 20px; + line-height: 1em; + padding: 15px; + font-family: sans-serif; + color: white; + background-color: rgba(0, 0, 0, 0.8); +} +div.ap-wrapper .title-bar img { + vertical-align: middle; + height: 48px; + margin-right: 16px; +} +div.ap-wrapper .title-bar a { + color: white; + text-decoration: underline; +} +div.ap-wrapper .title-bar a:hover { + text-decoration: none; +} +div.ap-wrapper:fullscreen { + background-color: #000; + width: 100%; + align-items: center; +} +div.ap-wrapper:fullscreen .title-bar { + display: initial; +} +div.ap-wrapper:fullscreen.hud .title-bar { + top: 0; +} +div.ap-wrapper div.ap-player { + text-align: left; + display: inline-block; + padding: 0px; + position: relative; + box-sizing: content-box; + overflow: hidden; + max-width: 100%; + border-radius: 4px; + font-size: 15px; + background-color: var(--term-color-background); +} +.ap-player { + --term-color-foreground: #ffffff; + --term-color-background: #000000; + --term-color-0: var(--term-color-foreground); + --term-color-1: var(--term-color-foreground); + --term-color-2: var(--term-color-foreground); + --term-color-3: var(--term-color-foreground); + --term-color-4: var(--term-color-foreground); + --term-color-5: var(--term-color-foreground); + --term-color-6: var(--term-color-foreground); + --term-color-7: var(--term-color-foreground); + --term-color-8: var(--term-color-0); + --term-color-9: var(--term-color-1); + --term-color-10: var(--term-color-2); + --term-color-11: var(--term-color-3); + --term-color-12: var(--term-color-4); + --term-color-13: var(--term-color-5); + --term-color-14: var(--term-color-6); + --term-color-15: var(--term-color-7); +} +.ap-player .fg-0 { + --fg: var(--term-color-0); +} +.ap-player .bg-0 { + --bg: var(--term-color-0); +} +.ap-player .fg-1 { + --fg: var(--term-color-1); +} +.ap-player .bg-1 { + --bg: var(--term-color-1); +} +.ap-player .fg-2 { + --fg: var(--term-color-2); +} +.ap-player .bg-2 { + --bg: var(--term-color-2); +} +.ap-player .fg-3 { + --fg: var(--term-color-3); +} +.ap-player .bg-3 { + --bg: var(--term-color-3); +} +.ap-player .fg-4 { + --fg: var(--term-color-4); +} +.ap-player .bg-4 { + --bg: var(--term-color-4); +} +.ap-player .fg-5 { + --fg: var(--term-color-5); +} +.ap-player .bg-5 { + --bg: var(--term-color-5); +} +.ap-player .fg-6 { + --fg: var(--term-color-6); +} +.ap-player .bg-6 { + --bg: var(--term-color-6); +} +.ap-player .fg-7 { + --fg: var(--term-color-7); +} +.ap-player .bg-7 { + --bg: var(--term-color-7); +} +.ap-player .fg-8 { + --fg: var(--term-color-8); +} +.ap-player .bg-8 { + --bg: var(--term-color-8); +} +.ap-player .fg-9 { + --fg: var(--term-color-9); +} +.ap-player .bg-9 { + --bg: var(--term-color-9); +} +.ap-player .fg-10 { + --fg: var(--term-color-10); +} +.ap-player .bg-10 { + --bg: var(--term-color-10); +} +.ap-player .fg-11 { + --fg: var(--term-color-11); +} +.ap-player .bg-11 { + --bg: var(--term-color-11); +} +.ap-player .fg-12 { + --fg: var(--term-color-12); +} +.ap-player .bg-12 { + --bg: var(--term-color-12); +} +.ap-player .fg-13 { + --fg: var(--term-color-13); +} +.ap-player .bg-13 { + --bg: var(--term-color-13); +} +.ap-player .fg-14 { + --fg: var(--term-color-14); +} +.ap-player .bg-14 { + --bg: var(--term-color-14); +} +.ap-player .fg-15 { + --fg: var(--term-color-15); +} +.ap-player .bg-15 { + --bg: var(--term-color-15); +} +.ap-player .fg-8, +.ap-player .fg-9, +.ap-player .fg-10, +.ap-player .fg-11, +.ap-player .fg-12, +.ap-player .fg-13, +.ap-player .fg-14, +.ap-player .fg-15 { + font-weight: bold; +} +pre.ap-terminal { + box-sizing: content-box; + overflow: hidden; + padding: 0; + margin: 0px; + display: block; + white-space: pre; + word-wrap: normal; + word-break: normal; + border-radius: 0; + border-style: solid; + cursor: text; + border-width: 0.75em; + color: var(--term-color-foreground); + background-color: var(--term-color-background); + border-color: var(--term-color-background); + outline: none; + line-height: var(--term-line-height); + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace, 'Powerline Symbols'; + font-variant-ligatures: none; +} +pre.ap-terminal .ap-line { + letter-spacing: normal; + overflow: hidden; +} +pre.ap-terminal .ap-line span { + padding: 0; + display: inline-block; + height: 100%; +} +pre.ap-terminal .ap-line { + display: block; + width: 100%; + height: var(--term-line-height); + position: relative; +} +pre.ap-terminal .ap-line span { + position: absolute; + left: calc(100% * var(--offset) / var(--term-cols)); + color: var(--fg); + background-color: var(--bg); +} +pre.ap-terminal .ap-line .ap-inverse { + color: var(--bg); + background-color: var(--fg); +} +pre.ap-terminal .ap-line .cp-2580 { + border-top: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2581 { + border-bottom: calc(0.125 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2582 { + border-bottom: calc(0.25 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2583 { + border-bottom: calc(0.375 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2584 { + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2585 { + border-bottom: calc(0.625 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2586 { + border-bottom: calc(0.75 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2587 { + border-bottom: calc(0.875 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2588 { + background-color: var(--fg); +} +pre.ap-terminal .ap-line .cp-2589 { + border-left: 0.875ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258a { + border-left: 0.75ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258b { + border-left: 0.625ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258c { + border-left: 0.5ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258d { + border-left: 0.375ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258e { + border-left: 0.25ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258f { + border-left: 0.125ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2590 { + border-right: 0.5ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2591 { + background-color: color-mix(in srgb, var(--fg) 25%, var(--bg)); +} +pre.ap-terminal .ap-line .cp-2592 { + background-color: color-mix(in srgb, var(--fg) 50%, var(--bg)); +} +pre.ap-terminal .ap-line .cp-2593 { + background-color: color-mix(in srgb, var(--fg) 75%, var(--bg)); +} +pre.ap-terminal .ap-line .cp-2594 { + border-top: calc(0.125 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2595 { + border-right: 0.125ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2596 { + border-right: 0.5ch solid var(--bg); + border-top: calc(0.5 * var(--term-line-height)) solid var(--bg); + background-color: var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2597 { + border-left: 0.5ch solid var(--bg); + border-top: calc(0.5 * var(--term-line-height)) solid var(--bg); + background-color: var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2598 { + border-right: 0.5ch solid var(--bg); + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--bg); + background-color: var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2599 { + border-left: 0.5ch solid var(--fg); + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259a { + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259a::before, +pre.ap-terminal .ap-line .cp-259a::after { + content: ''; + position: absolute; + width: 0.5ch; + height: calc(0.5 * var(--term-line-height)); + background-color: var(--fg); +} +pre.ap-terminal .ap-line .cp-259a::before { + top: 0; + left: 0; +} +pre.ap-terminal .ap-line .cp-259a::after { + bottom: 0; + right: 0; +} +pre.ap-terminal .ap-line .cp-259b { + border-left: 0.5ch solid var(--fg); + border-top: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259c { + border-right: 0.5ch solid var(--fg); + border-top: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259d { + border-left: 0.5ch solid var(--bg); + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--bg); + background-color: var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259e { + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259e::before, +pre.ap-terminal .ap-line .cp-259e::after { + content: ''; + position: absolute; + width: 0.5ch; + height: calc(0.5 * var(--term-line-height)); + background-color: var(--fg); +} +pre.ap-terminal .ap-line .cp-259e::before { + top: 0; + right: 0; +} +pre.ap-terminal .ap-line .cp-259e::after { + bottom: 0; + left: 0; +} +pre.ap-terminal .ap-line .cp-259f { + border-right: 0.5ch solid var(--fg); + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-e0b0 { + border-left: 1ch solid var(--fg); + border-top: calc(0.5 * var(--term-line-height)) solid transparent; + border-bottom: calc(0.5 * var(--term-line-height)) solid transparent; + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-e0b2 { + border-right: 1ch solid var(--fg); + border-top: calc(0.5 * var(--term-line-height)) solid transparent; + border-bottom: calc(0.5 * var(--term-line-height)) solid transparent; + box-sizing: border-box; +} +pre.ap-terminal.ap-cursor-on .ap-line .ap-cursor { + color: var(--bg); + background-color: var(--fg); + border-radius: 0.05em; +} +pre.ap-terminal.ap-cursor-on .ap-line .ap-cursor.ap-inverse { + color: var(--fg); + background-color: var(--bg); +} +pre.ap-terminal:not(.ap-blink) .ap-line .ap-blink { + color: transparent; + border-color: transparent; +} +pre.ap-terminal .ap-bright { + font-weight: bold; +} +pre.ap-terminal .ap-faint { + opacity: 0.5; +} +pre.ap-terminal .ap-underline { + text-decoration: underline; +} +pre.ap-terminal .ap-italic { + font-style: italic; +} +pre.ap-terminal .ap-strikethrough { + text-decoration: line-through; +} +.ap-line span { + --fg: var(--term-color-foreground); + --bg: var(--term-color-background); +} +div.ap-player div.ap-control-bar { + width: 100%; + height: 32px; + display: flex; + justify-content: space-between; + align-items: stretch; + color: var(--term-color-foreground); + box-sizing: content-box; + line-height: 1; + position: absolute; + bottom: 0; + left: 0; + opacity: 0; + transition: opacity 0.15s linear; + user-select: none; + border-top: 2px solid color-mix(in oklab, black 33%, var(--term-color-background)); + z-index: 30; +} +div.ap-player div.ap-control-bar * { + box-sizing: inherit; +} +div.ap-control-bar svg.ap-icon path { + fill: var(--term-color-foreground); +} +div.ap-control-bar span.ap-button { + display: flex; + flex: 0 0 auto; + cursor: pointer; +} +div.ap-control-bar span.ap-playback-button { + width: 12px; + height: 12px; + padding: 10px; +} +div.ap-control-bar span.ap-playback-button svg { + height: 12px; + width: 12px; +} +div.ap-control-bar span.ap-timer { + display: flex; + flex: 0 0 auto; + min-width: 50px; + margin: 0 10px; + height: 100%; + text-align: center; + font-size: 13px; + line-height: 100%; + cursor: default; +} +div.ap-control-bar span.ap-timer span { + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace; + font-size: inherit; + font-weight: 600; + margin: auto; +} +div.ap-control-bar span.ap-timer .ap-time-remaining { + display: none; +} +div.ap-control-bar span.ap-timer:hover .ap-time-elapsed { + display: none; +} +div.ap-control-bar span.ap-timer:hover .ap-time-remaining { + display: flex; +} +div.ap-control-bar .ap-progressbar { + display: block; + flex: 1 1 auto; + height: 100%; + padding: 0 10px; +} +div.ap-control-bar .ap-progressbar .ap-bar { + display: block; + position: relative; + cursor: default; + height: 100%; + font-size: 0; +} +div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter { + display: block; + position: absolute; + top: 15px; + left: 0; + right: 0; + height: 3px; +} +div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter-empty { + background-color: color-mix(in oklab, var(--term-color-foreground) 20%, var(--term-color-background)); +} +div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter-full { + width: 100%; + transform-origin: left center; + background-color: var(--term-color-foreground); + border-radius: 3px; +} +div.ap-control-bar.ap-seekable .ap-progressbar .ap-bar { + cursor: pointer; +} +div.ap-control-bar .ap-fullscreen-button { + width: 14px; + height: 14px; + padding: 9px; +} +div.ap-control-bar .ap-fullscreen-button svg { + width: 14px; + height: 14px; +} +div.ap-control-bar .ap-fullscreen-button svg.ap-icon-fullscreen-on { + display: inline; +} +div.ap-control-bar .ap-fullscreen-button svg.ap-icon-fullscreen-off { + display: none; +} +div.ap-control-bar .ap-fullscreen-button .ap-tooltip { + right: 5px; + left: initial; + transform: none; +} +div.ap-control-bar .ap-kbd-button { + height: 14px; + padding: 9px; + margin: 0 4px; +} +div.ap-control-bar .ap-kbd-button svg { + width: 26px; + height: 14px; +} +div.ap-control-bar .ap-kbd-button .ap-tooltip { + right: 5px; + left: initial; + transform: none; +} +div.ap-wrapper.ap-hud .ap-control-bar { + opacity: 1; +} +div.ap-wrapper:fullscreen .ap-fullscreen-button svg.ap-icon-fullscreen-on { + display: none; +} +div.ap-wrapper:fullscreen .ap-fullscreen-button svg.ap-icon-fullscreen-off { + display: inline; +} +span.ap-progressbar span.ap-marker-container { + display: block; + top: 0; + bottom: 0; + width: 21px; + position: absolute; + margin-left: -10px; +} +span.ap-marker-container span.ap-marker { + display: block; + top: 13px; + bottom: 12px; + left: 7px; + right: 7px; + background-color: color-mix(in oklab, var(--term-color-foreground) 33%, var(--term-color-background)); + position: absolute; + transition: top 0.1s, bottom 0.1s, left 0.1s, right 0.1s, background-color 0.1s; + border-radius: 50%; +} +span.ap-marker-container span.ap-marker.ap-marker-past { + background-color: var(--term-color-foreground); +} +span.ap-marker-container span.ap-marker:hover, +span.ap-marker-container:hover span.ap-marker { + background-color: var(--term-color-foreground); + top: 11px; + bottom: 10px; + left: 5px; + right: 5px; +} +.ap-tooltip-container span.ap-tooltip { + visibility: hidden; + background-color: var(--term-color-foreground); + color: var(--term-color-background); + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace; + font-weight: bold; + text-align: center; + padding: 0 0.5em; + border-radius: 4px; + position: absolute; + z-index: 1; + white-space: nowrap; + /* Prevents the text from wrapping and makes sure the tooltip width adapts to the text length */ + font-size: 13px; + line-height: 2em; + bottom: 100%; + left: 50%; + transform: translateX(-50%); +} +.ap-tooltip-container:hover span.ap-tooltip { + visibility: visible; +} +.ap-player .ap-overlay { + z-index: 10; + background-repeat: no-repeat; + background-position: center; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: flex; + justify-content: center; + align-items: center; +} +.ap-player .ap-overlay-start { + cursor: pointer; +} +.ap-player .ap-overlay-start .ap-play-button { + font-size: 0px; + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + text-align: center; + color: white; + height: 80px; + max-height: 66%; + margin: auto; +} +.ap-player .ap-overlay-start .ap-play-button div { + height: 100%; +} +.ap-player .ap-overlay-start .ap-play-button div span { + height: 100%; + display: block; +} +.ap-player .ap-overlay-start .ap-play-button div span svg { + height: 100%; +} +.ap-player .ap-overlay-start .ap-play-button svg { + filter: drop-shadow(0px 0px 5px rgba(0, 0, 0, 0.4)); +} +.ap-player .ap-overlay-loading .ap-loader { + width: 48px; + height: 48px; + border-radius: 50%; + display: inline-block; + position: relative; + border: 10px solid; + border-color: rgba(255, 255, 255, 0.3) rgba(255, 255, 255, 0.5) rgba(255, 255, 255, 0.7) #ffffff; + border-color: color-mix(in srgb, var(--term-color-foreground) 30%, var(--term-color-background)) color-mix(in srgb, var(--term-color-foreground) 50%, var(--term-color-background)) color-mix(in srgb, var(--term-color-foreground) 70%, var(--term-color-background)) color-mix(in srgb, var(--term-color-foreground) 100%, var(--term-color-background)); + box-sizing: border-box; + animation: ap-loader-rotation 1s linear infinite; +} +.ap-player .ap-overlay-info { + background-color: var(--term-color-background); +} +.ap-player .ap-overlay-info span { + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace, 'Powerline Symbols'; + font-variant-ligatures: none; + font-size: 2em; + color: var(--term-color-foreground); +} +.ap-player .ap-overlay-info span .ap-line { + letter-spacing: normal; + overflow: hidden; +} +.ap-player .ap-overlay-info span .ap-line span { + padding: 0; + display: inline-block; + height: 100%; +} +.ap-player .ap-overlay-help { + background-color: rgba(0, 0, 0, 0.8); + container-type: inline-size; +} +.ap-player .ap-overlay-help > div { + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace, 'Powerline Symbols'; + font-variant-ligatures: none; + max-width: 85%; + max-height: 85%; + font-size: 18px; + color: var(--term-color-foreground); + background-color: var(--term-color-background); + border-radius: 6px; + box-sizing: border-box; + margin-bottom: 32px; +} +.ap-player .ap-overlay-help > div .ap-line { + letter-spacing: normal; + overflow: hidden; +} +.ap-player .ap-overlay-help > div .ap-line span { + padding: 0; + display: inline-block; + height: 100%; +} +.ap-player .ap-overlay-help > div div { + padding: calc(min(4cqw, 40px)); + font-size: calc(min(1.9cqw, 18px)); +} +.ap-player .ap-overlay-help > div div p { + font-weight: bold; + margin: 0 0 2em 0; +} +.ap-player .ap-overlay-help > div div ul { + list-style: none; + padding: 0; +} +.ap-player .ap-overlay-help > div div ul li { + margin: 0 0 0.75em 0; +} +.ap-player .ap-overlay-help > div div kbd { + color: var(--term-color-background); + background-color: var(--term-color-foreground); + padding: 0.2em 0.5em; + border-radius: 0.2em; + font-family: inherit; + font-size: 0.85em; + border: none; + margin: 0; +} +.ap-player .ap-overlay-error span { + font-size: 8em; +} +@keyframes ap-loader-rotation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} +.ap-terminal .fg-16 { + --fg: #000000; +} +.ap-terminal .bg-16 { + --bg: #000000; +} +.ap-terminal .fg-17 { + --fg: #00005f; +} +.ap-terminal .bg-17 { + --bg: #00005f; +} +.ap-terminal .fg-18 { + --fg: #000087; +} +.ap-terminal .bg-18 { + --bg: #000087; +} +.ap-terminal .fg-19 { + --fg: #0000af; +} +.ap-terminal .bg-19 { + --bg: #0000af; +} +.ap-terminal .fg-20 { + --fg: #0000d7; +} +.ap-terminal .bg-20 { + --bg: #0000d7; +} +.ap-terminal .fg-21 { + --fg: #0000ff; +} +.ap-terminal .bg-21 { + --bg: #0000ff; +} +.ap-terminal .fg-22 { + --fg: #005f00; +} +.ap-terminal .bg-22 { + --bg: #005f00; +} +.ap-terminal .fg-23 { + --fg: #005f5f; +} +.ap-terminal .bg-23 { + --bg: #005f5f; +} +.ap-terminal .fg-24 { + --fg: #005f87; +} +.ap-terminal .bg-24 { + --bg: #005f87; +} +.ap-terminal .fg-25 { + --fg: #005faf; +} +.ap-terminal .bg-25 { + --bg: #005faf; +} +.ap-terminal .fg-26 { + --fg: #005fd7; +} +.ap-terminal .bg-26 { + --bg: #005fd7; +} +.ap-terminal .fg-27 { + --fg: #005fff; +} +.ap-terminal .bg-27 { + --bg: #005fff; +} +.ap-terminal .fg-28 { + --fg: #008700; +} +.ap-terminal .bg-28 { + --bg: #008700; +} +.ap-terminal .fg-29 { + --fg: #00875f; +} +.ap-terminal .bg-29 { + --bg: #00875f; +} +.ap-terminal .fg-30 { + --fg: #008787; +} +.ap-terminal .bg-30 { + --bg: #008787; +} +.ap-terminal .fg-31 { + --fg: #0087af; +} +.ap-terminal .bg-31 { + --bg: #0087af; +} +.ap-terminal .fg-32 { + --fg: #0087d7; +} +.ap-terminal .bg-32 { + --bg: #0087d7; +} +.ap-terminal .fg-33 { + --fg: #0087ff; +} +.ap-terminal .bg-33 { + --bg: #0087ff; +} +.ap-terminal .fg-34 { + --fg: #00af00; +} +.ap-terminal .bg-34 { + --bg: #00af00; +} +.ap-terminal .fg-35 { + --fg: #00af5f; +} +.ap-terminal .bg-35 { + --bg: #00af5f; +} +.ap-terminal .fg-36 { + --fg: #00af87; +} +.ap-terminal .bg-36 { + --bg: #00af87; +} +.ap-terminal .fg-37 { + --fg: #00afaf; +} +.ap-terminal .bg-37 { + --bg: #00afaf; +} +.ap-terminal .fg-38 { + --fg: #00afd7; +} +.ap-terminal .bg-38 { + --bg: #00afd7; +} +.ap-terminal .fg-39 { + --fg: #00afff; +} +.ap-terminal .bg-39 { + --bg: #00afff; +} +.ap-terminal .fg-40 { + --fg: #00d700; +} +.ap-terminal .bg-40 { + --bg: #00d700; +} +.ap-terminal .fg-41 { + --fg: #00d75f; +} +.ap-terminal .bg-41 { + --bg: #00d75f; +} +.ap-terminal .fg-42 { + --fg: #00d787; +} +.ap-terminal .bg-42 { + --bg: #00d787; +} +.ap-terminal .fg-43 { + --fg: #00d7af; +} +.ap-terminal .bg-43 { + --bg: #00d7af; +} +.ap-terminal .fg-44 { + --fg: #00d7d7; +} +.ap-terminal .bg-44 { + --bg: #00d7d7; +} +.ap-terminal .fg-45 { + --fg: #00d7ff; +} +.ap-terminal .bg-45 { + --bg: #00d7ff; +} +.ap-terminal .fg-46 { + --fg: #00ff00; +} +.ap-terminal .bg-46 { + --bg: #00ff00; +} +.ap-terminal .fg-47 { + --fg: #00ff5f; +} +.ap-terminal .bg-47 { + --bg: #00ff5f; +} +.ap-terminal .fg-48 { + --fg: #00ff87; +} +.ap-terminal .bg-48 { + --bg: #00ff87; +} +.ap-terminal .fg-49 { + --fg: #00ffaf; +} +.ap-terminal .bg-49 { + --bg: #00ffaf; +} +.ap-terminal .fg-50 { + --fg: #00ffd7; +} +.ap-terminal .bg-50 { + --bg: #00ffd7; +} +.ap-terminal .fg-51 { + --fg: #00ffff; +} +.ap-terminal .bg-51 { + --bg: #00ffff; +} +.ap-terminal .fg-52 { + --fg: #5f0000; +} +.ap-terminal .bg-52 { + --bg: #5f0000; +} +.ap-terminal .fg-53 { + --fg: #5f005f; +} +.ap-terminal .bg-53 { + --bg: #5f005f; +} +.ap-terminal .fg-54 { + --fg: #5f0087; +} +.ap-terminal .bg-54 { + --bg: #5f0087; +} +.ap-terminal .fg-55 { + --fg: #5f00af; +} +.ap-terminal .bg-55 { + --bg: #5f00af; +} +.ap-terminal .fg-56 { + --fg: #5f00d7; +} +.ap-terminal .bg-56 { + --bg: #5f00d7; +} +.ap-terminal .fg-57 { + --fg: #5f00ff; +} +.ap-terminal .bg-57 { + --bg: #5f00ff; +} +.ap-terminal .fg-58 { + --fg: #5f5f00; +} +.ap-terminal .bg-58 { + --bg: #5f5f00; +} +.ap-terminal .fg-59 { + --fg: #5f5f5f; +} +.ap-terminal .bg-59 { + --bg: #5f5f5f; +} +.ap-terminal .fg-60 { + --fg: #5f5f87; +} +.ap-terminal .bg-60 { + --bg: #5f5f87; +} +.ap-terminal .fg-61 { + --fg: #5f5faf; +} +.ap-terminal .bg-61 { + --bg: #5f5faf; +} +.ap-terminal .fg-62 { + --fg: #5f5fd7; +} +.ap-terminal .bg-62 { + --bg: #5f5fd7; +} +.ap-terminal .fg-63 { + --fg: #5f5fff; +} +.ap-terminal .bg-63 { + --bg: #5f5fff; +} +.ap-terminal .fg-64 { + --fg: #5f8700; +} +.ap-terminal .bg-64 { + --bg: #5f8700; +} +.ap-terminal .fg-65 { + --fg: #5f875f; +} +.ap-terminal .bg-65 { + --bg: #5f875f; +} +.ap-terminal .fg-66 { + --fg: #5f8787; +} +.ap-terminal .bg-66 { + --bg: #5f8787; +} +.ap-terminal .fg-67 { + --fg: #5f87af; +} +.ap-terminal .bg-67 { + --bg: #5f87af; +} +.ap-terminal .fg-68 { + --fg: #5f87d7; +} +.ap-terminal .bg-68 { + --bg: #5f87d7; +} +.ap-terminal .fg-69 { + --fg: #5f87ff; +} +.ap-terminal .bg-69 { + --bg: #5f87ff; +} +.ap-terminal .fg-70 { + --fg: #5faf00; +} +.ap-terminal .bg-70 { + --bg: #5faf00; +} +.ap-terminal .fg-71 { + --fg: #5faf5f; +} +.ap-terminal .bg-71 { + --bg: #5faf5f; +} +.ap-terminal .fg-72 { + --fg: #5faf87; +} +.ap-terminal .bg-72 { + --bg: #5faf87; +} +.ap-terminal .fg-73 { + --fg: #5fafaf; +} +.ap-terminal .bg-73 { + --bg: #5fafaf; +} +.ap-terminal .fg-74 { + --fg: #5fafd7; +} +.ap-terminal .bg-74 { + --bg: #5fafd7; +} +.ap-terminal .fg-75 { + --fg: #5fafff; +} +.ap-terminal .bg-75 { + --bg: #5fafff; +} +.ap-terminal .fg-76 { + --fg: #5fd700; +} +.ap-terminal .bg-76 { + --bg: #5fd700; +} +.ap-terminal .fg-77 { + --fg: #5fd75f; +} +.ap-terminal .bg-77 { + --bg: #5fd75f; +} +.ap-terminal .fg-78 { + --fg: #5fd787; +} +.ap-terminal .bg-78 { + --bg: #5fd787; +} +.ap-terminal .fg-79 { + --fg: #5fd7af; +} +.ap-terminal .bg-79 { + --bg: #5fd7af; +} +.ap-terminal .fg-80 { + --fg: #5fd7d7; +} +.ap-terminal .bg-80 { + --bg: #5fd7d7; +} +.ap-terminal .fg-81 { + --fg: #5fd7ff; +} +.ap-terminal .bg-81 { + --bg: #5fd7ff; +} +.ap-terminal .fg-82 { + --fg: #5fff00; +} +.ap-terminal .bg-82 { + --bg: #5fff00; +} +.ap-terminal .fg-83 { + --fg: #5fff5f; +} +.ap-terminal .bg-83 { + --bg: #5fff5f; +} +.ap-terminal .fg-84 { + --fg: #5fff87; +} +.ap-terminal .bg-84 { + --bg: #5fff87; +} +.ap-terminal .fg-85 { + --fg: #5fffaf; +} +.ap-terminal .bg-85 { + --bg: #5fffaf; +} +.ap-terminal .fg-86 { + --fg: #5fffd7; +} +.ap-terminal .bg-86 { + --bg: #5fffd7; +} +.ap-terminal .fg-87 { + --fg: #5fffff; +} +.ap-terminal .bg-87 { + --bg: #5fffff; +} +.ap-terminal .fg-88 { + --fg: #870000; +} +.ap-terminal .bg-88 { + --bg: #870000; +} +.ap-terminal .fg-89 { + --fg: #87005f; +} +.ap-terminal .bg-89 { + --bg: #87005f; +} +.ap-terminal .fg-90 { + --fg: #870087; +} +.ap-terminal .bg-90 { + --bg: #870087; +} +.ap-terminal .fg-91 { + --fg: #8700af; +} +.ap-terminal .bg-91 { + --bg: #8700af; +} +.ap-terminal .fg-92 { + --fg: #8700d7; +} +.ap-terminal .bg-92 { + --bg: #8700d7; +} +.ap-terminal .fg-93 { + --fg: #8700ff; +} +.ap-terminal .bg-93 { + --bg: #8700ff; +} +.ap-terminal .fg-94 { + --fg: #875f00; +} +.ap-terminal .bg-94 { + --bg: #875f00; +} +.ap-terminal .fg-95 { + --fg: #875f5f; +} +.ap-terminal .bg-95 { + --bg: #875f5f; +} +.ap-terminal .fg-96 { + --fg: #875f87; +} +.ap-terminal .bg-96 { + --bg: #875f87; +} +.ap-terminal .fg-97 { + --fg: #875faf; +} +.ap-terminal .bg-97 { + --bg: #875faf; +} +.ap-terminal .fg-98 { + --fg: #875fd7; +} +.ap-terminal .bg-98 { + --bg: #875fd7; +} +.ap-terminal .fg-99 { + --fg: #875fff; +} +.ap-terminal .bg-99 { + --bg: #875fff; +} +.ap-terminal .fg-100 { + --fg: #878700; +} +.ap-terminal .bg-100 { + --bg: #878700; +} +.ap-terminal .fg-101 { + --fg: #87875f; +} +.ap-terminal .bg-101 { + --bg: #87875f; +} +.ap-terminal .fg-102 { + --fg: #878787; +} +.ap-terminal .bg-102 { + --bg: #878787; +} +.ap-terminal .fg-103 { + --fg: #8787af; +} +.ap-terminal .bg-103 { + --bg: #8787af; +} +.ap-terminal .fg-104 { + --fg: #8787d7; +} +.ap-terminal .bg-104 { + --bg: #8787d7; +} +.ap-terminal .fg-105 { + --fg: #8787ff; +} +.ap-terminal .bg-105 { + --bg: #8787ff; +} +.ap-terminal .fg-106 { + --fg: #87af00; +} +.ap-terminal .bg-106 { + --bg: #87af00; +} +.ap-terminal .fg-107 { + --fg: #87af5f; +} +.ap-terminal .bg-107 { + --bg: #87af5f; +} +.ap-terminal .fg-108 { + --fg: #87af87; +} +.ap-terminal .bg-108 { + --bg: #87af87; +} +.ap-terminal .fg-109 { + --fg: #87afaf; +} +.ap-terminal .bg-109 { + --bg: #87afaf; +} +.ap-terminal .fg-110 { + --fg: #87afd7; +} +.ap-terminal .bg-110 { + --bg: #87afd7; +} +.ap-terminal .fg-111 { + --fg: #87afff; +} +.ap-terminal .bg-111 { + --bg: #87afff; +} +.ap-terminal .fg-112 { + --fg: #87d700; +} +.ap-terminal .bg-112 { + --bg: #87d700; +} +.ap-terminal .fg-113 { + --fg: #87d75f; +} +.ap-terminal .bg-113 { + --bg: #87d75f; +} +.ap-terminal .fg-114 { + --fg: #87d787; +} +.ap-terminal .bg-114 { + --bg: #87d787; +} +.ap-terminal .fg-115 { + --fg: #87d7af; +} +.ap-terminal .bg-115 { + --bg: #87d7af; +} +.ap-terminal .fg-116 { + --fg: #87d7d7; +} +.ap-terminal .bg-116 { + --bg: #87d7d7; +} +.ap-terminal .fg-117 { + --fg: #87d7ff; +} +.ap-terminal .bg-117 { + --bg: #87d7ff; +} +.ap-terminal .fg-118 { + --fg: #87ff00; +} +.ap-terminal .bg-118 { + --bg: #87ff00; +} +.ap-terminal .fg-119 { + --fg: #87ff5f; +} +.ap-terminal .bg-119 { + --bg: #87ff5f; +} +.ap-terminal .fg-120 { + --fg: #87ff87; +} +.ap-terminal .bg-120 { + --bg: #87ff87; +} +.ap-terminal .fg-121 { + --fg: #87ffaf; +} +.ap-terminal .bg-121 { + --bg: #87ffaf; +} +.ap-terminal .fg-122 { + --fg: #87ffd7; +} +.ap-terminal .bg-122 { + --bg: #87ffd7; +} +.ap-terminal .fg-123 { + --fg: #87ffff; +} +.ap-terminal .bg-123 { + --bg: #87ffff; +} +.ap-terminal .fg-124 { + --fg: #af0000; +} +.ap-terminal .bg-124 { + --bg: #af0000; +} +.ap-terminal .fg-125 { + --fg: #af005f; +} +.ap-terminal .bg-125 { + --bg: #af005f; +} +.ap-terminal .fg-126 { + --fg: #af0087; +} +.ap-terminal .bg-126 { + --bg: #af0087; +} +.ap-terminal .fg-127 { + --fg: #af00af; +} +.ap-terminal .bg-127 { + --bg: #af00af; +} +.ap-terminal .fg-128 { + --fg: #af00d7; +} +.ap-terminal .bg-128 { + --bg: #af00d7; +} +.ap-terminal .fg-129 { + --fg: #af00ff; +} +.ap-terminal .bg-129 { + --bg: #af00ff; +} +.ap-terminal .fg-130 { + --fg: #af5f00; +} +.ap-terminal .bg-130 { + --bg: #af5f00; +} +.ap-terminal .fg-131 { + --fg: #af5f5f; +} +.ap-terminal .bg-131 { + --bg: #af5f5f; +} +.ap-terminal .fg-132 { + --fg: #af5f87; +} +.ap-terminal .bg-132 { + --bg: #af5f87; +} +.ap-terminal .fg-133 { + --fg: #af5faf; +} +.ap-terminal .bg-133 { + --bg: #af5faf; +} +.ap-terminal .fg-134 { + --fg: #af5fd7; +} +.ap-terminal .bg-134 { + --bg: #af5fd7; +} +.ap-terminal .fg-135 { + --fg: #af5fff; +} +.ap-terminal .bg-135 { + --bg: #af5fff; +} +.ap-terminal .fg-136 { + --fg: #af8700; +} +.ap-terminal .bg-136 { + --bg: #af8700; +} +.ap-terminal .fg-137 { + --fg: #af875f; +} +.ap-terminal .bg-137 { + --bg: #af875f; +} +.ap-terminal .fg-138 { + --fg: #af8787; +} +.ap-terminal .bg-138 { + --bg: #af8787; +} +.ap-terminal .fg-139 { + --fg: #af87af; +} +.ap-terminal .bg-139 { + --bg: #af87af; +} +.ap-terminal .fg-140 { + --fg: #af87d7; +} +.ap-terminal .bg-140 { + --bg: #af87d7; +} +.ap-terminal .fg-141 { + --fg: #af87ff; +} +.ap-terminal .bg-141 { + --bg: #af87ff; +} +.ap-terminal .fg-142 { + --fg: #afaf00; +} +.ap-terminal .bg-142 { + --bg: #afaf00; +} +.ap-terminal .fg-143 { + --fg: #afaf5f; +} +.ap-terminal .bg-143 { + --bg: #afaf5f; +} +.ap-terminal .fg-144 { + --fg: #afaf87; +} +.ap-terminal .bg-144 { + --bg: #afaf87; +} +.ap-terminal .fg-145 { + --fg: #afafaf; +} +.ap-terminal .bg-145 { + --bg: #afafaf; +} +.ap-terminal .fg-146 { + --fg: #afafd7; +} +.ap-terminal .bg-146 { + --bg: #afafd7; +} +.ap-terminal .fg-147 { + --fg: #afafff; +} +.ap-terminal .bg-147 { + --bg: #afafff; +} +.ap-terminal .fg-148 { + --fg: #afd700; +} +.ap-terminal .bg-148 { + --bg: #afd700; +} +.ap-terminal .fg-149 { + --fg: #afd75f; +} +.ap-terminal .bg-149 { + --bg: #afd75f; +} +.ap-terminal .fg-150 { + --fg: #afd787; +} +.ap-terminal .bg-150 { + --bg: #afd787; +} +.ap-terminal .fg-151 { + --fg: #afd7af; +} +.ap-terminal .bg-151 { + --bg: #afd7af; +} +.ap-terminal .fg-152 { + --fg: #afd7d7; +} +.ap-terminal .bg-152 { + --bg: #afd7d7; +} +.ap-terminal .fg-153 { + --fg: #afd7ff; +} +.ap-terminal .bg-153 { + --bg: #afd7ff; +} +.ap-terminal .fg-154 { + --fg: #afff00; +} +.ap-terminal .bg-154 { + --bg: #afff00; +} +.ap-terminal .fg-155 { + --fg: #afff5f; +} +.ap-terminal .bg-155 { + --bg: #afff5f; +} +.ap-terminal .fg-156 { + --fg: #afff87; +} +.ap-terminal .bg-156 { + --bg: #afff87; +} +.ap-terminal .fg-157 { + --fg: #afffaf; +} +.ap-terminal .bg-157 { + --bg: #afffaf; +} +.ap-terminal .fg-158 { + --fg: #afffd7; +} +.ap-terminal .bg-158 { + --bg: #afffd7; +} +.ap-terminal .fg-159 { + --fg: #afffff; +} +.ap-terminal .bg-159 { + --bg: #afffff; +} +.ap-terminal .fg-160 { + --fg: #d70000; +} +.ap-terminal .bg-160 { + --bg: #d70000; +} +.ap-terminal .fg-161 { + --fg: #d7005f; +} +.ap-terminal .bg-161 { + --bg: #d7005f; +} +.ap-terminal .fg-162 { + --fg: #d70087; +} +.ap-terminal .bg-162 { + --bg: #d70087; +} +.ap-terminal .fg-163 { + --fg: #d700af; +} +.ap-terminal .bg-163 { + --bg: #d700af; +} +.ap-terminal .fg-164 { + --fg: #d700d7; +} +.ap-terminal .bg-164 { + --bg: #d700d7; +} +.ap-terminal .fg-165 { + --fg: #d700ff; +} +.ap-terminal .bg-165 { + --bg: #d700ff; +} +.ap-terminal .fg-166 { + --fg: #d75f00; +} +.ap-terminal .bg-166 { + --bg: #d75f00; +} +.ap-terminal .fg-167 { + --fg: #d75f5f; +} +.ap-terminal .bg-167 { + --bg: #d75f5f; +} +.ap-terminal .fg-168 { + --fg: #d75f87; +} +.ap-terminal .bg-168 { + --bg: #d75f87; +} +.ap-terminal .fg-169 { + --fg: #d75faf; +} +.ap-terminal .bg-169 { + --bg: #d75faf; +} +.ap-terminal .fg-170 { + --fg: #d75fd7; +} +.ap-terminal .bg-170 { + --bg: #d75fd7; +} +.ap-terminal .fg-171 { + --fg: #d75fff; +} +.ap-terminal .bg-171 { + --bg: #d75fff; +} +.ap-terminal .fg-172 { + --fg: #d78700; +} +.ap-terminal .bg-172 { + --bg: #d78700; +} +.ap-terminal .fg-173 { + --fg: #d7875f; +} +.ap-terminal .bg-173 { + --bg: #d7875f; +} +.ap-terminal .fg-174 { + --fg: #d78787; +} +.ap-terminal .bg-174 { + --bg: #d78787; +} +.ap-terminal .fg-175 { + --fg: #d787af; +} +.ap-terminal .bg-175 { + --bg: #d787af; +} +.ap-terminal .fg-176 { + --fg: #d787d7; +} +.ap-terminal .bg-176 { + --bg: #d787d7; +} +.ap-terminal .fg-177 { + --fg: #d787ff; +} +.ap-terminal .bg-177 { + --bg: #d787ff; +} +.ap-terminal .fg-178 { + --fg: #d7af00; +} +.ap-terminal .bg-178 { + --bg: #d7af00; +} +.ap-terminal .fg-179 { + --fg: #d7af5f; +} +.ap-terminal .bg-179 { + --bg: #d7af5f; +} +.ap-terminal .fg-180 { + --fg: #d7af87; +} +.ap-terminal .bg-180 { + --bg: #d7af87; +} +.ap-terminal .fg-181 { + --fg: #d7afaf; +} +.ap-terminal .bg-181 { + --bg: #d7afaf; +} +.ap-terminal .fg-182 { + --fg: #d7afd7; +} +.ap-terminal .bg-182 { + --bg: #d7afd7; +} +.ap-terminal .fg-183 { + --fg: #d7afff; +} +.ap-terminal .bg-183 { + --bg: #d7afff; +} +.ap-terminal .fg-184 { + --fg: #d7d700; +} +.ap-terminal .bg-184 { + --bg: #d7d700; +} +.ap-terminal .fg-185 { + --fg: #d7d75f; +} +.ap-terminal .bg-185 { + --bg: #d7d75f; +} +.ap-terminal .fg-186 { + --fg: #d7d787; +} +.ap-terminal .bg-186 { + --bg: #d7d787; +} +.ap-terminal .fg-187 { + --fg: #d7d7af; +} +.ap-terminal .bg-187 { + --bg: #d7d7af; +} +.ap-terminal .fg-188 { + --fg: #d7d7d7; +} +.ap-terminal .bg-188 { + --bg: #d7d7d7; +} +.ap-terminal .fg-189 { + --fg: #d7d7ff; +} +.ap-terminal .bg-189 { + --bg: #d7d7ff; +} +.ap-terminal .fg-190 { + --fg: #d7ff00; +} +.ap-terminal .bg-190 { + --bg: #d7ff00; +} +.ap-terminal .fg-191 { + --fg: #d7ff5f; +} +.ap-terminal .bg-191 { + --bg: #d7ff5f; +} +.ap-terminal .fg-192 { + --fg: #d7ff87; +} +.ap-terminal .bg-192 { + --bg: #d7ff87; +} +.ap-terminal .fg-193 { + --fg: #d7ffaf; +} +.ap-terminal .bg-193 { + --bg: #d7ffaf; +} +.ap-terminal .fg-194 { + --fg: #d7ffd7; +} +.ap-terminal .bg-194 { + --bg: #d7ffd7; +} +.ap-terminal .fg-195 { + --fg: #d7ffff; +} +.ap-terminal .bg-195 { + --bg: #d7ffff; +} +.ap-terminal .fg-196 { + --fg: #ff0000; +} +.ap-terminal .bg-196 { + --bg: #ff0000; +} +.ap-terminal .fg-197 { + --fg: #ff005f; +} +.ap-terminal .bg-197 { + --bg: #ff005f; +} +.ap-terminal .fg-198 { + --fg: #ff0087; +} +.ap-terminal .bg-198 { + --bg: #ff0087; +} +.ap-terminal .fg-199 { + --fg: #ff00af; +} +.ap-terminal .bg-199 { + --bg: #ff00af; +} +.ap-terminal .fg-200 { + --fg: #ff00d7; +} +.ap-terminal .bg-200 { + --bg: #ff00d7; +} +.ap-terminal .fg-201 { + --fg: #ff00ff; +} +.ap-terminal .bg-201 { + --bg: #ff00ff; +} +.ap-terminal .fg-202 { + --fg: #ff5f00; +} +.ap-terminal .bg-202 { + --bg: #ff5f00; +} +.ap-terminal .fg-203 { + --fg: #ff5f5f; +} +.ap-terminal .bg-203 { + --bg: #ff5f5f; +} +.ap-terminal .fg-204 { + --fg: #ff5f87; +} +.ap-terminal .bg-204 { + --bg: #ff5f87; +} +.ap-terminal .fg-205 { + --fg: #ff5faf; +} +.ap-terminal .bg-205 { + --bg: #ff5faf; +} +.ap-terminal .fg-206 { + --fg: #ff5fd7; +} +.ap-terminal .bg-206 { + --bg: #ff5fd7; +} +.ap-terminal .fg-207 { + --fg: #ff5fff; +} +.ap-terminal .bg-207 { + --bg: #ff5fff; +} +.ap-terminal .fg-208 { + --fg: #ff8700; +} +.ap-terminal .bg-208 { + --bg: #ff8700; +} +.ap-terminal .fg-209 { + --fg: #ff875f; +} +.ap-terminal .bg-209 { + --bg: #ff875f; +} +.ap-terminal .fg-210 { + --fg: #ff8787; +} +.ap-terminal .bg-210 { + --bg: #ff8787; +} +.ap-terminal .fg-211 { + --fg: #ff87af; +} +.ap-terminal .bg-211 { + --bg: #ff87af; +} +.ap-terminal .fg-212 { + --fg: #ff87d7; +} +.ap-terminal .bg-212 { + --bg: #ff87d7; +} +.ap-terminal .fg-213 { + --fg: #ff87ff; +} +.ap-terminal .bg-213 { + --bg: #ff87ff; +} +.ap-terminal .fg-214 { + --fg: #ffaf00; +} +.ap-terminal .bg-214 { + --bg: #ffaf00; +} +.ap-terminal .fg-215 { + --fg: #ffaf5f; +} +.ap-terminal .bg-215 { + --bg: #ffaf5f; +} +.ap-terminal .fg-216 { + --fg: #ffaf87; +} +.ap-terminal .bg-216 { + --bg: #ffaf87; +} +.ap-terminal .fg-217 { + --fg: #ffafaf; +} +.ap-terminal .bg-217 { + --bg: #ffafaf; +} +.ap-terminal .fg-218 { + --fg: #ffafd7; +} +.ap-terminal .bg-218 { + --bg: #ffafd7; +} +.ap-terminal .fg-219 { + --fg: #ffafff; +} +.ap-terminal .bg-219 { + --bg: #ffafff; +} +.ap-terminal .fg-220 { + --fg: #ffd700; +} +.ap-terminal .bg-220 { + --bg: #ffd700; +} +.ap-terminal .fg-221 { + --fg: #ffd75f; +} +.ap-terminal .bg-221 { + --bg: #ffd75f; +} +.ap-terminal .fg-222 { + --fg: #ffd787; +} +.ap-terminal .bg-222 { + --bg: #ffd787; +} +.ap-terminal .fg-223 { + --fg: #ffd7af; +} +.ap-terminal .bg-223 { + --bg: #ffd7af; +} +.ap-terminal .fg-224 { + --fg: #ffd7d7; +} +.ap-terminal .bg-224 { + --bg: #ffd7d7; +} +.ap-terminal .fg-225 { + --fg: #ffd7ff; +} +.ap-terminal .bg-225 { + --bg: #ffd7ff; +} +.ap-terminal .fg-226 { + --fg: #ffff00; +} +.ap-terminal .bg-226 { + --bg: #ffff00; +} +.ap-terminal .fg-227 { + --fg: #ffff5f; +} +.ap-terminal .bg-227 { + --bg: #ffff5f; +} +.ap-terminal .fg-228 { + --fg: #ffff87; +} +.ap-terminal .bg-228 { + --bg: #ffff87; +} +.ap-terminal .fg-229 { + --fg: #ffffaf; +} +.ap-terminal .bg-229 { + --bg: #ffffaf; +} +.ap-terminal .fg-230 { + --fg: #ffffd7; +} +.ap-terminal .bg-230 { + --bg: #ffffd7; +} +.ap-terminal .fg-231 { + --fg: #ffffff; +} +.ap-terminal .bg-231 { + --bg: #ffffff; +} +.ap-terminal .fg-232 { + --fg: #080808; +} +.ap-terminal .bg-232 { + --bg: #080808; +} +.ap-terminal .fg-233 { + --fg: #121212; +} +.ap-terminal .bg-233 { + --bg: #121212; +} +.ap-terminal .fg-234 { + --fg: #1c1c1c; +} +.ap-terminal .bg-234 { + --bg: #1c1c1c; +} +.ap-terminal .fg-235 { + --fg: #262626; +} +.ap-terminal .bg-235 { + --bg: #262626; +} +.ap-terminal .fg-236 { + --fg: #303030; +} +.ap-terminal .bg-236 { + --bg: #303030; +} +.ap-terminal .fg-237 { + --fg: #3a3a3a; +} +.ap-terminal .bg-237 { + --bg: #3a3a3a; +} +.ap-terminal .fg-238 { + --fg: #444444; +} +.ap-terminal .bg-238 { + --bg: #444444; +} +.ap-terminal .fg-239 { + --fg: #4e4e4e; +} +.ap-terminal .bg-239 { + --bg: #4e4e4e; +} +.ap-terminal .fg-240 { + --fg: #585858; +} +.ap-terminal .bg-240 { + --bg: #585858; +} +.ap-terminal .fg-241 { + --fg: #626262; +} +.ap-terminal .bg-241 { + --bg: #626262; +} +.ap-terminal .fg-242 { + --fg: #6c6c6c; +} +.ap-terminal .bg-242 { + --bg: #6c6c6c; +} +.ap-terminal .fg-243 { + --fg: #767676; +} +.ap-terminal .bg-243 { + --bg: #767676; +} +.ap-terminal .fg-244 { + --fg: #808080; +} +.ap-terminal .bg-244 { + --bg: #808080; +} +.ap-terminal .fg-245 { + --fg: #8a8a8a; +} +.ap-terminal .bg-245 { + --bg: #8a8a8a; +} +.ap-terminal .fg-246 { + --fg: #949494; +} +.ap-terminal .bg-246 { + --bg: #949494; +} +.ap-terminal .fg-247 { + --fg: #9e9e9e; +} +.ap-terminal .bg-247 { + --bg: #9e9e9e; +} +.ap-terminal .fg-248 { + --fg: #a8a8a8; +} +.ap-terminal .bg-248 { + --bg: #a8a8a8; +} +.ap-terminal .fg-249 { + --fg: #b2b2b2; +} +.ap-terminal .bg-249 { + --bg: #b2b2b2; +} +.ap-terminal .fg-250 { + --fg: #bcbcbc; +} +.ap-terminal .bg-250 { + --bg: #bcbcbc; +} +.ap-terminal .fg-251 { + --fg: #c6c6c6; +} +.ap-terminal .bg-251 { + --bg: #c6c6c6; +} +.ap-terminal .fg-252 { + --fg: #d0d0d0; +} +.ap-terminal .bg-252 { + --bg: #d0d0d0; +} +.ap-terminal .fg-253 { + --fg: #dadada; +} +.ap-terminal .bg-253 { + --bg: #dadada; +} +.ap-terminal .fg-254 { + --fg: #e4e4e4; +} +.ap-terminal .bg-254 { + --bg: #e4e4e4; +} +.ap-terminal .fg-255 { + --fg: #eeeeee; +} +.ap-terminal .bg-255 { + --bg: #eeeeee; +} +.asciinema-player-theme-asciinema { + --term-color-foreground: #cccccc; + --term-color-background: #121314; + --term-color-0: hsl(0, 0%, 0%); + --term-color-1: hsl(343, 70%, 55%); + --term-color-2: hsl(103, 70%, 44%); + --term-color-3: hsl(43, 70%, 55%); + --term-color-4: hsl(193, 70%, 49.5%); + --term-color-5: hsl(283, 70%, 60.5%); + --term-color-6: hsl(163, 70%, 60.5%); + --term-color-7: hsl(0, 0%, 85%); + --term-color-8: hsl(0, 0%, 30%); + --term-color-9: hsl(343, 70%, 55%); + --term-color-10: hsl(103, 70%, 44%); + --term-color-11: hsl(43, 70%, 55%); + --term-color-12: hsl(193, 70%, 49.5%); + --term-color-13: hsl(283, 70%, 60.5%); + --term-color-14: hsl(163, 70%, 60.5%); + --term-color-15: hsl(0, 0%, 100%); +} +/* + Based on Dracula: https://draculatheme.com + */ +.asciinema-player-theme-dracula { + --term-color-foreground: #f8f8f2; + --term-color-background: #282a36; + --term-color-0: #21222c; + --term-color-1: #ff5555; + --term-color-2: #50fa7b; + --term-color-3: #f1fa8c; + --term-color-4: #bd93f9; + --term-color-5: #ff79c6; + --term-color-6: #8be9fd; + --term-color-7: #f8f8f2; + --term-color-8: #6272a4; + --term-color-9: #ff6e6e; + --term-color-10: #69ff94; + --term-color-11: #ffffa5; + --term-color-12: #d6acff; + --term-color-13: #ff92df; + --term-color-14: #a4ffff; + --term-color-15: #ffffff; +} +/* Based on Monokai from base16 collection - https://github.com/chriskempson/base16 */ +.asciinema-player-theme-monokai { + --term-color-foreground: #f8f8f2; + --term-color-background: #272822; + --term-color-0: #272822; + --term-color-1: #f92672; + --term-color-2: #a6e22e; + --term-color-3: #f4bf75; + --term-color-4: #66d9ef; + --term-color-5: #ae81ff; + --term-color-6: #a1efe4; + --term-color-7: #f8f8f2; + --term-color-8: #75715e; + --term-color-15: #f9f8f5; +} +/* + Based on Nord: https://github.com/arcticicestudio/nord + Via: https://github.com/neilotoole/asciinema-theme-nord + */ +.asciinema-player-theme-nord { + --term-color-foreground: #eceff4; + --term-color-background: #2e3440; + --term-color-0: #3b4252; + --term-color-1: #bf616a; + --term-color-2: #a3be8c; + --term-color-3: #ebcb8b; + --term-color-4: #81a1c1; + --term-color-5: #b48ead; + --term-color-6: #88c0d0; + --term-color-7: #eceff4; +} +.asciinema-player-theme-seti { + --term-color-foreground: #cacecd; + --term-color-background: #111213; + --term-color-0: #323232; + --term-color-1: #c22832; + --term-color-2: #8ec43d; + --term-color-3: #e0c64f; + --term-color-4: #43a5d5; + --term-color-5: #8b57b5; + --term-color-6: #8ec43d; + --term-color-7: #eeeeee; + --term-color-15: #ffffff; +} +/* + Based on Solarized Dark: https://ethanschoonover.com/solarized/ + */ +.asciinema-player-theme-solarized-dark { + --term-color-foreground: #839496; + --term-color-background: #002b36; + --term-color-0: #073642; + --term-color-1: #dc322f; + --term-color-2: #859900; + --term-color-3: #b58900; + --term-color-4: #268bd2; + --term-color-5: #d33682; + --term-color-6: #2aa198; + --term-color-7: #eee8d5; + --term-color-8: #002b36; + --term-color-9: #cb4b16; + --term-color-10: #586e75; + --term-color-11: #657b83; + --term-color-12: #839496; + --term-color-13: #6c71c4; + --term-color-14: #93a1a1; + --term-color-15: #fdf6e3; +} +/* + Based on Solarized Light: https://ethanschoonover.com/solarized/ + */ +.asciinema-player-theme-solarized-light { + --term-color-foreground: #657b83; + --term-color-background: #fdf6e3; + --term-color-0: #073642; + --term-color-1: #dc322f; + --term-color-2: #859900; + --term-color-3: #b58900; + --term-color-4: #268bd2; + --term-color-5: #d33682; + --term-color-6: #2aa198; + --term-color-7: #eee8d5; + --term-color-8: #002b36; + --term-color-9: #cb4b16; + --term-color-10: #586e75; + --term-color-11: #657c83; + --term-color-12: #839496; + --term-color-13: #6c71c4; + --term-color-14: #93a1a1; + --term-color-15: #fdf6e3; +} +.asciinema-player-theme-solarized-light .ap-overlay-start .ap-play-button svg .ap-play-btn-fill { + fill: var(--term-color-1); +} +.asciinema-player-theme-solarized-light .ap-overlay-start .ap-play-button svg .ap-play-btn-stroke { + stroke: var(--term-color-1); +} +/* + Based on Tango: https://en.wikipedia.org/wiki/Tango_Desktop_Project + */ +.asciinema-player-theme-tango { + --term-color-foreground: #cccccc; + --term-color-background: #121314; + --term-color-0: #000000; + --term-color-1: #cc0000; + --term-color-2: #4e9a06; + --term-color-3: #c4a000; + --term-color-4: #3465a4; + --term-color-5: #75507b; + --term-color-6: #06989a; + --term-color-7: #d3d7cf; + --term-color-8: #555753; + --term-color-9: #ef2929; + --term-color-10: #8ae234; + --term-color-11: #fce94f; + --term-color-12: #729fcf; + --term-color-13: #ad7fa8; + --term-color-14: #34e2e2; + --term-color-15: #eeeeec; +} diff --git a/docs/docs/assets/vendor/asciinema-player/asciinema-player.min.js b/docs/docs/assets/vendor/asciinema-player/asciinema-player.min.js new file mode 100644 index 000000000..223f36519 --- /dev/null +++ b/docs/docs/assets/vendor/asciinema-player/asciinema-player.min.js @@ -0,0 +1 @@ +var AsciinemaPlayer=function(A){"use strict";function g(A){return"number"==typeof A?A:"string"==typeof A?A.split(":").reverse().map(parseFloat).reduce(((A,g,I)=>A+g*Math.pow(60,I))):void 0}class I{log(){}debug(){}info(){}warn(){}error(){}}class B{constructor(A,g){this.logger=A,this.prefix=g}log(A){for(var g=arguments.length,I=new Array(g>1?g-1:0),B=1;B1?g-1:0),B=1;B1?g-1:0),B=1;B1?g-1:0),B=1;B1?g-1:0),B=1;B{throw Error("TextDecoder not available")}};"undefined"!=typeof TextDecoder&&i.decode();let t=null;function o(){return null!==t&&0!==t.byteLength||(t=new Uint8Array(Q.memory.buffer)),t}function s(A,g){return A>>>=0,i.decode(o().subarray(A,A+g))}function n(A){V===C.length&&C.push(C.length+1);const g=V;return V=C[g],C[g]=A,g}function r(A){const g=typeof A;if("number"==g||"boolean"==g||null==A)return`${A}`;if("string"==g)return`"${A}"`;if("symbol"==g){const g=A.description;return null==g?"Symbol":`Symbol(${g})`}if("function"==g){const g=A.name;return"string"==typeof g&&g.length>0?`Function(${g})`:"Function"}if(Array.isArray(A)){const g=A.length;let I="[";g>0&&(I+=r(A[0]));for(let B=1;B1))return toString.call(A);if(B=I[1],"Object"==B)try{return"Object("+JSON.stringify(A)+")"}catch(A){return"Object"}return A instanceof Error?`${A.name}: ${A.message}\n${A.stack}`:B}let a=0;const c="undefined"!=typeof TextEncoder?new TextEncoder("utf-8"):{encode:()=>{throw Error("TextEncoder not available")}},D="function"==typeof c.encodeInto?function(A,g){return c.encodeInto(A,g)}:function(A,g){const I=c.encode(A);return g.set(I),{read:A.length,written:I.length}};function w(A,g,I){if(void 0===I){const I=c.encode(A),B=g(I.length,1)>>>0;return o().subarray(B,B+I.length).set(I),a=I.length,B}let B=A.length,Q=g(B,1)>>>0;const C=o();let E=0;for(;E127)break;C[Q+E]=g}if(E!==B){0!==E&&(A=A.slice(E)),Q=I(Q,B,B=E+3*A.length,1)>>>0;const g=o().subarray(Q+E,Q+B);E+=D(A,g).written,Q=I(Q,B,E,1)>>>0}return a=E,Q}let h=null;function l(){return null!==h&&0!==h.byteLength||(h=new Int32Array(Q.memory.buffer)),h}let y=null;function k(A,g){return A>>>=0,(null!==y&&0!==y.byteLength||(y=new Uint32Array(Q.memory.buffer)),y).subarray(A/4,A/4+g)}const G="undefined"==typeof FinalizationRegistry?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry((A=>Q.__wbg_vt_free(A>>>0)));class F{static __wrap(A){A>>>=0;const g=Object.create(F.prototype);return g.__wbg_ptr=A,G.register(g,g.__wbg_ptr,g),g}__destroy_into_raw(){const A=this.__wbg_ptr;return this.__wbg_ptr=0,G.unregister(this),A}free(){const A=this.__destroy_into_raw();Q.__wbg_vt_free(A)}feed(A){const g=w(A,Q.__wbindgen_malloc,Q.__wbindgen_realloc),I=a;return e(Q.vt_feed(this.__wbg_ptr,g,I))}resize(A,g){return e(Q.vt_resize(this.__wbg_ptr,A,g))}inspect(){let A,g;try{const C=Q.__wbindgen_add_to_stack_pointer(-16);Q.vt_inspect(C,this.__wbg_ptr);var I=l()[C/4+0],B=l()[C/4+1];return A=I,g=B,s(I,B)}finally{Q.__wbindgen_add_to_stack_pointer(16),Q.__wbindgen_free(A,g,1)}}getSize(){try{const B=Q.__wbindgen_add_to_stack_pointer(-16);Q.vt_getSize(B,this.__wbg_ptr);var A=l()[B/4+0],g=l()[B/4+1],I=k(A,g).slice();return Q.__wbindgen_free(A,4*g,4),I}finally{Q.__wbindgen_add_to_stack_pointer(16)}}getLine(A){return e(Q.vt_getLine(this.__wbg_ptr,A))}getCursor(){return e(Q.vt_getCursor(this.__wbg_ptr))}}function q(){const A={wbg:{}};return A.wbg.__wbindgen_object_drop_ref=function(A){e(A)},A.wbg.__wbindgen_error_new=function(A,g){return n(new Error(s(A,g)))},A.wbg.__wbindgen_object_clone_ref=function(A){return n(E(A))},A.wbg.__wbindgen_number_new=function(A){return n(A)},A.wbg.__wbindgen_bigint_from_u64=function(A){return n(BigInt.asUintN(64,A))},A.wbg.__wbindgen_string_new=function(A,g){return n(s(A,g))},A.wbg.__wbg_set_f975102236d3c502=function(A,g,I){E(A)[e(g)]=e(I)},A.wbg.__wbg_new_b525de17f44a8943=function(){return n(new Array)},A.wbg.__wbg_new_f841cc6f2098f4b5=function(){return n(new Map)},A.wbg.__wbg_new_f9876326328f45ed=function(){return n(new Object)},A.wbg.__wbindgen_is_string=function(A){return"string"==typeof E(A)},A.wbg.__wbg_set_17224bc548dd1d7b=function(A,g,I){E(A)[g>>>0]=e(I)},A.wbg.__wbg_set_388c4c6422704173=function(A,g,I){return n(E(A).set(E(g),E(I)))},A.wbg.__wbindgen_debug_string=function(A,g){const I=w(r(E(g)),Q.__wbindgen_malloc,Q.__wbindgen_realloc),B=a;l()[A/4+1]=B,l()[A/4+0]=I},A.wbg.__wbindgen_throw=function(A,g){throw new Error(s(A,g))},A}function d(A,g){return Q=A.exports,M.__wbindgen_wasm_module=g,h=null,y=null,t=null,Q}async function M(A){if(void 0!==Q)return Q;const g=q();("string"==typeof A||"function"==typeof Request&&A instanceof Request||"function"==typeof URL&&A instanceof URL)&&(A=fetch(A));const{instance:I,module:B}=await async function(A,g){if("function"==typeof Response&&A instanceof Response){if("function"==typeof WebAssembly.instantiateStreaming)try{return await WebAssembly.instantiateStreaming(A,g)}catch(g){if("application/wasm"==A.headers.get("Content-Type"))throw g;console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",g)}const I=await A.arrayBuffer();return await WebAssembly.instantiate(I,g)}{const I=await WebAssembly.instantiate(A,g);return I instanceof WebAssembly.Instance?{instance:I,module:A}:I}}(await A,g);return d(I,B)}var N=Object.freeze({__proto__:null,Vt:F,create:function(A,g,I){const B=Q.create(A,g,I);return F.__wrap(B)},default:M,initSync:function(A){if(void 0!==Q)return Q;const g=q();return A instanceof WebAssembly.Module||(A=new WebAssembly.Module(A)),d(new WebAssembly.Instance(A,g),A)}});const f=[62,0,0,0,63,52,53,54,55,56,57,58,59,60,61,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];function u(A){return f[A-43]}const R=function(A){let g,I=A.endsWith("==")?2:A.endsWith("=")?1:0,B=A.length,Q=new Uint8Array(B/4*3);for(let I=0,C=0;I>16,Q[C+1]=g>>8&255,Q[C+2]=255&g;return Q.subarray(0,Q.length-I)}("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QQhrIgAgA08NAQwDCyAHQQhrIQALA0AgBkEEaigCACIJQYqUqNAAc0GBgoQIayAJQX9zcSAGKAIAIglBipSo0ABzQYGChAhrIAlBf3NxckGAgYKEeHENAiAGQQhqIQYgACADQQhqIgNPDQALDAELIAIgBEYEQCACIQQMBAtBACEAA0AgACAFai0AAEEKRg0CIAcgAEEBaiIARw0ACyACIQQMAwsgAyAHRgRAIAIhBAwDCwNAIAMgBWotAABBCkYEQCADIQAMAgsgByADQQFqIgNHDQALIAIhBAwCCyAAIARqIgZBAWohBAJAIAIgBk0NACAAIAVqLQAAQQpHDQBBACEFIAQiBiEADAMLIAIgBE8NAAsLQQEhBSACIgAgCCIGRw0AQQAPCwJAIAwtAABFDQAgC0H49MAAQQQgCigCDBEBAEUNAEEBDwsgACAIayEHQQAhAyAAIAhHBEAgACANai0AAEEKRiEDCyABIAhqIQAgDCADOgAAIAYhCCALIAAgByAKKAIMEQEAIgAgBXJFDQALIAAL0gYBBX8jAEHAAWsiAiQAIAAoAgAhAyACQbgBakGojMAANgIAIAJBBGoiAEGsAWpBxJDAADYCACAAQaQBakG0kMAANgIAIABBnAFqQbSQwAA2AgAgAkGYAWpBmI7AADYCACACQZABakGYjsAANgIAIAJBiAFqQaSPwAA2AgAgAkGAAWpBpJDAADYCACAAQfQAakGkj8AANgIAIAJB8ABqQaSPwAA2AgAgAkHoAGpBpI/AADYCACAAQdwAakGkj8AANgIAIAJB2ABqQZSQwAA2AgAgAkHQAGpBmI7AADYCACACQcgAakGEkMAANgIAIAJBQGtBiI/AADYCACACQThqQfSPwAA2AgAgAkEwakHkj8AANgIAIABBJGpB1I/AADYCACACQSBqQcSPwAA2AgAgAkEYakHEj8AANgIAIAJBEGpBmI7AADYCACACIANB3ABqNgKsASACIANBiAFqNgKkASACIANB9ABqNgKcASACIANBrAFqNgKUASACIANBqAFqNgKMASACIANBwgFqNgKEASACIANBwQFqNgJ8IAIgA0HAAWo2AnQgAiADQb8BajYCbCACIANBvgFqNgJkIAIgA0G9AWo2AlwgAiADQdAAajYCVCACIANBpAFqNgJMIAIgA0GwAWo2AkQgAiADQbIB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amohAiADQSBqIQMgCCAHQQRqIgdHDQALCyAGBEAgB0EDdCAFakEEaiEDA0AgAygCACACaiECIANBCGohAyAGQQFrIgYNAAsLIAEoAgwEQCACQQBIDQEgBSgCBEUgAkEQSXENASACQQF0IQILIAINAQtBASEDQQAhAgwBCyACQQBIDQFBqYzBAC0AABogAkEBENcBIgNFDQILIARBADYCCCAEIAM2AgQgBCACNgIAIARBhO/AACABEBhFDQJB5O/AAEEzIARBD2pBmPDAAEHA8MAAEF0ACxCpAQALQQEgAkHkjMEAKAIAIgBB5AAgABsRAgAACyAAIAQpAgA3AgAgAEEIaiAEQQhqKAIANgIAIARBEGokAAvVAgEHf0EBIQkCQAJAIAJFDQAgASACQQF0aiEKIABBgP4DcUEIdiELIABB/wFxIQ0DQCABQQJqIQwgByABLQABIgJqIQggCyABLQAAIgFHBEAgASALSw0CIAghByAKIAwiAUYNAgwBCwJAAkAgByAITQRAIAQgCEkNASADIAdqIQEDQCACRQ0DIAJBAWshAiABLQAAIAFBAWohASANRw0AC0EAIQkMBQsgByAIQbj5wAAQ7AEACyAIIARBuPnAABDqAQALIAghByAKIAwiAUcNAAsLIAZFDQAgBSAGaiEDIABB//8DcSEBA0AgBUEBaiEAAkAgBS0AACICwCIEQQBOBEAgACEFDAELIAAgA0cEQCAFLQABIARB/wBxQQh0ciECIAVBAmohBQwBC0Go+cAAEO4BAAsgASACayIBQQBIDQEgCUEBcyEJIAMgBUcNAAsLIAlBAXEL8wIBBH8gACgCDCECAkACQCABQYACTwRAIAAoAhghAwJAAkAgACACRgRAIABBFEEQIAAoAhQiAhtqKAIAIgENAUEAIQIMAgsgACgCCCIBIAI2AgwgAiABNgIIDAELIABBFGogAEEQaiACGyEEA0AgBCEFIAEiAigCFCEBIAJBFGogAkEQaiABGyEEIAJBFEEQIAEbaigCACIBDQALIAVBADYCAAsgA0UNAiAAIAAoAhxBAnRB+IzBAGoiASgCAEcEQCADQRBBFCADKAIQIABGG2ogAjYCACACRQ0DDAILIAEgAjYCACACDQFBlJDBAEGUkMEAKAIAQX4gACgCHHdxNgIADAILIAIgACgCCCIARwRAIAAgAjYC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IhEoAgAhDyARIAwoAgA2AgAgDCAPNgIAIAVBBGoiBUEkRw0ACyALQQxqIAMoApwBIAMoAqABIgVBAUEAIANBsgFqECsgA0EMahCKASADKAIMIgwEQCADKAIQIAxBBHRBBBDkAQsgAyALQQxqQSQQiAJB3ABqQQAgBRB4CyALQTBqJAAgAxBCCyACQQJqIQIgB0ECayIHDQALCyANBEAgBCANQQF0QQIQ5AELDCALAkAgAi8BAiIEQQEgBEEBSxtBAWsiBCACLwEEIgIgAygCoAEiBSACG0EBayICSSACIAVJcUUEQCADKAKoASEEDAELIAMgAjYCrAEgAyAENgKoAQsgA0EAOgDCASADQQA2AmggAyAEQQAgAy0AvgEbNgJsDB8LIANBAToAcCADQQA7AL0BIANBADsBugEgA0ECOgC2ASADQQI6ALIBIANBADsBsAEgA0IANwKkASADQYCAgAg2AoQBIANBAjoAgAEgA0ECOgB8IANCADcCdCADIAMoAqABQQFrNgKsAQweCyADKAKgASADKAKsASIEQQFqIAQgAygCbCIESRshBSADIAQgBSACLwECIgJBASACQQFLGyADQbIBahAiIANB3ABqIAQgBRB4DB0LIAMgAygCaCADKAJsIgRBACACLwECIgJBASACQQFLGyADQbIBahAoIAQgAygCZCICTw0dIAMoAmAgBGpBAToAAAwcCwJAAkACQAJAIAItAAFBAWsOAwECAwALIAMgAygCaCADKAJsQQEgAyADQbIBahAoIANB3ABqIAMoAmwgAygCoAEQeAwCCyADIAMoAmggAygCbEECIAMgA0GyAWoQKCADQdwAakEAIAMoAmxBAWoQeAwBCyADQQAgAygCHCADQbIBahBLIANB3ABqQQAgAygCoAEQeAsMGwsgAyADKAJoIAMoAmwiBCACLQABQQRqIAMgA0GyAWoQKCAEIAMoAmQiAk8NGyADKAJgIARqQQE6AAAMGgsgAyACLQABOgCxAQwZCyADIAItAAE6ALABDBgLIAMoAlhBAnQhAiADKAJUIQUgAygCaCEHAkACQANAIAJFDQEgAkEEayECIAUoAgAhBCAFQQRqIQUgBCAHTQ0ACyADKAKcASICQQFrIQUMAQsgAygCnAEiAkEBayIFIQQLIANBADoAwgEgAyAEIAUgAiAESxs2AmgMFwsg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+gA2AiggACAAQSRqNgIUIAAgAEEvajYCJCAAQQxqQeCXwAAQpAEACyATQRBqJAAgAAvGAQECfyMAQRBrIgAkACABKAIUQbDswABBCyABKAIYKAIMEQEAIQMgAEEIaiICQQA6AAUgAiADOgAEIAIgATYCACACIgEtAAQhAwJAIAItAAVFBEAgA0EARyEBDAELQQEhAiADRQRAIAEoAgAiAi0AHEEEcUUEQCABIAIoAhRBh/XAAEECIAIoAhgoAgwRAQAiAToABAwCCyACKAIUQYb1wABBASACKAIYKAIMEQEAIQILIAEgAjoABCACIQELIABBEGokACABCzIBAX8gAEEQahAwAkAgACgCACIBQYCAgIB4Rg0AIAFFDQAgACgCBCABQQR0QQQQ5AELCy8BAn8gACAAKAKoASICIAAoAqwBQQFqIgMgASAAQbIBahBZIABB3ABqIAIgAxB4Cy8BAn8gACAAKAKoASICIAAoAqwBQQFqIgMgASAAQbIBahAiIABB3ABqIAIgAxB4CysAIAEgAkkEQEHcosAAQSNBzKPAABCcAQALIAIgACACQQR0aiABIAJrEBILJQAgAEEBNgIEIAAgASgCBCABKAIAa0EEdiIBNgIIIAAgATYCAAslACAARQRAQfCXwABBMhD7AQALIAAgAiADIAQgBSABKAIQEQgACzAAIAEoAhQgAC0AAEECdCIAQYyFwABqKAIAIABB1ITAAGooAgAgASgCGCgCDBEBAAswACABKAIUIAAtAABBAnQiAEGEi8AAaigCACAAQfiKwABqKAIAIAEoAhgoAgwRAQALMAAgASgCFCAALQAAQQJ0IgBB2JTAAGooAgAgAEHMlMAAaigCACABKAIYKAIMEQEACyMAIABFBEBB8JfAAEEyEPsBAAsgACACIAMgBCABKAIQEQUACyMAIABFBEBB8JfAAEEyEPsBAAsgACACIAMgBCABKAIQERgACyMAIABFBEBB8JfAAEEyEPsBAAsgACACIAMgBCABKAIQERoACyMAIABFBEBB8JfAAEEyEPsBAAsgACACIAMgBCABKAIQERwACyMAIABFBEBB8JfAAEEyEPsBAAsgACACIAMgBCABKAIQEQwACygBAX8gACgCACIBQYCAgIB4ckGAgICAeEcEQCAAKAIEIAFBARDkAQsLLgAgASgCFEH8icAAQfeJ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iPjAADYCCCADQgI3AhQgA0HjADYCJCADIANBIGo2AhAgAyADQQRqNgIoIAMgAzYCICADQQhqIAIQpAEACwsAIAA1AgAgARAkC2wBAX8jAEEwayIDJAAgAyABNgIEIAMgADYCACADQSxqQeMANgIAIANBAjYCDCADQbz4wAA2AgggA0ICNwIUIANB4wA2AiQgAyADQSBqNgIQIAMgA0EEajYCKCADIAM2AiAgA0EIaiACEKQBAAsLACAAMQAAIAEQJAsPAEGt8sAAQSsgABCcAQALCwAgACkDACABECQLCwAgACMAaiQAIwALDAAgACgCACABEMMBCwsAIAAoAgAgARAnCwcAIAAQyQELBwAgABDBAQsZACABKAIUQcyHwABBBSABKAIYKAIMEQEAC5cBAQF/IAAoAgAhAiMAQUBqIgAkACAAQgA3AzggAEE4aiACKAIAEA0gACAAKAI8IgI2AjQgACAAKAI4NgIwIAAgAjYCLCAAQd8ANgIoIABBAjYCECAAQcznwAA2AgwgAEIBNwIYIAAgAEEsaiICNgIkIAAgAEEkajYCFCABKAIUIAEoAhggAEEMahAYIAIQyQEgAEFAayQAC6IBAQR/QQIhAyMAQRBrIgIkACABKAIUQazywABBASABKAIYKAIMEQEAIQUgAkEEaiIEQQA6AAUgBCAFOgAEIAQgATYCAANAIAIgADYCDCACQQRqIAJBDGpByIzAABAsIABBAWohACADQQFrIgMNAAsgAkEEaiIALQAEBH9BAQUgACgCACIAKAIUQY71wABBASAAKAIYKAIMEQEACyACQRBqJAALowEBA38jAEEQayICJAAgASgCFEGs8sAAQQEgASgCGCgCDBEBACEEIAJBBGoiA0EAOgAFIAMgBDoABCADIAE2AgBBgAQhAQNAIAIgADYCDCACQQRqIAJBDGpBuIzAABAsIABBEGohACABQRBrIgENAAsgAkEEaiIALQAEBH9BAQUgACgCACIAKAIUQY71wABBASAAKAIYKAIMEQEACyACQRBqJAALBwAgABDCAQsMACAAEIoBIAAQwQELCQAgACABEA4ACw0AQeTowABBGxD7AQALDgBB/+jAAEHPABD7AQALDQAgAEHY6sAAIAEQGAsNACAAQfDqwAAgARAYCw0AIABBhO/AACABEBgLGQAgASgCFEH87sAAQQUgASgCGCgCDBEBAAuGBAEFfyMAQRBrIgMkAAJAAn8CQCABQYABTwRAIANBADYCDCABQYAQSQ0BIAFBgIAESQRAIAMgAUE/cUGAAXI6AA4gAyABQQx2QeABcjoADCADIAFBBnZBP3FBgAFyOgANQQMMAwsgAyABQT9xQYABcjoADyADIAFBBnZBP3FBgAFyOgAOIAMgAUEMdkE/cUGAAXI6AA0gAyABQRJ2QQdxQfABcjoADEEEDAILIAAoAggiAiAAKAIARgRAIwBBIGsiBCQAAkACQCACQQFqIgJFDQAgACgCACIFQQF0IgYgAiACIAZJGyICQQggAkEISxsiAkF/c0EfdiEGIAQgBQR/IAQgBTYCHCAEIAAoAgQ2AhRBAQVBAAs2AhggBEEIaiAGIAIgBEEUahBEIAQoAggEQCAEKAIMIgBFDQEgACAEKAIQQeSMwQAoAgAiAEHkACAAGxECAAALIAQoAgwhBSAAIAI2AgAgACAFNgIEIARBIGokAAwBCxCpAQALIAAoAgghAgsgACACQQFqNgIIIAAoAgQgAmogAToAAAwCCyADIAFBP3FBgAFyOgANIAMgAUEGdkHAAXI6AAxBAgshASABIAAoAgAgACgCCCICa0sEQCAAIAIgARA+IAAoAgghAgsgACgCBCACaiADQQxqIAEQiAIaIAAgASACajYCCAsgA0EQaiQAQQALDQAgAEHg9MAAIAEQGAsKACACIAAgARATC8ECAQN/IAAoAgAhACMAQYABayIEJAACfwJAAkAgASgCHCICQRBxRQRAIAJBIHENASAANQIAIAEQJAwDCyAAKAIAIQJBACEAA0AgACAEakH/AGogAkEPcSIDQTByIANB1wBqIANBCkkbOgAAIABBAWshACACQRBJIAJBBHYhAkUNAAsMAQsgACgCACECQQAhAANAIAAgBGpB/wBqIAJBD3EiA0EwciADQTdqIANBCkkbOgAAIABBAWshACACQRBJIAJBBHYhAkUNAAsgAEGAAWoiAkGBAU8EQCACQYABQaz1wAAQ6QEACyABQbz1wABBAiAAIARqQYABakEAIABrEBUMAQsgAEGAAWoiAkGBAU8EQCACQYABQaz1wAAQ6QEACyABQbz1wABBAiAAIARqQYABakEAIABrEBULIARBgAFqJAALkQUBB38CQAJ/AkAgAiIEIAAgAWtL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AIYIEAAIAAAAjggQAA4AAACcCBAABAAAAKAIEAALAAAAmAcQAAsAAAC0BxAADgAAAKsIEAANAAAAuAgQABAAAADICBAAEAAAANgIEAAKAAAA4ggQAA0AAADvCBAACQAAAPgIEAATAAAACwkQAAsAAAAWCRAACAAAAFByaW1hcnlBbHRlcm5hdGVBcHBsaWNhdGlvbkN1cnNvcmNvbHJvd3Zpc2libGVOb25lU29tZQAAJwAAAAQAAAAEAAAAJgAAACcAAAAEAAAABAAAAEMAAABEaXJ0eUxpbmVzAAAnAAAABAAAAAQAAABEAAAABgAAAAQAAAAFAAAAVwcQAF0HEABhBxAAY2Fubm90IGFjY2VzcyBhIFRocmVhZCBMb2NhbCBTdG9yYWdlIHZhbHVlIGR1cmluZyBvciBhZnRlciBkZXN0cnVjdGlvbgAARgAAAAAAAAABAAAARwAAAC9ydXN0Yy85YjAwOTU2ZTU2MDA5YmFiMmFhMTVkN2JmZjEwOTE2NTk5ZTNkNmQ2L2xpYnJhcnkvc3RkL3NyYy90aHJlYWQvbG9jYWwucnMAvAoQAE8AAAAEAQAAGgAAAAAAAAD//////////yALEABBuJbAAAvZFiBjYW4ndCBiZSByZXByZXNlbnRlZCBhcyBhIEphdmFTY3JpcHQgbnVtYmVyHAsQAAAAAAA4CxAALAAAAEgAAAAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tNmYxN2QyMmJiYTE1MDAxZi9zZXJkZS13YXNtLWJpbmRnZW4tMC42LjUvc3JjL2xpYi5ycwAAAHgLEABlAAAANQAAAA4AAABjbG9zdXJlIGludm9rZWQgcmVjdXJzaXZlbHkgb3IgYWZ0ZXIgYmVpbmcgZHJvcHBlZC9ydXN0Yy85YjAwOTU2ZTU2MDA5YmFiMmFhMTVkN2JmZjEwOTE2NTk5ZTNkNmQ2L2xpYnJhcnkvYWxsb2Mvc3JjL3ZlYy9tb2QucnMAACIMEABMAAAAYAgAACQAAAAiDBAATAAAABoGAAAVAAAAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTZmMTdkMjJiYmExNTAwMWYvYXZ0LTAuMTUuMC9zcmMvcGFyc2VyLnJzAACQDBAAWgAAAMYBAAAiAAAAkAwQAFoAAADaAQAADQAAAJAMEABaAAAA3AEAAA0AAACQDBAAWgAAAE0CAAAmAAAAkAwQAFoAAABSAgAAJgAAAJAMEABaAAAAWAIAABgAAACQDBAAWgAAAHACAAATAAAAkAwQAFoAAAB0AgAAEwAAAJAMEABaAAAABQMAACcAAACQDBAAWgAAAAsDAAAnAAAAkAwQAFoAAAARAwAAJwAAAJAMEABaAAAAFwMAACcAAACQDBAAWgAAAB0DAAAnAAAAkAwQAFoAAAAjAwAAJwAAAJAMEABaAAAAKQMAACcAAACQDBAAWgAAAC8DAAAnAAAAkAwQAFoAAAA1AwAAJwAAAJAMEABaAAAAOwMAACcAAACQDBAAWgAAAEEDAAAnAAAAkAwQAFoAAABHAwAAJwAAAJAMEABaAAAATQMAACcAAACQDBAAWgAAAFMDAAAnAAAAkAwQAFoAAABuAwAAKwAAAJAMEABaAAAAewMAAC8AAACQDBAAWgAAAIcDAAAvAAAAkAwQAFoAAACMAwAAKwAAAJAMEABaAAAAkQMAACcAAACQDBAAWgAAAK0DAAArAAAAkAwQAFoAAAC6AwAALwAAAJAMEABaAAAAxgMAAC8AAACQDBAAWgAAAMsDAAArAAAAkAwQAFoAAADQAwAAJwAAAJAMEABaAAAA3gMAACcAAACQDBAAWgAAANcDAAAnAAAAkAwQAFoAAACYAwAAJwAAAJAMEABaAAAAWgMAACcAAACQDBAAWgAAAGADAAAnAAAAkAwQAFoAAACfAwAAJwAAAJAMEABaAAAAZwMAACcAAACQDBAAWgAAAKYDAAAnAAAAkAwQAFoAAADkAwAAJwAAAJAMEABaAAAADgQAABMAAACQDBAAWgAAABcEAAAbAAAAkAwQAFoAAAAgBAAAFAAAAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby02ZjE3ZDIyYmJhMTUwMDFmL2F2dC0wLjE1LjAvc3JjL3RhYnMucnOsDxAAWAAAABcAAAAUAAAAVQAAAAAAAAABAAAAVgAAAFcAAABYAAAAWQAAAFoAAAAUAAAABAAAAFsAAABcAAAAXQAAAF4AAAAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tNmYxN2QyMmJiYTE1MDAxZi9hdnQtMC4xNS4wL3NyYy90ZXJtaW5hbC5yc0wQEABcAAAAeQIAABUAAABMEBAAXAAAAK0CAAAOAAAATBAQAFwAAADyAwAAIwAAAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby02ZjE3ZDIyYmJhMTUwMDFmL3VuaWNvZGUtd2lkdGgtMC4xLjE0L3NyYy90YWJsZXMucnPYEBAAZAAAAJEAAAAVAAAA2BAQAGQAAACXAAAAGQAAAGFzc2VydGlvbiBmYWlsZWQ6IG1pZCA8PSBzZWxmLmxlbigpL3J1c3RjLzliMDA5NTZlNTYwMDliYWIyYWExNWQ3YmZmMTA5MTY1OTllM2Q2ZDYvbGlicmFyeS9jb3JlL3NyYy9zbGljZS9tb2QucnN/ERAATQAAAFINAAAJAAAAYXNzZXJ0aW9uIGZhaWxlZDogayA8PSBzZWxmLmxlbigpAAAAfxEQAE0AAAB9DQAACQAAAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby02ZjE3ZDIyYmJhMTUwMDFmL2F2dC0wLjE1LjAvc3JjL2J1ZmZlci5ycwAAEBIQAFoAAABaAAAADQAAABASEABaAAAAXgAAAA0AAAAQEhAAWgAAAGMAAAANAAAAEBIQAFoAAABoAAAAHQAAABASEABaAAAAdQAAACUAAAAQEhAAWgAAAH8AAAAlAAAAEBIQAFoAAACHAAAAFQAAABASEABaAAAAkQAAACUAAAAQEhAAWgAAAJgAAAAVAAAAEBIQAFoAAACdAAAAJQAAABASEABaAAAAqAAAABEAAAAQEhAAWgAAALcAAAARAAAAEBIQAFoAAAC5AAAAEQAAABASEABaAAAAwwAAAA0AAAAQEhAAWgAAAMcAAAARAAAAEBIQAFoAAADKAAAADQAAABASEABaAAAA9AAAACsAAAAQEhAAWgAAADkBAAAsAAAAEBIQAFoAAAAyAQAAGwAAABASEABaAAAARQEAABQAAAAQEhAAWgAAAFcBAAAYAAAAEBIQAFoAAABcAQAAGAAAAGFzc2VydGlvbiBmYWlsZWQ6IGxpbmVzLml0ZXIoKS5hbGwofGx8IGwubGVuKCkgPT0gY29scykAEBIQAFoAAADJAQAABQAAAGFzc2VydGlvbiBmYWlsZWQ6IG1pZCA8PSBzZWxmLmxlbigpL3J1c3RjLzliMDA5NTZlNTYwMDliYWIyYWExNWQ3YmZmMTA5MTY1OTllM2Q2ZDYvbGlicmFyeS9jb3JlL3NyYy9zbGljZS9tb2QucnM3FBAATQAAAFINAAAJAAAAYXNzZXJ0aW9uIGZhaWxlZDogayA8PSBzZWxmLmxlbigpAAAANxQQAE0AAAB9DQAACQAAAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby02ZjE3ZDIyYmJhMTUwMDFmL2F2dC0wLjE1LjAvc3JjL2xpbmUucnPIFBAAWAAAABQAAAATAAAAyBQQAFgAAAAYAAAAEwAAAMgUEABYAAAAHAAAABMAAADIFBAAWAAAAB0AAAATAAAAyBQQAFgAAAAhAAAAEwAAAMgUEABYAAAAIwAAABMAAADIFBAAWAAAADgAAAAlAAAAZiYAAJIlAAAJJAAADCQAAA0kAAAKJAAAsAAAALEAAAAkJAAACyQAABglAAAQJQAADCUAABQlAAA8JQAAuiMAALsjAAAAJQAAvCMAAL0jAAAcJQAAJCUAADQlAAAsJQAAAiUAAGQiAABlIgAAwAMAAGAiAACjAAAAxSIAAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby02ZjE3ZDIyYmJhMTUwMDFmL2F2dC0wLjE1LjAvc3JjL3Rlcm1pbmFsL2RpcnR5X2xpbmVzLnJzDBYQAGgAAAAMAAAADwAAAAwWEABoAAAAEAAAAA8AQYGuwAALhwEBAgMDBAUGBwgJCgsMDQ4DAwMDAwMDDwMDAwMDAwMPCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkQCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkAQYGwwAALnwsBAgICAgMCAgQCBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHQICHgICAgICAgIfICEiIwIkJSYnKCkCKgICAgIrLAICAgItLgICAi8wMTIzAgICAgICNAICNTY3Ajg5Ojs8PT4/OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5QDk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTlBAgJCQwICREVGR0hJAko5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTlLAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICOTk5OUwCAgICAk1OT1ACAgJRAlJTAgICAgICAgICAgICAlRVAgJWAlcCAlhZWltcXV5fYGECYmMCZGVmZwJoAmlqa2wCAm1ub3ACcXICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0dQICAgICAgJ2dzk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5eDk5OTk5OTk5OXl6AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ7OTl8OTl9AgICAgICAgICAgICAgICAgICAn4CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ/AgICgIGCAgICAgICAgICAgICAgICg4QCAgICAgICAgIChYZ1AgKHAgICiAICAgICAgKJigICAgICAgICAgICAgKLjAKNjgKPkJGSk5SVlgKXAgKYmZqbAgICAgICAgICAjk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OZwdHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHQICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAJ0CAgICnp8CBAIFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdAgIeAgICAgICAh8gISIjAiQlJicoKQIqAgICAqChoqOkpaYup6ipqqusrTMCAgICAgKuAgI1NjcCODk6Ozw9Pq85OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTlMAgICAgKwTk+xhYZ1AgKHAgICiAICAgICAgKJigICAgICAgICAgICAgKLjLKzjgKPkJGSk5SVlgKXAgKYmZqbAgICAgICAgICAlVVdVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBBvLvAAAspVVVVVRUAUFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQEAQe+7wAALxAEQQRBVVVVVVVdVVVVVVVVVVVVRVVUAAEBU9d1VVVVVVVVVVRUAAAAAAFVVVVX8XVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVBQAUABQEUFVVVVVVVVUVUVVVVVVVVVUAAAAAAABAVVVVVVVVVVVV1VdVVVVVVVVVVVVVVQUAAFRVVVVVVVVVVVVVVVVVFQAAVVVRVVVVVVUFEAAAAQFQVVVVVVVVVVVVVQFVVVVVVf////9/VVVVUFUAAFVVVVVVVVVVVVUFAEHAvcAAC5gEQFVVVVVVVVVVVVVVVVVFVAEAVFEBAFVVBVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVEAVRVUVUVVVUFVVVVVVVVRUFVVVVVVVVVVVVVVVVVVVRBFRRQUVVVVVVVVVVQUVVVQVVVVVVVVVVVVVVVVVVVVAEQVFFVVVVVBVVVVVVVBQBRVVVVVVVVVVVVVVVVVVUEAVRVUVUBVVUFVVVVVVVVVUVVVVVVVVVVVVVVVVVVVUVUVVVRVRVVVVVVVVVVVVVVVFRVVVVVVVVVVVVVVVVVBFQFBFBVQVVVBVVVVVVVVVVRVVVVVVVVVVVVVVVVVVUURAUEUFVBVVUFVVVVVVVVVVBVVVVVVVVVVVVVVVVVFUQBVFVBVRVVVQVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVVVRRUFRFUVVVVVVVVVVVVVVVVVVVVVVVVVVVVRAEBVVRUAQFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVEAAFRVVQBAVVVVVVVVVVVVVVVVVVVVVVVVUFVVVVVVVRFRVVVVVVVVVVVVVVVVVQEAAEAABFUBAAABAAAAAAAAAABUVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAQQAQUFVVVVVVVVQBVRVVVUBVFVVRUFVUVVVVVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqoAQYDCwAALkANVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQFVVVVVVVVVVVVVVVUFVFVVVVVVVQVVVVVVVVVVBVVVVVVVVVUFVVVVf//99//911931tXXVRAAUFVFAQAAVVdRVVVVVVVVVVVVVRUAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVBVVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAFVRVRVUBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVxUUVVVVVVVVVVVVVVVVVVVFAEBEAQBUFQAAFFVVVVVVVVVVVVVVVQAAAAAAAABAVVVVVVVVVVVVVVVVAFVVVVVVVVVVVVVVVQAAUAVVVVVVVVVVVVUVAABVVVVQVVVVVVVVVQVQEFBVVVVVVVVVVVVVVVVVRVARUFVVVVVVVVVVVVVVVVVVAAAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAAAAABABUUVVUUFVVVVVVVVVVVVVVVVVVVVVVAEGgxcAAC5MIVVUVAFVVVVVVVQVAVVVVVVVVVVVVVVVVAAAAAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQAAAAAAAAAAVFVVVVVVVVVVVfVVVVVpVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX9V9dVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVfVVVVVVVX1VVVVVVVVVVVVVVVf///1VVVVVVVVVVVVXVVVVVVdVVVVVdVfVVVVVVfVVfVXVVV1VVVVV1VfVddV1VXfVVVVVVVVVVV1VVVVVVVVVVd9XfVVVVVVVVVVVVVVVVVVVV/VVVVVVVVVdVVdVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV1VdVVVVVVVVVVVVVVVVXXVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVUFVVVVVVVVVVVVVVVVVVVf3///////////////9fVdVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAAAAAAAAAACqqqqqqqqaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlVVVaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqWlVVVVVVVaqqqqqqqqqqqqqqqqqqCgCqqqpqqaqqqqqqqqqqqqqqqqqqqqqqqqqqaoGqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqVamqqqqqqqqqqqqqqaqqqqqqqqqqqqqqqqiqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqVVWVqqqqqqqqqqqqqqpqqqqqqqqqqqqqqlVVqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlVVVVVVVVVVVVVVVVVVVVWqqqpWqqqqqqqqqqqqqqqqqmpVVVVVVVVVVVVVVVVVX1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVAAABQVVVVVVVVVQVVVVVVVVVVVVVVVVVVVVVVVVVVVVBVVVVFRRVVVVVVVVVBVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUFVVVVVVVQAAAABQVUUVVVVVVVVVVVVVBQBQVVVVVVUVAABQVVVVqqqqqqqqqlZAVVVVVVVVVVVVVVUVBVBQVVVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVUBQEFBVVUVVVVUVVVVVVVVVVVVVVVUVVVVVVVVVVVVVVVVBBRUBVFVVVVVVVVVVVVVUFVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVRRVVVVVaqqqqqqqqqqqlVVVQAAAAAAQBUAQb/NwAAL4QxVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAAADwqqpaVQAAAACqqqqqqqqqqmqqqqqqaqpVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVqaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqVlVVVVVVVVVVVVVVVVVVBVRVVVVVVVVVVVVVVVVVVVWqalVVAABUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQVAVQFBVQBVVVVVVVVVVVVVQBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUFVVVVVVVXVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVUVVVVVVVVVVVVVVVVVVVVVVVVVQFVVVVVVVVVVVVVVVVVVVVVVQUAAFRVVVVVVVVVVVVVVQVQVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVVVVVVVVVVVVVVVVUAAABAVVVVVVVVVVVVVRRUVRVQVVVVVVVVVVVVVVUVQEFVRVVVVVVVVVVVVVVVVVVVVUBVVVVVVVVVVRUAAQBUVVVVVVVVVVVVVVVVVVUVVVVVUFVVVVVVVVVVVVVVVQUAQAVVARRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVQBFVFUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFRUAQFVVVVVVUFVVVVVVVVVVVVVVVVUVRFRVVVVVFVVVVQUAVABUVVVVVVVVVVVVVVVVVVVVVQAABURVVVVVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVRQARBEEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVBVBVEFRVVVVVVVVQVVVVVVVVVVVVVVVVVVVVVVVVVVUVAEARVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVUQAQVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQEFEABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRUAAEFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVFQQRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAAVVVFVVVVVVVVUBAEBVVVVVVVVVVVUVAARAVRVVVQFAAVVVVVVVVVVVVVUAAAAAQFBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAEAAEFVVVVVVVVVVVVVVVVVVVVVVVVVVBQAAAAAABQAEQVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQFARRAAAFVVVVVVVVVVVVVVVVVVVVVVVVARVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVRVVUBVVVVVVVVVVVVVVVUFQFVEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQVAAAAUFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAFRVVVVVVVVVVVVVVVVVVQBAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVUVQFVVVVVVVVVVVVVVVVVVVVVVVVWqVFVVWlVVVaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlVVqqqqqqqqqqqqqqqqqqqqqqqqqqqqWlVVVVVVVVVVVVWqqlZVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWqqappqqqqqqqqqqpqVVVVZVVVVVVVVVVqWVVVVapVVaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqVVVVVVVVVVVBAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAEGr2sAAC3VQAAAAAABAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVEVAFAAAAAEABAFVVVVVVVVUFUFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQVUVVVVVVVVVVVVVVVVVVUAQa3bwAALAkAVAEG728AAC8UGVFVRVVVVVFVVVVUVAAEAAABVVVVVVVVVVVVVVVVVVVVVVVVVVQBAAAAAABQAEARAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVUAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAQFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBAVVVVVVVVVVVVVVVVVVVXVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVdVVVVVVVVVVVVVVVVVVVVV1/f9/VVVVVVVVVVVVVVVVVVVVVVVV9f///////25VVVWqqrqqqqqq6vq/v1WqqlZVX1VVVapaVVVVVVVV//////////9XVVX9/9////////////////////////f//////1VVVf////////////9/1f9VVVX/////V1f//////////////////////3/3/////////////////////////////////////////////////////////////9f///////////////////9fVVXVf////////1VVVVV1VVVVVVVVfVVVVVdVVVVVVVVVVVVVVVVVVVVVVVVVVdX///////////////////////////9VVVVVVVVVVVVVVVX//////////////////////19VV3/9Vf9VVdVXVf//V1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf///1VXVVVVVVVV//////////////9////f/////////////////////////////////////////////////////////////1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX///9X//9XVf//////////////3/9fVfX///9V//9XVf//V1WqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqWlVVVVVVVVVVWZZVYaqlWapVVVVVVZVVVVVVVVVVlVVVAEGO4sAACwEDAEGc4sAAC4oqVVVVVVWVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVAJZqWlpqqgVAplmVZVVVVVVVVVVVAAAAAFVWVVWpVlVVVVVVVVVVVVZVVVVVVVVVVQAAAAAAAAAAVFVVVZVZWVVVZVVVaVVVVVVVVVVVVVVVlVaVaqqqqlWqqlpVVVVZVaqqqlVVVVVlVVVaVVVVVaVlVlVVVZVVVVVVVVWmlpqWWVllqZaqqmZVqlVaWVVaVmVVVVVqqqWlWlVVVaWqWlVVWVlVVVlVVVVVVZVVVVVVVVVVVVVVVVVVVVVVVVVVVWVV9VVVVWlVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlWqqqqqqqqqqqpVVVWqqqqqpVpVVZqqWlWlpVVaWqWWpVpVVVWlWlWVVVVVfVVpWaVVX1VmVVVVVVVVVVVmVf///1VVVZqaappVVVXVVVVVVdVVVaVdVfVVVVVVvVWvqrqqq6qqmlW6qvquuq5VXfVVVVVVVVVVV1VVVVVZVVVVd9XfVVVVVVVVVaWqqlVVVVVVVdVXVVVVVVVVVVVVVVVVV61aVVVVVVVVVVVVqqqqqqqqqmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqoAAADAqqpaVQAAAACqqqqqqqqqqmqqqqqqaqpVVVVVVVVVVVVVVVUFVFVVVVVVVVVVVVVVVVVVVapqVVUAAFRZqqpqVaqqqqqqqqpaqqqqqqqqqqqqqqqqqqpaVaqqqqqqqqq6/v+/qqqqqlZVVVVVVVVVVVVVVVVV9f///////0pzVmFsdWUoKQAAAMAzEAAIAAAAyDMQAAEAAABUcmllZCB0byBzaHJpbmsgdG8gYSBsYXJnZXIgY2FwYWNpdHncMxAAJAAAAC9ydXN0Yy85YjAwOTU2ZTU2MDA5YmFiMmFhMTVkN2JmZjEwOTE2NTk5ZTNkNmQ2L2xpYnJhcnkvYWxsb2Mvc3JjL3Jhd192ZWMucnMINBAATAAAAOcBAAAJAAAAbnVsbCBwb2ludGVyIHBhc3NlZCB0byBydXN0cmVjdXJzaXZlIHVzZSBvZiBhbiBvYmplY3QgZGV0ZWN0ZWQgd2hpY2ggd291bGQgbGVhZCB0byB1bnNhZmUgYWxpYXNpbmcgaW4gcnVzdAAAVHJpZWQgdG8gc2hyaW5rIHRvIGEgbGFyZ2VyIGNhcGFjaXR50DQQACQAAAAvcnVzdGMvOWIwMDk1NmU1NjAwOWJhYjJhYTE1ZDdiZmYxMDkxNjU5OWUzZDZkNi9saWJyYXJ5L2FsbG9jL3NyYy9yYXdfdmVjLnJz/DQQAEwAAADnAQAACQAAAGAAAAAMAAAABAAAAGEAAABiAAAAEQAAAGUAAAAMAAAABAAAAGYAAABnAAAAaAAAAC9ydXN0L2RlcHMvZGxtYWxsb2MtMC4yLjYvc3JjL2RsbWFsbG9jLnJzYXNzZXJ0aW9uIGZhaWxlZDogcHNpemUgPj0gc2l6ZSArIG1pbl9vdmVyaGVhZACINRAAKQAAAKgEAAAJAAAAYXNzZXJ0aW9uIGZhaWxlZDogcHNpemUgPD0gc2l6ZSArIG1heF9vdmVyaGVhZAAAiDUQACkAAACuBAAADQAAAEFjY2Vzc0Vycm9ybWVtb3J5IGFsbG9jYXRpb24gb2YgIGJ5dGVzIGZhaWxlZAAAADs2EAAVAAAAUDYQAA0AAABsaWJyYXJ5L3N0ZC9zcmMvYWxsb2MucnNwNhAAGAAAAGIBAAAJAAAAbGlicmFyeS9zdGQvc3JjL3Bhbmlja2luZy5yc5g2EAAcAAAAhAIAAB4AAABlAAAADAAAAAQAAABpAAAAagAAAAgAAAAEAAAAawAAAGoAAAAIAAAABAAAAGwAAABtAAAAbgAAABAAAAAEAAAAbwAAAHAAAABxAAAAAAAAAAEAAAByAAAASGFzaCB0YWJsZSBjYXBhY2l0eSBvdmVyZmxvdxw3EAAcAAAAL3J1c3QvZGVwcy9oYXNoYnJvd24tMC4xNC4zL3NyYy9yYXcvbW9kLnJzAABANxAAKgAAAFYAAAAoAAAARXJyb3IAAABzAAAADAAAAAQAAAB0AAAAdQAAAHYAAABjYXBhY2l0eSBvdmVyZmxvdwAAAJw3EAARAAAAbGlicmFyeS9hbGxvYy9zcmMvcmF3X3ZlYy5yc7g3EAAcAAAAGQAAAAUAAABhIGZvcm1hdHRpbmcgdHJhaXQgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3IAdwAAAAAAAAABAAAAeAAAAGxpYnJhcnkvYWxsb2Mvc3JjL2ZtdC5ycyg4EAAY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");class J{constructor(){let A=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;this.speed=A,this.startTime=performance.now()}getTime(){return this.speed*(performance.now()-this.startTime)/1e3}setTime(A){this.startTime=performance.now()-A/this.speed*1e3}}class S{constructor(){}getTime(A){}setTime(A){}}class Y{constructor(A,g){this.input="function"==typeof A.next?A:A[Symbol.iterator](),this.xfs=g??[]}map(A){return this.transform(function(A){return g=>I=>{g(A(I))}}(A))}flatMap(A){return this.transform(function(A){return g=>I=>{A(I).forEach(g)}}(A))}filter(A){return this.transform(function(A){return g=>I=>{A(I)&&g(I)}}(A))}take(A){return this.transform(function(A){let g=0;return I=>B=>{gB=>{g+=1,g>A&&I(B)}}(A))}transform(A){return new Y(this.input,this.xfs.concat([A]))}multiplex(A,g){return new Y(new p(this[Symbol.iterator](),A[Symbol.iterator](),g))}toArray(){return Array.from(this)}[Symbol.iterator](){let A=0,g=[],I=!1;const B=(Q=this.xfs,C=A=>g.push(A),Q.reverse().reduce(((A,g)=>{const I=U(g(A.step));return{step:I.step,flush:()=>{I.flush(),A.flush()}}}),U(C)));var Q,C;return{next:()=>{for(A===g.length&&(g=[],A=0);0===g.length;){const A=this.input.next();if(A.done)break;B.step(A.value)}return 0!==g.length||I||(B.flush(),I=!0),g.length>0?{done:!1,value:g[A++]}:{done:!0}}}}}function U(A){return"function"==typeof A?{step:A,flush:()=>{}}:A}class p{constructor(A,g,I){this.left=A,this.right=g,this.comparator=I}[Symbol.iterator](){let A,g;return{next:()=>{if(void 0===A&&void 0!==this.left){const g=this.left.next();g.done?this.left=void 0:A=g.value}if(void 0===g&&void 0!==this.right){const A=this.right.next();A.done?this.right=void 0:g=A.value}if(void 0===A&&void 0===g)return{done:!0};if(void 0===A){const A=g;return g=void 0,{done:!1,value:A}}if(void 0===g){const g=A;return A=void 0,{done:!1,value:g}}if(this.comparator(A,g)){const g=A;return A=void 0,{done:!1,value:g}}{const A=g;return g=void 0,{done:!1,value:A}}}}}}async function L(A){let g,I;if(A instanceof Response){const B=await A.text(),Q=function(A){const g=A.split("\n");let I;try{I=JSON.parse(g[0])}catch(A){return}const B=new Y(g).drop(1).filter((A=>"["===A[0])).map(JSON.parse).toArray();return{header:I,events:B}}(B);void 0!==Q?(g=Q.header,I=Q.events):g=JSON.parse(B)}else if("object"==typeof A&&"number"==typeof A.version)g=A;else{if(!Array.isArray(A))throw"invalid data";g=A[0],I=A.slice(1,A.length)}if(1===g.version)return function(A){let g=0;const I=new Y(A.stdout).map((A=>(g+=A[0],[g,"o",A[1]])));return{cols:A.width,rows:A.height,events:I}}(g);if(2===g.version)return function(A,g){return{cols:A.width,rows:A.height,theme:m(A.theme),events:g,idleTimeLimit:A.idle_time_limit}}(g,I);throw`asciicast v${g.version} format not supported`}function m(A){const g=/^#[0-9A-Fa-f]{6}$/,I=A?.fg,B=A?.bg,Q=A?.palette;if(g.test(I)&&g.test(B)&&/^(#[0-9A-Fa-f]{6}:){7,}#[0-9A-Fa-f]{6}$/.test(Q))return{foreground:I,background:B,palette:Q.split(":")}}function K(A){return"number"==typeof A?[A,"m",""]:[A[0],"m",A[1]]}function b(){let A=0;return function(g){return"m"===g[1]?[g[0],g[1],{index:A++,time:g[0],label:g[2]}]:g}}class H{constructor(){this.items=[],this.onPush=void 0}push(A){this.items.push(A),void 0!==this.onPush&&(this.onPush(this.popAll()),this.onPush=void 0)}popAll(){if(this.items.length>0){const A=this.items;return this.items=[],A}{const A=this;return new Promise((g=>{A.onPush=g}))}}}function v(A,g,I,B,Q,C,E){const V=function(A,g){return function(I,B){"o"===I?A(B):"r"===I&&g(B.cols,B.rows)}}(g,I);if(0===A)return E.debug("using no buffer"),function(A){return{pushEvent(g){A(g[1],g[2])},pushText(g){A("o",g)},stop(){}}}(V);{let g;return"number"==typeof(A=A??{})?(E.debug(`using fixed time buffer (${A} ms)`),g=g=>A):"function"==typeof A?(E.debug("using custom dynamic buffer"),g=A({logger:E})):(E.debug("using adaptive buffer",A),g=function(A,g){let{logger:I}=A,{minTime:B=25,maxLevel:Q=100,interval:C=50,windowSize:E=20,smoothingFactor:V=.2,minImprovementDuration:e=1e3}=g,i=0,t=a(i),o=[],s=0,n=0,r=null;function a(A){return 0===A?B:C*A}return A=>{if(o.push(A),o.lengthgg>A?g:A))}(o);s=B*V+s*(1-V),n=(B-g)*V+n*(1-V);const C=s+n;if(A>t&&I.debug("buffer underrun",{latency:A,maxJitter:s,jitterRange:n,bufferTime:t}),it)t=a(i+=1),I.debug("jitter increased, raising bufferTime",{latency:A,maxJitter:s,jitterRange:n,bufferTime:t});else if(i>1&&Ce&&(r=performance.now(),t=a(i-=1),I.debug("jitter decreased, lowering bufferTime",{latency:A,maxJitter:s,jitterRange:n,bufferTime:t})),t;return r=null,t}}({logger:E},A)),function(A,g,I,B,Q){let C=arguments.length>5&&void 0!==arguments[5]?arguments[5]:1/60,E=performance.now()-1e3*Q,V=A(0);const e=new H;C*=1e3;let i=-C,t=!1;function o(){return performance.now()-E}return setTimeout((async()=>{for(;!t;){const A=await e.popAll();if(t)return;for(const B of A){const A=1e3*B[0]+V;if(A-i0&&(await T(Q),t))return;I(B[0]),g(B[1],B[2]),i=A}}}),0),{pushEvent(g){let I=o()-1e3*g[0];I<0&&(B.debug(`correcting epoch by ${I} ms`),E+=I,I=0),V=A(I),e.push(g)},pushText(A){e.push([o()/1e3,"o",A])},stop(){t=!0,e.push(void 0)}}}(g,V,B,E,Q??0,C)}}function T(A){return new Promise((g=>{setTimeout(g,A)}))}const O=1e6;function x(A){const g=new TextDecoder,I=new TextDecoder;let B,Q=function(A){const g=(new TextDecoder).decode(A);if("ALiS"!==g)throw"not an ALiS v1 live stream";Q=C};function C(I){const C=new X(new DataView(I)),V=C.getUint8();if(1!==V)throw`expected init (0x01) frame, got ${V}`;let e=C.decodeVarUint();B=e,e/=O;const i=C.decodeVarUint(),t=C.decodeVarUint(),o=C.getUint8();let s;if(8===o){const A=30;s=j(new Uint8Array(I,C.offset,A)),C.forward(A)}else if(16===o){const A=54;s=j(new Uint8Array(I,C.offset,A)),C.forward(A)}else if(0!==o)return A.warn(`alis: unsupported theme format (${o})`),void socket.close();const n=C.decodeVarUint();let r;return n>0&&(r=g.decode(new Uint8Array(I,C.offset,n))),Q=E,{time:e,term:{size:{cols:i,rows:t},theme:s,init:r}}}function E(E){const V=new X(new DataView(E)),e=V.getUint8();if(111===e){const A=V.decodeVarUint();B+=A;const I=V.decodeVarUint(),Q=g.decode(new Uint8Array(E,V.offset,I));return[B/O,"o",Q]}if(105===e){const A=V.decodeVarUint();B+=A;const g=V.decodeVarUint(),Q=I.decode(new Uint8Array(E,V.offset,g));return[B/O,"i",Q]}if(114===e){const A=V.decodeVarUint();B+=A;const g=V.decodeVarUint(),I=V.decodeVarUint();return[B/O,"r",{cols:g,rows:I}]}if(109===e){const A=V.decodeVarUint();B+=A;const g=V.decodeVarUint(),I=(new TextDecoder).decode(new Uint8Array(E,V.offset,g));return[B/O,"m",I]}if(4===e)return Q=C,!1;A.debug(`alis: unknown frame type: ${e}`)}return function(A){return Q(A)}}function j(A){const g=A.length/3,I=Z(A[0],A[1],A[2]),B=Z(A[3],A[4],A[5]),Q=[];for(let I=2;I1&&void 0!==arguments[1]?arguments[1]:0;this.inner=A,this.offset=g}forward(A){this.offset+=A}getUint8(){const A=this.inner.getUint8(this.offset);return this.offset+=1,A}decodeVarUint(){let A=0,g=0,I=this.getUint8();for(;I>127;)I&=127,A+=I<(await M(R),N))();class gA{constructor(A){this.core=A,this.driver=A.driver}onEnter(A){}init(){}play(){}pause(){}togglePlay(){}seek(A){return!1}step(A){}stop(){this.driver.stop()}}class IA extends gA{async init(){try{return await this.core._initializeDriver(),this.core._setState("idle")}catch(A){throw this.core._setState("errored"),A}}async play(){this.core._dispatchEvent("play");const A=await this.init();await A.doPlay()}async togglePlay(){await this.play()}async seek(A){const g=await this.init();return await g.seek(A)}async step(A){const g=await this.init();await g.step(A)}stop(){}}class BA extends gA{onEnter(A){let{reason:g,message:I}=A;this.core._dispatchEvent("idle",{message:I}),"paused"===g&&this.core._dispatchEvent("pause")}async play(){this.core._dispatchEvent("play"),await this.doPlay()}async doPlay(){const A=await this.driver.play();!0===A?this.core._setState("playing"):"function"==typeof A&&(this.core._setState("playing"),this.driver.stop=A)}async togglePlay(){await this.play()}seek(A){return this.driver.seek(A)}step(A){this.driver.step(A)}}class QA extends gA{onEnter(){this.core._dispatchEvent("playing")}pause(){!0===this.driver.pause()&&this.core._setState("idle",{reason:"paused"})}togglePlay(){this.pause()}seek(A){return this.driver.seek(A)}}class CA extends gA{onEnter(){this.core._dispatchEvent("loading")}}class EA extends gA{onEnter(A){let{message:g}=A;this.core._dispatchEvent("offline",{message:g})}}class VA extends gA{onEnter(A){let{message:g}=A;this.core._dispatchEvent("ended",{message:g})}async play(){this.core._dispatchEvent("play"),await this.driver.restart()&&this.core._setState("playing")}async togglePlay(){await this.play()}seek(A){return!0===this.driver.seek(A)&&(this.core._setState("idle"),!0)}}class eA extends gA{onEnter(){this.core._dispatchEvent("errored")}}class iA{constructor(A,I){this.src=A,this.logger=I.logger,this.state=new IA(this),this.stateName="uninitialized",this.driver=null,this.changedLines=new Set,this.cursor=void 0,this.duration=void 0,this.cols=I.cols,this.rows=I.rows,this.speed=I.speed??1,this.loop=I.loop,this.idleTimeLimit=I.idleTimeLimit,this.preload=I.preload,this.startAt=g(I.startAt),this.poster=this._parsePoster(I.poster),this.markers=this._normalizeMarkers(I.markers),this.pauseOnMarkers=I.pauseOnMarkers,this.commandQueue=Promise.resolve(),this.eventHandlers=new Map([["ended",[]],["errored",[]],["idle",[]],["init",[]],["input",[]],["loading",[]],["marker",[]],["offline",[]],["pause",[]],["play",[]],["playing",[]],["reset",[]],["resize",[]],["seeked",[]],["terminalUpdate",[]]])}async init(){this.wasm=await AA;const A=this._feed.bind(this),g=this._now.bind(this),I=this._resetVt.bind(this),B=this._resizeVt.bind(this),Q=this._setState.bind(this),C="npt"===this.poster.type?this.poster.value:void 0;this.driver=function(A){if("function"==typeof A)return A;"string"==typeof A&&(A="ws://"==A.substring(0,5)||"wss://"==A.substring(0,6)?{driver:"websocket",url:A}:"clock:"==A.substring(0,6)?{driver:"clock"}:"random:"==A.substring(0,7)?{driver:"random"}:"benchmark:"==A.substring(0,10)?{driver:"benchmark",url:A.substring(10)}:{driver:"recording",url:A});void 0===A.driver&&(A.driver="recording");if("recording"==A.driver&&(void 0===A.parser&&(A.parser="asciicast"),"string"==typeof A.parser)){if(!oA.has(A.parser))throw`unknown parser: ${A.parser}`;A.parser=oA.get(A.parser)}if(tA.has(A.driver)){const g=tA.get(A.driver);return(I,B)=>g(A,I,B)}throw`unsupported driver: ${JSON.stringify(A)}`}(this.src)({feed:A,onInput:A=>{this._dispatchEvent("input",{data:A})},onMarker:A=>{let{index:g,time:I,label:B}=A;this._dispatchEvent("marker",{index:g,time:I,label:B})},reset:I,resize:B,now:g,setTimeout:(A,g)=>setTimeout(A,g/this.speed),setInterval:(A,g)=>setInterval(A,g/this.speed),setState:Q,logger:this.logger},{cols:this.cols,rows:this.rows,idleTimeLimit:this.idleTimeLimit,startAt:this.startAt,loop:this.loop,posterTime:C,markers:this.markers,pauseOnMarkers:this.pauseOnMarkers}),"function"==typeof this.driver&&(this.driver={play:this.driver}),(this.preload||void 0!==C)&&this._withState((A=>A.init()));const E="text"===this.poster.type?this._renderPoster(this.poster.value):void 0,V={isPausable:!!this.driver.pause,isSeekable:!!this.driver.seek,poster:E};if(void 0===this.driver.init&&(this.driver.init=()=>({})),void 0===this.driver.pause&&(this.driver.pause=()=>{}),void 0===this.driver.seek&&(this.driver.seek=A=>!1),void 0===this.driver.step&&(this.driver.step=A=>{}),void 0===this.driver.stop&&(this.driver.stop=()=>{}),void 0===this.driver.restart&&(this.driver.restart=()=>{}),void 0===this.driver.getCurrentTime){const A=this.driver.play;let g=new S;this.driver.play=()=>(g=new J(this.speed),A()),this.driver.getCurrentTime=()=>g.getTime()}return V}play(){return this._withState((A=>A.play()))}pause(){return this._withState((A=>A.pause()))}togglePlay(){return this._withState((A=>A.togglePlay()))}seek(A){return this._withState((async g=>{await g.seek(A)&&this._dispatchEvent("seeked")}))}step(A){return this._withState((g=>g.step(A)))}stop(){return this._withState((A=>A.stop()))}getChanges(){const A={};if(this.changedLines.size>0){const g=new Map,I=this.vt.rows;for(const A of this.changedLines)A1&&void 0!==arguments[1]?arguments[1]:{};for(const I of this.eventHandlers.get(A))I(g)}_withState(A){return this._enqueueCommand((()=>A(this.state)))}_enqueueCommand(A){return this.commandQueue=this.commandQueue.then(A),this.commandQueue}_setState(A){let g=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(this.stateName===A)return this.state;if(this.stateName=A,"playing"===A)this.state=new QA(this);else if("idle"===A)this.state=new BA(this);else if("loading"===A)this.state=new CA(this);else if("ended"===A)this.state=new VA(this);else if("offline"===A)this.state=new EA(this);else{if("errored"!==A)throw`invalid state: ${A}`;this.state=new eA(this)}return this.state.onEnter(g),this.state}_feed(A){this._doFeed(A),this._dispatchEvent("terminalUpdate")}_doFeed(A){this.vt.feed(A).forEach((A=>this.changedLines.add(A))),this.cursor=void 0}_now(){return performance.now()*this.speed}async _initializeDriver(){const A=await this.driver.init();this.cols=this.cols??A.cols??80,this.rows=this.rows??A.rows??24,this.duration=this.duration??A.duration,this.markers=this._normalizeMarkers(A.markers)??this.markers??[],0===this.cols&&(this.cols=80),0===this.rows&&(this.rows=24),this._initializeVt(this.cols,this.rows);const g=void 0!==A.poster?this._renderPoster(A.poster):void 0;this._dispatchEvent("init",{cols:this.cols,rows:this.rows,duration:this.duration,markers:this.markers,theme:A.theme,poster:g})}_resetVt(A,g){let I=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,B=arguments.length>3&&void 0!==arguments[3]?arguments[3]:void 0;this.cols=A,this.rows=g,this.cursor=void 0,this._initializeVt(A,g),void 0!==I&&""!==I&&this._doFeed(I),this._dispatchEvent("reset",{cols:A,rows:g,theme:B})}_resizeVt(A,g){if(A===this.vt.cols&&g===this.vt.rows)return;this.vt.resize(A,g).forEach((A=>this.changedLines.add(A))),this.cursor=void 0,this.vt.cols=A,this.vt.rows=g,this.logger.debug(`core: vt resize (${A}x${g})`),this._dispatchEvent("resize",{cols:A,rows:g})}_initializeVt(A,g){this.logger.debug(`core: vt init (${A}x${g})`),this.vt=this.wasm.create(A,g,!0,100),this.vt.cols=A,this.vt.rows=g,this.changedLines.clear();for(let A=0;AB.feed(A)));const Q=B.getCursor()??!1,C=[];for(let A=0;A"number"==typeof A?[A,""]:A))}}const tA=new Map([["benchmark",function(A,g){let I,{url:B,iterations:Q=10}=A,{feed:C,setState:E,now:V}=g,e=0;return{async init(){const A=await L(await fetch(B)),{cols:g,rows:Q,events:C}=A;I=Array.from(C).filter((A=>{let[g,I,B]=A;return"o"===I})).map((A=>{let[g,I,B]=A;return[g,B]}));const E=I[I.length-1][0];for(const[A,g]of I)e+=new Blob([g]).size;return{cols:g,rows:Q,duration:E}},play(){const A=V();for(let A=0;A{E("stopped",{reason:"ended"})}),0),!0}}}],["clock",function(A,g,I){let{hourColor:B=3,minuteColor:Q=4,separatorColor:C=9}=A,{feed:E}=g,{cols:V=5,rows:e=1}=I;const i=Math.floor(e/2),t=Math.floor(V/2)-2,o=`[?25l[${i}B`;let s;const n=()=>{const A=new Date,g=A.getHours(),I=A.getMinutes(),E=[];E.push("\r");for(let A=0;A{n().forEach(E)};return{init:()=>{const A=[o].concat(n());return{cols:V,rows:e,duration:1440,poster:A}},play:()=>(E(o),r(),s=setInterval(r,1e3),!0),stop:()=>{clearInterval(s)},getCurrentTime:()=>{const A=new Date;return 60*A.getHours()+A.getMinutes()}}}],["eventsource",function(A,g){let I,Q,{url:C,bufferTime:E,minFrameTime:V}=A,{feed:e,reset:i,setState:t,logger:o}=g;o=new B(o,"eventsource: ");let s=new S;function n(A){void 0!==Q&&Q.stop(),Q=v(E,e,(A=>s.setTime(A)),A,V,o)}return{play:()=>{I=new EventSource(C),I.addEventListener("open",(()=>{o.info("opened"),n()})),I.addEventListener("error",(A=>{o.info("errored"),o.debug({e:A}),t("loading")})),I.addEventListener("message",(A=>{const g=JSON.parse(A.data);if(Array.isArray(g))Q.pushEvent(g);else if(void 0!==g.cols||void 0!==g.width){const A=g.cols??g.width,I=g.rows??g.height;o.debug(`vt reset (${A}x${I})`),t("playing"),n(g.time),i(A,I,g.init??void 0),s=new J,"number"==typeof g.time&&s.setTime(g.time)}else"offline"===g.state&&(o.info("stream offline"),t("offline",{message:"Stream offline"}),s=new S)})),I.addEventListener("done",(()=>{o.info("closed"),I.close(),t("ended",{message:"Stream ended"})}))},stop:()=>{void 0!==Q&&Q.stop(),void 0!==I&&I.close()},getCurrentTime:()=>s.getTime()}}],["random",function(A,g){let{feed:I,setTimeout:B}=g;const Q=" ".charCodeAt(0),C="~".charCodeAt(0)-Q;let E;const V=()=>{const A=Math.pow(5,4*Math.random());E=B(e,A)},e=()=>{V();const A=String.fromCharCode(Q+Math.floor(Math.random()*C));I(A)};return()=>(V(),()=>clearInterval(E))}],["recording",function(A,g,I){let B,Q,C,E,V,e,i,t,o,{feed:s,resize:n,onInput:r,onMarker:a,now:c,setTimeout:D,setState:w,logger:h}=g,{idleTimeLimit:l,startAt:y,loop:k,posterTime:G,markers:F,pauseOnMarkers:q,cols:d,rows:M}=I,N=0,f=0,u=0;async function R(A,g){const I=await fetch(A,g);if(!I.ok)throw`failed fetching recording from ${A}: ${I.status} ${I.statusText}`;return I}function J(){const A=C[N];A?i=D(S,function(A){let g=1e3*A-(c()-t);return g<0&&(g=0),g}(A[0])):L()}function S(){let A,g=C[N];do{f=g[0],N++;if(p(g))return;g=C[N],A=c()-t}while(g&&A>1e3*g[0]);J()}function U(){clearTimeout(i),i=null}function p(A){const[g,I,B]=A;if("o"===I)s(B);else if("i"===I)r(B);else if("r"===I){const[A,g]=B.split("x");n(A,g)}else if("m"===I&&(a(B),q))return m(),o=1e3*g,w("idle",{reason:"paused"}),!0;return!1}function L(){U(),u++,!0===k||"number"==typeof k&&u>"===A?A=I+5:"<<<"===A?A=I-.1*V:">>>"===A?A=I+.1*V:"%"===A[A.length-1]&&(A=parseFloat(A.substring(0,A.length-1))/100*V);else if("object"==typeof A)if("prev"===A.marker)A=T(I)??0,g&&I-A<1&&(A=T(A)??0);else if("next"===A.marker)A=function(A){if(0==E.length)return;let g,I=E.length-1,B=E[I];for(;B&&B[0]>A;)g=B[0],B=E[--I];return g}(I)??V;else if("number"==typeof A.marker){const g=E[A.marker];if(void 0===g)throw`invalid marker index: ${A.marker}`;A=g[0]}const B=Math.min(Math.max(A,0),V);B1&&void 0!==arguments[1]?arguments[1]:1/60;return B=>{let Q=0,C=0;return{step:A=>{Q++,void 0!==g?"o"===A[1]&&"o"===g[1]&&A[0]-g[0]{void 0!==g&&(B(g),C++),A.debug(`batched ${Q} frames to ${C} frames`)}}}}(g,C)).map(function(A,g,I){let B=0,Q=0;return function(C){const E=C[0]-B-A;return B=C[0],E>0&&(Q+=E,C[0]"m"!==A[1])).multiplex(V,((A,g)=>A[0]"i"===A[1]?[A[0]+E,A[1],A[2]]:A)),e.sort(((A,g)=>A[0]-g[0])));const t=e[e.length-1][0],o=B-i.offset;return{...A,events:e,duration:t,effectiveStartAt:o}}(await g(await function(A){let{url:g,data:I,fetchOpts:B={}}=A;if("string"==typeof g)return R(g,B);if(Array.isArray(g))return Promise.all(g.map((A=>R(A,B))));if(void 0!==I)return"function"==typeof I&&(I=I()),I instanceof Promise||(I=Promise.resolve(I)),I.then((A=>"string"==typeof A||A instanceof ArrayBuffer?new Response(A):A));throw"failed fetching recording file: url/data missing in src"}(A),{encoding:o}),h,{idleTimeLimit:l,startAt:y,minFrameTime:I,inputOffset:i,markers_:F});if(({cols:B,rows:Q,events:C,duration:V,effectiveStartAt:e}=s),d=d??B,M=M??Q,0===C.length)throw"recording is missing events";void 0!==t&&function(A,g){const I=document.createElement("a"),B=A.events.map((A=>"m"===A[1]?[A[0],A[1],A[2].label]:A)),Q=function(A){return`${JSON.stringify({version:2,width:A.cols,height:A.rows})}\n${A.events.map(JSON.stringify).join("\n")}\n`}({...A,events:B});I.href=URL.createObjectURL(new Blob([Q],{type:"text/plain"})),I.download=g,I.click()}(s,t);const n=void 0!==G?(r=G,C.filter((A=>A[0]A[2]))):void 0;var r;return E=C.filter((A=>"m"===A[1])).map((A=>[A[0],A[2].label])),{cols:B,rows:Q,duration:V,theme:s.theme,poster:n,markers:E}},play:function(){if(i)throw"already playing";if(void 0===C[N])throw"already ended";return null!==e&&v(e),H(),!0},pause:m,seek:v,step:function(A){let g,I;if(void 0===A&&(A=1),A>0){let B=N;g=C[B];for(let Q=0;Q{const A=I.protocol||"raw";n.info("opened"),n.info(`activating ${A} protocol handler`),"v1.alis"===A?I.onmessage=y(x(n)):"v2.asciicast"===A?I.onmessage=y(function(){let A=function(I){const B=JSON.parse(I);if(2!==B.version)throw"not an asciicast v2 stream";return A=g,{time:0,term:{size:{cols:B.width,rows:B.height}}}};function g(A){const g=JSON.parse(A);if("r"===g[1]){const[A,I]=g[2].split("x");return[g[0],"r",{cols:A,rows:I}]}return g}return function(g){return A(g)}}()):"raw"===A&&(I.onmessage=y(z())),r=setTimeout((()=>{D=0}),1e3)},I.onclose=A=>{if(clearTimeout(a),G(),w||1e3===A.code||1005===A.code)n.info("closed"),s("ended",{message:"Stream ended"});else if(1002===A.code)n.debug(`close reason: ${A.reason}`),s("ended",{message:"Err: Player not compatible with the server"});else{clearTimeout(r);const A=V(D++);n.info(`unclean close, reconnecting in ${A}...`),s("loading"),setTimeout(l,A)}},h=!1}function y(A){return a=setTimeout(k,5e3),function(g){const I=A(g.data);if(Q){if(Array.isArray(I))Q.pushEvent(I);else if("string"==typeof I)Q.pushText(I);else if(!1===I)k();else if(void 0!==I)throw`unexpected value from protocol handler: ${I}`}else if("object"!=typeof I||Array.isArray(I)){if(void 0!==I)throw clearTimeout(a),`unexpected value from protocol handler: ${I}`;clearTimeout(a),a=setTimeout(k,1e3)}else{const{time:A,term:g}=I,{size:B,init:C,theme:V}=g,{cols:r,rows:D}=B;!function(A,g,I,B,C){n.info(`stream init (${A}x${g} @${I})`),s("playing"),G(),Q=v(E,i,o,(A=>c.setTime(A)),I,e,n),t(A,g,B,C),c=new J,h=!0,"number"==typeof I&&c.setTime(I)}(r,D,A,C,V),clearTimeout(a)}}}function k(){G(),h?(n.info("stream ended"),s("offline",{message:"Stream ended"})):(n.info("stream offline"),s("offline",{message:"Stream offline"})),c=new S}function G(){Q&&Q.stop(),Q=null}return{play:()=>{l()},stop:()=>{w=!0,G(),void 0!==I&&I.close()},getCurrentTime:()=>c.getTime()}}]]),oA=new Map([["asciicast",L],["typescript",async function(A,g){let{encoding:I}=g;const B=new TextDecoder(I);let Q,C,E=(await A[0].text()).split("\n").filter((A=>A.length>0)).map((A=>A.split(" ")));E[0].length<3&&(E=E.map((A=>["O",A[0],A[1]])));const V=await A[1].arrayBuffer(),e=new Uint8Array(V),i=e.findIndex((A=>10==A))+1,t=B.decode(e.subarray(0,i)).match(/COLUMNS="(\d+)" LINES="(\d+)"/);null!==t&&(Q=parseInt(t[1],10),C=parseInt(t[2],10));const o={array:e,cursor:i};let s=o;if(void 0!==A[2]){const g=await A[2].arrayBuffer();s={array:new Uint8Array(g),cursor:i}}const n=[];let r=0;for(const A of E)if(r+=parseFloat(A[1]),"O"===A[0]){const g=parseInt(A[2],10),I=o.array.subarray(o.cursor,o.cursor+g),Q=B.decode(I);n.push([r,"o",Q]),o.cursor+=g}else if("I"===A[0]){const g=parseInt(A[2],10),I=s.array.subarray(s.cursor,s.cursor+g),Q=B.decode(I);n.push([r,"i",Q]),s.cursor+=g}else if("S"===A[0]&&"SIGWINCH"===A[2]){const g=parseInt(A[4].slice(5),10),I=parseInt(A[3].slice(5),10);n.push([r,"r",`${g}x${I}`])}else"H"===A[0]&&"COLUMNS"===A[2]?Q=parseInt(A[3],10):"H"===A[0]&&"LINES"===A[2]&&(C=parseInt(A[3],10));return Q=Q??80,C=C??24,{cols:Q,rows:C,events:n}}],["ttyrec",async function(A,g){let{encoding:I}=g;const B=new TextDecoder(I),Q=await A.arrayBuffer(),C=new Uint8Array(Q),E=_(C),V=E.time,e=B.decode(E.data).match(/\x1b\[8;(\d+);(\d+)t/),i=[];let t=80,o=24;null!==e&&(t=parseInt(e[2],10),o=parseInt(e[1],10));let s=0,n=_(C);for(;void 0!==n;){const A=n.time-V,g=B.decode(n.data);i.push([A,"o",g]),s+=n.len,n=_(C.subarray(s))}return{cols:t,rows:o,events:i}}]]);const sA={};const nA=Symbol("solid-proxy"),rA=Symbol("solid-track"),aA={equals:(A,g)=>A===g};let cA=vA;const DA=1,wA=2,hA={owned:null,cleanups:null,context:null,owner:null};var lA=null;let yA=null,kA=null,GA=null,FA=null,qA=0;function dA(A,g){const I=kA,B=lA,Q=0===A.length,C=Q?hA:{owned:null,cleanups:null,context:null,owner:void 0===g?B:g},E=Q?A:()=>A((()=>RA((()=>jA(C)))));lA=C,kA=null;try{return HA(E,!0)}finally{kA=I,lA=B}}function MA(A,g){const I={value:A,observers:null,observerSlots:null,comparator:(g=g?Object.assign({},aA,g):aA).equals||void 0};return[pA.bind(I),A=>("function"==typeof A&&(A=A(I.value)),LA(I,A))]}function NA(A,g,I){mA(KA(A,g,!1,DA))}function fA(A,g,I){I=I?Object.assign({},aA,I):aA;const B=KA(A,g,!0,0);return B.observers=null,B.observerSlots=null,B.comparator=I.equals||void 0,mA(B),pA.bind(B)}function uA(A){return HA(A,!1)}function RA(A){if(null===kA)return A();const g=kA;kA=null;try{return A()}finally{kA=g}}function JA(A){!function(A,g,I){cA=TA;const B=KA(A,g,!1,DA);B.user=!0,FA?FA.push(B):mA(B)}((()=>RA(A)))}function SA(A){return null===lA||(null===lA.cleanups?lA.cleanups=[A]:lA.cleanups.push(A)),A}function YA(){return kA}function UA(A){const g=fA(A),I=fA((()=>WA(g())));return I.toArray=()=>{const A=I();return Array.isArray(A)?A:null!=A?[A]:[]},I}function pA(){const A=yA;if(this.sources&&(this.state||A))if(this.state===DA||A)mA(this);else{const A=GA;GA=null,HA((()=>OA(this)),!1),GA=A}if(kA){const A=this.observers?this.observers.length:0;kA.sources?(kA.sources.push(this),kA.sourceSlots.push(A)):(kA.sources=[this],kA.sourceSlots=[A]),this.observers?(this.observers.push(kA),this.observerSlots.push(kA.sources.length-1)):(this.observers=[kA],this.observerSlots=[kA.sources.length-1])}return this.value}function LA(A,g,I){let B=A.value;return A.comparator&&A.comparator(B,g)||(A.value=g,A.observers&&A.observers.length&&HA((()=>{for(let g=0;g1e6)throw GA=[],new Error}),!1)),g}function mA(A){if(!A.fn)return;jA(A);const g=lA,I=kA,B=qA;kA=lA=A,function(A,g,I){let B;try{B=A.fn(g)}catch(g){A.pure&&(A.state=DA,A.owned&&A.owned.forEach(jA),A.owned=null),ZA(g)}(!A.updatedAt||A.updatedAt<=I)&&(null!=A.updatedAt&&"observers"in A?LA(A,B):A.value=B,A.updatedAt=I)}(A,A.value,B),kA=I,lA=g}function KA(A,g,I,B=DA,Q){const C={fn:A,state:B,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:g,owner:lA,context:null,pure:I};return null===lA||lA!==hA&&(lA.owned?lA.owned.push(C):lA.owned=[C]),C}function bA(A){const g=yA;if(0===A.state||g)return;if(A.state===wA||g)return OA(A);if(A.suspense&&RA(A.suspense.inFallback))return A.suspense.effects.push(A);const I=[A];for(;(A=A.owner)&&(!A.updatedAt||A.updatedAt=0;B--)if((A=I[B]).state===DA||g)mA(A);else if(A.state===wA||g){const g=GA;GA=null,HA((()=>OA(A,I[0])),!1),GA=g}}function HA(A,g){if(GA)return A();let I=!1;g||(GA=[]),FA?I=!0:FA=[],qA++;try{const g=A();return function(A){GA&&(vA(GA),GA=null);if(A)return;const g=FA;FA=null,g.length&&HA((()=>cA(g)),!1)}(I),g}catch(A){I||(FA=null),GA=null,ZA(A)}}function vA(A){for(let g=0;gA(g||{})))}function _A(){return!0}const $A={get:(A,g,I)=>g===nA?I:A.get(g),has:(A,g)=>g===nA||A.has(g),set:_A,deleteProperty:_A,getOwnPropertyDescriptor:(A,g)=>({configurable:!0,enumerable:!0,get:()=>A.get(g),set:_A,deleteProperty:_A}),ownKeys:A=>A.keys()};function Ag(A){return(A="function"==typeof A?A():A)?A:{}}function gg(A){const g="fallback"in A&&{fallback:()=>A.fallback};return fA(function(A,g,I={}){let B=[],Q=[],C=[],E=0,V=g.length>1?[]:null;return SA((()=>zA(C))),()=>{let e,i,t=A()||[];return t[rA],RA((()=>{let A,g,s,n,r,a,c,D,w,h=t.length;if(0===h)0!==E&&(zA(C),C=[],B=[],Q=[],E=0,V&&(V=[])),I.fallback&&(B=[XA],Q[0]=dA((A=>(C[0]=A,I.fallback()))),E=1);else if(0===E){for(Q=new Array(h),i=0;i=a&&D>=a&&B[c]===t[D];c--,D--)s[D]=Q[c],n[D]=C[c],V&&(r[D]=V[c]);for(A=new Map,g=new Array(D+1),i=D;i>=a;i--)w=t[i],e=A.get(w),g[i]=void 0===e?-1:e,A.set(w,i);for(e=a;e<=c;e++)w=B[e],i=A.get(w),void 0!==i&&-1!==i?(s[i]=Q[e],n[i]=C[e],V&&(r[i]=V[e]),i=g[i],A.set(w,i)):C[e]();for(i=a;iA.each),A.children,g||void 0))}function Ig(A){const g="fallback"in A&&{fallback:()=>A.fallback};return fA(function(A,g,I={}){let B,Q=[],C=[],E=[],V=[],e=0;return SA((()=>zA(E))),()=>{const i=A()||[];return i[rA],RA((()=>{if(0===i.length)return 0!==e&&(zA(E),E=[],Q=[],C=[],e=0,V=[]),I.fallback&&(Q=[XA],C[0]=dA((A=>(E[0]=A,I.fallback()))),e=1),C;for(Q[0]===XA&&(E[0](),E=[],Q=[],C=[],e=0),B=0;Bi[B])):B>=Q.length&&(C[B]=dA(t));for(;BA.each),A.children,g||void 0))}function Bg(A){let g=!1;const I=A.keyed,B=fA((()=>A.when),void 0,{equals:(A,I)=>g?A===I:!A==!I});return fA((()=>{const Q=B();if(Q){const B=A.children,C="function"==typeof B&&B.length>0;return g=I||C,C?RA((()=>B(Q))):B}return A.fallback}),void 0,void 0)}function Qg(A){let g=!1,I=!1;const B=UA((()=>A.children)),Q=fA((()=>{let A=B();Array.isArray(A)||(A=[A]);for(let g=0;gA[0]===I[0]&&(g?A[1]===I[1]:!A[1]==!I[1])&&A[2]===I[2]});return fA((()=>{const[B,C,E]=Q();if(B<0)return A.fallback;const V=E.children,e="function"==typeof V&&V.length>0;return g=I||e,e?RA((()=>V(C))):V}),void 0,void 0)}function Cg(A){return A}const Eg="_$DX_DELEGATE";function Vg(A,g,I,B={}){let Q;return dA((B=>{Q=B,g===document?A():rg(g,A(),g.firstChild?null:void 0,I)}),B.owner),()=>{Q(),g.textContent=""}}function eg(A,g,I){const B=document.createElement("template");B.innerHTML=A;let Q=B.content.firstChild;return I&&(Q=Q.firstChild),Q}function ig(A,g=window.document){const I=g[Eg]||(g[Eg]=new Set);for(let B=0,Q=A.length;BB.call(A,I[1],g))}else A.addEventListener(g,I)}function sg(A,g,I){if(!g)return I?function(A,g,I){null==I?A.removeAttribute(g):A.setAttribute(g,I)}(A,"style"):g;const B=A.style;if("string"==typeof g)return B.cssText=g;let Q,C;for(C in"string"==typeof I&&(B.cssText=I=void 0),I||(I={}),g||(g={}),I)null==g[C]&&B.removeProperty(C),delete I[C];for(C in g)Q=g[C],Q!==I[C]&&(B.setProperty(C,Q),I[C]=Q);return I}function ng(A,g,I){return RA((()=>A(g,I)))}function rg(A,g,I,B){if(void 0===I||B||(B=[]),"function"!=typeof g)return cg(A,g,B,I);NA((B=>cg(A,g(),B,I)),B)}function ag(A){const g=`$$${A.type}`;let I=A.composedPath&&A.composedPath()[0]||A.target;for(A.target!==I&&Object.defineProperty(A,"target",{configurable:!0,value:I}),Object.defineProperty(A,"currentTarget",{configurable:!0,get:()=>I||document}),sA.registry&&!sA.done&&(sA.done=!0,document.querySelectorAll("[id^=pl-]").forEach((g=>{for(;g&&8!==g.nodeType&&g.nodeValue!=="pl-"+A;){let A=g.nextSibling;g.remove(),g=A}g&&g.remove()})));I;){const B=I[g];if(B&&!I.disabled){const Q=I[`${g}Data`];if(void 0!==Q?B.call(I,Q,A):B.call(I,A),A.cancelBubble)return}I=I._$host||I.parentNode||I.host}}function cg(A,g,I,B,Q){for(sA.context&&!I&&(I=[...A.childNodes]);"function"==typeof I;)I=I();if(g===I)return I;const C=typeof g,E=void 0!==B;if(A=E&&I[0]&&I[0].parentNode||A,"string"===C||"number"===C){if(sA.context)return I;if("number"===C&&(g=g.toString()),E){let Q=I[0];Q&&3===Q.nodeType?Q.data=g:Q=document.createTextNode(g),I=hg(A,I,B,Q)}else I=""!==I&&"string"==typeof I?A.firstChild.data=g:A.textContent=g}else if(null==g||"boolean"===C){if(sA.context)return I;I=hg(A,I,B)}else{if("function"===C)return NA((()=>{let Q=g();for(;"function"==typeof Q;)Q=Q();I=cg(A,Q,I,B)})),()=>I;if(Array.isArray(g)){const C=[],V=I&&Array.isArray(I);if(Dg(C,g,I,Q))return NA((()=>I=cg(A,C,I,B,!0))),()=>I;if(sA.context){if(!C.length)return I;for(let A=0;AB-V){const Q=g[E];for(;V=0;C--){const E=g[C];if(Q!==E){const g=E.parentNode===A;B||C?g&&E.remove():g?A.replaceChild(Q,E):A.insertBefore(Q,I)}else B=!0}}else A.insertBefore(Q,I);return[Q]}const lg=Symbol("store-raw"),yg=Symbol("store-node"),kg=Symbol("store-name");function Gg(A,g){let I=A[nA];if(!I&&(Object.defineProperty(A,nA,{value:I=new Proxy(A,ug)}),!Array.isArray(A))){const g=Object.keys(A),B=Object.getOwnPropertyDescriptors(A);for(let Q=0,C=g.length;Q!0,deleteProperty:()=>!0,ownKeys:function(A){return Ng(A),Reflect.ownKeys(A)},getOwnPropertyDescriptor:function(A,g){const I=Reflect.getOwnPropertyDescriptor(A,g);return I&&!I.get&&I.configurable&&g!==nA&&g!==yg&&g!==kg?(delete I.value,delete I.writable,I.get=()=>A[nA][g],I):I}};function Rg(A,g,I,B=!1){if(!B&&A[g]===I)return;const Q=A[g],C=A.length;void 0===I?delete A[g]:A[g]=I;let E,V=dg(A);(E=Mg(V,g,Q))&&E.$((()=>I)),Array.isArray(A)&&A.length!==C&&(E=Mg(V,"length",C))&&E.$(A.length),(E=V._)&&E.$()}function Jg(A,g){const I=Object.keys(g);for(let B=0;B1){B=g.shift();const C=typeof B,E=Array.isArray(A);if(Array.isArray(B)){for(let Q=0;Q1)return void Sg(A[B],g,[B].concat(I));Q=A[B],I=[B].concat(I)}let C=g[0];"function"==typeof C&&(C=C(Q,I),C===Q)||void 0===B&&null==C||(C=qg(C),void 0===B||Fg(Q)&&Fg(C)&&!Array.isArray(C)?Jg(Q,C):Rg(A,B,C))}function Yg(...[A,g]){const I=qg(A||{}),B=Array.isArray(I);return[Gg(I),function(...A){uA((()=>{B&&1===A.length?function(A,g){if("function"==typeof g&&(g=g(A)),g=qg(g),Array.isArray(g)){if(A===g)return;let I=0,B=g.length;for(;I=E&&e>=E&&(C[V]===A[e]||Q&&C[E]&&A[E]&&C[V][Q]===A[e][Q]);V--,e--)s[e]=C[V];if(E>e||E>V){for(I=E;I<=e;I++)Rg(C,I,A[I]);for(;IA.length&&Rg(C,"length",A.length))}for(t=new Array(e+1),I=e;I>=E;I--)i=A[I],o=Q&&i?i[Q]:i,g=n.get(o),t[I]=void 0===g?-1:g,n.set(o,I);for(g=E;g<=V;g++)i=C[g],o=Q&&i?i[Q]:i,I=n.get(o),void 0!==I&&-1!==I&&(s[I]=C[g],I=t[I],n.set(o,I));for(I=E;IA.length&&Rg(C,"length",A.length))}const E=Object.keys(A);for(let g=0,I=E.length;g{if(!Fg(A)||!Fg(Q))return Q;const g=pg(Q,{[Ug]:A},Ug,I,B);return void 0===g?A:g}}const mg=eg("");var Kg=A=>{const g=fA((()=>{if(1==A.text.length){const g=A.text.codePointAt(0);if(g>=9600&&g<=9631||57520==g||57522==g)return g}})),I=fA((()=>g()?" ":A.text)),B=fA((()=>function(A,g,I){const B=A.get("fg"),Q=A.get("bg");let C={"--offset":g,width:`${I+.01}ch`};"string"==typeof B&&(C["--fg"]=B);"string"==typeof Q&&(C["--bg"]=Q);return C}(A.pen,A.offset,A.width))),Q=fA((()=>function(A,g,I){const B=bg(A.get("fg"),A.get("bold"),"fg-"),Q=bg(A.get("bg"),!1,"bg-");let C=I??"";void 0!==g&&(C+=` cp-${g.toString(16)}`);B&&(C+=" "+B);Q&&(C+=" "+Q);A.has("bold")&&(C+=" ap-bright");A.has("faint")&&(C+=" ap-faint");A.has("italic")&&(C+=" ap-italic");A.has("underline")&&(C+=" ap-underline");A.has("blink")&&(C+=" ap-blink");A.get("inverse")&&(C+=" ap-inverse");return C}(A.pen,g(),A.extraClass)));return(()=>{const A=mg.cloneNode(!0);return rg(A,I),NA((g=>{const I=Q(),C=B();return I!==g._v$&&tg(A,g._v$=I),g._v$2=sg(A,C,g._v$2),g}),{_v$:void 0,_v$2:void 0}),A})()};function bg(A,g,I){if("number"==typeof A)return g&&A<8&&(A+=8),`${I}${A}`}const Hg=eg('');var vg=A=>(()=>{const g=Hg.cloneNode(!0);return rg(g,PA(Ig,{get each(){return(()=>{if("number"==typeof A.cursor){const g=[];let I=0,B=0;for(;B0&&g.push({...Q,text:Q.text.substring(0,C)}),g.push({...Q,text:Q.text[C],offset:Q.offset+C,extraClass:"ap-cursor"}),CPA(Kg,function(...A){let g=!1;for(let I=0;I=0;I--){const B=Ag(A[I])[g];if(void 0!==B)return B}},has(g){for(let I=A.length-1;I>=0;I--)if(g in Ag(A[I]))return!0;return!1},keys(){const g=[];for(let I=0;I=0;g--)if(A[g]){const B=Object.getOwnPropertyDescriptors(A[g]);for(const g in B)g in I||Object.defineProperty(I,g,{enumerable:!0,get(){for(let I=A.length-1;I>=0;I--){const B=(A[I]||{})[g];if(void 0!==B)return B}}})}return I}(A))})),g})();const Tg=eg('
');var Og=A=>{const g=()=>A.lineHeight??1.3333333333,I=fA((()=>({width:`${A.cols}ch`,height:g()*A.rows+"em","font-size":100*(A.scale||1)+"%","font-family":A.fontFamily,"--term-line-height":`${g()}em`,"--term-cols":A.cols}))),B=fA((()=>A.cursor?.[0])),Q=fA((()=>A.cursor?.[1]));return(()=>{const g=Tg.cloneNode(!0),C=A.ref;return"function"==typeof C?ng(C,g):A.ref=g,rg(g,PA(gg,{get each(){return A.lines},children:(A,g)=>PA(vg,{get segments(){return A.segments},get cursor(){return fA((()=>g()===Q()))()?B():null}})})),NA((B=>{const Q=!(!A.blink&&!A.cursorHold),C=!!A.blink,E=I();return Q!==B._v$&&g.classList.toggle("ap-cursor-on",B._v$=Q),C!==B._v$2&&g.classList.toggle("ap-blink",B._v$2=C),B._v$3=sg(g,E,B._v$3),B}),{_v$:void 0,_v$2:void 0,_v$3:void 0}),g})()};const xg=eg(''),jg=eg(''),Zg=eg(''),Wg=eg(''),Xg=eg('
Keyboard shortcuts (?)Fullscreen (f)
'),zg=eg('');function Pg(A){let g=Math.floor(A);const I=Math.floor(g/86400);g%=86400;const B=Math.floor(g/3600);g%=3600;const Q=Math.floor(g/60);return g%=60,I>0?`${_g(I)}:${_g(B)}:${_g(Q)}:${_g(g)}`:B>0?`${_g(B)}:${_g(Q)}:${_g(g)}`:`${_g(Q)}:${_g(g)}`}function _g(A){return A<10?`0${A}`:A.toString()}var $g=A=>{const g=A=>g=>{g.preventDefault(),A(g)},I=()=>"number"==typeof A.currentTime?Pg(A.currentTime):"--:--",B=()=>"number"==typeof A.remainingTime?"-"+Pg(A.remainingTime):I(),Q=fA((()=>"number"==typeof A.duration?A.markers.filter((g=>g[0]{const g=A.currentTarget.offsetWidth,I=A.currentTarget.getBoundingClientRect(),B=A.clientX-I.left;return 100*Math.max(0,B/g)+"%"},[E,V]=MA(!1),e=function(A,g){let I=!0;return function(){if(I){I=!1;for(var B=arguments.length,Q=new Array(B),C=0;CI=!0),g)}}}(A.onSeekClick,50),i=g=>{g._marker||g.altKey||g.shiftKey||g.metaKey||g.ctrlKey||0!==g.button||(V(!0),A.onSeekClick(C(g)))},t=A=>{A.altKey||A.shiftKey||A.metaKey||A.ctrlKey||E()&&e(C(A))},o=()=>{V(!1)};return document.addEventListener("mouseup",o),SA((()=>{document.removeEventListener("mouseup",o)})),(()=>{const C=Xg.cloneNode(!0),E=C.firstChild,V=E.firstChild,e=V.nextSibling,o=E.nextSibling,s=o.nextSibling,n=s.nextSibling,r=A.ref;return"function"==typeof r?ng(r,C):A.ref=C,rg(C,PA(Bg,{get when(){return A.isPausable},get children(){const I=Zg.cloneNode(!0);return og(I,"click",g(A.onPlayClick),!0),rg(I,PA(Qg,{get children(){return[PA(Cg,{get when(){return A.isPlaying},get children(){return xg.cloneNode(!0)}}),PA(Cg,{get when(){return!A.isPlaying},get children(){return jg.cloneNode(!0)}})]}})),I}}),E),rg(V,I),rg(e,B),rg(o,PA(Bg,{get when(){return"number"==typeof A.progress||A.isSeekable},get children(){const I=Wg.cloneNode(!0),B=I.firstChild.nextSibling;return I.$$mousemove=t,I.$$mousedown=i,rg(I,PA(gg,{get each(){return Q()},children:(I,B)=>(()=>{const Q=zg.cloneNode(!0),C=Q.firstChild,E=C.nextSibling;var V;return Q.$$mousedown=A=>{A._marker=!0},og(Q,"click",(V=B(),g((()=>{A.onSeekClick({marker:V})}))),!0),rg(E,(()=>(A=>""===A[1]?Pg(A[0]):`${Pg(A[0])} - ${A[1]}`)(I))),NA((g=>{const B=(g=>g[0]/A.duration*100+"%")(I),E=!!(g=>"number"==typeof A.currentTime&&g[0]<=A.currentTime)(I);return B!==g._v$&&Q.style.setProperty("left",g._v$=B),E!==g._v$2&&C.classList.toggle("ap-marker-past",g._v$2=E),g}),{_v$:void 0,_v$2:void 0}),Q})()}),null),NA((g=>sg(B,{transform:`scaleX(${A.progress||0}`},g))),I}})),og(s,"click",g(A.onHelpClick),!0),og(n,"click",g(A.onFullscreenClick),!0),NA((()=>C.classList.toggle("ap-seekable",!!A.isSeekable))),C})()};ig(["click","mousedown","mousemove"]);const AI=eg('
💥
');var gI=A=>AI.cloneNode(!0);const II=eg('
');var BI=A=>II.cloneNode(!0);const QI=eg('
');var CI=A=>(()=>{const g=QI.cloneNode(!0),I=g.firstChild;return rg(I,(()=>A.message)),NA((g=>sg(I,{"font-family":A.fontFamily},g))),g})();const EI=eg('
');var VI=A=>(()=>{const g=EI.cloneNode(!0);var I;return og(g,"click",(I=A.onClick,A=>{A.preventDefault(),I(A)}),!0),g})();ig(["click"]);const eI=eg('

Keyboard shortcuts

  • space - pause / resume
  • f - toggle fullscreen mode
  • / - rewind / fast-forward by 5 seconds
  • Shift + / - rewind / fast-forward by 10%
  • [ / ] - jump to the previous / next marker
  • 0, 1, 2 ... 9 - jump to 0%, 10%, 20% ... 90%
  • , / . - step back / forward, a frame at a time (when paused)
  • ? - toggle this help popup
');var iI=A=>(()=>{const g=eI.cloneNode(!0),I=g.firstChild;var B;return og(g,"click",(B=A.onClose,A=>{A.preventDefault(),B(A)}),!0),I.$$click=A=>{A.stopPropagation()},NA((I=>sg(g,{"font-family":A.fontFamily},I))),g})();ig(["click"]);const tI=eg('
');var oI=A=>{const g=A.logger,I=A.core,B=A.autoPlay,[Q,C]=Yg({lines:[],cursor:void 0,charW:A.charW,charH:A.charH,bordersW:A.bordersW,bordersH:A.bordersH,containerW:0,containerH:0,isPausable:!0,isSeekable:!0,isFullscreen:!1,currentTime:null,remainingTime:null,progress:null,blink:!0,cursorHold:!1}),[E,V]=MA(!1),[e,i]=MA(B?null:"start"),[t,o]=MA(null),[s,n]=MA({cols:A.cols,rows:A.rows},{equals:(A,g)=>A.cols===g.cols&&A.rows===g.rows}),[r,a]=MA(void 0),[c,D]=Yg([]),[w,h]=MA(!1),[l,y]=MA(!1),[k,G]=MA(void 0),F=fA((()=>s().cols||80)),q=fA((()=>s().rows||24)),d=()=>!1===A.controls?0:32;let M,N,f,u,R,J,S,Y,U;function p(){$(),z(),P()}function L(A){uA((()=>{A.rows{let{cols:g,rows:I,duration:B,theme:Q,poster:C,markers:E}=A;uA((()=>{L({cols:g,rows:I}),a(B),G(Q),D(E),m(C)}))})),I.addEventListener("play",(()=>{i(null)})),I.addEventListener("playing",(()=>{uA((()=>{V(!0),i(null),H(),_(),X()}))})),I.addEventListener("idle",(()=>{uA((()=>{V(!1),p()}))})),I.addEventListener("loading",(()=>{uA((()=>{V(!1),p(),i("loader")}))})),I.addEventListener("offline",(A=>{let{message:g}=A;uA((()=>{V(!1),p(),void 0!==g&&(o(g),i("info"))}))}));let K=0;I.addEventListener("ended",(A=>{let{message:I}=A;uA((()=>{V(!1),p(),void 0!==I&&(o(I),i("info"))})),g.debug(`view: render count: ${K}`)})),I.addEventListener("errored",(()=>{i("error")})),I.addEventListener("resize",L),I.addEventListener("reset",(A=>{let{cols:g,rows:I,theme:B}=A;uA((()=>{L({cols:g,rows:I}),G(B),H()}))})),I.addEventListener("seeked",(()=>{P()})),I.addEventListener("terminalUpdate",(()=>{void 0===M&&(M=requestAnimationFrame(H))}));const b=()=>{U=new ResizeObserver(function(A,g){let I;return function(){for(var B=arguments.length,Q=new Array(B),C=0;CA.apply(this,Q)),g)}}((A=>{C({containerW:R.offsetWidth,containerH:R.offsetHeight}),R.dispatchEvent(new CustomEvent("resize",{detail:{el:J}}))}),10)),U.observe(R)};JA((async()=>{g.info("view: mounted"),g.debug("view: font measurements",{charW:Q.charW,charH:Q.charH}),b();const{isPausable:A,isSeekable:E,poster:V}=await I.init();uA((()=>{C({isPausable:A,isSeekable:E,containerW:R.offsetWidth,containerH:R.offsetHeight}),m(V)})),B&&I.play()})),SA((()=>{I.stop(),$(),z(),U.disconnect()}));const H=async()=>{const A=await I.getChanges();uA((()=>{void 0!==A.lines&&A.lines.forEach(((A,g)=>{C("lines",g,Lg(A))})),void 0!==A.cursor&&C("cursor",Lg(A.cursor)),C("cursorHold",!0)})),M=void 0,K+=1},v=fA((()=>{const g=Q.charW*F()+Q.bordersW,I=Q.charH*q()+Q.bordersH;let B=A.fit??"width";if("both"===B||Q.isFullscreen){B=Q.containerW/(Q.containerH-d())>g/I?"height":"width"}if(!1===B||"none"===B)return{};if("width"===B){const A=Q.containerW/g;return{scale:A,width:Q.containerW,height:I*A+d()}}if("height"===B){const A=(Q.containerH-d())/I;return{scale:A,width:g*A,height:Q.containerH}}throw`unsupported fit mode: ${B}`})),T=()=>{C("isFullscreen",document.fullscreenElement??document.webkitFullscreenElement)},O=()=>{Q.isFullscreen?(document.exitFullscreen??document.webkitExitFullscreen??(()=>{})).apply(document):(R.requestFullscreen??R.webkitRequestFullscreen??(()=>{})).apply(R)},x=()=>{l()?y(!1):(I.pause(),y(!0))},j=A=>{if(!(A.altKey||A.metaKey||A.ctrlKey)){if(" "==A.key)I.togglePlay();else if(","==A.key)I.step(-1),P();else if("."==A.key)I.step(),P();else if("f"==A.key)O();else if("["==A.key)I.seek({marker:"prev"});else if("]"==A.key)I.seek({marker:"next"});else if(A.key.charCodeAt(0)>=48&&A.key.charCodeAt(0)<=57){const g=(A.key.charCodeAt(0)-48)/10;I.seek(100*g+"%")}else if("?"==A.key)x();else if("ArrowLeft"==A.key)A.shiftKey?I.seek("<<<"):I.seek("<<");else if("ArrowRight"==A.key)A.shiftKey?I.seek(">>>"):I.seek(">>");else{if("Escape"!=A.key)return;y(!1)}A.stopPropagation(),A.preventDefault()}},Z=()=>{Q.isFullscreen&&AA(!0)},W=()=>{Q.isFullscreen||AA(!1)},X=()=>{f=setInterval(P,100)},z=()=>{clearInterval(f)},P=async()=>{const A=await I.getCurrentTime(),g=await I.getRemainingTime(),B=await I.getProgress();C({currentTime:A,remainingTime:g,progress:B})},_=()=>{u=setInterval((()=>{C((A=>{const g={blink:!A.blink};return g.blink&&(g.cursorHold=!1),g}))}),500)},$=()=>{clearInterval(u),C("blink",!0)},AA=A=>{clearTimeout(N),A&&(N=setTimeout((()=>AA(!1)),2e3)),h(A)},gA=fA((()=>{const g=A.theme||"auto/asciinema";return"auto/"===g.slice(0,5)?{name:g.slice(5),colors:k()}:{name:g}})),IA=(()=>{const g=tI.cloneNode(!0),B=g.firstChild;"function"==typeof R?ng(R,g):R=g,g.addEventListener("webkitfullscreenchange",T),g.addEventListener("fullscreenchange",T),g.$$mousemove=Z,g.$$keydown=j;return"function"==typeof J?ng(J,B):J=B,B.$$mousemove=()=>AA(!0),B.addEventListener("mouseleave",W),rg(B,PA(Og,{get cols(){return F()},get rows(){return q()},get scale(){return v()?.scale},get blink(){return Q.blink},get lines(){return Q.lines},get cursor(){return Q.cursor},get cursorHold(){return Q.cursorHold},get fontFamily(){return A.terminalFontFamily},get lineHeight(){return A.terminalLineHeight},ref(A){"function"==typeof S?S(A):S=A}}),null),rg(B,PA(Bg,{get when(){return!1!==A.controls},get children(){return PA($g,{get duration(){return r()},get currentTime(){return Q.currentTime},get remainingTime(){return Q.remainingTime},get progress(){return Q.progress},markers:c,get isPlaying(){return E()},get isPausable(){return Q.isPausable},get isSeekable(){return Q.isSeekable},onPlayClick:()=>I.togglePlay(),onFullscreenClick:O,onHelpClick:x,onSeekClick:A=>I.seek(A),ref(A){"function"==typeof Y?Y(A):Y=A}})}}),null),rg(B,PA(Qg,{get children(){return[PA(Cg,{get when(){return"start"==e()},get children(){return PA(VI,{onClick:()=>I.play()})}}),PA(Cg,{get when(){return"loader"==e()},get children(){return PA(BI,{})}}),PA(Cg,{get when(){return"info"==e()},get children(){return PA(CI,{get message(){return t()},get fontFamily(){return A.terminalFontFamily}})}}),PA(Cg,{get when(){return"error"==e()},get children(){return PA(gI,{})}})]}}),null),rg(B,PA(Bg,{get when(){return l()},get children(){return PA(iI,{get fontFamily(){return A.terminalFontFamily},onClose:()=>y(!1)})}}),null),NA((I=>{const Q=!!(!0===A.controls||"auto"===A.controls&&w()),C=`ap-player asciinema-player-theme-${gA().name}`,E=(()=>{const g={};!1!==A.fit&&"none"!==A.fit||void 0===A.terminalFontSize||("small"===A.terminalFontSize?g["font-size"]="12px":"medium"===A.terminalFontSize?g["font-size"]="18px":"big"===A.terminalFontSize?g["font-size"]="24px":g["font-size"]=A.terminalFontSize);const I=v();void 0!==I.width&&(g.width=`${I.width}px`,g.height=`${I.height}px`);const B=gA().colors;return void 0!==B&&(g["--term-color-foreground"]=B.foreground,g["--term-color-background"]=B.background,B.palette.forEach(((A,I)=>{g[`--term-color-${I}`]=A}))),g})();return Q!==I._v$&&g.classList.toggle("ap-hud",I._v$=Q),C!==I._v$2&&tg(B,I._v$2=C),I._v$3=sg(B,E,I._v$3),I}),{_v$:void 0,_v$2:void 0,_v$3:void 0}),g})();return IA};function sI(A,g){let I=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const B=function(A,g){const I=80,B=24,Q=document.createElement("div");let C;Q.style.height="0px",Q.style.overflow="hidden",Q.style.fontSize="15px",document.body.appendChild(Q);const E=Vg((()=>(C=PA(Og,{cols:I,rows:B,lineHeight:g,fontFamily:A,lines:[]}),C)),Q),V={charW:C.clientWidth/I,charH:C.clientHeight/B,bordersW:C.offsetWidth-C.clientWidth,bordersH:C.offsetHeight-C.clientHeight};return E(),document.body.removeChild(Q),V}(I.terminalFontFamily,I.terminalLineHeight),Q={core:A,logger:I.logger,cols:I.cols,rows:I.rows,fit:I.fit,controls:I.controls??"auto",autoPlay:I.autoPlay??I.autoplay,terminalFontSize:I.terminalFontSize,terminalFontFamily:I.terminalFontFamily,terminalLineHeight:I.terminalLineHeight,theme:I.theme,...B};let C;const E=Vg((()=>(C=PA(oI,Q),C)),g),V={el:C,dispose:E,getCurrentTime:()=>A.getCurrentTime(),getDuration:()=>A.getDuration(),play:()=>A.play(),pause:()=>A.pause(),seek:g=>A.seek(g),addEventListener:(g,I)=>A.addEventListener(g,I.bind(V))};return V}ig(["keydown","mousemove"]);const nI=["cols","idleTimeLimit","loop","markers","pauseOnMarkers","poster","preload","rows","speed","startAt"],rI=["autoPlay","autoplay","cols","controls","fit","rows","terminalFontFamily","terminalFontSize","terminalLineHeight","theme"];return A.create=function(A,g){let B=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const Q=B.logger??new I,C=new iA(A,function(A){let g=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return{...Object.fromEntries(Object.entries(A).filter((A=>{let[g]=A;return nI.includes(g)}))),...g}}(B,{logger:Q}));return sI(C,g,function(A){let g=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return{...Object.fromEntries(Object.entries(A).filter((A=>{let[g]=A;return rI.includes(g)}))),...g}}(B,{logger:Q}))},A}({}); diff --git a/scripts/a2a_docs_pipeline.py b/scripts/a2a_docs_pipeline.py index 576025eda..ed8ab1088 100755 --- a/scripts/a2a_docs_pipeline.py +++ b/scripts/a2a_docs_pipeline.py @@ -160,9 +160,29 @@ def check() -> None: path = SNIPPETS / filename if not path.exists() or path.read_text(encoding="utf-8") != text: missing_or_changed.append(str(path.relative_to(ROOT))) + required_assets = [ + ASSETS / "a2a-streaming-files.cast", + ROOT / "docs" / "docs" / "assets" / "vendor" / "asciinema-player" / "asciinema-player.css", + ROOT / "docs" / "docs" / "assets" / "vendor" / "asciinema-player" / "asciinema-player.min.js", + ] + for asset in required_assets: + if not asset.exists(): + missing_or_changed.append(str(asset.relative_to(ROOT))) + + page = DOCS_A2A / "getting-started.md" + page_text = page.read_text(encoding="utf-8") if page.exists() else "" + for required_text in [ + "AsciinemaPlayer.create", + "../../assets/a2a/a2a-streaming-files.cast", + "../../assets/vendor/asciinema-player/asciinema-player.css", + "../../assets/vendor/asciinema-player/asciinema-player.min.js", + ]: + if required_text not in page_text: + missing_or_changed.append(f"{page.relative_to(ROOT)} missing {required_text}") + if missing_or_changed: raise SystemExit( - "A2A docs snippets are stale; run `uv run scripts/a2a_docs_pipeline.py generate`.\n" + "A2A docs snippets/assets are stale; run `uv run scripts/a2a_docs_pipeline.py generate`.\n" + "\n".join(missing_or_changed) ) diff --git a/tests/unit/test_a2a_docs_pipeline.py b/tests/unit/test_a2a_docs_pipeline.py index 71589f4dc..c5f4d1a41 100644 --- a/tests/unit/test_a2a_docs_pipeline.py +++ b/tests/unit/test_a2a_docs_pipeline.py @@ -35,3 +35,22 @@ def test_a2a_cast_asset_is_present() -> None: assert asset.is_file() first_line = asset.read_text(encoding="utf-8").splitlines()[0] assert '"version"' in first_line + + +def test_a2a_getting_started_embeds_asciinema_player() -> None: + page = ROOT / "docs" / "docs" / "a2a" / "getting-started.md" + text = page.read_text(encoding="utf-8") + assert "AsciinemaPlayer.create" in text + assert "../../assets/a2a/a2a-streaming-files.cast" in text + assert "../../assets/vendor/asciinema-player/asciinema-player.css" in text + assert "../../assets/vendor/asciinema-player/asciinema-player.min.js" in text + + +def test_asciinema_player_vendor_assets_are_present() -> None: + vendor = ROOT / "docs" / "docs" / "assets" / "vendor" / "asciinema-player" + css = vendor / "asciinema-player.css" + js = vendor / "asciinema-player.min.js" + assert css.is_file() + assert js.is_file() + assert "ap-wrapper" in css.read_text(encoding="utf-8") + assert "AsciinemaPlayer" in js.read_text(encoding="utf-8")[:200] From 0b91bf5c023c6e1c1d36b2a6c92ba862f9a80395 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Wed, 20 May 2026 20:53:24 +0100 Subject: [PATCH 10/58] record colored a2a docs casts --- docs/docs/a2a/getting-started.md | 36 ++++++++++-- docs/docs/assets/a2a/a2a-streaming-files.cast | 58 ++++++++++++++++++- .../vendor/asciinema-player/catppuccin.css | 42 ++++++++++++++ scripts/a2a_docs_pipeline.py | 34 +++++++---- tests/unit/test_a2a_docs_pipeline.py | 13 +++++ 5 files changed, 166 insertions(+), 17 deletions(-) create mode 100644 docs/docs/assets/vendor/asciinema-player/catppuccin.css diff --git a/docs/docs/a2a/getting-started.md b/docs/docs/a2a/getting-started.md index 635345b09..d5a2d486a 100644 --- a/docs/docs/a2a/getting-started.md +++ b/docs/docs/a2a/getting-started.md @@ -129,19 +129,40 @@ The repeatable docs pipeline can generate an asciinema recording for the TUI streaming/files flow. The committed `.cast` file is embedded below and can also be downloaded for local replay. - - -
+
+ + +
+
diff --git a/docs/docs/assets/a2a/a2a-streaming-files.cast b/docs/docs/assets/a2a/a2a-streaming-files.cast index 026e669b6..f7cc8df7c 100644 --- a/docs/docs/assets/a2a/a2a-streaming-files.cast +++ b/docs/docs/assets/a2a/a2a-streaming-files.cast @@ -1,2 +1,56 @@ -{"version": 2, "width": 104, "height": 34, "timestamp": 1779305110, "idle_time_limit": 1.3, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}, "title": "fast-agent A2A streaming and files demo"} -[10.025144, "o", "fast-agent is accessing the OS keyring for stored tokens. Some platforms may\r\npause and show a prompt. (loading Codex OAuth tokens)\r\nUse '/' for commands, '!' for shell. '#' to query, '@' to switch agents\r\nCTRL+T multiline, CTRL+Y copy last message, CTRL+E external editor.\r\nCTRL+Space or Tab for path completion. Use /attach, `^file:`, or `^url:` for\r\nattachments. F10 to clear.\r\nfast-agent environment ~/source/fast-agent-pr/.cdx (2 agents, 2 hooks, 8\r\nextensions, 2 modelrefs) via cli\r\n\r\n▎▶ a2a_remote ──────────────────────────────────────────────────────────────────\r\nplease stream\r\n\r\n▎◀ a2a_remote A2A\r\nstream chunk one\r\nstream chunk two\r\n\r\n▎▶ a2a_remote ──────────────────────────────────────────────────────────────────\r\nrespond with files\r\n\r\n▎◀ a2a_remote A2A\r\nfile response report.pdf (application/pdf)\r\n\r\n{\r\n \"ok\": true,\r\n \"source\": \"fake-a2a-server\"\r\n}\r\n\r\n[note.txt: 3 bytes text/plain]\r\n\r\n❯\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n a2a_remote[A2A] ▲ fast-agent fake A2A serv… | 002 | NRML | fast-agent 0.\r\n"] +{"version": 2, "width": 104, "height": 34, "timestamp": 1779306706, "idle_time_limit": 1.3, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}, "title": "fast-agent A2A streaming and files demo"} +[0.018339, "o", "\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?2004l\u001b[1;1H\u001b[1;34r\u001b[>c\u001b[>q\u001b[1;1H"] +[0.018948, "o", "\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[H\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?2004l\u001b[1;1H\u001b[1;34r\u001b[1;1H\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[H"] +[1.020613, "o", "\u001b[?7727h"] +[2.188387, "o", "\u001b[?25l"] +[2.297334, "o", "fast-agent is accessing the OS keyring for stored tokens. Some platforms may pause and show a prompt. \r\n(loading Codex OAuth tokens)\r\n"] +[2.873807, "o", "\u001b[?12l\u001b[?25h"] +[2.881997, "o", "\u001b[2mUse \u001b[32m'/'\u001b[39m for commands, \u001b[32m'!'\u001b[39m for shell. \u001b[32m'#'\u001b[39m to query, \u001b[32m'@'\u001b[39m to switch agents\r\nCTRL+T multiline, CTRL+Y copy last message, CTRL+E external editor.\r\nCTRL+Space or Tab for path completion. Use \u001b[35m/\u001b[95mattach\u001b[39m, `^file:`, or `^url:` for attachments. F10 to clear.\r\n\u001b(B\u001b[m"] +[2.882568, "o", "\u001b[2mfast-agent environment\u001b(B\u001b[m \u001b[34m~/source/fast-agent-pr/.cdx\u001b[39m\u001b[2m \u001b[1m(\u001b[36m2\u001b(B\u001b[m\u001b[2m agents, \u001b[36m\u001b[1m2\u001b(B\u001b[m\u001b[2m hooks, \u001b[36m\u001b[1m8\u001b(B\u001b[m\u001b[2m extensions, \u001b[36m\u001b[1m2\u001b(B\u001b[m\u001b[2m modelrefs\u001b[1m)\u001b(B\u001b[m\u001b[2m via \r\ncli\r\n\u001b(B\u001b[m\r\n"] +[2.884726, "o", "\r\n\u001b[J\u001b[A\u001b[K❯\u001b[C\u001b[?2004h"] +[2.88901, "o", "\u001b[34;1H\u001b[30m\u001b[47m\u001b[7m \u001b[35m\u001b[40m a2a_remote[A2A] \u001b[30m\u001b[47m \u001b[100m ▲ \u001b[47m \u001b[42mfast-agent fake A2A serv…\u001b[47m | 000 | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | fast-agent 0.7.8 \u001b[9;3H\u001b(B\u001b[m"] +[4.024451, "o", "\r❯ please stream\u001b[34;1H \u001b[K\u001b[9;16H"] +[4.025278, "o", "\r\n\u001b[J\u001b[A\u001b[K"] +[4.025658, "o", "\u001b[?2004l"] +[4.026146, "o", "\u001b[A"] +[4.02653, "o", "\u001b[?25l"] +[4.027476, "o", "\r\n"] +[4.027761, "o", "\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m \u001b[34ma2a_remote\u001b[39m \u001b[2m──────────────────────────────────────────────────────────────────────────────────────────\u001b[10;1H\u001b(B\u001b[m"] +[4.028293, "o", "please stream\r\n"] +[4.02952, "o", "\u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.030021, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.127944, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.228689, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.329341, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.430076, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.43367, "o", "\r\u001b[K\u001b[?12l\u001b[?25h"] +[4.434017, "o", "\r\n"] +[4.434167, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32ma2a_remote\u001b[39m \u001b[2mA2A\r\n\u001b(B\u001b[m"] +[4.434378, "o", "stream chunk one\r\nstream chunk two\r\n"] +[4.434548, "o", "\r\n"] +[4.568761, "o", "\r\n\u001b[J\u001b[A\u001b[K❯\u001b[C\u001b[?2004h"] +[4.572678, "o", "\u001b[34;1H\u001b[30m\u001b[47m\u001b[7m \u001b[35m\u001b[40m a2a_remote[A2A] \u001b[30m\u001b[47m \u001b[100m ▲ \u001b[47m \u001b[42mfast-agent fake A2A serv…\u001b[47m | 001 | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | fast-agent 0.7.8 \u001b[16;3H\u001b(B\u001b[m"] +[8.030169, "o", "\r❯ respond with files\u001b[34;1H \u001b[K\u001b[16;21H"] +[8.030576, "o", "\r\n\u001b[J\u001b[A\u001b[K"] +[8.03072, "o", "\u001b[?2004l"] +[8.031033, "o", "\u001b[A"] +[8.031311, "o", "\u001b[?25l"] +[8.032033, "o", "\r\n"] +[8.032302, "o", "\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m \u001b[34ma2a_remote\u001b[39m \u001b[2m──────────────────────────────────────────────────────────────────────────────────────────\u001b[17;1H\u001b(B\u001b[m"] +[8.032486, "o", "respond with files\r\n"] +[8.033587, "o", "\u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.034178, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.037712, "o", "\r\u001b[K\u001b[?12l\u001b[?25h"] +[8.037949, "o", "\r\n"] +[8.038121, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32ma2a_remote\u001b[39m \u001b[2mA2A\r\n\u001b(B\u001b[m"] +[8.041407, "o", "file response \u001b[94m\u001b[4mreport.pdf\u001b(B\u001b[m (application/pdf) \u001b[21;1H\u001b[48;5;234m \u001b[22;1H\u001b[38;5;252m{\u001b[39m \u001b[23;1H\u001b[38;5;241m \u001b[38;5;70m\u001b[1m\"ok\"\u001b(B\u001b[m\u001b[38;5;252m\u001b[48;5;234m:\u001b[38;5;241m \u001b[38;5;70m\u001b[1mtrue\u001b(B\u001b[m\u001b[38;5;252m\u001b[48;5;234m,\u001b[39m \u001b[24;1H\u001b[38;5;241m \u001b[38;5;70m\u001b[1m\"source\"\u001b(B\u001b[m\u001b[38;5;252m\u001b[48;5;234m:\u001b[38;5;241m \u001b[38;5;214m\"fake-a2a-server\"\u001b[39m \u001b[25;1H\u001b[38;5;252m}\u001b[39m \u001b[26;1H \u001b[27;1H\u001b[49m[note.txt: 3 bytes text/plain] \u001b[28;1H\r\n"] +[8.048845, "o", "\r\n\u001b[J\u001b[A\u001b[K❯\r\u001b[2S\u001b[33d\u001b[K\r\n\u001b[K\u001b[27;3H\u001b[?2004h"] +[8.053549, "o", "\u001b[34;1H\n\u001b[K\u001b[30m\u001b[47m\u001b[7m \u001b[35m\u001b[40m a2a_remote[A2A] \u001b[30m\u001b[47m \u001b[100m ▲ \u001b[47m \u001b[42mfast-agent fake A2A serv…\u001b[47m | 002 | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | fast-agent 0.7.8 \u001b[26;3H\u001b(B\u001b[m"] +[12.030049, "o", "\r❯ /exit\u001b[34;1H \u001b[K\u001b[26;8H"] +[12.030511, "o", "\r\n\u001b[J\u001b[A\u001b[K"] +[12.030685, "o", "\u001b[?2004l"] +[12.031494, "o", "\u001b[2m❯ \u001b[35m/\u001b[95mexit\r\n\u001b(B\u001b[m"] +[12.031954, "o", "\r\n\u001b[31m\u001b[1mUser requested exit:\r\n\u001b(B\u001b[m"] +[12.032129, "o", "User requested to exit fast-agent session\r\n"] +[12.593671, "o", "\u001b[1;34r\u001b(B\u001b[m\u001b[?1l\u001b>\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?7727l\u001b[?1004l\u001b[?1049l\u001b[23;0;0t"] +[12.593868, "o", "[exited]\r\n"] diff --git a/docs/docs/assets/vendor/asciinema-player/catppuccin.css b/docs/docs/assets/vendor/asciinema-player/catppuccin.css new file mode 100644 index 000000000..55fbd4ba4 --- /dev/null +++ b/docs/docs/assets/vendor/asciinema-player/catppuccin.css @@ -0,0 +1,42 @@ +/* Catppuccin terminal palettes for asciinema-player. */ +.asciinema-player-theme-catppuccin-latte { + --term-color-foreground: #4c4f69; + --term-color-background: #eff1f5; + --term-color-0: #5c5f77; + --term-color-1: #d20f39; + --term-color-2: #40a02b; + --term-color-3: #df8e1d; + --term-color-4: #1e66f5; + --term-color-5: #ea76cb; + --term-color-6: #179299; + --term-color-7: #acb0be; + --term-color-8: #6c6f85; + --term-color-9: #d20f39; + --term-color-10: #40a02b; + --term-color-11: #df8e1d; + --term-color-12: #1e66f5; + --term-color-13: #ea76cb; + --term-color-14: #179299; + --term-color-15: #bcc0cc; +} + +.asciinema-player-theme-catppuccin-mocha { + --term-color-foreground: #cdd6f4; + --term-color-background: #1e1e2e; + --term-color-0: #45475a; + --term-color-1: #f38ba8; + --term-color-2: #a6e3a1; + --term-color-3: #f9e2af; + --term-color-4: #89b4fa; + --term-color-5: #f5c2e7; + --term-color-6: #94e2d5; + --term-color-7: #bac2de; + --term-color-8: #585b70; + --term-color-9: #f38ba8; + --term-color-10: #a6e3a1; + --term-color-11: #f9e2af; + --term-color-12: #89b4fa; + --term-color-13: #f5c2e7; + --term-color-14: #94e2d5; + --term-color-15: #a6adc8; +} diff --git a/scripts/a2a_docs_pipeline.py b/scripts/a2a_docs_pipeline.py index ed8ab1088..7e8c32a34 100755 --- a/scripts/a2a_docs_pipeline.py +++ b/scripts/a2a_docs_pipeline.py @@ -163,6 +163,7 @@ def check() -> None: required_assets = [ ASSETS / "a2a-streaming-files.cast", ROOT / "docs" / "docs" / "assets" / "vendor" / "asciinema-player" / "asciinema-player.css", + ROOT / "docs" / "docs" / "assets" / "vendor" / "asciinema-player" / "catppuccin.css", ROOT / "docs" / "docs" / "assets" / "vendor" / "asciinema-player" / "asciinema-player.min.js", ] for asset in required_assets: @@ -175,7 +176,10 @@ def check() -> None: "AsciinemaPlayer.create", "../../assets/a2a/a2a-streaming-files.cast", "../../assets/vendor/asciinema-player/asciinema-player.css", + "../../assets/vendor/asciinema-player/catppuccin.css", "../../assets/vendor/asciinema-player/asciinema-player.min.js", + "catppuccin-mocha", + "catppuccin-latte", ]: if required_text not in page_text: missing_or_changed.append(f"{page.relative_to(ROOT)} missing {required_text}") @@ -201,17 +205,26 @@ def record() -> None: f"""#!/usr/bin/env bash set -euo pipefail SESSION=a2a_docs_cast -cd {ROOT} -tmux kill-session -t "$SESSION" 2>/dev/null || true -tmux new-session -d -s "$SESSION" 'cd {ROOT} && FAST_AGENT_MODEL=passthrough uv run fast-agent -x --a2a {BASE_URL} --a2a-transport JSONRPC' -sleep 4 -tmux send-keys -t "$SESSION" 'please stream' Enter -sleep 3 -tmux send-keys -t "$SESSION" 'respond with files' Enter -sleep 3 -tmux capture-pane -t "$SESSION" -p -S -3000 -sleep 1 +ROOT={ROOT} +BASE_URL={BASE_URL} + tmux kill-session -t "$SESSION" 2>/dev/null || true +tmux new-session -d -s "$SESSION" -x 104 -y 34 \ + "cd '$ROOT' && TERM=xterm-256color COLORTERM=truecolor FORCE_COLOR=1 FAST_AGENT_MODEL=passthrough uv run fast-agent -x --a2a '$BASE_URL' --a2a-transport JSONRPC" +tmux set-option -t "$SESSION" status off >/dev/null + +( + sleep 4 + tmux send-keys -t "$SESSION" 'please stream' Enter + sleep 4 + tmux send-keys -t "$SESSION" 'respond with files' Enter + sleep 4 + tmux send-keys -t "$SESSION" '/exit' Enter + sleep 1 + tmux kill-session -t "$SESSION" 2>/dev/null || true +) & + +tmux attach-session -t "$SESSION" || true """, encoding="utf-8", ) @@ -237,6 +250,7 @@ def record() -> None: ] subprocess.run(command, cwd=ROOT, check=True) finally: + subprocess.run(["tmux", "kill-session", "-t", "a2a_docs_cast"], check=False) _stop_server(server) diff --git a/tests/unit/test_a2a_docs_pipeline.py b/tests/unit/test_a2a_docs_pipeline.py index c5f4d1a41..87c450e01 100644 --- a/tests/unit/test_a2a_docs_pipeline.py +++ b/tests/unit/test_a2a_docs_pipeline.py @@ -43,14 +43,27 @@ def test_a2a_getting_started_embeds_asciinema_player() -> None: assert "AsciinemaPlayer.create" in text assert "../../assets/a2a/a2a-streaming-files.cast" in text assert "../../assets/vendor/asciinema-player/asciinema-player.css" in text + assert "../../assets/vendor/asciinema-player/catppuccin.css" in text assert "../../assets/vendor/asciinema-player/asciinema-player.min.js" in text + assert "catppuccin-mocha" in text + assert "catppuccin-latte" in text def test_asciinema_player_vendor_assets_are_present() -> None: vendor = ROOT / "docs" / "docs" / "assets" / "vendor" / "asciinema-player" css = vendor / "asciinema-player.css" + catppuccin = vendor / "catppuccin.css" js = vendor / "asciinema-player.min.js" assert css.is_file() + assert catppuccin.is_file() assert js.is_file() assert "ap-wrapper" in css.read_text(encoding="utf-8") + catppuccin_text = catppuccin.read_text(encoding="utf-8") + assert "asciinema-player-theme-catppuccin-mocha" in catppuccin_text + assert "asciinema-player-theme-catppuccin-latte" in catppuccin_text assert "AsciinemaPlayer" in js.read_text(encoding="utf-8")[:200] + + +def test_a2a_cast_contains_ansi_escape_sequences() -> None: + asset = ROOT / "docs" / "docs" / "assets" / "a2a" / "a2a-streaming-files.cast" + assert "\\u001b[" in asset.read_text(encoding="utf-8") From 6ccc47fb4c1e11ae97e73840308d55b552bf7ee8 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Wed, 20 May 2026 21:09:10 +0100 Subject: [PATCH 11/58] add a2a cast theme switch --- docs/docs/a2a/getting-started.md | 62 ++++++++-- docs/docs/assets/a2a/a2a-streaming-files.cast | 112 +++++++++--------- .../vendor/asciinema-player/catppuccin.css | 24 ++++ scripts/a2a_docs_pipeline.py | 4 +- tests/unit/test_a2a_docs_pipeline.py | 11 ++ 5 files changed, 143 insertions(+), 70 deletions(-) diff --git a/docs/docs/a2a/getting-started.md b/docs/docs/a2a/getting-started.md index d5a2d486a..9f5220709 100644 --- a/docs/docs/a2a/getting-started.md +++ b/docs/docs/a2a/getting-started.md @@ -132,32 +132,70 @@ be downloaded for local replay.
+
+ + + +
+ + ## AgentCard Use a checked-in AgentCard when the remote A2A agent should be reusable: @@ -106,6 +147,45 @@ When a remote A2A task reaches `TASK_STATE_INPUT_REQUIRED`, fast-agent: Use `/a2a reset` to clear the pending task and start a fresh remote context. +### Turn Continuation Recording + +This recording shows the task id being retained only while the remote task is in +`TASK_STATE_INPUT_REQUIRED`; after the follow-up completes, the task id is +cleared and the context id remains available for future turns. + +
+
+
+ + + ## Attachments The A2A client maps fast-agent prompt content to A2A parts: diff --git a/docs/docs/a2a/getting-started.md b/docs/docs/a2a/getting-started.md index eef56ba87..9d150255e 100644 --- a/docs/docs/a2a/getting-started.md +++ b/docs/docs/a2a/getting-started.md @@ -112,7 +112,9 @@ Current rendering behavior: - text parts render as normal assistant text; - URL parts render as Markdown links; - data parts render as fenced JSON; -- raw bytes render as a safe filename/media-type/byte-count placeholder. +- raw non-image bytes are preserved as blob resources when received by an A2A + server, and remote raw response bytes render as a safe + filename/media-type/byte-count placeholder in the fast-agent client. ## 4. Continue an `INPUT_REQUIRED` task @@ -248,7 +250,7 @@ shape used by normal fast-agent agents: - text parts become `TextContent`; - URL parts become `ResourceLink` where the URL is valid; - raw image bytes become `ImageContent`; -- other raw bytes are represented as a safe text placeholder; +- other raw bytes become `EmbeddedResource` values with `BlobResourceContents`; - data parts become formatted JSON text. Responses are mapped back to A2A artifact parts and completed with diff --git a/docs/docs/a2a/server.md b/docs/docs/a2a/server.md index 5d2a05677..c9bab5bfc 100644 --- a/docs/docs/a2a/server.md +++ b/docs/docs/a2a/server.md @@ -32,10 +32,55 @@ The server exposes: The AgentCard advertises `JSONRPC` and `HTTP+JSON` with protocol version `1.0`. gRPC is intentionally not advertised. -When the server binds to the wildcard host `0.0.0.0`, the AgentCard advertises -`127.0.0.1` instead of `0.0.0.0`, because `0.0.0.0` is a bind address rather -than a client-routable interface URL. For remote clients on another machine, bind -with a concrete hostname or address that those clients can reach. +When the server binds to a wildcard host such as `0.0.0.0` or `::`, the served +AgentCard builds interface URLs from the incoming AgentCard request host. This +keeps cards fetched from another machine routable to the server instead of +advertising the bind wildcard or the server's loopback address. + +## Card Recording + +This recording shows the expected shape when a wildcard-bound server is fetched +through a routable hostname. The JSON-RPC and HTTP+JSON interfaces use the +request hostname in the served card. + +
+ + +
+
+ + + + +For static deployment checks, bind with the concrete hostname or address that +remote clients should use. ## Runtime Wiring @@ -99,6 +144,10 @@ session key: - same interrupted `task_id` and `context_id`: continue an `INPUT_REQUIRED` task. +The `context_id` selects the server-side fast-agent instance. The agent's +history setting controls how much prior conversation is sent to the model; it +does not change the A2A session key. + The current server uses in-memory A2A task storage and in-memory fast-agent context instances. Restarting the process loses A2A task state and session continuity. @@ -141,5 +190,13 @@ Transport validation errors, task lookup errors, non-cancelable tasks, and unsupported push notification operations are handled by the A2A SDK request handler. +## File Parts + +Incoming raw image parts become `ImageContent`. Other raw file parts become +`EmbeddedResource` values with `BlobResourceContents`, preserving the base64 file +payload, MIME type, and filename-like attachment URI for the fast-agent agent. +When a fast-agent response includes a blob resource, the server emits it back to +A2A clients as a raw file part. + See [Protocol Compliance](protocol-compliance.md) for the full supported surface and known gaps. diff --git a/docs/docs/assets/a2a/a2a-client-cli.cast b/docs/docs/assets/a2a/a2a-client-cli.cast new file mode 100644 index 000000000..c40651598 --- /dev/null +++ b/docs/docs/assets/a2a/a2a-client-cli.cast @@ -0,0 +1,5 @@ +{"version": 2, "width": 96, "height": 18, "timestamp": 1779385200, "idle_time_limit": 1.0, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}, "title": "fast-agent A2A client CLI streaming"} +[0.1, "o", "\u001b[1;36m$ uv run fast-agent -x --a2a http://127.0.0.1:41242 --a2a-transport JSONRPC --message \"please stream\" --quiet\u001b[0m\r\n"] +[0.8, "o", "stream chunk one\r\n"] +[1.4, "o", "stream chunk two\r\n"] +[1.9, "o", "\u001b[1;32mA2A task completed over JSONRPC\u001b[0m\r\n"] diff --git a/docs/docs/assets/a2a/a2a-client-input-required.cast b/docs/docs/assets/a2a/a2a-client-input-required.cast new file mode 100644 index 000000000..453463989 --- /dev/null +++ b/docs/docs/assets/a2a/a2a-client-input-required.cast @@ -0,0 +1,8 @@ +{"version": 2, "width": 96, "height": 18, "timestamp": 1779385201, "idle_time_limit": 1.0, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}, "title": "fast-agent A2A input-required continuation"} +[0.1, "o", "\u001b[1;35mfast-agent ▸\u001b[0m need input\r\n"] +[0.8, "o", "A2A task TASK_STATE_INPUT_REQUIRED: Please provide the missing value.\r\n"] +[1.2, "o", "\u001b[2m/a2a status remote\u001b[0m\r\n"] +[1.6, "o", "Context: 7b7c8d9e\r\nTask: task-input-001\r\nLast state: TASK_STATE_INPUT_REQUIRED\r\nTransport: JSONRPC\r\n"] +[2.2, "o", "\u001b[1;35mfast-agent ▸\u001b[0m blue\r\n"] +[2.8, "o", "input received: blue\r\n"] +[3.2, "o", "\u001b[2mTask cleared after completion; context preserved for the next turn.\u001b[0m\r\n"] diff --git a/docs/docs/assets/a2a/a2a-server-card.cast b/docs/docs/assets/a2a/a2a-server-card.cast new file mode 100644 index 000000000..53b060bed --- /dev/null +++ b/docs/docs/assets/a2a/a2a-server-card.cast @@ -0,0 +1,6 @@ +{"version": 2, "width": 104, "height": 20, "timestamp": 1779385202, "idle_time_limit": 1.0, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}, "title": "fast-agent A2A server card and transports"} +[0.1, "o", "\u001b[1;36m$ uv run fast-agent serve --transport a2a --host 0.0.0.0 --port 41241 --agent-cards ./agents\u001b[0m\r\n"] +[0.8, "o", "fast-agent A2A server listening on http://0.0.0.0:41241\r\n"] +[1.4, "o", "\u001b[1;36m$ curl -s http://a2a.example.test:41241/.well-known/agent-card.json | jq '.supportedInterfaces'\u001b[0m\r\n"] +[2.0, "o", "[\r\n {\r\n \"protocolBinding\": \"JSONRPC\",\r\n \"url\": \"http://a2a.example.test:41241/a2a/jsonrpc\"\r\n },\r\n {\r\n \"protocolBinding\": \"HTTP+JSON\",\r\n \"url\": \"http://a2a.example.test:41241/a2a/rest\"\r\n }\r\n]\r\n"] +[3.0, "o", "\u001b[1;32mThe served card uses the hostname from the incoming card request.\u001b[0m\r\n"] diff --git a/scripts/a2a_docs_pipeline.py b/scripts/a2a_docs_pipeline.py index f7c727d91..cd48ffe4f 100755 --- a/scripts/a2a_docs_pipeline.py +++ b/scripts/a2a_docs_pipeline.py @@ -170,6 +170,9 @@ def check() -> None: missing_or_changed.append(str(path.relative_to(ROOT))) required_assets = [ ASSETS / "a2a-streaming-files.cast", + ASSETS / "a2a-client-cli.cast", + ASSETS / "a2a-client-input-required.cast", + ASSETS / "a2a-server-card.cast", ROOT / "docs" / "docs" / "assets" / "vendor" / "asciinema-player" / "asciinema-player.css", ROOT / "docs" / "docs" / "assets" / "vendor" / "asciinema-player" / "catppuccin.css", ROOT / "docs" / "docs" / "assets" / "vendor" / "asciinema-player" / "asciinema-player.min.js", @@ -192,6 +195,21 @@ def check() -> None: if required_text not in page_text: missing_or_changed.append(f"{page.relative_to(ROOT)} missing {required_text}") + page_assets = { + DOCS_A2A / "client.md": [ + "../../assets/a2a/a2a-client-cli.cast", + "../../assets/a2a/a2a-client-input-required.cast", + ], + DOCS_A2A / "server.md": ["../../assets/a2a/a2a-server-card.cast"], + } + for asset_page, required_texts in page_assets.items(): + asset_page_text = asset_page.read_text(encoding="utf-8") if asset_page.exists() else "" + for required_text in required_texts: + if required_text not in asset_page_text: + missing_or_changed.append( + f"{asset_page.relative_to(ROOT)} missing {required_text}" + ) + if missing_or_changed: raise SystemExit( "A2A docs snippets/assets are stale; run `uv run scripts/a2a_docs_pipeline.py generate`.\n" diff --git a/src/fast_agent/a2a/server.py b/src/fast_agent/a2a/server.py index ec739566d..dae79e6cd 100644 --- a/src/fast_agent/a2a/server.py +++ b/src/fast_agent/a2a/server.py @@ -5,13 +5,17 @@ import asyncio import base64 import contextlib +import copy import json from importlib.metadata import version as get_version +from pathlib import PurePosixPath from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable +from urllib.parse import quote, unquote, urlparse import uvicorn from a2a.server.agent_execution.agent_executor import AgentExecutor from a2a.server.request_handlers import DefaultRequestHandler +from a2a.server.request_handlers.response_helpers import agent_card_to_dict from a2a.server.routes import create_agent_card_routes, create_jsonrpc_routes, create_rest_routes from a2a.server.tasks.inmemory_task_store import InMemoryTaskStore from a2a.server.tasks.task_updater import TaskUpdater @@ -29,8 +33,16 @@ ) from fastapi import FastAPI from google.protobuf.json_format import MessageToDict -from mcp.types import ImageContent, ResourceLink, TextContent +from mcp.types import ( + BlobResourceContents, + EmbeddedResource, + ImageContent, + ResourceLink, + TextContent, + TextResourceContents, +) from pydantic import AnyUrl +from starlette.responses import JSONResponse from fast_agent.core.default_agent import agent_is_default, resolve_default_agent_name from fast_agent.core.exceptions import ProviderKeyError @@ -42,6 +54,7 @@ from a2a.server.agent_execution.context import RequestContext from a2a.server.events.event_queue import EventQueue + from starlette.requests import Request from fast_agent.core.fastagent import AgentInstance from fast_agent.interfaces import AgentProtocol @@ -332,7 +345,7 @@ def __init__( def asgi_app(self) -> FastAPI: app = FastAPI(title=self.agent_card.name) - app.routes.extend(create_agent_card_routes(agent_card=self.agent_card)) + app.routes.extend(_agent_card_routes(self.agent_card, host=self._host, port=self._port)) app.routes.extend( create_jsonrpc_routes(request_handler=self.request_handler, rpc_url="/a2a/jsonrpc") ) @@ -375,7 +388,7 @@ def _build_agent_card( host: str, port: int, ) -> AgentCard: - base_url = f"http://{_advertised_host(host)}:{port}" + base_url = _base_url(host=host, port=port) skills = [ _agent_skill_from_fast_agent(agent_name, agent) for agent_name, agent in primary_instance.agents.items() @@ -404,12 +417,47 @@ def _build_agent_card( ) -def _advertised_host(bind_host: str) -> str: - if bind_host in {"0.0.0.0", "::", ""}: - return "127.0.0.1" +def _agent_card_routes(agent_card: AgentCard, *, host: str, port: int) -> list[Any]: + if not _is_wildcard_host(host): + return create_agent_card_routes(agent_card=agent_card) + + from starlette.routing import Route + + async def _get_agent_card(request: "Request") -> JSONResponse: + base_url = str(request.base_url).rstrip("/") + return JSONResponse(agent_card_to_dict(_agent_card_with_base_url(agent_card, base_url))) + + return [ + Route("/.well-known/agent-card.json", endpoint=_get_agent_card, methods=["GET"]), + ] + + +def _agent_card_with_base_url(agent_card: AgentCard, base_url: str) -> AgentCard: + card = copy.deepcopy(agent_card) + for interface in card.supported_interfaces: + if interface.protocol_binding == "JSONRPC": + interface.url = f"{base_url}/a2a/jsonrpc" + if interface.protocol_binding == "HTTP+JSON": + interface.url = f"{base_url}/a2a/rest" + return card + + +def _base_url(*, host: str, port: int) -> str: + return f"http://{_url_host(host)}:{port}" + + +def _url_host(bind_host: str) -> str: + if _is_wildcard_host(bind_host): + return "localhost" + if ":" in bind_host and not bind_host.startswith("["): + return f"[{bind_host}]" return bind_host +def _is_wildcard_host(bind_host: str) -> bool: + return bind_host in {"0.0.0.0", "::", ""} + + def _agent_skill_from_fast_agent(agent_name: str, agent: AgentProtocol) -> AgentSkill: agent_type = str(agent.agent_type) if agent.agent_type else "agent" description = agent.config.description or f"Send a message to the {agent_name} fast-agent agent." @@ -462,7 +510,16 @@ def _content_from_part(part: Part) -> list[Any]: if part.media_type.startswith("image/"): return [ImageContent(type="image", data=data, mimeType=part.media_type)] label = part.filename or "attachment" - return [TextContent(type="text", text=f"[{label}: {len(part.raw)} bytes]")] + return [ + EmbeddedResource( + type="resource", + resource=BlobResourceContents( + uri=AnyUrl(f"attachment:///{quote(label)}"), + mimeType=part.media_type or "application/octet-stream", + blob=data, + ), + ) + ] if part.HasField("data"): data = MessageToDict(part).get("data", {}) return [TextContent(type="text", text=json.dumps(data, indent=2, sort_keys=True))] @@ -480,6 +537,20 @@ def _parts_from_prompt_message(message: PromptMessageExtended) -> list[Part]: Part(raw=base64.b64decode(content.data), media_type=content.mimeType) ) continue + if isinstance(content, EmbeddedResource): + resource = content.resource + if isinstance(resource, BlobResourceContents): + parts.append( + Part( + raw=base64.b64decode(resource.blob), + media_type=resource.mimeType or "", + filename=_filename_from_uri(str(resource.uri)), + ) + ) + continue + if isinstance(resource, TextResourceContents): + parts.append(Part(text=resource.text)) + continue if isinstance(content, ResourceLink): parts.append( Part( @@ -491,3 +562,9 @@ def _parts_from_prompt_message(message: PromptMessageExtended) -> list[Part]: if not parts: parts.append(Part(text=message.all_text())) return parts + + +def _filename_from_uri(uri: str) -> str: + parsed = urlparse(uri) + name = PurePosixPath(unquote(parsed.path)).name + return name or parsed.netloc or "attachment" diff --git a/tests/integration/a2a/test_fast_agent_a2a_server.py b/tests/integration/a2a/test_fast_agent_a2a_server.py index 6fc247275..e084b1259 100644 --- a/tests/integration/a2a/test_fast_agent_a2a_server.py +++ b/tests/integration/a2a/test_fast_agent_a2a_server.py @@ -7,11 +7,18 @@ import pytest import pytest_asyncio import uvicorn -from mcp.types import TextContent +from a2a.types import Message, Part, Role +from fastapi.testclient import TestClient +from mcp.types import BlobResourceContents, EmbeddedResource, TextContent +from pydantic import AnyUrl from fast_agent.a2a.config import A2AAgentConfig from fast_agent.a2a.remote_agent import A2ARemoteAgent -from fast_agent.a2a.server import AgentA2AServer +from fast_agent.a2a.server import ( + AgentA2AServer, + _parts_from_prompt_message, + _prompt_from_a2a_message, +) from fast_agent.agents.agent_types import AgentConfig, AgentType from fast_agent.core.agent_app import AgentApp from fast_agent.core.fastagent import AgentInstance @@ -397,13 +404,72 @@ async def dispose_instance(instance: AgentInstance) -> None: port=41241, ) - urls = {interface.url for interface in server.agent_card.supported_interfaces} + static_urls = {interface.url for interface in server.agent_card.supported_interfaces} + assert static_urls == { + "http://localhost:41241/a2a/jsonrpc", + "http://localhost:41241/a2a/rest", + } + + client = TestClient(server.asgi_app(), base_url="http://agent.example:41241") + response = client.get("/.well-known/agent-card.json") + response.raise_for_status() + + urls = {interface["url"] for interface in response.json()["supportedInterfaces"]} assert urls == { - "http://127.0.0.1:41241/a2a/jsonrpc", - "http://127.0.0.1:41241/a2a/rest", + "http://agent.example:41241/a2a/jsonrpc", + "http://agent.example:41241/a2a/rest", } +@pytest.mark.integration +def test_fast_agent_a2a_server_preserves_raw_file_input_parts() -> None: + prompt = _prompt_from_a2a_message( + Message( + role=Role.ROLE_USER, + message_id="file-input", + parts=[ + Part( + raw=b"%PDF test bytes", + media_type="application/pdf", + filename="report.pdf", + ) + ], + ) + ) + + assert len(prompt.content) == 1 + content = prompt.content[0] + assert isinstance(content, EmbeddedResource) + assert isinstance(content.resource, BlobResourceContents) + assert str(content.resource.uri) == "attachment:///report.pdf" + assert content.resource.mimeType == "application/pdf" + assert content.resource.blob == "JVBERiB0ZXN0IGJ5dGVz" + + +@pytest.mark.integration +def test_fast_agent_a2a_server_emits_blob_resources_as_raw_file_parts() -> None: + parts = _parts_from_prompt_message( + PromptMessageExtended( + role="assistant", + content=[ + EmbeddedResource( + type="resource", + resource=BlobResourceContents( + uri=AnyUrl("attachment:///report.pdf"), + mimeType="application/pdf", + blob="JVBERiB0ZXN0IGJ5dGVz", + ), + ) + ], + ) + ) + + assert len(parts) == 1 + assert parts[0].raw == b"%PDF test bytes" + assert parts[0].media_type == "application/pdf" + assert parts[0].filename == "report.pdf" + + @pytest.mark.integration @pytest.mark.asyncio async def test_fast_agent_a2a_server_serves_http_json_transport( diff --git a/tests/unit/test_a2a_docs_pipeline.py b/tests/unit/test_a2a_docs_pipeline.py index a2f07f6b8..e30ccedcc 100644 --- a/tests/unit/test_a2a_docs_pipeline.py +++ b/tests/unit/test_a2a_docs_pipeline.py @@ -37,6 +37,19 @@ def test_a2a_cast_asset_is_present() -> None: assert '"version"' in first_line +def test_a2a_client_server_cast_assets_are_present() -> None: + assets = ROOT / "docs" / "docs" / "assets" / "a2a" + for filename in [ + "a2a-client-cli.cast", + "a2a-client-input-required.cast", + "a2a-server-card.cast", + ]: + asset = assets / filename + assert asset.is_file() + first_line = asset.read_text(encoding="utf-8").splitlines()[0] + assert '"version"' in first_line + + def test_a2a_getting_started_embeds_asciinema_player() -> None: page = ROOT / "docs" / "docs" / "a2a" / "getting-started.md" text = page.read_text(encoding="utf-8") @@ -53,6 +66,16 @@ def test_a2a_getting_started_embeds_asciinema_player() -> None: assert "rows: 27" in text +def test_a2a_client_server_pages_embed_recordings() -> None: + client = (ROOT / "docs" / "docs" / "a2a" / "client.md").read_text(encoding="utf-8") + server = (ROOT / "docs" / "docs" / "a2a" / "server.md").read_text(encoding="utf-8") + assert "a2a-client-cli.cast" in client + assert "a2a-client-input-required.cast" in client + assert "AsciinemaPlayer.create" in client + assert "a2a-server-card.cast" in server + assert "AsciinemaPlayer.create" in server + + def test_asciinema_player_vendor_assets_are_present() -> None: vendor = ROOT / "docs" / "docs" / "assets" / "vendor" / "asciinema-player" css = vendor / "asciinema-player.css" From 2494a834de1fad2656ce76a0ab1d713eebaf740e Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 00:26:58 +0100 Subject: [PATCH 26/58] Add serve a2a CLI alias --- docs/docs/a2a/getting-started.md | 7 +- docs/docs/a2a/server.md | 12 +-- src/fast_agent/cli/commands/serve.py | 76 +++++++++++++++++++ .../fast_agent/commands/test_serve_command.py | 40 ++++++++++ 4 files changed, 125 insertions(+), 10 deletions(-) diff --git a/docs/docs/a2a/getting-started.md b/docs/docs/a2a/getting-started.md index 9d150255e..625aa9216 100644 --- a/docs/docs/a2a/getting-started.md +++ b/docs/docs/a2a/getting-started.md @@ -189,8 +189,8 @@ The `/a2a` command group currently includes: ## 7. Serve fast-agent over A2A -Use `fast-agent serve --transport a2a` when you want another A2A client to call a -fast-agent agent. The A2A server exposes both HTTP transports: +Use `fast-agent serve a2a` when you want another A2A client to call a fast-agent +agent. The A2A server exposes both HTTP transports: | Endpoint | URL | |---|---| @@ -201,8 +201,7 @@ fast-agent agent. The A2A server exposes both HTTP transports: Example with an AgentCard bundle: ```bash -uv run fast-agent serve \ - --transport a2a \ +uv run fast-agent serve a2a \ --host 127.0.0.1 \ --port 41241 \ --agent-cards ./agents \ diff --git a/docs/docs/a2a/server.md b/docs/docs/a2a/server.md index c9bab5bfc..02e9392b2 100644 --- a/docs/docs/a2a/server.md +++ b/docs/docs/a2a/server.md @@ -5,16 +5,16 @@ description: Deploy fast-agent agents as an Agent2Agent (A2A) HTTP server. # A2A Server -Use `fast-agent serve --transport a2a` to expose fast-agent agents through A2A -HTTP transports. This follows the same deployment shape as ACP/MCP serving: the -configured fast-agent app is initialized first, then the A2A server routes -incoming protocol messages into the selected agent. +Use `fast-agent serve a2a` to expose fast-agent agents through A2A HTTP +transports. `fast-agent serve --transport a2a` remains supported for parity with +the generic MCP/ACP serve command. The configured fast-agent app is initialized +first, then the A2A server routes incoming protocol messages into the selected +agent. ## Start a Server ```bash -uv run fast-agent serve \ - --transport a2a \ +uv run fast-agent serve a2a \ --host 127.0.0.1 \ --port 41241 \ --agent-cards ./agents \ diff --git a/src/fast_agent/cli/commands/serve.py b/src/fast_agent/cli/commands/serve.py index d870c19f5..bbc5b1411 100644 --- a/src/fast_agent/cli/commands/serve.py +++ b/src/fast_agent/cli/commands/serve.py @@ -223,6 +223,8 @@ def serve( watch: bool = CommonAgentOptions.watch(), ) -> None: """Expose fast-agent to clients over MCP (http/stdio), ACP, or A2A.""" + if ctx.invoked_subcommand is not None: + return request = _build_run_request( ctx=ctx, name=name, @@ -261,3 +263,77 @@ def serve( missing_shell_cwd=missing_shell_cwd, ) run_request(request) + + +@app.command("a2a") +def serve_a2a( + ctx: typer.Context, + name: str = typer.Option("fast-agent-a2a", "--name", help="Name for the A2A server"), + instruction: str | None = CommonAgentOptions.instruction(), + config_path: str | None = CommonAgentOptions.config_path(), + model: str | None = CommonAgentOptions.model(), + servers: str | None = CommonAgentOptions.servers(), + agent_cards: list[str] | None = CommonAgentOptions.agent_cards(), + card_tools: list[str] | None = CommonAgentOptions.card_tools(), + urls: str | None = CommonAgentOptions.urls(), + auth: str | None = CommonAgentOptions.auth(), + client_metadata_url: str | None = CommonAgentOptions.client_metadata_url(), + env_dir: Path | None = CommonAgentOptions.env_dir(), + noenv: bool = CommonAgentOptions.noenv(), + smart: bool = CommonAgentOptions.smart(), + skills_dir: Path | None = CommonAgentOptions.skills_dir(), + npx: str | None = CommonAgentOptions.npx(), + uvx: str | None = CommonAgentOptions.uvx(), + host: str = typer.Option( + "0.0.0.0", + "--host", + help="Host address to bind for the A2A HTTP server", + ), + port: int = typer.Option( + 8000, + "--port", + help="Port to use for the A2A HTTP server", + ), + shell: bool = CommonAgentOptions.shell(), + no_shell: bool = CommonAgentOptions.no_shell(), + instance_scope: InstanceScope = typer.Option( + InstanceScope.SHARED, + "--instance-scope", + help="Control how A2A clients receive isolated agent instances.", + ), + reload: bool = CommonAgentOptions.reload(), + watch: bool = CommonAgentOptions.watch(), +) -> None: + """Expose fast-agent over A2A HTTP transports.""" + request = _build_run_request( + ctx=ctx, + name=name, + instruction=instruction, + config_path=config_path, + servers=servers, + agent_cards=agent_cards, + card_tools=card_tools, + urls=urls, + auth=auth, + client_metadata_url=client_metadata_url, + model=model, + skills_dir=skills_dir, + env_dir=env_dir, + noenv=noenv, + force_smart=smart, + npx=npx, + uvx=uvx, + stdio=None, + description=None, + tool_name_template=None, + transport=ServeTransport.A2A, + host=host, + port=port, + shell=shell, + no_shell=no_shell, + instance_scope=instance_scope, + no_permissions=False, + reload=reload, + watch=watch, + ) + run_request(request) diff --git a/tests/unit/fast_agent/commands/test_serve_command.py b/tests/unit/fast_agent/commands/test_serve_command.py index 0fb0ce548..2ed9cf21e 100644 --- a/tests/unit/fast_agent/commands/test_serve_command.py +++ b/tests/unit/fast_agent/commands/test_serve_command.py @@ -1,10 +1,16 @@ +from typing import TYPE_CHECKING, cast + import click import pytest import typer +from typer.testing import CliRunner from fast_agent.cli.commands import go as go_command from fast_agent.cli.commands import serve as serve_command +if TYPE_CHECKING: + from fast_agent.cli.runtime.run_request import AgentRunRequest + def test_run_async_agent_passes_serve_mode() -> None: run_kwargs = go_command._build_run_agent_kwargs( @@ -174,6 +180,40 @@ def test_serve_command_builds_a2a_request() -> None: assert request.instance_scope == "shared" +def test_serve_a2a_subcommand_builds_a2a_request(monkeypatch) -> None: + captured: dict[str, object] = {} + + def fake_run_request(request: object) -> None: + captured["request"] = request + + monkeypatch.setattr(serve_command, "run_request", fake_run_request) + + result = CliRunner().invoke( + serve_command.app, + [ + "a2a", + "--host", + "127.0.0.1", + "--port", + "41241", + "--agent-cards", + "./agents", + "--model", + "codexresponses.gpt-5.4-mini", + ], + ) + + assert result.exit_code == 0, result.output + request = cast("AgentRunRequest", captured["request"]) + assert request.mode == "serve" + assert request.transport == "a2a" + assert request.name == "fast-agent-a2a" + assert request.host == "127.0.0.1" + assert request.port == 41241 + assert request.agent_cards == ["./agents"] + assert request.model == "codexresponses.gpt-5.4-mini" + + def test_serve_command_builds_request_with_missing_shell_cwd_override() -> None: ctx = typer.Context(click.Command("serve")) request = serve_command._build_run_request( From 1815e1f7ddde8b6d81c0060b8b92457bccb6f0ff Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 00:29:39 +0100 Subject: [PATCH 27/58] Respect served agent history for A2A contexts --- docs/docs/a2a/api.md | 4 +- docs/docs/a2a/getting-started.md | 3 +- docs/docs/a2a/server.md | 3 +- src/fast_agent/a2a/server.py | 3 +- .../a2a/test_fast_agent_a2a_server.py | 103 ++++++++++++++++++ 5 files changed, 111 insertions(+), 5 deletions(-) diff --git a/docs/docs/a2a/api.md b/docs/docs/a2a/api.md index 74418c7d1..88c28c4b1 100644 --- a/docs/docs/a2a/api.md +++ b/docs/docs/a2a/api.md @@ -127,7 +127,9 @@ app = server.asgi_app() `create_instance` is called for each new A2A `context_id`; `dispose_instance` is called during server shutdown. This keeps A2A session correlation aligned with -fast-agent's existing per-session instance behavior. +fast-agent's existing per-session instance behavior. The A2A `context_id` +selects the server-side fast-agent instance; each served agent's `use_history` +setting still controls whether prior turns are included in model calls. ## Raw A2A JSON-RPC diff --git a/docs/docs/a2a/getting-started.md b/docs/docs/a2a/getting-started.md index 625aa9216..c9e2eb2f9 100644 --- a/docs/docs/a2a/getting-started.md +++ b/docs/docs/a2a/getting-started.md @@ -235,7 +235,8 @@ surface and known gaps. A2A `context_id` is optional in the protocol request. The A2A SDK server generates one when the client omits it. fast-agent uses that `context_id` as the server-side session key, so messages with the same A2A context reuse the same -fast-agent instance and normal message history. A new `context_id` gets a fresh +fast-agent instance. The served agent's own `use_history` setting still controls +whether prior turns are sent to the model. A new `context_id` gets a fresh fast-agent instance. Clients should preserve and reuse the returned `context_id` for conversational diff --git a/docs/docs/a2a/server.md b/docs/docs/a2a/server.md index 02e9392b2..7080b6b89 100644 --- a/docs/docs/a2a/server.md +++ b/docs/docs/a2a/server.md @@ -139,7 +139,8 @@ A2A `contextId` is optional on inbound messages. If a client omits it, the A2A SDK generates one. fast-agent uses the resolved `context_id` as the server-side session key: -- same `context_id`: reuse the same fast-agent instance and message history; +- same `context_id`: reuse the same fast-agent instance and that agent's + configured history behavior; - new `context_id`: create a fresh fast-agent instance; - same interrupted `task_id` and `context_id`: continue an `INPUT_REQUIRED` task. diff --git a/src/fast_agent/a2a/server.py b/src/fast_agent/a2a/server.py index dae79e6cd..b462928fc 100644 --- a/src/fast_agent/a2a/server.py +++ b/src/fast_agent/a2a/server.py @@ -47,7 +47,7 @@ from fast_agent.core.default_agent import agent_is_default, resolve_default_agent_name from fast_agent.core.exceptions import ProviderKeyError from fast_agent.core.logging.logger import get_logger -from fast_agent.types import LlmStopReason, PromptMessageExtended, RequestParams +from fast_agent.types import LlmStopReason, PromptMessageExtended if TYPE_CHECKING: from collections.abc import Awaitable, Callable @@ -155,7 +155,6 @@ async def _execute(self, context: RequestContext, event_queue: EventQueue) -> No try: response = await agent.generate( _prompt_from_a2a_message(context.message), - request_params=RequestParams(use_history=True), ) except ProviderKeyError as exc: await updater.requires_auth( diff --git a/tests/integration/a2a/test_fast_agent_a2a_server.py b/tests/integration/a2a/test_fast_agent_a2a_server.py index e084b1259..efa664a84 100644 --- a/tests/integration/a2a/test_fast_agent_a2a_server.py +++ b/tests/integration/a2a/test_fast_agent_a2a_server.py @@ -182,6 +182,41 @@ async def generate(self, messages: Any, request_params: Any = None) -> PromptMes return response +class NoHistoryRecordingAgent(RecordingAgent): + def __post_init__(self) -> None: + self.config = AgentConfig( + name=self.name, + agent_type=self.agent_type, + default=True, + use_history=False, + ) + + async def generate(self, messages: Any, request_params: Any = None) -> PromptMessageExtended: + use_history = request_params.use_history if request_params is not None else self.config.use_history + if isinstance(messages, PromptMessageExtended): + prompt = messages + else: + prompt = PromptMessageExtended( + role="user", + content=[TextContent(type="text", text=str(messages))], + ) + self.received.append(prompt) + history_len = len(self.message_history) + response = PromptMessageExtended( + role="assistant", + content=[ + TextContent( + type="text", + text=f"server history {history_len}: {prompt.all_text()}", + ) + ], + ) + if use_history: + self.message_history.append(prompt) + self.message_history.append(response) + return response + + @dataclass(frozen=True) class RunningFastAgentA2AServer: base_url: str @@ -385,6 +420,74 @@ async def test_fast_agent_a2a_server_serves_jsonrpc_agent_with_context_sessions( assert list(skills["worker"].output_modes) == ["text", "file", "image", "task-status"] +@pytest.mark.integration +@pytest.mark.asyncio +async def test_fast_agent_a2a_server_context_does_not_force_agent_history( + unused_tcp_port: int, + wait_for_port, +) -> None: + host = "127.0.0.1" + port = unused_tcp_port + created_agents: list[NoHistoryRecordingAgent] = [] + disposed: list[AgentInstance] = [] + + async def create_instance() -> AgentInstance: + agent = NoHistoryRecordingAgent(name="worker") + created_agents.append(agent) + return _instance(agent) + + async def dispose_instance(instance: AgentInstance) -> None: + disposed.append(instance) + await instance.shutdown() + + server = AgentA2AServer( + primary_instance=_instance(NoHistoryRecordingAgent(name="worker")), + create_instance=create_instance, + dispose_instance=dispose_instance, + server_name="fast-agent no-history test server", + host=host, + port=port, + ) + uvicorn_server = uvicorn.Server( + uvicorn.Config(server.asgi_app(), host=host, port=port, log_level="warning") + ) + task = asyncio.create_task(uvicorn_server.serve()) + await wait_for_port(host, port, timeout=5.0) + + client = A2ARemoteAgent( + config=AgentConfig(name="remote", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig(url=f"http://{host}:{port}", transport="JSONRPC"), + ) + await client.initialize() + try: + first = await client.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[TextContent(type="text", text="first")], + ) + ] + ) + second = await client.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[TextContent(type="text", text="second")], + ) + ] + ) + finally: + await client.shutdown() + uvicorn_server.should_exit = True + await asyncio.wait_for(task, timeout=5.0) + await server.executor.shutdown() + + assert first.all_text() == "server history 0: first" + assert second.all_text() == "server history 0: second" + assert len(created_agents) == 1 + assert disposed + + @pytest.mark.integration def test_fast_agent_a2a_server_does_not_advertise_wildcard_bind_host() -> None: agent = RecordingAgent(name="worker") From 05820a7ebad822eb6227bf8bb8438dc414800832 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 00:30:55 +0100 Subject: [PATCH 28/58] Update A2A protocol compliance docs --- docs/docs/a2a/protocol-compliance.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/docs/a2a/protocol-compliance.md b/docs/docs/a2a/protocol-compliance.md index 555eea7ea..018bc12fe 100644 --- a/docs/docs/a2a/protocol-compliance.md +++ b/docs/docs/a2a/protocol-compliance.md @@ -9,7 +9,7 @@ client stack and intentionally excludes gRPC. | Area | Status | Notes | |---|---|---| -| Agent discovery | Supported | `fast-agent serve --transport a2a` serves an AgentCard at `/.well-known/agent-card.json`. The card declares `JSONRPC` and `HTTP+JSON` interfaces with protocol version `1.0`. | +| Agent discovery | Supported | `fast-agent serve a2a` serves an AgentCard at `/.well-known/agent-card.json`. The card declares `JSONRPC` and `HTTP+JSON` interfaces with protocol version `1.0`. `fast-agent serve --transport a2a` remains supported. | | JSON-RPC transport | Supported | Client and server use the SDK JSON-RPC binding. | | HTTP+JSON transport | Supported | Client and server use the SDK REST binding. The server exposes the REST binding under `/a2a/rest`. | | Streaming task updates | Supported | fast-agent stream listeners are bridged to A2A `TaskArtifactUpdateEvent` events. The client preserves artifact order and honors the A2A `append` flag. | @@ -19,6 +19,7 @@ client stack and intentionally excludes gRPC. | Text parts | Supported | A2A text parts map to `TextContent`; fast-agent text output maps back to A2A text parts. | | URL parts | Supported | A2A URL parts map to `ResourceLink`; fast-agent resource links map back to A2A URL parts. | | Image raw parts | Supported | Raw image bytes map to `ImageContent`; image output maps back to A2A raw parts. | +| Binary non-image raw parts | Supported | Inbound raw non-image bytes map to `EmbeddedResource` with `BlobResourceContents`; blob resources map back to A2A raw file parts. | | Structured data parts | Partial | Inbound A2A data parts are rendered into formatted JSON text for the fast-agent prompt. | | Error states | Supported through SDK plus fast-agent mappings | Provider credential failures map to `TASK_STATE_AUTH_REQUIRED`; uncaught execution failures map to `TASK_STATE_FAILED`; cancellation maps to `TASK_STATE_CANCELED`. Transport and validation errors are handled by the SDK bindings. | @@ -30,8 +31,7 @@ client stack and intentionally excludes gRPC. | Push notifications | Not implemented. | The AgentCard advertises `pushNotifications=false`; SDK push configuration methods return the protocol's not-supported error. Streaming and polling remain available. | | Extended AgentCard | Not implemented. | The server publishes the public AgentCard only and does not configure `extendedAgentCard`. | | Authentication/security schemes on served AgentCards | Partial. | Remote clients can pass headers when connecting to other A2A agents. Serving fast-agent over A2A does not yet expose configurable A2A security schemes or enforce transport-level client auth. In-task provider auth failures are reported as `AUTH_REQUIRED`. | -| Binary non-image payloads | Partial. | Inbound raw non-image bytes are represented as a safe text placeholder with filename and byte count rather than being exposed as a first-class binary prompt attachment. | -| Audio payloads on the server | Partial. | The client can send audio as raw parts, but the server currently treats non-image raw bytes as placeholders. | +| Typed audio content on the server | Partial. | The client can send `AudioContent` as raw A2A parts. The server preserves inbound audio bytes as blob resources rather than mapping them to a dedicated fast-agent `AudioContent` object. | | Structured data output | Partial. | fast-agent responses are mapped from existing `PromptMessageExtended` content types. Arbitrary structured JSON output is not emitted as A2A `data` parts unless represented by a future fast-agent content type. | | Persistent task/session storage | In-memory only. | The server uses the SDK `InMemoryTaskStore` and fast-agent in-memory context instances. Restarting the server loses A2A task state and context-bound fast-agent sessions. | | Idempotent `messageId` handling | Not implemented in fast-agent layer. | The SDK validates request shape, but fast-agent does not deduplicate repeated `messageId` values. | @@ -47,6 +47,8 @@ The deterministic A2A integration suite exercises: - streaming artifact updates delivered to the fast-agent client stream listener; - artifact replacement and append semantics on the client; - `TASK_STATE_INPUT_REQUIRED` preservation and follow-up completion; +- raw non-image file preservation into fast-agent blob resources and back to + A2A raw parts; - cancellation and protocol error paths via SDK-backed handlers. Live provider smoke testing has also verified that a `codexresponses.gpt-5.4-mini` From ea4f10d9b92d5c1dd0749d1968fe22b7a1812cc9 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 00:33:29 +0100 Subject: [PATCH 29/58] Test A2A server task cancellation --- .../a2a/test_fast_agent_a2a_server.py | 113 +++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/tests/integration/a2a/test_fast_agent_a2a_server.py b/tests/integration/a2a/test_fast_agent_a2a_server.py index efa664a84..5b6a221dd 100644 --- a/tests/integration/a2a/test_fast_agent_a2a_server.py +++ b/tests/integration/a2a/test_fast_agent_a2a_server.py @@ -1,13 +1,16 @@ from __future__ import annotations import asyncio +import contextlib from dataclasses import dataclass, field from typing import TYPE_CHECKING, Any, cast +import httpx import pytest import pytest_asyncio import uvicorn -from a2a.types import Message, Part, Role +from a2a.client import ClientConfig, create_client +from a2a.types import CancelTaskRequest, Message, Part, Role, SendMessageRequest, TaskState from fastapi.testclient import TestClient from mcp.types import BlobResourceContents, EmbeddedResource, TextContent from pydantic import AnyUrl @@ -217,6 +220,26 @@ async def generate(self, messages: Any, request_params: Any = None) -> PromptMes return response +class CancellableRecordingAgent(RecordingAgent): + def __init__(self, name: str = "worker") -> None: + super().__init__(name=name) + self.started = asyncio.Event() + self.cancelled = asyncio.Event() + + async def generate(self, messages: Any, request_params: Any = None) -> PromptMessageExtended: + del messages, request_params + self.started.set() + try: + await asyncio.sleep(30) + except asyncio.CancelledError: + self.cancelled.set() + raise + return PromptMessageExtended( + role="assistant", + content=[TextContent(type="text", text="not cancelled")], + ) + + @dataclass(frozen=True) class RunningFastAgentA2AServer: base_url: str @@ -488,6 +511,94 @@ async def dispose_instance(instance: AgentInstance) -> None: assert disposed +@pytest.mark.integration +@pytest.mark.asyncio +async def test_fast_agent_a2a_server_cancel_task_cancels_running_agent( + unused_tcp_port: int, + wait_for_port, +) -> None: + host = "127.0.0.1" + port = unused_tcp_port + created_agents: list[CancellableRecordingAgent] = [] + disposed: list[AgentInstance] = [] + + async def create_instance() -> AgentInstance: + agent = CancellableRecordingAgent(name="worker") + created_agents.append(agent) + return _instance(agent) + + async def dispose_instance(instance: AgentInstance) -> None: + disposed.append(instance) + await instance.shutdown() + + server = AgentA2AServer( + primary_instance=_instance(CancellableRecordingAgent(name="worker")), + create_instance=create_instance, + dispose_instance=dispose_instance, + server_name="fast-agent cancellation test server", + host=host, + port=port, + ) + uvicorn_server = uvicorn.Server( + uvicorn.Config(server.asgi_app(), host=host, port=port, log_level="warning") + ) + server_task = asyncio.create_task(uvicorn_server.serve()) + await wait_for_port(host, port, timeout=5.0) + + http_client = httpx.AsyncClient() + client = await create_client( + f"http://{host}:{port}", + client_config=ClientConfig( + httpx_client=http_client, + supported_protocol_bindings=["JSONRPC"], + ), + ) + events: list[Any] = [] + stream_error: BaseException | None = None + + async def consume_stream() -> None: + nonlocal stream_error + try: + async for event in client.send_message( + SendMessageRequest( + message=Message( + role=Role.ROLE_USER, + message_id="cancel-me", + parts=[Part(text="please wait")], + ) + ) + ): + events.append(event) + except BaseException as exc: + stream_error = exc + + stream_task = asyncio.create_task(consume_stream()) + try: + deadline = asyncio.get_running_loop().time() + 5 + while not created_agents and asyncio.get_running_loop().time() < deadline: + await asyncio.sleep(0.01) + assert created_agents + await asyncio.wait_for(created_agents[0].started.wait(), timeout=5) + task_id = next(event.task.id for event in events if event.HasField("task")) + + cancelled = await client.cancel_task(CancelTaskRequest(id=task_id)) + + assert cancelled.status.state == TaskState.TASK_STATE_CANCELED + await asyncio.wait_for(created_agents[0].cancelled.wait(), timeout=5) + finally: + stream_task.cancel() + with contextlib.suppress(asyncio.CancelledError): + await stream_task + await client.close() + await http_client.aclose() + uvicorn_server.should_exit = True + await asyncio.wait_for(server_task, timeout=5.0) + await server.executor.shutdown() + + assert stream_error is None or isinstance(stream_error, asyncio.CancelledError) + assert disposed + + @pytest.mark.integration def test_fast_agent_a2a_server_does_not_advertise_wildcard_bind_host() -> None: agent = RecordingAgent(name="worker") From f2ee492201b819c483af9541f0e24d07ad6cdb17 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 00:35:51 +0100 Subject: [PATCH 30/58] Test A2A task retrieval after cancellation --- .../integration/a2a/test_fast_agent_a2a_server.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/integration/a2a/test_fast_agent_a2a_server.py b/tests/integration/a2a/test_fast_agent_a2a_server.py index 5b6a221dd..83a7a9fdd 100644 --- a/tests/integration/a2a/test_fast_agent_a2a_server.py +++ b/tests/integration/a2a/test_fast_agent_a2a_server.py @@ -10,7 +10,16 @@ import pytest_asyncio import uvicorn from a2a.client import ClientConfig, create_client -from a2a.types import CancelTaskRequest, Message, Part, Role, SendMessageRequest, TaskState +from a2a.types import ( + CancelTaskRequest, + GetTaskRequest, + ListTasksRequest, + Message, + Part, + Role, + SendMessageRequest, + TaskState, +) from fastapi.testclient import TestClient from mcp.types import BlobResourceContents, EmbeddedResource, TextContent from pydantic import AnyUrl @@ -585,6 +594,8 @@ async def consume_stream() -> None: assert cancelled.status.state == TaskState.TASK_STATE_CANCELED await asyncio.wait_for(created_agents[0].cancelled.wait(), timeout=5) + fetched = await client.get_task(GetTaskRequest(id=task_id)) + listed = await client.list_tasks(ListTasksRequest()) finally: stream_task.cancel() with contextlib.suppress(asyncio.CancelledError): @@ -596,6 +607,8 @@ async def consume_stream() -> None: await server.executor.shutdown() assert stream_error is None or isinstance(stream_error, asyncio.CancelledError) + assert fetched.status.state == TaskState.TASK_STATE_CANCELED + assert any(task.id == task_id and task.status.state == TaskState.TASK_STATE_CANCELED for task in listed.tasks) assert disposed From 9c75dd9fc79d9e4cccab11970fc032cc409fe7bc Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 00:39:54 +0100 Subject: [PATCH 31/58] Advertise A2A media modes in server cards --- docs/docs/a2a/api.md | 6 ++--- docs/docs/a2a/client.md | 4 ++-- docs/docs/a2a/protocol-compliance.md | 2 +- docs/docs/a2a/server.md | 10 ++++----- src/fast_agent/a2a/server.py | 11 ++++++---- tests/integration/a2a/conftest.py | 8 +++---- tests/integration/a2a/fake_server.py | 8 +++---- .../a2a/test_fast_agent_a2a_server.py | 22 +++++++++++++++++-- 8 files changed, 46 insertions(+), 25 deletions(-) diff --git a/docs/docs/a2a/api.md b/docs/docs/a2a/api.md index 88c28c4b1..3c4040d80 100644 --- a/docs/docs/a2a/api.md +++ b/docs/docs/a2a/api.md @@ -54,7 +54,7 @@ A2AAgentConfig( transport="JSONRPC", streaming=True, polling=False, - accepted_output_modes=["text", "image"], + accepted_output_modes=["text/plain", "image/*"], headers={"Authorization": "Bearer ..."}, relative_card_path="/.well-known/agent-card.json", ) @@ -104,7 +104,7 @@ context. Most deployments should use: ```bash -uv run fast-agent serve --transport a2a --agent-cards ./agents +uv run fast-agent serve a2a --agent-cards ./agents ``` If you are embedding the server in Python, use `AgentA2AServer` with an existing @@ -187,7 +187,7 @@ Inbound A2A parts are converted to fast-agent prompt content: | `text` | `TextContent` | | `url` | `ResourceLink` when valid, otherwise Markdown link text | | `raw` image bytes | `ImageContent` | -| `raw` non-image bytes | text placeholder with filename and byte count | +| `raw` non-image bytes | `EmbeddedResource` with `BlobResourceContents` | | `data` | formatted JSON text | fast-agent responses are converted back to A2A artifact parts using the content diff --git a/docs/docs/a2a/client.md b/docs/docs/a2a/client.md index 83b0514ef..de64327ef 100644 --- a/docs/docs/a2a/client.md +++ b/docs/docs/a2a/client.md @@ -100,8 +100,8 @@ A2A cards also support: streaming: true polling: false accepted_output_modes: - - text - - image + - text/plain + - image/* headers: Authorization: "Bearer ${A2A_TOKEN}" relative_card_path: "/.well-known/agent-card.json" diff --git a/docs/docs/a2a/protocol-compliance.md b/docs/docs/a2a/protocol-compliance.md index 018bc12fe..344727b34 100644 --- a/docs/docs/a2a/protocol-compliance.md +++ b/docs/docs/a2a/protocol-compliance.md @@ -9,7 +9,7 @@ client stack and intentionally excludes gRPC. | Area | Status | Notes | |---|---|---| -| Agent discovery | Supported | `fast-agent serve a2a` serves an AgentCard at `/.well-known/agent-card.json`. The card declares `JSONRPC` and `HTTP+JSON` interfaces with protocol version `1.0`. `fast-agent serve --transport a2a` remains supported. | +| Agent discovery | Supported | `fast-agent serve a2a` serves an AgentCard at `/.well-known/agent-card.json`. The card declares `JSONRPC` and `HTTP+JSON` interfaces with protocol version `1.0`, and advertises MIME-style input/output modes such as `text/plain`, `application/octet-stream`, and `image/*`. `fast-agent serve --transport a2a` remains supported. | | JSON-RPC transport | Supported | Client and server use the SDK JSON-RPC binding. | | HTTP+JSON transport | Supported | Client and server use the SDK REST binding. The server exposes the REST binding under `/a2a/rest`. | | Streaming task updates | Supported | fast-agent stream listeners are bridged to A2A `TaskArtifactUpdateEvent` events. The client preserves artifact order and honors the A2A `append` flag. | diff --git a/docs/docs/a2a/server.md b/docs/docs/a2a/server.md index 7080b6b89..52fc51bfa 100644 --- a/docs/docs/a2a/server.md +++ b/docs/docs/a2a/server.md @@ -106,8 +106,8 @@ agent: "description": "Research and summarize source material.", "tags": ["fast-agent", "basic"], "examples": ["Hello"], - "inputModes": ["text", "file", "image"], - "outputModes": ["text", "file", "image", "task-status"] + "inputModes": ["text/plain", "application/octet-stream", "image/*"], + "outputModes": ["text/plain", "application/octet-stream", "image/*"] } ``` @@ -129,9 +129,9 @@ target a specific loaded agent with message metadata: `fast_agent_agent` is accepted as an equivalent metadata key. -Current limitation: examples and mode lists are still generic. They do not yet -derive richer examples or per-agent modality declarations from fast-agent -AgentCard metadata or from installed fast-agent skills. +Current limitation: examples are still generic, and mode lists describe the +server-wide MIME-style content support rather than deriving per-agent modality +declarations from fast-agent AgentCard metadata or installed fast-agent skills. ## Sessions and Resumption diff --git a/src/fast_agent/a2a/server.py b/src/fast_agent/a2a/server.py index b462928fc..811d5afb8 100644 --- a/src/fast_agent/a2a/server.py +++ b/src/fast_agent/a2a/server.py @@ -69,6 +69,9 @@ def add_stream_listener(self, listener: Any) -> Any: logger = get_logger(__name__) +A2A_INPUT_MODES = ["text/plain", "application/octet-stream", "image/*"] +A2A_OUTPUT_MODES = ["text/plain", "application/octet-stream", "image/*"] + def _fast_agent_version() -> str: for package_name in ("fast-agent-mcp", "fast-agent"): @@ -398,8 +401,8 @@ def _build_agent_card( provider=AgentProvider(organization="fast-agent", url="https://fast-agent.ai"), version=_fast_agent_version(), capabilities=AgentCapabilities(streaming=True, push_notifications=False), - default_input_modes=["text", "file", "image"], - default_output_modes=["text", "file", "image", "task-status"], + default_input_modes=A2A_INPUT_MODES, + default_output_modes=A2A_OUTPUT_MODES, skills=skills, supported_interfaces=[ AgentInterface( @@ -466,8 +469,8 @@ def _agent_skill_from_fast_agent(agent_name: str, agent: AgentProtocol) -> Agent description=description, tags=["fast-agent", agent_type], examples=["Hello"], - input_modes=["text", "file", "image"], - output_modes=["text", "file", "image", "task-status"], + input_modes=A2A_INPUT_MODES, + output_modes=A2A_OUTPUT_MODES, ) diff --git a/tests/integration/a2a/conftest.py b/tests/integration/a2a/conftest.py index 4718a8fda..235650302 100644 --- a/tests/integration/a2a/conftest.py +++ b/tests/integration/a2a/conftest.py @@ -258,8 +258,8 @@ async def a2a_test_server(unused_tcp_port: int, wait_for_port) -> AsyncIterator[ provider=AgentProvider(organization="fast-agent", url="https://fast-agent.ai"), version="1.0.0", capabilities=AgentCapabilities(streaming=True, push_notifications=False), - default_input_modes=["text"], - default_output_modes=["text", "task-status"], + default_input_modes=["text/plain"], + default_output_modes=["text/plain"], skills=[ AgentSkill( id="echo", @@ -267,8 +267,8 @@ async def a2a_test_server(unused_tcp_port: int, wait_for_port) -> AsyncIterator[ description="Echo user input.", tags=["test"], examples=["hello"], - input_modes=["text"], - output_modes=["text", "task-status"], + input_modes=["text/plain"], + output_modes=["text/plain"], ) ], supported_interfaces=[ diff --git a/tests/integration/a2a/fake_server.py b/tests/integration/a2a/fake_server.py index 35ed550fd..342401f76 100644 --- a/tests/integration/a2a/fake_server.py +++ b/tests/integration/a2a/fake_server.py @@ -202,8 +202,8 @@ def build_app(host: str, port: int) -> FastAPI: provider=AgentProvider(organization="fast-agent", url="https://fast-agent.ai"), version="1.0.0", capabilities=AgentCapabilities(streaming=True, push_notifications=False), - default_input_modes=["text", "image", "file"], - default_output_modes=["text", "task-status", "application/json"], + default_input_modes=["text/plain", "application/octet-stream", "image/*"], + default_output_modes=["text/plain", "application/json", "application/octet-stream"], skills=[ AgentSkill( id="fake_echo_stream_files", @@ -211,8 +211,8 @@ def build_app(host: str, port: int) -> FastAPI: description="Echoes text, streams short/long chunks, and returns URL/data/raw parts.", tags=["test", "streaming", "files"], examples=["hello", "please stream", "please long stream", "respond with files"], - input_modes=["text", "image", "file"], - output_modes=["text", "task-status", "application/json"], + input_modes=["text/plain", "application/octet-stream", "image/*"], + output_modes=["text/plain", "application/json", "application/octet-stream"], ) ], supported_interfaces=[ diff --git a/tests/integration/a2a/test_fast_agent_a2a_server.py b/tests/integration/a2a/test_fast_agent_a2a_server.py index 83a7a9fdd..6f02aa8f7 100644 --- a/tests/integration/a2a/test_fast_agent_a2a_server.py +++ b/tests/integration/a2a/test_fast_agent_a2a_server.py @@ -448,8 +448,26 @@ async def test_fast_agent_a2a_server_serves_jsonrpc_agent_with_context_sessions( assert skills["worker"].name == "worker" assert skills["worker"].description == "Send a message to the worker fast-agent agent." assert list(skills["worker"].tags) == ["fast-agent", "basic"] - assert list(skills["worker"].input_modes) == ["text", "file", "image"] - assert list(skills["worker"].output_modes) == ["text", "file", "image", "task-status"] + assert list(fast_agent_a2a_server.server.agent_card.default_input_modes) == [ + "text/plain", + "application/octet-stream", + "image/*", + ] + assert list(fast_agent_a2a_server.server.agent_card.default_output_modes) == [ + "text/plain", + "application/octet-stream", + "image/*", + ] + assert list(skills["worker"].input_modes) == [ + "text/plain", + "application/octet-stream", + "image/*", + ] + assert list(skills["worker"].output_modes) == [ + "text/plain", + "application/octet-stream", + "image/*", + ] @pytest.mark.integration From a51f27840dc57845e1aa2b77ee5d88e9f0578ea6 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 00:46:54 +0100 Subject: [PATCH 32/58] Fix A2A history and instance scopes --- docs/docs/a2a/api.md | 16 +- docs/docs/a2a/client.md | 5 + docs/docs/a2a/protocol-compliance.md | 2 +- docs/docs/a2a/server.md | 33 +- src/fast_agent/a2a/remote_agent.py | 8 + src/fast_agent/a2a/server.py | 80 +++-- src/fast_agent/core/fastagent.py | 2 + .../a2a/test_fast_agent_a2a_server.py | 289 +++++++++++++++++- .../fast_agent/commands/test_serve_command.py | 44 ++- .../test_a2a_remote_agent_events.py | 26 ++ 10 files changed, 456 insertions(+), 49 deletions(-) diff --git a/docs/docs/a2a/api.md b/docs/docs/a2a/api.md index 3c4040d80..903d2377e 100644 --- a/docs/docs/a2a/api.md +++ b/docs/docs/a2a/api.md @@ -120,16 +120,22 @@ server = AgentA2AServer( server_name="research agents", host="127.0.0.1", port=41241, + instance_scope="connection", ) app = server.asgi_app() ``` -`create_instance` is called for each new A2A `context_id`; `dispose_instance` is -called during server shutdown. This keeps A2A session correlation aligned with -fast-agent's existing per-session instance behavior. The A2A `context_id` -selects the server-side fast-agent instance; each served agent's `use_history` -setting still controls whether prior turns are included in model calls. +`instance_scope` accepts the same values as `fast-agent serve`: + +| Scope | Server API behavior | +|---|---| +| `shared` | Reuse `primary_instance` for all A2A messages. | +| `connection` | Call `create_instance` for each new A2A `context_id` and reuse that instance for later messages in the same context. | +| `request` | Call `create_instance` and `dispose_instance` for each A2A message. | + +Each served agent's `use_history` setting still controls whether prior turns are +included in model calls inside the selected instance scope. ## Raw A2A JSON-RPC diff --git a/docs/docs/a2a/client.md b/docs/docs/a2a/client.md index de64327ef..6fcc67bc7 100644 --- a/docs/docs/a2a/client.md +++ b/docs/docs/a2a/client.md @@ -128,6 +128,11 @@ Useful diagnostics: `/a2a status` shows the current A2A `context_id`, pending `task_id`, last task state, and selected client transport. +When the local A2A AgentCard or request has `use_history: false`, fast-agent +starts each completed turn with a fresh A2A context. The exception is +`TASK_STATE_INPUT_REQUIRED`: fast-agent keeps the returned `task_id` and +`context_id` so the next user message can continue the interrupted task. + ## Streaming Remote A2A `TaskArtifactUpdateEvent` updates are emitted through the normal diff --git a/docs/docs/a2a/protocol-compliance.md b/docs/docs/a2a/protocol-compliance.md index 344727b34..d68c1df39 100644 --- a/docs/docs/a2a/protocol-compliance.md +++ b/docs/docs/a2a/protocol-compliance.md @@ -13,7 +13,7 @@ client stack and intentionally excludes gRPC. | JSON-RPC transport | Supported | Client and server use the SDK JSON-RPC binding. | | HTTP+JSON transport | Supported | Client and server use the SDK REST binding. The server exposes the REST binding under `/a2a/rest`. | | Streaming task updates | Supported | fast-agent stream listeners are bridged to A2A `TaskArtifactUpdateEvent` events. The client preserves artifact order and honors the A2A `append` flag. | -| Multi-turn contexts | Supported | Inbound `contextId` is optional. The SDK generates one when omitted, and fast-agent uses the resolved `context_id` as the server-side session key. | +| Multi-turn contexts | Supported | Inbound `contextId` is optional. The SDK generates one when omitted. In A2A server `connection` scope, fast-agent uses the resolved `context_id` as the server-side instance key; `shared` and `request` scopes intentionally reuse or recreate instances independently of the A2A context. | | `INPUT_REQUIRED` continuation | Supported | Server responses with `PromptMessageExtended.stop_reason == LlmStopReason.PAUSE` become `TASK_STATE_INPUT_REQUIRED`. The fast-agent A2A client preserves the pending `task_id` and returned `context_id`, and surfaces the local response with `LlmStopReason.PAUSE`. | | Task retrieval, listing, cancellation, and subscribe | SDK-backed | These operations are provided by the SDK request handler and in-memory task store. Cancellation also cancels the running fast-agent task when still active. | | Text parts | Supported | A2A text parts map to `TextContent`; fast-agent text output maps back to A2A text parts. | diff --git a/docs/docs/a2a/server.md b/docs/docs/a2a/server.md index 52fc51bfa..a3c45a6c5 100644 --- a/docs/docs/a2a/server.md +++ b/docs/docs/a2a/server.md @@ -17,6 +17,7 @@ agent. uv run fast-agent serve a2a \ --host 127.0.0.1 \ --port 41241 \ + --instance-scope shared \ --agent-cards ./agents \ --model codexresponses.gpt-5.4-mini ``` @@ -133,21 +134,27 @@ Current limitation: examples are still generic, and mode lists describe the server-wide MIME-style content support rather than deriving per-agent modality declarations from fast-agent AgentCard metadata or installed fast-agent skills. -## Sessions and Resumption +## Instance Scope, Sessions, and Resumption A2A `contextId` is optional on inbound messages. If a client omits it, the A2A -SDK generates one. fast-agent uses the resolved `context_id` as the server-side -session key: - -- same `context_id`: reuse the same fast-agent instance and that agent's - configured history behavior; -- new `context_id`: create a fresh fast-agent instance; -- same interrupted `task_id` and `context_id`: continue an `INPUT_REQUIRED` - task. - -The `context_id` selects the server-side fast-agent instance. The agent's -history setting controls how much prior conversation is sent to the model; it -does not change the A2A session key. +SDK generates one. The server still returns and tracks the resolved A2A +`context_id`; how that maps to fast-agent runtime instances depends on +`--instance-scope`: + +| Scope | Behavior | +|---|---| +| `shared` | Use the primary fast-agent instance for all A2A contexts. This is the default for `fast-agent serve a2a`, matching the generic serve default. | +| `connection` | Use the A2A `context_id` as the server-side instance/session key. The same `context_id` reuses the same fast-agent instance; a new `context_id` creates a fresh instance. | +| `request` | Create and dispose a fresh fast-agent instance for every A2A message. | + +The served agent's history setting controls how much prior conversation is sent +to the model inside whichever instance scope is selected. It does not change the +A2A protocol `context_id`. + +For `INPUT_REQUIRED`, clients should continue with the returned `task_id` and +`context_id`. `shared` and `connection` scopes preserve in-memory fast-agent +state for follow-up turns. `request` scope intentionally creates a fresh +fast-agent instance for each message, so it is best for stateless agents. The current server uses in-memory A2A task storage and in-memory fast-agent context instances. Restarting the process loses A2A task state and session diff --git a/src/fast_agent/a2a/remote_agent.py b/src/fast_agent/a2a/remote_agent.py index 8669cf182..740e305ea 100644 --- a/src/fast_agent/a2a/remote_agent.py +++ b/src/fast_agent/a2a/remote_agent.py @@ -180,6 +180,7 @@ async def generate_impl( raise RuntimeError("A2A remote agent is not initialized") use_history = request_params.use_history if request_params else self.config.use_history + self._prepare_turn_state(use_history=use_history) self._timestamp_messages(messages) self._display_user_messages(messages) user_text = _latest_text(messages) @@ -221,6 +222,13 @@ async def generate_impl( self._persist_history(messages, assistant_message) return assistant_message + def _prepare_turn_state(self, *, use_history: bool) -> None: + if use_history: + return + if self.last_task_state == _INPUT_REQUIRED_STATE and self.current_task_id: + return + self.reset_a2a_state() + def _display_user_messages(self, messages: list[PromptMessageExtended]) -> None: display_messages = [message for message in messages if message.role == "user"] if not display_messages: diff --git a/src/fast_agent/a2a/server.py b/src/fast_agent/a2a/server.py index 811d5afb8..b0789e3e4 100644 --- a/src/fast_agent/a2a/server.py +++ b/src/fast_agent/a2a/server.py @@ -90,11 +90,13 @@ def __init__( dispose_instance: Callable[[AgentInstance], Awaitable[None]], *, primary_agent_name: str, + instance_scope: str = "connection", ) -> None: self._primary_instance = primary_instance self._create_instance = create_instance self._dispose_instance = dispose_instance self._primary_agent_name = primary_agent_name + self._instance_scope = instance_scope self._context_instances: dict[str, AgentInstance] = {} self._context_locks: dict[str, asyncio.Lock] = {} self._running_tasks: dict[str, asyncio.Task[None]] = {} @@ -147,33 +149,39 @@ async def _execute(self, context: RequestContext, event_queue: EventQueue) -> No message=updater.new_agent_message(parts=[Part(text="fast-agent is working")]) ) - lock = await self._context_lock(context.context_id) + lock = await self._context_lock(self._lock_key(context)) async with lock: - instance = await self._instance_for_context(context.context_id) - agent = self._select_agent(instance, context.message) - stream_context = self._prepare_streaming_context( - agent=agent, - updater=updater, - ) + instance = await self._acquire_instance(context.context_id) try: - response = await agent.generate( - _prompt_from_a2a_message(context.message), - ) - except ProviderKeyError as exc: - await updater.requires_auth( - message=updater.new_agent_message(parts=[Part(text=exc.message)]) - ) - return - except asyncio.CancelledError: - await updater.cancel() - raise - except Exception as exc: - await updater.failed( - message=updater.new_agent_message(parts=[Part(text=str(exc))]) + agent = self._select_agent(instance, context.message) + stream_context = self._prepare_streaming_context( + agent=agent, + updater=updater, ) - return + try: + response = await agent.generate( + _prompt_from_a2a_message(context.message), + ) + except ProviderKeyError as exc: + await updater.requires_auth( + message=updater.new_agent_message(parts=[Part(text=exc.message)]) + ) + return + except asyncio.CancelledError: + await updater.cancel() + raise + except Exception as exc: + await updater.failed( + message=updater.new_agent_message(parts=[Part(text=str(exc))]) + ) + return + finally: + await self._cleanup_streaming_context(stream_context) finally: - await self._cleanup_streaming_context(stream_context) + await self._release_instance( + context.context_id, + instance, + ) streamed_text = stream_context.streamed_text() response_text = response.all_text() @@ -230,15 +238,26 @@ async def _cleanup_streaming_context(self, stream_context: "_A2AStreamingContext if stream_context.tasks: await asyncio.gather(*stream_context.tasks, return_exceptions=True) - async def _context_lock(self, context_id: str) -> asyncio.Lock: + def _lock_key(self, context: RequestContext) -> str: + if self._instance_scope == "shared": + return "__shared__" + if self._instance_scope == "request": + return context.task_id or context.context_id or "__request__" + return context.context_id or "__context__" + + async def _context_lock(self, lock_key: str) -> asyncio.Lock: async with self._lock: - lock = self._context_locks.get(context_id) + lock = self._context_locks.get(lock_key) if lock is None: lock = asyncio.Lock() - self._context_locks[context_id] = lock + self._context_locks[lock_key] = lock return lock - async def _instance_for_context(self, context_id: str) -> AgentInstance: + async def _acquire_instance(self, context_id: str) -> AgentInstance: + if self._instance_scope == "shared": + return self._primary_instance + if self._instance_scope == "request": + return await self._create_instance() instance = self._context_instances.get(context_id) if instance is not None: return instance @@ -246,6 +265,11 @@ async def _instance_for_context(self, context_id: str) -> AgentInstance: self._context_instances[context_id] = instance return instance + async def _release_instance(self, context_id: str, instance: AgentInstance) -> None: + del context_id + if self._instance_scope == "request": + await self._dispose_instance(instance) + def _select_agent(self, instance: AgentInstance, message: Message) -> AgentProtocol: agent_name = _requested_agent_name(message) if agent_name and agent_name in instance.agents: @@ -322,6 +346,7 @@ def __init__( server_description: str | None = None, host: str = "0.0.0.0", port: int = 8000, + instance_scope: str = "connection", ) -> None: self._host = host self._port = port @@ -338,6 +363,7 @@ def __init__( create_instance=create_instance, dispose_instance=dispose_instance, primary_agent_name=self._primary_agent_name, + instance_scope=instance_scope, ) self.request_handler = DefaultRequestHandler( agent_executor=self.executor, diff --git a/src/fast_agent/core/fastagent.py b/src/fast_agent/core/fastagent.py index 5a4e33e4c..e19b2d1e0 100644 --- a/src/fast_agent/core/fastagent.py +++ b/src/fast_agent/core/fastagent.py @@ -2371,6 +2371,7 @@ async def _run_a2a_server( server_description = getattr(self.args, "server_description", None) server_name = getattr(self.args, "server_name", None) + instance_scope = getattr(self.args, "instance_scope", "shared") a2a_server = AgentA2AServer( primary_instance=state.primary_instance, create_instance=callbacks.create_instance, @@ -2379,6 +2380,7 @@ async def _run_a2a_server( server_description=server_description, host=self.args.host, port=self.args.port, + instance_scope=instance_scope, ) await a2a_server.run_async(host=self.args.host, port=self.args.port) diff --git a/tests/integration/a2a/test_fast_agent_a2a_server.py b/tests/integration/a2a/test_fast_agent_a2a_server.py index 6f02aa8f7..4c07b46af 100644 --- a/tests/integration/a2a/test_fast_agent_a2a_server.py +++ b/tests/integration/a2a/test_fast_agent_a2a_server.py @@ -229,6 +229,26 @@ async def generate(self, messages: Any, request_params: Any = None) -> PromptMes return response +class NamedResponseAgent(RecordingAgent): + async def generate(self, messages: Any, request_params: Any = None) -> PromptMessageExtended: + del request_params + if isinstance(messages, PromptMessageExtended): + prompt = messages + else: + prompt = PromptMessageExtended( + role="user", + content=[TextContent(type="text", text=str(messages))], + ) + self.received.append(prompt) + self.message_history.append(prompt) + response = PromptMessageExtended( + role="assistant", + content=[TextContent(type="text", text=f"{self.name} handled: {prompt.all_text()}")], + ) + self.message_history.append(response) + return response + + class CancellableRecordingAgent(RecordingAgent): def __init__(self, name: str = "worker") -> None: super().__init__(name=name) @@ -264,6 +284,14 @@ def _instance(agent: RecordingAgent) -> AgentInstance: ) +def _multi_agent_instance(*agents: RecordingAgent) -> AgentInstance: + protocol_agents = {agent.name: cast("AgentProtocol", agent) for agent in agents} + return AgentInstance( + app=AgentApp(protocol_agents), + agents=protocol_agents, + ) + + @pytest_asyncio.fixture async def fast_agent_a2a_server( unused_tcp_port: int, @@ -411,7 +439,7 @@ async def test_fast_agent_a2a_server_serves_jsonrpc_agent_with_context_sessions( fast_agent_a2a_server: RunningFastAgentA2AServer, ) -> None: client = A2ARemoteAgent( - config=AgentConfig(name="remote", agent_type=AgentType.A2A, use_history=False), + config=AgentConfig(name="remote", agent_type=AgentType.A2A, use_history=True), a2a_config=A2AAgentConfig(url=fast_agent_a2a_server.base_url, transport="JSONRPC"), ) await client.initialize() @@ -470,6 +498,263 @@ async def test_fast_agent_a2a_server_serves_jsonrpc_agent_with_context_sessions( ] +@pytest.mark.integration +@pytest.mark.asyncio +async def test_a2a_remote_agent_without_history_uses_fresh_server_contexts( + fast_agent_a2a_server: RunningFastAgentA2AServer, +) -> None: + client = A2ARemoteAgent( + config=AgentConfig(name="remote_no_history", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig(url=fast_agent_a2a_server.base_url, transport="JSONRPC"), + ) + await client.initialize() + try: + first = await client.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[TextContent(type="text", text="first")], + ) + ] + ) + first_context_id = client.context_id + second = await client.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[TextContent(type="text", text="second")], + ) + ] + ) + finally: + await client.shutdown() + + assert first.all_text() == "server saw 1: first" + assert second.all_text() == "server saw 1: second" + assert client.context_id != first_context_id + assert len(fast_agent_a2a_server.created_agents) == 2 + + +@pytest.mark.integration +@pytest.mark.asyncio +async def test_fast_agent_a2a_server_shared_instance_scope_reuses_primary_instance( + unused_tcp_port: int, + wait_for_port, +) -> None: + host = "127.0.0.1" + port = unused_tcp_port + created_agents: list[RecordingAgent] = [] + + async def create_instance() -> AgentInstance: + agent = RecordingAgent(name="worker") + created_agents.append(agent) + return _instance(agent) + + async def dispose_instance(instance: AgentInstance) -> None: + await instance.shutdown() + + server = AgentA2AServer( + primary_instance=_instance(RecordingAgent(name="worker")), + create_instance=create_instance, + dispose_instance=dispose_instance, + server_name="fast-agent shared scope test server", + host=host, + port=port, + instance_scope="shared", + ) + uvicorn_server = uvicorn.Server( + uvicorn.Config(server.asgi_app(), host=host, port=port, log_level="warning") + ) + task = asyncio.create_task(uvicorn_server.serve()) + await wait_for_port(host, port, timeout=5.0) + + client = A2ARemoteAgent( + config=AgentConfig(name="remote_shared", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig(url=f"http://{host}:{port}", transport="JSONRPC"), + ) + await client.initialize() + try: + first = await client.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[TextContent(type="text", text="first")], + ) + ] + ) + second = await client.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[TextContent(type="text", text="second")], + ) + ] + ) + finally: + await client.shutdown() + uvicorn_server.should_exit = True + await asyncio.wait_for(task, timeout=5.0) + await server.executor.shutdown() + + assert first.all_text() == "server saw 1: first" + assert second.all_text() == "server saw 3: second" + assert not created_agents + + +@pytest.mark.integration +@pytest.mark.asyncio +async def test_fast_agent_a2a_server_request_instance_scope_disposes_each_turn( + unused_tcp_port: int, + wait_for_port, +) -> None: + host = "127.0.0.1" + port = unused_tcp_port + created_agents: list[RecordingAgent] = [] + disposed: list[AgentInstance] = [] + + async def create_instance() -> AgentInstance: + agent = RecordingAgent(name="worker") + created_agents.append(agent) + return _instance(agent) + + async def dispose_instance(instance: AgentInstance) -> None: + disposed.append(instance) + await instance.shutdown() + + server = AgentA2AServer( + primary_instance=_instance(RecordingAgent(name="worker")), + create_instance=create_instance, + dispose_instance=dispose_instance, + server_name="fast-agent request scope test server", + host=host, + port=port, + instance_scope="request", + ) + uvicorn_server = uvicorn.Server( + uvicorn.Config(server.asgi_app(), host=host, port=port, log_level="warning") + ) + task = asyncio.create_task(uvicorn_server.serve()) + await wait_for_port(host, port, timeout=5.0) + + client = A2ARemoteAgent( + config=AgentConfig(name="remote_request", agent_type=AgentType.A2A, use_history=True), + a2a_config=A2AAgentConfig(url=f"http://{host}:{port}", transport="JSONRPC"), + ) + await client.initialize() + try: + first = await client.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[TextContent(type="text", text="first")], + ) + ] + ) + second = await client.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[TextContent(type="text", text="second")], + ) + ] + ) + finally: + await client.shutdown() + uvicorn_server.should_exit = True + await asyncio.wait_for(task, timeout=5.0) + await server.executor.shutdown() + + assert first.all_text() == "server saw 1: first" + assert second.all_text() == "server saw 1: second" + assert len(created_agents) == 2 + assert len(disposed) == 2 + + +@pytest.mark.integration +@pytest.mark.asyncio +async def test_fast_agent_a2a_server_routes_to_agent_skill_named_in_metadata( + unused_tcp_port: int, + wait_for_port, +) -> None: + host = "127.0.0.1" + port = unused_tcp_port + created_agents: list[tuple[NamedResponseAgent, NamedResponseAgent]] = [] + disposed: list[AgentInstance] = [] + + def agent_pair() -> tuple[NamedResponseAgent, NamedResponseAgent]: + primary = NamedResponseAgent(name="primary") + primary.config.default = True + specialist = NamedResponseAgent(name="specialist") + specialist.config.default = False + specialist.config.description = "Handle specialist work." + return primary, specialist + + async def create_instance() -> AgentInstance: + primary, specialist = agent_pair() + created_agents.append((primary, specialist)) + return _multi_agent_instance(primary, specialist) + + async def dispose_instance(instance: AgentInstance) -> None: + disposed.append(instance) + await instance.shutdown() + + bootstrap_primary, bootstrap_specialist = agent_pair() + server = AgentA2AServer( + primary_instance=_multi_agent_instance(bootstrap_primary, bootstrap_specialist), + create_instance=create_instance, + dispose_instance=dispose_instance, + server_name="fast-agent routing test server", + host=host, + port=port, + ) + uvicorn_server = uvicorn.Server( + uvicorn.Config(server.asgi_app(), host=host, port=port, log_level="warning") + ) + task = asyncio.create_task(uvicorn_server.serve()) + await wait_for_port(host, port, timeout=5.0) + + http_client = httpx.AsyncClient() + client = await create_client( + f"http://{host}:{port}", + client_config=ClientConfig( + httpx_client=http_client, + supported_protocol_bindings=["JSONRPC"], + ), + ) + response_text: str | None = None + try: + async for event in client.send_message( + SendMessageRequest( + message=Message( + role=Role.ROLE_USER, + message_id="target-specialist", + parts=[Part(text="route this")], + metadata={"agent": "specialist"}, + ) + ) + ): + if event.HasField("artifact_update"): + artifact_parts = event.artifact_update.artifact.parts + if artifact_parts and artifact_parts[0].HasField("text"): + response_text = artifact_parts[0].text + finally: + await client.close() + await http_client.aclose() + uvicorn_server.should_exit = True + await asyncio.wait_for(task, timeout=5.0) + await server.executor.shutdown() + + skills = {skill.id: skill for skill in server.agent_card.skills} + assert set(skills) == {"primary", "specialist"} + assert skills["specialist"].description == "Handle specialist work." + assert response_text == "specialist handled: route this" + assert created_agents + primary, specialist = created_agents[0] + assert not primary.received + assert len(specialist.received) == 1 + assert disposed + + @pytest.mark.integration @pytest.mark.asyncio async def test_fast_agent_a2a_server_context_does_not_force_agent_history( @@ -534,7 +819,7 @@ async def dispose_instance(instance: AgentInstance) -> None: assert first.all_text() == "server history 0: first" assert second.all_text() == "server history 0: second" - assert len(created_agents) == 1 + assert len(created_agents) == 2 assert disposed diff --git a/tests/unit/fast_agent/commands/test_serve_command.py b/tests/unit/fast_agent/commands/test_serve_command.py index 2ed9cf21e..e29f529cf 100644 --- a/tests/unit/fast_agent/commands/test_serve_command.py +++ b/tests/unit/fast_agent/commands/test_serve_command.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, cast +from types import SimpleNamespace +from typing import TYPE_CHECKING, Any, cast import click import pytest @@ -7,6 +8,7 @@ from fast_agent.cli.commands import go as go_command from fast_agent.cli.commands import serve as serve_command +from fast_agent.core.fastagent import FastAgent if TYPE_CHECKING: from fast_agent.cli.runtime.run_request import AgentRunRequest @@ -214,6 +216,46 @@ def fake_run_request(request: object) -> None: assert request.model == "codexresponses.gpt-5.4-mini" +@pytest.mark.asyncio +async def test_fastagent_run_a2a_server_passes_instance_scope(monkeypatch) -> None: + captured: dict[str, Any] = {} + + class FakeA2AServer: + def __init__(self, **kwargs: Any) -> None: + captured.update(kwargs) + + async def run_async(self, *, host: str, port: int) -> None: + captured["run_host"] = host + captured["run_port"] = port + + monkeypatch.setattr("fast_agent.a2a.AgentA2AServer", FakeA2AServer) + + fast = FastAgent.__new__(FastAgent) + fast.name = "fast-agent-a2a" + fast.args = SimpleNamespace( + server_description=None, + server_name=None, + host="127.0.0.1", + port=41241, + instance_scope="request", + ) + state = SimpleNamespace(primary_instance=object()) + callbacks = SimpleNamespace( + create_instance=object(), + dispose_instance=object(), + ) + + run_a2a_server = cast("Any", FastAgent._run_a2a_server) + await run_a2a_server(fast, state, callbacks) + + assert captured["primary_instance"] is state.primary_instance + assert captured["create_instance"] is callbacks.create_instance + assert captured["dispose_instance"] is callbacks.dispose_instance + assert captured["instance_scope"] == "request" + assert captured["run_host"] == "127.0.0.1" + assert captured["run_port"] == 41241 + + def test_serve_command_builds_request_with_missing_shell_cwd_override() -> None: ctx = typer.Context(click.Command("serve")) request = serve_command._build_run_request( diff --git a/tests/unit/fast_agent/test_a2a_remote_agent_events.py b/tests/unit/fast_agent/test_a2a_remote_agent_events.py index 4e37f2122..d7a51ef47 100644 --- a/tests/unit/fast_agent/test_a2a_remote_agent_events.py +++ b/tests/unit/fast_agent/test_a2a_remote_agent_events.py @@ -70,3 +70,29 @@ async def test_a2a_remote_agent_keeps_task_id_for_input_required_full_task_event assert agent.context_id == "ctx-2" assert agent.last_task_state == "TASK_STATE_INPUT_REQUIRED" assert agent.current_task_id == "input-task" + + +def test_a2a_remote_agent_resets_context_for_no_history_completed_turns() -> None: + agent = _remote_agent() + agent.context_id = "ctx-completed" + agent.current_task_id = None + agent.last_task_state = "TASK_STATE_COMPLETED" + + agent._prepare_turn_state(use_history=False) + + assert agent.context_id != "ctx-completed" + assert agent.current_task_id is None + assert agent.last_task_state is None + + +def test_a2a_remote_agent_keeps_input_required_task_for_no_history_follow_up() -> None: + agent = _remote_agent() + agent.context_id = "ctx-input" + agent.current_task_id = "task-input" + agent.last_task_state = "TASK_STATE_INPUT_REQUIRED" + + agent._prepare_turn_state(use_history=False) + + assert agent.context_id == "ctx-input" + assert agent.current_task_id == "task-input" + assert agent.last_task_state == "TASK_STATE_INPUT_REQUIRED" From f1cd0e60bd03c6b3a8f8f56f54afaf51e8f56b06 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 00:48:46 +0100 Subject: [PATCH 33/58] Test A2A server multimodal input mapping --- docs/docs/a2a/getting-started.md | 18 ++++--- .../a2a/test_fast_agent_a2a_server.py | 50 ++++++++++++++++++- 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/docs/docs/a2a/getting-started.md b/docs/docs/a2a/getting-started.md index c9e2eb2f9..cb25dd664 100644 --- a/docs/docs/a2a/getting-started.md +++ b/docs/docs/a2a/getting-started.md @@ -233,14 +233,20 @@ surface and known gaps. ### Server sessions A2A `context_id` is optional in the protocol request. The A2A SDK server -generates one when the client omits it. fast-agent uses that `context_id` as the -server-side session key, so messages with the same A2A context reuse the same -fast-agent instance. The served agent's own `use_history` setting still controls -whether prior turns are sent to the model. A new `context_id` gets a fresh -fast-agent instance. +generates one when the client omits it. `fast-agent serve a2a` also honors the +normal `--instance-scope` option: + +- `shared` reuses the primary fast-agent instance for all A2A contexts; +- `connection` uses the A2A `context_id` as the server-side instance key; +- `request` creates and disposes a fresh fast-agent instance per message. + +The served agent's own `use_history` setting still controls whether prior turns +are sent to the model inside the selected instance scope. Clients should preserve and reuse the returned `context_id` for conversational -continuity. The fast-agent A2A client does this automatically. +continuity. The fast-agent A2A client does this automatically when history is +enabled, and intentionally starts completed no-history turns with a fresh +context. ### API behavior diff --git a/tests/integration/a2a/test_fast_agent_a2a_server.py b/tests/integration/a2a/test_fast_agent_a2a_server.py index 4c07b46af..0e5717be8 100644 --- a/tests/integration/a2a/test_fast_agent_a2a_server.py +++ b/tests/integration/a2a/test_fast_agent_a2a_server.py @@ -21,7 +21,7 @@ TaskState, ) from fastapi.testclient import TestClient -from mcp.types import BlobResourceContents, EmbeddedResource, TextContent +from mcp.types import BlobResourceContents, EmbeddedResource, ImageContent, TextContent from pydantic import AnyUrl from fast_agent.a2a.config import A2AAgentConfig @@ -976,6 +976,54 @@ def test_fast_agent_a2a_server_preserves_raw_file_input_parts() -> None: assert content.resource.blob == "JVBERiB0ZXN0IGJ5dGVz" +@pytest.mark.integration +def test_fast_agent_a2a_server_maps_raw_image_input_parts() -> None: + prompt = _prompt_from_a2a_message( + Message( + role=Role.ROLE_USER, + message_id="image-input", + parts=[ + Part( + raw=b"image bytes", + media_type="image/png", + filename="chart.png", + ) + ], + ) + ) + + assert len(prompt.content) == 1 + content = prompt.content[0] + assert isinstance(content, ImageContent) + assert content.mimeType == "image/png" + assert content.data == "aW1hZ2UgYnl0ZXM=" + + +@pytest.mark.integration +def test_fast_agent_a2a_server_preserves_raw_audio_as_blob_resource() -> None: + prompt = _prompt_from_a2a_message( + Message( + role=Role.ROLE_USER, + message_id="audio-input", + parts=[ + Part( + raw=b"audio bytes", + media_type="audio/wav", + filename="clip.wav", + ) + ], + ) + ) + + assert len(prompt.content) == 1 + content = prompt.content[0] + assert isinstance(content, EmbeddedResource) + assert isinstance(content.resource, BlobResourceContents) + assert str(content.resource.uri) == "attachment:///clip.wav" + assert content.resource.mimeType == "audio/wav" + assert content.resource.blob == "YXVkaW8gYnl0ZXM=" + + @pytest.mark.integration def test_fast_agent_a2a_server_emits_blob_resources_as_raw_file_parts() -> None: parts = _parts_from_prompt_message( From 28a9798b194058ae004aa5f269dc3c8adbee7530 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 00:51:34 +0100 Subject: [PATCH 34/58] Update A2A compliance verification docs --- docs/docs/a2a/protocol-compliance.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/docs/a2a/protocol-compliance.md b/docs/docs/a2a/protocol-compliance.md index d68c1df39..944b897f8 100644 --- a/docs/docs/a2a/protocol-compliance.md +++ b/docs/docs/a2a/protocol-compliance.md @@ -44,12 +44,20 @@ The deterministic A2A integration suite exercises: - JSON-RPC and HTTP+JSON client/server calls; - generated `context_id` continuity across turns; +- fresh A2A context/task state for `use_history=False` turns, except while + continuing an `INPUT_REQUIRED` task; +- A2A server `shared`, `connection`, and `request` instance scopes; +- AgentCard skill advertisement and skill routing via message metadata; - streaming artifact updates delivered to the fast-agent client stream listener; - artifact replacement and append semantics on the client; - `TASK_STATE_INPUT_REQUIRED` preservation and follow-up completion; - raw non-image file preservation into fast-agent blob resources and back to A2A raw parts; -- cancellation and protocol error paths via SDK-backed handlers. - -Live provider smoke testing has also verified that a `codexresponses.gpt-5.4-mini` -fast-agent A2A server streams incremental chunks to the fast-agent A2A client. +- raw image and audio input mapping; +- cancellation, task retrieval/listing after cancellation, and protocol error + paths via SDK-backed handlers. + +For provider smoke testing, run a fast-agent A2A server with +`codexresponses.gpt-5.4-mini` and connect to it with the fast-agent A2A client. +The expected behavior is incremental streaming chunks delivered to client stream +listeners before the final task completion event. From 535d6751f4cce822f0987cf9aaa399d4889f91a6 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 00:58:35 +0100 Subject: [PATCH 35/58] Add A2A TUI and JSON data coverage --- docs/docs/a2a/api.md | 26 ++- docs/docs/a2a/client.md | 2 + docs/docs/a2a/protocol-compliance.md | 7 +- docs/docs/a2a/server.md | 13 +- plan/05-21-a2a-orientation.md | 9 + src/fast_agent/a2a/remote_agent.py | 18 +- src/fast_agent/a2a/server.py | 22 ++- .../a2a/test_fast_agent_a2a_server.py | 39 ++++- .../test_a2a_remote_agent_events.py | 31 +++- .../ui/test_a2a_command_dispatch.py | 154 ++++++++++++++++++ 10 files changed, 309 insertions(+), 12 deletions(-) create mode 100644 tests/unit/fast_agent/ui/test_a2a_command_dispatch.py diff --git a/docs/docs/a2a/api.md b/docs/docs/a2a/api.md index 903d2377e..ba76c567a 100644 --- a/docs/docs/a2a/api.md +++ b/docs/docs/a2a/api.md @@ -54,7 +54,7 @@ A2AAgentConfig( transport="JSONRPC", streaming=True, polling=False, - accepted_output_modes=["text/plain", "image/*"], + accepted_output_modes=["text/plain", "application/json", "image/*"], headers={"Authorization": "Bearer ..."}, relative_card_path="/.well-known/agent-card.json", ) @@ -198,3 +198,27 @@ Inbound A2A parts are converted to fast-agent prompt content: fast-agent responses are converted back to A2A artifact parts using the content types available in `PromptMessageExtended`. + +For structured JSON, A2A supports JSON-compatible `data` parts and also permits +JSON returned as text artifacts. fast-agent keeps model text as text, but maps an +`EmbeddedResource` containing `TextResourceContents` with +`mimeType="application/json"` to an A2A `data` part: + +```python +from mcp.types import EmbeddedResource, TextResourceContents +from pydantic import AnyUrl + +PromptMessageExtended( + role="assistant", + content=[ + EmbeddedResource( + type="resource", + resource=TextResourceContents( + uri=AnyUrl("resource:///tickets.json"), + mimeType="application/json", + text='{"tickets": [{"id": "REQ123", "status": "open"}]}', + ), + ) + ], +) +``` diff --git a/docs/docs/a2a/client.md b/docs/docs/a2a/client.md index 6fcc67bc7..909148b2a 100644 --- a/docs/docs/a2a/client.md +++ b/docs/docs/a2a/client.md @@ -101,6 +101,7 @@ streaming: true polling: false accepted_output_modes: - text/plain + - application/json - image/* headers: Authorization: "Bearer ${A2A_TOKEN}" @@ -201,6 +202,7 @@ The A2A client maps fast-agent prompt content to A2A parts: | `ResourceLink` | `Part(url=...)` | | `ImageContent` | `Part(raw=..., mediaType=image/...)` | | `AudioContent` | `Part(raw=..., mediaType=audio/...)` | +| `EmbeddedResource` with JSON `TextResourceContents` | `Part(data=...)` | Remote URL, data, raw, and text response parts are rendered into fast-agent assistant output. See [Protocol Compliance](protocol-compliance.md) for current diff --git a/docs/docs/a2a/protocol-compliance.md b/docs/docs/a2a/protocol-compliance.md index 944b897f8..7f9d084b7 100644 --- a/docs/docs/a2a/protocol-compliance.md +++ b/docs/docs/a2a/protocol-compliance.md @@ -9,7 +9,7 @@ client stack and intentionally excludes gRPC. | Area | Status | Notes | |---|---|---| -| Agent discovery | Supported | `fast-agent serve a2a` serves an AgentCard at `/.well-known/agent-card.json`. The card declares `JSONRPC` and `HTTP+JSON` interfaces with protocol version `1.0`, and advertises MIME-style input/output modes such as `text/plain`, `application/octet-stream`, and `image/*`. `fast-agent serve --transport a2a` remains supported. | +| Agent discovery | Supported | `fast-agent serve a2a` serves an AgentCard at `/.well-known/agent-card.json`. The card declares `JSONRPC` and `HTTP+JSON` interfaces with protocol version `1.0`, and advertises MIME-style input/output modes such as `text/plain`, `application/json`, `application/octet-stream`, and `image/*`. `fast-agent serve --transport a2a` remains supported. | | JSON-RPC transport | Supported | Client and server use the SDK JSON-RPC binding. | | HTTP+JSON transport | Supported | Client and server use the SDK REST binding. The server exposes the REST binding under `/a2a/rest`. | | Streaming task updates | Supported | fast-agent stream listeners are bridged to A2A `TaskArtifactUpdateEvent` events. The client preserves artifact order and honors the A2A `append` flag. | @@ -20,7 +20,7 @@ client stack and intentionally excludes gRPC. | URL parts | Supported | A2A URL parts map to `ResourceLink`; fast-agent resource links map back to A2A URL parts. | | Image raw parts | Supported | Raw image bytes map to `ImageContent`; image output maps back to A2A raw parts. | | Binary non-image raw parts | Supported | Inbound raw non-image bytes map to `EmbeddedResource` with `BlobResourceContents`; blob resources map back to A2A raw file parts. | -| Structured data parts | Partial | Inbound A2A data parts are rendered into formatted JSON text for the fast-agent prompt. | +| Structured data parts | Supported for prompt content bridges | Inbound A2A data parts are rendered into formatted JSON text for the fast-agent prompt. Outbound fast-agent `TextResourceContents` with `mimeType="application/json"` are emitted as A2A data parts. The A2A 1.0 structured data example also permits JSON returned as text artifacts. | | Error states | Supported through SDK plus fast-agent mappings | Provider credential failures map to `TASK_STATE_AUTH_REQUIRED`; uncaught execution failures map to `TASK_STATE_FAILED`; cancellation maps to `TASK_STATE_CANCELED`. Transport and validation errors are handled by the SDK bindings. | ## Known Gaps @@ -32,7 +32,7 @@ client stack and intentionally excludes gRPC. | Extended AgentCard | Not implemented. | The server publishes the public AgentCard only and does not configure `extendedAgentCard`. | | Authentication/security schemes on served AgentCards | Partial. | Remote clients can pass headers when connecting to other A2A agents. Serving fast-agent over A2A does not yet expose configurable A2A security schemes or enforce transport-level client auth. In-task provider auth failures are reported as `AUTH_REQUIRED`. | | Typed audio content on the server | Partial. | The client can send `AudioContent` as raw A2A parts. The server preserves inbound audio bytes as blob resources rather than mapping them to a dedicated fast-agent `AudioContent` object. | -| Structured data output | Partial. | fast-agent responses are mapped from existing `PromptMessageExtended` content types. Arbitrary structured JSON output is not emitted as A2A `data` parts unless represented by a future fast-agent content type. | +| Structured JSON output from model text | Partial. | fast-agent JSON text responses remain text artifacts unless represented as `TextResourceContents` with `mimeType="application/json"`. This avoids guessing whether ordinary text is intended to be protocol data. | | Persistent task/session storage | In-memory only. | The server uses the SDK `InMemoryTaskStore` and fast-agent in-memory context instances. Restarting the server loses A2A task state and context-bound fast-agent sessions. | | Idempotent `messageId` handling | Not implemented in fast-agent layer. | The SDK validates request shape, but fast-agent does not deduplicate repeated `messageId` values. | | AgentCard signing | Not implemented. | The public AgentCard is unsigned. | @@ -54,6 +54,7 @@ The deterministic A2A integration suite exercises: - raw non-image file preservation into fast-agent blob resources and back to A2A raw parts; - raw image and audio input mapping; +- JSON `TextResourceContents` mapping to A2A data parts; - cancellation, task retrieval/listing after cancellation, and protocol error paths via SDK-backed handlers. diff --git a/docs/docs/a2a/server.md b/docs/docs/a2a/server.md index a3c45a6c5..e4cf805ca 100644 --- a/docs/docs/a2a/server.md +++ b/docs/docs/a2a/server.md @@ -107,8 +107,8 @@ agent: "description": "Research and summarize source material.", "tags": ["fast-agent", "basic"], "examples": ["Hello"], - "inputModes": ["text/plain", "application/octet-stream", "image/*"], - "outputModes": ["text/plain", "application/octet-stream", "image/*"] + "inputModes": ["text/plain", "application/json", "application/octet-stream", "image/*"], + "outputModes": ["text/plain", "application/json", "application/octet-stream", "image/*"] } ``` @@ -206,5 +206,14 @@ payload, MIME type, and filename-like attachment URI for the fast-agent agent. When a fast-agent response includes a blob resource, the server emits it back to A2A clients as a raw file part. +## Structured JSON + +A2A supports structured JSON exchange through JSON-compatible data content and +also allows JSON to be returned as text artifacts. fast-agent does not parse +ordinary model text and guess that it should become protocol data. Instead, it +maps `TextResourceContents` with `mimeType="application/json"` to A2A data +parts. This gives API users and structured-output wrappers an explicit path to +return protocol-level JSON while preserving normal markdown/text responses. + See [Protocol Compliance](protocol-compliance.md) for the full supported surface and known gaps. diff --git a/plan/05-21-a2a-orientation.md b/plan/05-21-a2a-orientation.md index 5034d45f9..dcd0abb85 100644 --- a/plan/05-21-a2a-orientation.md +++ b/plan/05-21-a2a-orientation.md @@ -223,6 +223,15 @@ blue - `docs/docs/assets/a2a/a2a-streaming-files.cast` - Embedded asciinema recording for the A2A TUI flow. +- Requested follow-up recording: + - Add one docs asciinema cast that shows a real LLM-backed fast-agent A2A + server streaming to a fast-agent A2A client. + - Preferred scenario: serve an agent using `codexresponses.gpt-5.4-mini` + with access to the Hugging Face MCP server, then ask for a markdown + response about currently trending models. + - This should be labeled as a provider/network smoke recording, separate from + the deterministic fake-server recordings used for repeatable tests. + - `/home/ssmith/plan/records/a2a-streaming-files-input-required.cast` - Local copy of the latest generated recording. diff --git a/src/fast_agent/a2a/remote_agent.py b/src/fast_agent/a2a/remote_agent.py index 740e305ea..00598d623 100644 --- a/src/fast_agent/a2a/remote_agent.py +++ b/src/fast_agent/a2a/remote_agent.py @@ -12,7 +12,7 @@ import httpx from a2a.client import A2ACardResolver, ClientConfig, create_client from a2a.types import Message, Part, Role, SendMessageRequest, TaskState -from google.protobuf.json_format import MessageToDict +from google.protobuf.json_format import MessageToDict, ParseDict from mcp.types import ( AudioContent, BlobResourceContents, @@ -398,6 +398,10 @@ def _parts_from_messages(messages: Sequence[PromptMessageExtended]) -> list[Part ) continue if isinstance(resource, TextResourceContents): + data_part = _json_data_part(resource.text, media_type=resource.mimeType) + if data_part is not None: + parts.append(data_part) + continue parts.append( Part( text=resource.text, @@ -500,3 +504,15 @@ def _state_message(state: str | None) -> str: if state == "TASK_STATE_COMPLETED": return "A2A task completed without text output." return "A2A task ended without text output." + + +def _json_data_part(text: str, *, media_type: str | None) -> Part | None: + if media_type != "application/json": + return None + try: + data = json.loads(text) + except json.JSONDecodeError: + return None + part = Part(media_type=media_type) + ParseDict(data, part.data) + return part diff --git a/src/fast_agent/a2a/server.py b/src/fast_agent/a2a/server.py index b0789e3e4..e91fe6ac9 100644 --- a/src/fast_agent/a2a/server.py +++ b/src/fast_agent/a2a/server.py @@ -32,7 +32,7 @@ TaskStatus, ) from fastapi import FastAPI -from google.protobuf.json_format import MessageToDict +from google.protobuf.json_format import MessageToDict, ParseDict from mcp.types import ( BlobResourceContents, EmbeddedResource, @@ -69,8 +69,8 @@ def add_stream_listener(self, listener: Any) -> Any: logger = get_logger(__name__) -A2A_INPUT_MODES = ["text/plain", "application/octet-stream", "image/*"] -A2A_OUTPUT_MODES = ["text/plain", "application/octet-stream", "image/*"] +A2A_INPUT_MODES = ["text/plain", "application/json", "application/octet-stream", "image/*"] +A2A_OUTPUT_MODES = ["text/plain", "application/json", "application/octet-stream", "image/*"] def _fast_agent_version() -> str: @@ -577,6 +577,10 @@ def _parts_from_prompt_message(message: PromptMessageExtended) -> list[Part]: ) continue if isinstance(resource, TextResourceContents): + data_part = _json_data_part(resource.text, media_type=resource.mimeType) + if data_part is not None: + parts.append(data_part) + continue parts.append(Part(text=resource.text)) continue if isinstance(content, ResourceLink): @@ -596,3 +600,15 @@ def _filename_from_uri(uri: str) -> str: parsed = urlparse(uri) name = PurePosixPath(unquote(parsed.path)).name return name or parsed.netloc or "attachment" + + +def _json_data_part(text: str, *, media_type: str | None) -> Part | None: + if media_type != "application/json": + return None + try: + data = json.loads(text) + except json.JSONDecodeError: + return None + part = Part(media_type=media_type) + ParseDict(data, part.data) + return part diff --git a/tests/integration/a2a/test_fast_agent_a2a_server.py b/tests/integration/a2a/test_fast_agent_a2a_server.py index 0e5717be8..fe3efeedd 100644 --- a/tests/integration/a2a/test_fast_agent_a2a_server.py +++ b/tests/integration/a2a/test_fast_agent_a2a_server.py @@ -21,7 +21,14 @@ TaskState, ) from fastapi.testclient import TestClient -from mcp.types import BlobResourceContents, EmbeddedResource, ImageContent, TextContent +from google.protobuf.json_format import MessageToDict +from mcp.types import ( + BlobResourceContents, + EmbeddedResource, + ImageContent, + TextContent, + TextResourceContents, +) from pydantic import AnyUrl from fast_agent.a2a.config import A2AAgentConfig @@ -478,21 +485,25 @@ async def test_fast_agent_a2a_server_serves_jsonrpc_agent_with_context_sessions( assert list(skills["worker"].tags) == ["fast-agent", "basic"] assert list(fast_agent_a2a_server.server.agent_card.default_input_modes) == [ "text/plain", + "application/json", "application/octet-stream", "image/*", ] assert list(fast_agent_a2a_server.server.agent_card.default_output_modes) == [ "text/plain", + "application/json", "application/octet-stream", "image/*", ] assert list(skills["worker"].input_modes) == [ "text/plain", + "application/json", "application/octet-stream", "image/*", ] assert list(skills["worker"].output_modes) == [ "text/plain", + "application/json", "application/octet-stream", "image/*", ] @@ -1048,6 +1059,32 @@ def test_fast_agent_a2a_server_emits_blob_resources_as_raw_file_parts() -> None: assert parts[0].filename == "report.pdf" +@pytest.mark.integration +def test_fast_agent_a2a_server_emits_json_text_resources_as_data_parts() -> None: + parts = _parts_from_prompt_message( + PromptMessageExtended( + role="assistant", + content=[ + EmbeddedResource( + type="resource", + resource=TextResourceContents( + uri=AnyUrl("resource:///tickets.json"), + mimeType="application/json", + text='{"tickets": [{"id": "REQ123", "status": "open"}]}', + ), + ) + ], + ) + ) + + assert len(parts) == 1 + assert parts[0].HasField("data") + assert parts[0].media_type == "application/json" + assert MessageToDict(parts[0])["data"] == { + "tickets": [{"id": "REQ123", "status": "open"}] + } + + @pytest.mark.integration @pytest.mark.asyncio async def test_fast_agent_a2a_server_serves_http_json_transport( diff --git a/tests/unit/fast_agent/test_a2a_remote_agent_events.py b/tests/unit/fast_agent/test_a2a_remote_agent_events.py index d7a51ef47..fffa158ca 100644 --- a/tests/unit/fast_agent/test_a2a_remote_agent_events.py +++ b/tests/unit/fast_agent/test_a2a_remote_agent_events.py @@ -4,10 +4,14 @@ import pytest from a2a.types import Artifact, Part, StreamResponse, Task, TaskState, TaskStatus +from google.protobuf.json_format import MessageToDict +from mcp.types import EmbeddedResource, TextResourceContents +from pydantic import AnyUrl from fast_agent.a2a.config import A2AAgentConfig -from fast_agent.a2a.remote_agent import A2ARemoteAgent +from fast_agent.a2a.remote_agent import A2ARemoteAgent, _parts_from_messages from fast_agent.agents.agent_types import AgentConfig, AgentType +from fast_agent.types import PromptMessageExtended if TYPE_CHECKING: from collections.abc import AsyncIterator @@ -96,3 +100,28 @@ def test_a2a_remote_agent_keeps_input_required_task_for_no_history_follow_up() - assert agent.context_id == "ctx-input" assert agent.current_task_id == "task-input" assert agent.last_task_state == "TASK_STATE_INPUT_REQUIRED" + + +def test_a2a_remote_agent_sends_json_text_resources_as_data_parts() -> None: + parts = _parts_from_messages( + [ + PromptMessageExtended( + role="user", + content=[ + EmbeddedResource( + type="resource", + resource=TextResourceContents( + uri=AnyUrl("resource:///query.json"), + mimeType="application/json", + text='{"format": "markdown", "limit": 5}', + ), + ) + ], + ) + ] + ) + + assert len(parts) == 1 + assert parts[0].HasField("data") + assert parts[0].media_type == "application/json" + assert MessageToDict(parts[0])["data"] == {"format": "markdown", "limit": 5.0} diff --git a/tests/unit/fast_agent/ui/test_a2a_command_dispatch.py b/tests/unit/fast_agent/ui/test_a2a_command_dispatch.py new file mode 100644 index 000000000..c4f146fd8 --- /dev/null +++ b/tests/unit/fast_agent/ui/test_a2a_command_dispatch.py @@ -0,0 +1,154 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +import pytest +from a2a.types import AgentCard, AgentInterface, AgentProvider + +from fast_agent.a2a.config import A2AAgentConfig +from fast_agent.a2a.remote_agent import A2ARemoteAgent +from fast_agent.agents.agent_types import AgentConfig, AgentType +from fast_agent.core.agent_app import AgentApp +from fast_agent.ui.command_payloads import A2ACommand +from fast_agent.ui.interactive import command_dispatch +from fast_agent.ui.interactive.command_dispatch import dispatch_command_payload +from fast_agent.ui.interactive_prompt import InteractivePrompt + +if TYPE_CHECKING: + from fast_agent.interfaces import AgentProtocol + + +class _SelectedTransport: + pass + + +def _remote_agent(*, name: str = "remote") -> A2ARemoteAgent: + agent = A2ARemoteAgent( + config=AgentConfig(name=name, agent_type=AgentType.A2A, use_history=True), + a2a_config=A2AAgentConfig(url="http://127.0.0.1:41242", transport="JSONRPC"), + ) + agent.context_id = "ctx-current" + agent.current_task_id = "task-current" + agent.last_task_state = "TASK_STATE_INPUT_REQUIRED" + agent.remote_card = AgentCard( + name="Remote A2A", + description="Deterministic remote A2A agent.", + provider=AgentProvider(organization="tests", url="https://example.com"), + version="1.0", + supported_interfaces=[ + AgentInterface( + protocol_binding="JSONRPC", + protocol_version="1.0", + url="http://127.0.0.1:41242/a2a/jsonrpc", + ) + ], + ) + agent._client = _SelectedTransport() + return agent + + +async def _dispatch( + owner: InteractivePrompt, + app: AgentApp, + payload: A2ACommand, +) -> command_dispatch.DispatchResult: + return await dispatch_command_payload( + owner, + payload, + prompt_provider=app, + agent="remote", + available_agents=list(app.registered_agents()), + available_agents_set=set(app.registered_agents()), + merge_pinned_agents=lambda names: names, + ) + + +def _app(agents: dict[str, object]) -> AgentApp: + return AgentApp(cast("dict[str, AgentProtocol]", agents)) + + +@pytest.mark.asyncio +async def test_a2a_tui_dispatch_reports_status_transport_and_card( + monkeypatch: pytest.MonkeyPatch, +) -> None: + printed: list[str] = [] + monkeypatch.setattr( + command_dispatch, + "rich_print", + lambda value="", *args, **kwargs: printed.append(str(value)), + ) + remote = _remote_agent() + app = _app({"remote": remote}) + owner = InteractivePrompt(agent_types={"remote": AgentType.A2A}) + + status = await _dispatch(owner, app, A2ACommand(action="status", argument=None)) + transport = await _dispatch(owner, app, A2ACommand(action="transport", argument="remote")) + card = await _dispatch(owner, app, A2ACommand(action="card", argument="remote")) + + assert status.handled + assert transport.handled + assert card.handled + output = "\n".join(printed) + assert "A2A status: remote" in output + assert "Context: ctx-current" in output + assert "Task: task-current" in output + assert "Last state: TASK_STATE_INPUT_REQUIRED" in output + assert "A2A transport: remote" in output + assert "Requested: JSONRPC" in output + assert "Selected client: _SelectedTransport" in output + assert "A2A card: Remote A2A" in output + assert "JSONRPC 1.0: http://127.0.0.1:41242/a2a/jsonrpc" in output + + +@pytest.mark.asyncio +async def test_a2a_tui_dispatch_lists_and_resets_remote_agents( + monkeypatch: pytest.MonkeyPatch, +) -> None: + printed: list[str] = [] + monkeypatch.setattr( + command_dispatch, + "rich_print", + lambda value="", *args, **kwargs: printed.append(str(value)), + ) + remote = _remote_agent() + local = object() + app = _app({"remote": remote, "local": local}) + owner = InteractivePrompt(agent_types={"remote": AgentType.A2A, "local": AgentType.BASIC}) + + listed = await _dispatch(owner, app, A2ACommand(action="list", argument=None)) + reset = await _dispatch(owner, app, A2ACommand(action="reset", argument="remote")) + + assert listed.handled + assert reset.handled + assert " • remote" in printed + assert all("local" not in line for line in printed) + assert remote.context_id != "ctx-current" + assert remote.current_task_id is None + assert remote.last_task_state is None + + +@pytest.mark.asyncio +async def test_a2a_tui_dispatch_rejects_a2a_commands_for_local_agent( + monkeypatch: pytest.MonkeyPatch, +) -> None: + printed: list[str] = [] + monkeypatch.setattr( + command_dispatch, + "rich_print", + lambda value="", *args, **kwargs: printed.append(str(value)), + ) + app = _app({"local": object()}) + owner = InteractivePrompt(agent_types={"local": AgentType.BASIC}) + + result = await dispatch_command_payload( + owner, + A2ACommand(action="status", argument="local"), + prompt_provider=app, + agent="local", + available_agents=["local"], + available_agents_set={"local"}, + merge_pinned_agents=lambda names: names, + ) + + assert result.handled + assert "Agent 'local' is not an A2A agent." in "\n".join(printed) From 750760699f41ec5c8b3de7256f3a1e5eddad5b73 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 01:35:07 +0100 Subject: [PATCH 36/58] Add real LLM A2A recording path --- docs/docs/a2a/api.md | 1 + docs/docs/a2a/client.md | 52 ++ .../assets/a2a/a2a-real-llm-hf-streaming.cast | 614 ++++++++++++++++++ scripts/a2a_docs_pipeline.py | 211 +++++- src/fast_agent/a2a/config.py | 2 +- src/fast_agent/a2a/remote_agent.py | 5 +- src/fast_agent/core/agent_card_loader.py | 7 + src/fast_agent/core/agent_card_rules.py | 1 + .../fast_agent/core/test_agent_card_loader.py | 2 + .../test_a2a_remote_agent_config.py | 80 +++ 10 files changed, 971 insertions(+), 4 deletions(-) create mode 100644 docs/docs/assets/a2a/a2a-real-llm-hf-streaming.cast diff --git a/docs/docs/a2a/api.md b/docs/docs/a2a/api.md index ba76c567a..ff5ba5f43 100644 --- a/docs/docs/a2a/api.md +++ b/docs/docs/a2a/api.md @@ -57,6 +57,7 @@ A2AAgentConfig( accepted_output_modes=["text/plain", "application/json", "image/*"], headers={"Authorization": "Bearer ..."}, relative_card_path="/.well-known/agent-card.json", + request_timeout_seconds=120, ) ``` diff --git a/docs/docs/a2a/client.md b/docs/docs/a2a/client.md index 909148b2a..ba11d6f1e 100644 --- a/docs/docs/a2a/client.md +++ b/docs/docs/a2a/client.md @@ -103,6 +103,7 @@ accepted_output_modes: - text/plain - application/json - image/* +request_timeout_seconds: 120 headers: Authorization: "Bearer ${A2A_TOKEN}" relative_card_path: "/.well-known/agent-card.json" @@ -141,6 +142,57 @@ fast-agent stream listener path. The client assembles final text per artifact and honors the A2A `append` flag, so replacement updates replace the artifact content and append updates extend it. +The A2A client defaults to a longer HTTP request timeout than httpx's default so +real LLM-backed servers have time to emit the first stream event. Set +`request_timeout_seconds` on an A2A AgentCard when a remote endpoint needs a +different timeout. + +### Real LLM Server Recording + +This recording shows a fast-agent A2A client streaming from a fast-agent A2A +server backed by a real LLM and the Hugging Face MCP server. It is a provider +smoke recording, separate from the deterministic fake-server recordings used by +the test suite. + +
+
+
+ + + +Regenerate this provider-backed cast with: + +```bash +uv run scripts/a2a_docs_pipeline.py record-real-llm +``` + ## `INPUT_REQUIRED` When a remote A2A task reaches `TASK_STATE_INPUT_REQUIRED`, fast-agent: diff --git a/docs/docs/assets/a2a/a2a-real-llm-hf-streaming.cast b/docs/docs/assets/a2a/a2a-real-llm-hf-streaming.cast new file mode 100644 index 000000000..a742ed9ce --- /dev/null +++ b/docs/docs/assets/a2a/a2a-real-llm-hf-streaming.cast @@ -0,0 +1,614 @@ +{"version": 2, "width": 120, "height": 32, "timestamp": 1779323555, "idle_time_limit": 1.3, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}, "title": "fast-agent A2A real LLM Hugging Face MCP streaming demo"} +[0.024469, "o", "\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?2004l\u001b[1;1H\u001b[1;32r\u001b[>c\u001b[>q\u001b[14;1H"] +[0.025159, "o", "\u001b[?25l\u001b[2A─────────────────────────────────────────────────────────────\u001b[32m───────────────────────────────────────────────────────────\u001b(B\u001b[m\u001b[1;1Hfast-agent A2A server ready\u001b[K\r\nmodel: codexresponses.gpt-5.4-mini\u001b[K\r\nMCP: https://hf.co/mcp\u001b[K\r\nlog: /tmp/a2a-real-llm-server.log\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[2BA2A card: http://127.0.0.1:41243/.well-known/agent-card.json\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[14d\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?2004l\u001b[1;1H\u001b[1;32r\u001b[14;1H\u001b[?25l\u001b[2A─────────────────────────────────────────────────────────────\u001b[32m───────────────────────────────────────────────────────────\u001b(B\u001b[m\u001b[1;1Hfast-agent A2A server ready\u001b[K\r\nmodel: codexresponses.gpt-5.4-mini\u001b[K\r\nMCP: https://hf.co/mcp\u001b[K\r\nlog: /tmp/a2a-real-llm-server.log\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[2BA2A card: http://127.0.0.1:41243/.well-known/agent-card.json\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[14d"] +[0.04037, "o", "{\r\n \"name\": \"hf-model-research\",\r\n \"description\": \"A fast-agent A2A server.\",\r\n \"supportedInterfaces\": [\r\n {\r\n \"url\": \"http://127.0.0.1:41243/a2a/jsonrpc\",\r\n \"protocolBinding\": \"JSONRPC\",\r\n \"protocolVersion\": \"1.0\"\r\n },\r\n {\r\n \"url\": \"http://127.0.0.1:41243/a2a/rest\",\r\n \"protocolBinding\": \"HTTP+JSON\",\r\n \"protocolVersion\": \"1.0\"\r\n }\r\n ],\r\n \"provider\": {\r\n \"url\": \"https://fast-agent.ai\",\r\n\u001b[13;32r\u001b[1;1H\u001b[4S\u001b[27d \"organization\": \"fast-agent\"\r\n },\r\n \"version\": \"0.7.8\",\u001b[K\r\n \"capabilities\": {\u001b[K\r\n \"streaming\": true,\u001b[K\r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[0.043338, "o", "\u001b[13;32r\u001b[1;1H\u001b[2S\u001b[31dinteractive A2A JSON-RPC client\u001b[K\r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[0.527263, "o", "\u001b[?25l\u001b[12d─────────────────────────────────────────────────────────────\u001b[32m───────────────────────────────────────────────────────────\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[32;1H"] +[1.026129, "o", "\u001b[?7727h"] +[2.169532, "o", "\u001b[?25l"] +[2.187965, "o", "\u001b[?12l\u001b[?25h"] +[2.197368, "o", "\u001b[13;32r\u001b[1;1H\u001b[3S\u001b[29d\u001b[2mUse \u001b[32m'/'\u001b[39m for commands, \u001b[32m'!'\u001b[39m for shell. \u001b[32m'#'\u001b[39m to query, \u001b[32m'@'\u001b[39m to switch agents\r\nCTRL+T multiline, CTRL+Y copy last message, CTRL+E external editor.\u001b(B\u001b[m\u001b[K\r\n\u001b[2mCTRL+Space or Tab for path completion. Use \u001b[35m/\u001b[95mattach\u001b[39m, `^file:`, or `^url:` for attachments. F10 to clear.\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[2.197491, "o", "\u001b[13;32r\u001b[32;1H\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[2.200535, "o", "\u001b[13;32r\u001b[32;1H\u001b[K❯\r\u001b[7S\u001b[6A\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[1;32r\u001b[25;3H\u001b[?2004h"] +[2.204388, "o", "\u001b[13;32r\u001b[32;1H\n\u001b[K\u001b[30m\u001b[47m\u001b[7m \u001b[35m\u001b[40m a2a_remote[A2A] \u001b[30m\u001b[47m \u001b[100m ▲ \u001b[47m \u001b[42mhf-model-research\u001b[47m | 000 | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | fast-agent 0.7.8 \u001b[32;1H\u001b[1;32r\u001b[24;3H\u001b(B\u001b[m"] +[3.570918, "o", "Use the Hugging Face MCP server if available. Answer in markdown: what models are trending on Hugging Face right now?\r\nInclude concise bullets and mention any uncertainty."] +[3.574149, "o", "\u001b[24;1H❯ \u001b[32;1H \u001b[K\u001b[25;53H"] +[3.574432, "o", "\u001b[13;32r\u001b[25;1H\u001b[J\u001b[A\u001b[K\u001b[1;32r\u001b[24;1H\u001b[?2004l"] +[3.574743, "o", "\u001b[A"] +[3.575061, "o", "\u001b[?25l"] +[3.575849, "o", "\r\n"] +[3.57623, "o", "\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m \u001b[34ma2a_remote\u001b[39m \u001b[2m──────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[25;1H\u001b(B\u001b[m"] +[3.576799, "o", "Use the Hugging Face MCP server if available. Answer in markdown: what models are trending on Hugging Face right now? \r\nInclude concise bullets and mention any uncertainty.\r\n"] +[3.577997, "o", "\u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.578381, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.676465, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.777234, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.878126, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.896019, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.896431, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.978868, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.079536, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.180286, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.281106, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.381781, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.482551, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.583144, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.684086, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.78485, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.885568, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.986237, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.086948, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.187858, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.288624, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.38933, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.489961, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.590855, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.691642, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.792418, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.893163, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.993885, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.094589, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.195364, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.284472, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.286844, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.287428, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.288685, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.295809, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.302287, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.303364, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.304045, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.304461, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.304906, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.30549, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.305965, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.306383, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.308467, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.310429, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.312391, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.313259, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.318022, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.318456, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.319966, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.323255, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.327462, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.329796, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.331294, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.333173, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.351392, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.352354, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.353348, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.354078, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.354325, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.3547, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.355195, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.355787, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.356284, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.356883, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.357163, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.396597, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.497407, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.598102, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.698808, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.79943, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.900203, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.000904, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.101527, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.20218, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.302868, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.403625, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.504553, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.605218, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.705965, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.806797, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.907536, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.008259, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.109062, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.20974, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.310584, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.411351, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.512302, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.612955, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.713788, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.814454, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.915386, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.016044, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.116718, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.217377, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.318249, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.418944, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.519597, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.565337, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.568087, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.571001, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.573388, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.57975, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.58016, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.581761, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.586139, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.590768, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.593236, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.595392, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.597281, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.599215, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.601009, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.604803, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.612336, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.612862, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.615799, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.616321, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.617374, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.620142, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.621249, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.622584, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.624818, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.626274, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.630165, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.634695, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.640682, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.643798, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.646002, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.649133, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.651386, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.653249, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.655885, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.660725, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.663332, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.665126, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.666878, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.669716, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.675527, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.676006, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.681943, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.684137, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.684857, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.687018, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.690254, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.69278, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.694093, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.697054, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.701088, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.705735, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.708494, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.710713, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.71247, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.714125, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.715671, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.718494, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.7206, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.725264, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.725708, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.728053, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.731071, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.732762, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.736476, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.73773, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.739179, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.741514, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.744319, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.749066, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.750473, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.75299, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.75495, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.757119, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.759231, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.761705, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.765178, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.769135, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.770849, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.773526, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.777311, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.780245, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.781803, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.784488, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.788582, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.793552, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.798131, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.800503, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.80334, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.806015, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.808911, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.809525, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.811611, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.814309, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.817687, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.820757, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.821192, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.823583, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.826296, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.827907, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.830099, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.836944, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.839396, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.847663, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.848562, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.850388, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.854323, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.855721, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.85768, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.858826, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.861377, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.865453, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.869254, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.871695, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.874704, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.87773, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.881312, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.884983, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.887754, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.892722, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.897053, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.899948, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.901361, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.903401, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.907653, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.909686, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.911787, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.920726, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.921157, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.921704, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.923607, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.925816, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.92779, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.929826, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.931728, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.934355, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.938305, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.943663, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.948586, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.94983, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.952418, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.954366, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.956578, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.959454, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.962553, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.9661, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.969565, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.973763, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.977303, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.982574, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.985629, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.991676, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.996274, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.008774, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.013768, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.018955, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.020367, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.022302, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.025894, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.031732, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.037332, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.041746, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.044739, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.046789, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.050216, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.053876, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.056451, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.05939, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.060881, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.065322, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.06902, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.076494, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.080851, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.081501, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.082951, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.086185, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.088643, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.090103, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.092814, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.096715, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.100603, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.104651, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.106563, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.108883, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.110515, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.112234, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.118917, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.119491, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.122937, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.123655, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.126673, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.129436, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.131612, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.133122, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.136048, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.138966, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.141257, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.144642, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.146693, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.149673, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.151798, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.155618, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.156273, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.158722, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.162717, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.166074, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.171221, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.173986, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.176031, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.180549, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.181509, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.186973, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.187395, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.191381, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.194411, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.196744, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.198989, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.20138, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.202683, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.204453, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.208491, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.212407, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.216277, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.223388, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.224556, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.225258, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.225694, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.226074, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.227652, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.231017, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.237852, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.239582, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.24234, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.245169, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.248396, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.25089, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.252284, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.255192, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.258318, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.262528, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.266441, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.268974, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.270974, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.276273, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.278673, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.283881, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.28601, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.288289, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.290182, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.292237, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.294559, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.296725, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.299044, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.301575, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.305601, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.309658, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.312387, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.316354, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.317507, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.321024, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.322599, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.323813, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.326927, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.330617, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.332773, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.33471, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.336911, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.337806, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.340693, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.343963, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.345134, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.348423, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.351267, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.353735, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.355982, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.358706, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.362331, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.362826, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.364482, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.367409, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.370554, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.374913, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.379874, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.383506, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.385537, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.386996, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.389941, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.390948, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.392408, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.396786, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.400913, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.401777, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.40561, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.406006, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.407622, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.409509, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.411318, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.414297, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.416716, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.420561, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.42316, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.42436, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.42631, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.429699, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.431793, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.43629, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.441067, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.445435, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.449339, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.452144, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.454448, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.456191, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.458148, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.460659, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.46374, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.467309, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.470916, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.474955, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.476083, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.478035, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.481267, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.483998, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.48818, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.492153, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.495635, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.49879, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.501566, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.509383, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.509787, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.510223, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.511254, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.515335, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.51905, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.521833, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.524892, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.526739, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.529581, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.53368, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.537669, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.542474, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.54763, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.550139, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.553301, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.557015, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.558501, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.560688, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.5622, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.566011, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.570012, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.572316, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.575806, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.57925, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.581036, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.58311, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.58717, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.592002, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.594606, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.597375, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.598476, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.600395, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.603894, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.605396, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.608548, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.613342, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.617564, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.619385, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.621432, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.624425, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.625333, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.626908, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.630239, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.6332, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.636512, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.640755, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.643309, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.646774, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.648563, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.650504, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.653233, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.656799, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.65983, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.663747, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.666872, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.669298, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.671953, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.674746, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.676648, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.679429, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.682182, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.684801, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.689402, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.691886, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.693732, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.696077, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.70161, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.70634, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.71586, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.720604, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.725912, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.730659, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.734795, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.739189, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.746592, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.749051, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.753031, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.757946, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.760662, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.764256, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.769773, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.772851, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.777345, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.778806, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.780819, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.785071, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.78796, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.793693, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.799555, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.802301, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.803119, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.805165, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.807966, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.81107, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.814747, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.821221, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.825312, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.826357, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.828497, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.830907, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.834001, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.837861, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.840889, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.845321, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.848912, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.852021, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.85666, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.860373, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.863257, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.86484, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.869219, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.86997, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.87329, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.876669, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.880619, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.885835, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.888985, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.893128, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.896476, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.903124, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.907867, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.909776, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.911612, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.914051, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.915707, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.917621, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.919235, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.921825, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.924201, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.926823, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.936293, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.936726, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.941992, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.942404, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.942857, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.946351, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.946759, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.951561, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.955904, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.956432, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.959772, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.960272, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.962362, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.963125, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.963582, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.964069, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.964588, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.965099, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.967358, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.971352, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[11.027772, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[11.052512, "o", "\r\u001b[K\u001b[?12l\u001b[?25h"] +[11.052945, "o", "\r\n"] +[11.053114, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32ma2a_remote\u001b[39m \u001b[2mA2A\r\n\u001b(B\u001b[m"] +[11.059437, "o", "Here are the \u001b[1mcurrently trending Hugging Face models\u001b(B\u001b[m I found via the Hub’s trending ranking. \u001b[1mUncertainty:\u001b(B\u001b[m “Trending” is \u001b[30;1Hdynamic and can shift by hour/day, so treat this as a snapshot from right now. \u001b[32;1H\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m —\u001b[13;32r\u001b[32;1H\n\u001b[31;30H any-to-any / multimodal \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m —\r\n\u001b[31;30H text-to-video \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4mopenbmb/MiniCPM-V-4.6\u001b(B\u001b[m —\r\n\u001b[31;27H image-text-to-text \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m —\r\n\u001b[31;28H text-to-speech \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4munsloth/Qwen3.6-27B-MTP-GGUF\u001b(B\u001b[m —\r\n\u001b[31;34H image-text-to-text \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4mcirclestone-labs/Anima\u001b(B\u001b[m —\r\n\u001b[31;28H diffusion-single-file \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4munsloth/Qwen3.6-35B-A3B-MTP-GGUF\u001b(B\u001b[m —\r\n\u001b[31;38H image-text-to-text \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4mResembleAI/Dramabox\u001b(B\u001b[m —\r\n\u001b[31;25H text-to-speech \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m —\r\n\u001b[31;28H text-generation \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4mfroggeric/Qwen-Fixed-Chat-Templates\u001b(B\u001b[m —\r\u001b[4S\u001b[28;41H chat-template utilities \u001b[29;1H\u001b[K\r\nIf you want, I can also narrow this down to: \u001b[31;1H\u001b[K\r\n\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m•\u001b(B\u001b[m\r\n\u001b[31;3H\u001b[1m top open-weights LLMs\u001b(B\u001b[m \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m•\u001b(B\u001b[m\r\n\u001b[31;3H\u001b[1m top multimodal models\u001b(B\u001b[m \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m•\u001b(B\u001b[m\r\n\u001b[31;3H\u001b[1m top text-to-image/video/speech models\u001b(B\u001b[m \u001b[32;1H\u001b[K\u001b[1;32r\u001b[32;1H"] +[11.059537, "o", "\u001b[13;32r\u001b[32;1H\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[11.191844, "o", "\u001b[13;32r\u001b[32;1H\u001b[K❯\r\u001b[7S\u001b[6A\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[1;32r\u001b[25;3H\u001b[?2004h"] +[11.195311, "o", "\u001b[13;32r\u001b[32;1H\n\u001b[K\u001b[30m\u001b[47m\u001b[7m \u001b[35m\u001b[40m a2a_remote[A2A] \u001b[30m\u001b[47m \u001b[100m ▲ \u001b[47m \u001b[42mhf-model-research\u001b[47m | 001 | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | fast-agent 0.7.8 \u001b[32;1H\u001b[1;32r\u001b[24;3H\u001b(B\u001b[m"] +[73.558241, "o", "\r❯ /exit\u001b[32;1H \u001b[K\u001b[24;8H"] +[73.558482, "o", "\u001b[13;32r\u001b[25;1H\u001b[J\u001b[A\u001b[K\u001b[1;32r\u001b[24;1H"] +[73.558661, "o", "\u001b[?2004l"] +[73.559305, "o", "\u001b[2m❯ \u001b[35m/\u001b[95mexit\r\n\u001b(B\u001b[m"] +[73.559746, "o", "\r\n\u001b[31m\u001b[1mUser requested exit:\r\n\u001b(B\u001b[m"] +[73.559913, "o", "User requested to exit fast-agent session\r\n"] +[74.056648, "o", "\u001b[?25l\u001b[Hfast-agent A2A server ready\u001b[K\r\nmodel: codexresponses.gpt-5.4-mini\u001b[K\r\nMCP: https://hf.co/mcp\u001b[K\r\nlog: /tmp/a2a-real-llm-server.log\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[6d"] +[74.308143, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] +[75.560495, "o", "\u001b[1;32r\u001b(B\u001b[m\u001b[?1l\u001b>\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?7727l\u001b[?1004l\u001b[?1049l\u001b[23;0;0t"] +[75.56079, "o", "[exited]\r\n"] diff --git a/scripts/a2a_docs_pipeline.py b/scripts/a2a_docs_pipeline.py index cd48ffe4f..52a34c2d2 100755 --- a/scripts/a2a_docs_pipeline.py +++ b/scripts/a2a_docs_pipeline.py @@ -9,12 +9,15 @@ uv run scripts/a2a_docs_pipeline.py generate uv run scripts/a2a_docs_pipeline.py check uv run scripts/a2a_docs_pipeline.py record + uv run scripts/a2a_docs_pipeline.py record-real-llm """ from __future__ import annotations import argparse +import os import shutil +import signal import subprocess import sys import time @@ -27,7 +30,14 @@ ASSETS = ROOT / "docs" / "docs" / "assets" / "a2a" RECORDS = Path.home() / "plan" / "records" PORT = 41242 +REAL_LLM_PORT = 41243 BASE_URL = f"http://127.0.0.1:{PORT}" +REAL_LLM_BASE_URL = f"http://127.0.0.1:{REAL_LLM_PORT}" +REAL_LLM_MCP_URL = "https://hf.co/mcp" +REAL_LLM_MODEL = "codexresponses.gpt-5.4-mini" +REAL_LLM_CAST = "a2a-real-llm-hf-streaming.cast" +REAL_LLM_SERVER_LOG = Path("/tmp/a2a-real-llm-server.log") +REAL_LLM_READY_TIMEOUT_SECONDS = 90.0 START_FAKE_SERVER = f"uv run python tests/integration/a2a/fake_server.py --port {PORT}\n" STREAM_COMMAND = f"""uv run fast-agent -x \\ @@ -131,6 +141,37 @@ def _stop_server(process: subprocess.Popen[str]) -> None: process.wait(timeout=5) +def _log_tail(path: Path, *, lines: int = 80) -> str: + if not path.exists(): + return f"{path} does not exist" + content = path.read_text(encoding="utf-8", errors="replace").splitlines() + return "\n".join(content[-lines:]) + + +def _wait_for_url( + url: str, + *, + process: subprocess.Popen[str] | None = None, + log_path: Path | None = None, + timeout_seconds: float = 10.0, +) -> None: + deadline = time.monotonic() + timeout_seconds + while time.monotonic() < deadline: + if process is not None and process.poll() is not None: + details = f"\nLOG:\n{_log_tail(log_path)}" if log_path is not None else "" + raise RuntimeError( + f"process exited before {url} became ready with status {process.returncode}{details}" + ) + try: + with urllib.request.urlopen(url, timeout=0.5) as response: # noqa: S310 - docs smoke URL + if response.status == 200: + return + except OSError: + time.sleep(0.5) + details = f"\nLOG:\n{_log_tail(log_path)}" if log_path is not None else "" + raise TimeoutError(f"{url} did not become ready within {timeout_seconds:.1f}s{details}") + + def generate() -> None: SNIPPETS.mkdir(parents=True, exist_ok=True) ASSETS.mkdir(parents=True, exist_ok=True) @@ -173,6 +214,7 @@ def check() -> None: ASSETS / "a2a-client-cli.cast", ASSETS / "a2a-client-input-required.cast", ASSETS / "a2a-server-card.cast", + ASSETS / REAL_LLM_CAST, ROOT / "docs" / "docs" / "assets" / "vendor" / "asciinema-player" / "asciinema-player.css", ROOT / "docs" / "docs" / "assets" / "vendor" / "asciinema-player" / "catppuccin.css", ROOT / "docs" / "docs" / "assets" / "vendor" / "asciinema-player" / "asciinema-player.min.js", @@ -199,6 +241,7 @@ def check() -> None: DOCS_A2A / "client.md": [ "../../assets/a2a/a2a-client-cli.cast", "../../assets/a2a/a2a-client-input-required.cast", + f"../../assets/a2a/{REAL_LLM_CAST}", ], DOCS_A2A / "server.md": ["../../assets/a2a/a2a-server-card.cast"], } @@ -288,16 +331,180 @@ def record() -> None: _stop_server(server) +def _require_real_llm_recording_tools() -> None: + missing = [tool for tool in ["asciinema", "tmux", "curl"] if not shutil.which(tool)] + if missing: + raise SystemExit("record-real-llm requires these tools: " + ", ".join(missing)) + missing_env = [ + name + for name in ["HF_TOKEN", "OPENAI_API_KEY"] + if not os.environ.get(name) + ] + if missing_env: + raise SystemExit( + "record-real-llm requires environment variables: " + ", ".join(missing_env) + ) + + +def _start_real_llm_server(instruction: Path) -> subprocess.Popen[str]: + REAL_LLM_SERVER_LOG.unlink(missing_ok=True) + log_file = REAL_LLM_SERVER_LOG.open("w", encoding="utf-8") + env = os.environ.copy() + model = env.get("A2A_REAL_LLM_MODEL", REAL_LLM_MODEL) + hf_mcp_url = env.get("A2A_HF_MCP_URL", REAL_LLM_MCP_URL) + command = [ + "uv", + "run", + "fast-agent", + "serve", + "a2a", + "--host", + "127.0.0.1", + "--port", + str(REAL_LLM_PORT), + "--name", + "hf-model-research", + "--model", + model, + "--url", + hf_mcp_url, + "--instruction", + str(instruction), + ] + process = subprocess.Popen( + command, + cwd=ROOT, + env=env, + text=True, + stdout=log_file, + stderr=subprocess.STDOUT, + start_new_session=True, + ) + log_file.close() + _wait_for_url( + f"{REAL_LLM_BASE_URL}/.well-known/agent-card.json", + process=process, + log_path=REAL_LLM_SERVER_LOG, + timeout_seconds=float( + os.environ.get( + "A2A_REAL_LLM_READY_TIMEOUT_SECONDS", + str(REAL_LLM_READY_TIMEOUT_SECONDS), + ) + ), + ) + return process + + +def _stop_real_llm_server(process: subprocess.Popen[str]) -> None: + if process.poll() is not None: + return + try: + os.killpg(process.pid, signal.SIGTERM) + except ProcessLookupError: + return + try: + process.wait(timeout=10) + except subprocess.TimeoutExpired: + os.killpg(process.pid, signal.SIGKILL) + process.wait(timeout=5) + + +def record_real_llm() -> None: + """Record a provider-backed A2A server/client streaming demo.""" + _require_real_llm_recording_tools() + ASSETS.mkdir(parents=True, exist_ok=True) + RECORDS.mkdir(parents=True, exist_ok=True) + + instruction = Path("/tmp/a2a-real-llm-instruction.md") + instruction.write_text( + """You are a concise Hugging Face model research assistant. + +Use available Hugging Face MCP tools to answer questions about models. When the +user asks about trending models, use markdown with a short heading, 3-5 bullets, +and a brief note about the source or any uncertainty. +""", + encoding="utf-8", + ) + + server = _start_real_llm_server(instruction) + driver = Path("/tmp/a2a-real-llm-record.sh") + driver.write_text( + f"""#!/usr/bin/env bash +set -euo pipefail +SESSION=a2a_real_llm_cast +ROOT={ROOT} +BASE_URL={REAL_LLM_BASE_URL} +SERVER_LOG={REAL_LLM_SERVER_LOG} +RECORD_SECONDS="${{A2A_REAL_LLM_RECORD_SECONDS:-70}}" +MODEL="${{A2A_REAL_LLM_MODEL:-{REAL_LLM_MODEL}}}" +HF_MCP_URL="${{A2A_HF_MCP_URL:-{REAL_LLM_MCP_URL}}}" +PROMPT='Use the Hugging Face MCP server if available. Answer in markdown: what models are trending on Hugging Face right now? Include concise bullets and mention any uncertainty.' + +tmux kill-session -t "$SESSION" 2>/dev/null || true +tmux new-session -d -s "$SESSION" -x 120 -y 32 \ + "printf 'fast-agent A2A server ready\\nmodel: %s\\nMCP: %s\\nlog: %s\\n\\n' '$MODEL' '$HF_MCP_URL' '$SERVER_LOG'; tail -n 80 -f '$SERVER_LOG'" +tmux set-option -t "$SESSION" status off >/dev/null +tmux split-window -v -t "$SESSION" -l 20 \ + "cd '$ROOT' && printf 'A2A card: %s/.well-known/agent-card.json\\n' '$BASE_URL'; curl -fsS '$BASE_URL/.well-known/agent-card.json' | python -m json.tool | sed -n '1,22p'; printf '\\ninteractive A2A JSON-RPC client\\n'; TERM=xterm-256color COLORTERM=truecolor FORCE_COLOR=1 FAST_AGENT_MODEL=passthrough uv run fast-agent -x --noenv --a2a '$BASE_URL' --a2a-transport JSONRPC" + +( + for _ in $(seq 1 120); do + if tmux capture-pane -p -t "$SESSION":0.1 | grep -q 'a2a_remote'; then + break + fi + sleep 0.5 + done + sleep 1 + tmux send-keys -l -t "$SESSION":0.1 "$PROMPT" + tmux send-keys -t "$SESSION":0.1 Enter + sleep "$RECORD_SECONDS" + tmux send-keys -t "$SESSION":0.1 '/exit' Enter + sleep 2 + tmux kill-session -t "$SESSION" 2>/dev/null || true +) & + +tmux select-pane -t "$SESSION":0.1 +tmux attach-session -t "$SESSION" || true +""", + encoding="utf-8", + ) + driver.chmod(0o755) + + command = [ + "asciinema", + "rec", + "--overwrite", + "--cols", + "120", + "--rows", + "32", + "--idle-time-limit", + "1.3", + "-t", + "fast-agent A2A real LLM Hugging Face MCP streaming demo", + "-c", + str(driver), + str(ASSETS / REAL_LLM_CAST), + ] + try: + subprocess.run(command, cwd=ROOT, check=True) + finally: + subprocess.run(["tmux", "kill-session", "-t", "a2a_real_llm_cast"], check=False) + _stop_real_llm_server(server) + + def main() -> int: parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("command", choices=["generate", "check", "record"]) + parser.add_argument("command", choices=["generate", "check", "record", "record-real-llm"]) args = parser.parse_args() if args.command == "generate": generate() elif args.command == "check": check() - else: + elif args.command == "record": record() + else: + record_real_llm() return 0 diff --git a/src/fast_agent/a2a/config.py b/src/fast_agent/a2a/config.py index 9cb1baec7..33e5561db 100644 --- a/src/fast_agent/a2a/config.py +++ b/src/fast_agent/a2a/config.py @@ -12,4 +12,4 @@ class A2AAgentConfig: accepted_output_modes: list[str] = field(default_factory=list) headers: dict[str, str] = field(default_factory=dict) relative_card_path: str | None = None - + request_timeout_seconds: float | None = 120.0 diff --git a/src/fast_agent/a2a/remote_agent.py b/src/fast_agent/a2a/remote_agent.py index 00598d623..2363aeb52 100644 --- a/src/fast_agent/a2a/remote_agent.py +++ b/src/fast_agent/a2a/remote_agent.py @@ -105,7 +105,10 @@ def agent_type(self) -> AgentType: async def initialize(self) -> None: await super().initialize() - self._httpx_client = httpx.AsyncClient(headers=self.a2a_config.headers or None) + self._httpx_client = httpx.AsyncClient( + headers=self.a2a_config.headers or None, + timeout=self.a2a_config.request_timeout_seconds, + ) client_config = ClientConfig( streaming=self.a2a_config.streaming, polling=self.a2a_config.polling, diff --git a/src/fast_agent/core/agent_card_loader.py b/src/fast_agent/core/agent_card_loader.py index 2cc5f6d52..1f64592f7 100644 --- a/src/fast_agent/core/agent_card_loader.py +++ b/src/fast_agent/core/agent_card_loader.py @@ -552,6 +552,11 @@ def _build_agent_data( relative_card_path=_ensure_optional_str( raw.get("relative_card_path"), "relative_card_path", path ), + request_timeout_seconds=( + _ensure_float(raw.get("request_timeout_seconds"), "request_timeout_seconds", path) + if raw.get("request_timeout_seconds") is not None + else 120.0 + ), ) return agent_data @@ -1205,6 +1210,8 @@ def _serialize_a2a_fields( card["headers"] = dict(a2a_config.headers) if a2a_config.relative_card_path: card["relative_card_path"] = a2a_config.relative_card_path + if a2a_config.request_timeout_seconds != 120.0: + card["request_timeout_seconds"] = a2a_config.request_timeout_seconds _CARD_SERIALIZERS: dict[CardType, CardTypeSerializer] = { diff --git a/src/fast_agent/core/agent_card_rules.py b/src/fast_agent/core/agent_card_rules.py index 9d901a624..141682bf5 100644 --- a/src/fast_agent/core/agent_card_rules.py +++ b/src/fast_agent/core/agent_card_rules.py @@ -152,6 +152,7 @@ "accepted_output_modes", "headers", "relative_card_path", + "request_timeout_seconds", }, } diff --git a/tests/unit/fast_agent/core/test_agent_card_loader.py b/tests/unit/fast_agent/core/test_agent_card_loader.py index 694777266..bf9fad344 100644 --- a/tests/unit/fast_agent/core/test_agent_card_loader.py +++ b/tests/unit/fast_agent/core/test_agent_card_loader.py @@ -517,6 +517,7 @@ def test_load_a2a_agent_card(tmp_path: Path) -> None: "name: hello_remote", "url: http://127.0.0.1:41241", "transport: JSONRPC", + "request_timeout_seconds: 45", "accepted_output_modes:", " - text", ] @@ -534,6 +535,7 @@ def test_load_a2a_agent_card(tmp_path: Path) -> None: assert a2a_config.transport == "JSONRPC" assert a2a_config.streaming is True assert a2a_config.accepted_output_modes == ["text"] + assert a2a_config.request_timeout_seconds == 45.0 def test_load_a2a_agent_card_rejects_invalid_transport(tmp_path: Path) -> None: diff --git a/tests/unit/fast_agent/test_a2a_remote_agent_config.py b/tests/unit/fast_agent/test_a2a_remote_agent_config.py index a8ab25e95..e8e82eda7 100644 --- a/tests/unit/fast_agent/test_a2a_remote_agent_config.py +++ b/tests/unit/fast_agent/test_a2a_remote_agent_config.py @@ -62,8 +62,16 @@ async def fake_create_client(agent_card: AgentCard, *, client_config: Any) -> Fa captured["client_config"] = client_config return FakeClient() + class FakeAsyncClient: + def __init__(self, *_args: Any, **kwargs: Any) -> None: + captured["httpx_timeout"] = kwargs.get("timeout") + + async def aclose(self) -> None: + return None + monkeypatch.setattr("fast_agent.a2a.remote_agent.A2ACardResolver", FakeResolver) monkeypatch.setattr("fast_agent.a2a.remote_agent.create_client", fake_create_client) + monkeypatch.setattr("fast_agent.a2a.remote_agent.httpx.AsyncClient", FakeAsyncClient) agent = A2ARemoteAgent( config=AgentConfig(name="remote", agent_type=AgentType.A2A, use_history=False), @@ -73,6 +81,78 @@ async def fake_create_client(agent_card: AgentCard, *, client_config: Any) -> Fa try: client_config = captured["client_config"] assert client_config.supported_protocol_bindings == SUPPORTED_A2A_HTTP_TRANSPORTS + assert captured["httpx_timeout"] == 120.0 + finally: + await agent.shutdown() + + +@pytest.mark.asyncio +async def test_a2a_remote_agent_uses_configured_request_timeout(monkeypatch) -> None: + captured: dict[str, Any] = {} + + class FakeResolver: + def __init__(self, *_args: Any, **_kwargs: Any) -> None: + return None + + async def get_agent_card(self) -> AgentCard: + return AgentCard( + name="jsonrpc", + description="JSON-RPC", + provider=AgentProvider(organization="test", url="https://example.com"), + version="1.0.0", + capabilities=AgentCapabilities(streaming=True, push_notifications=False), + default_input_modes=["text"], + default_output_modes=["text"], + skills=[ + AgentSkill( + id="echo", + name="Echo", + description="Echo input", + tags=["test"], + examples=["hello"], + input_modes=["text"], + output_modes=["text"], + ) + ], + supported_interfaces=[ + AgentInterface( + protocol_binding="JSONRPC", + protocol_version="1.0", + url="http://127.0.0.1:41242/a2a/jsonrpc", + ) + ], + ) + + class FakeClient: + async def close(self) -> None: + return None + + class FakeAsyncClient: + def __init__(self, *_args: Any, **kwargs: Any) -> None: + captured["httpx_timeout"] = kwargs.get("timeout") + + async def aclose(self) -> None: + return None + + async def fake_create_client(agent_card: AgentCard, *, client_config: Any) -> FakeClient: + captured["agent_card"] = agent_card + captured["client_config"] = client_config + return FakeClient() + + monkeypatch.setattr("fast_agent.a2a.remote_agent.A2ACardResolver", FakeResolver) + monkeypatch.setattr("fast_agent.a2a.remote_agent.create_client", fake_create_client) + monkeypatch.setattr("fast_agent.a2a.remote_agent.httpx.AsyncClient", FakeAsyncClient) + + agent = A2ARemoteAgent( + config=AgentConfig(name="remote", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig( + url="http://127.0.0.1:41242", + request_timeout_seconds=30.0, + ), + ) + await agent.initialize() + try: + assert captured["httpx_timeout"] == 30.0 finally: await agent.shutdown() From 0f3b8407f1b4b4dd5ea478c27873ab36faa98943 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 01:39:26 +0100 Subject: [PATCH 37/58] Test A2A serve CLI paths --- plan/05-21-a2a-orientation.md | 155 +++++++++++++++--- .../fast_agent/cli/test_a2a_serve_options.py | 85 ++++++++++ 2 files changed, 216 insertions(+), 24 deletions(-) create mode 100644 tests/unit/fast_agent/cli/test_a2a_serve_options.py diff --git a/plan/05-21-a2a-orientation.md b/plan/05-21-a2a-orientation.md index dcd0abb85..3b56f5f96 100644 --- a/plan/05-21-a2a-orientation.md +++ b/plan/05-21-a2a-orientation.md @@ -6,20 +6,28 @@ Last updated: 2026-05-21 ## Purpose This note is a handoff/orientation guide for fast-agent's current A2A client -work. It points to the key files, deterministic fixtures, docs assets, and -manual commands so the next session can avoid rediscovery. +and server work. It points to the key files, deterministic fixtures, docs +assets, and manual commands so the next session can avoid rediscovery. ## Current feature shape -fast-agent is currently an A2A **client**: +fast-agent is currently both an A2A **client** and **server** for HTTP +transports: - remote A2A agents can be configured via `type: a2a` AgentCards; - `/a2a connect` can create a runtime A2A agent from the TUI; - JSON-RPC and HTTP+JSON are covered by deterministic integration tests; -- gRPC is accepted/configurable through the SDK path but does not yet have - fast-agent-owned integration coverage; +- gRPC is intentionally out of scope for this A2A support pass and is rejected + by fast-agent card/command validation; - A2A messages map to normal fast-agent user/assistant turns and local history; - A2A `context_id`, `task_id`, and task state are tracked on `A2ARemoteAgent`. +- `fast-agent serve a2a` and `fast-agent serve --transport a2a` expose loaded + fast-agent agents over JSON-RPC and HTTP+JSON. +- served A2A AgentCards advertise one A2A `AgentSkill` per loaded fast-agent + agent, plus JSON-RPC and HTTP+JSON interfaces. +- server-side `contextId` is optional in inbound A2A messages; the SDK resolves + one when omitted, and `--instance-scope connection` uses it as the fast-agent + instance/session key. ## Key implementation files @@ -44,13 +52,29 @@ fast-agent is currently an A2A **client**: - `accepted_output_modes` - `headers` - `relative_card_path` + - `request_timeout_seconds` - `src/fast_agent/a2a/connect.py` - URL and argument normalization for `/a2a connect`. - Transport aliases: - `jsonrpc`, `json-rpc`, `rpc` -> `JSONRPC` - `http`, `http+json`, `rest` -> `HTTP+JSON` - - `grpc` -> `GRPC` + - `grpc` -> rejected; gRPC is not supported by fast-agent A2A. + +### Server adapter + +- `src/fast_agent/a2a/server.py` + - `AgentA2AServer` exposes fast-agent through SDK JSON-RPC and REST routes. + - `FastAgentA2AExecutor` maps A2A messages to `PromptMessageExtended`, calls + the selected fast-agent agent, and emits A2A task status/artifact updates. + - `TaskArtifactUpdateEvent.append` is used for streaming chunks; the final + response can replace the streamed artifact when needed. + - `TASK_STATE_INPUT_REQUIRED` is returned when the fast-agent response has + `LlmStopReason.PAUSE`. + - `AUTH_REQUIRED`, `FAILED`, and `CANCELED` states are mapped from provider + auth errors, unexpected execution errors, and cancellation. + - raw image/file/data/text URL parts are bridged to and from fast-agent + content blocks. ### AgentCard/direct factory wiring @@ -84,6 +108,10 @@ fast-agent is currently an A2A **client**: - `src/fast_agent/cli/commands/go.py` - `--a2a` and `--a2a-transport` runtime connection shortcuts. +- `src/fast_agent/cli/commands/serve.py` + - `fast-agent serve a2a` subcommand. + - legacy-compatible `fast-agent serve --transport a2a` callback path. + ## Deterministic A2A fixtures and tests ### Integration fixture @@ -142,9 +170,31 @@ fast-agent is currently an A2A **client**: - Long streaming chunks. - Inbound URL/data/raw rendering. - Outbound URL/raw parts. + - JSON `TextResourceContents` emitted as A2A data parts. + - no-history A2A context reset except while continuing `INPUT_REQUIRED`. - `/a2a connect` runtime agent creation. - `INPUT_REQUIRED` task preservation and follow-up completion. +- `tests/integration/a2a/test_fast_agent_a2a_server.py` + - fast-agent served as JSON-RPC and HTTP+JSON A2A server. + - context/session continuity, request/shared/connection instance scopes, and + served-agent `use_history` behavior. + - generated AgentCard interfaces, wildcard host rewriting, and A2A + `AgentSkill` advertisement/routing. + - streaming artifact updates, final artifact replacement, and cancellation. + - raw image/audio/file preservation and outbound raw/data/url/text mapping. + - task list/get/cancel behavior through SDK handlers. + +- Unit coverage: + - `tests/unit/fast_agent/test_a2a_remote_agent_events.py` + - `tests/unit/fast_agent/test_a2a_remote_agent_config.py` + - `tests/unit/fast_agent/a2a_connect_test.py` + - `tests/unit/fast_agent/cli/test_a2a_go_options.py` + - `tests/unit/fast_agent/cli/test_a2a_serve_options.py` + - `tests/unit/fast_agent/ui/test_parse_a2a_commands.py` + - `tests/unit/fast_agent/ui/test_a2a_command_dispatch.py` + - `tests/unit/fast_agent/core/test_a2a_error_formatting.py` + Run: ```bash @@ -210,6 +260,22 @@ need input blue ``` +Serve fast-agent as A2A: + +```bash +uv run fast-agent serve a2a \ + --host 127.0.0.1 \ + --port 41241 \ + --instance-scope connection \ + --agent-cards ./agents +``` + +Fetch the served card: + +```bash +curl -s http://127.0.0.1:41241/.well-known/agent-card.json | jq . +``` + ## Docs and recordings - `docs/docs/a2a/getting-started.md` @@ -217,20 +283,36 @@ blue - Includes short streaming, long streaming, file/data/raw, and `INPUT_REQUIRED` explanation. +- `docs/docs/a2a/client.md` + - Client CLI, AgentCard, TUI, streaming, `INPUT_REQUIRED`, content mapping, + error handling, and resumption guidance. + - Embeds deterministic client recordings and the provider-backed real LLM + recording. + +- `docs/docs/a2a/server.md` + - `fast-agent serve a2a`, served AgentCard interface URLs, runtime wiring, + A2A `AgentSkill` exposure, instance scopes, streaming, errors, file parts, + and structured JSON. + +- `docs/docs/a2a/api.md` + - Direct `A2ARemoteAgent` usage, `AgentA2AServer` embedding, raw JSON-RPC and + HTTP+JSON examples, content mapping, and explicit JSON data part examples. + +- `docs/docs/a2a/protocol-compliance.md` + - Current support matrix, known gaps, and verification coverage against A2A + Protocol Specification 1.0. + - `docs/docs/a2a/snippets/` - Generated snippets consumed by the docs page. - `docs/docs/assets/a2a/a2a-streaming-files.cast` - Embedded asciinema recording for the A2A TUI flow. -- Requested follow-up recording: - - Add one docs asciinema cast that shows a real LLM-backed fast-agent A2A - server streaming to a fast-agent A2A client. - - Preferred scenario: serve an agent using `codexresponses.gpt-5.4-mini` - with access to the Hugging Face MCP server, then ask for a markdown - response about currently trending models. - - This should be labeled as a provider/network smoke recording, separate from - the deterministic fake-server recordings used for repeatable tests. +- `docs/docs/assets/a2a/a2a-real-llm-hf-streaming.cast` + - Provider/network smoke recording. + - Shows `fast-agent serve a2a` backed by `codexresponses.gpt-5.4-mini`, + connected to the Hugging Face MCP server, and an interactive fast-agent A2A + client asking for a markdown answer about trending Hugging Face models. - `/home/ssmith/plan/records/a2a-streaming-files-input-required.cast` - Local copy of the latest generated recording. @@ -239,6 +321,9 @@ blue - `generate`: refresh snippets and CLI outputs. - `check`: verify snippets/assets are in sync. - `record`: regenerate the asciinema recording using tmux. + - `record-real-llm`: regenerate the provider-backed Hugging Face MCP/LLM + streaming recording; requires `HF_TOKEN`, `OPENAI_API_KEY`, network access, + `asciinema`, `tmux`, and `curl`. - Note: the script uses fixed port `41242`; if a stale fake server is already bound there it now fails early. @@ -248,6 +333,7 @@ Commands: uv run scripts/a2a_docs_pipeline.py generate uv run scripts/a2a_docs_pipeline.py check uv run scripts/a2a_docs_pipeline.py record +uv run scripts/a2a_docs_pipeline.py record-real-llm ``` ## A2A SDK reference checkout @@ -310,6 +396,15 @@ Current fast-agent mapping: - `TASK_STATE_INPUT_REQUIRED` preserves `current_task_id`; - the next user turn is sent with that pending `task_id`; - `/a2a reset` creates a fresh remote context and clears task state. +- when local A2A card/request `use_history=False`, the client generates a fresh + remote context for completed turns, but preserves context/task state while + continuing `INPUT_REQUIRED`. +- on the server, `--instance-scope connection` maps resolved A2A `context_id` + to a fast-agent instance; `shared` ignores per-context instance isolation and + `request` creates a fresh instance per message. +- structured JSON is protocol-level data only when represented as A2A `data` + parts or fast-agent `TextResourceContents(mimeType="application/json")`. + Ordinary model text remains a text artifact. ## Known gaps / next good targets @@ -319,18 +414,22 @@ Current fast-agent mapping: - toolbar currently special-cases A2A and does not render a TVD segment. - Inbound file persistence: - - inbound raw bytes are currently rendered as `[filename: N bytes media/type]`; - - they are not saved to `/a2a/` yet. - -- Streaming fidelity: - - artifact updates emit `StreamChunk`s; - - status/task events update state and log progress; - - `TaskArtifactUpdateEvent.append`/`last_chunk` is not yet used for nuanced - artifact assembly beyond whole-text de-dupe. + - server-side inbound raw bytes are preserved as `BlobResourceContents` for + the fast-agent agent; + - client-side inbound remote raw bytes are still rendered as readable text + placeholders and are not saved to `/a2a/` yet. - gRPC integration coverage: - - accepted by config/SDK; - - no fast-agent-owned deterministic gRPC test yet. + - intentionally out of scope for the current A2A HTTP support target. + +- Persistent task/session storage: + - the server currently uses the SDK `InMemoryTaskStore` plus in-memory + fast-agent instances; process restart loses A2A task/context state. + +- A2A security schemes: + - client connections support headers; + - served A2A AgentCards do not yet advertise configurable security schemes or + enforce A2A transport-level client authentication. ## Required validation after A2A changes @@ -338,6 +437,14 @@ At minimum: ```bash uv run pytest tests/integration/a2a -q +uv run pytest tests/unit/fast_agent/test_a2a_remote_agent_events.py \ + tests/unit/fast_agent/test_a2a_remote_agent_config.py \ + tests/unit/fast_agent/a2a_connect_test.py \ + tests/unit/fast_agent/cli/test_a2a_go_options.py \ + tests/unit/fast_agent/cli/test_a2a_serve_options.py \ + tests/unit/fast_agent/ui/test_parse_a2a_commands.py \ + tests/unit/fast_agent/ui/test_a2a_command_dispatch.py \ + tests/unit/fast_agent/core/test_a2a_error_formatting.py -q uv run scripts/a2a_docs_pipeline.py check uv run scripts/lint.py uv run scripts/typecheck.py diff --git a/tests/unit/fast_agent/cli/test_a2a_serve_options.py b/tests/unit/fast_agent/cli/test_a2a_serve_options.py new file mode 100644 index 000000000..97600109f --- /dev/null +++ b/tests/unit/fast_agent/cli/test_a2a_serve_options.py @@ -0,0 +1,85 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from typer.testing import CliRunner + +from fast_agent.cli.commands import serve as serve_command + +if TYPE_CHECKING: + from fast_agent.cli.runtime.run_request import AgentRunRequest + + +def test_serve_a2a_command_builds_a2a_run_request(monkeypatch) -> None: + captured: list[AgentRunRequest] = [] + + def fake_run_request(request: AgentRunRequest) -> None: + captured.append(request) + + monkeypatch.setattr(serve_command, "run_request", fake_run_request) + + result = CliRunner().invoke( + serve_command.app, + [ + "a2a", + "--name", + "research-a2a", + "--host", + "127.0.0.1", + "--port", + "41241", + "--instance-scope", + "connection", + "--agent-cards", + "./agents", + "--model", + "passthrough", + "--noenv", + ], + ) + + assert result.exit_code == 0 + assert len(captured) == 1 + request = captured[0] + assert request.name == "research-a2a" + assert request.mode == "serve" + assert request.transport == "a2a" + assert request.host == "127.0.0.1" + assert request.port == 41241 + assert request.instance_scope == "connection" + assert request.agent_cards == ["./agents"] + assert request.model == "passthrough" + assert request.noenv is True + + +def test_serve_transport_a2a_callback_path_builds_a2a_run_request(monkeypatch) -> None: + captured: list[AgentRunRequest] = [] + + def fake_run_request(request: AgentRunRequest) -> None: + captured.append(request) + + monkeypatch.setattr(serve_command, "run_request", fake_run_request) + + result = CliRunner().invoke( + serve_command.app, + [ + "--transport", + "a2a", + "--name", + "generic-a2a", + "--host", + "127.0.0.1", + "--port", + "41242", + "--instance-scope", + "request", + "--noenv", + ], + ) + + assert result.exit_code == 0 + assert len(captured) == 1 + request = captured[0] + assert request.name == "generic-a2a" + assert request.transport == "a2a" + assert request.instance_scope == "request" From 841bcd775b742969d57054ec924c2214286e3c3d Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 01:42:10 +0100 Subject: [PATCH 38/58] Document A2A goal addendum --- plan/05-21-a2a-goal-addendum.md | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 plan/05-21-a2a-goal-addendum.md diff --git a/plan/05-21-a2a-goal-addendum.md b/plan/05-21-a2a-goal-addendum.md new file mode 100644 index 000000000..ab3f2a765 --- /dev/null +++ b/plan/05-21-a2a-goal-addendum.md @@ -0,0 +1,51 @@ +# A2A Goal Addendum + +This addendum extends the active A2A completion goal with the latest review +requirements that are not represented in the immutable goal tracker text. + +## Documentation recordings + +- Include at least one asciinema recording that shows a real fast-agent A2A + client streaming from a real fast-agent A2A server backed by an LLM. +- The preferred provider smoke path is: + - server model: `codexresponses.gpt-5.4-mini`; + - server tools: Hugging Face MCP server; + - client prompt: ask for a Markdown-formatted answer about trending Hugging + Face models; + - expected user-visible behavior: the client receives streaming updates before + the final task completion. +- Keep this recording separate from deterministic fake-server recordings. The + deterministic recordings and tests remain the required regression signal; the + real-LLM recording is a provider/network smoke demonstration. + +Current implementation notes: + +- `docs/docs/assets/a2a/a2a-real-llm-hf-streaming.cast` is the expected checked-in + cast file. +- `uv run scripts/a2a_docs_pipeline.py record-real-llm` is the expected + regeneration command. +- The checked-in cast must not contain provider tokens, bearer headers, or other + secrets. + +## Structured JSON output + +A2A protocol support for structured JSON is through `Part.data`, not through an +LLM-output-schema negotiation feature. The fast-agent integration should treat +structured JSON as protocol data only when it is represented as structured +content, and should keep ordinary model text as text. + +Expected fast-agent mapping: + +- inbound A2A `Part.data` maps into fast-agent prompt content as formatted JSON + text unless a richer internal structured-content representation is added later; +- outbound fast-agent `TextResourceContents` with + `mimeType="application/json"` maps to A2A `Part.data`; +- ordinary model text that happens to contain JSON remains a text artifact; +- docs must make this distinction explicit so users do not assume A2A provides + model-level JSON schema enforcement. + +Open follow-up: + +- If fast-agent adds a first-class structured-output content object later, the + A2A bridge should map that object directly to `Part.data` instead of requiring + JSON `TextResourceContents`. From e2f4605b309166174f555207a6a1723d7354f34f Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 01:44:33 +0100 Subject: [PATCH 39/58] Audit A2A completion evidence --- plan/05-21-a2a-completion-audit.md | 78 ++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 plan/05-21-a2a-completion-audit.md diff --git a/plan/05-21-a2a-completion-audit.md b/plan/05-21-a2a-completion-audit.md new file mode 100644 index 000000000..3f0e22e06 --- /dev/null +++ b/plan/05-21-a2a-completion-audit.md @@ -0,0 +1,78 @@ +# A2A Completion Audit + +Current audit status: not yet marked complete. The implementation has broad +coverage, but the goal should remain active until the verification set below has +been rerun after the final A2A changes and any remaining intentional gaps have +been accepted. + +## Requirement Evidence + +| Requirement | Current evidence | Status | +|---|---|---| +| HTTP A2A client support, no gRPC | `src/fast_agent/a2a/remote_agent.py` restricts default bindings to `JSONRPC` and `HTTP+JSON`; `src/fast_agent/a2a/connect.py` rejects gRPC aliases; `tests/integration/a2a/test_remote_agent_runtime.py` covers both HTTP bindings. | Implemented and tested. | +| HTTP/JSON-RPC A2A server support | `src/fast_agent/a2a/server.py` exposes SDK JSON-RPC and REST routes; `tests/integration/a2a/test_fast_agent_a2a_server.py` covers JSON-RPC and HTTP+JSON clients against fast-agent-as-server. | Implemented and tested. | +| Deployable like ACP/MCP | `fast-agent serve a2a` and `fast-agent serve --transport a2a` are covered by `tests/unit/fast_agent/cli/test_a2a_serve_options.py`; server docs show `fast-agent serve a2a`. | Implemented and tested at CLI request-construction level. | +| PromptMessageExtended API behaves like normal agents | Client and server bridges convert A2A parts to/from `PromptMessageExtended`; integration tests cover text, stream listeners, raw/blob/image/audio/data content, and history behavior. | Implemented and tested. | +| `INPUT_REQUIRED` turn management | Client preserves task/context only for `TASK_STATE_INPUT_REQUIRED`; server maps `LlmStopReason.PAUSE` to `TASK_STATE_INPUT_REQUIRED`; integration tests cover follow-up completion in both fake-server and fast-agent-server paths. | Implemented and tested. | +| Session/context correlation | A2A `contextId` is optional inbound; SDK resolves it. Server `connection` scope maps resolved context id to an instance; `shared` and `request` scopes are explicit alternatives. Tests cover context reuse, no-history fresh contexts, and all instance scopes. | Implemented and tested in-memory. | +| AgentCard and A2A AgentSkill docs | `docs/docs/a2a/server.md` explains AgentCard interfaces and one A2A `AgentSkill` per loaded fast-agent agent; integration tests assert skills, modes, descriptions, tags, and metadata routing. | Implemented, documented, and tested. | +| API documentation | `docs/docs/a2a/api.md` covers direct `A2ARemoteAgent`, embedded `AgentA2AServer`, raw JSON-RPC, raw HTTP+JSON, content mapping, and structured JSON data parts. | Documented. | +| Client/server docs pages and recordings | `docs/docs/a2a/client.md` and `server.md` embed deterministic recordings; client docs embed the real-LLM Hugging Face MCP streaming recording; `scripts/a2a_docs_pipeline.py check` verifies required assets/pages. | Documented and pipeline-checked. | +| Deterministic API/CLI/TUI tests | API/server integration tests cover runtime protocol behavior; CLI tests cover `--a2a`, `--a2a-transport`, and `serve a2a`; TUI unit tests cover `/a2a` parsing and command dispatch. | Covered, but full prompt-toolkit E2E remains a possible future hardening target. | +| Real LLM streaming demo with HF MCP | `docs/docs/assets/a2a/a2a-real-llm-hf-streaming.cast` is checked in; `scripts/a2a_docs_pipeline.py record-real-llm` regenerates it with `codexresponses.gpt-5.4-mini` and `https://hf.co/mcp`; client docs embed it. | Implemented as provider smoke artifact. | +| Structured JSON protocol answer | A2A structured JSON is represented as `Part.data`; fast-agent maps explicit JSON resources to data parts and leaves ordinary model text as text. Documented in API/server/compliance pages and addendum. | Implemented and documented. | +| Multimodal support | Tests cover raw image input and audio-as-blob preservation; docs list partial typed audio support as a known gap. | Partially implemented and documented. | +| Hooks/tools/skills bundle deployment | Server docs state A2A serving uses the normal fast-agent runtime, so AgentCards, MCP servers, tools, skills, hooks, model settings, and workflows load before serving. | Documented; mostly proven indirectly through shared serve/bootstrap path. | +| Review fixes: clone config | `A2ARemoteAgent._clone_constructor_kwargs()` preserves `a2a_config`; integration test covers detached clone contacting remote server. | Fixed and tested. | +| Review fixes: artifact append semantics | Client assembles per-artifact output and honors append/replacement; integration test covers replacement plus repeated appended chunks. | Fixed and tested. | +| Review fixes: default transport probing | Client defaults supported protocol bindings to `JSONRPC` and `HTTP+JSON` when no transport is requested. | Fixed and unit/integration covered. | +| Review fixes: routable AgentCard URLs | Served wildcard-host AgentCards are rewritten from the incoming request base URL; integration test covers wildcard bind. | Fixed and tested. | +| Review fixes: terminal task ids | Terminal full-task and status events clear task id except for `INPUT_REQUIRED`; unit tests cover full-task terminal behavior. | Fixed and tested. | +| Review fixes: raw file preservation | Inbound raw non-image file bytes become `BlobResourceContents`; outbound blobs become A2A raw parts. | Fixed and tested. | +| Review fixes: no-history A2A context reset | `use_history=False` gets a fresh context between completed turns but preserves context/task while continuing `INPUT_REQUIRED`. | Fixed and tested. | +| Review fixes: A2A instance scope | A2A serve path passes `instance_scope`; server implements `shared`, `connection`, and `request`; tests cover all scopes. | Fixed and tested. | + +## Known Gaps + +These are documented as current protocol-compliance gaps rather than hidden +unfinished work: + +- gRPC transport is intentionally unsupported. +- A2A push notifications are not implemented; streaming and polling are the + supported client update paths. +- Extended AgentCard, card signing, extension negotiation, transport-level + security scheme advertisement/enforcement, idempotent message replay handling, + and persistent task/session storage are not implemented. +- Audio is preserved as raw/blob content on the server rather than mapped to a + dedicated fast-agent audio content object. +- Ordinary model text that contains JSON is not guessed into protocol data. + +## Required Final Verification + +Before marking the goal complete, rerun: + +```bash +uv run pytest tests/integration/a2a \ + tests/unit/fast_agent/test_a2a_remote_agent_events.py \ + tests/unit/fast_agent/test_a2a_remote_agent_config.py \ + tests/unit/fast_agent/a2a_connect_test.py \ + tests/unit/fast_agent/cli/test_a2a_go_options.py \ + tests/unit/fast_agent/cli/test_a2a_serve_options.py \ + tests/unit/fast_agent/ui/test_parse_a2a_commands.py \ + tests/unit/fast_agent/ui/test_a2a_command_dispatch.py \ + tests/unit/fast_agent/core/test_a2a_error_formatting.py \ + tests/unit/test_a2a_docs_pipeline.py \ + -q +uv run scripts/a2a_docs_pipeline.py check +uv run scripts/lint.py +uv run scripts/typecheck.py +``` + +Also verify the checked-in real-LLM cast does not contain provider secrets: + +```bash +rg -q "hf_|sk-|OPENAI|ANTHROPIC|Authorization|Bearer|HF_TOKEN|OPENAI_API_KEY|ANTHROPIC_API_KEY" \ + docs/docs/assets/a2a/a2a-real-llm-hf-streaming.cast +``` + +The secret scan should exit with status 1 because it finds no matches. From 829a05488c41bec5bb5dd4542fca56807a73727b Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 01:45:31 +0100 Subject: [PATCH 40/58] Archive initial A2A client plan --- plan/05-20-a2a-client.md | 473 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 473 insertions(+) create mode 100644 plan/05-20-a2a-client.md diff --git a/plan/05-20-a2a-client.md b/plan/05-20-a2a-client.md new file mode 100644 index 000000000..2790f0f06 --- /dev/null +++ b/plan/05-20-a2a-client.md @@ -0,0 +1,473 @@ +# A2A client integration status + +Historical status: superseded. + +This file records the initial 2026-05-20 client-only planning pass. It is kept +as source material for the later A2A implementation, but it is no longer the +authoritative plan: + +- fast-agent now supports both A2A client and A2A server paths for HTTP + transports; +- gRPC is intentionally out of scope for the current fast-agent A2A support + target; +- current orientation, evidence, and remaining gaps live in: + - `plan/05-21-a2a-orientation.md`; + - `plan/05-21-a2a-goal-addendum.md`; + - `plan/05-21-a2a-completion-audit.md`; + - `docs/docs/a2a/protocol-compliance.md`. + +The sections below should be read as implementation history, not as current +acceptance criteria. + +Date: 2026-05-20 +Last updated: 2026-05-20 + +## Goal + +Allow fast-agent to treat remote A2A agents as first-class configured agents via the +existing AgentCard mechanism. + +Initial scope remains client-only. Server-side fast-agent-as-A2A is deferred. + +## Current status + +Implemented and smoke-tested: + +- `type: a2a` AgentCards load successfully. +- `AgentType.A2A` is registered and participates in direct factory creation. +- A2A cards parse the currently supported fields: + - `url`; + - `transport` (`JSONRPC`, `HTTP+JSON`, `GRPC` accepted by config validation); + - `streaming`; + - `polling`; + - `accepted_output_modes`; + - `headers`; + - `relative_card_path`. +- `A2ARemoteAgent` resolves the remote A2A AgentCard and creates an SDK client. +- JSON-RPC text request/response works against the SDK sample server. +- The A2A agent is created without attaching a local LLM. +- Fast-agent local history records A2A user/assistant turns; `/history` works. +- TUI now maps A2A turns into the existing display infrastructure: + - user messages render via `ConsoleDisplay.show_user_message(...)`; + - assistant messages render via `ConsoleDisplay.show_assistant_message(...)`; + - the active-agent toolbar shows `name[A2A]` in magenta; + - the toolbar model segment shows the remote card name instead of `$system.default`. +- CLI auto tool-card attachment now skips A2A agents, because A2A agents are not + valid agents-as-tools parents. +- Unit coverage exists for A2A card parsing, transport validation, and toolbar + A2A identity styling. + +Validated commands: + +```bash +uv run pytest tests/unit/fast_agent/core/test_agent_card_loader.py -q +uv run pytest tests/unit/fast_agent/ui/test_enhanced_prompt_toolbar.py tests/unit/fast_agent/ui/test_input_toolbar.py -q +uv run scripts/lint.py +uv run scripts/typecheck.py +``` + +## Reference A2A SDK sample server + +The local A2A SDK source is at: + +```text +../a2a-python/ +``` + +Run the sample server: + +```bash +cd ../a2a-python +uv run python samples/hello_world_agent.py +``` + +The sample exposes: + +- agent card: `http://127.0.0.1:41241/.well-known/agent-card.json` +- JSON-RPC: `http://127.0.0.1:41241/a2a/jsonrpc` +- HTTP+JSON: `http://127.0.0.1:41241/a2a/rest` +- gRPC v1.0: `127.0.0.1:50051` +- gRPC v0.3 compatibility: `127.0.0.1:50052` + +Minimal fast-agent card: + +```yaml +type: a2a +name: hello_remote +url: http://127.0.0.1:41241 +transport: JSONRPC +``` + +Smoke test without the TUI: + +```bash +uv run fast-agent -x --agent-cards /tmp/a2a-card.yaml --agent hello_remote --message hello --quiet +``` + +Expected output: + +```text +Hello World! Nice to meet you! +``` + +## Current runtime mapping + +For each `agent.send(...)` / `agent.generate(...)` call: + +1. fast-agent input is normalized by `LlmDecorator.generate(...)`. +2. `A2ARemoteAgent.generate_impl(...)` displays trailing user messages through + the same console display path used by local LLM agents. +3. The latest user text is mapped to an A2A `Message`: + + ```python + Message( + role=Role.ROLE_USER, + message_id=str(uuid.uuid4()), + context_id=current_context_id, + task_id=current_task_id, + parts=[Part(text=user_text)], + ) + ``` + +4. The SDK client sends `SendMessageRequest(message=message)`. +5. The returned async event iterator is consumed. +6. The agent records `context_id`, `current_task_id`, and `last_task_state` where + available. +7. Text is aggregated from direct A2A messages and artifact updates. +8. A normal `PromptMessageExtended(role="assistant", ...)` is returned and + displayed through `ConsoleDisplay.show_assistant_message(...)`. + +Terminal state behavior currently implemented: + +- completed: returns aggregated text, or a no-output message; +- failed/canceled/cancelled/rejected/input-required/auth-required: returns a + clear A2A task state message; +- terminal non-input-required tasks clear `current_task_id`; +- `input_required` preserves task state for future follow-up work. + +## TUI verification with tmux + +`tmux` has been useful for deterministic TUI reproduction and regression checks. +It lets us start fast-agent, send keystrokes, and capture the visible terminal +state without manually driving the UI. + +Example: + +```bash +# Ensure sample A2A server is running first. +cat >/tmp/a2a-card.yaml <<'YAML' +type: a2a +name: hello_remote +url: http://127.0.0.1:41241 +transport: JSONRPC +YAML + +cd /home/ssmith/source/fast-agent-pr + +tmux kill-session -t a2atest 2>/dev/null || true +tmux new-session -d -s a2atest \ + 'cd /home/ssmith/source/fast-agent-pr && FAST_AGENT_MODEL=passthrough uv run fast-agent -x --agent-cards /tmp/a2a-card.yaml --agent hello_remote' + +sleep 4 +tmux send-keys -t a2atest 'whhhhhhaaaattt' Enter +sleep 4 +tmux send-keys -t a2atest 'hello' Enter +sleep 4 +tmux capture-pane -t a2atest -p -S -3000 | tail -80 +``` + +Expected visible shape: + +```text +▎▶ hello_remote ──────────────────────────────────────────────────────────────── +whhhhhhaaaattt + +▎◀ hello_remote A2A +Hello World! You said: 'whhhhhhaaaattt'. Thanks for your message! + +▎▶ hello_remote ──────────────────────────────────────────────────────────────── +hello + +▎◀ hello_remote A2A +Hello World! Nice to meet you! + +❯ + + hello_remote[A2A] ▲ Sample Agent | 002 | NRML | fast-agent 0.7.8 +``` + +Useful tmux commands for future automated checks/docs captures: + +```bash +# Capture current pane text. +tmux capture-pane -t a2atest -p -S -3000 > /tmp/a2a-tui.txt + +# Append all pane output to a log while the session runs. +tmux pipe-pane -t a2atest -o 'cat >> /tmp/a2a-tui.log' + +# Send slash commands or normal input. +tmux send-keys -t a2atest '/history' Enter +tmux send-keys -t a2atest 'hello' Enter + +# Stop the session. +tmux kill-session -t a2atest +``` + +## Asciinema capture plan + +We should try asciinema for documentation-quality terminal recordings while the +feature evolves. tmux is good for testable text snapshots; asciinema is better for +replayable demos that can be embedded or converted for the docs site. + +Initial local experiment: + +```bash +# Install if needed. Options depend on the environment. +uv tool install asciinema +# or: pipx install asciinema +# or: sudo apt install asciinema + +# Start the A2A sample server in another terminal/tmux pane first. +cd /home/ssmith/source/fast-agent-pr +asciinema rec /tmp/fast-agent-a2a.cast \ + -c 'FAST_AGENT_MODEL=passthrough uv run fast-agent -x --agent-cards /tmp/a2a-card.yaml --agent hello_remote' +``` + +During recording, type a short scripted flow: + +```text +hello +whhhhhhaaaattt +/history +/exit +``` + +Replay locally: + +```bash +asciinema play /tmp/fast-agent-a2a.cast +``` + +Potential docs pipeline options to evaluate: + +- keep `.cast` files as source artifacts; +- embed asciinema player in docs pages; +- convert selected recordings to GIF/SVG/video if static assets are preferred; +- pair each asciinema capture with a tmux `capture-pane` text fixture for + regression-oriented assertions. + +## Session and conversation state + +A2A does have remote conversational continuity, but it is represented by +`context_id`, not by replaying fast-agent history. + +Current behavior: + +- fast-agent keeps normal local `message_history` for display, `/history`, and + saved transcript behavior; +- the remote A2A agent receives only the latest user text for each request; +- remote continuity is carried through `context_id`; +- `task_id` tracks current/outstanding A2A work and is cleared on terminal states + except input-required style flows. + +Recommendation: + +- treat local fast-agent history as the transcript/UI history; +- treat A2A `context_id` as remote conversation/thread state; +- do not resend the full fast-agent transcript by default; +- persist A2A state alongside sessions in a future step: + - `context_id`; + - `current_task_id`; + - `last_task_state`; + - selected transport; + - remote card identity/version. + +Open question for resume: + +- On fast-agent session resume, should we always reuse the saved A2A `context_id`, + or should there be a freshness/remote-card-version check that starts a new + context when the old one may no longer be meaningful? + +## Remaining work + +### Short-term + +1. Add SDK-backed tests for factory/runtime connectivity. + - Prefer the A2A SDK server primitives over monkeypatching. + - Cover JSON-RPC send and text aggregation. +2. Add a tmux-driven smoke test script or documented manual check. + - Keep it optional initially if CI terminal behavior is unreliable. +3. Try asciinema capture and decide where `.cast` files should live. +4. Add `/a2a` diagnostics commands. + +### `/a2a` command surface + +MVP commands still worth adding: + +```text +/a2a list +/a2a card [agent] +/a2a status [agent] +/a2a reset [agent] +/a2a transport [agent] +``` + +Later task lifecycle commands: + +```text +/a2a tasks [agent] +/a2a get [agent] +/a2a cancel [agent] +/a2a subscribe [agent] +/a2a resume [agent] +``` + +### Transport coverage + +Current practical validation is JSON-RPC. Configuration validation accepts +`HTTP+JSON` and `GRPC`, but these need explicit integration coverage. + +Next transport tests: + +- HTTP+JSON against the SDK sample server; +- gRPC only when optional dependencies are available and the environment is + suitable. + +### Content mapping beyond text + +Current MVP is text-only: + +- fast-agent user text -> A2A text part; +- A2A text messages/artifacts -> fast-agent assistant text. + +Later mapping: + +- `data` parts -> JSON/fenced JSON or structured side channel; +- `url` parts -> markdown links/resource references; +- `raw` parts -> media/document attachments where fast-agent can display or + persist them; +- preserve `media_type` where possible. + +### Streaming behavior + +The current UI path prioritizes stable user/assistant turn rendering. It consumes +A2A events synchronously and displays the final aggregated assistant message. + +Future streaming refinement: + +- route artifact/direct-message text updates into the existing streaming handle; +- avoid duplicate blank headers; +- preserve post-stream re-render behavior exactly like local LLM agents; +- dedupe servers that send full artifact snapshots rather than deltas. + +### Server-side fast-agent-as-A2A + +Deferred until the client mapping settles. + +The SDK server layer should make this straightforward later: + +- implement an `AgentExecutor` that wraps an `AgentProtocol` or `AgentApp`; +- map A2A user messages to fast-agent `send()`/`generate()`; +- stream fast-agent `StreamChunk`s as A2A artifact updates; +- expose fast-agent `agent_card()` as the A2A AgentCard. + +## 2026-05-20 asciinema/progress spike update + +Asciinema capture is now validated as part of the local development/testing +workflow for TUI-facing A2A work. + +Artifacts produced during the spike: + +```text +/tmp/fast-agent-a2a-clean.cast +/tmp/fast-agent-a2a-natural.cast +/tmp/fast-agent-a2a-progress.cast +``` + +The most useful current demo is: + +```text +/tmp/fast-agent-a2a-progress.cast +``` + +Replay it with: + +```bash +asciinema play /tmp/fast-agent-a2a-progress.cast +``` + +Fast inspection: + +```bash +asciinema play /tmp/fast-agent-a2a-progress.cast --speed 100 +``` + +Recording script: + +```text +/tmp/a2a-asciinema-progress.sh +``` + +The progress demo uses the same tmux-driven approach: + +- create a fixed-size tmux session; +- disable the tmux status bar; +- start fast-agent with the A2A card; +- type input character-by-character for a more natural feel; +- leave enough delay after Enter for the SDK sample server's wait state to show; +- record the whole interaction with asciinema. + +Recording command: + +```bash +asciinema rec \ + --overwrite \ + --cols 104 \ + --rows 34 \ + --idle-time-limit 1.3 \ + -t 'fast-agent A2A progress display demo' \ + -c /tmp/a2a-asciinema-progress.sh \ + /tmp/fast-agent-a2a-progress.cast +``` + +The `.cast` file is newline-delimited JSON: + +- first line: metadata (`version`, `width`, `height`, `timestamp`, `env`, `title`, + optional `idle_time_limit`); +- remaining lines: events shaped like `[time_offset_seconds, "o", "terminal output"]`. + +This makes simple edits scriptable: + +- retitle recordings by rewriting the first JSON line; +- trim beginning/end events; +- redact paths or usernames; +- compress pauses by rewriting timestamps. + +For docs embedding, use `asciinema-player` and serve `.cast` files as static +assets. Keep the tmux scripts as reproducible sources and the `.cast` files as +recorded documentation artifacts. + +A2A progress display was also wired into the normal progress board. While waiting +for the remote A2A response the TUI now shows the standard sending row, e.g.: + +```text +▎▶ hello_remote ──────────────────────────────────────────────────────────────── +hello +▎▶ Sending ⠄ hello_remote +``` + +Then the progress display is paused before rendering the final assistant message, +so the progress row does not overwrite the completed A2A response: + +```text +▎◀ hello_remote A2A +Hello World! Nice to meet you! +``` + +Recommendation for ongoing A2A UI work: + +- run a tmux text capture as a quick regression check; +- record or update an asciinema cast when the visible behavior changes; +- keep casts short and focused (one feature per cast); +- use `--idle-time-limit` so docs recordings remain compact; +- prefer deterministic tmux scripts over manual recordings for repeatability. From 1cfaf80e890fe94e2e4201d26e4931a38cb42c52 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 01:47:08 +0100 Subject: [PATCH 41/58] Mark A2A completion audit verified --- plan/05-21-a2a-completion-audit.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plan/05-21-a2a-completion-audit.md b/plan/05-21-a2a-completion-audit.md index 3f0e22e06..0925ecd3f 100644 --- a/plan/05-21-a2a-completion-audit.md +++ b/plan/05-21-a2a-completion-audit.md @@ -1,9 +1,9 @@ # A2A Completion Audit -Current audit status: not yet marked complete. The implementation has broad -coverage, but the goal should remain active until the verification set below has -been rerun after the final A2A changes and any remaining intentional gaps have -been accepted. +Current audit status: complete as of the final verification pass. The +implementation satisfies the requested HTTP A2A client/server scope; the known +gaps below are intentionally documented protocol/operational limitations rather +than hidden unfinished work for this goal. ## Requirement Evidence @@ -47,9 +47,9 @@ unfinished work: dedicated fast-agent audio content object. - Ordinary model text that contains JSON is not guessed into protocol data. -## Required Final Verification +## Final Verification -Before marking the goal complete, rerun: +Final verification was rerun successfully with: ```bash uv run pytest tests/integration/a2a \ From e489c83fdac5a3d9acf3d87cd3bfba91836d9fdf Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 08:59:05 +0100 Subject: [PATCH 42/58] Plan A2A OAuth HF hosting --- docs/docs/a2a/host-on-hf.md | 198 +++++++++++++++++++++++++++++ docs/zensical.toml | 1 + plan/05-21-a2a-oauth-hf-hosting.md | 116 +++++++++++++++++ 3 files changed, 315 insertions(+) create mode 100644 docs/docs/a2a/host-on-hf.md create mode 100644 plan/05-21-a2a-oauth-hf-hosting.md diff --git a/docs/docs/a2a/host-on-hf.md b/docs/docs/a2a/host-on-hf.md new file mode 100644 index 000000000..f2c6d0550 --- /dev/null +++ b/docs/docs/a2a/host-on-hf.md @@ -0,0 +1,198 @@ +--- +title: Host A2A on Hugging Face +description: Deploy a fast-agent A2A server on Hugging Face Spaces with OAuth credential pass-through. +--- + +# Host A2A on Hugging Face + +This page describes the target deployment shape for hosting fast-agent as an A2A +server on Hugging Face Spaces. + +The important behavior is credential pass-through: the caller authenticates to +the hosted A2A server with a Hugging Face OAuth/bearer credential, and +fast-agent makes that credential available to the running agent. That lets the +agent use Hugging Face Inference Provider models, the Hugging Face MCP server, +and Hugging Face tools as the caller rather than as a shared server account. + +## Current Status + +A2A server auth for Hugging Face hosting is planned work. The current A2A server +supports unauthenticated HTTP `JSONRPC` and `HTTP+JSON` serving. MCP serving +already has the Hugging Face OAuth/pass-through pattern that A2A will mirror. + +Use this page as the setup target for the OAuth-enabled A2A server work. + +## Space Layout + +A minimal Space should contain: + +```text +. +├── app.py +├── fast-agent.yaml +├── agents/ +│ └── researcher.yaml +└── requirements.txt +``` + +`requirements.txt`: + +```text +fast-agent-mcp +``` + +`app.py`: + +```python +import os + +from fast_agent.cli.main import app + + +if __name__ == "__main__": + os.environ.setdefault("FAST_AGENT_SERVE_OAUTH", "huggingface") + os.environ.setdefault("FAST_AGENT_OAUTH_SCOPES", "access") + app() +``` + +Start the Space with: + +```bash +fast-agent serve a2a \ + --host 0.0.0.0 \ + --port 7860 \ + --agent-cards ./agents \ + --model hf.moonshotai/Kimi-K2-Thinking +``` + +Use the model/provider alias that matches your application. The key point is +that Hugging Face provider credentials should come from the request token, not +from a shared `HF_TOKEN`, when OAuth pass-through is enabled. + +## Space Environment + +Set these environment variables in the Space: + +```text +FAST_AGENT_SERVE_OAUTH=huggingface +FAST_AGENT_OAUTH_RESOURCE_URL=https://.hf.space +FAST_AGENT_OAUTH_SCOPES=access +``` + +Do not set a shared `HF_TOKEN` unless the Space intentionally needs a server +credential fallback. For user-scoped inference, the inbound bearer credential is +the credential source. + +## Request Flow + +Expected OAuth-enabled A2A flow: + +1. The client fetches `/.well-known/agent-card.json`. +2. The AgentCard advertises bearer/OAuth security requirements. +3. The client sends A2A requests to `/a2a/jsonrpc` or `/a2a/rest` with either: + - `Authorization: Bearer `; + - `X-HF-Authorization: Bearer ` when running through Hugging Face + Space infrastructure. +4. The A2A server normalizes the Hugging Face header and validates that a bearer + credential is present. +5. fast-agent stores the token in request context while the agent runs. +6. Hugging Face Inference Provider model calls and Hugging Face MCP/tool calls + can use the request token. + +## AgentCard Security + +An OAuth-enabled card should advertise security metadata so A2A clients know +that credentials are required. + +The first implementation target is bearer security: + +```json +{ + "securitySchemes": { + "hf_bearer": { + "httpAuthSecurityScheme": { + "scheme": "bearer", + "bearerFormat": "HF_TOKEN", + "description": "Hugging Face bearer token" + } + } + }, + "security": [ + { + "hf_bearer": [] + } + ] +} +``` + +Later implementations can advertise OAuth2 or OpenID Connect metadata when the +client can complete the browser OAuth flow directly from the AgentCard. + +## Client Configuration + +For a checked-in fast-agent A2A client card, explicit bearer headers remain the +most direct option: + +```yaml +type: a2a +name: hf_space_agent +url: https://.hf.space +transport: JSONRPC +headers: + Authorization: "Bearer ${HF_TOKEN}" +``` + +For Hugging Face Space routing, clients may also need: + +```yaml +headers: + Authorization: "Bearer ${HF_TOKEN}" + X-HF-Authorization: "Bearer ${HF_TOKEN}" +``` + +The planned fast-agent A2A client behavior is to reuse the existing Hugging Face +token discovery used by MCP URL connections, so explicit headers are not needed +when the target is `hf.co`, `huggingface.co`, or `*.hf.space` and no auth header +has already been configured. + +## Inference Provider Use + +With request token pass-through, hosted A2A agents can use Hugging Face models +without putting a shared user token in the Space: + +```yaml +name: researcher +type: basic +model: hf.moonshotai/Kimi-K2-Thinking +instruction: | + Answer with concise Markdown. + Use Hugging Face tools when current Hub context is needed. +mcp_servers: + - name: huggingface + target: "https://huggingface.co/mcp" +``` + +When the A2A request arrives with a user bearer token, both provider calls and +the Hugging Face MCP server should be able to use that token through the normal +fast-agent request auth context. + +## Operational Notes + +- Keep the AgentCard public so clients can discover endpoint and auth metadata. +- Require bearer credentials only on A2A action routes. +- Prefer `--instance-scope connection` for multi-turn authenticated sessions + where A2A `contextId` should correlate with a fast-agent instance. +- Prefer `--instance-scope request` for stateless public endpoints. +- Use `--host 0.0.0.0` inside the Space; the served AgentCard should advertise + the external Space hostname when fetched by clients. + +## Verification Targets + +The OAuth-enabled A2A implementation should include tests that prove: + +- unauthenticated A2A requests are rejected; +- authenticated A2A requests reach the agent; +- `Authorization` and `X-HF-Authorization` both propagate to request context; +- the AgentCard advertises security schemes and requirements; +- client-side Hugging Face token auto-headers are added for HF URLs; +- explicit user-supplied auth headers are preserved. diff --git a/docs/zensical.toml b/docs/zensical.toml index 39de07bb0..2c72c61d7 100644 --- a/docs/zensical.toml +++ b/docs/zensical.toml @@ -41,6 +41,7 @@ nav = [ { "Getting Started" = "a2a/getting-started.md" }, { "Use as Client" = "a2a/client.md" }, { "Serve as A2A Server" = "a2a/server.md" }, + { "Host on HF" = "a2a/host-on-hf.md" }, { "API Usage" = "a2a/api.md" }, { "Protocol Compliance" = "a2a/protocol-compliance.md" }, ] }, diff --git a/plan/05-21-a2a-oauth-hf-hosting.md b/plan/05-21-a2a-oauth-hf-hosting.md new file mode 100644 index 000000000..c69af0978 --- /dev/null +++ b/plan/05-21-a2a-oauth-hf-hosting.md @@ -0,0 +1,116 @@ +# A2A OAuth and Hugging Face Hosting Goal + +Status: planned. + +## Goal + +Add OAuth authentication for fast-agent A2A servers and clients, with Hugging +Face Spaces as a first-class hosted deployment target. + +The key requirement is credential pass-through: when an A2A server is hosted on +Hugging Face, the caller's OAuth/bearer credential must be available inside the +fast-agent request context so Hugging Face Inference Provider models, the +Hugging Face MCP server, and Hugging Face tools can act using that caller +credential. + +## Outcomes + +- A2A servers can enforce bearer/OAuth authentication for `JSONRPC` and + `HTTP+JSON` endpoints. +- Hugging Face Spaces deployment supports `X-HF-Authorization` and standard + `Authorization` bearer headers, matching the existing MCP behavior. +- The request bearer token is written to `request_bearer_token` while the + fast-agent agent handles an A2A request. +- Served A2A AgentCards advertise security metadata through A2A + `security_schemes`, `security_requirements`, and, where appropriate, + per-skill security requirements. +- A2A clients can send static bearer/HF tokens and can later use the existing + fast-agent OAuth browser flow where the remote AgentCard advertises OAuth or + OIDC. +- Documentation includes an A2A "Host on HF" page with Space setup, + environment variables, OAuth behavior, AgentCard security metadata, and + inference-provider usage. + +## Existing Pieces to Reuse + +- `fast_agent.mcp.auth.middleware.HFAuthHeaderMiddleware` + - Normalizes `X-HF-Authorization` to `Authorization`. +- `fast_agent.mcp.auth.context.request_bearer_token` + - Request-scoped token context already consumed by provider key resolution. +- `fast_agent.mcp.auth.presence.PresenceTokenVerifier` + - Useful model for the initial server-side "present bearer token" check. +- `fast_agent.mcp.hf_auth.add_hf_auth_header` + - Adds Hugging Face token headers for `hf.co`, `huggingface.co`, and + `*.hf.space`. +- `fast_agent.mcp.oauth_client` + - Existing OAuth login, callback, keyring, and client metadata machinery. +- A2A SDK `AuthInterceptor`, `CredentialService`, `ClientCallContext`, and + AgentCard security scheme types. + +## Proposed Server Design + +1. Add A2A serve auth settings: + - initially reuse `FAST_AGENT_SERVE_OAUTH=huggingface`; + - reuse `FAST_AGENT_OAUTH_SCOPES`; + - reuse `FAST_AGENT_OAUTH_RESOURCE_URL`; + - later expose CLI/config fields if needed. +2. Wrap `AgentA2AServer.asgi_app()` with auth middleware when auth is enabled: + - public AgentCard route remains reachable; + - `/a2a/jsonrpc` and `/a2a/rest` require bearer auth; + - missing/invalid auth returns `401` with `WWW-Authenticate`. +3. Normalize Hugging Face Space headers: + - accept `Authorization: Bearer ...`; + - accept `X-HF-Authorization: Bearer ...` and copy to `Authorization`. +4. Propagate credentials: + - extract the bearer token from request headers/scope; + - set `request_bearer_token` around the agent `generate(...)` call; + - reset the context variable after the request. +5. Advertise security in the AgentCard: + - use `HTTPAuthSecurityScheme(scheme="bearer")` for the first pass; + - add `OAuth2SecurityScheme` or `OpenIdConnectSecurityScheme` once we have + provider metadata details that A2A clients can use reliably. + +## Proposed Client Design + +1. Static token support: + - keep explicit `headers` on `A2AAgentConfig`; + - add `auth`/`oauth` fields only if the UX needs parity with MCP cards; + - automatically add HF token headers for Hugging Face URLs when no explicit + auth header is present. +2. AgentCard-driven credential injection: + - inspect `remote_card.security_schemes` and `security_requirements`; + - use A2A SDK `AuthInterceptor` with a fast-agent `CredentialService`; + - pass per-call `ClientCallContext` so the SDK transports receive + `Authorization` or API key headers. +3. OAuth browser flow: + - adapt `fast_agent.mcp.oauth_client` to an A2A-oriented server identity; + - store tokens in keyring using a distinct service or identity prefix; + - emit OAuth events through CLI/TUI surfaces similarly to `/mcp connect`. + +## Testing + +- Server auth: + - public AgentCard route is accessible; + - A2A routes reject missing bearer tokens; + - `Authorization` reaches `request_bearer_token`; + - `X-HF-Authorization` reaches `request_bearer_token` on HF mode. +- AgentCard metadata: + - auth-enabled A2A server advertises expected security schemes and + requirements. +- Client auth: + - explicit A2A headers are sent; + - HF token auto-header logic applies only to Hugging Face URLs; + - existing explicit auth headers win over auto HF auth. +- Inference pass-through: + - deterministic test agent reads `request_bearer_token`; + - provider-key-manager behavior can use the request token for Hugging Face. + +## Open Questions + +- Should A2A server auth configuration live only in shared serve environment + variables, or should `fast-agent serve a2a` expose first-class `--oauth` + flags? +- Should the first client OAuth pass be generic OAuth/OIDC, or should it focus + on Hugging Face Spaces first? +- Should authenticated extended AgentCards be implemented as part of this work, + or should public cards advertise enough security metadata for the first pass? From b0dec6783d743d70e5222d5b6435080b07fc30ea Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 09:23:43 +0100 Subject: [PATCH 43/58] Add A2A Hugging Face bearer auth --- docs/docs/a2a/client.md | 5 + docs/docs/a2a/host-on-hf.md | 34 ++-- docs/docs/a2a/protocol-compliance.md | 5 +- docs/docs/a2a/server.md | 21 +++ plan/05-21-a2a-oauth-hf-hosting.md | 41 +++-- src/fast_agent/a2a/remote_agent.py | 4 +- src/fast_agent/a2a/server.py | 140 ++++++++++++++++- .../a2a/test_fast_agent_a2a_server.py | 121 ++++++++++++++ .../test_a2a_remote_agent_config.py | 148 ++++++++++++++++++ 9 files changed, 490 insertions(+), 29 deletions(-) diff --git a/docs/docs/a2a/client.md b/docs/docs/a2a/client.md index ba11d6f1e..5d8b7c24b 100644 --- a/docs/docs/a2a/client.md +++ b/docs/docs/a2a/client.md @@ -109,6 +109,11 @@ headers: relative_card_path: "/.well-known/agent-card.json" ``` +For Hugging Face URLs (`hf.co`, `huggingface.co`, and `*.hf.space`), +fast-agent automatically applies the local Hugging Face token as A2A request +headers when no explicit auth header is configured. For Spaces this includes +both `Authorization` and `X-HF-Authorization`. + ## TUI Inside the interactive prompt, connect a remote A2A agent at runtime: diff --git a/docs/docs/a2a/host-on-hf.md b/docs/docs/a2a/host-on-hf.md index f2c6d0550..0eb7e8f51 100644 --- a/docs/docs/a2a/host-on-hf.md +++ b/docs/docs/a2a/host-on-hf.md @@ -16,11 +16,14 @@ and Hugging Face tools as the caller rather than as a shared server account. ## Current Status -A2A server auth for Hugging Face hosting is planned work. The current A2A server -supports unauthenticated HTTP `JSONRPC` and `HTTP+JSON` serving. MCP serving -already has the Hugging Face OAuth/pass-through pattern that A2A will mirror. +fast-agent A2A serving supports Hugging Face bearer authentication for HTTP +`JSONRPC` and `HTTP+JSON` routes when `FAST_AGENT_SERVE_OAUTH=huggingface` is +set. The public AgentCard stays discoverable, and action routes require a bearer +token. -Use this page as the setup target for the OAuth-enabled A2A server work. +The implemented first pass supports static bearer credentials and Hugging Face +Space header normalization. Browser-based OAuth login for A2A clients is a later +phase. ## Space Layout @@ -85,7 +88,7 @@ the credential source. ## Request Flow -Expected OAuth-enabled A2A flow: +OAuth-enabled A2A flow: 1. The client fetches `/.well-known/agent-card.json`. 2. The AgentCard advertises bearer/OAuth security requirements. @@ -104,7 +107,7 @@ Expected OAuth-enabled A2A flow: An OAuth-enabled card should advertise security metadata so A2A clients know that credentials are required. -The first implementation target is bearer security: +The current implementation advertises bearer security: ```json { @@ -117,16 +120,19 @@ The first implementation target is bearer security: } } }, - "security": [ + "securityRequirements": [ { - "hf_bearer": [] + "schemes": { + "hf_bearer": {} + } } ] } ``` -Later implementations can advertise OAuth2 or OpenID Connect metadata when the -client can complete the browser OAuth flow directly from the AgentCard. +Skills include the same `securityRequirements` entry. Later implementations can +advertise OAuth2 or OpenID Connect metadata when the client can complete the +browser OAuth flow directly from the AgentCard. ## Client Configuration @@ -150,10 +156,10 @@ headers: X-HF-Authorization: "Bearer ${HF_TOKEN}" ``` -The planned fast-agent A2A client behavior is to reuse the existing Hugging Face -token discovery used by MCP URL connections, so explicit headers are not needed -when the target is `hf.co`, `huggingface.co`, or `*.hf.space` and no auth header -has already been configured. +fast-agent A2A clients reuse the existing Hugging Face token discovery used by +MCP URL connections, so explicit headers are not needed when the target is +`hf.co`, `huggingface.co`, or `*.hf.space` and no auth header has already been +configured. ## Inference Provider Use diff --git a/docs/docs/a2a/protocol-compliance.md b/docs/docs/a2a/protocol-compliance.md index 7f9d084b7..776663ba5 100644 --- a/docs/docs/a2a/protocol-compliance.md +++ b/docs/docs/a2a/protocol-compliance.md @@ -30,7 +30,7 @@ client stack and intentionally excludes gRPC. | gRPC transport | Not supported by design for this work. | The AgentCard does not advertise gRPC, and the CLI/API should use `JSONRPC` or `HTTP+JSON`. | | Push notifications | Not implemented. | The AgentCard advertises `pushNotifications=false`; SDK push configuration methods return the protocol's not-supported error. Streaming and polling remain available. | | Extended AgentCard | Not implemented. | The server publishes the public AgentCard only and does not configure `extendedAgentCard`. | -| Authentication/security schemes on served AgentCards | Partial. | Remote clients can pass headers when connecting to other A2A agents. Serving fast-agent over A2A does not yet expose configurable A2A security schemes or enforce transport-level client auth. In-task provider auth failures are reported as `AUTH_REQUIRED`. | +| Authentication/security schemes on served AgentCards | Supported for Hugging Face bearer auth | Remote clients can pass headers when connecting to other A2A agents. When `FAST_AGENT_SERVE_OAUTH=huggingface` is set, serving fast-agent over A2A advertises an `hf_bearer` HTTP bearer security scheme, requires bearer auth on A2A action routes, accepts `Authorization` and `X-HF-Authorization`, and passes the bearer token into fast-agent request context. Browser OAuth for A2A clients remains a future extension. In-task provider auth failures are reported as `AUTH_REQUIRED`. | | Typed audio content on the server | Partial. | The client can send `AudioContent` as raw A2A parts. The server preserves inbound audio bytes as blob resources rather than mapping them to a dedicated fast-agent `AudioContent` object. | | Structured JSON output from model text | Partial. | fast-agent JSON text responses remain text artifacts unless represented as `TextResourceContents` with `mimeType="application/json"`. This avoids guessing whether ordinary text is intended to be protocol data. | | Persistent task/session storage | In-memory only. | The server uses the SDK `InMemoryTaskStore` and fast-agent in-memory context instances. Restarting the server loses A2A task state and context-bound fast-agent sessions. | @@ -57,6 +57,9 @@ The deterministic A2A integration suite exercises: - JSON `TextResourceContents` mapping to A2A data parts; - cancellation, task retrieval/listing after cancellation, and protocol error paths via SDK-backed handlers. +- Hugging Face bearer auth route protection, AgentCard security metadata, + `Authorization`/`X-HF-Authorization` token propagation, and client-side HF + auth header application. For provider smoke testing, run a fast-agent A2A server with `codexresponses.gpt-5.4-mini` and connect to it with the fast-agent A2A client. diff --git a/docs/docs/a2a/server.md b/docs/docs/a2a/server.md index e4cf805ca..3e020d6ef 100644 --- a/docs/docs/a2a/server.md +++ b/docs/docs/a2a/server.md @@ -198,6 +198,27 @@ Transport validation errors, task lookup errors, non-cancelable tasks, and unsupported push notification operations are handled by the A2A SDK request handler. +## Hugging Face Bearer Auth + +Set `FAST_AGENT_SERVE_OAUTH=huggingface` before starting `fast-agent serve a2a` +to require bearer authentication on `/a2a/jsonrpc` and `/a2a/rest` while keeping +the public AgentCard discoverable. + +The A2A server accepts both: + +```text +Authorization: Bearer +X-HF-Authorization: Bearer +``` + +The Hugging Face header form is useful on Spaces. The server advertises an +`hf_bearer` HTTP bearer security scheme in the AgentCard and stores the inbound +token in fast-agent request context while the agent runs, allowing Hugging Face +Inference Provider models and Hugging Face MCP/tools to use the caller +credential. + +See [Host A2A on Hugging Face](host-on-hf.md) for a Space-oriented setup. + ## File Parts Incoming raw image parts become `ImageContent`. Other raw file parts become diff --git a/plan/05-21-a2a-oauth-hf-hosting.md b/plan/05-21-a2a-oauth-hf-hosting.md index c69af0978..dab447302 100644 --- a/plan/05-21-a2a-oauth-hf-hosting.md +++ b/plan/05-21-a2a-oauth-hf-hosting.md @@ -1,6 +1,6 @@ # A2A OAuth and Hugging Face Hosting Goal -Status: planned. +Status: first bearer/Hugging Face pass implemented. ## Goal @@ -15,19 +15,20 @@ credential. ## Outcomes -- A2A servers can enforce bearer/OAuth authentication for `JSONRPC` and +- [x] A2A servers can enforce bearer authentication for `JSONRPC` and `HTTP+JSON` endpoints. -- Hugging Face Spaces deployment supports `X-HF-Authorization` and standard +- [x] Hugging Face Spaces deployment supports `X-HF-Authorization` and standard `Authorization` bearer headers, matching the existing MCP behavior. -- The request bearer token is written to `request_bearer_token` while the +- [x] The request bearer token is written to `request_bearer_token` while the fast-agent agent handles an A2A request. -- Served A2A AgentCards advertise security metadata through A2A - `security_schemes`, `security_requirements`, and, where appropriate, - per-skill security requirements. -- A2A clients can send static bearer/HF tokens and can later use the existing - fast-agent OAuth browser flow where the remote AgentCard advertises OAuth or - OIDC. -- Documentation includes an A2A "Host on HF" page with Space setup, +- [x] Served A2A AgentCards advertise security metadata through A2A + `security_schemes`, `security_requirements`, and per-skill security + requirements. +- [x] A2A clients can send static bearer/HF tokens, including automatic + Hugging Face token headers for Hugging Face URLs. +- [ ] A2A clients can use the existing fast-agent OAuth browser flow where the + remote AgentCard advertises OAuth or OIDC. +- [x] Documentation includes an A2A "Host on HF" page with Space setup, environment variables, OAuth behavior, AgentCard security metadata, and inference-provider usage. @@ -70,6 +71,16 @@ credential. - add `OAuth2SecurityScheme` or `OpenIdConnectSecurityScheme` once we have provider metadata details that A2A clients can use reliably. +Implemented first pass: + +- `FAST_AGENT_SERVE_OAUTH=huggingface` enables A2A bearer auth. +- AgentCard discovery stays public. +- `/a2a/jsonrpc` and `/a2a/rest` require a bearer token. +- `X-HF-Authorization` is accepted and normalized for Hugging Face Spaces. +- The bearer token is available through `request_bearer_token` while the + fast-agent agent runs. +- The public AgentCard advertises an `hf_bearer` HTTP bearer security scheme. + ## Proposed Client Design 1. Static token support: @@ -87,6 +98,14 @@ credential. - store tokens in keyring using a distinct service or identity prefix; - emit OAuth events through CLI/TUI surfaces similarly to `/mcp connect`. +Implemented first pass: + +- A2A explicit `headers` remain supported. +- A2A clients automatically apply Hugging Face token headers through + `add_hf_auth_header(...)` for Hugging Face URLs when no explicit auth header + is configured. +- Browser OAuth remains open. + ## Testing - Server auth: diff --git a/src/fast_agent/a2a/remote_agent.py b/src/fast_agent/a2a/remote_agent.py index 2363aeb52..d29f7a529 100644 --- a/src/fast_agent/a2a/remote_agent.py +++ b/src/fast_agent/a2a/remote_agent.py @@ -28,6 +28,7 @@ from fast_agent.core.logging.logger import get_logger from fast_agent.event_progress import ProgressAction from fast_agent.llm.stream_types import StreamChunk +from fast_agent.mcp.hf_auth import add_hf_auth_header from fast_agent.types import LlmStopReason, PromptMessageExtended, RequestParams from fast_agent.ui import console from fast_agent.ui.console_display import ConsoleDisplay @@ -105,8 +106,9 @@ def agent_type(self) -> AgentType: async def initialize(self) -> None: await super().initialize() + headers = add_hf_auth_header(self.a2a_config.url, self.a2a_config.headers) self._httpx_client = httpx.AsyncClient( - headers=self.a2a_config.headers or None, + headers=headers or None, timeout=self.a2a_config.request_timeout_seconds, ) client_config = ClientConfig( diff --git a/src/fast_agent/a2a/server.py b/src/fast_agent/a2a/server.py index e91fe6ac9..a288f4494 100644 --- a/src/fast_agent/a2a/server.py +++ b/src/fast_agent/a2a/server.py @@ -7,6 +7,7 @@ import contextlib import copy import json +import os from importlib.metadata import version as get_version from pathlib import PurePosixPath from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable @@ -25,8 +26,12 @@ AgentInterface, AgentProvider, AgentSkill, + HTTPAuthSecurityScheme, Message, Part, + SecurityRequirement, + SecurityScheme, + StringList, Task, TaskState, TaskStatus, @@ -47,6 +52,7 @@ from fast_agent.core.default_agent import agent_is_default, resolve_default_agent_name from fast_agent.core.exceptions import ProviderKeyError from fast_agent.core.logging.logger import get_logger +from fast_agent.mcp.auth.context import request_bearer_token from fast_agent.types import LlmStopReason, PromptMessageExtended if TYPE_CHECKING: @@ -55,6 +61,7 @@ from a2a.server.agent_execution.context import RequestContext from a2a.server.events.event_queue import EventQueue from starlette.requests import Request + from starlette.types import ASGIApp, Receive, Scope, Send from fast_agent.core.fastagent import AgentInstance from fast_agent.interfaces import AgentProtocol @@ -71,6 +78,7 @@ def add_stream_listener(self, listener: Any) -> Any: A2A_INPUT_MODES = ["text/plain", "application/json", "application/octet-stream", "image/*"] A2A_OUTPUT_MODES = ["text/plain", "application/json", "application/octet-stream", "image/*"] +A2A_HF_BEARER_SCHEME = "hf_bearer" def _fast_agent_version() -> str: @@ -80,6 +88,92 @@ def _fast_agent_version() -> str: return "unknown" +def _get_a2a_oauth_provider() -> str | None: + oauth_provider = os.environ.get("FAST_AGENT_SERVE_OAUTH", "").lower() + if oauth_provider in {"hf", "huggingface"}: + return "huggingface" + if not oauth_provider: + return None + return oauth_provider + + +def _bearer_token_from_header(value: str | None) -> str | None: + if value is None: + return None + stripped = value.strip() + if not stripped: + return None + prefix = "bearer " + if stripped.lower().startswith(prefix): + token = stripped[len(prefix) :].strip() + return token or None + return None + + +def _bearer_token_from_call_context(context: RequestContext) -> str | None: + headers = context.call_context.state.get("headers") + if not isinstance(headers, dict): + return None + authorization = headers.get("authorization") or headers.get("Authorization") + token = _bearer_token_from_header(authorization if isinstance(authorization, str) else None) + if token is not None: + return token + hf_authorization = headers.get("x-hf-authorization") or headers.get("X-HF-Authorization") + return _bearer_token_from_header( + hf_authorization if isinstance(hf_authorization, str) else None + ) + + +class A2ABearerAuthMiddleware: + """Require bearer authentication for A2A action routes.""" + + def __init__(self, app: ASGIApp, *, provider: str) -> None: + self.app = app + self.provider = provider + + async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: + if scope["type"] != "http": + await self.app(scope, receive, send) + return + + path = str(scope.get("path", "")) + if not path.startswith("/a2a/"): + await self.app(scope, receive, send) + return + + headers = list(scope.get("headers", [])) + authorization = _header_value(headers, b"authorization") + hf_authorization = _header_value(headers, b"x-hf-authorization") + if authorization is None and hf_authorization is not None: + authorization = hf_authorization + headers.append((b"authorization", hf_authorization.encode("latin-1"))) + scope = dict(scope, headers=headers) + + token = _bearer_token_from_header(authorization) + if token is None: + response = JSONResponse( + {"error": "unauthorized"}, + status_code=401, + headers={ + "WWW-Authenticate": ( + f'Bearer realm="fast-agent-a2a", ' + f'error="invalid_token", provider="{self.provider}"' + ) + }, + ) + await response(scope, receive, send) + return + + await self.app(scope, receive, send) + + +def _header_value(headers: list[tuple[bytes, bytes]], name: bytes) -> str | None: + for key, value in headers: + if key.lower() == name: + return value.decode("latin-1") + return None + + class FastAgentA2AExecutor(AgentExecutor): """A2A executor that routes tasks into fast-agent agents.""" @@ -158,6 +252,9 @@ async def _execute(self, context: RequestContext, event_queue: EventQueue) -> No agent=agent, updater=updater, ) + saved_bearer_token = request_bearer_token.set( + _bearer_token_from_call_context(context) + ) try: response = await agent.generate( _prompt_from_a2a_message(context.message), @@ -176,6 +273,7 @@ async def _execute(self, context: RequestContext, event_queue: EventQueue) -> No ) return finally: + request_bearer_token.reset(saved_bearer_token) await self._cleanup_streaming_context(stream_context) finally: await self._release_instance( @@ -350,6 +448,7 @@ def __init__( ) -> None: self._host = host self._port = port + self._oauth_provider = _get_a2a_oauth_provider() self._primary_agent_name = _select_primary_agent(primary_instance) self.agent_card = _build_agent_card( primary_instance=primary_instance, @@ -357,6 +456,7 @@ def __init__( server_description=server_description, host=host, port=port, + auth_enabled=self._oauth_provider == "huggingface", ) self.executor = FastAgentA2AExecutor( primary_instance=primary_instance, @@ -380,6 +480,8 @@ def asgi_app(self) -> FastAPI: app.routes.extend( create_rest_routes(request_handler=self.request_handler, path_prefix="/a2a/rest") ) + if self._oauth_provider == "huggingface": + app.add_middleware(A2ABearerAuthMiddleware, provider=self._oauth_provider) return app async def run_async(self, *, host: str | None = None, port: int | None = None) -> None: @@ -415,10 +517,16 @@ def _build_agent_card( server_description: str | None, host: str, port: int, + auth_enabled: bool = False, ) -> AgentCard: base_url = _base_url(host=host, port=port) + security_requirements = _security_requirements() if auth_enabled else [] skills = [ - _agent_skill_from_fast_agent(agent_name, agent) + _agent_skill_from_fast_agent( + agent_name, + agent, + security_requirements=security_requirements, + ) for agent_name, agent in primary_instance.agents.items() ] return AgentCard( @@ -430,6 +538,8 @@ def _build_agent_card( default_input_modes=A2A_INPUT_MODES, default_output_modes=A2A_OUTPUT_MODES, skills=skills, + security_schemes=_security_schemes() if auth_enabled else {}, + security_requirements=security_requirements, supported_interfaces=[ AgentInterface( protocol_binding="JSONRPC", @@ -486,7 +596,32 @@ def _is_wildcard_host(bind_host: str) -> bool: return bind_host in {"0.0.0.0", "::", ""} -def _agent_skill_from_fast_agent(agent_name: str, agent: AgentProtocol) -> AgentSkill: +def _security_schemes() -> dict[str, SecurityScheme]: + return { + A2A_HF_BEARER_SCHEME: SecurityScheme( + http_auth_security_scheme=HTTPAuthSecurityScheme( + scheme="bearer", + bearer_format="HF_TOKEN", + description="Hugging Face bearer token", + ) + ) + } + + +def _security_requirements() -> list[SecurityRequirement]: + return [ + SecurityRequirement( + schemes={A2A_HF_BEARER_SCHEME: StringList(list=[])} + ) + ] + + +def _agent_skill_from_fast_agent( + agent_name: str, + agent: AgentProtocol, + *, + security_requirements: list[SecurityRequirement] | None = None, +) -> AgentSkill: agent_type = str(agent.agent_type) if agent.agent_type else "agent" description = agent.config.description or f"Send a message to the {agent_name} fast-agent agent." return AgentSkill( @@ -497,6 +632,7 @@ def _agent_skill_from_fast_agent(agent_name: str, agent: AgentProtocol) -> Agent examples=["Hello"], input_modes=A2A_INPUT_MODES, output_modes=A2A_OUTPUT_MODES, + security_requirements=security_requirements or [], ) diff --git a/tests/integration/a2a/test_fast_agent_a2a_server.py b/tests/integration/a2a/test_fast_agent_a2a_server.py index fe3efeedd..9549a8778 100644 --- a/tests/integration/a2a/test_fast_agent_a2a_server.py +++ b/tests/integration/a2a/test_fast_agent_a2a_server.py @@ -42,6 +42,7 @@ from fast_agent.core.agent_app import AgentApp from fast_agent.core.fastagent import AgentInstance from fast_agent.llm.stream_types import StreamChunk +from fast_agent.mcp.auth.context import request_bearer_token from fast_agent.types import LlmStopReason, PromptMessageExtended if TYPE_CHECKING: @@ -276,6 +277,20 @@ async def generate(self, messages: Any, request_params: Any = None) -> PromptMes ) +class TokenEchoAgent(RecordingAgent): + async def generate(self, messages: Any, request_params: Any = None) -> PromptMessageExtended: + del messages, request_params + return PromptMessageExtended( + role="assistant", + content=[ + TextContent( + type="text", + text=request_bearer_token.get() or "missing", + ) + ], + ) + + @dataclass(frozen=True) class RunningFastAgentA2AServer: base_url: str @@ -1183,3 +1198,109 @@ async def test_fast_agent_a2a_server_preserves_input_required_task_for_follow_up assert client.current_task_id is None assert client.last_task_state == "TASK_STATE_COMPLETED" assert len(input_required_fast_agent_a2a_server.created_agents) == 1 + + +@pytest.mark.integration +def test_fast_agent_a2a_server_hf_auth_card_and_rejection(monkeypatch) -> None: + monkeypatch.setenv("FAST_AGENT_SERVE_OAUTH", "huggingface") + monkeypatch.setenv("FAST_AGENT_OAUTH_RESOURCE_URL", "http://testserver") + server = AgentA2AServer( + primary_instance=_instance(TokenEchoAgent(name="worker")), + create_instance=lambda: _async_instance(TokenEchoAgent(name="worker")), + dispose_instance=_async_dispose_instance, + server_name="fast-agent auth test server", + host="127.0.0.1", + port=41241, + ) + client = TestClient(server.asgi_app(), base_url="http://testserver") + + card_response = client.get("/.well-known/agent-card.json") + card_response.raise_for_status() + payload = card_response.json() + + assert "hf_bearer" in payload["securitySchemes"] + assert payload["securityRequirements"] == [{"schemes": {"hf_bearer": {}}}] + assert payload["skills"][0]["securityRequirements"] == [{"schemes": {"hf_bearer": {}}}] + + rejected = client.post("/a2a/jsonrpc", json={}) + assert rejected.status_code == 401 + assert rejected.headers["www-authenticate"].startswith("Bearer ") + + +@pytest.mark.integration +@pytest.mark.asyncio +@pytest.mark.parametrize( + ("headers", "expected"), + [ + ({"Authorization": "Bearer request-token"}, "request-token"), + ({"X-HF-Authorization": "Bearer hf-space-token"}, "hf-space-token"), + ], +) +async def test_fast_agent_a2a_server_passes_bearer_token_to_request_context( + monkeypatch, + unused_tcp_port: int, + wait_for_port, + headers: dict[str, str], + expected: str, +) -> None: + monkeypatch.setenv("FAST_AGENT_SERVE_OAUTH", "huggingface") + monkeypatch.setenv("FAST_AGENT_OAUTH_RESOURCE_URL", "http://127.0.0.1") + host = "127.0.0.1" + port = unused_tcp_port + disposed: list[AgentInstance] = [] + + async def create_instance() -> AgentInstance: + return _instance(TokenEchoAgent(name="worker")) + + async def dispose_instance(instance: AgentInstance) -> None: + disposed.append(instance) + await instance.shutdown() + + server = AgentA2AServer( + primary_instance=_instance(TokenEchoAgent(name="worker")), + create_instance=create_instance, + dispose_instance=dispose_instance, + server_name="fast-agent auth propagation test server", + host=host, + port=port, + ) + uvicorn_server = uvicorn.Server( + uvicorn.Config(server.asgi_app(), host=host, port=port, log_level="warning") + ) + server_task = asyncio.create_task(uvicorn_server.serve()) + await wait_for_port(host, port, timeout=5.0) + + client = A2ARemoteAgent( + config=AgentConfig(name="remote_auth", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig( + url=f"http://{host}:{port}", + transport="JSONRPC", + headers=headers, + ), + ) + await client.initialize() + try: + response = await client.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[TextContent(type="text", text="who am i")], + ) + ] + ) + finally: + await client.shutdown() + uvicorn_server.should_exit = True + await asyncio.wait_for(server_task, timeout=5.0) + await server.executor.shutdown() + + assert response.all_text() == expected + assert disposed + + +async def _async_instance(agent: RecordingAgent) -> AgentInstance: + return _instance(agent) + + +async def _async_dispose_instance(instance: AgentInstance) -> None: + await instance.shutdown() diff --git a/tests/unit/fast_agent/test_a2a_remote_agent_config.py b/tests/unit/fast_agent/test_a2a_remote_agent_config.py index e8e82eda7..4dfb1f973 100644 --- a/tests/unit/fast_agent/test_a2a_remote_agent_config.py +++ b/tests/unit/fast_agent/test_a2a_remote_agent_config.py @@ -65,6 +65,7 @@ async def fake_create_client(agent_card: AgentCard, *, client_config: Any) -> Fa class FakeAsyncClient: def __init__(self, *_args: Any, **kwargs: Any) -> None: captured["httpx_timeout"] = kwargs.get("timeout") + captured["httpx_headers"] = kwargs.get("headers") async def aclose(self) -> None: return None @@ -82,6 +83,153 @@ async def aclose(self) -> None: client_config = captured["client_config"] assert client_config.supported_protocol_bindings == SUPPORTED_A2A_HTTP_TRANSPORTS assert captured["httpx_timeout"] == 120.0 + assert captured["httpx_headers"] is None + finally: + await agent.shutdown() + + +@pytest.mark.asyncio +async def test_a2a_remote_agent_adds_hf_auth_headers_for_hf_space( + monkeypatch, +) -> None: + captured: dict[str, Any] = {} + + class FakeResolver: + def __init__(self, *_args: Any, **_kwargs: Any) -> None: + return None + + async def get_agent_card(self) -> AgentCard: + return AgentCard( + name="hf-space", + description="HF Space", + provider=AgentProvider(organization="test", url="https://example.com"), + version="1.0.0", + capabilities=AgentCapabilities(streaming=True, push_notifications=False), + default_input_modes=["text"], + default_output_modes=["text"], + skills=[ + AgentSkill( + id="echo", + name="Echo", + description="Echo input", + tags=["test"], + examples=["hello"], + input_modes=["text"], + output_modes=["text"], + ) + ], + supported_interfaces=[ + AgentInterface( + protocol_binding="JSONRPC", + protocol_version="1.0", + url="https://demo.hf.space/a2a/jsonrpc", + ) + ], + ) + + class FakeClient: + async def close(self) -> None: + return None + + class FakeAsyncClient: + def __init__(self, *_args: Any, **kwargs: Any) -> None: + captured["httpx_headers"] = kwargs.get("headers") + + async def aclose(self) -> None: + return None + + async def fake_create_client(agent_card: AgentCard, *, client_config: Any) -> FakeClient: + captured["agent_card"] = agent_card + captured["client_config"] = client_config + return FakeClient() + + monkeypatch.setenv("HF_TOKEN", "hf-test-token") + monkeypatch.setattr("fast_agent.a2a.remote_agent.A2ACardResolver", FakeResolver) + monkeypatch.setattr("fast_agent.a2a.remote_agent.create_client", fake_create_client) + monkeypatch.setattr("fast_agent.a2a.remote_agent.httpx.AsyncClient", FakeAsyncClient) + + agent = A2ARemoteAgent( + config=AgentConfig(name="remote", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig(url="https://demo.hf.space"), + ) + await agent.initialize() + try: + assert captured["httpx_headers"] == { + "Authorization": "Bearer hf-test-token", + "X-HF-Authorization": "Bearer hf-test-token", + } + finally: + await agent.shutdown() + + +@pytest.mark.asyncio +async def test_a2a_remote_agent_preserves_explicit_auth_headers_for_hf_space( + monkeypatch, +) -> None: + captured: dict[str, Any] = {} + + class FakeResolver: + def __init__(self, *_args: Any, **_kwargs: Any) -> None: + return None + + async def get_agent_card(self) -> AgentCard: + return AgentCard( + name="hf-space", + description="HF Space", + provider=AgentProvider(organization="test", url="https://example.com"), + version="1.0.0", + capabilities=AgentCapabilities(streaming=True, push_notifications=False), + default_input_modes=["text"], + default_output_modes=["text"], + skills=[ + AgentSkill( + id="echo", + name="Echo", + description="Echo input", + tags=["test"], + examples=["hello"], + input_modes=["text"], + output_modes=["text"], + ) + ], + supported_interfaces=[ + AgentInterface( + protocol_binding="JSONRPC", + protocol_version="1.0", + url="https://demo.hf.space/a2a/jsonrpc", + ) + ], + ) + + class FakeClient: + async def close(self) -> None: + return None + + class FakeAsyncClient: + def __init__(self, *_args: Any, **kwargs: Any) -> None: + captured["httpx_headers"] = kwargs.get("headers") + + async def aclose(self) -> None: + return None + + async def fake_create_client(agent_card: AgentCard, *, client_config: Any) -> FakeClient: + captured["agent_card"] = agent_card + captured["client_config"] = client_config + return FakeClient() + + monkeypatch.setenv("HF_TOKEN", "hf-env-token") + monkeypatch.setattr("fast_agent.a2a.remote_agent.A2ACardResolver", FakeResolver) + monkeypatch.setattr("fast_agent.a2a.remote_agent.create_client", fake_create_client) + monkeypatch.setattr("fast_agent.a2a.remote_agent.httpx.AsyncClient", FakeAsyncClient) + + explicit_headers = {"Authorization": "Bearer explicit-token"} + agent = A2ARemoteAgent( + config=AgentConfig(name="remote", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig(url="https://demo.hf.space", headers=explicit_headers), + ) + await agent.initialize() + try: + assert captured["httpx_headers"] == explicit_headers finally: await agent.shutdown() From 66e9ffd68b859819089ab66ea41768e1e99472a4 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 09:33:54 +0100 Subject: [PATCH 44/58] Add A2A client OAuth flow support --- docs/docs/a2a/client.md | 49 ++++++ docs/docs/a2a/host-on-hf.md | 25 ++- docs/docs/a2a/protocol-compliance.md | 5 +- plan/05-21-a2a-oauth-hf-hosting.md | 21 ++- src/fast_agent/a2a/config.py | 3 + src/fast_agent/a2a/connect.py | 15 +- src/fast_agent/a2a/remote_agent.py | 54 ++++++- src/fast_agent/cli/commands/go.py | 14 ++ src/fast_agent/core/agent_card_loader.py | 6 +- src/fast_agent/core/agent_card_rules.py | 1 + .../ui/interactive/command_dispatch.py | 3 +- tests/unit/fast_agent/a2a_connect_test.py | 14 ++ .../fast_agent/cli/test_a2a_go_options.py | 3 + .../fast_agent/core/test_agent_card_loader.py | 6 + .../test_a2a_remote_agent_config.py | 149 ++++++++++++++++++ .../fast_agent/ui/test_parse_a2a_commands.py | 8 + 16 files changed, 363 insertions(+), 13 deletions(-) diff --git a/docs/docs/a2a/client.md b/docs/docs/a2a/client.md index 5d8b7c24b..61a3bb658 100644 --- a/docs/docs/a2a/client.md +++ b/docs/docs/a2a/client.md @@ -27,6 +27,16 @@ When no transport is specified, fast-agent asks the SDK to use either supported HTTP binding: `JSONRPC` or `HTTP+JSON`. Set `--a2a-transport` only when you want to force one binding. +Use `--a2a-oauth` or `--no-a2a-oauth` to force or disable browser OAuth for an +ad hoc remote agent: + +```bash +uv run fast-agent -x \ + --a2a https://research.example.com \ + --a2a-oauth \ + --message "hello" +``` + Supported HTTP transports: | Canonical | Useful aliases | @@ -106,6 +116,9 @@ accepted_output_modes: request_timeout_seconds: 120 headers: Authorization: "Bearer ${A2A_TOKEN}" +auth: + oauth: true + persist: keyring relative_card_path: "/.well-known/agent-card.json" ``` @@ -114,6 +127,14 @@ fast-agent automatically applies the local Hugging Face token as A2A request headers when no explicit auth header is configured. For Spaces this includes both `Authorization` and `X-HF-Authorization`. +When a remote AgentCard advertises OAuth2 or OpenID Connect security schemes, +fast-agent can reuse the existing browser OAuth flow. If `auth` is omitted, the +A2A client enables that flow only for OAuth/OIDC cards. Set `auth.oauth: false` +to disable browser OAuth, or `auth.oauth: true` to allow OAuth challenge handling +even before the card requires it. The flow uses the same local callback, +paste-URL fallback, client metadata URL, and keyring storage behavior as MCP URL +connections. + ## TUI Inside the interactive prompt, connect a remote A2A agent at runtime: @@ -122,6 +143,34 @@ Inside the interactive prompt, connect a remote A2A agent at runtime: /a2a connect http://127.0.0.1:41242 --transport JSONRPC --name research_remote ``` +Use `--oauth` or `--no-oauth` to force or disable browser OAuth for a runtime +connection: + +```text +/a2a connect https://research.example.com --oauth --name research_remote +``` + +## Python API + +Use `A2ARemoteAgent` directly when constructing agents in code: + +```python +from fast_agent.a2a.config import A2AAgentConfig +from fast_agent.a2a.remote_agent import A2ARemoteAgent +from fast_agent.agents.agent_types import AgentConfig, AgentType +from fast_agent.config import MCPServerAuthSettings + +remote_agent = A2ARemoteAgent( + config=AgentConfig(name="research_remote", agent_type=AgentType.A2A), + a2a_config=A2AAgentConfig( + url="https://research.example.com", + transport="JSONRPC", + auth=MCPServerAuthSettings(oauth=True), + ), +) +await remote_agent.initialize() +``` + Useful diagnostics: ```text diff --git a/docs/docs/a2a/host-on-hf.md b/docs/docs/a2a/host-on-hf.md index 0eb7e8f51..80c7f6c1e 100644 --- a/docs/docs/a2a/host-on-hf.md +++ b/docs/docs/a2a/host-on-hf.md @@ -130,9 +130,9 @@ The current implementation advertises bearer security: } ``` -Skills include the same `securityRequirements` entry. Later implementations can -advertise OAuth2 or OpenID Connect metadata when the client can complete the -browser OAuth flow directly from the AgentCard. +Skills include the same `securityRequirements` entry. fast-agent A2A clients can +also use the existing browser OAuth flow when a remote AgentCard advertises +OAuth2 or OpenID Connect security schemes. ## Client Configuration @@ -161,6 +161,25 @@ MCP URL connections, so explicit headers are not needed when the target is `hf.co`, `huggingface.co`, or `*.hf.space` and no auth header has already been configured. +For AgentCards that advertise OAuth2 or OpenID Connect instead of a static +bearer scheme, enable browser OAuth explicitly or allow the card to activate it: + +```yaml +type: a2a +name: hosted_agent +url: https://.hf.space +transport: JSONRPC +auth: + oauth: true + persist: keyring +``` + +The same `--oauth` switch is available from the TUI: + +```text +/a2a connect https://.hf.space --oauth --name hosted_agent +``` + ## Inference Provider Use With request token pass-through, hosted A2A agents can use Hugging Face models diff --git a/docs/docs/a2a/protocol-compliance.md b/docs/docs/a2a/protocol-compliance.md index 776663ba5..935ccb28e 100644 --- a/docs/docs/a2a/protocol-compliance.md +++ b/docs/docs/a2a/protocol-compliance.md @@ -30,7 +30,7 @@ client stack and intentionally excludes gRPC. | gRPC transport | Not supported by design for this work. | The AgentCard does not advertise gRPC, and the CLI/API should use `JSONRPC` or `HTTP+JSON`. | | Push notifications | Not implemented. | The AgentCard advertises `pushNotifications=false`; SDK push configuration methods return the protocol's not-supported error. Streaming and polling remain available. | | Extended AgentCard | Not implemented. | The server publishes the public AgentCard only and does not configure `extendedAgentCard`. | -| Authentication/security schemes on served AgentCards | Supported for Hugging Face bearer auth | Remote clients can pass headers when connecting to other A2A agents. When `FAST_AGENT_SERVE_OAUTH=huggingface` is set, serving fast-agent over A2A advertises an `hf_bearer` HTTP bearer security scheme, requires bearer auth on A2A action routes, accepts `Authorization` and `X-HF-Authorization`, and passes the bearer token into fast-agent request context. Browser OAuth for A2A clients remains a future extension. In-task provider auth failures are reported as `AUTH_REQUIRED`. | +| Authentication/security schemes on served AgentCards | Supported for Hugging Face bearer auth and OAuth/OIDC clients | Remote clients can pass headers when connecting to other A2A agents. When `FAST_AGENT_SERVE_OAUTH=huggingface` is set, serving fast-agent over A2A advertises an `hf_bearer` HTTP bearer security scheme, requires bearer auth on A2A action routes, accepts `Authorization` and `X-HF-Authorization`, and passes the bearer token into fast-agent request context. A2A clients reuse the existing browser OAuth flow when a remote AgentCard advertises OAuth2 or OpenID Connect security schemes, with `auth.oauth` and `/a2a connect --oauth/--no-oauth` controls. In-task provider auth failures are reported as `AUTH_REQUIRED`. | | Typed audio content on the server | Partial. | The client can send `AudioContent` as raw A2A parts. The server preserves inbound audio bytes as blob resources rather than mapping them to a dedicated fast-agent `AudioContent` object. | | Structured JSON output from model text | Partial. | fast-agent JSON text responses remain text artifacts unless represented as `TextResourceContents` with `mimeType="application/json"`. This avoids guessing whether ordinary text is intended to be protocol data. | | Persistent task/session storage | In-memory only. | The server uses the SDK `InMemoryTaskStore` and fast-agent in-memory context instances. Restarting the server loses A2A task state and context-bound fast-agent sessions. | @@ -60,6 +60,9 @@ The deterministic A2A integration suite exercises: - Hugging Face bearer auth route protection, AgentCard security metadata, `Authorization`/`X-HF-Authorization` token propagation, and client-side HF auth header application. +- A2A client OAuth activation for OAuth/OIDC AgentCards, `auth.oauth: false` + suppression, checked-in AgentCard auth parsing, and TUI `--oauth/--no-oauth` + parsing. For provider smoke testing, run a fast-agent A2A server with `codexresponses.gpt-5.4-mini` and connect to it with the fast-agent A2A client. diff --git a/plan/05-21-a2a-oauth-hf-hosting.md b/plan/05-21-a2a-oauth-hf-hosting.md index dab447302..08cba6f9e 100644 --- a/plan/05-21-a2a-oauth-hf-hosting.md +++ b/plan/05-21-a2a-oauth-hf-hosting.md @@ -1,6 +1,6 @@ # A2A OAuth and Hugging Face Hosting Goal -Status: first bearer/Hugging Face pass implemented. +Status: bearer/Hugging Face pass and first A2A client browser OAuth pass implemented. ## Goal @@ -26,7 +26,7 @@ credential. requirements. - [x] A2A clients can send static bearer/HF tokens, including automatic Hugging Face token headers for Hugging Face URLs. -- [ ] A2A clients can use the existing fast-agent OAuth browser flow where the +- [x] A2A clients can use the existing fast-agent OAuth browser flow where the remote AgentCard advertises OAuth or OIDC. - [x] Documentation includes an A2A "Host on HF" page with Space setup, environment variables, OAuth behavior, AgentCard security metadata, and @@ -104,7 +104,15 @@ Implemented first pass: - A2A clients automatically apply Hugging Face token headers through `add_hf_auth_header(...)` for Hugging Face URLs when no explicit auth header is configured. -- Browser OAuth remains open. +- Checked-in A2A AgentCards accept an `auth` block compatible with the existing + MCP OAuth settings. +- `fast-agent --a2a` accepts `--a2a-oauth` and `--no-a2a-oauth`. +- `/a2a connect` accepts `--oauth` and `--no-oauth`. +- When `auth` is omitted, A2A clients attach the existing browser OAuth + `httpx` auth flow only when the remote AgentCard advertises OAuth2 or OpenID + Connect security schemes. +- The A2A OAuth bridge preserves the A2A base URL as the protected-resource + identity instead of rewriting it to an MCP endpoint. ## Testing @@ -120,6 +128,9 @@ Implemented first pass: - explicit A2A headers are sent; - HF token auto-header logic applies only to Hugging Face URLs; - existing explicit auth headers win over auto HF auth. + - OAuth/OIDC AgentCards enable the browser OAuth provider; + - `auth.oauth: false` suppresses browser OAuth; + - checked-in A2A cards, CLI `--a2a`, and `/a2a connect` parse OAuth settings. - Inference pass-through: - deterministic test agent reads `request_bearer_token`; - provider-key-manager behavior can use the request token for Hugging Face. @@ -129,7 +140,7 @@ Implemented first pass: - Should A2A server auth configuration live only in shared serve environment variables, or should `fast-agent serve a2a` expose first-class `--oauth` flags? -- Should the first client OAuth pass be generic OAuth/OIDC, or should it focus - on Hugging Face Spaces first? +- Should A2A OAuth tokens share the existing MCP keyring service/index long + term, or should they move to a distinct A2A service name after migration? - Should authenticated extended AgentCards be implemented as part of this work, or should public cards advertise enough security metadata for the first pass? diff --git a/src/fast_agent/a2a/config.py b/src/fast_agent/a2a/config.py index 33e5561db..a085802bd 100644 --- a/src/fast_agent/a2a/config.py +++ b/src/fast_agent/a2a/config.py @@ -2,6 +2,8 @@ from dataclasses import dataclass, field +from fast_agent.config import MCPServerAuthSettings + @dataclass(frozen=True) class A2AAgentConfig: @@ -11,5 +13,6 @@ class A2AAgentConfig: polling: bool = False accepted_output_modes: list[str] = field(default_factory=list) headers: dict[str, str] = field(default_factory=dict) + auth: MCPServerAuthSettings | None = None relative_card_path: str | None = None request_timeout_seconds: float | None = 120.0 diff --git a/src/fast_agent/a2a/connect.py b/src/fast_agent/a2a/connect.py index 41c055a8c..390523f4a 100644 --- a/src/fast_agent/a2a/connect.py +++ b/src/fast_agent/a2a/connect.py @@ -7,6 +7,8 @@ from dataclasses import dataclass from urllib.parse import urlsplit, urlunsplit +from fast_agent.config import MCPServerAuthSettings + _TRANSPORT_ALIASES = { "jsonrpc": "JSONRPC", "json-rpc": "JSONRPC", @@ -22,12 +24,13 @@ class A2AConnectRequest: url: str name: str | None = None transport: str | None = None + auth: MCPServerAuthSettings | None = None relative_card_path: str | None = None def parse_a2a_connect_arguments(arguments: str | None) -> tuple[A2AConnectRequest | None, str | None]: if not arguments: - return None, "Usage: /a2a connect [--transport JSONRPC|HTTP+JSON] [--name NAME] [--card-path PATH]" + return None, "Usage: /a2a connect [--transport JSONRPC|HTTP+JSON] [--name NAME] [--card-path PATH] [--oauth|--no-oauth]" try: tokens = shlex.split(arguments) except ValueError as exc: @@ -37,6 +40,7 @@ def parse_a2a_connect_arguments(arguments: str | None) -> tuple[A2AConnectReques name: str | None = None transport: str | None = None card_path: str | None = None + trigger_oauth: bool | None = None index = 0 while index < len(tokens): token = tokens[index] @@ -56,6 +60,10 @@ def parse_a2a_connect_arguments(arguments: str | None) -> tuple[A2AConnectReques card_path = value index += 2 continue + if token in {"--oauth", "--no-oauth"}: + trigger_oauth = token == "--oauth" + index += 1 + continue if token.startswith("-"): return None, f"Unknown /a2a connect option: {token}" if url is not None: @@ -73,6 +81,11 @@ def parse_a2a_connect_arguments(arguments: str | None) -> tuple[A2AConnectReques url=normalized_url, name=name, transport=transport, + auth=( + MCPServerAuthSettings(oauth=trigger_oauth) + if trigger_oauth is not None + else None + ), relative_card_path=card_path or inferred_card_path, ), None, diff --git a/src/fast_agent/a2a/remote_agent.py b/src/fast_agent/a2a/remote_agent.py index d29f7a529..ca84a7b1d 100644 --- a/src/fast_agent/a2a/remote_agent.py +++ b/src/fast_agent/a2a/remote_agent.py @@ -7,7 +7,8 @@ import uuid from dataclasses import dataclass from pathlib import PurePosixPath -from typing import TYPE_CHECKING, Any +from types import SimpleNamespace +from typing import TYPE_CHECKING, Any, cast import httpx from a2a.client import A2ACardResolver, ClientConfig, create_client @@ -29,6 +30,7 @@ from fast_agent.event_progress import ProgressAction from fast_agent.llm.stream_types import StreamChunk from fast_agent.mcp.hf_auth import add_hf_auth_header +from fast_agent.mcp.oauth_client import build_oauth_provider from fast_agent.types import LlmStopReason, PromptMessageExtended, RequestParams from fast_agent.ui import console from fast_agent.ui.console_display import ConsoleDisplay @@ -42,6 +44,7 @@ from mcp import Tool from fast_agent.a2a.config import A2AAgentConfig + from fast_agent.config import MCPServerSettings from fast_agent.context import Context _TERMINAL_STATES = { @@ -128,6 +131,15 @@ async def initialize(self) -> None: self.a2a_config.relative_card_path or "/.well-known/agent-card.json", ) self.remote_card = await resolver.get_agent_card() + oauth_provider = self._build_oauth_provider_for_card(self.remote_card) + if oauth_provider is not None: + await self._httpx_client.aclose() + self._httpx_client = httpx.AsyncClient( + auth=oauth_provider, + headers=headers or None, + timeout=self.a2a_config.request_timeout_seconds, + ) + client_config.httpx_client = self._httpx_client self._client = await create_client( self.remote_card, client_config=client_config, @@ -158,6 +170,26 @@ def _clone_constructor_kwargs(self) -> dict[str, Any]: """Carry remote A2A connection configuration into detached clones.""" return {"a2a_config": self.a2a_config} + def _build_oauth_provider_for_card(self, card: AgentCard) -> Any | None: + auth_config = self.a2a_config.auth + if auth_config is not None and not auth_config.oauth: + return None + if auth_config is None and not _card_advertises_oauth(card): + return None + if self.a2a_config.headers: + return None + return build_oauth_provider( + cast( + "MCPServerSettings", + SimpleNamespace( + name=self.config.name, + transport="http", + url=self.a2a_config.url, + auth=auth_config, + ), + ) + ) + def reset_a2a_state(self) -> None: self.context_id = str(uuid.uuid4()) self.current_task_id = None @@ -447,6 +479,26 @@ def _part_text(part: Part) -> str: return f"[{label}: {len(part.raw)} bytes{suffix}]" return "" + +def _card_advertises_oauth(card: AgentCard) -> bool: + if not card.security_schemes or not card.security_requirements: + return False + required_scheme_names = { + scheme_name + for requirement in card.security_requirements + for scheme_name in requirement.schemes + } + for scheme_name in required_scheme_names: + scheme = card.security_schemes.get(scheme_name) + if scheme is None: + continue + if scheme.HasField("oauth2_security_scheme") or scheme.HasField( + "open_id_connect_security_scheme" + ): + return True + return False + + def _latest_text(messages: Sequence[PromptMessageExtended]) -> str: for message in reversed(messages): text = message.all_text() diff --git a/src/fast_agent/cli/commands/go.py b/src/fast_agent/cli/commands/go.py index 3ff632299..3e5c46a10 100644 --- a/src/fast_agent/cli/commands/go.py +++ b/src/fast_agent/cli/commands/go.py @@ -103,6 +103,7 @@ def _materialize_a2a_agent_cards( urls: list[str], *, transport: str | None, + oauth: bool | None = None, ) -> tuple[tempfile.TemporaryDirectory[str], list[str]]: normalized_transport = None if transport: @@ -128,6 +129,13 @@ def _materialize_a2a_agent_cards( ] if normalized_transport: lines.append(f"transport: {normalized_transport}") + if oauth is not None: + lines.extend( + [ + "auth:", + f" oauth: {str(oauth).lower()}", + ] + ) if card_path: lines.append(f"relative_card_path: {card_path}") path = Path(tempdir.name) / f"{name}.yaml" @@ -381,6 +389,11 @@ def go( "--a2a-transport", help="Preferred A2A transport for --a2a: JSONRPC or HTTP+JSON.", ), + a2a_oauth: bool | None = typer.Option( + None, + "--a2a-oauth/--no-a2a-oauth", + help="Force or disable browser OAuth for --a2a remote agents.", + ), card_tools: list[str] | None = CommonAgentOptions.card_tools(), urls: str | None = CommonAgentOptions.urls(), auth: str | None = CommonAgentOptions.auth(), @@ -511,6 +524,7 @@ def go( a2a_tempdir, a2a_cards = _materialize_a2a_agent_cards( a2a, transport=a2a_transport, + oauth=a2a_oauth, ) agent_cards = [*(agent_cards or []), *a2a_cards] if agent is None and len(a2a_cards) == 1: diff --git a/src/fast_agent/core/agent_card_loader.py b/src/fast_agent/core/agent_card_loader.py index 1f64592f7..ef4b0bd53 100644 --- a/src/fast_agent/core/agent_card_loader.py +++ b/src/fast_agent/core/agent_card_loader.py @@ -19,7 +19,7 @@ MCPConnectTarget, ) from fast_agent.command_actions import PluginCommandActionSpec, parse_plugin_command_action_specs -from fast_agent.config import MCPServerSettings, resolve_env_vars +from fast_agent.config import MCPServerAuthSettings, MCPServerSettings, resolve_env_vars from fast_agent.constants import DEFAULT_AGENT_INSTRUCTION, SMART_AGENT_INSTRUCTION from fast_agent.core.agent_card_rules import ( AGENT_TYPE_TO_CARD_TYPE, @@ -540,6 +540,9 @@ def _build_agent_data( transport = raw.get("transport") if transport is not None: transport = _ensure_a2a_transport(transport, path) + auth = raw.get("auth") + if auth is not None and not isinstance(auth, dict): + raise AgentConfigError(f"'auth' must be a mapping in {path}") agent_data["a2a"] = A2AAgentConfig( url=_ensure_str(raw.get("url"), "url", path), transport=transport, @@ -549,6 +552,7 @@ def _build_agent_data( raw.get("accepted_output_modes", []), "accepted_output_modes", path ), headers=_ensure_headers_map(raw.get("headers"), "headers", path) or {}, + auth=MCPServerAuthSettings.model_validate(auth) if auth is not None else None, relative_card_path=_ensure_optional_str( raw.get("relative_card_path"), "relative_card_path", path ), diff --git a/src/fast_agent/core/agent_card_rules.py b/src/fast_agent/core/agent_card_rules.py index 141682bf5..27d767928 100644 --- a/src/fast_agent/core/agent_card_rules.py +++ b/src/fast_agent/core/agent_card_rules.py @@ -151,6 +151,7 @@ "polling", "accepted_output_modes", "headers", + "auth", "relative_card_path", "request_timeout_seconds", }, diff --git a/src/fast_agent/ui/interactive/command_dispatch.py b/src/fast_agent/ui/interactive/command_dispatch.py index 920b67356..52ca7d06e 100644 --- a/src/fast_agent/ui/interactive/command_dispatch.py +++ b/src/fast_agent/ui/interactive/command_dispatch.py @@ -378,7 +378,7 @@ def _print_a2a_help() -> None: "/a2a card [agent]", "/a2a transport [agent]", "/a2a reset [agent]", - "/a2a connect [--transport JSONRPC|HTTP+JSON|GRPC] [--name NAME] [--card-path PATH]", + "/a2a connect [--transport JSONRPC|HTTP+JSON] [--name NAME] [--card-path PATH] [--oauth|--no-oauth]", "/a2a help", ]: rich_print(f" {line}") @@ -482,6 +482,7 @@ async def _dispatch_a2a_payload( a2a_config=A2AAgentConfig( url=request.url, transport=request.transport, + auth=request.auth, relative_card_path=request.relative_card_path, ), ) diff --git a/tests/unit/fast_agent/a2a_connect_test.py b/tests/unit/fast_agent/a2a_connect_test.py index 9cbdd55fd..ad18942b4 100644 --- a/tests/unit/fast_agent/a2a_connect_test.py +++ b/tests/unit/fast_agent/a2a_connect_test.py @@ -40,6 +40,20 @@ def test_parse_a2a_connect_arguments() -> None: assert request.relative_card_path == "/card.json" +def test_parse_a2a_connect_oauth_switches() -> None: + request, error = parse_a2a_connect_arguments("http://127.0.0.1:41241 --oauth") + assert error is None + assert request is not None + assert request.auth is not None + assert request.auth.oauth is True + + request, error = parse_a2a_connect_arguments("http://127.0.0.1:41241 --no-oauth") + assert error is None + assert request is not None + assert request.auth is not None + assert request.auth.oauth is False + + def test_parse_a2a_connect_rejects_endpointless_url() -> None: request, error = parse_a2a_connect_arguments("127.0.0.1:41241") assert request is None diff --git a/tests/unit/fast_agent/cli/test_a2a_go_options.py b/tests/unit/fast_agent/cli/test_a2a_go_options.py index 44831ea6e..9384378a3 100644 --- a/tests/unit/fast_agent/cli/test_a2a_go_options.py +++ b/tests/unit/fast_agent/cli/test_a2a_go_options.py @@ -10,6 +10,7 @@ def test_materialize_a2a_agent_card() -> None: tempdir, paths = _materialize_a2a_agent_cards( ["http://127.0.0.1:41241/.well-known/agent-card.json"], transport="rest", + oauth=True, ) try: assert len(paths) == 1 @@ -18,6 +19,8 @@ def test_materialize_a2a_agent_card() -> None: assert "name: a2a_remote" in text assert "url: http://127.0.0.1:41241" in text assert "transport: HTTP+JSON" in text + assert "auth:" in text + assert " oauth: true" in text assert "relative_card_path: /.well-known/agent-card.json" in text finally: tempdir.cleanup() diff --git a/tests/unit/fast_agent/core/test_agent_card_loader.py b/tests/unit/fast_agent/core/test_agent_card_loader.py index bf9fad344..111deb68d 100644 --- a/tests/unit/fast_agent/core/test_agent_card_loader.py +++ b/tests/unit/fast_agent/core/test_agent_card_loader.py @@ -517,6 +517,9 @@ def test_load_a2a_agent_card(tmp_path: Path) -> None: "name: hello_remote", "url: http://127.0.0.1:41241", "transport: JSONRPC", + "auth:", + " oauth: true", + " persist: memory", "request_timeout_seconds: 45", "accepted_output_modes:", " - text", @@ -534,6 +537,9 @@ def test_load_a2a_agent_card(tmp_path: Path) -> None: assert a2a_config.url == "http://127.0.0.1:41241" assert a2a_config.transport == "JSONRPC" assert a2a_config.streaming is True + assert a2a_config.auth is not None + assert a2a_config.auth.oauth is True + assert a2a_config.auth.persist == "memory" assert a2a_config.accepted_output_modes == ["text"] assert a2a_config.request_timeout_seconds == 45.0 diff --git a/tests/unit/fast_agent/test_a2a_remote_agent_config.py b/tests/unit/fast_agent/test_a2a_remote_agent_config.py index 4dfb1f973..fed9ed0a6 100644 --- a/tests/unit/fast_agent/test_a2a_remote_agent_config.py +++ b/tests/unit/fast_agent/test_a2a_remote_agent_config.py @@ -9,11 +9,18 @@ AgentInterface, AgentProvider, AgentSkill, + AuthorizationCodeOAuthFlow, + OAuth2SecurityScheme, + OAuthFlows, + SecurityRequirement, + SecurityScheme, + StringList, ) from fast_agent.a2a.config import A2AAgentConfig from fast_agent.a2a.remote_agent import SUPPORTED_A2A_HTTP_TRANSPORTS, A2ARemoteAgent from fast_agent.agents.agent_types import AgentConfig, AgentType +from fast_agent.config import MCPServerAuthSettings @pytest.mark.asyncio @@ -364,3 +371,145 @@ async def fake_create_client(agent_card: AgentCard, *, client_config: Any) -> Fa assert client_config.supported_protocol_bindings == ["JSONRPC"] finally: await agent.shutdown() + + +@pytest.mark.asyncio +async def test_a2a_remote_agent_enables_oauth_for_oauth_agent_card(monkeypatch) -> None: + captured: dict[str, Any] = {"httpx_auth": []} + oauth_provider = object() + + class FakeResolver: + def __init__(self, *_args: Any, **_kwargs: Any) -> None: + return None + + async def get_agent_card(self) -> AgentCard: + return _oauth_agent_card() + + class FakeClient: + async def close(self) -> None: + return None + + class FakeAsyncClient: + def __init__(self, *_args: Any, **kwargs: Any) -> None: + captured["httpx_auth"].append(kwargs.get("auth")) + + async def aclose(self) -> None: + return None + + async def fake_create_client(agent_card: AgentCard, *, client_config: Any) -> FakeClient: + captured["agent_card"] = agent_card + captured["client_config"] = client_config + return FakeClient() + + def fake_build_oauth_provider(server_config: Any) -> object: + captured["oauth_server"] = server_config + return oauth_provider + + monkeypatch.setattr("fast_agent.a2a.remote_agent.A2ACardResolver", FakeResolver) + monkeypatch.setattr("fast_agent.a2a.remote_agent.create_client", fake_create_client) + monkeypatch.setattr("fast_agent.a2a.remote_agent.httpx.AsyncClient", FakeAsyncClient) + monkeypatch.setattr( + "fast_agent.a2a.remote_agent.build_oauth_provider", + fake_build_oauth_provider, + ) + + agent = A2ARemoteAgent( + config=AgentConfig(name="remote", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig(url="https://agent.example.com"), + ) + await agent.initialize() + try: + assert captured["httpx_auth"] == [None, oauth_provider] + assert captured["client_config"].httpx_client is agent._httpx_client + assert captured["oauth_server"].transport == "http" + assert captured["oauth_server"].url == "https://agent.example.com" + finally: + await agent.shutdown() + + +@pytest.mark.asyncio +async def test_a2a_remote_agent_no_oauth_disables_advertised_oauth(monkeypatch) -> None: + captured: dict[str, Any] = {} + + class FakeResolver: + def __init__(self, *_args: Any, **_kwargs: Any) -> None: + return None + + async def get_agent_card(self) -> AgentCard: + return _oauth_agent_card() + + class FakeClient: + async def close(self) -> None: + return None + + async def fake_create_client(agent_card: AgentCard, *, client_config: Any) -> FakeClient: + captured["client_config"] = client_config + return FakeClient() + + def fail_build_oauth_provider(_server_config: Any) -> object: + raise AssertionError("OAuth provider should not be built") + + monkeypatch.setattr("fast_agent.a2a.remote_agent.A2ACardResolver", FakeResolver) + monkeypatch.setattr("fast_agent.a2a.remote_agent.create_client", fake_create_client) + monkeypatch.setattr( + "fast_agent.a2a.remote_agent.build_oauth_provider", + fail_build_oauth_provider, + ) + + agent = A2ARemoteAgent( + config=AgentConfig(name="remote", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig( + url="https://agent.example.com", + auth=MCPServerAuthSettings(oauth=False), + ), + ) + await agent.initialize() + try: + assert captured["client_config"].httpx_client is agent._httpx_client + finally: + await agent.shutdown() + + +def _oauth_agent_card() -> AgentCard: + return AgentCard( + name="oauth-agent", + description="OAuth Agent", + provider=AgentProvider(organization="test", url="https://example.com"), + version="1.0.0", + capabilities=AgentCapabilities(streaming=True, push_notifications=False), + default_input_modes=["text"], + default_output_modes=["text"], + skills=[ + AgentSkill( + id="echo", + name="Echo", + description="Echo input", + tags=["test"], + examples=["hello"], + input_modes=["text"], + output_modes=["text"], + ) + ], + supported_interfaces=[ + AgentInterface( + protocol_binding="JSONRPC", + protocol_version="1.0", + url="https://agent.example.com/a2a/jsonrpc", + ) + ], + security_requirements=[ + SecurityRequirement(schemes={"oauth": StringList(list=["openid"])}) + ], + security_schemes={ + "oauth": SecurityScheme( + oauth2_security_scheme=OAuth2SecurityScheme( + flows=OAuthFlows( + authorization_code=AuthorizationCodeOAuthFlow( + authorization_url="https://auth.example.com/authorize", + token_url="https://auth.example.com/token", + ) + ) + ) + ) + }, + ) diff --git a/tests/unit/fast_agent/ui/test_parse_a2a_commands.py b/tests/unit/fast_agent/ui/test_parse_a2a_commands.py index 7e06c6571..3bda6c4f0 100644 --- a/tests/unit/fast_agent/ui/test_parse_a2a_commands.py +++ b/tests/unit/fast_agent/ui/test_parse_a2a_commands.py @@ -25,6 +25,14 @@ def test_parse_a2a_connect_preserves_arguments() -> None: assert result.error is None +def test_parse_a2a_connect_preserves_oauth_switch() -> None: + result = parse_special_input("/a2a connect http://127.0.0.1:41241 --oauth") + assert isinstance(result, A2ACommand) + assert result.action == "connect" + assert result.argument == "http://127.0.0.1:41241 --oauth" + assert result.error is None + + def test_parse_a2a_unknown_action_reports_error() -> None: result = parse_special_input("/a2a wat remote") assert isinstance(result, A2ACommand) From 359f505c60e87d4d57a9700d53dd2c2bfecbf5ba Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 10:26:24 +0100 Subject: [PATCH 45/58] Serialize A2A auth in card dumps --- src/fast_agent/core/agent_card_loader.py | 4 ++++ tests/unit/fast_agent/core/test_agent_card_loader.py | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/src/fast_agent/core/agent_card_loader.py b/src/fast_agent/core/agent_card_loader.py index ef4b0bd53..2c765c0a4 100644 --- a/src/fast_agent/core/agent_card_loader.py +++ b/src/fast_agent/core/agent_card_loader.py @@ -1212,6 +1212,10 @@ def _serialize_a2a_fields( card["accepted_output_modes"] = list(a2a_config.accepted_output_modes) if a2a_config.headers: card["headers"] = dict(a2a_config.headers) + if a2a_config.auth is not None: + auth = a2a_config.auth.model_dump(mode="python", exclude_none=True, exclude_defaults=True) + auth["oauth"] = a2a_config.auth.oauth + card["auth"] = auth if a2a_config.relative_card_path: card["relative_card_path"] = a2a_config.relative_card_path if a2a_config.request_timeout_seconds != 120.0: diff --git a/tests/unit/fast_agent/core/test_agent_card_loader.py b/tests/unit/fast_agent/core/test_agent_card_loader.py index 111deb68d..0bf103a73 100644 --- a/tests/unit/fast_agent/core/test_agent_card_loader.py +++ b/tests/unit/fast_agent/core/test_agent_card_loader.py @@ -543,6 +543,11 @@ def test_load_a2a_agent_card(tmp_path: Path) -> None: assert a2a_config.accepted_output_modes == ["text"] assert a2a_config.request_timeout_seconds == 45.0 + dumped = dump_agent_to_string("hello_remote", loaded.agent_data, as_yaml=True) + assert "auth:" in dumped + assert "oauth: true" in dumped + assert "persist: memory" in dumped + def test_load_a2a_agent_card_rejects_invalid_transport(tmp_path: Path) -> None: card_path = tmp_path / "bad_remote.yaml" From 88bad89ac822c779fb419d27f6af795752436b96 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 21:21:40 +0100 Subject: [PATCH 46/58] docs update --- docs/docs/a2a/api.md | 10 ++-- docs/docs/a2a/client.md | 29 ++++++++++-- docs/docs/a2a/getting-started.md | 21 ++++---- docs/docs/a2a/host-on-hf.md | 71 ++++++++++++++++++---------- docs/docs/a2a/protocol-compliance.md | 8 ++-- docs/docs/a2a/server.md | 60 ++++++++++++++--------- 6 files changed, 132 insertions(+), 67 deletions(-) diff --git a/docs/docs/a2a/api.md b/docs/docs/a2a/api.md index ff5ba5f43..53f160722 100644 --- a/docs/docs/a2a/api.md +++ b/docs/docs/a2a/api.md @@ -153,15 +153,17 @@ External clients can call the served fast-agent endpoint directly: "messageId": "msg-1", "parts": [ {"text": "hello"} - ], - "metadata": { - "agent": "researcher" - } + ] } } } ``` +The endpoint behaves as one A2A remote agent. Requests route to the fast-agent +default agent, which can orchestrate or delegate internally. fast-agent servers +also accept a non-portable metadata routing extension, such as +`{"agent": "researcher"}`, for fast-agent-to-fast-agent integrations. + To continue a session, include the returned `contextId`. To continue an `INPUT_REQUIRED` task, include both the returned `contextId` and `taskId`. diff --git a/docs/docs/a2a/client.md b/docs/docs/a2a/client.md index 61a3bb658..c00d28181 100644 --- a/docs/docs/a2a/client.md +++ b/docs/docs/a2a/client.md @@ -37,6 +37,16 @@ uv run fast-agent -x \ --message "hello" ``` +Use `--auth` when the remote A2A endpoint itself expects bearer auth. This uses +the standard `Authorization` header, including for Hugging Face Space endpoints: + +```bash +uv run fast-agent -x \ + --a2a https://agent-demo.hf.space \ + --auth "$HF_TOKEN" \ + --message "hello" +``` + Supported HTTP transports: | Canonical | Useful aliases | @@ -123,9 +133,22 @@ relative_card_path: "/.well-known/agent-card.json" ``` For Hugging Face URLs (`hf.co`, `huggingface.co`, and `*.hf.space`), -fast-agent automatically applies the local Hugging Face token as A2A request -headers when no explicit auth header is configured. For Spaces this includes -both `Authorization` and `X-HF-Authorization`. +fast-agent has two different auth policies: + +- Ambient Hugging Face auth discovers `HF_TOKEN` or the local Hub login and adds + it only to Hugging Face URLs. It uses `Authorization` for `hf.co` and + `huggingface.co`, and `X-HF-Authorization` for `*.hf.space`. This is intended + for ordinary HF MCP calls and Space apps that consume the caller's HF token + without taking over app-level `Authorization`. +- Explicit endpoint auth uses `Authorization: Bearer ...`, including for + `*.hf.space`. This is the policy behind `--auth`, checked-in `headers: + Authorization: ...`, and OAuth-managed A2A/MCP servers. + +For `*.hf.space` A2A URLs, fast-agent first fetches the public AgentCard. If the +card advertises HTTP bearer security and no explicit headers were configured, +the client treats the Space as a protected endpoint: a discovered local +`HF_TOKEN`/Hub login is sent as `Authorization`, not `X-HF-Authorization`. If no +local token is available and OAuth is allowed, the client uses the OAuth flow. When a remote AgentCard advertises OAuth2 or OpenID Connect security schemes, fast-agent can reuse the existing browser OAuth flow. If `auth` is omitted, the diff --git a/docs/docs/a2a/getting-started.md b/docs/docs/a2a/getting-started.md index cb25dd664..0d80357e7 100644 --- a/docs/docs/a2a/getting-started.md +++ b/docs/docs/a2a/getting-started.md @@ -208,14 +208,18 @@ uv run fast-agent serve a2a \ --model codexresponses.gpt-5.4-mini ``` -The same runtime wiring used by normal fast-agent agents is available inside the -served agent: configured MCP servers, tools, skills, hooks, and AgentCard-loaded -agents are initialized through the regular fast-agent path before the A2A server -starts. +The same runtime wiring used by normal fast-agent agents is available behind the +served A2A agent: configured MCP servers, tools, skills, hooks, and +AgentCard-loaded agents are initialized through the regular fast-agent path +before the A2A server starts. -The generated A2A AgentCard lists each loaded fast-agent agent as an A2A skill. -By default, incoming A2A messages are routed to the fast-agent default agent. API -clients can route to a specific loaded agent by adding message metadata: +A2A treats the endpoint as one remote agent or agentic system. The generated A2A +AgentCard uses skills as capability metadata, and incoming A2A messages route to +the fast-agent default agent. That default can orchestrate or delegate to other +loaded agents internally. + +For fast-agent-to-fast-agent integrations, API clients can opt into a +fast-agent-specific routing extension by adding message metadata: ```json { @@ -225,7 +229,8 @@ clients can route to a specific loaded agent by adding message metadata: } ``` -`fast_agent_agent` is accepted as an equivalent metadata key. +`fast_agent_agent` is accepted as an equivalent metadata key. Generic A2A +clients should not depend on this extension. See [Protocol Compliance](protocol-compliance.md) for the supported A2A 1.0 surface and known gaps. diff --git a/docs/docs/a2a/host-on-hf.md b/docs/docs/a2a/host-on-hf.md index 80c7f6c1e..92d5b8088 100644 --- a/docs/docs/a2a/host-on-hf.md +++ b/docs/docs/a2a/host-on-hf.md @@ -92,16 +92,23 @@ OAuth-enabled A2A flow: 1. The client fetches `/.well-known/agent-card.json`. 2. The AgentCard advertises bearer/OAuth security requirements. -3. The client sends A2A requests to `/a2a/jsonrpc` or `/a2a/rest` with either: - - `Authorization: Bearer `; - - `X-HF-Authorization: Bearer ` when running through Hugging Face - Space infrastructure. -4. The A2A server normalizes the Hugging Face header and validates that a bearer - credential is present. +3. The client sends A2A requests to `/a2a/jsonrpc` or `/a2a/rest` with + `Authorization: Bearer `, or uses OAuth when the card advertises an + OAuth/OIDC challenge. +4. The A2A server validates that a bearer credential is present. 5. fast-agent stores the token in request context while the agent runs. 6. Hugging Face Inference Provider model calls and Hugging Face MCP/tool calls can use the request token. +Do not confuse this with fast-agent's ambient Hugging Face client policy. The +normal CLI can add a discovered local `HF_TOKEN` to Hugging Face URLs without an +explicit `--auth`: it sends `Authorization` to `hf.co` and `huggingface.co`, and +`X-HF-Authorization` to ordinary `*.hf.space` app URLs. That protects local +tokens from being sent as app-level `Authorization` to arbitrary Space apps. +When the Space endpoint itself is the authenticated A2A or MCP server, use +explicit endpoint auth instead: `--auth`, checked-in `headers: Authorization: +...`, or OAuth. + ## AgentCard Security An OAuth-enabled card should advertise security metadata so A2A clients know @@ -148,18 +155,14 @@ headers: Authorization: "Bearer ${HF_TOKEN}" ``` -For Hugging Face Space routing, clients may also need: - -```yaml -headers: - Authorization: "Bearer ${HF_TOKEN}" - X-HF-Authorization: "Bearer ${HF_TOKEN}" -``` - -fast-agent A2A clients reuse the existing Hugging Face token discovery used by -MCP URL connections, so explicit headers are not needed when the target is -`hf.co`, `huggingface.co`, or `*.hf.space` and no auth header has already been -configured. +This is endpoint authentication: the Space-hosted A2A server is the protected +resource, so the standard `Authorization` header is the right header. The +ambient `X-HF-Authorization` Space policy is for ordinary Space apps, not for +authenticating to an A2A action route that advertises bearer/OAuth security. +When a fast-agent A2A client connects to a `*.hf.space` URL and the public +AgentCard advertises HTTP bearer security, a discovered local Hugging Face token +is automatically promoted to endpoint `Authorization` unless explicit headers +were configured. For AgentCards that advertise OAuth2 or OpenID Connect instead of a static bearer scheme, enable browser OAuth explicitly or allow the card to activate it: @@ -187,19 +190,36 @@ without putting a shared user token in the Space: ```yaml name: researcher -type: basic +type: agent model: hf.moonshotai/Kimi-K2-Thinking instruction: | Answer with concise Markdown. Use Hugging Face tools when current Hub context is needed. -mcp_servers: +mcp_connect: - name: huggingface - target: "https://huggingface.co/mcp" + target: "https://huggingface.co/mcp?bouquet=hub_repo_details_readme" + auth: + forward: huggingface ``` -When the A2A request arrives with a user bearer token, both provider calls and -the Hugging Face MCP server should be able to use that token through the normal -fast-agent request auth context. +When the A2A request arrives with a user bearer token, Hugging Face provider +calls use that request token before falling back to Space configuration. + +For client-managed Hugging Face MCP URLs, set `auth.forward: huggingface` to +forward the same inbound request token to `hf.co`, `huggingface.co`, or +`*.hf.space` upstreams. For Space upstreams, forwarded requests use +`X-HF-Authorization`; for `hf.co` and `huggingface.co`, they use +`Authorization`. This mode is intended for hosted Spaces where the agent should +act as the caller rather than as a shared Space identity. For the Hugging Face +MCP server itself, use `https://huggingface.co/mcp?...`; the forwarded request +token is sent there as `Authorization: Bearer ...`. It preserves explicit +`Authorization`/`X-HF-Authorization` headers when they are configured and +disables OAuth escalation for that MCP connection. + +Do not combine `auth.forward: huggingface` with a shared `HF_TOKEN` expectation +for that MCP server: forward mode deliberately avoids capturing the Space +process token during configuration and uses the per-request bearer token at +connection time. ## Operational Notes @@ -217,7 +237,8 @@ The OAuth-enabled A2A implementation should include tests that prove: - unauthenticated A2A requests are rejected; - authenticated A2A requests reach the agent; -- `Authorization` and `X-HF-Authorization` both propagate to request context; +- the verified bearer token is saved at the A2A HTTP boundary and propagated + into fast-agent request context; - the AgentCard advertises security schemes and requirements; - client-side Hugging Face token auto-headers are added for HF URLs; - explicit user-supplied auth headers are preserved. diff --git a/docs/docs/a2a/protocol-compliance.md b/docs/docs/a2a/protocol-compliance.md index 935ccb28e..fa1d0eef4 100644 --- a/docs/docs/a2a/protocol-compliance.md +++ b/docs/docs/a2a/protocol-compliance.md @@ -30,7 +30,7 @@ client stack and intentionally excludes gRPC. | gRPC transport | Not supported by design for this work. | The AgentCard does not advertise gRPC, and the CLI/API should use `JSONRPC` or `HTTP+JSON`. | | Push notifications | Not implemented. | The AgentCard advertises `pushNotifications=false`; SDK push configuration methods return the protocol's not-supported error. Streaming and polling remain available. | | Extended AgentCard | Not implemented. | The server publishes the public AgentCard only and does not configure `extendedAgentCard`. | -| Authentication/security schemes on served AgentCards | Supported for Hugging Face bearer auth and OAuth/OIDC clients | Remote clients can pass headers when connecting to other A2A agents. When `FAST_AGENT_SERVE_OAUTH=huggingface` is set, serving fast-agent over A2A advertises an `hf_bearer` HTTP bearer security scheme, requires bearer auth on A2A action routes, accepts `Authorization` and `X-HF-Authorization`, and passes the bearer token into fast-agent request context. A2A clients reuse the existing browser OAuth flow when a remote AgentCard advertises OAuth2 or OpenID Connect security schemes, with `auth.oauth` and `/a2a connect --oauth/--no-oauth` controls. In-task provider auth failures are reported as `AUTH_REQUIRED`. | +| Authentication/security schemes on served AgentCards | Supported for Hugging Face bearer auth and OAuth/OIDC clients | Remote clients can pass headers when connecting to other A2A agents. When `FAST_AGENT_SERVE_OAUTH=huggingface` is set, serving fast-agent over A2A advertises an `hf_bearer` HTTP bearer security scheme, requires bearer auth on A2A action routes, accepts `Authorization` and also accepts `X-HF-Authorization` when deployment ingress forwards it, and passes the bearer token into fast-agent request context. A2A clients reuse the existing browser OAuth flow when a remote AgentCard advertises OAuth2 or OpenID Connect security schemes, with `auth.oauth` and `/a2a connect --oauth/--no-oauth` controls. In-task provider auth failures are reported as `AUTH_REQUIRED`. | | Typed audio content on the server | Partial. | The client can send `AudioContent` as raw A2A parts. The server preserves inbound audio bytes as blob resources rather than mapping them to a dedicated fast-agent `AudioContent` object. | | Structured JSON output from model text | Partial. | fast-agent JSON text responses remain text artifacts unless represented as `TextResourceContents` with `mimeType="application/json"`. This avoids guessing whether ordinary text is intended to be protocol data. | | Persistent task/session storage | In-memory only. | The server uses the SDK `InMemoryTaskStore` and fast-agent in-memory context instances. Restarting the server loses A2A task state and context-bound fast-agent sessions. | @@ -47,7 +47,8 @@ The deterministic A2A integration suite exercises: - fresh A2A context/task state for `use_history=False` turns, except while continuing an `INPUT_REQUIRED` task; - A2A server `shared`, `connection`, and `request` instance scopes; -- AgentCard skill advertisement and skill routing via message metadata; +- AgentCard skill advertisement and fast-agent-specific routing via message + metadata; - streaming artifact updates delivered to the fast-agent client stream listener; - artifact replacement and append semantics on the client; - `TASK_STATE_INPUT_REQUIRED` preservation and follow-up completion; @@ -58,8 +59,7 @@ The deterministic A2A integration suite exercises: - cancellation, task retrieval/listing after cancellation, and protocol error paths via SDK-backed handlers. - Hugging Face bearer auth route protection, AgentCard security metadata, - `Authorization`/`X-HF-Authorization` token propagation, and client-side HF - auth header application. + saved request-token propagation, and client-side HF auth header application. - A2A client OAuth activation for OAuth/OIDC AgentCards, `auth.oauth: false` suppression, checked-in AgentCard auth parsing, and TUI `--oauth/--no-oauth` parsing. diff --git a/docs/docs/a2a/server.md b/docs/docs/a2a/server.md index 3e020d6ef..7db8687c1 100644 --- a/docs/docs/a2a/server.md +++ b/docs/docs/a2a/server.md @@ -5,11 +5,11 @@ description: Deploy fast-agent agents as an Agent2Agent (A2A) HTTP server. # A2A Server -Use `fast-agent serve a2a` to expose fast-agent agents through A2A HTTP +Use `fast-agent serve a2a` to expose a fast-agent app through A2A HTTP transports. `fast-agent serve --transport a2a` remains supported for parity with the generic MCP/ACP serve command. The configured fast-agent app is initialized -first, then the A2A server routes incoming protocol messages into the selected -agent. +first, then the A2A server routes ordinary protocol messages into the +fast-agent default agent. ## Start a Server @@ -85,20 +85,24 @@ remote clients should use. ## Runtime Wiring -The served agents use the normal fast-agent runtime. AgentCards, MCP servers, +The served A2A agent uses the normal fast-agent runtime. AgentCards, MCP servers, tools, skills, hooks, model settings, and workflow agents are loaded through the same path used by the CLI and TUI before the A2A server starts. -That means an A2A request can drive a full fast-agent bundle: an orchestrator, -router, tool-using agent, MCP-backed agent, or AgentCard-loaded group. +That means an A2A request can drive a full fast-agent bundle behind one A2A +agent boundary: an orchestrator, router, tool-using agent, MCP-backed agent, or +AgentCard-loaded group. ## Agent Skills in the A2A Card -A2A `AgentSkill` is the protocol's advertised capability object. It is separate -from fast-agent "skills" on disk. +A2A models the served endpoint as one remote agent or agentic system. A2A +`AgentSkill` entries are advertised capabilities for that remote agent; they are +not a standard routing table and do not make multiple directly addressable +agents at the same endpoint. A2A `AgentSkill` is also separate from fast-agent +"skills" on disk. -fast-agent currently exposes one A2A `AgentSkill` for each loaded fast-agent -agent: +fast-agent advertises loaded user-facing fast-agent agents as A2A skills so +clients can understand the capabilities available behind the endpoint: ```json { @@ -112,13 +116,18 @@ agent: } ``` -The generated skill list comes from `primary_instance.agents` at server startup. -The skill `id` and `name` are the fast-agent agent name. The description uses the -agent's configured `description` when present, otherwise fast-agent generates a -generic description. Tags include `fast-agent` and the fast-agent agent type. +The generated skill list comes from the user-facing fast-agent agents loaded at +server startup. The skill `id` and `name` are derived from the fast-agent agent +name. The description uses the agent's configured `description` when present, +otherwise fast-agent generates a generic description. Tags include `fast-agent` +and the fast-agent agent type. -By default, messages route to the fast-agent default agent. A2A clients can -target a specific loaded agent with message metadata: +Messages route to the fast-agent default agent by default. That default agent +should orchestrate, delegate, or call helper agents internally just as it would +in normal fast-agent use. + +For fast-agent-to-fast-agent integrations, the server also accepts a +fast-agent-specific routing extension in message metadata: ```json { @@ -128,7 +137,9 @@ target a specific loaded agent with message metadata: } ``` -`fast_agent_agent` is accepted as an equivalent metadata key. +`fast_agent_agent` is accepted as an equivalent metadata key. This metadata is +not portable A2A behavior; generic A2A clients should treat skills as capability +metadata and send normal messages to the endpoint. Current limitation: examples are still generic, and mode lists describe the server-wide MIME-style content support rather than deriving per-agent modality @@ -204,18 +215,21 @@ Set `FAST_AGENT_SERVE_OAUTH=huggingface` before starting `fast-agent serve a2a` to require bearer authentication on `/a2a/jsonrpc` and `/a2a/rest` while keeping the public AgentCard discoverable. -The A2A server accepts both: +The A2A server middleware accepts both header names when they reach the app: ```text Authorization: Bearer X-HF-Authorization: Bearer ``` -The Hugging Face header form is useful on Spaces. The server advertises an -`hf_bearer` HTTP bearer security scheme in the AgentCard and stores the inbound -token in fast-agent request context while the agent runs, allowing Hugging Face -Inference Provider models and Hugging Face MCP/tools to use the caller -credential. +For Space-hosted A2A endpoints, clients should use `Authorization` through +`--auth`, explicit AgentCard headers, or OAuth. `X-HF-Authorization` is the +ambient fast-agent CLI policy for ordinary Space app calls; it is not a +substitute for endpoint bearer auth unless the deployment ingress passes that +header through to the app. The server advertises an `hf_bearer` HTTP bearer +security scheme in the AgentCard and stores the inbound token in fast-agent +request context while the agent runs, allowing Hugging Face Inference Provider +models and Hugging Face MCP/tools to use the caller credential. See [Host A2A on Hugging Face](host-on-hf.md) for a Space-oriented setup. From c0bf3fbfd890c3a86143c73dc5ed9b99bf115035 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Thu, 21 May 2026 21:45:55 +0100 Subject: [PATCH 47/58] commit latest --- docs/docs/ref/go_command.md | 11 +- pyproject.toml | 2 +- src/fast_agent/a2a/remote_agent.py | 69 +++++++- src/fast_agent/a2a/server.py | 72 ++++++-- src/fast_agent/cli/commands/README.md | 13 +- src/fast_agent/cli/commands/go.py | 14 ++ src/fast_agent/cli/shared_options.py | 2 +- src/fast_agent/config.py | 7 + src/fast_agent/mcp/hf_auth.py | 140 +++++++++++++--- src/fast_agent/mcp/mcp_aggregator.py | 19 ++- src/fast_agent/mcp/mcp_connection_manager.py | 15 ++ src/fast_agent/mcp/provider_management.py | 4 +- .../ui/prompt/completion_sources.py | 2 +- .../a2a/test_fast_agent_a2a_server.py | 111 +++++++++++++ .../fast_agent/cli/test_a2a_go_options.py | 15 ++ tests/unit/fast_agent/mcp/test_hf_auth.py | 47 ++++-- .../mcp/test_mcp_aggregator_nonpersistent.py | 68 +++++++- .../mcp/test_mcp_connection_manager.py | 74 ++++++++- .../test_a2a_remote_agent_config.py | 155 +++++++++++++++++- uv.lock | 2 +- 20 files changed, 762 insertions(+), 80 deletions(-) diff --git a/docs/docs/ref/go_command.md b/docs/docs/ref/go_command.md index 4b6ec2fc8..c13cfd199 100644 --- a/docs/docs/ref/go_command.md +++ b/docs/docs/ref/go_command.md @@ -28,7 +28,7 @@ fast-agent go [OPTIONS] - `--config-path`, `-c `: Path, HTTP(S) URL, `file://` URI, or `hf://` URI to config file - `--servers ,`: Comma-separated list of server names to enable from config - `--url TEXT`: Comma-separated list of HTTP/SSE URLs to connect to directly -- `--auth TEXT`: Bearer token for authorization with URL-based servers +- `--auth TEXT`: Bearer token for authorization with remote MCP URL servers and A2A endpoints - `--model`, `--models `: Override the default model (e.g., haiku, sonnet, gpt-4) - `--model`, `--models ,,...`: Run one agent per model in parallel and print a side-by-side comparison of responses - `--pack`, `--card-pack `: Ensure a named card pack is installed in the selected environment before starting @@ -273,8 +273,11 @@ The `--url` parameter allows you to connect directly to HTTP or SSE servers usin ### Authentication -The `--auth` parameter provides authentication for URL-based servers: +The `--auth` parameter provides authentication for remote connections created by +the CLI: -- When provided, it creates an `Authorization: Bearer TOKEN` header for all URL-based servers -- This is commonly used with API endpoints that require authentication +- For `--url`, it creates an `Authorization: Bearer TOKEN` header for all URL-based MCP servers +- For `--a2a`, it creates an `Authorization: Bearer TOKEN` header for all generated ad hoc A2A AgentCards +- This is a convenience flag for simple runs where the same credential applies to every remote endpoint +- Use checked-in config or AgentCards when different remote endpoints need different credentials - Example: `fast-agent go --url=https://api.example.com/mcp --auth=12345abcde` diff --git a/pyproject.toml b/pyproject.toml index d68b53703..9ca4b5dbd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "fast-agent-mcp" -version = "0.7.8" +version = "0.7.9" description = "Define, Prompt and Test MCP enabled Agents and Workflows" readme = "README.md" license = { file = "LICENSE" } diff --git a/src/fast_agent/a2a/remote_agent.py b/src/fast_agent/a2a/remote_agent.py index ca84a7b1d..561de5139 100644 --- a/src/fast_agent/a2a/remote_agent.py +++ b/src/fast_agent/a2a/remote_agent.py @@ -29,7 +29,12 @@ from fast_agent.core.logging.logger import get_logger from fast_agent.event_progress import ProgressAction from fast_agent.llm.stream_types import StreamChunk -from fast_agent.mcp.hf_auth import add_hf_auth_header +from fast_agent.mcp.hf_auth import ( + add_explicit_bearer_auth_header, + add_hf_auth_header, + get_hf_token_from_env, + is_hf_space_url, +) from fast_agent.mcp.oauth_client import build_oauth_provider from fast_agent.types import LlmStopReason, PromptMessageExtended, RequestParams from fast_agent.ui import console @@ -131,6 +136,20 @@ async def initialize(self) -> None: self.a2a_config.relative_card_path or "/.well-known/agent-card.json", ) self.remote_card = await resolver.get_agent_card() + card_headers = _headers_for_resolved_card( + url=self.a2a_config.url, + headers=headers, + explicit_headers=bool(self.a2a_config.headers), + card=self.remote_card, + ) + if card_headers != headers: + headers = card_headers + await self._httpx_client.aclose() + self._httpx_client = httpx.AsyncClient( + headers=headers or None, + timeout=self.a2a_config.request_timeout_seconds, + ) + client_config.httpx_client = self._httpx_client oauth_provider = self._build_oauth_provider_for_card(self.remote_card) if oauth_provider is not None: await self._httpx_client.aclose() @@ -174,10 +193,20 @@ def _build_oauth_provider_for_card(self, card: AgentCard) -> Any | None: auth_config = self.a2a_config.auth if auth_config is not None and not auth_config.oauth: return None - if auth_config is None and not _card_advertises_oauth(card): + hf_space_bearer = is_hf_space_url(self.a2a_config.url) and _card_advertises_http_bearer( + card + ) + if auth_config is None and not (_card_advertises_oauth(card) or hf_space_bearer): return None if self.a2a_config.headers: return None + if _headers_for_resolved_card( + url=self.a2a_config.url, + headers=None, + explicit_headers=False, + card=card, + ): + return None return build_oauth_provider( cast( "MCPServerSettings", @@ -499,6 +528,42 @@ def _card_advertises_oauth(card: AgentCard) -> bool: return False +def _card_advertises_http_bearer(card: AgentCard) -> bool: + if not card.security_schemes or not card.security_requirements: + return False + required_scheme_names = { + scheme_name + for requirement in card.security_requirements + for scheme_name in requirement.schemes + } + for scheme_name in required_scheme_names: + scheme = card.security_schemes.get(scheme_name) + if scheme is None: + continue + if not scheme.HasField("http_auth_security_scheme"): + continue + http_scheme = scheme.http_auth_security_scheme.scheme + if http_scheme.lower() == "bearer": + return True + return False + + +def _headers_for_resolved_card( + *, + url: str, + headers: dict[str, str] | None, + explicit_headers: bool, + card: AgentCard, +) -> dict[str, str] | None: + if explicit_headers or not is_hf_space_url(url) or not _card_advertises_http_bearer(card): + return headers + + token = get_hf_token_from_env() + if not token: + return None + return add_explicit_bearer_auth_header(url, None, token) + + def _latest_text(messages: Sequence[PromptMessageExtended]) -> str: for message in reversed(messages): text = message.all_text() diff --git a/src/fast_agent/a2a/server.py b/src/fast_agent/a2a/server.py index a288f4494..e5a961413 100644 --- a/src/fast_agent/a2a/server.py +++ b/src/fast_agent/a2a/server.py @@ -18,6 +18,7 @@ from a2a.server.request_handlers import DefaultRequestHandler from a2a.server.request_handlers.response_helpers import agent_card_to_dict from a2a.server.routes import create_agent_card_routes, create_jsonrpc_routes, create_rest_routes +from a2a.server.routes.common import DefaultServerCallContextBuilder from a2a.server.tasks.inmemory_task_store import InMemoryTaskStore from a2a.server.tasks.task_updater import TaskUpdater from a2a.types import ( @@ -111,6 +112,10 @@ def _bearer_token_from_header(value: str | None) -> str | None: def _bearer_token_from_call_context(context: RequestContext) -> str | None: + saved_token = context.call_context.state.get("fast_agent_bearer_token") + if isinstance(saved_token, str) and saved_token: + return saved_token + headers = context.call_context.state.get("headers") if not isinstance(headers, dict): return None @@ -164,6 +169,9 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: await response(scope, receive, send) return + state = dict(scope.get("state") or {}) + state["fast_agent_bearer_token"] = token + scope = dict(scope, state=state) await self.app(scope, receive, send) @@ -174,6 +182,17 @@ def _header_value(headers: list[tuple[bytes, bytes]], name: bytes) -> str | None return None +class A2AServerCallContextBuilder(DefaultServerCallContextBuilder): + """Build A2A call context while preserving fast-agent request auth state.""" + + def build(self, request: Request) -> Any: + context = super().build(request) + token = getattr(request.state, "fast_agent_bearer_token", None) + if isinstance(token, str) and token: + context.state["fast_agent_bearer_token"] = token + return context + + class FastAgentA2AExecutor(AgentExecutor): """A2A executor that routes tasks into fast-agent agents.""" @@ -245,17 +264,19 @@ async def _execute(self, context: RequestContext, event_queue: EventQueue) -> No lock = await self._context_lock(self._lock_key(context)) async with lock: - instance = await self._acquire_instance(context.context_id) + saved_bearer_token = request_bearer_token.set( + _bearer_token_from_call_context(context) + ) + instance: AgentInstance | None = None try: - agent = self._select_agent(instance, context.message) - stream_context = self._prepare_streaming_context( - agent=agent, - updater=updater, - ) - saved_bearer_token = request_bearer_token.set( - _bearer_token_from_call_context(context) - ) + instance = await self._acquire_instance(context.context_id) + stream_context: _A2AStreamingContext | None = None try: + agent = self._select_agent(instance, context.message) + stream_context = self._prepare_streaming_context( + agent=agent, + updater=updater, + ) response = await agent.generate( _prompt_from_a2a_message(context.message), ) @@ -273,13 +294,15 @@ async def _execute(self, context: RequestContext, event_queue: EventQueue) -> No ) return finally: - request_bearer_token.reset(saved_bearer_token) - await self._cleanup_streaming_context(stream_context) + if stream_context is not None: + await self._cleanup_streaming_context(stream_context) finally: - await self._release_instance( - context.context_id, - instance, - ) + request_bearer_token.reset(saved_bearer_token) + if instance is not None: + await self._release_instance( + context.context_id, + instance, + ) streamed_text = stream_context.streamed_text() response_text = response.all_text() @@ -473,12 +496,21 @@ def __init__( def asgi_app(self) -> FastAPI: app = FastAPI(title=self.agent_card.name) + context_builder = A2AServerCallContextBuilder() app.routes.extend(_agent_card_routes(self.agent_card, host=self._host, port=self._port)) app.routes.extend( - create_jsonrpc_routes(request_handler=self.request_handler, rpc_url="/a2a/jsonrpc") + create_jsonrpc_routes( + request_handler=self.request_handler, + rpc_url="/a2a/jsonrpc", + context_builder=context_builder, + ) ) app.routes.extend( - create_rest_routes(request_handler=self.request_handler, path_prefix="/a2a/rest") + create_rest_routes( + request_handler=self.request_handler, + path_prefix="/a2a/rest", + context_builder=context_builder, + ) ) if self._oauth_provider == "huggingface": app.add_middleware(A2ABearerAuthMiddleware, provider=self._oauth_provider) @@ -562,7 +594,11 @@ def _agent_card_routes(agent_card: AgentCard, *, host: str, port: int) -> list[A from starlette.routing import Route async def _get_agent_card(request: "Request") -> JSONResponse: - base_url = str(request.base_url).rstrip("/") + base_url = ( + os.environ.get("FAST_AGENT_PUBLIC_URL") + or os.environ.get("FAST_AGENT_OAUTH_RESOURCE_URL") + or str(request.base_url) + ).rstrip("/") return JSONResponse(agent_card_to_dict(_agent_card_with_base_url(agent_card, base_url))) return [ diff --git a/src/fast_agent/cli/commands/README.md b/src/fast_agent/cli/commands/README.md index 29db4ae33..5e72c38b3 100644 --- a/src/fast_agent/cli/commands/README.md +++ b/src/fast_agent/cli/commands/README.md @@ -20,7 +20,7 @@ fast-agent go [OPTIONS] - `--config-path`, `-c `: Path, HTTP(S) URL, `file://` URI, or `hf://` URI to config file - `--servers TEXT`: Comma-separated list of server names to enable from config - `--url TEXT`: Comma-separated list of HTTP/SSE URLs to connect to directly -- `--auth TEXT`: Bearer token for authorization with URL-based servers +- `--auth TEXT`: Bearer token for authorization with remote MCP URL servers and A2A endpoints - `--client-metadata-url TEXT`: OAuth Client ID Metadata Document URL for URL-based servers - `--model TEXT`: Override the default model (e.g., haiku, sonnet, gpt-4) - `--pack`, `--card-pack TEXT`: Install or reuse a named card pack in the selected environment before launch @@ -83,10 +83,13 @@ The `--url` parameter allows you to connect directly to HTTP or SSE servers usin ### Authentication -The `--auth` parameter provides authentication for URL-based servers: +The `--auth` parameter provides authentication for remote connections created by +the CLI: -- When provided, it creates an `Authorization: Bearer TOKEN` header for all URL-based servers -- This is commonly used with API endpoints that require authentication +- For `--url`, it creates an `Authorization: Bearer TOKEN` header for all URL-based MCP servers +- For `--a2a`, it creates an `Authorization: Bearer TOKEN` header for all generated ad hoc A2A AgentCards +- This is a convenience flag for simple runs where the same credential applies to every remote endpoint +- Use checked-in config or AgentCards when different remote endpoints need different credentials - Example: `fast-agent go --url=https://api.example.com/mcp --auth=12345abcde` ## Serve Command @@ -107,7 +110,7 @@ fast-agent serve [OPTIONS] - `--servers TEXT`: Comma-separated list of server names to enable from config - `--card`, `--agent-cards `: Path, HTTP(S) URL, `file://` URI, or `hf://` URI to an AgentCard file or directory (repeatable) - `--url TEXT`: Comma-separated list of HTTP/SSE URLs to connect to -- `--auth TEXT`: Bearer token for authorization with URL-based servers +- `--auth TEXT`: Bearer token for authorization with remote MCP URL servers and A2A endpoints - `--client-metadata-url TEXT`: OAuth Client ID Metadata Document URL for URL-based servers - `--model TEXT`: Override the default model (e.g., haiku, sonnet, gpt-4) - `--skills-dir`, `--skills PATH`: Override the default skills directory diff --git a/src/fast_agent/cli/commands/go.py b/src/fast_agent/cli/commands/go.py index 3e5c46a10..1ce10721b 100644 --- a/src/fast_agent/cli/commands/go.py +++ b/src/fast_agent/cli/commands/go.py @@ -47,6 +47,7 @@ from fast_agent.cli.update_check import check_for_update_notice, should_run_update_check from fast_agent.constants import FAST_AGENT_SHELL_CHILD_ENV from fast_agent.core.exceptions import AgentConfigError +from fast_agent.mcp.hf_auth import add_explicit_bearer_auth_header from fast_agent.paths import resolve_environment_paths CARD_EXTENSIONS = _CARD_EXTENSIONS @@ -104,6 +105,7 @@ def _materialize_a2a_agent_cards( *, transport: str | None, oauth: bool | None = None, + auth_token: str | None = None, ) -> tuple[tempfile.TemporaryDirectory[str], list[str]]: normalized_transport = None if transport: @@ -127,6 +129,17 @@ def _materialize_a2a_agent_cards( f"name: {name}", f"url: {url}", ] + if auth_token: + normalized_token = auth_token.strip() + if normalized_token.lower().startswith("bearer "): + normalized_token = normalized_token[7:].strip() + if not normalized_token: + tempdir.cleanup() + raise typer.BadParameter("Auth token cannot be empty", param_hint="--auth") + headers = add_explicit_bearer_auth_header(url, None, normalized_token) + lines.append("headers:") + for key, value in headers.items(): + lines.append(f" {key}: {value!r}") if normalized_transport: lines.append(f"transport: {normalized_transport}") if oauth is not None: @@ -525,6 +538,7 @@ def go( a2a, transport=a2a_transport, oauth=a2a_oauth, + auth_token=auth, ) agent_cards = [*(agent_cards or []), *a2a_cards] if agent is None and len(a2a_cards) == 1: diff --git a/src/fast_agent/cli/shared_options.py b/src/fast_agent/cli/shared_options.py index 01d884373..69ceaa019 100644 --- a/src/fast_agent/cli/shared_options.py +++ b/src/fast_agent/cli/shared_options.py @@ -59,7 +59,7 @@ def auth(): None, "--auth", help=( - "Authorization token value for URL-based servers " + "Authorization token value for remote MCP URL servers and A2A endpoints " "(pass token only; optional 'Bearer ' prefix is accepted)" ), ) diff --git a/src/fast_agent/config.py b/src/fast_agent/config.py index 722443297..465c0a7bd 100644 --- a/src/fast_agent/config.py +++ b/src/fast_agent/config.py @@ -51,6 +51,10 @@ class MCPServerAuthSettings(BaseModel): # and escalates to OAuth on a 401 challenge. oauth: bool = True + # Forward the inbound request bearer token to matching upstream services. + # "huggingface" applies only to hf.co, huggingface.co, and *.hf.space URLs. + forward: Literal["huggingface"] | None = None + # Local callback server configuration redirect_port: int = 3030 redirect_path: str = "/callback" @@ -568,6 +572,9 @@ def _normalize_management_specific_settings(self) -> "MCPServerSettings": url=self.url, headers=self.headers, access_token=self.access_token, + forward_huggingface=( + self.auth is not None and self.auth.forward == "huggingface" + ), ) return self diff --git a/src/fast_agent/mcp/hf_auth.py b/src/fast_agent/mcp/hf_auth.py index 715448cc3..b9c1ba769 100644 --- a/src/fast_agent/mcp/hf_auth.py +++ b/src/fast_agent/mcp/hf_auth.py @@ -1,13 +1,16 @@ -"""HuggingFace authentication utilities for MCP connections.""" +"""HuggingFace authentication utilities for hosted and remote connections.""" import os from collections.abc import Callable +from dataclasses import dataclass +from typing import Literal from urllib.parse import urlparse from fast_agent.utils.huggingface_hub import get_huggingface_hub_token # Type alias for token provider functions TokenProvider = Callable[[], str | None] +HFAuthHeader = Literal["Authorization", "X-HF-Authorization"] def _default_hub_token_provider() -> str | None: @@ -58,6 +61,17 @@ def is_huggingface_url(url: str) -> bool: return False +def is_hf_space_url(url: str) -> bool: + """Return True when ``url`` is a validated Hugging Face Space hostname.""" + if not is_huggingface_url(url): + return False + try: + hostname = urlparse(url).hostname + except Exception: + return False + return bool(hostname and hostname.endswith(".hf.space")) + + def get_hf_token_from_env( hub_token_provider: TokenProvider | None = None, ) -> str | None: @@ -82,6 +96,69 @@ def get_hf_token_from_env( return provider() +def _has_auth_header(headers: dict[str, str] | None) -> bool: + if not headers: + return False + return any(key.lower() in {"authorization", "x-hf-authorization"} for key in headers) + + +def _bearer(value: str) -> str: + return f"Bearer {value}" + + +@dataclass(frozen=True) +class HuggingFaceAuthPolicy: + """Policy for attaching Hugging Face bearer credentials to outbound requests. + + The policies below intentionally keep ambient Hugging Face credentials separate + from explicit server authentication. Ambient HF tokens use X-HF-Authorization + for Spaces so they can be consumed by Space apps without taking over app-level + Authorization. Explicit auth, including --auth and OAuth challenges, uses the + standard Authorization header because it is authenticating to that endpoint. + """ + + hf_space_header: HFAuthHeader + + def add_ambient_hf_token( + self, + url: str, + headers: dict[str, str] | None, + hub_token_provider: TokenProvider | None = None, + ) -> dict[str, str] | None: + if not is_huggingface_url(url) or _has_auth_header(headers): + return headers + + hf_token = get_hf_token_from_env(hub_token_provider) + if hf_token is None: + return headers + + return self.add_bearer_token(url, headers, hf_token) + + def add_bearer_token( + self, + url: str, + headers: dict[str, str] | None, + token: str, + ) -> dict[str, str]: + result_headers = dict(headers) if headers else {} + result_headers[self.header_for_url(url)] = _bearer(token) + return result_headers + + def header_for_url(self, url: str) -> HFAuthHeader: + return self.hf_space_header if is_hf_space_url(url) else "Authorization" + + +HF_CLI_AMBIENT_AUTH_POLICY = HuggingFaceAuthPolicy( + hf_space_header="X-HF-Authorization", +) +HF_EXPLICIT_BEARER_AUTH_POLICY = HuggingFaceAuthPolicy( + hf_space_header="Authorization", +) +HF_REQUEST_PASSTHROUGH_AUTH_POLICY = HuggingFaceAuthPolicy( + hf_space_header="X-HF-Authorization", +) + + def should_add_hf_auth( url: str, existing_headers: dict[str, str] | None, @@ -108,9 +185,8 @@ def should_add_hf_auth( return False # Don't add auth if Authorization or X-HF-Authorization already present - if existing_headers: - if "Authorization" in existing_headers or "X-HF-Authorization" in existing_headers: - return False + if _has_auth_header(existing_headers): + return False return get_hf_token_from_env(hub_token_provider) is not None @@ -132,30 +208,44 @@ def add_hf_auth_header( Returns: Updated headers dictionary with HF auth if appropriate, or original headers """ - if not should_add_hf_auth(url, headers, hub_token_provider): + return HF_CLI_AMBIENT_AUTH_POLICY.add_ambient_hf_token( + url, + headers, + hub_token_provider, + ) + + +def add_explicit_bearer_auth_header( + url: str, + headers: dict[str, str] | None, + token: str, +) -> dict[str, str]: + """Add explicit bearer auth for a target endpoint. + + This is the policy behind ``--auth`` and OAuth-managed A2A/MCP endpoints. + It uses Authorization even for ``*.hf.space`` because the credential is for + the target server itself rather than an ambient HF token for a Space app. + """ + return HF_EXPLICIT_BEARER_AUTH_POLICY.add_bearer_token(url, headers, token) + + +def add_forwarded_hf_auth_header(url: str, headers: dict[str, str] | None) -> dict[str, str] | None: + """Add the request-scoped bearer token to Hugging Face URLs. + + This is intended for hosted agents that should call Hugging Face services as the + inbound user rather than as the Space/server process. Existing auth headers are + preserved. + """ + if not is_huggingface_url(url): return headers - hf_token = get_hf_token_from_env(hub_token_provider) - if hf_token is None: + if _has_auth_header(headers): return headers - # Create new headers dict or copy existing one - result_headers = dict(headers) if headers else {} + from fast_agent.mcp.auth.context import request_bearer_token - try: - parsed = urlparse(url) - hostname = parsed.hostname - if hostname and hostname.endswith(".hf.space"): - # For .hf.space domains, send BOTH headers: - # - Authorization: for the app's OAuth (HF infra doesn't consume this) - # - X-HF-Authorization: for HF infrastructure (inference credit tracking) - result_headers["Authorization"] = f"Bearer {hf_token}" - result_headers["X-HF-Authorization"] = f"Bearer {hf_token}" - else: - # For other HF domains, use standard Authorization header - result_headers["Authorization"] = f"Bearer {hf_token}" - except Exception: - # Fallback to standard Authorization header - result_headers["Authorization"] = f"Bearer {hf_token}" + token = request_bearer_token.get() + if not token: + return headers - return result_headers + return HF_REQUEST_PASSTHROUGH_AUTH_POLICY.add_bearer_token(url, headers, token) diff --git a/src/fast_agent/mcp/mcp_aggregator.py b/src/fast_agent/mcp/mcp_aggregator.py index 800ed9f77..d00f33cf0 100644 --- a/src/fast_agent/mcp/mcp_aggregator.py +++ b/src/fast_agent/mcp/mcp_aggregator.py @@ -53,6 +53,7 @@ resolve_model_spec, ) from fast_agent.event_progress import ProgressAction +from fast_agent.mcp.auth.context import request_bearer_token from fast_agent.mcp.common import SEP, create_namespaced_name, is_namespaced_name from fast_agent.mcp.experimental_session_client import ExperimentalSessionClient from fast_agent.mcp.gen_client import gen_client @@ -436,6 +437,20 @@ def _require_server_registry(self) -> ServerRegistryProtocol: raise RuntimeError("Context is missing server registry for MCP connections") return cast("ServerRegistryProtocol", server_registry) + def _should_use_request_scoped_connection(self, server_name: str) -> bool: + """Use a fresh MCP transport when auth.forward depends on request context.""" + if not request_bearer_token.get(): + return False + try: + config = self._require_server_registry().get_server_config(server_name) + except Exception: + return False + return ( + config is not None + and config.auth is not None + and config.auth.forward == "huggingface" + ) + def _require_connection_manager(self) -> MCPConnectionManager: if self._persistent_connection_manager is None: raise RuntimeError("Persistent connection manager is not initialized") @@ -1732,7 +1747,9 @@ async def try_execute(client: ClientSession): # Try initial execution try: - if self.connection_persistence: + if self.connection_persistence and not self._should_use_request_scoped_connection( + server_name + ): manager = self._require_connection_manager() server_connection = await manager.get_server( server_name, client_session_factory=self._create_session_factory(server_name) diff --git a/src/fast_agent/mcp/mcp_connection_manager.py b/src/fast_agent/mcp/mcp_connection_manager.py index d8b2d33d5..82ffbdbb9 100644 --- a/src/fast_agent/mcp/mcp_connection_manager.py +++ b/src/fast_agent/mcp/mcp_connection_manager.py @@ -36,6 +36,7 @@ from fast_agent.core.logging.logger import get_logger from fast_agent.event_progress import ProgressAction from fast_agent.home import build_child_environment +from fast_agent.mcp.hf_auth import add_forwarded_hf_auth_header from fast_agent.mcp.interfaces import ClientSessionFactory from fast_agent.mcp.logger_textio import get_stderr_handler from fast_agent.mcp.mcp_agent_client_session import MCPAgentClientSession @@ -112,6 +113,18 @@ def _prepare_headers_and_auth( auth_header_keys = {"authorization", "x-hf-authorization"} user_provided_auth_keys = {key for key in headers if key.lower() in auth_header_keys} + if ( + server_config.auth is not None + and server_config.auth.forward == "huggingface" + and server_config.url + and not user_provided_auth_keys + ): + headers = add_forwarded_hf_auth_header(server_config.url, headers) or {} + user_provided_auth_keys = {key for key in headers if key.lower() in auth_header_keys} + + if server_config.auth is not None and server_config.auth.forward == "huggingface": + return headers, None, user_provided_auth_keys + # OAuth is only relevant for SSE/HTTP transports and should be skipped when the # user has already supplied explicit Authorization headers. if not trigger_oauth or server_config.transport not in ("sse", "http") or user_provided_auth_keys: @@ -147,6 +160,8 @@ def _resolve_oauth_mode( if trigger_oauth is False: return "disabled" auth_config = server_config.auth + if auth_config is not None and auth_config.forward == "huggingface": + return "disabled" if auth_config is not None and auth_config.oauth is False: return "disabled" if trigger_oauth is True: diff --git a/src/fast_agent/mcp/provider_management.py b/src/fast_agent/mcp/provider_management.py index 748d4a7b6..f348b747c 100644 --- a/src/fast_agent/mcp/provider_management.py +++ b/src/fast_agent/mcp/provider_management.py @@ -39,6 +39,7 @@ def normalize_client_managed_url_server( url: str, headers: Mapping[str, str] | None, access_token: str | None, + forward_huggingface: bool = False, ) -> tuple[str, dict[str, str] | None]: final_headers = dict(headers) if headers else None @@ -55,7 +56,8 @@ def normalize_client_managed_url_server( if transport == "http": _server_name, _transport, final_url = parse_server_url(url) - final_headers = add_hf_auth_header(final_url, final_headers) + if not forward_huggingface: + final_headers = add_hf_auth_header(final_url, final_headers) return final_url, final_headers or None diff --git a/src/fast_agent/ui/prompt/completion_sources.py b/src/fast_agent/ui/prompt/completion_sources.py index 13abbaaa6..caf22916e 100644 --- a/src/fast_agent/ui/prompt/completion_sources.py +++ b/src/fast_agent/ui/prompt/completion_sources.py @@ -87,7 +87,7 @@ def _complete_attached_mcp_servers(completer: "AgentCompleter", partial: str) -> def _mcp_connect_completions(completer: "AgentCompleter", remainder: str) -> list[Completion]: connect_flags = { "--name": "set attached server name", - "--auth": "set bearer token for URL servers", + "--auth": "set bearer token for remote MCP/A2A", "--timeout": "set startup timeout in seconds", "--oauth": "enable oauth flow", "--no-oauth": "disable oauth flow", diff --git a/tests/integration/a2a/test_fast_agent_a2a_server.py b/tests/integration/a2a/test_fast_agent_a2a_server.py index 9549a8778..6152b4cab 100644 --- a/tests/integration/a2a/test_fast_agent_a2a_server.py +++ b/tests/integration/a2a/test_fast_agent_a2a_server.py @@ -3,6 +3,7 @@ import asyncio import contextlib from dataclasses import dataclass, field +from types import SimpleNamespace from typing import TYPE_CHECKING, Any, cast import httpx @@ -35,6 +36,7 @@ from fast_agent.a2a.remote_agent import A2ARemoteAgent from fast_agent.a2a.server import ( AgentA2AServer, + _bearer_token_from_call_context, _parts_from_prompt_message, _prompt_from_a2a_message, ) @@ -977,6 +979,39 @@ async def dispose_instance(instance: AgentInstance) -> None: } +@pytest.mark.integration +def test_fast_agent_a2a_server_uses_public_url_env_for_dynamic_card( + monkeypatch: pytest.MonkeyPatch, +) -> None: + agent = RecordingAgent(name="worker") + + async def create_instance() -> AgentInstance: + return _instance(RecordingAgent(name="worker")) + + async def dispose_instance(instance: AgentInstance) -> None: + del instance + + monkeypatch.setenv("FAST_AGENT_PUBLIC_URL", "https://agent.example") + server = AgentA2AServer( + primary_instance=_instance(agent), + create_instance=create_instance, + dispose_instance=dispose_instance, + server_name="fast-agent public URL test server", + host="0.0.0.0", + port=41241, + ) + + client = TestClient(server.asgi_app(), base_url="http://internal.example:41241") + response = client.get("/.well-known/agent-card.json") + response.raise_for_status() + + urls = {interface["url"] for interface in response.json()["supportedInterfaces"]} + assert urls == { + "https://agent.example/a2a/jsonrpc", + "https://agent.example/a2a/rest", + } + + @pytest.mark.integration def test_fast_agent_a2a_server_preserves_raw_file_input_parts() -> None: prompt = _prompt_from_a2a_message( @@ -1298,6 +1333,82 @@ async def dispose_instance(instance: AgentInstance) -> None: assert disposed +@pytest.mark.integration +@pytest.mark.asyncio +async def test_fast_agent_a2a_server_sets_bearer_token_before_instance_creation( + monkeypatch, + unused_tcp_port: int, + wait_for_port, +) -> None: + monkeypatch.setenv("FAST_AGENT_SERVE_OAUTH", "huggingface") + monkeypatch.setenv("FAST_AGENT_OAUTH_RESOURCE_URL", "http://127.0.0.1") + host = "127.0.0.1" + port = unused_tcp_port + tokens_seen: list[str | None] = [] + + async def create_instance() -> AgentInstance: + tokens_seen.append(request_bearer_token.get()) + return _instance(TokenEchoAgent(name="worker")) + + async def dispose_instance(instance: AgentInstance) -> None: + await instance.shutdown() + + server = AgentA2AServer( + primary_instance=_instance(TokenEchoAgent(name="worker")), + create_instance=create_instance, + dispose_instance=dispose_instance, + server_name="fast-agent auth early propagation test server", + host=host, + port=port, + instance_scope="request", + ) + uvicorn_server = uvicorn.Server( + uvicorn.Config(server.asgi_app(), host=host, port=port, log_level="warning") + ) + server_task = asyncio.create_task(uvicorn_server.serve()) + await wait_for_port(host, port, timeout=5.0) + + client = A2ARemoteAgent( + config=AgentConfig(name="remote_auth", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig( + url=f"http://{host}:{port}", + transport="JSONRPC", + headers={"Authorization": "Bearer request-token"}, + ), + ) + await client.initialize() + try: + response = await client.generate_impl( + [ + PromptMessageExtended( + role="user", + content=[TextContent(type="text", text="who am i")], + ) + ] + ) + finally: + await client.shutdown() + uvicorn_server.should_exit = True + await asyncio.wait_for(server_task, timeout=5.0) + await server.executor.shutdown() + + assert response.all_text() == "request-token" + assert tokens_seen == ["request-token"] + + +def test_bearer_token_from_call_context_prefers_saved_request_state() -> None: + context = SimpleNamespace( + call_context=SimpleNamespace( + state={ + "fast_agent_bearer_token": "saved-token", + "headers": {"authorization": "Bearer header-token"}, + } + ) + ) + + assert _bearer_token_from_call_context(cast("Any", context)) == "saved-token" + + async def _async_instance(agent: RecordingAgent) -> AgentInstance: return _instance(agent) diff --git a/tests/unit/fast_agent/cli/test_a2a_go_options.py b/tests/unit/fast_agent/cli/test_a2a_go_options.py index 9384378a3..bbc1f7ea2 100644 --- a/tests/unit/fast_agent/cli/test_a2a_go_options.py +++ b/tests/unit/fast_agent/cli/test_a2a_go_options.py @@ -26,6 +26,21 @@ def test_materialize_a2a_agent_card() -> None: tempdir.cleanup() +def test_materialize_a2a_agent_card_with_auth_uses_authorization_for_hf_space() -> None: + tempdir, paths = _materialize_a2a_agent_cards( + ["https://demo.hf.space"], + transport="jsonrpc", + auth_token="Bearer explicit-token", + ) + try: + text = Path(paths[0]).read_text(encoding="utf-8") + assert "headers:" in text + assert " Authorization: 'Bearer explicit-token'" in text + assert "X-HF-Authorization" not in text + finally: + tempdir.cleanup() + + def test_materialize_a2a_rejects_bad_transport() -> None: with pytest.raises(typer.BadParameter): _materialize_a2a_agent_cards(["http://127.0.0.1:41241"], transport="bogus") diff --git a/tests/unit/fast_agent/mcp/test_hf_auth.py b/tests/unit/fast_agent/mcp/test_hf_auth.py index 3e147a905..eff84fa95 100644 --- a/tests/unit/fast_agent/mcp/test_hf_auth.py +++ b/tests/unit/fast_agent/mcp/test_hf_auth.py @@ -7,8 +7,12 @@ import os from fast_agent.mcp.hf_auth import ( + HF_CLI_AMBIENT_AUTH_POLICY, + HF_EXPLICIT_BEARER_AUTH_POLICY, + add_explicit_bearer_auth_header, add_hf_auth_header, get_hf_token_from_env, + is_hf_space_url, is_huggingface_url, should_add_hf_auth, ) @@ -96,6 +100,10 @@ def test_hf_space_http(self): def test_hf_space_with_port(self): assert is_huggingface_url("https://space.hf.space:8080/path") is True + def test_is_hf_space_url_distinguishes_hub_domain(self): + assert is_hf_space_url("https://space.hf.space/api") is True + assert is_hf_space_url("https://huggingface.co/mcp?mix=jobs") is False + class TestGetHfTokenFromEnv: """Test HF_TOKEN environment variable retrieval.""" @@ -203,13 +211,11 @@ def test_adds_auth_header_for_huggingface_co(self): _restore_hf_token(original) def test_adds_x_hf_auth_header_for_hf_space(self): - """Test that .hf.space domains get both Authorization and X-HF-Authorization headers.""" + """Test that .hf.space domains get only X-HF-Authorization.""" original = _set_hf_token("test_token_123") try: result = add_hf_auth_header("https://myspace.hf.space/api", None) - # Both headers are needed: Authorization for the app, X-HF-Authorization for HF infra expected = { - "Authorization": "Bearer test_token_123", "X-HF-Authorization": "Bearer test_token_123", } assert result == expected @@ -237,11 +243,9 @@ def test_preserves_existing_headers_for_hf_space(self): try: existing = {"Content-Type": "application/json", "User-Agent": "test"} result = add_hf_auth_header("https://myspace.hf.space/api", existing) - # Both headers are needed: Authorization for the app, X-HF-Authorization for HF infra expected = { "Content-Type": "application/json", "User-Agent": "test", - "Authorization": "Bearer test_token_123", "X-HF-Authorization": "Bearer test_token_123", } assert result == expected @@ -293,21 +297,33 @@ def test_returns_none_when_no_token_available(self): finally: _restore_hf_token(original) - def test_case_sensitive_authorization_header(self): - """Test that Authorization header check is case-sensitive as per HTTP spec.""" + def test_lowercase_authorization_header_prevents_ambient_auth(self): original = _set_hf_token("test_token_123") try: - # Lower case 'authorization' should not prevent HF auth existing = {"authorization": "Bearer existing_token"} result = add_hf_auth_header("https://hf.co/models", existing) - expected = { - "authorization": "Bearer existing_token", - "Authorization": "Bearer test_token_123", - } - assert result == expected + assert result == existing finally: _restore_hf_token(original) + def test_explicit_bearer_auth_uses_authorization_for_hf_space(self): + result = add_explicit_bearer_auth_header("https://demo.hf.space/a2a/jsonrpc", None, "abc") + assert result == {"Authorization": "Bearer abc"} + + def test_policies_make_hf_space_header_choice_explicit(self): + assert ( + HF_CLI_AMBIENT_AUTH_POLICY.header_for_url("https://demo.hf.space/api") + == "X-HF-Authorization" + ) + assert ( + HF_EXPLICIT_BEARER_AUTH_POLICY.header_for_url("https://demo.hf.space/a2a/jsonrpc") + == "Authorization" + ) + assert ( + HF_CLI_AMBIENT_AUTH_POLICY.header_for_url("https://huggingface.co/mcp?mix=jobs") + == "Authorization" + ) + class TestHfSpaceAntiSpoofing: """Test comprehensive anti-spoofing measures for .hf.space domains.""" @@ -436,13 +452,10 @@ def test_hf_token_correctly_added_to_valid_hf_spaces(self): for url in valid_urls: result = add_hf_auth_header(url, None) assert result is not None, f"Should add auth to: {url}" - # Both headers are needed: Authorization for the app, X-HF-Authorization for HF infra assert result["X-HF-Authorization"] == "Bearer test_token_123", ( f"Incorrect X-HF-Authorization for: {url}" ) - assert result["Authorization"] == "Bearer test_token_123", ( - f"Incorrect Authorization for: {url}" - ) + assert "Authorization" not in result finally: _restore_hf_token(original) diff --git a/tests/unit/fast_agent/mcp/test_mcp_aggregator_nonpersistent.py b/tests/unit/fast_agent/mcp/test_mcp_aggregator_nonpersistent.py index bd4c38181..d32ae5dd7 100644 --- a/tests/unit/fast_agent/mcp/test_mcp_aggregator_nonpersistent.py +++ b/tests/unit/fast_agent/mcp/test_mcp_aggregator_nonpersistent.py @@ -5,6 +5,7 @@ import pytest from mcp.shared.exceptions import McpError from mcp.types import ( + CallToolResult, ErrorData, Implementation, InitializeResult, @@ -13,12 +14,14 @@ Prompt, PromptsCapability, ServerCapabilities, + TextContent, Tool, ToolsCapability, ) -from fast_agent.config import MCPServerSettings +from fast_agent.config import MCPServerAuthSettings, MCPServerSettings from fast_agent.context import Context +from fast_agent.mcp.auth.context import request_bearer_token from fast_agent.mcp.gen_client import gen_client from fast_agent.mcp.interfaces import ServerInitializerProtocol from fast_agent.mcp.mcp_aggregator import ( @@ -304,6 +307,69 @@ async def _fake_gen_client( assert trigger_history == [None, True] +@pytest.mark.asyncio +async def test_execute_on_server_uses_request_scoped_connection_for_forwarded_hf_auth( + monkeypatch, +) -> None: + context = _build_context( + { + "hf": MCPServerSettings( + name="hf", + transport="http", + url="https://huggingface.co/mcp", + auth=MCPServerAuthSettings(forward="huggingface"), + ) + } + ) + aggregator = MCPAggregator( + server_names=["hf"], + connection_persistence=True, + context=context, + ) + + class _PersistentManager: + async def get_server(self, *args, **kwargs): # noqa: ANN002, ANN003 + del args, kwargs + raise AssertionError("persistent connection must not be reused for forwarded auth") + + class _RequestClient: + async def call_tool(self, **kwargs): # noqa: ANN003 + del kwargs + return CallToolResult(content=[TextContent(type="text", text="ok")]) + + gen_client_calls: list[str] = [] + + @asynccontextmanager + async def _fake_gen_client( + server_name, + server_registry, + client_session_factory=_DummySession, + *, + trigger_oauth=None, + ): + del server_registry, client_session_factory, trigger_oauth + gen_client_calls.append(server_name) + yield _RequestClient() + + monkeypatch.setattr("fast_agent.mcp.mcp_aggregator.gen_client", _fake_gen_client) + aggregator._persistent_connection_manager = cast("MCPConnectionManager", _PersistentManager()) + + token = request_bearer_token.set("request-token") + try: + result = await aggregator._execute_on_server( + "hf", + "tools/call", + "hf_whoami", + "call_tool", + method_args={"name": "hf_whoami", "arguments": {}}, + ) + finally: + request_bearer_token.reset(token) + + assert isinstance(result, CallToolResult) + assert gen_client_calls == ["hf"] + + # --------------------------------------------------------------------------- # get_capabilities (non-persistent path) # --------------------------------------------------------------------------- diff --git a/tests/unit/fast_agent/mcp/test_mcp_connection_manager.py b/tests/unit/fast_agent/mcp/test_mcp_connection_manager.py index dc954c4b6..6d685037e 100644 --- a/tests/unit/fast_agent/mcp/test_mcp_connection_manager.py +++ b/tests/unit/fast_agent/mcp/test_mcp_connection_manager.py @@ -9,8 +9,9 @@ from anyio import create_task_group from mcp import ClientSession -from fast_agent.config import MCPServerSettings +from fast_agent.config import MCPServerAuthSettings, MCPServerSettings from fast_agent.core.exceptions import ServerInitializationError +from fast_agent.mcp.auth.context import request_bearer_token from fast_agent.mcp.interfaces import ClientSessionFactory from fast_agent.mcp.mcp_connection_manager import ( MCPConnectionManager, @@ -124,6 +125,77 @@ def _builder(_config, **_kwargs): assert user_keys == set() +def test_prepare_headers_forwards_hf_request_token() -> None: + config = MCPServerSettings( + name="test", + transport="http", + url="https://huggingface.co/mcp", + auth=MCPServerAuthSettings(forward="huggingface"), + ) + + saved_token = request_bearer_token.set("request-token") + try: + headers, auth, user_keys = _prepare_headers_and_auth(config, trigger_oauth=True) + finally: + request_bearer_token.reset(saved_token) + + assert headers == {"Authorization": "Bearer request-token"} + assert auth is None + assert user_keys == {"Authorization"} + + +def test_forward_hf_config_does_not_capture_env_token(monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setenv("HF_TOKEN", "env-token") + + config = MCPServerSettings( + name="test", + transport="http", + url="https://huggingface.co/mcp", + auth=MCPServerAuthSettings(forward="huggingface"), + ) + + assert config.headers is None + + +def test_prepare_headers_forwards_hf_space_request_token() -> None: + config = MCPServerSettings( + name="test", + transport="http", + url="https://demo.hf.space/mcp", + auth=MCPServerAuthSettings(forward="huggingface"), + ) + + saved_token = request_bearer_token.set("request-token") + try: + headers, auth, user_keys = _prepare_headers_and_auth(config, trigger_oauth=True) + finally: + request_bearer_token.reset(saved_token) + + assert headers == {"X-HF-Authorization": "Bearer request-token"} + assert auth is None + assert user_keys == {"X-HF-Authorization"} + + +def test_prepare_headers_forward_preserves_explicit_authorization() -> None: + config = MCPServerSettings( + name="test", + transport="http", + url="https://huggingface.co/mcp", + headers={"Authorization": "Bearer explicit"}, + auth=MCPServerAuthSettings(forward="huggingface"), + ) + + saved_token = request_bearer_token.set("request-token") + try: + headers, auth, user_keys = _prepare_headers_and_auth(config, trigger_oauth=True) + finally: + request_bearer_token.reset(saved_token) + + assert headers == {"Authorization": "Bearer explicit"} + assert auth is None + assert user_keys == {"Authorization"} + + @pytest.mark.asyncio async def test_managed_http_transport_context_closes_client_after_transport() -> None: class _FakeClient: diff --git a/tests/unit/fast_agent/test_a2a_remote_agent_config.py b/tests/unit/fast_agent/test_a2a_remote_agent_config.py index fed9ed0a6..07e06a405 100644 --- a/tests/unit/fast_agent/test_a2a_remote_agent_config.py +++ b/tests/unit/fast_agent/test_a2a_remote_agent_config.py @@ -10,6 +10,7 @@ AgentProvider, AgentSkill, AuthorizationCodeOAuthFlow, + HTTPAuthSecurityScheme, OAuth2SecurityScheme, OAuthFlows, SecurityRequirement, @@ -162,13 +163,120 @@ async def fake_create_client(agent_card: AgentCard, *, client_config: Any) -> Fa await agent.initialize() try: assert captured["httpx_headers"] == { - "Authorization": "Bearer hf-test-token", "X-HF-Authorization": "Bearer hf-test-token", } finally: await agent.shutdown() +@pytest.mark.asyncio +async def test_a2a_remote_agent_switches_hf_space_bearer_card_to_endpoint_auth( + monkeypatch, +) -> None: + captured: dict[str, Any] = {"httpx_headers": []} + + class FakeResolver: + def __init__(self, *_args: Any, **_kwargs: Any) -> None: + return None + + async def get_agent_card(self) -> AgentCard: + return _hf_bearer_agent_card() + + class FakeClient: + async def close(self) -> None: + return None + + class FakeAsyncClient: + def __init__(self, *_args: Any, **kwargs: Any) -> None: + captured["httpx_headers"].append(kwargs.get("headers")) + + async def aclose(self) -> None: + return None + + async def fake_create_client(agent_card: AgentCard, *, client_config: Any) -> FakeClient: + captured["agent_card"] = agent_card + captured["client_config"] = client_config + return FakeClient() + + monkeypatch.setenv("HF_TOKEN", "hf-test-token") + monkeypatch.setattr("fast_agent.a2a.remote_agent.A2ACardResolver", FakeResolver) + monkeypatch.setattr("fast_agent.a2a.remote_agent.create_client", fake_create_client) + monkeypatch.setattr("fast_agent.a2a.remote_agent.httpx.AsyncClient", FakeAsyncClient) + + agent = A2ARemoteAgent( + config=AgentConfig(name="remote", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig(url="https://demo.hf.space"), + ) + await agent.initialize() + try: + assert captured["httpx_headers"] == [ + {"X-HF-Authorization": "Bearer hf-test-token"}, + {"Authorization": "Bearer hf-test-token"}, + ] + assert captured["client_config"].httpx_client is agent._httpx_client + finally: + await agent.shutdown() + + +@pytest.mark.asyncio +async def test_a2a_remote_agent_uses_oauth_for_hf_bearer_card_without_token( + monkeypatch, +) -> None: + captured: dict[str, Any] = {"httpx_auth": []} + oauth_provider = object() + + class FakeResolver: + def __init__(self, *_args: Any, **_kwargs: Any) -> None: + return None + + async def get_agent_card(self) -> AgentCard: + return _hf_bearer_agent_card() + + class FakeClient: + async def close(self) -> None: + return None + + class FakeAsyncClient: + def __init__(self, *_args: Any, **kwargs: Any) -> None: + captured["httpx_auth"].append(kwargs.get("auth")) + captured["httpx_headers"] = kwargs.get("headers") + + async def aclose(self) -> None: + return None + + async def fake_create_client(agent_card: AgentCard, *, client_config: Any) -> FakeClient: + captured["agent_card"] = agent_card + captured["client_config"] = client_config + return FakeClient() + + def fake_build_oauth_provider(server_config: Any) -> object: + captured["oauth_server"] = server_config + return oauth_provider + + monkeypatch.delenv("HF_TOKEN", raising=False) + monkeypatch.setattr("fast_agent.a2a.remote_agent.get_hf_token_from_env", lambda: None) + monkeypatch.setattr("fast_agent.mcp.hf_auth.get_hf_token_from_env", lambda *_args: None) + monkeypatch.setattr("fast_agent.a2a.remote_agent.A2ACardResolver", FakeResolver) + monkeypatch.setattr("fast_agent.a2a.remote_agent.create_client", fake_create_client) + monkeypatch.setattr("fast_agent.a2a.remote_agent.httpx.AsyncClient", FakeAsyncClient) + monkeypatch.setattr( + "fast_agent.a2a.remote_agent.build_oauth_provider", + fake_build_oauth_provider, + ) + + agent = A2ARemoteAgent( + config=AgentConfig(name="remote", agent_type=AgentType.A2A, use_history=False), + a2a_config=A2AAgentConfig(url="https://demo.hf.space"), + ) + await agent.initialize() + try: + assert captured["httpx_auth"] == [None, None, oauth_provider] + assert captured["oauth_server"].url == "https://demo.hf.space" + assert captured["client_config"].httpx_client is agent._httpx_client + finally: + await agent.shutdown() + + @pytest.mark.asyncio async def test_a2a_remote_agent_preserves_explicit_auth_headers_for_hf_space( monkeypatch, @@ -513,3 +621,48 @@ def _oauth_agent_card() -> AgentCard: ) }, ) + + +def _hf_bearer_agent_card() -> AgentCard: + return AgentCard( + name="hf-bearer-agent", + description="HF bearer protected agent", + provider=AgentProvider(organization="test", url="https://example.com"), + version="1.0.0", + capabilities=AgentCapabilities(streaming=True, push_notifications=False), + default_input_modes=["text"], + default_output_modes=["text"], + skills=[ + AgentSkill( + id="echo", + name="Echo", + description="Echo input", + tags=["test"], + examples=["hello"], + input_modes=["text"], + output_modes=["text"], + security_requirements=[ + SecurityRequirement(schemes={"hf_bearer": StringList(list=[])}) + ], + ) + ], + supported_interfaces=[ + AgentInterface( + protocol_binding="JSONRPC", + protocol_version="1.0", + url="https://demo.hf.space/a2a/jsonrpc", + ) + ], + security_requirements=[ + SecurityRequirement(schemes={"hf_bearer": StringList(list=[])}) + ], + security_schemes={ + "hf_bearer": SecurityScheme( + http_auth_security_scheme=HTTPAuthSecurityScheme( + scheme="bearer", + bearer_format="HF_TOKEN", + description="Hugging Face bearer token", + ) + ) + }, + ) diff --git a/uv.lock b/uv.lock index 91ec70b57..f97fb6b6a 100644 --- a/uv.lock +++ b/uv.lock @@ -760,7 +760,7 @@ requires-dist = [{ name = "fast-agent-mcp", editable = "." }] [[package]] name = "fast-agent-mcp" -version = "0.7.8" +version = "0.7.9" source = { editable = "." } dependencies = [ { name = "a2a-sdk" }, From 660053fdcb3bb9eb7d795eae1d25f9aaef3f6445 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Mon, 25 May 2026 21:16:24 +0100 Subject: [PATCH 48/58] Suppress keyring notice in docs recordings --- docs/docs/ref/docs_automation.md | 2 ++ scripts/a2a_docs_pipeline.py | 5 +++-- scripts/docs_assets.py | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/docs/ref/docs_automation.md b/docs/docs/ref/docs_automation.md index 9571d915d..305ef041b 100644 --- a/docs/docs/ref/docs_automation.md +++ b/docs/docs/ref/docs_automation.md @@ -75,6 +75,8 @@ so the user-facing recording does not show a trailing `/exit`. Set `FAST_AGENT_TUI_DEMO_SHOW_EXIT=1` when you explicitly want the exit command included. Cast recordings also set `TUI__COMPLETION_MENU_RESERVED_LINES=4` by default to keep the prompt area compact; override it when a recording needs to demonstrate completion menus. +The recording drivers set `FAST_AGENT_KEYRING_NOTICE=0` so the one-time OS keyring probe message +does not appear in committed casts. The default recording command is: diff --git a/scripts/a2a_docs_pipeline.py b/scripts/a2a_docs_pipeline.py index c564d905d..dad8f4608 100755 --- a/scripts/a2a_docs_pipeline.py +++ b/scripts/a2a_docs_pipeline.py @@ -280,7 +280,7 @@ def record() -> None: tmux kill-session -t "$SESSION" 2>/dev/null || true tmux new-session -d -s "$SESSION" -x 104 -y 27 \ - "cd '$ROOT' && TERM=xterm-256color COLORTERM=truecolor FORCE_COLOR=1 FAST_AGENT_MODEL=passthrough uv run fast-agent -x --a2a '$BASE_URL' --a2a-transport JSONRPC" + "cd '$ROOT' && TERM=xterm-256color COLORTERM=truecolor FORCE_COLOR=1 FAST_AGENT_KEYRING_NOTICE=0 FAST_AGENT_MODEL=passthrough uv run fast-agent -x --a2a '$BASE_URL' --a2a-transport JSONRPC" tmux set-option -t "$SESSION" status off >/dev/null ( @@ -342,6 +342,7 @@ def _start_real_llm_server(instruction: Path) -> subprocess.Popen[str]: REAL_LLM_SERVER_LOG.unlink(missing_ok=True) log_file = REAL_LLM_SERVER_LOG.open("w", encoding="utf-8") env = os.environ.copy() + env["FAST_AGENT_KEYRING_NOTICE"] = "0" model = env.get("A2A_REAL_LLM_MODEL", REAL_LLM_MODEL) hf_mcp_url = env.get("A2A_HF_MCP_URL", REAL_LLM_MCP_URL) command = [ @@ -437,7 +438,7 @@ def record_real_llm() -> None: "printf 'fast-agent A2A server ready\\nmodel: %s\\nMCP: %s\\nlog: %s\\n\\n' '$MODEL' '$HF_MCP_URL' '$SERVER_LOG'; tail -n 80 -f '$SERVER_LOG'" tmux set-option -t "$SESSION" status off >/dev/null tmux split-window -v -t "$SESSION" -l 20 \ - "cd '$ROOT' && printf 'A2A card: %s/.well-known/agent-card.json\\n' '$BASE_URL'; curl -fsS '$BASE_URL/.well-known/agent-card.json' | python -m json.tool | sed -n '1,22p'; printf '\\ninteractive A2A JSON-RPC client\\n'; TERM=xterm-256color COLORTERM=truecolor FORCE_COLOR=1 FAST_AGENT_MODEL=passthrough uv run fast-agent -x --noenv --a2a '$BASE_URL' --a2a-transport JSONRPC" + "cd '$ROOT' && printf 'A2A card: %s/.well-known/agent-card.json\\n' '$BASE_URL'; curl -fsS '$BASE_URL/.well-known/agent-card.json' | python -m json.tool | sed -n '1,22p'; printf '\\ninteractive A2A JSON-RPC client\\n'; TERM=xterm-256color COLORTERM=truecolor FORCE_COLOR=1 FAST_AGENT_KEYRING_NOTICE=0 FAST_AGENT_MODEL=passthrough uv run fast-agent -x --noenv --a2a '$BASE_URL' --a2a-transport JSONRPC" ( for _ in $(seq 1 120); do diff --git a/scripts/docs_assets.py b/scripts/docs_assets.py index ac9d45d8f..466526215 100644 --- a/scripts/docs_assets.py +++ b/scripts/docs_assets.py @@ -148,7 +148,7 @@ def _record_script(scenario: TerminalCastScenario) -> str: tmux kill-session -t "$SESSION" 2>/dev/null || true tmux new-session -d -s "$SESSION" -x {scenario.cols} -y {scenario.rows} \\ - "cd '$ROOT' && TERM=xterm-256color COLORTERM=truecolor FORCE_COLOR=1 TUI__COMPLETION_MENU_RESERVED_LINES=${{TUI__COMPLETION_MENU_RESERVED_LINES:-4}} bash --noprofile --norc" + "cd '$ROOT' && TERM=xterm-256color COLORTERM=truecolor FORCE_COLOR=1 FAST_AGENT_KEYRING_NOTICE=0 TUI__COMPLETION_MENU_RESERVED_LINES=${{TUI__COMPLETION_MENU_RESERVED_LINES:-4}} bash --noprofile --norc" tmux set-option -t "$SESSION" status off >/dev/null ( From 2ce16187bf911184c75b3727adfaa782a2d90e70 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Mon, 25 May 2026 21:17:31 +0100 Subject: [PATCH 49/58] Document asciinema image capture experiment --- docs/docs/ref/docs_automation.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/docs/docs/ref/docs_automation.md b/docs/docs/ref/docs_automation.md index 305ef041b..df435f51a 100644 --- a/docs/docs/ref/docs_automation.md +++ b/docs/docs/ref/docs_automation.md @@ -112,6 +112,38 @@ export A2A_REAL_LLM_RECORD_SECONDS=70 uv run scripts/a2a_docs_pipeline.py record-real-llm ``` +### Image output capture experiment + +For review, an interactive Hugging Face MCP image-generation run was recorded with the keyring +notice suppressed and terminal image rendering enabled: + +```bash +export FAST_AGENT_KEYRING_NOTICE=0 +export LOGGER__TERMINAL_IMAGES__ENABLED=true +uv run fast-agent -x --model codexplan --url https://huggingface.co/mcp +``` + +Prompt: + +```text +generate an image of a sunflower +``` + +The Hugging Face MCP server invoked `evalstate/flux1_schnell` and returned an `image/webp` block, +an image URL, and a seed. In the asciinema cast, terminal image output is captured as terminal +frames rather than as a separate image asset. In this environment the inline preview appeared as +SIXEL-style text frames, for example: + +```text +[IMAGE: image/webp, 81600 bytes] +Image URL: https://evalstate-flux1-schnell.hf.space/.../image.webp +Seed used for generation: 2131209976 +SIXEL IMAGE (96x33) +++++... +``` + +The URL and Markdown image link remain visible in the cast, so this is safe as a docs fallback even +when the player does not reconstruct the inline terminal image exactly. + ## Social Cards Every Markdown page gets a committed 1200×630 PNG under `docs/assets/social/`. `overrides/main.html` From 3dfec305a5410e13992cc1b549ac7b90027f60eb Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Mon, 25 May 2026 21:19:23 +0100 Subject: [PATCH 50/58] Add TUI image generation cast --- docs/docs/assets/tui/hf-image-generation.cast | 620 ++++++++++++++++++ docs/docs/guides/tui.md | 122 ++++ 2 files changed, 742 insertions(+) create mode 100644 docs/docs/assets/tui/hf-image-generation.cast diff --git a/docs/docs/assets/tui/hf-image-generation.cast b/docs/docs/assets/tui/hf-image-generation.cast new file mode 100644 index 000000000..8bf4b5396 --- /dev/null +++ b/docs/docs/assets/tui/hf-image-generation.cast @@ -0,0 +1,620 @@ +{"version": 2, "width": 120, "height": 34, "timestamp": 1779740052, "idle_time_limit": 1.3, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}, "title": "fast-agent HF MCP image generation experiment"} +[0.031875, "o", "\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004h\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[c\u001b[>c\u001b[>q\u001b]10;?\u001b\\\u001b]11;?\u001b\\\u001b[1;1H\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[H"] +[0.032389, "o", "\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[1;1H\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[H"] +[0.414887, "o", "\u001b[33m\u001b[1mwarning\u001b[39m:\u001b(B\u001b[m \u001b[1m`VIRTUAL_ENV=/home/shaun/source/fast-agent-docs-update/.venv` does not match the project environment path `.venv` and will be ignored; use `--active` to target the active environment instead\r\n\u001b(B\u001b[m"] +[0.536251, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] +[4.59083, "o", "\u001b[?25l"] +[5.036106, "o", "\u001b[?7727h\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[3;1H\u001b[?25l\u001b[33m\u001b[1m\u001b[Hwarning\u001b[39m:\u001b(B\u001b[m \u001b[1m`VIRTUAL_ENV=/home/shaun/source/fast-agent-docs-update/.venv` does not match the project environment path `.venv` and will be ignored; use `--active` to target the active environment instead\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[3d"] +[5.208707, "o", "\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[5.209614, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[5.22259, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[5.325514, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[5.427988, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[5.530509, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[5.632153, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[5.733572, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[5.835471, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[5.936917, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[6.038162, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[6.140059, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[6.240405, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[6.342288, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[6.444693, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[6.500899, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[6.546603, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[6.648666, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[6.749995, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[6.85135, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[6.95245, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[7.054307, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[7.156372, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[7.257875, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[7.359661, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[7.460017, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[7.561563, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[7.663626, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[7.765525, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[7.866897, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[7.967816, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.076998, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.178122, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.2796, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.381226, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.48354, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.587495, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.673891, "o", "\r\u001b[K\u001b[?12l\u001b[?25h"] +[8.687765, "o", "\u001b[2mUse \u001b[32m'/'\u001b[39m for commands, \u001b[32m'!'\u001b[39m for shell. \u001b[32m'#'\u001b[39m to query, \u001b[32m'@'\u001b[39m to switch agents\r\nCTRL+T multiline, CTRL+Y copy last message, CTRL+E external editor.\r\nCTRL+Space or Tab for path completion. Use \u001b[35m/\u001b[95mattach\u001b[39m, `^file:`, `^url:`, or \u001b[33mCtrl+Alt+V\u001b[39m for attachments \u001b[1m(\u001b(B\u001b[m\u001b[2mexperimental\u001b[1m)\u001b(B\u001b[m\u001b[2m. F10\u001b[6;1Hto clear.\r\n\u001b(B\u001b[m"] +[8.688, "o", "\u001b[2mModel shortcuts:\r\n\u001b(B\u001b[m"] +[8.688144, "o", "\u001b[2m Shift+Tab = Service tier \u001b[1m(\u001b(B\u001b[m\u001b[2mstandard, fast\u001b[1m)\r\n\u001b(B\u001b[m"] +[8.688371, "o", "\u001b[2m F6 = Reasoning \u001b[1m(\u001b(B\u001b[m\u001b[2mnone, low, medium, high, xhigh\u001b[1m)\r\n\u001b(B\u001b[m"] +[8.688425, "o", "\u001b[2m F7 = Verbosity \u001b[1m(\u001b(B\u001b[m\u001b[2mlow, medium, high\u001b[1m)\r\n\u001b(B\u001b[m"] +[8.688682, "o", "\u001b[2m F8 = Web search \u001b[1m(\u001b(B\u001b[m\u001b[2mon, off\u001b[1m)\r\n\u001b(B\u001b[m\r\n"] +[8.689171, "o", "\u001b[2mfast-agent environment\u001b(B\u001b[m \u001b[34m~/source/fast-agent-pr/.fast-agent\u001b[39m\u001b[2m \u001b[1m(\u001b[36m3\u001b(B\u001b[m\u001b[2m agents, \u001b[36m\u001b[1m4\u001b(B\u001b[m\u001b[2m hooks, \u001b[36m\u001b[1m3\u001b(B\u001b[m\u001b[2m extensions, \u001b[36m\u001b[1m2\u001b(B\u001b[m\u001b[2m modelrefs\u001b[1m)\u001b(B\u001b[m\u001b[2m via cli\r\n\u001b(B\u001b[m"] +[8.689384, "o", "\u001b[33m\u001b[1mAgents have shell\u001b(B\u001b[m\u001b[2m (skills, switch, sub-agent, bash | cwd: source/fast-agent-pr)\r\n\u001b(B\u001b[m"] +[8.858303, "o", "\u001b[2mAgent \u001b(B\u001b[m\u001b[34mdev\u001b[39m\u001b[2m:\u001b(B\u001b[m \u001b[36m\u001b[1m2\u001b(B\u001b[m\u001b[2m child agents. \u001b(B\u001b[m\u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m MCP Server \u001b[1m(\u001b(B\u001b[m\u001b[36m\u001b[1m27\u001b(B\u001b[m\u001b[2m tools, \u001b(B\u001b[m\u001b[36m\u001b[1m4\u001b(B\u001b[m\u001b[2m prompts, \u001b(B\u001b[m\u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m resource\u001b[1m)\u001b(B\u001b[m\u001b[2m. \u001b(B\u001b[m\u001b[36m\u001b[1m3\u001b(B\u001b[m\u001b[2m skills available\r\n\u001b(B\u001b[m"] +[8.858745, "o", "\r\n"] +[8.859213, "o", "\u001b[2mInteractive MCP app integrations detected:\r\n\u001b(B\u001b[m"] +[8.860274, "o", "\u001b[2m ● \u001b(B\u001b[m\u001b[36mhuggingface_co\u001b[39m\u001b[2m — \u001b(B\u001b[m\u001b[36mMCP Apps\u001b[39m\u001b[2m: \u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m tools, \u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m resources\r\n\u001b(B\u001b[m"] +[8.861265, "o", "\u001b[2m · \u001b(B\u001b[mhuggingface_co__file_manager \r\n\u001b[1m\u001b[2m(\u001b(B\u001b[m\u001b[2mui:\u001b[35m//hf-mcp-proxy/hf_files/\u001b[95mdWk6Ly9wcmVmYWIvdG9vbC81MDY1Y2UwYTAxMjEvcmVuZGVyZXIuaHRtbA\u001b[39m\u001b[1m)\r\n\u001b(B\u001b[m"] +[8.986702, "o", "\u001b[2m ├─ \u001b(B\u001b[m\u001b[34mripgrep_oss\u001b[39m\u001b[2m: No MCP Servers\r\n\u001b(B\u001b[m"] +[8.987036, "o", "\u001b[2m └─ \u001b(B\u001b[m\u001b[34mripgrep_spark\u001b[39m\u001b[2m: No MCP Servers\r\n\u001b(B\u001b[m"] +[8.987264, "o", "\u001b[2mStreaming Enabled - markdown mode\u001b[25;1H\u001b(B\u001b[m"] +[8.990058, "o", "\r\n\u001b[J\u001b[A\u001b[K\u001b[93m❯\u001b[C\u001b(B\u001b[m"] +[8.995128, "o", "\u001b[34;1H\u001b[30m\u001b[47m\u001b[7m \u001b[34m\u001b[40m dev[S] \u001b[30m\u001b[47m \u001b[32m\u001b[40mTVD\u001b[30m\u001b[100m ▲ \u001b[42m⢠\u001b[43m⡆\u001b[47m \u001b[42m∞gpt-5.5\u001b[100m»⊕\u001b[47m | 0.00% | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | source/fast-agent-pr | fast-agent 0.7.11 \u001b[25;3H\u001b(B\u001b[m"] +[47.562541, "o", "generate an image of a sunflower"] +[47.565172, "o", "\r\u001b[93m❯\u001b[39m generate an image of a sunflower\u001b[34;1H \u001b[K\u001b[25;35H"] +[47.565364, "o", "\r\n\u001b[J\u001b[A\u001b[K"] +[47.575327, "o", "\u001b[A"] +[47.576211, "o", "\u001b[?25l"] +[47.578078, "o", "\r\n"] +[47.578343, "o", "\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m \u001b[34mdev\u001b[39m \u001b[2m─────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[26;1H\u001b(B\u001b[m"] +[47.579099, "o", "generate an image of a sunflower\r\n"] +[47.816751, "o", "\u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[47.817405, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[47.879775, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[47.981156, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[48.082655, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[48.184064, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[48.284777, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[48.386133, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[48.487545, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[48.588324, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[48.689727, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[48.790995, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[48.892555, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[48.993869, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[49.095283, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[49.1973, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[49.298946, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[49.400483, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[49.501827, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[49.603069, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[49.705296, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[49.806567, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[49.908332, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[49.935216, "o", "\r\u001b[K\u001b[33m▎\u001b[2m◀\u001b(B\u001b[m\u001b[33m 33 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 (summary) turn 1\u001b(B\u001b[m"] +[49.944567, "o", "\r\u001b[K"] +[49.946738, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5\u001b[29;1H\u001b[1m\u001b[3mExploring image generation\u001b(B\u001b[m \u001b[31;1H\u001b[2m\u001b[3mI●\u001b(B\u001b[m \r\n"] +[49.97876, "o", "\u001b[A\u001b[2m\u001b[3mI realize I●\u001b(B\u001b[m \r\n"] +[49.99082, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need●\u001b(B\u001b[m \r\n"] +[50.003764, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to●\u001b(B\u001b[m \r\n"] +[50.018928, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find●\u001b(B\u001b[m \r\n"] +[50.03319, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an●\u001b(B\u001b[m \r\n"] +[50.053206, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach●\u001b(B\u001b[m \r\n"] +[50.07649, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer●\u001b(B\u001b[m \r\n"] +[50.091148, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving●\u001b(B\u001b[m \r\n"] +[50.104464, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF●\u001b(B\u001b[m \r\n"] +[50.117777, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic●\u001b(B\u001b[m \r\n"] +[50.138797, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic space●\u001b(B\u001b[m \r\n"] +[50.154075, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic space. It●\u001b(B\u001b[m \r\n"] +[50.174879, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic space. It seems likely●\u001b(B\u001b[m \r\n"] +[50.189684, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic space. It seems likely that●\u001b(B\u001b[m \r\n"] +[50.209999, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic space. It seems likely that I'll be●\u001b(B\u001b[m \r\n"] +[50.226258, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic space. It seems likely that I'll be \u001b(B\u001b[m \r\n\u001b[2m\u001b[3mfocusing●\u001b(B\u001b[m \r\n"] +[50.244906, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on●\u001b(B\u001b[m \r\n"] +[50.261629, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image●\u001b(B\u001b[m \r\n"] +[50.275927, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation●\u001b(B\u001b[m \r\n"] +[50.297042, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and●\u001b(B\u001b[m \r\n"] +[50.317105, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it●\u001b(B\u001b[m \r\n"] +[50.33177, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works●\u001b(B\u001b[m \r\n"] +[50.34773, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works.●\u001b(B\u001b[m \r\n"] +[50.366293, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll●\u001b(B\u001b[m \r\n"] +[50.384427, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking●\u001b(B\u001b[m \r\n"] +[50.419089, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods●\u001b(B\u001b[m \r\n"] +[50.443715, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and●\u001b(B\u001b[m \r\n"] +[50.462144, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and techniques●\u001b(B\u001b[m \r\n"] +[50.48232, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and techniques used●\u001b(B\u001b[m \r\n"] +[50.497204, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and techniques used in●\u001b(B\u001b[m \r\n"] +[50.522884, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and techniques used in this area●\u001b(B\u001b[m \r\n"] +[50.548149, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and techniques used in this area to●\u001b(B\u001b[m \r\n"] +[50.562863, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and techniques used in this area to \u001b(B\u001b[m \r\n\u001b[2m\u001b[3mprepare●\u001b(B\u001b[m \r\n"] +[50.585285, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive●\u001b(B\u001b[m \r\n"] +[50.599588, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response●\u001b(B\u001b[m \r\n"] +[50.611128, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response.●\u001b(B\u001b[m \r\n"] +[50.625152, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It●\u001b(B\u001b[m \r\n"] +[50.641796, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels●\u001b(B\u001b[m \r\n"] +[50.668894, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like●\u001b(B\u001b[m \r\n"] +[50.719911, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite●\u001b(B\u001b[m \r\n"] +[50.757686, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a●\u001b(B\u001b[m \r\n"] +[50.784478, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit●\u001b(B\u001b[m \r\n"] +[50.811146, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to●\u001b(B\u001b[m \r\n"] +[50.857014, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn,●\u001b(B\u001b[m \r\n"] +[50.877573, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but●\u001b(B\u001b[m \r\n"] +[50.891858, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm●\u001b(B\u001b[m \r\n"] +[50.907674, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking●\u001b(B\u001b[m \r\n"] +[50.92336, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking forward●\u001b(B\u001b[m \r\n"] +[50.93889, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking forward to●\u001b(B\u001b[m \r\n"] +[50.955491, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking forward to uncover●\u001b(B\u001b[m \r\n"] +[50.971752, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking forward to uncovering●\u001b(B\u001b[m \r\n"] +[50.994358, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking forward to uncovering \u001b(B\u001b[m \r\n\u001b[2m\u001b[3mhow●\u001b(B\u001b[m\r\n\u001b[33;5H \r\n\u001b[K"] +[51.023884, "o", "\u001b[2A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking forward to uncovering how\r\nimage generation●\u001b(B\u001b[m \r\n"] +[51.04514, "o", "\u001b[A\u001b[2m\u001b[3mimage generation operates●\u001b(B\u001b[m \r\n"] +[51.061572, "o", "\u001b[A\u001b[2m\u001b[3mimage generation operates within●\u001b(B\u001b[m \r\n"] +[51.085724, "o", "\u001b[A\u001b[2m\u001b[3mimage generation operates within these●\u001b(B\u001b[m \r\n"] +[51.100471, "o", "\u001b[A\u001b[2m\u001b[3mimage generation operates within these frameworks●\u001b(B\u001b[m \r\n"] +[51.128969, "o", "\u001b[A\u001b[2m\u001b[3mimage generation operates within these frameworks!●\u001b(B\u001b[m \r\n"] +[51.261062, "o", "\u001b[A\u001b[2m\u001b[3mimage generation operates within these frameworks!\u001b(B\u001b[m \r\n\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[35mhuggingface_co__dynamic_space\r\n\u001b[39m{\"operation\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[51.278713, "o", "\u001b[A{\"operation\":\"discover\u001b[2m●\r\n\u001b(B\u001b[m"] +[51.300997, "o", "\u001b[A{\"operation\":\"discover\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[51.324612, "o", "\u001b[A{\"operation\":\"discover\",\"space\u001b[2m●\r\n\u001b(B\u001b[m"] +[51.347628, "o", "\u001b[A{\"operation\":\"discover\",\"space_name\u001b[2m●\r\n\u001b(B\u001b[m"] +[51.366405, "o", "\u001b[A{\"operation\":\"discover\",\"space_name\":\"\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[51.394935, "o", "\u001b[A{\"operation\":\"discover\",\"space_name\":\"\",\"parameters\u001b[2m●\r\n\u001b(B\u001b[m"] +[51.413989, "o", "\u001b[A{\"operation\":\"discover\",\"space_name\":\"\",\"parameters\":\"\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[51.435493, "o", "\u001b[A{\"operation\":\"discover\",\"space_name\":\"\",\"parameters\":\"\"}\u001b[2m●\r\n\u001b(B\u001b[m"] +[51.609133, "o", "\u001b[4S\u001b[5A{\u001b[K\r\n \"operation\": \"discover\",\r\n \"space_name\": \"\",\u001b[K\r\n \"parameters\": \"\"\u001b[K\r\n}\u001b[K\r\n\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[51.643585, "o", "\u001b[15A\u001b[K\u001b[2B\u001b[K\u001b[2B\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[14A\u001b[?12l\u001b[?25h"] +[51.663617, "o", "\r\n\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5 ↗ (1.90%)\r\n\u001b(B\u001b[m"] +[51.664377, "o", "\u001b[1m\u001b[2m\u001b[3mExploring image generation\u001b(B\u001b[m \u001b[23;1H\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic space. It seems likely that I'll be \u001b(B\u001b[m \u001b[24;1H\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and techniques used in this area to \u001b(B\u001b[m \u001b[25;1H\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking forward to uncovering how \u001b[26;1Himage generation operates within these frameworks!\u001b(B\u001b[m \u001b[27;1H"] +[51.664459, "o", "\u001b[32m\u001b[2m\u001b[3mThe assistant requested tool calls\r\n\u001b(B\u001b[m"] +[51.664695, "o", "\r\n"] +[51.665067, "o", "\u001b[2m▎ \u001b[37mbash\u001b[39m • \u001b(B\u001b[m\u001b[92mhuggingface…\u001b[39m\u001b[2m • \u001b[37mskill\u001b[39m • \u001b[37mcard_tools\u001b[39m • \u001b[37mripgrep_oss\u001b[39m • \u001b[37mripgrep_spa…\r\n\u001b(B\u001b[m\r\n"] +[51.725839, "o", "\r\n"] +[51.726305, "o", "\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m \u001b[35mdev\u001b[39m \u001b[2mtool call - huggingface_co__dynamic_space\r\n\u001b(B\u001b[m"] +[51.733675, "o", "\u001b[1m\u001b[2m{\u001b(B\u001b[m\u001b[32m\u001b[2m'operation'\u001b[39m: \u001b[32m'discover'\u001b[39m, \u001b[32m'space_name'\u001b[39m: \u001b[32m''\u001b[39m, \u001b[32m'parameters'\u001b[39m: \u001b[32m''\u001b[39m\u001b[1m}\r\n\u001b(B\u001b[m"] +[51.734051, "o", "\n\u001b[K"] +[51.73441, "o", "\u001b[2m▎ \u001b[37mhf_whoami\u001b[39m • \u001b[37mhub_repo_se…\u001b[39m • \u001b[37mpaper_search\u001b[39m • \u001b[37mhub_repo_de…\u001b[39m • \u001b[37mhf_jobs\u001b[39m • \u001b(B\u001b[m\u001b[35mdynamic_spa…\u001b[39m\u001b[2m • \u001b[37mwrite_file\u001b[39m • \u001b[37mlist_files\u001b[39m •\u001b(B\u001b[m\r\n\u001b[33;110H\u001b[2m \u001b[37mread_file\u001b[39m \u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[2m…\u001b(B\u001b[m\r\n\u001b[K\n\u001b[K"] +[51.735982, "o", "\u001b[?25l"] +[51.736772, "o", "\u001b[33m▎\u001b[2m◀\u001b(B\u001b[m\u001b[33m 432 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 (summary) turn 1\u001b(B\u001b[m"] +[51.737665, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m 51 ⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 turn 1 \u001b(B\u001b[m"] +[51.739255, "o", "\r\u001b[K\u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space \u001b(B\u001b[m"] +[51.740583, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] +[51.838771, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] +[51.940278, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] +[51.971071, "o", "\r\n\u001b[A\u001b[K\r\n\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] +[51.971614, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[2mtool result - text only 2333 chars\u001b(B\u001b[m\r\n\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] +[51.972641, "o", "\r\u001b[9S\u001b[9A\u001b[2m**Available Spaces:**\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2mThese spaces can be invoked using the `dynamic_space` tool.\u001b(B\u001b[m\u001b[K\r\n\u001b[2mUse `\u001b[32m\"operation\"\u001b[39m: \u001b[32m\"view_parameters\"\u001b[39m` to inspect a space's parameters before invoking.\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m| Space ID | Category | Description |\u001b(B\u001b[m\u001b[K\r\n\u001b[2m|----------|----------|-------------|\u001b(B\u001b[m\u001b[K\r\n\u001b[2m| `evalstate/flux1\\_schnell` | Image Generation | Simple, fast image generator. Use for quick tests and ideas. |\u001b(B\u001b[m\u001b[K\r\n\u001b[2m|\u001b[33m...\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[35m\u001b[2m▎◀ Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] +[52.043428, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] +[52.145576, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] +[52.200946, "o", "\r\u001b[K\u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[52.201814, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[52.246844, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[52.348756, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[52.43745, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[52.538754, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[52.640581, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[52.742077, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[52.843813, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[52.944522, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[53.046273, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[53.147156, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[53.248962, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[53.350533, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[53.451978, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[53.553895, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[53.654577, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[53.757163, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[53.858257, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[53.960016, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[54.061612, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[54.163846, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[54.265567, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[54.367449, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[54.468707, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[54.495761, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞\u001b(B\u001b[m\r\n\u001b[33;32H\u001b[37m\u001b[2mgpt-5.5 turn 2 \u001b(B\u001b[m\r\n\u001b[K\u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start)\u001b(B\u001b[m"] +[54.497275, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_j1nuF2zE…\u001b(B\u001b[m"] +[54.569871, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_j1nuF2zE…\u001b(B\u001b[m"] +[54.581135, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A"] +[54.581626, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\r\n\n\u001b[32;3H \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5\u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[35mhuggingface_co__dynamic_space\r\n\u001b[39m{\"\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[54.635955, "o", "\u001b[A{\"operation\u001b[2m●\r\n\u001b(B\u001b[m"] +[54.689234, "o", "\u001b[A{\"operation\":\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[54.746382, "o", "\u001b[A{\"operation\":\"view\u001b[2m●\r\n\u001b(B\u001b[m"] +[54.811214, "o", "\u001b[A{\"operation\":\"view_parameters\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[54.882793, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space\u001b[2m●\r\n\u001b(B\u001b[m"] +[54.936755, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[54.997512, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"eval\u001b[2m●\r\n\u001b(B\u001b[m"] +[55.053035, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate\u001b[2m●\r\n\u001b(B\u001b[m"] +[55.125097, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux\u001b[2m●\r\n\u001b(B\u001b[m"] +[55.164492, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1\u001b[2m●\r\n\u001b(B\u001b[m"] +[55.224617, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_s\u001b[2m●\r\n\u001b(B\u001b[m"] +[55.280529, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schn\u001b[2m●\r\n\u001b(B\u001b[m"] +[55.37704, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schnell\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[55.400715, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\u001b[2m●\r\n\u001b(B\u001b[m"] +[55.455053, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\u001b[2m●\r\n\u001b(B\u001b[m"] +[56.444801, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"\"}\u001b[2m●\r\n\u001b(B\u001b[m"] +[56.611262, "o", "\u001b[4S\u001b[5A{\u001b[K\r\n \"operation\": \"view_parameters\",\r\n \"space_name\": \"evalstate/flux1_schnell\",\u001b[K\r\n \"parameters\": \"\"\u001b[K\r\n}\u001b[K\r\n\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[56.640135, "o", "\u001b[9A\u001b[K\u001b[2B\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[8A\u001b[?12l\u001b[?25h"] +[56.640585, "o", "\r\n"] +[56.640864, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5 ↔ (2.13%)\r\n\u001b(B\u001b[m"] +[56.640931, "o", "\u001b[32m\u001b[2m\u001b[3mThe assistant requested tool calls\r\n\u001b(B\u001b[m\r\n"] +[56.641107, "o", "\u001b[2m▎ \u001b[37mbash\u001b[39m • \u001b(B\u001b[m\u001b[92mhuggingface…\u001b[39m\u001b[2m • \u001b[37mskill\u001b[39m • \u001b[37mcard_tools\u001b[39m • \u001b[37mripgrep_oss\u001b[39m • \u001b[37mripgrep_spa…\u001b[31;1H\u001b(B\u001b[m"] +[56.656807, "o", "\r\n\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m \u001b[35mdev\u001b[39m \u001b[2mtool call - huggingface_co__dynamic_space\r\n\u001b(B\u001b[m"] +[56.657144, "o", "\u001b[1m\u001b[2m{\u001b(B\u001b[m\u001b[32m\u001b[2m'operation'\u001b[39m: \u001b[32m'view_parameters'\u001b[39m, \u001b[32m'space_name'\u001b[39m: \u001b[32m'evalstate/flux1_schnell'\u001b[39m, \u001b[32m'parameters'\u001b[39m: \u001b[32m''\u001b[39m\u001b[1m}\r\n\u001b(B\u001b[m"] +[56.657347, "o", "\n\u001b[K"] +[56.657549, "o", "\u001b[2m▎ \u001b[37mhf_whoami\u001b[39m • \u001b[37mhub_repo_se…\u001b[39m • \u001b[37mpaper_search\u001b[39m • \u001b[37mhub_repo_de…\u001b[39m • \u001b[37mhf_jobs\u001b[39m • \u001b(B\u001b[m\u001b[35mdynamic_spa…\u001b[39m\u001b[2m • \u001b[37mwrite_file\u001b[39m • \u001b[37mlist_files\u001b[39m •\u001b(B\u001b[m\r\n\u001b[33;110H\u001b[2m \u001b[37mread_file\u001b[39m \u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[2m…\u001b(B\u001b[m\r\u001b[2S\u001b[A\u001b[K\r\n\u001b[K"] +[56.658158, "o", "\u001b[?25l"] +[56.658612, "o", "\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[56.659313, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m 41 ⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 turn 2 \u001b(B\u001b[m"] +[56.6605, "o", "\r\u001b[K\u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space \u001b(B\u001b[m"] +[56.660794, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] +[56.760712, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] +[56.861094, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] +[56.938133, "o", "\r\n\u001b[A\u001b[K\r\n\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] +[56.938781, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[2mtool result - text only 759 chars\u001b(B\u001b[m\r\n\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] +[56.940673, "o", "\r\u001b[17S\u001b[17d\u001b[2m# Parameters for: flux1_schnell_infer\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m**Description:** Generate an image using the Flux \u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m Schnell Image Generator.\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m## Parameters:\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m### height \u001b[1m[\u001b(B\u001b[m\u001b[2mOPTIONAL\u001b[1m]\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Type:** number\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Default:** \u001b[36m\u001b[1m1024\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m### num_inference_steps \u001b[1m[\u001b(B\u001b[m\u001b[2mOPTIONAL\u001b[1m]\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Type:** number\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Default:** \u001b[36m\u001b[1m4\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m### prompt \u001b[1m[\u001b(B\u001b[m\u001b[2mOPTIONAL\u001b[1m]\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Type:** string\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Description:** Approximately \u001b[36m\u001b[1m60\u001b(B\u001b[m\u001b[2m-\u001b[36m\u001b[1m70\u001b(B\u001b[m\u001b[2m words max - d\u001b[33m...\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[35m\u001b[2m▎◀ Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] +[56.961782, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] +[57.062889, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] +[57.160613, "o", "\r\u001b[K\u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[57.160988, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[57.163539, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[57.264413, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[57.365919, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[57.46722, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[57.56891, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[57.670161, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[57.770679, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[57.872331, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[57.974076, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[58.075445, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[58.176545, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[58.277421, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[58.378021, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[58.479651, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[58.580845, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[58.682135, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[58.783715, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[58.885299, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[58.985916, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[59.086945, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[59.188414, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[59.289353, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[59.390202, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[59.492325, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[59.593559, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[59.695117, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[59.797179, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[59.898499, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[60.000177, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[60.101596, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[60.202247, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[60.303754, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[60.405189, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[60.506492, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[60.607856, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[60.709366, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[60.810589, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[60.912215, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[61.013382, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[61.115186, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[61.21673, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[61.318824, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[61.420558, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[61.522143, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[61.623606, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[61.725879, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[61.827035, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[61.928696, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[62.029974, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[62.109921, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞\u001b(B\u001b[m\r\n\u001b[33;32H\u001b[37m\u001b[2mgpt-5.5 turn 3 \u001b(B\u001b[m\r\n\u001b[K\u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start)\u001b(B\u001b[m"] +[62.110125, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[62.13086, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[62.233151, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[62.335709, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[62.437664, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[62.539649, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[62.641606, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[62.744139, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[62.846263, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[62.948127, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[63.050428, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[63.152458, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[63.25427, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[63.356514, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[63.458723, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[63.559643, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[63.661885, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[63.764354, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[63.866397, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[63.968825, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[64.070757, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[64.172357, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[64.273236, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[64.375156, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[64.476989, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[64.578617, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[64.681472, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[64.783058, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[64.885141, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] +[64.980863, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A"] +[64.981738, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\r\n\n\u001b[32;3H \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5\u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[35mhuggingface_co__dynamic_space\r\n\u001b[39m{\"\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[65.000155, "o", "\u001b[A{\"operation\u001b[2m●\r\n\u001b(B\u001b[m"] +[65.151246, "o", "\u001b[A{\"operation\":\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[65.185039, "o", "\u001b[A{\"operation\":\"invoke\u001b[2m●\r\n\u001b(B\u001b[m"] +[65.832878, "o", "\u001b[A{\"operation\":\"invoke\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[65.852396, "o", "\u001b[A{\"operation\":\"invoke\",\"space\u001b[2m●\r\n\u001b(B\u001b[m"] +[65.884882, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[65.907746, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"eval\u001b[2m●\r\n\u001b(B\u001b[m"] +[66.897889, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate\u001b[2m●\r\n\u001b(B\u001b[m"] +[66.913436, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/\u001b[2m●\r\n\u001b(B\u001b[m"] +[66.924766, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux\u001b[2m●\r\n\u001b(B\u001b[m"] +[66.938489, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_s\u001b[2m●\r\n\u001b(B\u001b[m"] +[66.956572, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[66.999512, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\u001b[2m●\r\n\u001b(B\u001b[m"] +[67.012545, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[67.704306, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[67.75864, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\u001b[2m●\r\n\u001b(B\u001b[m"] +[67.771111, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[67.842419, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"A vibrant close\u001b[2m●\r\n\u001b(B\u001b[m"] +[67.863522, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"A vibrant close-up\u001b[2m●\r\n\u001b(B\u001b[m"] +[67.900199, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"A vibrant close-up photograph \r\nof a\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[67.919201, "o", "\u001b[Aof a single sunflower\u001b[2m●\r\n\u001b(B\u001b[m"] +[68.485011, "o", "\u001b[Aof a single sunflower in\u001b[2m●\r\n\u001b(B\u001b[m"] +[68.568733, "o", "\u001b[Aof a single sunflower in full\u001b[2m●\r\n\u001b(B\u001b[m"] +[68.645127, "o", "\u001b[Aof a single sunflower in full bloom\u001b[2m●\r\n\u001b(B\u001b[m"] +[69.665603, "o", "\u001b[Aof a single sunflower in full bloom,\u001b[2m●\r\n\u001b(B\u001b[m"] +[69.676945, "o", "\u001b[Aof a single sunflower in full bloom, golden\u001b[2m●\r\n\u001b(B\u001b[m"] +[69.691545, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radi\u001b[2m●\r\n\u001b(B\u001b[m"] +[69.810214, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating\u001b[2m●\r\n\u001b(B\u001b[m"] +[69.959659, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating around a\u001b[2m●\r\n\u001b(B\u001b[m"] +[70.593552, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating around a textured brown\u001b[2m●\r\n\u001b(B\u001b[m"] +[71.288328, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating around a textured brown center\u001b[2m●\r\n\u001b(B\u001b[m"] +[71.359754, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating around a textured brown center,\u001b[2m●\r\n\u001b(B\u001b[m"] +[71.377474, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating around a textured brown center, standing in\u001b[2m●\r\n\u001b(B\u001b[m"] +[71.418417, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating around a textured brown center, standing in a sun\u001b[2m●\r\n\u001b(B\u001b[m"] +[71.993861, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating around a textured brown center, standing in a \u001b[K\r\nsunlit\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[72.027188, "o", "\u001b[Asunlit summer field with soft green\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.110546, "o", "\u001b[Asunlit summer field with soft green b\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.122607, "o", "\u001b[Asunlit summer field with soft green bokeh\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.166744, "o", "\u001b[Asunlit summer field with soft green bokeh background, warm natural\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.185202, "o", "\u001b[Asunlit summer field with soft green bokeh background, warm natural light, crisp details\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.204897, "o", "\u001b[Asunlit summer field with soft green bokeh background, warm natural light, crisp details, cheerful and\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.242461, "o", "\u001b[Asunlit summer field with soft green bokeh background, warm natural light, crisp details, cheerful and realistic, high\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.262014, "o", "\u001b[Asunlit summer field with soft green bokeh background, warm natural light, crisp details, cheerful and realistic, high \r\nresolution.\\\",\\\"width\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[72.282407, "o", "\u001b[Aresolution.\\\",\\\"width\\\":\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.303865, "o", "\u001b[Aresolution.\\\",\\\"width\\\":1024,\\\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.321946, "o", "\u001b[Aresolution.\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.341579, "o", "\u001b[Aresolution.\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.359968, "o", "\u001b[Aresolution.\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.446301, "o", "\u001b[Aresolution.\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.540543, "o", "\u001b[Aresolution.\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"randomize_seed\\\":true}\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.554456, "o", "\u001b[Aresolution.\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"randomize_seed\\\":true}\"}\u001b[2m●\r\n\u001b(B\u001b[m"] +[72.795291, "o", "\u001b[4S\u001b[8A{\u001b[K\r\n \"operation\": \"invoke\",\u001b[K\r\n \"space_name\": \"evalstate/flux1_schnell\",\u001b[K\r\n \"parameters\": \"{\\\"prompt\\\":\\\"A vibrant close-up photograph of a single sunflower in full bloom, golden yellow petals \r\nradiating around a textured brown center, standing in a sunlit summer field with soft green bokeh background, warm \r\nnatural light, crisp details, cheerful and realistic, high \u001b[K\r\nresolution.\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"randomize_seed\\\":true}\"\u001b[K\r\n}\u001b[K\r\n\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[72.830613, "o", "\u001b[12A\u001b[K\u001b[2B\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[11A\u001b[?12l\u001b[?25h"] +[72.830984, "o", "\r\n"] +[72.831408, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5 ↔ (2.26%)\r\n\u001b(B\u001b[m"] +[72.831597, "o", "\u001b[32m\u001b[2m\u001b[3mThe assistant requested tool calls\r\n\u001b(B\u001b[m\r\n\u001b[2m▎ \u001b[37mbash\u001b[39m • \u001b(B\u001b[m\u001b[92mhuggingface…\u001b[39m\u001b[2m • \u001b[37mskill\u001b[39m • \u001b[37mcard_tools\u001b[39m • \u001b[37mripgrep_oss\u001b[39m • \u001b[37mripgrep_spa…\r\n\u001b(B\u001b[m\r\n"] +[72.856372, "o", "\r\n\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m \u001b[35mdev\u001b[39m \u001b[2mtool call - huggingface_co__dynamic_space\r\n\u001b(B\u001b[m"] +[72.857136, "o", "\u001b[34d\n\u001b[5A\u001b[1m\u001b[2m{\r\n\u001b(B\u001b[m\u001b[2m \u001b[32m'operation'\u001b[39m: \u001b[32m'invoke'\u001b[39m,\r\n \u001b[32m'space_name'\u001b[39m: \u001b[32m'evalstate/flux1_schnell'\u001b[39m,\r\n \u001b[32m'parameters'\u001b[39m: \u001b[32m'{\"prompt\":\"A vibrant close-up photograph of a sing'\u001b[39m+\u001b[36m\u001b[1m309\r\n\u001b[39m}\u001b(B\u001b[m\r\n\u001b[K\n\u001b[K"] +[72.85744, "o", "\u001b[2m▎ \u001b[37mhf_whoami\u001b[39m • \u001b[37mhub_repo_se…\u001b[39m • \u001b[37mpaper_search\u001b[39m • \u001b[37mhub_repo_de…\u001b[39m • \u001b[37mhf_jobs\u001b[39m • \u001b(B\u001b[m\u001b[35mdynamic_spa…\u001b[39m\u001b[2m • \u001b[37mwrite_file\u001b[39m • \u001b[37mlist_files\u001b[39m •\u001b(B\u001b[m\r\n\u001b[33;110H\u001b[2m \u001b[37mread_file\u001b[39m \u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[2m…\u001b(B\u001b[m\r\u001b[2S\u001b[A\u001b[K\r\n\u001b[K"] +[72.858186, "o", "\u001b[?25l"] +[72.858771, "o", "\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[72.859364, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m 119 ⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 turn 3 \u001b(B\u001b[m"] +[72.860605, "o", "\r\u001b[K\u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space \u001b(B\u001b[m"] +[72.861015, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[72.959937, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[73.0618, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[73.163357, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[73.264831, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[73.365381, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[73.467194, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[73.568705, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[73.670377, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[73.771508, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[73.873322, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[73.974648, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[74.076552, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[74.1772, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[74.278916, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[74.379467, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[74.481197, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[74.582728, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[74.686737, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[74.788617, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[74.890127, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[74.991758, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[75.093485, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[75.195197, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[75.29575, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] +[75.397411, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] +[75.498013, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] +[75.600452, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] +[75.701144, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] +[75.803358, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] +[75.905199, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] +[76.006588, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] +[76.108025, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 2 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 10 of 100\u001b(B\u001b[m"] +[76.209047, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 2 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 10 of 100\u001b(B\u001b[m"] +[76.310283, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 2 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 10 of 100\u001b(B\u001b[m"] +[76.412029, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 3 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 20 of 100\u001b(B\u001b[m"] +[76.513601, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 3 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 20 of 100\u001b(B\u001b[m"] +[76.615539, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 4 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 22 of 100\u001b(B\u001b[m"] +[76.717994, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 5 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 23 of 100\u001b(B\u001b[m"] +[76.819527, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 6 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 25 of 100\u001b(B\u001b[m"] +[76.921727, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 7 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 27 of 100\u001b(B\u001b[m"] +[77.023475, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 8 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 29 of 100\u001b(B\u001b[m"] +[77.124786, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 9 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 31 of 100\u001b(B\u001b[m"] +[77.225329, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 10 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 33 of 100\u001b(B\u001b[m"] +[77.327051, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 11 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 35 of 100\u001b(B\u001b[m"] +[77.42891, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 12 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 37 of 100\u001b(B\u001b[m"] +[77.531255, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 13 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 39 of 100\u001b(B\u001b[m"] +[77.632305, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 14 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 41 of 100\u001b(B\u001b[m"] +[77.735534, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 15 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 44 of 100\u001b(B\u001b[m"] +[77.837028, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 16 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 47 of 100\u001b(B\u001b[m"] +[77.938344, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 17 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 50 of 100\u001b(B\u001b[m"] +[78.039982, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 18 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 53 of 100\u001b(B\u001b[m"] +[78.141571, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 19 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 55 of 100\u001b(B\u001b[m"] +[78.243338, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 20 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 58 of 100\u001b(B\u001b[m"] +[78.344643, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 21 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 61 of 100\u001b(B\u001b[m"] +[78.446248, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 22 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 63 of 100\u001b(B\u001b[m"] +[78.548081, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 23 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 66 of 100\u001b(B\u001b[m"] +[78.64955, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 24 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 69 of 100\u001b(B\u001b[m"] +[78.752774, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 25 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 72 of 100\u001b(B\u001b[m"] +[78.853755, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 26 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 74 of 100\u001b(B\u001b[m"] +[78.95528, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 27 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 76 of 100\u001b(B\u001b[m"] +[79.056671, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 28 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 77 of 100\u001b(B\u001b[m"] +[79.15857, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 30 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 85 of 100\u001b(B\u001b[m"] +[79.260539, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 31 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 86 of 100\u001b(B\u001b[m"] +[79.362617, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 32 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 88 of 100\u001b(B\u001b[m"] +[79.464048, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 33 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 92 of 100\u001b(B\u001b[m"] +[79.565562, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 34 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 95 of 100\u001b(B\u001b[m"] +[79.666655, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 35 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 99 of 100\u001b(B\u001b[m"] +[79.768693, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 36 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 99 of 100\u001b(B\u001b[m"] +[79.870123, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 36 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 99 of 100\u001b(B\u001b[m"] +[79.971647, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 36 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 99 of 100\u001b(B\u001b[m"] +[80.073741, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 36 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 99 of 100\u001b(B\u001b[m"] +[80.175747, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 36 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 99 of 100\u001b(B\u001b[m"] +[80.277164, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 37 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 0 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[80.378683, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 37 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 0 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[80.480234, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 37 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 0 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[80.581874, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 37 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 0 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[80.683229, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 37 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 0 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[80.785804, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 38 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[80.885944, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 38 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[80.987539, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 38 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[81.089169, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 38 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[81.190867, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 38 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[81.292406, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 38 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[81.394165, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 39 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[81.495541, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 39 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[81.597467, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 39 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[81.698679, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 39 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[81.801373, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 39 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[81.903162, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 39 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[82.004428, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 39 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[82.105933, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 40 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[82.208512, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 40 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[82.309349, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 40 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[82.410963, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 40 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[82.512826, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 40 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[82.614363, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 40 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[82.715762, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[82.821539, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[82.922969, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[83.024152, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[83.125423, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[83.227147, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[83.328007, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[83.430005, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] +[83.531829, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[83.632459, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[83.734815, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[83.835908, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[83.937544, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[84.038933, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[84.14006, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[84.145521, "o", "\r\n\u001b[A\u001b[K\r\n\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[84.145931, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[2mtool result - 3 Content Blocks\u001b(B\u001b[m\r\n\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[84.158768, "o", "\r\u001b[5S\u001b[5A\u001b[1m\u001b[2m[\u001b(B\u001b[m\u001b[2mIMAGE: image/webp, \u001b[36m\u001b[1m81600\u001b(B\u001b[m\u001b[2m bytes\u001b[1m]\u001b(B\u001b[m\u001b[K\r\n\u001b[2mImage URL: \u001b(B\u001b[m\u001b[K\r\n\u001b[94m\u001b[2m\u001b[4mhttps://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e36f3f51ecd2d99c31d1850\u001b[32;1H622329ce1beeb60328e1b4b76f76cf/image.webp\u001b(B\u001b[m\u001b[K\r\n\u001b[2mSeed used for generation: \u001b[36m\u001b[1m2131209976\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[35m\u001b[2m▎▶ 43 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[84.240713, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[84.344217, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] +[84.411872, "o", "\r\u001b[K\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[84.41228, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[84.445088, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[84.547179, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[84.649034, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[84.691447, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[84.793092, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[84.894379, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[84.995913, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[85.097413, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[85.1985, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[85.300335, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[85.401772, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[85.503232, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[85.60467, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[85.706171, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[85.807738, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[85.909167, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[86.010494, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[86.112067, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[86.212595, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[86.313905, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[86.415762, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[86.51712, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[86.618401, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[86.719804, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[86.82156, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[86.923102, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[87.025205, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[87.126422, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[87.211734, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m 1 ⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[87.221132, "o", "\r\u001b[K"] +[87.224078, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\r\u001b[2S\u001b[32;3H \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5\u001b(B\u001b[m\r\n\u001b[K\r\nHere\u001b[K●\r\n\u001b[33;6H \r\n\u001b[K"] +[87.241425, "o", "\u001b[AHere’s● \r\n"] +[87.265331, "o", "\u001b[AHere’s your● \r\n"] +[87.287919, "o", "\u001b[AHere’s your sunflower image● \r\n"] +[87.307025, "o", "\u001b[AHere’\r\n\n\u001b[32;6Hs your sunflower image: \u001b[34;1H\u001b[K●\r\n\u001b[33;2H \r\n\u001b[K"] +[87.328542, "o", "\u001b[A![● \r\n"] +[87.35174, "o", "\u001b[A![Sun● \r\n"] +[87.370723, "o", "\u001b[A![Sunflower● \r\n"] +[87.39, "o", "\u001b[A![Sunflower](● \r\n"] +[87.433465, "o", "\u001b[A![Sunflower](https://● \r\n"] +[87.445023, "o", "\u001b[A![Sunflower](https://eval● \r\n"] +[87.457552, "o", "\u001b[A![Sunflower](https://evalstate● \r\n"] +[87.475898, "o", "\u001b[A![Sunflower](https://evalstate-fl● \r\n"] +[87.495485, "o", "\u001b[A![Sunflower](https://evalstate-flux● \r\n"] +[87.523071, "o", "\u001b[A![Sunflower](https://evalstate-flux1-s● \r\n"] +[87.547349, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schn● \r\n"] +[87.562927, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell● \r\n"] +[87.587818, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.h● \r\n"] +[87.604551, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf● \r\n"] +[87.651213, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--● \r\n"] +[87.670648, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--rep● \r\n"] +[87.695252, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas● \r\n"] +[87.722538, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrb● \r\n"] +[87.742654, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs● \r\n"] +[87.760802, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gr● \r\n"] +[87.78157, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio● \r\n"] +[87.815762, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file● \r\n"] +[87.831917, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/● \r\n"] +[87.852297, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp● \r\n"] +[87.873785, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gr● \r\n"] +[87.890333, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio● \r\n"] +[87.939559, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/● \r\n"] +[87.958223, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9● \r\n"] +[87.975445, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab● \r\n"] +[87.987691, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19● \r\n"] +[88.007657, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8● \r\n"] +[88.027447, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd● \r\n"] +[88.051712, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11● \r\n"] +[88.065466, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e● \r\n"] +[88.109712, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e36● \r\n"] +[88.123212, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e36f● \r\n"] +[88.158119, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e36f3f● \r\n"] +[88.186968, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e36f3f51e\r\ncd●\r\n\u001b[33;4H \r\n\u001b[K"] +[88.201249, "o", "\u001b[Acd2● \r\n"] +[88.22907, "o", "\u001b[Acd2d● \r\n"] +[88.254238, "o", "\u001b[Acd2d99● \r\n"] +[88.27019, "o", "\u001b[Acd2d99c● \r\n"] +[88.288178, "o", "\u001b[Acd2d99c31● \r\n"] +[88.306732, "o", "\u001b[Acd2d99c31d185● \r\n"] +[88.331045, "o", "\u001b[Acd2d99c31d185062● \r\n"] +[88.352131, "o", "\u001b[Acd2d99c31d1850622329ce1● \r\n"] +[88.373179, "o", "\u001b[Acd2d99c31d1850622329ce1be● \r\n"] +[88.394161, "o", "\u001b[Acd2d99c31d1850622329ce1beeb603● \r\n"] +[88.412303, "o", "\u001b[Acd2d99c31d1850622329ce1beeb60328● \r\n"] +[88.434009, "o", "\u001b[Acd2d99c31d1850622329ce1beeb60328e● \r\n"] +[88.453285, "o", "\u001b[Acd2d99c31d1850622329ce1beeb60328e1● \r\n"] +[88.467617, "o", "\u001b[Acd2d99c31d1850622329ce1beeb60328e1b● \r\n"] +[88.489365, "o", "\u001b[Acd2d99c31d1850622329ce1beeb60328e1b4b● \r\n"] +[88.520553, "o", "\u001b[Acd2d99c31d1850622329ce1beeb60328e1b4b76● \r\n"] +[88.583235, "o", "\u001b[Acd2d99c31d1850622329ce1beeb60328e1b4b76f76cf/image● \r\n"] +[88.625902, "o", "\u001b[2A🌆 Sunflower ● \r\n\u001b[K\r\n"] +[88.793567, "o", "\u001b[2A🌆 Sunflower \r\n\u001b[?12l\u001b[?25h"] +[89.039961, "o", "\r\n"] +[89.391573, "o", "\u001b[34S\u001b[H \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\u001b[7S\u001b[27;34H \r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n\u001b[K\u001b[H"] +[89.446279, "o", "SIXEL IMAGE (96x33)+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[34;1H"] +[89.46412, "o", "\u001b[?25l\u001b[H \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\u001b[2m\r\nImage URL: \u001b(B\u001b[m\u001b[K\u001b[2m\r\nhttps://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e36f3f51ecd2d99c31d1850\u001b[25;1H622329ce1beeb60328e1b4b76f76cf/image.webp\u001b(B\u001b[m\u001b[K\u001b[2m\r\nSeed used for generation: 2131209976\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[2m\r\nLast turn: \u001b[36m\u001b[1m7\u001b(B\u001b[m\u001b[2m,\u001b[36m\u001b[1m487\u001b(B\u001b[m\u001b[2m Input, \u001b[36m\u001b[1m85\u001b(B\u001b[m\u001b[2m Output \u001b[1m(\u001b[36m2.8\u001b(B\u001b[m\u001b[2m%\u001b[1m)\u001b(B\u001b[m \u001b[92m*\u001b[39m\u001b[K\u001b[93m\r\n❯\u001b[39m\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[HSIXEL IMAGE (96x22)+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++"] +[89.464182, "o", "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n\u001b(B\u001b[m\u001b[?25l\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[?12l\u001b[?25h\u001b[29;3H"] +[89.471882, "o", "\u001b[?25l\u001b[H \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\u001b[2m\r\nImage URL: \u001b(B\u001b[m\u001b[K\u001b[2m\r\nhttps://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e36f3f51ecd2d99c31d1850\u001b[24;1H622329ce1beeb60328e1b4b76f76cf/image.webp\u001b(B\u001b[m\u001b[K\u001b[2m\r\nSeed used for generation: 2131209976\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[2m\r\nLast turn: \u001b[36m\u001b[1m7\u001b(B\u001b[m\u001b[2m,\u001b[36m\u001b[1m487\u001b(B\u001b[m\u001b[2m Input, \u001b[36m\u001b[1m85\u001b(B\u001b[m\u001b[2m Output \u001b[1m(\u001b[36m2.8\u001b(B\u001b[m\u001b[2m%\u001b[1m)\u001b(B\u001b[m \u001b[92m*\u001b[39m\u001b[K\u001b[93m\r\n❯\u001b[39m\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[30m\u001b[47m\u001b[7m\r\n \u001b[34m\u001b[40m dev[S] \u001b[30m\u001b[47m \u001b[32m\u001b[40mTVD\u001b[30m\u001b[100m ▲ \u001b[42m⢠\u001b[43m⡆\u001b[47m \u001b[42m∞gpt-5.5\u001b[100m»⊕\u001b[47m | 2.78% | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | source/fast-agent-pr | fast-agent 0.7.11 \u001b[1;1HSIXEL IMAGE (96x21)+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"] +[89.471944, "o", "+++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n\u001b(B\u001b[m\u001b[?25l\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[?12l\u001b[?25h\u001b[28;3H"] diff --git a/docs/docs/guides/tui.md b/docs/docs/guides/tui.md index 3d3d45a34..aac7c95ab 100644 --- a/docs/docs/guides/tui.md +++ b/docs/docs/guides/tui.md @@ -161,6 +161,128 @@ logger: For example, use `LOGGER__TERMINAL_IMAGES__ENABLED=false` to disable terminal image rendering or `LOGGER__TERMINAL_IMAGES__BACKEND=kitty` to choose a backend. +The recording below is a review capture of image generation through the Hugging Face MCP server. +It was recorded with `FAST_AGENT_KEYRING_NOTICE=0` so the OS keyring access notice does not appear +in the cast, and with `LOGGER__TERMINAL_IMAGES__ENABLED=true` so terminal image output is enabled: + +```bash +export FAST_AGENT_KEYRING_NOTICE=0 +export LOGGER__TERMINAL_IMAGES__ENABLED=true +uv run fast-agent -x --model codexplan --url https://huggingface.co/mcp +``` + +Prompt: + +```text +generate an image of a sunflower +``` + +In this environment the terminal preview is captured by asciinema as SIXEL-style terminal frames +(`SIXEL IMAGE (...) +++++...`) rather than as a separate image asset. The Markdown image link and +source URL remain visible in the recording. + +
+ + +
+ + + +
+
+
+ + + ### Paste and Attach Images / Documents You can attach images and documents using `/attach` or by using the `^` syntax. The indicator in the status bar shows a count of attachments, and is green if they are found, red if there is an error. Press ++f10++ to clear all attachments. From 32a317a305e0a5190bdcb8d2e43a8e95b87add9f Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Mon, 25 May 2026 21:31:07 +0100 Subject: [PATCH 51/58] Use halfcell backend for TUI image cast --- docs/docs/assets/tui/hf-image-generation.cast | 1216 ++++++++--------- docs/docs/guides/tui.md | 9 +- docs/docs/ref/docs_automation.md | 8 +- 3 files changed, 604 insertions(+), 629 deletions(-) diff --git a/docs/docs/assets/tui/hf-image-generation.cast b/docs/docs/assets/tui/hf-image-generation.cast index 8bf4b5396..dbf73a392 100644 --- a/docs/docs/assets/tui/hf-image-generation.cast +++ b/docs/docs/assets/tui/hf-image-generation.cast @@ -1,620 +1,596 @@ -{"version": 2, "width": 120, "height": 34, "timestamp": 1779740052, "idle_time_limit": 1.3, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}, "title": "fast-agent HF MCP image generation experiment"} -[0.031875, "o", "\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004h\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[c\u001b[>c\u001b[>q\u001b]10;?\u001b\\\u001b]11;?\u001b\\\u001b[1;1H\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[H"] -[0.032389, "o", "\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[1;1H\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[H"] -[0.414887, "o", "\u001b[33m\u001b[1mwarning\u001b[39m:\u001b(B\u001b[m \u001b[1m`VIRTUAL_ENV=/home/shaun/source/fast-agent-docs-update/.venv` does not match the project environment path `.venv` and will be ignored; use `--active` to target the active environment instead\r\n\u001b(B\u001b[m"] -[0.536251, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] -[4.59083, "o", "\u001b[?25l"] -[5.036106, "o", "\u001b[?7727h\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[3;1H\u001b[?25l\u001b[33m\u001b[1m\u001b[Hwarning\u001b[39m:\u001b(B\u001b[m \u001b[1m`VIRTUAL_ENV=/home/shaun/source/fast-agent-docs-update/.venv` does not match the project environment path `.venv` and will be ignored; use `--active` to target the active environment instead\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[3d"] -[5.208707, "o", "\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[5.209614, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[5.22259, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[5.325514, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[5.427988, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[5.530509, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[5.632153, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[5.733572, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[5.835471, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[5.936917, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[6.038162, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[6.140059, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[6.240405, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[6.342288, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[6.444693, "o", "\r\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[6.500899, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[6.546603, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[6.648666, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[6.749995, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[6.85135, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[6.95245, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[7.054307, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[7.156372, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[7.257875, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[7.359661, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[7.460017, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[7.561563, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[7.663626, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[7.765525, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[7.866897, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[7.967816, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[8.076998, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[8.178122, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[8.2796, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[8.381226, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[8.48354, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[8.587495, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] -[8.673891, "o", "\r\u001b[K\u001b[?12l\u001b[?25h"] -[8.687765, "o", "\u001b[2mUse \u001b[32m'/'\u001b[39m for commands, \u001b[32m'!'\u001b[39m for shell. \u001b[32m'#'\u001b[39m to query, \u001b[32m'@'\u001b[39m to switch agents\r\nCTRL+T multiline, CTRL+Y copy last message, CTRL+E external editor.\r\nCTRL+Space or Tab for path completion. Use \u001b[35m/\u001b[95mattach\u001b[39m, `^file:`, `^url:`, or \u001b[33mCtrl+Alt+V\u001b[39m for attachments \u001b[1m(\u001b(B\u001b[m\u001b[2mexperimental\u001b[1m)\u001b(B\u001b[m\u001b[2m. F10\u001b[6;1Hto clear.\r\n\u001b(B\u001b[m"] -[8.688, "o", "\u001b[2mModel shortcuts:\r\n\u001b(B\u001b[m"] -[8.688144, "o", "\u001b[2m Shift+Tab = Service tier \u001b[1m(\u001b(B\u001b[m\u001b[2mstandard, fast\u001b[1m)\r\n\u001b(B\u001b[m"] -[8.688371, "o", "\u001b[2m F6 = Reasoning \u001b[1m(\u001b(B\u001b[m\u001b[2mnone, low, medium, high, xhigh\u001b[1m)\r\n\u001b(B\u001b[m"] -[8.688425, "o", "\u001b[2m F7 = Verbosity \u001b[1m(\u001b(B\u001b[m\u001b[2mlow, medium, high\u001b[1m)\r\n\u001b(B\u001b[m"] -[8.688682, "o", "\u001b[2m F8 = Web search \u001b[1m(\u001b(B\u001b[m\u001b[2mon, off\u001b[1m)\r\n\u001b(B\u001b[m\r\n"] -[8.689171, "o", "\u001b[2mfast-agent environment\u001b(B\u001b[m \u001b[34m~/source/fast-agent-pr/.fast-agent\u001b[39m\u001b[2m \u001b[1m(\u001b[36m3\u001b(B\u001b[m\u001b[2m agents, \u001b[36m\u001b[1m4\u001b(B\u001b[m\u001b[2m hooks, \u001b[36m\u001b[1m3\u001b(B\u001b[m\u001b[2m extensions, \u001b[36m\u001b[1m2\u001b(B\u001b[m\u001b[2m modelrefs\u001b[1m)\u001b(B\u001b[m\u001b[2m via cli\r\n\u001b(B\u001b[m"] -[8.689384, "o", "\u001b[33m\u001b[1mAgents have shell\u001b(B\u001b[m\u001b[2m (skills, switch, sub-agent, bash | cwd: source/fast-agent-pr)\r\n\u001b(B\u001b[m"] -[8.858303, "o", "\u001b[2mAgent \u001b(B\u001b[m\u001b[34mdev\u001b[39m\u001b[2m:\u001b(B\u001b[m \u001b[36m\u001b[1m2\u001b(B\u001b[m\u001b[2m child agents. \u001b(B\u001b[m\u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m MCP Server \u001b[1m(\u001b(B\u001b[m\u001b[36m\u001b[1m27\u001b(B\u001b[m\u001b[2m tools, \u001b(B\u001b[m\u001b[36m\u001b[1m4\u001b(B\u001b[m\u001b[2m prompts, \u001b(B\u001b[m\u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m resource\u001b[1m)\u001b(B\u001b[m\u001b[2m. \u001b(B\u001b[m\u001b[36m\u001b[1m3\u001b(B\u001b[m\u001b[2m skills available\r\n\u001b(B\u001b[m"] -[8.858745, "o", "\r\n"] -[8.859213, "o", "\u001b[2mInteractive MCP app integrations detected:\r\n\u001b(B\u001b[m"] -[8.860274, "o", "\u001b[2m ● \u001b(B\u001b[m\u001b[36mhuggingface_co\u001b[39m\u001b[2m — \u001b(B\u001b[m\u001b[36mMCP Apps\u001b[39m\u001b[2m: \u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m tools, \u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m resources\r\n\u001b(B\u001b[m"] -[8.861265, "o", "\u001b[2m · \u001b(B\u001b[mhuggingface_co__file_manager \r\n\u001b[1m\u001b[2m(\u001b(B\u001b[m\u001b[2mui:\u001b[35m//hf-mcp-proxy/hf_files/\u001b[95mdWk6Ly9wcmVmYWIvdG9vbC81MDY1Y2UwYTAxMjEvcmVuZGVyZXIuaHRtbA\u001b[39m\u001b[1m)\r\n\u001b(B\u001b[m"] -[8.986702, "o", "\u001b[2m ├─ \u001b(B\u001b[m\u001b[34mripgrep_oss\u001b[39m\u001b[2m: No MCP Servers\r\n\u001b(B\u001b[m"] -[8.987036, "o", "\u001b[2m └─ \u001b(B\u001b[m\u001b[34mripgrep_spark\u001b[39m\u001b[2m: No MCP Servers\r\n\u001b(B\u001b[m"] -[8.987264, "o", "\u001b[2mStreaming Enabled - markdown mode\u001b[25;1H\u001b(B\u001b[m"] -[8.990058, "o", "\r\n\u001b[J\u001b[A\u001b[K\u001b[93m❯\u001b[C\u001b(B\u001b[m"] -[8.995128, "o", "\u001b[34;1H\u001b[30m\u001b[47m\u001b[7m \u001b[34m\u001b[40m dev[S] \u001b[30m\u001b[47m \u001b[32m\u001b[40mTVD\u001b[30m\u001b[100m ▲ \u001b[42m⢠\u001b[43m⡆\u001b[47m \u001b[42m∞gpt-5.5\u001b[100m»⊕\u001b[47m | 0.00% | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | source/fast-agent-pr | fast-agent 0.7.11 \u001b[25;3H\u001b(B\u001b[m"] -[47.562541, "o", "generate an image of a sunflower"] -[47.565172, "o", "\r\u001b[93m❯\u001b[39m generate an image of a sunflower\u001b[34;1H \u001b[K\u001b[25;35H"] -[47.565364, "o", "\r\n\u001b[J\u001b[A\u001b[K"] -[47.575327, "o", "\u001b[A"] -[47.576211, "o", "\u001b[?25l"] -[47.578078, "o", "\r\n"] -[47.578343, "o", "\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m \u001b[34mdev\u001b[39m \u001b[2m─────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[26;1H\u001b(B\u001b[m"] -[47.579099, "o", "generate an image of a sunflower\r\n"] -[47.816751, "o", "\u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[47.817405, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[47.879775, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[47.981156, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[48.082655, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[48.184064, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[48.284777, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[48.386133, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[48.487545, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[48.588324, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[48.689727, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[48.790995, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[48.892555, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[48.993869, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[49.095283, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[49.1973, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[49.298946, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[49.400483, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[49.501827, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[49.603069, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[49.705296, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[49.806567, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[49.908332, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] -[49.935216, "o", "\r\u001b[K\u001b[33m▎\u001b[2m◀\u001b(B\u001b[m\u001b[33m 33 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 (summary) turn 1\u001b(B\u001b[m"] -[49.944567, "o", "\r\u001b[K"] -[49.946738, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5\u001b[29;1H\u001b[1m\u001b[3mExploring image generation\u001b(B\u001b[m \u001b[31;1H\u001b[2m\u001b[3mI●\u001b(B\u001b[m \r\n"] -[49.97876, "o", "\u001b[A\u001b[2m\u001b[3mI realize I●\u001b(B\u001b[m \r\n"] -[49.99082, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need●\u001b(B\u001b[m \r\n"] -[50.003764, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to●\u001b(B\u001b[m \r\n"] -[50.018928, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find●\u001b(B\u001b[m \r\n"] -[50.03319, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an●\u001b(B\u001b[m \r\n"] -[50.053206, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach●\u001b(B\u001b[m \r\n"] -[50.07649, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer●\u001b(B\u001b[m \r\n"] -[50.091148, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving●\u001b(B\u001b[m \r\n"] -[50.104464, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF●\u001b(B\u001b[m \r\n"] -[50.117777, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic●\u001b(B\u001b[m \r\n"] -[50.138797, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic space●\u001b(B\u001b[m \r\n"] -[50.154075, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic space. It●\u001b(B\u001b[m \r\n"] -[50.174879, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic space. It seems likely●\u001b(B\u001b[m \r\n"] -[50.189684, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic space. It seems likely that●\u001b(B\u001b[m \r\n"] -[50.209999, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic space. It seems likely that I'll be●\u001b(B\u001b[m \r\n"] -[50.226258, "o", "\u001b[A\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic space. It seems likely that I'll be \u001b(B\u001b[m \r\n\u001b[2m\u001b[3mfocusing●\u001b(B\u001b[m \r\n"] -[50.244906, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on●\u001b(B\u001b[m \r\n"] -[50.261629, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image●\u001b(B\u001b[m \r\n"] -[50.275927, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation●\u001b(B\u001b[m \r\n"] -[50.297042, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and●\u001b(B\u001b[m \r\n"] -[50.317105, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it●\u001b(B\u001b[m \r\n"] -[50.33177, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works●\u001b(B\u001b[m \r\n"] -[50.34773, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works.●\u001b(B\u001b[m \r\n"] -[50.366293, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll●\u001b(B\u001b[m \r\n"] -[50.384427, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking●\u001b(B\u001b[m \r\n"] -[50.419089, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods●\u001b(B\u001b[m \r\n"] -[50.443715, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and●\u001b(B\u001b[m \r\n"] -[50.462144, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and techniques●\u001b(B\u001b[m \r\n"] -[50.48232, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and techniques used●\u001b(B\u001b[m \r\n"] -[50.497204, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and techniques used in●\u001b(B\u001b[m \r\n"] -[50.522884, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and techniques used in this area●\u001b(B\u001b[m \r\n"] -[50.548149, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and techniques used in this area to●\u001b(B\u001b[m \r\n"] -[50.562863, "o", "\u001b[A\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and techniques used in this area to \u001b(B\u001b[m \r\n\u001b[2m\u001b[3mprepare●\u001b(B\u001b[m \r\n"] -[50.585285, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive●\u001b(B\u001b[m \r\n"] -[50.599588, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response●\u001b(B\u001b[m \r\n"] -[50.611128, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response.●\u001b(B\u001b[m \r\n"] -[50.625152, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It●\u001b(B\u001b[m \r\n"] -[50.641796, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels●\u001b(B\u001b[m \r\n"] -[50.668894, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like●\u001b(B\u001b[m \r\n"] -[50.719911, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite●\u001b(B\u001b[m \r\n"] -[50.757686, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a●\u001b(B\u001b[m \r\n"] -[50.784478, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit●\u001b(B\u001b[m \r\n"] -[50.811146, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to●\u001b(B\u001b[m \r\n"] -[50.857014, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn,●\u001b(B\u001b[m \r\n"] -[50.877573, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but●\u001b(B\u001b[m \r\n"] -[50.891858, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm●\u001b(B\u001b[m \r\n"] -[50.907674, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking●\u001b(B\u001b[m \r\n"] -[50.92336, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking forward●\u001b(B\u001b[m \r\n"] -[50.93889, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking forward to●\u001b(B\u001b[m \r\n"] -[50.955491, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking forward to uncover●\u001b(B\u001b[m \r\n"] -[50.971752, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking forward to uncovering●\u001b(B\u001b[m \r\n"] -[50.994358, "o", "\u001b[A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking forward to uncovering \u001b(B\u001b[m \r\n\u001b[2m\u001b[3mhow●\u001b(B\u001b[m\r\n\u001b[33;5H \r\n\u001b[K"] -[51.023884, "o", "\u001b[2A\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking forward to uncovering how\r\nimage generation●\u001b(B\u001b[m \r\n"] -[51.04514, "o", "\u001b[A\u001b[2m\u001b[3mimage generation operates●\u001b(B\u001b[m \r\n"] -[51.061572, "o", "\u001b[A\u001b[2m\u001b[3mimage generation operates within●\u001b(B\u001b[m \r\n"] -[51.085724, "o", "\u001b[A\u001b[2m\u001b[3mimage generation operates within these●\u001b(B\u001b[m \r\n"] -[51.100471, "o", "\u001b[A\u001b[2m\u001b[3mimage generation operates within these frameworks●\u001b(B\u001b[m \r\n"] -[51.128969, "o", "\u001b[A\u001b[2m\u001b[3mimage generation operates within these frameworks!●\u001b(B\u001b[m \r\n"] -[51.261062, "o", "\u001b[A\u001b[2m\u001b[3mimage generation operates within these frameworks!\u001b(B\u001b[m \r\n\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[35mhuggingface_co__dynamic_space\r\n\u001b[39m{\"operation\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] -[51.278713, "o", "\u001b[A{\"operation\":\"discover\u001b[2m●\r\n\u001b(B\u001b[m"] -[51.300997, "o", "\u001b[A{\"operation\":\"discover\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[51.324612, "o", "\u001b[A{\"operation\":\"discover\",\"space\u001b[2m●\r\n\u001b(B\u001b[m"] -[51.347628, "o", "\u001b[A{\"operation\":\"discover\",\"space_name\u001b[2m●\r\n\u001b(B\u001b[m"] -[51.366405, "o", "\u001b[A{\"operation\":\"discover\",\"space_name\":\"\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[51.394935, "o", "\u001b[A{\"operation\":\"discover\",\"space_name\":\"\",\"parameters\u001b[2m●\r\n\u001b(B\u001b[m"] -[51.413989, "o", "\u001b[A{\"operation\":\"discover\",\"space_name\":\"\",\"parameters\":\"\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[51.435493, "o", "\u001b[A{\"operation\":\"discover\",\"space_name\":\"\",\"parameters\":\"\"}\u001b[2m●\r\n\u001b(B\u001b[m"] -[51.609133, "o", "\u001b[4S\u001b[5A{\u001b[K\r\n \"operation\": \"discover\",\r\n \"space_name\": \"\",\u001b[K\r\n \"parameters\": \"\"\u001b[K\r\n}\u001b[K\r\n\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] -[51.643585, "o", "\u001b[15A\u001b[K\u001b[2B\u001b[K\u001b[2B\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[14A\u001b[?12l\u001b[?25h"] -[51.663617, "o", "\r\n\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5 ↗ (1.90%)\r\n\u001b(B\u001b[m"] -[51.664377, "o", "\u001b[1m\u001b[2m\u001b[3mExploring image generation\u001b(B\u001b[m \u001b[23;1H\u001b[2m\u001b[3mI realize I need to find an appropriate approach to answer involving HF dynamic space. It seems likely that I'll be \u001b(B\u001b[m \u001b[24;1H\u001b[2m\u001b[3mfocusing on image generation and how it works. I'll keep looking into methods and techniques used in this area to \u001b(B\u001b[m \u001b[25;1H\u001b[2m\u001b[3mprepare a comprehensive response. It feels like there's quite a bit to learn, but I'm looking forward to uncovering how \u001b[26;1Himage generation operates within these frameworks!\u001b(B\u001b[m \u001b[27;1H"] -[51.664459, "o", "\u001b[32m\u001b[2m\u001b[3mThe assistant requested tool calls\r\n\u001b(B\u001b[m"] -[51.664695, "o", "\r\n"] -[51.665067, "o", "\u001b[2m▎ \u001b[37mbash\u001b[39m • \u001b(B\u001b[m\u001b[92mhuggingface…\u001b[39m\u001b[2m • \u001b[37mskill\u001b[39m • \u001b[37mcard_tools\u001b[39m • \u001b[37mripgrep_oss\u001b[39m • \u001b[37mripgrep_spa…\r\n\u001b(B\u001b[m\r\n"] -[51.725839, "o", "\r\n"] -[51.726305, "o", "\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m \u001b[35mdev\u001b[39m \u001b[2mtool call - huggingface_co__dynamic_space\r\n\u001b(B\u001b[m"] -[51.733675, "o", "\u001b[1m\u001b[2m{\u001b(B\u001b[m\u001b[32m\u001b[2m'operation'\u001b[39m: \u001b[32m'discover'\u001b[39m, \u001b[32m'space_name'\u001b[39m: \u001b[32m''\u001b[39m, \u001b[32m'parameters'\u001b[39m: \u001b[32m''\u001b[39m\u001b[1m}\r\n\u001b(B\u001b[m"] -[51.734051, "o", "\n\u001b[K"] -[51.73441, "o", "\u001b[2m▎ \u001b[37mhf_whoami\u001b[39m • \u001b[37mhub_repo_se…\u001b[39m • \u001b[37mpaper_search\u001b[39m • \u001b[37mhub_repo_de…\u001b[39m • \u001b[37mhf_jobs\u001b[39m • \u001b(B\u001b[m\u001b[35mdynamic_spa…\u001b[39m\u001b[2m • \u001b[37mwrite_file\u001b[39m • \u001b[37mlist_files\u001b[39m •\u001b(B\u001b[m\r\n\u001b[33;110H\u001b[2m \u001b[37mread_file\u001b[39m \u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[2m…\u001b(B\u001b[m\r\n\u001b[K\n\u001b[K"] -[51.735982, "o", "\u001b[?25l"] -[51.736772, "o", "\u001b[33m▎\u001b[2m◀\u001b(B\u001b[m\u001b[33m 432 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 (summary) turn 1\u001b(B\u001b[m"] -[51.737665, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m 51 ⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 turn 1 \u001b(B\u001b[m"] -[51.739255, "o", "\r\u001b[K\u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space \u001b(B\u001b[m"] -[51.740583, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] -[51.838771, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] -[51.940278, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] -[51.971071, "o", "\r\n\u001b[A\u001b[K\r\n\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] -[51.971614, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[2mtool result - text only 2333 chars\u001b(B\u001b[m\r\n\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] -[51.972641, "o", "\r\u001b[9S\u001b[9A\u001b[2m**Available Spaces:**\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2mThese spaces can be invoked using the `dynamic_space` tool.\u001b(B\u001b[m\u001b[K\r\n\u001b[2mUse `\u001b[32m\"operation\"\u001b[39m: \u001b[32m\"view_parameters\"\u001b[39m` to inspect a space's parameters before invoking.\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m| Space ID | Category | Description |\u001b(B\u001b[m\u001b[K\r\n\u001b[2m|----------|----------|-------------|\u001b(B\u001b[m\u001b[K\r\n\u001b[2m| `evalstate/flux1\\_schnell` | Image Generation | Simple, fast image generator. Use for quick tests and ideas. |\u001b(B\u001b[m\u001b[K\r\n\u001b[2m|\u001b[33m...\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[35m\u001b[2m▎◀ Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] -[52.043428, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] -[52.145576, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_mx1T88AH…\u001b(B\u001b[m"] -[52.200946, "o", "\r\u001b[K\u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[52.201814, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[52.246844, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[52.348756, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[52.43745, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[52.538754, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[52.640581, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[52.742077, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[52.843813, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[52.944522, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[53.046273, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[53.147156, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[53.248962, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[53.350533, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[53.451978, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[53.553895, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[53.654577, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[53.757163, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[53.858257, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[53.960016, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[54.061612, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[54.163846, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[54.265567, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[54.367449, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[54.468707, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[54.495761, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞\u001b(B\u001b[m\r\n\u001b[33;32H\u001b[37m\u001b[2mgpt-5.5 turn 2 \u001b(B\u001b[m\r\n\u001b[K\u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start)\u001b(B\u001b[m"] -[54.497275, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_j1nuF2zE…\u001b(B\u001b[m"] -[54.569871, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_j1nuF2zE…\u001b(B\u001b[m"] -[54.581135, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A"] -[54.581626, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\r\n\n\u001b[32;3H \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5\u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[35mhuggingface_co__dynamic_space\r\n\u001b[39m{\"\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] -[54.635955, "o", "\u001b[A{\"operation\u001b[2m●\r\n\u001b(B\u001b[m"] -[54.689234, "o", "\u001b[A{\"operation\":\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[54.746382, "o", "\u001b[A{\"operation\":\"view\u001b[2m●\r\n\u001b(B\u001b[m"] -[54.811214, "o", "\u001b[A{\"operation\":\"view_parameters\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[54.882793, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space\u001b[2m●\r\n\u001b(B\u001b[m"] -[54.936755, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[54.997512, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"eval\u001b[2m●\r\n\u001b(B\u001b[m"] -[55.053035, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate\u001b[2m●\r\n\u001b(B\u001b[m"] -[55.125097, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux\u001b[2m●\r\n\u001b(B\u001b[m"] -[55.164492, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1\u001b[2m●\r\n\u001b(B\u001b[m"] -[55.224617, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_s\u001b[2m●\r\n\u001b(B\u001b[m"] -[55.280529, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schn\u001b[2m●\r\n\u001b(B\u001b[m"] -[55.37704, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schnell\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[55.400715, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\u001b[2m●\r\n\u001b(B\u001b[m"] -[55.455053, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\u001b[2m●\r\n\u001b(B\u001b[m"] -[56.444801, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"\"}\u001b[2m●\r\n\u001b(B\u001b[m"] -[56.611262, "o", "\u001b[4S\u001b[5A{\u001b[K\r\n \"operation\": \"view_parameters\",\r\n \"space_name\": \"evalstate/flux1_schnell\",\u001b[K\r\n \"parameters\": \"\"\u001b[K\r\n}\u001b[K\r\n\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] -[56.640135, "o", "\u001b[9A\u001b[K\u001b[2B\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[8A\u001b[?12l\u001b[?25h"] -[56.640585, "o", "\r\n"] -[56.640864, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5 ↔ (2.13%)\r\n\u001b(B\u001b[m"] -[56.640931, "o", "\u001b[32m\u001b[2m\u001b[3mThe assistant requested tool calls\r\n\u001b(B\u001b[m\r\n"] -[56.641107, "o", "\u001b[2m▎ \u001b[37mbash\u001b[39m • \u001b(B\u001b[m\u001b[92mhuggingface…\u001b[39m\u001b[2m • \u001b[37mskill\u001b[39m • \u001b[37mcard_tools\u001b[39m • \u001b[37mripgrep_oss\u001b[39m • \u001b[37mripgrep_spa…\u001b[31;1H\u001b(B\u001b[m"] -[56.656807, "o", "\r\n\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m \u001b[35mdev\u001b[39m \u001b[2mtool call - huggingface_co__dynamic_space\r\n\u001b(B\u001b[m"] -[56.657144, "o", "\u001b[1m\u001b[2m{\u001b(B\u001b[m\u001b[32m\u001b[2m'operation'\u001b[39m: \u001b[32m'view_parameters'\u001b[39m, \u001b[32m'space_name'\u001b[39m: \u001b[32m'evalstate/flux1_schnell'\u001b[39m, \u001b[32m'parameters'\u001b[39m: \u001b[32m''\u001b[39m\u001b[1m}\r\n\u001b(B\u001b[m"] -[56.657347, "o", "\n\u001b[K"] -[56.657549, "o", "\u001b[2m▎ \u001b[37mhf_whoami\u001b[39m • \u001b[37mhub_repo_se…\u001b[39m • \u001b[37mpaper_search\u001b[39m • \u001b[37mhub_repo_de…\u001b[39m • \u001b[37mhf_jobs\u001b[39m • \u001b(B\u001b[m\u001b[35mdynamic_spa…\u001b[39m\u001b[2m • \u001b[37mwrite_file\u001b[39m • \u001b[37mlist_files\u001b[39m •\u001b(B\u001b[m\r\n\u001b[33;110H\u001b[2m \u001b[37mread_file\u001b[39m \u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[2m…\u001b(B\u001b[m\r\u001b[2S\u001b[A\u001b[K\r\n\u001b[K"] -[56.658158, "o", "\u001b[?25l"] -[56.658612, "o", "\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] -[56.659313, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m 41 ⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 turn 2 \u001b(B\u001b[m"] -[56.6605, "o", "\r\u001b[K\u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space \u001b(B\u001b[m"] -[56.660794, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] -[56.760712, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] -[56.861094, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] -[56.938133, "o", "\r\n\u001b[A\u001b[K\r\n\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] -[56.938781, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[2mtool result - text only 759 chars\u001b(B\u001b[m\r\n\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] -[56.940673, "o", "\r\u001b[17S\u001b[17d\u001b[2m# Parameters for: flux1_schnell_infer\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m**Description:** Generate an image using the Flux \u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m Schnell Image Generator.\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m## Parameters:\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m### height \u001b[1m[\u001b(B\u001b[m\u001b[2mOPTIONAL\u001b[1m]\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Type:** number\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Default:** \u001b[36m\u001b[1m1024\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m### num_inference_steps \u001b[1m[\u001b(B\u001b[m\u001b[2mOPTIONAL\u001b[1m]\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Type:** number\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Default:** \u001b[36m\u001b[1m4\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m### prompt \u001b[1m[\u001b(B\u001b[m\u001b[2mOPTIONAL\u001b[1m]\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Type:** string\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Description:** Approximately \u001b[36m\u001b[1m60\u001b(B\u001b[m\u001b[2m-\u001b[36m\u001b[1m70\u001b(B\u001b[m\u001b[2m words max - d\u001b[33m...\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[35m\u001b[2m▎◀ Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] -[56.961782, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] -[57.062889, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_j1nuF2zE…\u001b(B\u001b[m"] -[57.160613, "o", "\r\u001b[K\u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[57.160988, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[57.163539, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[57.264413, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[57.365919, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[57.46722, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[57.56891, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[57.670161, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[57.770679, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[57.872331, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[57.974076, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[58.075445, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[58.176545, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[58.277421, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[58.378021, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[58.479651, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[58.580845, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[58.682135, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[58.783715, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[58.885299, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[58.985916, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[59.086945, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[59.188414, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[59.289353, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[59.390202, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[59.492325, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[59.593559, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[59.695117, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[59.797179, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[59.898499, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[60.000177, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[60.101596, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[60.202247, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[60.303754, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[60.405189, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[60.506492, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[60.607856, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[60.709366, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[60.810589, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[60.912215, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[61.013382, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[61.115186, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[61.21673, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[61.318824, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[61.420558, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[61.522143, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[61.623606, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[61.725879, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[61.827035, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[61.928696, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[62.029974, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[62.109921, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞\u001b(B\u001b[m\r\n\u001b[33;32H\u001b[37m\u001b[2mgpt-5.5 turn 3 \u001b(B\u001b[m\r\n\u001b[K\u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start)\u001b(B\u001b[m"] -[62.110125, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[62.13086, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[62.233151, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[62.335709, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[62.437664, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[62.539649, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[62.641606, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[62.744139, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[62.846263, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[62.948127, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[63.050428, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[63.152458, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[63.25427, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[63.356514, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[63.458723, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[63.559643, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[63.661885, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[63.764354, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[63.866397, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[63.968825, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[64.070757, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[64.172357, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[64.273236, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[64.375156, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[64.476989, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[64.578617, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[64.681472, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[64.783058, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[64.885141, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_P4pxye9h…\u001b(B\u001b[m"] -[64.980863, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A"] -[64.981738, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\r\n\n\u001b[32;3H \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5\u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[35mhuggingface_co__dynamic_space\r\n\u001b[39m{\"\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] -[65.000155, "o", "\u001b[A{\"operation\u001b[2m●\r\n\u001b(B\u001b[m"] -[65.151246, "o", "\u001b[A{\"operation\":\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[65.185039, "o", "\u001b[A{\"operation\":\"invoke\u001b[2m●\r\n\u001b(B\u001b[m"] -[65.832878, "o", "\u001b[A{\"operation\":\"invoke\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[65.852396, "o", "\u001b[A{\"operation\":\"invoke\",\"space\u001b[2m●\r\n\u001b(B\u001b[m"] -[65.884882, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[65.907746, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"eval\u001b[2m●\r\n\u001b(B\u001b[m"] -[66.897889, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate\u001b[2m●\r\n\u001b(B\u001b[m"] -[66.913436, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/\u001b[2m●\r\n\u001b(B\u001b[m"] -[66.924766, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux\u001b[2m●\r\n\u001b(B\u001b[m"] -[66.938489, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_s\u001b[2m●\r\n\u001b(B\u001b[m"] -[66.956572, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[66.999512, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\u001b[2m●\r\n\u001b(B\u001b[m"] -[67.012545, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[67.704306, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[67.75864, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\u001b[2m●\r\n\u001b(B\u001b[m"] -[67.771111, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[67.842419, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"A vibrant close\u001b[2m●\r\n\u001b(B\u001b[m"] -[67.863522, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"A vibrant close-up\u001b[2m●\r\n\u001b(B\u001b[m"] -[67.900199, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"A vibrant close-up photograph \r\nof a\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] -[67.919201, "o", "\u001b[Aof a single sunflower\u001b[2m●\r\n\u001b(B\u001b[m"] -[68.485011, "o", "\u001b[Aof a single sunflower in\u001b[2m●\r\n\u001b(B\u001b[m"] -[68.568733, "o", "\u001b[Aof a single sunflower in full\u001b[2m●\r\n\u001b(B\u001b[m"] -[68.645127, "o", "\u001b[Aof a single sunflower in full bloom\u001b[2m●\r\n\u001b(B\u001b[m"] -[69.665603, "o", "\u001b[Aof a single sunflower in full bloom,\u001b[2m●\r\n\u001b(B\u001b[m"] -[69.676945, "o", "\u001b[Aof a single sunflower in full bloom, golden\u001b[2m●\r\n\u001b(B\u001b[m"] -[69.691545, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radi\u001b[2m●\r\n\u001b(B\u001b[m"] -[69.810214, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating\u001b[2m●\r\n\u001b(B\u001b[m"] -[69.959659, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating around a\u001b[2m●\r\n\u001b(B\u001b[m"] -[70.593552, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating around a textured brown\u001b[2m●\r\n\u001b(B\u001b[m"] -[71.288328, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating around a textured brown center\u001b[2m●\r\n\u001b(B\u001b[m"] -[71.359754, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating around a textured brown center,\u001b[2m●\r\n\u001b(B\u001b[m"] -[71.377474, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating around a textured brown center, standing in\u001b[2m●\r\n\u001b(B\u001b[m"] -[71.418417, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating around a textured brown center, standing in a sun\u001b[2m●\r\n\u001b(B\u001b[m"] -[71.993861, "o", "\u001b[Aof a single sunflower in full bloom, golden yellow petals radiating around a textured brown center, standing in a \u001b[K\r\nsunlit\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] -[72.027188, "o", "\u001b[Asunlit summer field with soft green\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.110546, "o", "\u001b[Asunlit summer field with soft green b\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.122607, "o", "\u001b[Asunlit summer field with soft green bokeh\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.166744, "o", "\u001b[Asunlit summer field with soft green bokeh background, warm natural\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.185202, "o", "\u001b[Asunlit summer field with soft green bokeh background, warm natural light, crisp details\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.204897, "o", "\u001b[Asunlit summer field with soft green bokeh background, warm natural light, crisp details, cheerful and\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.242461, "o", "\u001b[Asunlit summer field with soft green bokeh background, warm natural light, crisp details, cheerful and realistic, high\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.262014, "o", "\u001b[Asunlit summer field with soft green bokeh background, warm natural light, crisp details, cheerful and realistic, high \r\nresolution.\\\",\\\"width\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] -[72.282407, "o", "\u001b[Aresolution.\\\",\\\"width\\\":\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.303865, "o", "\u001b[Aresolution.\\\",\\\"width\\\":1024,\\\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.321946, "o", "\u001b[Aresolution.\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.341579, "o", "\u001b[Aresolution.\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.359968, "o", "\u001b[Aresolution.\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.446301, "o", "\u001b[Aresolution.\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.540543, "o", "\u001b[Aresolution.\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"randomize_seed\\\":true}\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.554456, "o", "\u001b[Aresolution.\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"randomize_seed\\\":true}\"}\u001b[2m●\r\n\u001b(B\u001b[m"] -[72.795291, "o", "\u001b[4S\u001b[8A{\u001b[K\r\n \"operation\": \"invoke\",\u001b[K\r\n \"space_name\": \"evalstate/flux1_schnell\",\u001b[K\r\n \"parameters\": \"{\\\"prompt\\\":\\\"A vibrant close-up photograph of a single sunflower in full bloom, golden yellow petals \r\nradiating around a textured brown center, standing in a sunlit summer field with soft green bokeh background, warm \r\nnatural light, crisp details, cheerful and realistic, high \u001b[K\r\nresolution.\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"randomize_seed\\\":true}\"\u001b[K\r\n}\u001b[K\r\n\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] -[72.830613, "o", "\u001b[12A\u001b[K\u001b[2B\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[11A\u001b[?12l\u001b[?25h"] -[72.830984, "o", "\r\n"] -[72.831408, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5 ↔ (2.26%)\r\n\u001b(B\u001b[m"] -[72.831597, "o", "\u001b[32m\u001b[2m\u001b[3mThe assistant requested tool calls\r\n\u001b(B\u001b[m\r\n\u001b[2m▎ \u001b[37mbash\u001b[39m • \u001b(B\u001b[m\u001b[92mhuggingface…\u001b[39m\u001b[2m • \u001b[37mskill\u001b[39m • \u001b[37mcard_tools\u001b[39m • \u001b[37mripgrep_oss\u001b[39m • \u001b[37mripgrep_spa…\r\n\u001b(B\u001b[m\r\n"] -[72.856372, "o", "\r\n\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m \u001b[35mdev\u001b[39m \u001b[2mtool call - huggingface_co__dynamic_space\r\n\u001b(B\u001b[m"] -[72.857136, "o", "\u001b[34d\n\u001b[5A\u001b[1m\u001b[2m{\r\n\u001b(B\u001b[m\u001b[2m \u001b[32m'operation'\u001b[39m: \u001b[32m'invoke'\u001b[39m,\r\n \u001b[32m'space_name'\u001b[39m: \u001b[32m'evalstate/flux1_schnell'\u001b[39m,\r\n \u001b[32m'parameters'\u001b[39m: \u001b[32m'{\"prompt\":\"A vibrant close-up photograph of a sing'\u001b[39m+\u001b[36m\u001b[1m309\r\n\u001b[39m}\u001b(B\u001b[m\r\n\u001b[K\n\u001b[K"] -[72.85744, "o", "\u001b[2m▎ \u001b[37mhf_whoami\u001b[39m • \u001b[37mhub_repo_se…\u001b[39m • \u001b[37mpaper_search\u001b[39m • \u001b[37mhub_repo_de…\u001b[39m • \u001b[37mhf_jobs\u001b[39m • \u001b(B\u001b[m\u001b[35mdynamic_spa…\u001b[39m\u001b[2m • \u001b[37mwrite_file\u001b[39m • \u001b[37mlist_files\u001b[39m •\u001b(B\u001b[m\r\n\u001b[33;110H\u001b[2m \u001b[37mread_file\u001b[39m \u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[2m…\u001b(B\u001b[m\r\u001b[2S\u001b[A\u001b[K\r\n\u001b[K"] -[72.858186, "o", "\u001b[?25l"] -[72.858771, "o", "\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] -[72.859364, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m 119 ⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 turn 3 \u001b(B\u001b[m"] -[72.860605, "o", "\r\u001b[K\u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space \u001b(B\u001b[m"] -[72.861015, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[72.959937, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[73.0618, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[73.163357, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[73.264831, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[73.365381, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[73.467194, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[73.568705, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[73.670377, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[73.771508, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[73.873322, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[73.974648, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[74.076552, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[74.1772, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[74.278916, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[74.379467, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[74.481197, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[74.582728, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[74.686737, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[74.788617, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[74.890127, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[74.991758, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[75.093485, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[75.195197, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[75.29575, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] -[75.397411, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] -[75.498013, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] -[75.600452, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] -[75.701144, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] -[75.803358, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] -[75.905199, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] -[76.006588, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_P4pxye9h…\u001b(B\u001b[m"] -[76.108025, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 2 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 10 of 100\u001b(B\u001b[m"] -[76.209047, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 2 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 10 of 100\u001b(B\u001b[m"] -[76.310283, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 2 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 10 of 100\u001b(B\u001b[m"] -[76.412029, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 3 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 20 of 100\u001b(B\u001b[m"] -[76.513601, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 3 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 20 of 100\u001b(B\u001b[m"] -[76.615539, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 4 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 22 of 100\u001b(B\u001b[m"] -[76.717994, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 5 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 23 of 100\u001b(B\u001b[m"] -[76.819527, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 6 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 25 of 100\u001b(B\u001b[m"] -[76.921727, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 7 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 27 of 100\u001b(B\u001b[m"] -[77.023475, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 8 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 29 of 100\u001b(B\u001b[m"] -[77.124786, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 9 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 31 of 100\u001b(B\u001b[m"] -[77.225329, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 10 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 33 of 100\u001b(B\u001b[m"] -[77.327051, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 11 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 35 of 100\u001b(B\u001b[m"] -[77.42891, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 12 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 37 of 100\u001b(B\u001b[m"] -[77.531255, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 13 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 39 of 100\u001b(B\u001b[m"] -[77.632305, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 14 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 41 of 100\u001b(B\u001b[m"] -[77.735534, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 15 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 44 of 100\u001b(B\u001b[m"] -[77.837028, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 16 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 47 of 100\u001b(B\u001b[m"] -[77.938344, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 17 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 50 of 100\u001b(B\u001b[m"] -[78.039982, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 18 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 53 of 100\u001b(B\u001b[m"] -[78.141571, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 19 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 55 of 100\u001b(B\u001b[m"] -[78.243338, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 20 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 58 of 100\u001b(B\u001b[m"] -[78.344643, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 21 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 61 of 100\u001b(B\u001b[m"] -[78.446248, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 22 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 63 of 100\u001b(B\u001b[m"] -[78.548081, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 23 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 66 of 100\u001b(B\u001b[m"] -[78.64955, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 24 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 69 of 100\u001b(B\u001b[m"] -[78.752774, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 25 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 72 of 100\u001b(B\u001b[m"] -[78.853755, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 26 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 74 of 100\u001b(B\u001b[m"] -[78.95528, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 27 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 76 of 100\u001b(B\u001b[m"] -[79.056671, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 28 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 77 of 100\u001b(B\u001b[m"] -[79.15857, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 30 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 85 of 100\u001b(B\u001b[m"] -[79.260539, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 31 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 86 of 100\u001b(B\u001b[m"] -[79.362617, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 32 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 88 of 100\u001b(B\u001b[m"] -[79.464048, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 33 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 92 of 100\u001b(B\u001b[m"] -[79.565562, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 34 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 95 of 100\u001b(B\u001b[m"] -[79.666655, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 35 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 99 of 100\u001b(B\u001b[m"] -[79.768693, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 36 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 99 of 100\u001b(B\u001b[m"] -[79.870123, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 36 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 99 of 100\u001b(B\u001b[m"] -[79.971647, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 36 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 99 of 100\u001b(B\u001b[m"] -[80.073741, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 36 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 99 of 100\u001b(B\u001b[m"] -[80.175747, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 36 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 99 of 100\u001b(B\u001b[m"] -[80.277164, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 37 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 0 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[80.378683, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 37 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 0 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[80.480234, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 37 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 0 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[80.581874, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 37 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 0 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[80.683229, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 37 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 0 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[80.785804, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 38 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[80.885944, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 38 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[80.987539, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 38 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[81.089169, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 38 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[81.190867, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 38 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[81.292406, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 38 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[81.394165, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 39 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[81.495541, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 39 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[81.597467, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 39 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[81.698679, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 39 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[81.801373, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 39 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[81.903162, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 39 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[82.004428, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 39 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[82.105933, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 40 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[82.208512, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 40 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[82.309349, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 40 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[82.410963, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 40 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[82.512826, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 40 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[82.614363, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 40 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[82.715762, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[82.821539, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[82.922969, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[83.024152, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[83.125423, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[83.227147, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[83.328007, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[83.430005, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 41 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_P4pxye9h…\u001b(B\u001b[m"] -[83.531829, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[83.632459, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[83.734815, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[83.835908, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[83.937544, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[84.038933, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[84.14006, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[84.145521, "o", "\r\n\u001b[A\u001b[K\r\n\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[84.145931, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[2mtool result - 3 Content Blocks\u001b(B\u001b[m\r\n\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[84.158768, "o", "\r\u001b[5S\u001b[5A\u001b[1m\u001b[2m[\u001b(B\u001b[m\u001b[2mIMAGE: image/webp, \u001b[36m\u001b[1m81600\u001b(B\u001b[m\u001b[2m bytes\u001b[1m]\u001b(B\u001b[m\u001b[K\r\n\u001b[2mImage URL: \u001b(B\u001b[m\u001b[K\r\n\u001b[94m\u001b[2m\u001b[4mhttps://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e36f3f51ecd2d99c31d1850\u001b[32;1H622329ce1beeb60328e1b4b76f76cf/image.webp\u001b(B\u001b[m\u001b[K\r\n\u001b[2mSeed used for generation: \u001b[36m\u001b[1m2131209976\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[35m\u001b[2m▎▶ 43 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[84.240713, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[84.344217, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 43 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_P4pxye9h…\u001b(B\u001b[m"] -[84.411872, "o", "\r\u001b[K\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[84.41228, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[84.445088, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[84.547179, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[84.649034, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[84.691447, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[84.793092, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[84.894379, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[84.995913, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[85.097413, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[85.1985, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[85.300335, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[85.401772, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[85.503232, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[85.60467, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[85.706171, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[85.807738, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[85.909167, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[86.010494, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[86.112067, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[86.212595, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[86.313905, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[86.415762, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[86.51712, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[86.618401, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[86.719804, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[86.82156, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[86.923102, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[87.025205, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[87.126422, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[87.211734, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m 1 ⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] -[87.221132, "o", "\r\u001b[K"] -[87.224078, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\r\u001b[2S\u001b[32;3H \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5\u001b(B\u001b[m\r\n\u001b[K\r\nHere\u001b[K●\r\n\u001b[33;6H \r\n\u001b[K"] -[87.241425, "o", "\u001b[AHere’s● \r\n"] -[87.265331, "o", "\u001b[AHere’s your● \r\n"] -[87.287919, "o", "\u001b[AHere’s your sunflower image● \r\n"] -[87.307025, "o", "\u001b[AHere’\r\n\n\u001b[32;6Hs your sunflower image: \u001b[34;1H\u001b[K●\r\n\u001b[33;2H \r\n\u001b[K"] -[87.328542, "o", "\u001b[A![● \r\n"] -[87.35174, "o", "\u001b[A![Sun● \r\n"] -[87.370723, "o", "\u001b[A![Sunflower● \r\n"] -[87.39, "o", "\u001b[A![Sunflower](● \r\n"] -[87.433465, "o", "\u001b[A![Sunflower](https://● \r\n"] -[87.445023, "o", "\u001b[A![Sunflower](https://eval● \r\n"] -[87.457552, "o", "\u001b[A![Sunflower](https://evalstate● \r\n"] -[87.475898, "o", "\u001b[A![Sunflower](https://evalstate-fl● \r\n"] -[87.495485, "o", "\u001b[A![Sunflower](https://evalstate-flux● \r\n"] -[87.523071, "o", "\u001b[A![Sunflower](https://evalstate-flux1-s● \r\n"] -[87.547349, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schn● \r\n"] -[87.562927, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell● \r\n"] -[87.587818, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.h● \r\n"] -[87.604551, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf● \r\n"] -[87.651213, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--● \r\n"] -[87.670648, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--rep● \r\n"] -[87.695252, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas● \r\n"] -[87.722538, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrb● \r\n"] -[87.742654, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs● \r\n"] -[87.760802, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gr● \r\n"] -[87.78157, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio● \r\n"] -[87.815762, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file● \r\n"] -[87.831917, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/● \r\n"] -[87.852297, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp● \r\n"] -[87.873785, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gr● \r\n"] -[87.890333, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio● \r\n"] -[87.939559, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/● \r\n"] -[87.958223, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9● \r\n"] -[87.975445, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab● \r\n"] -[87.987691, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19● \r\n"] -[88.007657, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8● \r\n"] -[88.027447, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd● \r\n"] -[88.051712, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11● \r\n"] -[88.065466, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e● \r\n"] -[88.109712, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e36● \r\n"] -[88.123212, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e36f● \r\n"] -[88.158119, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e36f3f● \r\n"] -[88.186968, "o", "\u001b[A![Sunflower](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e36f3f51e\r\ncd●\r\n\u001b[33;4H \r\n\u001b[K"] -[88.201249, "o", "\u001b[Acd2● \r\n"] -[88.22907, "o", "\u001b[Acd2d● \r\n"] -[88.254238, "o", "\u001b[Acd2d99● \r\n"] -[88.27019, "o", "\u001b[Acd2d99c● \r\n"] -[88.288178, "o", "\u001b[Acd2d99c31● \r\n"] -[88.306732, "o", "\u001b[Acd2d99c31d185● \r\n"] -[88.331045, "o", "\u001b[Acd2d99c31d185062● \r\n"] -[88.352131, "o", "\u001b[Acd2d99c31d1850622329ce1● \r\n"] -[88.373179, "o", "\u001b[Acd2d99c31d1850622329ce1be● \r\n"] -[88.394161, "o", "\u001b[Acd2d99c31d1850622329ce1beeb603● \r\n"] -[88.412303, "o", "\u001b[Acd2d99c31d1850622329ce1beeb60328● \r\n"] -[88.434009, "o", "\u001b[Acd2d99c31d1850622329ce1beeb60328e● \r\n"] -[88.453285, "o", "\u001b[Acd2d99c31d1850622329ce1beeb60328e1● \r\n"] -[88.467617, "o", "\u001b[Acd2d99c31d1850622329ce1beeb60328e1b● \r\n"] -[88.489365, "o", "\u001b[Acd2d99c31d1850622329ce1beeb60328e1b4b● \r\n"] -[88.520553, "o", "\u001b[Acd2d99c31d1850622329ce1beeb60328e1b4b76● \r\n"] -[88.583235, "o", "\u001b[Acd2d99c31d1850622329ce1beeb60328e1b4b76f76cf/image● \r\n"] -[88.625902, "o", "\u001b[2A🌆 Sunflower ● \r\n\u001b[K\r\n"] -[88.793567, "o", "\u001b[2A🌆 Sunflower \r\n\u001b[?12l\u001b[?25h"] -[89.039961, "o", "\r\n"] -[89.391573, "o", "\u001b[34S\u001b[H \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\u001b[7S\u001b[27;34H \r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n\u001b[K\u001b[H"] -[89.446279, "o", "SIXEL IMAGE (96x33)+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[34;1H"] -[89.46412, "o", "\u001b[?25l\u001b[H \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\u001b[2m\r\nImage URL: \u001b(B\u001b[m\u001b[K\u001b[2m\r\nhttps://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e36f3f51ecd2d99c31d1850\u001b[25;1H622329ce1beeb60328e1b4b76f76cf/image.webp\u001b(B\u001b[m\u001b[K\u001b[2m\r\nSeed used for generation: 2131209976\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[2m\r\nLast turn: \u001b[36m\u001b[1m7\u001b(B\u001b[m\u001b[2m,\u001b[36m\u001b[1m487\u001b(B\u001b[m\u001b[2m Input, \u001b[36m\u001b[1m85\u001b(B\u001b[m\u001b[2m Output \u001b[1m(\u001b[36m2.8\u001b(B\u001b[m\u001b[2m%\u001b[1m)\u001b(B\u001b[m \u001b[92m*\u001b[39m\u001b[K\u001b[93m\r\n❯\u001b[39m\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[HSIXEL IMAGE (96x22)+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++"] -[89.464182, "o", "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n\u001b(B\u001b[m\u001b[?25l\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[?12l\u001b[?25h\u001b[29;3H"] -[89.471882, "o", "\u001b[?25l\u001b[H \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\r\n \u001b[K\u001b[2m\r\nImage URL: \u001b(B\u001b[m\u001b[K\u001b[2m\r\nhttps://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/9ab19a8dd11e36f3f51ecd2d99c31d1850\u001b[24;1H622329ce1beeb60328e1b4b76f76cf/image.webp\u001b(B\u001b[m\u001b[K\u001b[2m\r\nSeed used for generation: 2131209976\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[2m\r\nLast turn: \u001b[36m\u001b[1m7\u001b(B\u001b[m\u001b[2m,\u001b[36m\u001b[1m487\u001b(B\u001b[m\u001b[2m Input, \u001b[36m\u001b[1m85\u001b(B\u001b[m\u001b[2m Output \u001b[1m(\u001b[36m2.8\u001b(B\u001b[m\u001b[2m%\u001b[1m)\u001b(B\u001b[m \u001b[92m*\u001b[39m\u001b[K\u001b[93m\r\n❯\u001b[39m\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[30m\u001b[47m\u001b[7m\r\n \u001b[34m\u001b[40m dev[S] \u001b[30m\u001b[47m \u001b[32m\u001b[40mTVD\u001b[30m\u001b[100m ▲ \u001b[42m⢠\u001b[43m⡆\u001b[47m \u001b[42m∞gpt-5.5\u001b[100m»⊕\u001b[47m | 2.78% | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | source/fast-agent-pr | fast-agent 0.7.11 \u001b[1;1HSIXEL IMAGE (96x21)+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"] -[89.471944, "o", "+++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n\u001b(B\u001b[m\u001b[?25l\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[?12l\u001b[?25h\u001b[28;3H"] +{"version": 2, "width": 120, "height": 34, "timestamp": 1779740952, "idle_time_limit": 1.3, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}, "title": "fast-agent HF MCP image generation halfcell experiment"} +[0.039054, "o", "\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004h\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[c\u001b[>c\u001b[>q\u001b]10;?\u001b\\\u001b]11;?\u001b\\\u001b[1;1H\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[H"] +[0.039727, "o", "\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[1;1H\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[H"] +[5.04434, "o", "\u001b[?7727h\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;34r\u001b[1;1H\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[H"] +[7.063389, "o", "\u001b[?25l"] +[8.197207, "o", "\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.199048, "o", "\u001b[H\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.20507, "o", "\u001b[H\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.308042, "o", "\u001b[H\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.40906, "o", "\u001b[H\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.510515, "o", "\u001b[H\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.611956, "o", "\u001b[H\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.713009, "o", "\u001b[H\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.815736, "o", "\u001b[H\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[8.916867, "o", "\u001b[H\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[9.018886, "o", "\u001b[H\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[9.119942, "o", "\u001b[H\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[9.22164, "o", "\u001b[H\u001b[K\u001b[33m\u001b[1m▎\u001b[2m•\u001b(B\u001b[m\u001b[33m\u001b[1m Connecting \u001b(B\u001b[m\u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[9.231979, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[9.323268, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[9.424647, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[9.526272, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[9.627887, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[9.728421, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[9.830772, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[9.931292, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[10.032598, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[10.133216, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[10.240952, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[10.341844, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[10.442617, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[10.543689, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[10.64509, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[10.746183, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[10.849284, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[10.95135, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[11.052746, "o", "\u001b[H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mhuggingface_co \u001b(B\u001b[m"] +[11.106964, "o", "\u001b[H\u001b[K\u001b[?12l\u001b[?25h"] +[11.129905, "o", "\u001b[2mUse \u001b[32m'/'\u001b[39m for commands, \u001b[32m'!'\u001b[39m for shell. \u001b[32m'#'\u001b[39m to query, \u001b[32m'@'\u001b[39m to switch agents\r\nCTRL+T multiline, CTRL+Y copy last message, CTRL+E external editor.\r\nCTRL+Space or Tab for path completion. Use \u001b[35m/\u001b[95mattach\u001b[39m, `^file:`, `^url:`, or \u001b[33mCtrl+Alt+V\u001b[39m for attachments \u001b[1m(\u001b(B\u001b[m\u001b[2mexperimental\u001b[1m)\u001b(B\u001b[m\u001b[2m. F10\u001b[4;1Hto clear.\r\n\u001b(B\u001b[m\u001b[2mModel shortcuts:\r\n\u001b(B\u001b[m"] +[11.130181, "o", "\u001b[2m Shift+Tab = Service tier \u001b[1m(\u001b(B\u001b[m\u001b[2mstandard, fast\u001b[1m)\r\n\u001b(B\u001b[m"] +[11.130231, "o", "\u001b[2m F6 = Reasoning \u001b[1m(\u001b(B\u001b[m\u001b[2mnone, low, medium, high, xhigh\u001b[1m)\r\n\u001b(B\u001b[m"] +[11.13072, "o", "\u001b[2m F7 = Verbosity \u001b[1m(\u001b(B\u001b[m\u001b[2mlow, medium, high\u001b[1m)\r\n\u001b(B\u001b[m\u001b[2m F8 = Web search \u001b[1m(\u001b(B\u001b[m\u001b[2mon, off\u001b[1m)\u001b[11;1H\u001b(B\u001b[m"] +[11.131318, "o", "\u001b[2mfast-agent environment\u001b(B\u001b[m \u001b[34m~/source/fast-agent-pr/.fast-agent\u001b[39m\u001b[2m \u001b[1m(\u001b[36m3\u001b(B\u001b[m\u001b[2m agents, \u001b[36m\u001b[1m4\u001b(B\u001b[m\u001b[2m hooks, \u001b[36m\u001b[1m3\u001b(B\u001b[m\u001b[2m extensions, \u001b[36m\u001b[1m2\u001b(B\u001b[m\u001b[2m modelrefs\u001b[1m)\u001b(B\u001b[m\u001b[2m via cli\r\n\u001b(B\u001b[m"] +[11.131411, "o", "\u001b[33m\u001b[1mAgents have shell\u001b(B\u001b[m\u001b[2m (skills, switch, sub-agent, bash | cwd: source/fast-agent-pr)\r\n\u001b(B\u001b[m"] +[11.318732, "o", "\u001b[2mAgent \u001b(B\u001b[m\u001b[34mdev\u001b[39m\u001b[2m:\u001b(B\u001b[m \u001b[36m\u001b[1m2\u001b(B\u001b[m\u001b[2m child agents. \u001b(B\u001b[m\u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m MCP Server \u001b[1m(\u001b(B\u001b[m\u001b[36m\u001b[1m27\u001b(B\u001b[m\u001b[2m tools, \u001b(B\u001b[m\u001b[36m\u001b[1m4\u001b(B\u001b[m\u001b[2m prompts, \u001b(B\u001b[m\u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m resource\u001b[1m)\u001b(B\u001b[m\u001b[2m. \u001b(B\u001b[m\u001b[36m\u001b[1m3\u001b(B\u001b[m\u001b[2m skills available\r\n\u001b(B\u001b[m"] +[11.319199, "o", "\r\n"] +[11.319341, "o", "\u001b[2mInteractive MCP app integrations detected:\r\n\u001b(B\u001b[m"] +[11.319958, "o", "\u001b[2m ● \u001b(B\u001b[m\u001b[36mhuggingface_co\u001b[39m\u001b[2m — \u001b(B\u001b[m\u001b[36mMCP Apps\u001b[39m\u001b[2m: \u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m tools, \u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m resources\r\n\u001b(B\u001b[m"] +[11.320596, "o", "\u001b[2m · \u001b(B\u001b[mhuggingface_co__file_manager \r\n\u001b[1m\u001b[2m(\u001b(B\u001b[m\u001b[2mui:\u001b[35m//hf-mcp-proxy/hf_files/\u001b[95mdWk6Ly9wcmVmYWIvdG9vbC81MDY1Y2UwYTAxMjEvcmVuZGVyZXIuaHRtbA\u001b[39m\u001b[1m)\r\n\u001b(B\u001b[m"] +[11.452024, "o", "\u001b[2m ├─ \u001b(B\u001b[m\u001b[34mripgrep_oss\u001b[39m\u001b[2m: No MCP Servers\r\n\u001b(B\u001b[m"] +[11.452607, "o", "\u001b[2m └─ \u001b(B\u001b[m\u001b[34mripgrep_spark\u001b[39m\u001b[2m: No MCP Servers\r\n\u001b(B\u001b[m"] +[11.452828, "o", "\u001b[2mStreaming Enabled - markdown mode\r\n\u001b(B\u001b[m\r\n"] +[11.456469, "o", "\r\n\u001b[J\u001b[A\u001b[K\u001b[93m❯\u001b[C\u001b(B\u001b[m"] +[11.462126, "o", "\u001b[34;1H\u001b[30m\u001b[47m\u001b[7m \u001b[34m\u001b[40m dev[S] \u001b[30m\u001b[47m \u001b[32m\u001b[40mTVD\u001b[30m\u001b[100m ▲ \u001b[42m⢠\u001b[43m⡆\u001b[47m \u001b[42m∞gpt-5.5\u001b[100m»⊕\u001b[47m | 0.00% | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | source/fast-agent-pr | fast-agent 0.7.11 \u001b[23;3H\u001b(B\u001b[m"] +[12.055882, "o", "generate an image of a sunflower"] +[12.063148, "o", "\r\u001b[93m❯\u001b[39m generate an image of a sunflower\u001b[34;1H \u001b[K\u001b[23;35H"] +[12.063847, "o", "\r\n\u001b[J\u001b[A\u001b[K"] +[12.068947, "o", "\u001b[A"] +[12.070574, "o", "\u001b[?25l"] +[12.07305, "o", "\r\n"] +[12.073398, "o", "\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m \u001b[34mdev\u001b[39m \u001b[2m─────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[24;1H\u001b(B\u001b[m"] +[12.07492, "o", "generate an image of a sunflower\r\n"] +[12.341642, "o", "\u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[12.341969, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[12.377236, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[12.479115, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[12.580493, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[12.682121, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[12.783576, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[12.885234, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[12.986923, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[13.087587, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[13.188712, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[13.290106, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[13.391473, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[13.493075, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[13.594664, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[13.696261, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[13.797503, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[13.899384, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[14.001007, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[14.102171, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[14.203186, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[14.304557, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[14.405879, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[14.507433, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[14.608765, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[14.709424, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[14.810966, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[14.912502, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[15.013897, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[15.115239, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[15.217113, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[15.318067, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[15.419827, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[15.52119, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[15.623398, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[15.724947, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 1 \u001b(B\u001b[m"] +[15.786998, "o", "\r\u001b[K\u001b[33m▎\u001b[2m◀\u001b(B\u001b[m\u001b[33m 41 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 (summary) turn 1\u001b(B\u001b[m"] +[15.795938, "o", "\r\u001b[K"] +[15.799827, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5\u001b[27;1H\u001b[1m\u001b[3mExploring dynamic image generation\u001b(B\u001b[m \u001b[29;1H\u001b[2m\u001b[3mI●\u001b(B\u001b[m \r\n"] +[15.832596, "o", "\u001b[A\u001b[2m\u001b[3mI’m●\u001b(B\u001b[m \r\n"] +[15.867107, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking●\u001b(B\u001b[m \r\n"] +[15.90679, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about●\u001b(B\u001b[m \r\n"] +[15.934939, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how●\u001b(B\u001b[m \r\n"] +[15.972445, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to●\u001b(B\u001b[m \r\n"] +[16.005787, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use●\u001b(B\u001b[m \r\n"] +[16.041065, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic●\u001b(B\u001b[m \r\n"] +[16.074971, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces●\u001b(B\u001b[m \r\n"] +[16.117123, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to●\u001b(B\u001b[m \r\n"] +[16.147397, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to generate●\u001b(B\u001b[m \r\n"] +[16.185036, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to generate images●\u001b(B\u001b[m \r\n"] +[16.222183, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to generate images.●\u001b(B\u001b[m \r\n"] +[16.25596, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to generate images. I●\u001b(B\u001b[m \r\n"] +[16.283446, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to generate images. I need●\u001b(B\u001b[m \r\n"] +[16.318115, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to generate images. I need to●\u001b(B\u001b[m \r\n"] +[16.354529, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to generate images. I need to explore●\u001b(B\u001b[m \r\n"] +[16.392775, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to generate images. I need to explore available●\u001b(B\u001b[m \r\n"] +[16.419593, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to generate images. I need to explore available tools●\u001b(B\u001b[m \r\n"] +[16.46071, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to generate images. I need to explore available tools or●\u001b(B\u001b[m \r\n"] +[16.492594, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to generate images. I need to explore available tools or frameworks●\u001b(B\u001b[m \r\n"] +[16.529831, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to generate images. I need to explore available tools or frameworks to●\u001b(B\u001b[m \r\n"] +[16.566464, "o", "\u001b[A\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to generate images. I need to explore available tools or frameworks to \u001b(B\u001b[m \r\n\u001b[2m\u001b[3mdiscover●\u001b(B\u001b[m \r\n"] +[16.595777, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the●\u001b(B\u001b[m \r\n"] +[16.627792, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best●\u001b(B\u001b[m \r\n"] +[16.667036, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods●\u001b(B\u001b[m \r\n"] +[16.701764, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to●\u001b(B\u001b[m \r\n"] +[16.735089, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create●\u001b(B\u001b[m \r\n"] +[16.771569, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what●\u001b(B\u001b[m \r\n"] +[16.817488, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s●\u001b(B\u001b[m \r\n"] +[16.839649, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed●\u001b(B\u001b[m \r\n"] +[16.874678, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed.●\u001b(B\u001b[m \r\n"] +[16.915706, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed. It●\u001b(B\u001b[m \r\n"] +[16.932097, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed. It’s●\u001b(B\u001b[m \r\n"] +[16.969378, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed. It’s interesting●\u001b(B\u001b[m \r\n"] +[17.010537, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed. It’s interesting how●\u001b(B\u001b[m \r\n"] +[17.044744, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed. It’s interesting how technology●\u001b(B\u001b[m \r\n"] +[17.080809, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed. It’s interesting how technology can●\u001b(B\u001b[m \r\n"] +[17.115546, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed. It’s interesting how technology can evolve●\u001b(B\u001b[m \r\n"] +[17.153721, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed. It’s interesting how technology can evolve to●\u001b(B\u001b[m \r\n"] +[17.18851, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed. It’s interesting how technology can evolve to meet●\u001b(B\u001b[m \r\n"] +[17.221632, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed. It’s interesting how technology can evolve to meet creative●\u001b(B\u001b[m \r\n"] +[17.257104, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed. It’s interesting how technology can evolve to meet creative demands●\r\n\u001b(B\u001b[m"] +[17.29447, "o", "\u001b[A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed. It’s interesting how technology can evolve to meet creative \u001b(B\u001b[m \r\n\u001b[2m\u001b[3mdemands,●\u001b(B\u001b[m \r\n"] +[17.327811, "o", "\u001b[2A\u001b[2m\u001b[3mdiscover the best methods to create what’s needed. It’s interesting how technology can evolve to meet creative demands,\r\nand●\u001b(B\u001b[m \r\n"] +[17.367318, "o", "\u001b[A\u001b[2m\u001b[3mand I'm●\u001b(B\u001b[m \r\n"] +[17.398403, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious●\u001b(B\u001b[m \r\n"] +[17.43089, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about●\u001b(B\u001b[m \r\n"] +[17.461563, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the●\u001b(B\u001b[m \r\n"] +[17.500841, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities●\u001b(B\u001b[m \r\n"] +[17.540363, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities that●\u001b(B\u001b[m \r\n"] +[17.577491, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities that could●\u001b(B\u001b[m \r\n"] +[17.616199, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities that could unfold●\u001b(B\u001b[m \r\n"] +[17.649977, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities that could unfold through●\u001b(B\u001b[m \r\n"] +[17.684808, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities that could unfold through image●\u001b(B\u001b[m \r\n"] +[17.722526, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities that could unfold through image generation●\u001b(B\u001b[m \r\n"] +[17.762604, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities that could unfold through image generation.●\u001b(B\u001b[m \r\n"] +[17.79576, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities that could unfold through image generation. Let●\u001b(B\u001b[m \r\n"] +[17.828433, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities that could unfold through image generation. Let’s●\u001b(B\u001b[m \r\n"] +[17.865413, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities that could unfold through image generation. Let’s see●\u001b(B\u001b[m \r\n"] +[17.904524, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities that could unfold through image generation. Let’s see what●\u001b(B\u001b[m \r\n"] +[17.942458, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities that could unfold through image generation. Let’s see what options●\u001b(B\u001b[m \r\n"] +[17.992072, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities that could unfold through image generation. Let’s see what options are●\u001b(B\u001b[m \r\n"] +[18.022801, "o", "\u001b[A\u001b[2m\u001b[3mand I'm curious about the possibilities that could unfold through image generation. Let’s see what options are \u001b(B\u001b[m \r\n\u001b[2m\u001b[3mavailable●\u001b(B\u001b[m \r\n"] +[18.052567, "o", "\u001b[A\u001b[2m\u001b[3mavailable for●\u001b(B\u001b[m \r\n"] +[18.084413, "o", "\u001b[A\u001b[2m\u001b[3mavailable for generating●\u001b(B\u001b[m \r\n"] +[18.128742, "o", "\u001b[A\u001b[2m\u001b[3mavailable for generating images●\u001b(B\u001b[m \r\n"] +[18.156996, "o", "\u001b[A\u001b[2m\u001b[3mavailable for generating images effectively●\u001b(B\u001b[m \r\n"] +[18.1923, "o", "\u001b[A\u001b[2m\u001b[3mavailable for generating images effectively!●\u001b(B\u001b[m \r\n"] +[18.253431, "o", "\u001b[A\u001b[2m\u001b[3mavailable for generating images effectively!\u001b(B\u001b[m \r\n\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m \u001b[35mdev\u001b[39m \u001b[35mhuggingface_co__dynamic_space\r\n\u001b[39m{\"operation\":\"discover\",\"space\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[18.267145, "o", "\u001b[A{\"operation\":\"discover\",\"space_name\":\"\",\"parameters\":\"\"}\u001b[2m●\r\n\u001b(B\u001b[m"] +[18.3353, "o", "\u001b[4S\u001b[5A{\u001b[K\r\n \"operation\": \"discover\",\r\n \"space_name\": \"\",\u001b[K\r\n \"parameters\": \"\"\u001b[K\r\n}\u001b[K\r\n\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[18.339798, "o", "\u001b[15A\u001b[K\u001b[2B\u001b[K\u001b[2B\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[14A\u001b[?12l\u001b[?25h"] +[18.354875, "o", "\r\n\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5 ↗ (1.90%)\r\n\u001b(B\u001b[m"] +[18.355443, "o", "\u001b[1m\u001b[2m\u001b[3mExploring dynamic image generation\u001b(B\u001b[m \u001b[23;1H\u001b[2m\u001b[3mI’m thinking about how to use dynamic spaces to generate images. I need to explore available tools or frameworks to \u001b(B\u001b[m \u001b[24;1H\u001b[2m\u001b[3mdiscover the best methods to create what’s needed. It’s interesting how technology can evolve to meet creative demands, \u001b[25;1Hand I'm curious about the possibilities that could unfold through image generation. Let’s see what options are available\u001b[26;1Hfor generating images effectively!\u001b(B\u001b[m \u001b[27;1H\u001b[32m\u001b[2m\u001b[3mThe assistant requested tool calls\r\n\u001b(B\u001b[m"] +[18.35573, "o", "\r\n"] +[18.35593, "o", "\u001b[2m▎ \u001b[37mbash\u001b[39m • \u001b(B\u001b[m\u001b[92mhuggingface…\u001b[39m\u001b[2m • \u001b[37mskill\u001b[39m • \u001b[37mcard_tools\u001b[39m • \u001b[37mripgrep_oss\u001b[39m • \u001b[37mripgrep_spa…\u001b[31;1H\u001b(B\u001b[m"] +[18.395897, "o", "\r\n"] +[18.3961, "o", "\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m \u001b[35mdev\u001b[39m \u001b[2mtool call - huggingface_co__dynamic_space\r\n\u001b(B\u001b[m"] +[18.398961, "o", "\u001b[1m\u001b[2m{\u001b(B\u001b[m\u001b[32m\u001b[2m'operation'\u001b[39m: \u001b[32m'discover'\u001b[39m, \u001b[32m'space_name'\u001b[39m: \u001b[32m''\u001b[39m, \u001b[32m'parameters'\u001b[39m: \u001b[32m''\u001b[39m\u001b[1m}\r\n\u001b(B\u001b[m"] +[18.399103, "o", "\n\u001b[K"] +[18.399391, "o", "\u001b[2m▎ \u001b[37mhf_whoami\u001b[39m • \u001b[37mhub_repo_se…\u001b[39m • \u001b[37mpaper_search\u001b[39m • \u001b[37mhub_repo_de…\u001b[39m • \u001b[37mhf_jobs\u001b[39m • \u001b(B\u001b[m\u001b[35mdynamic_spa…\u001b[39m\u001b[2m • \u001b[37mwrite_file\u001b[39m • \u001b[37mlist_files\u001b[39m •\u001b(B\u001b[m\r\n\u001b[33;110H\u001b[2m \u001b[37mread_file\u001b[39m \u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[2m…\u001b(B\u001b[m\r\n\u001b[K\n\u001b[K"] +[18.400221, "o", "\u001b[?25l"] +[18.400695, "o", "\u001b[33m▎\u001b[2m◀\u001b(B\u001b[m\u001b[33m 431 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 (summary) turn 1\u001b(B\u001b[m"] +[18.401533, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m 52 ⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 turn 1 \u001b(B\u001b[m"] +[18.402791, "o", "\r\u001b[K\u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space \u001b(B\u001b[m"] +[18.403186, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_SQG6aB04…\u001b(B\u001b[m"] +[18.502034, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_SQG6aB04…\u001b(B\u001b[m"] +[18.603819, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_SQG6aB04…\u001b(B\u001b[m"] +[18.641717, "o", "\r\n\u001b[A\u001b[K\r\n\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_SQG6aB04…\u001b(B\u001b[m"] +[18.64273, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[2mtool result - text only 2333 chars\u001b(B\u001b[m\r\n\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_SQG6aB04…\u001b(B\u001b[m"] +[18.644114, "o", "\r\u001b[9S\u001b[9A\u001b[2m**Available Spaces:**\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2mThese spaces can be invoked using the `dynamic_space` tool.\u001b(B\u001b[m\u001b[K\r\n\u001b[2mUse `\u001b[32m\"operation\"\u001b[39m: \u001b[32m\"view_parameters\"\u001b[39m` to inspect a space's parameters before invoking.\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m| Space ID | Category | Description |\u001b(B\u001b[m\u001b[K\r\n\u001b[2m|----------|----------|-------------|\u001b(B\u001b[m\u001b[K\r\n\u001b[2m| `evalstate/flux1\\_schnell` | Image Generation | Simple, fast image generator. Use for quick tests and ideas. |\u001b(B\u001b[m\u001b[K\r\n\u001b[2m|\u001b[33m...\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[35m\u001b[2m▎◀ Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37mdynamic_space • id:call_SQG6aB04…\u001b(B\u001b[m"] +[18.704335, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_SQG6aB04…\u001b(B\u001b[m"] +[18.805049, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_SQG6aB04…\u001b(B\u001b[m"] +[18.873826, "o", "\r\u001b[K\u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[18.87402, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[18.905674, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[19.007791, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[19.108227, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[19.209809, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[19.311645, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[19.413002, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[19.514704, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[19.615826, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[19.716488, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[19.747439, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞\u001b(B\u001b[m\r\n\u001b[33;32H\u001b[37m\u001b[2mgpt-5.5 turn 2 \u001b(B\u001b[m\r\n\u001b[K\u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start)\u001b(B\u001b[m"] +[19.748876, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_GFD0XPOv…\u001b(B\u001b[m"] +[19.759997, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A"] +[19.761217, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\r\n\n\u001b[32;3H \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5\u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[35mhuggingface_co__dynamic_space\r\n\u001b[39m{\"\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[19.776381, "o", "\u001b[A{\"operation\u001b[2m●\r\n\u001b(B\u001b[m"] +[19.793933, "o", "\u001b[A{\"operation\":\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[19.817001, "o", "\u001b[A{\"operation\":\"view\u001b[2m●\r\n\u001b(B\u001b[m"] +[19.837125, "o", "\u001b[A{\"operation\":\"view_parameters\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[19.860606, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space\u001b[2m●\r\n\u001b(B\u001b[m"] +[19.877221, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\u001b[2m●\r\n\u001b(B\u001b[m"] +[19.89763, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[19.920781, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"eval\u001b[2m●\r\n\u001b(B\u001b[m"] +[19.938987, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate\u001b[2m●\r\n\u001b(B\u001b[m"] +[19.965805, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux\u001b[2m●\r\n\u001b(B\u001b[m"] +[19.981182, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1\u001b[2m●\r\n\u001b(B\u001b[m"] +[20.003678, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_s\u001b[2m●\r\n\u001b(B\u001b[m"] +[20.018944, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schn\u001b[2m●\r\n\u001b(B\u001b[m"] +[20.050178, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schnell\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[20.076333, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\u001b[2m●\r\n\u001b(B\u001b[m"] +[20.093393, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\u001b[2m●\r\n\u001b(B\u001b[m"] +[20.130086, "o", "\u001b[A{\"operation\":\"view_parameters\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"\"}\u001b[2m●\r\n\u001b(B\u001b[m"] +[20.250171, "o", "\u001b[4S\u001b[5A{\u001b[K\r\n \"operation\": \"view_parameters\",\r\n \"space_name\": \"evalstate/flux1_schnell\",\u001b[K\r\n \"parameters\": \"\"\u001b[K\r\n}\u001b[K\r\n\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[20.275197, "o", "\u001b[9A\u001b[K\u001b[2B\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[8A\u001b[?12l\u001b[?25h"] +[20.275626, "o", "\r\n"] +[20.275914, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5 ↔ (2.13%)\r\n\u001b(B\u001b[m\u001b[32m\u001b[2m\u001b[3mThe assistant requested tool calls\r\n\u001b(B\u001b[m"] +[20.276104, "o", "\r\n\u001b[2m▎ \u001b[37mbash\u001b[39m • \u001b(B\u001b[m\u001b[92mhuggingface…\u001b[39m\u001b[2m • \u001b[37mskill\u001b[39m • \u001b[37mcard_tools\u001b[39m • \u001b[37mripgrep_oss\u001b[39m • \u001b[37mripgrep_spa…\r\n\u001b(B\u001b[m\r\n"] +[20.30057, "o", "\r\n\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m \u001b[35mdev\u001b[39m \u001b[2mtool call - huggingface_co__dynamic_space\r\n\u001b(B\u001b[m"] +[20.300903, "o", "\u001b[1m\u001b[2m{\u001b(B\u001b[m\u001b[32m\u001b[2m'operation'\u001b[39m: \u001b[32m'view_parameters'\u001b[39m, \u001b[32m'space_name'\u001b[39m: \u001b[32m'evalstate/flux1_schnell'\u001b[39m, \u001b[32m'parameters'\u001b[39m: \u001b[32m''\u001b[39m\u001b[1m}\r\n\u001b(B\u001b[m"] +[20.301088, "o", "\n\u001b[K"] +[20.30157, "o", "\u001b[2m▎ \u001b[37mhf_whoami\u001b[39m • \u001b[37mhub_repo_se…\u001b[39m • \u001b[37mpaper_search\u001b[39m • \u001b[37mhub_repo_de…\u001b[39m • \u001b[37mhf_jobs\u001b[39m • \u001b(B\u001b[m\u001b[35mdynamic_spa…\u001b[39m\u001b[2m • \u001b[37mwrite_file\u001b[39m • \u001b[37mlist_files\u001b[39m •\u001b(B\u001b[m\r\n\u001b[33;110H\u001b[2m \u001b[37mread_file\u001b[39m \u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[2m…\u001b(B\u001b[m\r\u001b[2S\u001b[A\u001b[K\r\n\u001b[K"] +[20.302417, "o", "\u001b[?25l"] +[20.302913, "o", "\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 2 \u001b(B\u001b[m"] +[20.303722, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m 41 ⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 turn 2 \u001b(B\u001b[m"] +[20.305059, "o", "\r\u001b[K\u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space \u001b(B\u001b[m"] +[20.3056, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_GFD0XPOv…\u001b(B\u001b[m"] +[20.404699, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_GFD0XPOv…\u001b(B\u001b[m"] +[20.505205, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_GFD0XPOv…\u001b(B\u001b[m"] +[20.588333, "o", "\r\n\u001b[A\u001b[K\r\n\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_GFD0XPOv…\u001b(B\u001b[m"] +[20.588598, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[2mtool result - text only 759 chars\u001b(B\u001b[m\r\n\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_GFD0XPOv…\u001b(B\u001b[m"] +[20.589601, "o", "\r\u001b[17S\u001b[17d\u001b[2m# Parameters for: flux1_schnell_infer\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m**Description:** Generate an image using the Flux \u001b[36m\u001b[1m1\u001b(B\u001b[m\u001b[2m Schnell Image Generator.\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m## Parameters:\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m### height \u001b[1m[\u001b(B\u001b[m\u001b[2mOPTIONAL\u001b[1m]\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Type:** number\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Default:** \u001b[36m\u001b[1m1024\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m### num_inference_steps \u001b[1m[\u001b(B\u001b[m\u001b[2mOPTIONAL\u001b[1m]\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Type:** number\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Default:** \u001b[36m\u001b[1m4\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[2m### prompt \u001b[1m[\u001b(B\u001b[m\u001b[2mOPTIONAL\u001b[1m]\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Type:** string\u001b(B\u001b[m\u001b[K\r\n\u001b[2m- **Description:** Approximately \u001b[36m\u001b[1m60\u001b(B\u001b[m\u001b[2m-\u001b[36m\u001b[1m70\u001b(B\u001b[m\u001b[2m words max - d\u001b[33m...\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[35m\u001b[2m▎◀ Calling Tool \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37mdynamic_space • id:call_GFD0XPOv…\u001b(B\u001b[m"] +[20.606306, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_GFD0XPOv…\u001b(B\u001b[m"] +[20.707022, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_GFD0XPOv…\u001b(B\u001b[m"] +[20.807699, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_GFD0XPOv…\u001b(B\u001b[m"] +[20.863165, "o", "\r\u001b[K\u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[20.864585, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[20.910123, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[21.011429, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[21.113637, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[21.214637, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[21.31711, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[21.418203, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[21.519523, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[21.621278, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[21.723001, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[21.824928, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[21.899023, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞\u001b(B\u001b[m\r\n\u001b[33;32H\u001b[37m\u001b[2mgpt-5.5 turn 3 \u001b(B\u001b[m\r\n\u001b[K\u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start)\u001b(B\u001b[m"] +[21.901034, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[21.9261, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \r\n\u001b(B\u001b[m\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 • huggingface_co__dynamic_space (start) • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[21.92655, "o", "\u001b[33;1H\u001b[K\r\n\u001b[K\u001b[A"] +[21.927022, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\r\n\n\u001b[32;3H \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5\u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[35mhuggingface_co__dynamic_space\r\n\u001b[39m{\"\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[21.943912, "o", "\u001b[A{\"operation\u001b[2m●\r\n\u001b(B\u001b[m"] +[21.963761, "o", "\u001b[A{\"operation\":\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[21.984521, "o", "\u001b[A{\"operation\":\"invoke\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.00435, "o", "\u001b[A{\"operation\":\"invoke\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.02418, "o", "\u001b[A{\"operation\":\"invoke\",\"space\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.046416, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.066606, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"eval\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.086307, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.105466, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.125472, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.144686, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.166882, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_s\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.190384, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schn\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.205087, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.223064, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.243257, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.262334, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.284315, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.303164, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.327193, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"A vibrant\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.34444, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"A vibrant close\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.364373, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"A vibrant close-up\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.382702, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"A vibrant close-up of\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.404014, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"A vibrant close-up of a\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.422977, "o", "\u001b[A{\"operation\":\"invoke\",\"space_name\":\"evalstate/flux1_schnell\",\"parameters\":\"{\\\"prompt\\\":\\\"A vibrant close-up of a \r\nsunflower\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[22.461453, "o", "\u001b[Asunflower in full\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.48326, "o", "\u001b[Asunflower in full bloom,\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.505229, "o", "\u001b[Asunflower in full bloom, golden\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.527326, "o", "\u001b[Asunflower in full bloom, golden yellow\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.549937, "o", "\u001b[Asunflower in full bloom, golden yellow petals\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.561535, "o", "\u001b[Asunflower in full bloom, golden yellow petals radi\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.581664, "o", "\u001b[Asunflower in full bloom, golden yellow petals radiating\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.600549, "o", "\u001b[Asunflower in full bloom, golden yellow petals radiating around\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.619944, "o", "\u001b[Asunflower in full bloom, golden yellow petals radiating around a\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.639047, "o", "\u001b[Asunflower in full bloom, golden yellow petals radiating around a detailed\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.661376, "o", "\u001b[Asunflower in full bloom, golden yellow petals radiating around a detailed dark brown\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.679905, "o", "\u001b[Asunflower in full bloom, golden yellow petals radiating around a detailed dark brown center\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.701821, "o", "\u001b[Asunflower in full bloom, golden yellow petals radiating around a detailed dark brown center,\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.720456, "o", "\u001b[Asunflower in full bloom, golden yellow petals radiating around a detailed dark brown center, sun\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.738828, "o", "\u001b[Asunflower in full bloom, golden yellow petals radiating around a detailed dark brown center, sunlit\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.763239, "o", "\u001b[Asunflower in full bloom, golden yellow petals radiating around a detailed dark brown center, sunlit green\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.786916, "o", "\u001b[Asunflower in full bloom, golden yellow petals radiating around a detailed dark brown center, sunlit green field softly\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.801533, "o", "\u001b[Asunflower in full bloom, golden yellow petals radiating around a detailed dark brown center, sunlit green field softly \r\nblurred\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[22.821486, "o", "\u001b[Ablurred in\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.840477, "o", "\u001b[Ablurred in the\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.858101, "o", "\u001b[Ablurred in the background\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.878531, "o", "\u001b[Ablurred in the background,\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.899432, "o", "\u001b[Ablurred in the background, warm\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.917404, "o", "\u001b[Ablurred in the background, warm natural\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.937636, "o", "\u001b[Ablurred in the background, warm natural light,\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.958024, "o", "\u001b[Ablurred in the background, warm natural light, crisp\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.976924, "o", "\u001b[Ablurred in the background, warm natural light, crisp botanical\u001b[2m●\r\n\u001b(B\u001b[m"] +[22.996888, "o", "\u001b[Ablurred in the background, warm natural light, crisp botanical detail\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.018499, "o", "\u001b[Ablurred in the background, warm natural light, crisp botanical detail,\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.039354, "o", "\u001b[Ablurred in the background, warm natural light, crisp botanical detail, cheerful\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.057133, "o", "\u001b[Ablurred in the background, warm natural light, crisp botanical detail, cheerful summer\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.079545, "o", "\u001b[Ablurred in the background, warm natural light, crisp botanical detail, cheerful summer atmosphere,\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.096329, "o", "\u001b[Ablurred in the background, warm natural light, crisp botanical detail, cheerful summer atmosphere, phot\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.11948, "o", "\u001b[Ablurred in the background, warm natural light, crisp botanical detail, cheerful summer atmosphere, photore\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.134913, "o", "\u001b[Ablurred in the background, warm natural light, crisp botanical detail, cheerful summer atmosphere, photoreal\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.154701, "o", "\u001b[Ablurred in the background, warm natural light, crisp botanical detail, cheerful summer atmosphere, photorealistic\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.172037, "o", "\u001b[Ablurred in the background, warm natural light, crisp botanical detail, cheerful summer atmosphere, photorealistic,\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.195018, "o", "\u001b[Ablurred in the background, warm natural light, crisp botanical detail, cheerful summer atmosphere, photorealistic, \r\nhigh\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[23.213217, "o", "\u001b[2Ablurred in the background, warm natural light, crisp botanical detail, cheerful summer atmosphere, photorealistic, high\r\nresolution\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.234961, "o", "\u001b[Aresolution\\\",\\\"width\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.254963, "o", "\u001b[Aresolution\\\",\\\"width\\\":\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.272633, "o", "\u001b[Aresolution\\\",\\\"width\\\":102\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.291863, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.311386, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.330459, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.349703, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.371063, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":102\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.388048, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.411063, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.431304, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_in\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.451952, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.470897, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.490481, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.509319, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.529061, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.549157, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"randomize\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.568105, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"randomize_seed\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.589993, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"randomize_seed\\\":\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.609097, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"randomize_seed\\\":true\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.628856, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"randomize_seed\\\":true}\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.647729, "o", "\u001b[Aresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"randomize_seed\\\":true}\"}\u001b[2m●\r\n\u001b(B\u001b[m"] +[23.74594, "o", "\u001b[4S\u001b[8A{\u001b[K\r\n \"operation\": \"invoke\",\u001b[K\r\n \"space_name\": \"evalstate/flux1_schnell\",\u001b[K\r\n \"parameters\": \"{\\\"prompt\\\":\\\"A vibrant close-up of a sunflower in full bloom, golden yellow petals radiating around a\r\ndetailed dark brown center, sunlit green field softly blurred in the background, warm natural light, crisp botanical \r\ndetail, cheerful summer atmosphere, photorealistic, high \u001b[K\r\nresolution\\\",\\\"width\\\":1024,\\\"height\\\":1024,\\\"num_inference_steps\\\":4,\\\"randomize_seed\\\":true}\"\u001b[K\r\n}\u001b[K\r\n\u001b[K\u001b[2m●\u001b(B\u001b[m\r\n\u001b[K"] +[23.774213, "o", "\u001b[12A\u001b[K\u001b[2B\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[11A\u001b[?12l\u001b[?25h"] +[23.775271, "o", "\r\n"] +[23.77583, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5 ↔ (2.26%)\r\n\u001b(B\u001b[m\u001b[32m\u001b[2m\u001b[3mThe assistant requested tool calls\r\n\u001b(B\u001b[m"] +[23.776188, "o", "\r\n"] +[23.776272, "o", "\u001b[2m▎ \u001b[37mbash\u001b[39m • \u001b(B\u001b[m\u001b[92mhuggingface…\u001b[39m\u001b[2m • \u001b[37mskill\u001b[39m • \u001b[37mcard_tools\u001b[39m • \u001b[37mripgrep_oss\u001b[39m • \u001b[37mripgrep_spa…\u001b[28;1H\u001b(B\u001b[m"] +[23.804077, "o", "\r\n"] +[23.804545, "o", "\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m \u001b[35mdev\u001b[39m \u001b[2mtool call - huggingface_co__dynamic_space\r\n\u001b(B\u001b[m"] +[23.805542, "o", "\u001b[34d\n\u001b[5A\u001b[1m\u001b[2m{\r\n\u001b(B\u001b[m\u001b[2m \u001b[32m'operation'\u001b[39m: \u001b[32m'invoke'\u001b[39m,\r\n \u001b[32m'space_name'\u001b[39m: \u001b[32m'evalstate/flux1_schnell'\u001b[39m,\r\n \u001b[32m'parameters'\u001b[39m: \u001b[32m'{\"prompt\":\"A vibrant close-up of a sunflower in fu'\u001b[39m+\u001b[36m\u001b[1m309\r\n\u001b[39m}\u001b(B\u001b[m\r\n\u001b[K\n\u001b[K"] +[23.806239, "o", "\u001b[2m▎ \u001b[37mhf_whoami\u001b[39m • \u001b[37mhub_repo_se…\u001b[39m • \u001b[37mpaper_search\u001b[39m • \u001b[37mhub_repo_de…\u001b[39m • \u001b[37mhf_jobs\u001b[39m • \u001b(B\u001b[m\u001b[35mdynamic_spa…\u001b[39m\u001b[2m • \u001b[37mwrite_file\u001b[39m • \u001b[37mlist_files\u001b[39m •\u001b(B\u001b[m\r\n\u001b[33;110H\u001b[2m \u001b[37mread_file\u001b[39m \u001b(B\u001b[m\u001b[34;1H\u001b[K\u001b[2m…\u001b(B\u001b[m\r\u001b[2S\u001b[A\u001b[K\r\n\u001b[K"] +[23.807239, "o", "\u001b[?25l"] +[23.807921, "o", "\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 3 \u001b(B\u001b[m"] +[23.808661, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m 118 ⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mgpt-5.5 turn 3 \u001b(B\u001b[m"] +[23.810022, "o", "\r\u001b[K\u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space \u001b(B\u001b[m"] +[23.810335, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[23.909836, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[24.01141, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[24.112789, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[24.214152, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[24.315904, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[24.41751, "o", "\r\u001b[K\u001b[35m▎\u001b[2m◀\u001b(B\u001b[m\u001b[35m Calling Tool \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[24.518913, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 0 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - In queue. Position 0 out of 1. Estimated time remaining…\u001b(B\u001b[m"] +[24.620546, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[24.722223, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[24.823925, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[24.925461, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[25.025962, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[25.127587, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[25.229857, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[25.331049, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[25.432974, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[25.533227, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[25.635022, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[25.736765, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[25.837328, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[25.939286, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[26.039933, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 1 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Processing • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[26.141716, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 2 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 10 of 100\u001b(B\u001b[m"] +[26.242162, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 2 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 10 of 100\u001b(B\u001b[m"] +[26.343485, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 2 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 10 of 100\u001b(B\u001b[m"] +[26.445054, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 2 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 10 of 100\u001b(B\u001b[m"] +[26.546319, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 2 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 10 of 100\u001b(B\u001b[m"] +[26.647657, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 3 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 20 of 100\u001b(B\u001b[m"] +[26.749592, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 4 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 20 of 100\u001b(B\u001b[m"] +[26.851096, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 5 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 24 of 100\u001b(B\u001b[m"] +[26.952932, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 6 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 28 of 100\u001b(B\u001b[m"] +[27.053478, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 7 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 33 of 100\u001b(B\u001b[m"] +[27.155361, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 8 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 38 of 100\u001b(B\u001b[m"] +[27.257218, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 9 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 42 of 100\u001b(B\u001b[m"] +[27.359366, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 10 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 46 of 100\u001b(B\u001b[m"] +[27.46087, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 11 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 50 of 100\u001b(B\u001b[m"] +[27.562556, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 12 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 55 of 100\u001b(B\u001b[m"] +[27.664242, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 13 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 59 of 100\u001b(B\u001b[m"] +[27.764751, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 14 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 63 of 100\u001b(B\u001b[m"] +[27.866819, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 15 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 67 of 100\u001b(B\u001b[m"] +[27.968693, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 16 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 71 of 100\u001b(B\u001b[m"] +[28.070328, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 17 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 75 of 100\u001b(B\u001b[m"] +[28.171682, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 18 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 79 of 100\u001b(B\u001b[m"] +[28.273078, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 19 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 84 of 100\u001b(B\u001b[m"] +[28.374886, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 20 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 88 of 100\u001b(B\u001b[m"] +[28.477076, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 21 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 92 of 100\u001b(B\u001b[m"] +[28.578965, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 23 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 97 of 100\u001b(B\u001b[m"] +[28.681178, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 23 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 97 of 100\u001b(B\u001b[m"] +[28.78245, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 23 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 97 of 100\u001b(B\u001b[m"] +[28.884773, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 23 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 97 of 100\u001b(B\u001b[m"] +[28.986489, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 23 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 97 of 100\u001b(B\u001b[m"] +[29.088068, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 23 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress ZeroGPU init: Step 97 of 100\u001b(B\u001b[m"] +[29.189902, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 24 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 0 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[29.291932, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 24 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 0 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[29.393269, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 24 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 0 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[29.494714, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 24 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 0 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[29.596621, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 25 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[29.697074, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 25 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[29.798627, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 25 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[29.900257, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 25 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[30.001009, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 25 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[30.102297, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 25 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 1 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[30.202865, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 26 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[30.304582, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 26 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[30.405788, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 26 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[30.507322, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 26 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[30.60891, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 26 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[30.710159, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 26 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[30.81164, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 26 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 2 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[30.913046, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 27 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[31.014462, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 27 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[31.115699, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 27 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[31.217585, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 27 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[31.319204, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 27 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[31.419879, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 28 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[31.521801, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 28 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[31.62311, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 28 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[31.724307, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 28 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[31.825899, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 28 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[31.927145, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 28 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[32.028305, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 29 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[32.130221, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 29 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space - Progress: Step 3 of 4 • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[32.232525, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 30 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[32.333421, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 30 \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[32.438144, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 30 \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[32.536194, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 30 \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[32.637061, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 30 \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[32.738914, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 30 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[32.805149, "o", "\r\n\u001b[A\u001b[K\r\n\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 30 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[32.805852, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\r\n\u001b[33;3H \u001b[35mdev\u001b[39m \u001b[2mtool result - 3 Content Blocks\u001b(B\u001b[m\r\n\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 30 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[32.817535, "o", "\r\u001b[5S\u001b[5A\u001b[1m\u001b[2m[\u001b(B\u001b[m\u001b[2mIMAGE: image/webp, \u001b[36m\u001b[1m88132\u001b(B\u001b[m\u001b[2m bytes\u001b[1m]\u001b(B\u001b[m\u001b[K\r\n\u001b[2mImage URL: \u001b(B\u001b[m\u001b[K\r\n\u001b[94m\u001b[2m\u001b[4mhttps://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3c2890688d5354e0584364bfe67225bdf3\u001b[32;1Hf409faa48f3a27173395a25ad64222/image.webp\u001b(B\u001b[m\u001b[K\r\n\u001b[2mSeed used for generation: \u001b[36m\u001b[1m1824537418\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[35m\u001b[2m▎▶ 30 \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[32.839583, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 30 \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[32.941755, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 30 \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[33.043219, "o", "\r\u001b[K\u001b[35m▎\u001b[2m▶\u001b(B\u001b[m\u001b[35m 30 \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2mdynamic_space • id:call_KXf9L0Rr…\u001b(B\u001b[m"] +[33.044492, "o", "\r\u001b[K\u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[33.044781, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[33.144857, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[33.246819, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[33.347741, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⡀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[33.449859, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⢀\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[33.550454, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠠\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[33.652329, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠐\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[33.753831, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠈\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[33.855219, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[33.957003, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[34.013979, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m 1 ⠄\u001b[39m \u001b[34mdev \u001b[39m \u001b[37m\u001b[2m∞gpt-5.5 turn 4 \u001b(B\u001b[m"] +[34.023026, "o", "\r\u001b[K"] +[34.025096, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\r\u001b[2S\u001b[32;3H \u001b[32mdev\u001b[39m \u001b[2mgpt-5.5\u001b(B\u001b[m\r\n\u001b[K\r\n![\u001b[K●\r\n\u001b[33;4H \r\n\u001b[K"] +[34.043017, "o", "\u001b[A![Generated● \r\n"] +[34.077576, "o", "\u001b[A![Generated sunflower image● \r\n"] +[34.091385, "o", "\u001b[A![Generated sunflower image](● \r\n"] +[34.107445, "o", "\u001b[A![Generated sunflower image](https● \r\n"] +[34.154569, "o", "\u001b[A![Generated sunflower image](https://● \r\n"] +[34.166315, "o", "\u001b[A![Generated sunflower image](https://eval● \r\n"] +[34.189805, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux● \r\n"] +[34.20295, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1● \r\n"] +[34.220537, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-s● \r\n"] +[34.243847, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schn● \r\n"] +[34.262287, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell● \r\n"] +[34.281498, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.h● \r\n"] +[34.29777, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf● \r\n"] +[34.327513, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/● \r\n"] +[34.340193, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--● \r\n"] +[34.358739, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--rep● \r\n"] +[34.377271, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--replicas● \r\n"] +[34.404618, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--replicas/z● \r\n"] +[34.417947, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--replicas/zrb● \r\n"] +[34.43502, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs● \r\n"] +[34.454114, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gr● \r\n"] +[34.468481, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio● \r\n"] +[34.501893, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file● \r\n"] +[34.515566, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/● \r\n"] +[34.533056, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp● \r\n"] +[34.549819, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gr● \r\n"] +[34.568144, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio● \r\n"] +[34.597495, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3● \r\n"] +[34.617074, "o", "\u001b[A![Generated sunflower image](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3c● \r\n"] +[34.63103, "o", "\u001b[A![Generated sunflower \r\nimage](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3c289●\r\n\u001b[33;100H \r\n\u001b[K"] +[34.649609, "o", "\u001b[Aimage](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3c289068● \r\n"] +[34.668752, "o", "\u001b[Aimage](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3c2890688● \r\n"] +[34.690185, "o", "\u001b[Aimage](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3c2890688d● \r\n"] +[34.708605, "o", "\u001b[Aimage](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3c2890688d535● \r\n"] +[34.729779, "o", "\u001b[Aimage](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3c2890688d5354e● \r\n"] +[34.749465, "o", "\u001b[Aimage](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3c2890688d5354e058● \r\n"] +[34.771083, "o", "\u001b[Aimage](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3c2890688d5354e058436● \r\n"] +[34.788066, "o", "\u001b[Aimage](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3c2890688d5354e0584364● \r\n"] +[34.810665, "o", "\u001b[Aimage](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3c2890688d5354e0584364b● \r\n"] +[34.835285, "o", "\u001b[Aimage](https://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3c2890688d5354e0584364bfe6\r\n72●\r\n\u001b[33;4H \r\n\u001b[K"] +[34.855885, "o", "\u001b[A7225● \r\n"] +[34.87828, "o", "\u001b[A7225b● \r\n"] +[34.898566, "o", "\u001b[A7225bdf3● \r\n"] +[34.918689, "o", "\u001b[A7225bdf3f● \r\n"] +[34.938501, "o", "\u001b[A7225bdf3f409● \r\n"] +[34.95733, "o", "\u001b[A7225bdf3f409faa● \r\n"] +[34.975929, "o", "\u001b[A7225bdf3f409faa48● \r\n"] +[35.002838, "o", "\u001b[A7225bdf3f409faa48f● \r\n"] +[35.016748, "o", "\u001b[A7225bdf3f409faa48f3● \r\n"] +[35.036729, "o", "\u001b[A7225bdf3f409faa48f3a271● \r\n"] +[35.057308, "o", "\u001b[A7225bdf3f409faa48f3a271733● \r\n"] +[35.075741, "o", "\u001b[A7225bdf3f409faa48f3a27173395● \r\n"] +[35.096942, "o", "\u001b[A7225bdf3f409faa48f3a27173395a● \r\n"] +[35.126805, "o", "\u001b[A7225bdf3f409faa48f3a27173395a25● \r\n"] +[35.148593, "o", "\u001b[A7225bdf3f409faa48f3a27173395a25ad● \r\n"] +[35.165258, "o", "\u001b[A7225bdf3f409faa48f3a27173395a25ad642● \r\n"] +[35.185913, "o", "\u001b[A7225bdf3f409faa48f3a27173395a25ad64222● \r\n"] +[35.214237, "o", "\u001b[A7225bdf3f409faa48f3a27173395a25ad64222/image.webp● \r\n"] +[35.230491, "o", "\u001b[3A🌆 Generated sunflower image \r\n\u001b[K\r\n●\r\u001b[2S\u001b[31;2H \u001b[33;1H\u001b[K\r\n\u001b[K"] +[35.24659, "o", "\u001b[5A🌆 Generated sunflower image \u001b[31;1HSeed● \u001b[33;1H"] +[35.268914, "o", "\u001b[4A🌆 Generated sunflower image \u001b[31;1HSeed:● \u001b[33;1H"] +[35.288642, "o", "\u001b[4A🌆 Generated sunflower image \u001b[31;1HSeed: `● \u001b[33;1H"] +[35.311221, "o", "\u001b[4A🌆 Generated sunflower image \u001b[31;1HSeed: `182453● \u001b[33;1H"] +[35.331892, "o", "\u001b[4A🌆 Generated sunflower image \u001b[31;1HSeed: `182453741● \u001b[33;1H"] +[35.345768, "o", "\u001b[4A🌆 Generated sunflower image \u001b[31;1HSeed: `1824537418● \u001b[33;1H"] +[35.364942, "o", "\u001b[4A🌆 Generated sunflower image \u001b[31;1HSeed: \u001b[92m\u001b[40m1824537418\u001b[39m\u001b[49m● \u001b[33;1H"] +[35.601696, "o", "\u001b[4A🌆 Generated sunflower image \u001b[31;1HSeed: \u001b[92m\u001b[40m1824537418\u001b[39m\u001b[49m \r\n\u001b[?12l\u001b[?25h"] +[35.838429, "o", "\r\n"] +[35.876226, "o", "\u001b[2m[IMAGE 1: image/webp, 66098 bytes]\r\n\u001b(B\u001b[m\u001b[38;5;136m\u001b[48;5;142m▀\u001b[48;5;178m▀▀\u001b[38;5;142m▀\u001b[38;5;178m▀▀\u001b[38;5;136m▀\u001b[38;5;100m\u001b[48;5;142m▀▀▀\u001b[48;5;136m▀\u001b[48;5;100m▀▀▀\u001b[38;5;136m\u001b[48;5;136m▀▀▀▀\u001b[48;5;100m▀▀\u001b[48;5;136m▀▀\u001b[38;5;142m▀\u001b[38;5;178m\u001b[48;5;142m▀\u001b[38;5;142m▀▀\u001b[38;5;136m\u001b[48;5;136m▀▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀\u001b[38;5;136m\u001b[48;5;136m▀▀▀▀▀\u001b[48;5;100m▀\u001b[38;5;100m▀\u001b[48;5;136m▀\u001b[48;5;142m▀▀\u001b[38;5;106m▀▀▀▀\u001b[48;5;107m▀\u001b[48;5;106m▀\u001b[38;5;100m▀\u001b[48;5;100m▀▀▀▀▀▀▀▀▀▀▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[38;5;142m\u001b[48;5;142m▀\u001b[38;5;136m▀\u001b[48;5;136m▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀\u001b[48;5;64m▀\u001b[38;5;64m▀▀▀▀▀▀▀\u001b[38;5;100m▀\u001b[48;5;100m▀▀▀▀▀▀▀▀▀▀▀\u001b[38;5;101m\u001b[48;5;101m▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀▀▀\u001b[38;5;100m▀\u001b[48;5;100m▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;178m\u001b[48;5;178m▀\u001b[48;5;214m▀▀\u001b[38;5;214m▀\u001b(B\u001b[m"] +[35.876324, "o", "\u001b[38;5;220m\u001b[48;5;214m▀\u001b[38;5;214m▀\u001b[38;5;178m▀\u001b[48;5;178m▀▀▀\u001b[38;5;142m▀\u001b[38;5;136m\u001b[48;5;142m▀\u001b[48;5;136m▀▀▀▀\u001b[48;5;100m▀▀\u001b[38;5;100m▀▀▀\u001b[38;5;136m▀\u001b[48;5;136m▀▀▀▀▀\u001b[48;5;100m▀\u001b[38;5;100m▀▀▀\u001b[38;5;136m▀▀\u001b[48;5;136m▀\u001b[48;5;100m▀\u001b[38;5;100m▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[48;5;142m▀\u001b[38;5;142m▀▀\u001b[48;5;178m▀\u001b[48;5;142m▀▀▀▀▀\u001b[38;5;106m\u001b[48;5;106m▀▀\u001b[38;5;100m▀\u001b[48;5;100m▀▀▀▀▀▀▀▀▀\u001b[48;5;136m▀\u001b[38;5;136m\u001b[48;5;142m▀\u001b[38;5;142m▀▀▀\u001b[38;5;136m▀\u001b[38;5;100m\u001b[48;5;136m▀\u001b[48;5;100m▀\u001b[38;5;64m▀\u001b[48;5;64m▀\u001b[48;5;58m▀\u001b[38;5;58m▀▀\u001b[38;5;64m▀\u001b[48;5;64m▀▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀▀▀▀▀▀▀\u001b[38;5;101m\u001b[48;5;101m▀▀▀\u001b[38;5;64m\u001b[48;5;65m▀\u001b[48;5;64m▀▀▀▀▀\u001b[38;5;100m▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;178m\u001b[48;5;178m▀\u001b[38;5;214m▀▀\u001b[38;5;178m\u001b[48;5;172m▀▀▀▀\u001b[48;5;178m▀▀\u001b(B\u001b[m"] +[35.876582, "o", "\u001b[38;5;178m\u001b[48;5;178m▀▀▀\u001b[38;5;142m▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\u001b[38;5;142m\u001b[48;5;142m▀▀\u001b[48;5;178m▀\u001b[38;5;178m▀▀▀\u001b[38;5;142m▀\u001b[48;5;142m▀▀\u001b[48;5;136m▀\u001b[38;5;106m\u001b[48;5;100m▀▀\u001b[48;5;106m▀▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀\u001b[48;5;142m▀\u001b[38;5;142m\u001b[48;5;220m▀\u001b[38;5;178m▀\u001b[38;5;100m\u001b[48;5;100m▀▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[38;5;142m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀\u001b[38;5;142m▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[38;5;100m\u001b[48;5;100m▀▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀▀▀\u001b[38;5;64m▀\u001b[48;5;64m▀▀\u001b[38;5;100m▀\u001b[48;5;100m▀▀▀▀▀▀▀▀\u001b[48;5;101m▀\u001b[38;5;101m\u001b[48;5;100m▀▀\u001b[38;5;100m▀\u001b[38;5;64m▀\u001b[48;5;64m▀▀▀\u001b[48;5;58m▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;178m\u001b[48;5;178m▀\u001b[48;5;172m▀\u001b[38;5;172m\u001b[48;5;130m▀\u001b[38;5;130m\u001b[48;5;94m▀\u001b[48;5;58m▀\u001b[48;5;94m▀\u001b[38;5;136m▀\u001b[38;5;172m\u001b[48;5;136m▀\u001b[38;5;178m\u001b[48;5;172m▀\u001b[48;5;178m▀\u001b[38;5;214m\u001b[48;5;214m▀\u001b[38;5;178m▀\u001b[48;5;178m▀\u001b[38;5;142m\u001b[48;5;142m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b(B\u001b[m"] +[35.876787, "o", "\u001b[38;5;100m\u001b[48;5;100m▀▀▀▀▀▀▀▀▀▀▀▀▀▀\u001b[48;5;101m▀▀▀▀▀▀▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[38;5;142m\u001b[48;5;142m▀\u001b[38;5;178m\u001b[48;5;178m▀▀\u001b[48;5;220m▀\u001b[48;5;178m▀\u001b[38;5;142m\u001b[48;5;136m▀▀\u001b[38;5;136m▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀▀▀▀\u001b[48;5;142m▀\u001b[38;5;142m\u001b[48;5;220m▀\u001b[38;5;220m▀▀▀\u001b[38;5;136m\u001b[48;5;142m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;136m▀\u001b[48;5;136m▀\u001b[38;5;178m▀▀▀\u001b[38;5;172m▀\u001b[38;5;136m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀▀\u001b[38;5;100m▀\u001b[48;5;100m▀▀▀▀▀▀▀▀▀▀▀▀▀\u001b[38;5;64m▀\u001b[48;5;64m▀\u001b[38;5;58m▀\u001b[48;5;58m▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;172m\u001b[48;5;172m▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[38;5;94m\u001b[48;5;94m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;235m\u001b[48;5;52m▀\u001b[38;5;52m▀\u001b[38;5;94m\u001b[48;5;94m▀\u001b[38;5;130m\u001b[48;5;130m▀\u001b[38;5;172m\u001b[48;5;172m▀\u001b[38;5;178m\u001b[48;5;214m▀\u001b[38;5;214m▀▀\u001b[38;5;178m\u001b[48;5;178m▀\u001b[38;5;142m\u001b[48;5;142m▀\u001b[38;5;100m\u001b[48;5;106m▀\u001b[48;5;100m▀▀▀▀▀▀\u001b(B\u001b[m"] +[35.876956, "o", "\u001b[38;5;100m\u001b[48;5;100m▀▀▀▀▀▀▀\u001b[38;5;101m▀\u001b[48;5;101m▀▀\u001b[48;5;107m▀\u001b[48;5;143m▀\u001b[48;5;107m▀\u001b[48;5;101m▀▀\u001b[38;5;136m\u001b[48;5;137m▀\u001b[38;5;142m\u001b[48;5;136m▀\u001b[38;5;136m▀\u001b[38;5;178m\u001b[48;5;178m▀\u001b[38;5;220m\u001b[48;5;220m▀▀\u001b[38;5;178m▀\u001b[38;5;136m\u001b[48;5;142m▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀▀▀▀\u001b[48;5;142m▀\u001b[38;5;184m\u001b[48;5;220m▀\u001b[38;5;220m▀▀▀▀\u001b[38;5;142m\u001b[48;5;178m▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀\u001b[38;5;136m▀▀▀\u001b[38;5;100m▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;58m▀\u001b[48;5;58m▀▀▀\u001b[48;5;64m▀\u001b[48;5;100m▀▀\u001b[48;5;64m▀\u001b[48;5;58m▀\u001b[38;5;64m▀\u001b[48;5;64m▀▀\u001b[38;5;100m▀\u001b[48;5;100m▀▀▀▀▀▀▀▀▀▀▀▀\u001b[38;5;64m▀\u001b[48;5;64m▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;172m\u001b[48;5;172m▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[38;5;130m▀\u001b[38;5;94m\u001b[48;5;130m▀\u001b[38;5;58m\u001b[48;5;94m▀\u001b[38;5;94m\u001b[48;5;130m▀▀\u001b[38;5;136m\u001b[48;5;172m▀\u001b[38;5;178m\u001b[48;5;178m▀\u001b[38;5;214m▀▀\u001b[38;5;178m▀\u001b[48;5;142m▀\u001b[38;5;142m\u001b[48;5;100m▀\u001b[38;5;100m▀▀▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀▀\u001b[48;5;64m▀\u001b(B\u001b[m"] +[35.877187, "o", "\u001b[38;5;64m\u001b[48;5;64m▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;101m\u001b[48;5;101m▀▀\u001b[38;5;143m\u001b[48;5;142m▀\u001b[38;5;184m\u001b[48;5;220m▀\u001b[38;5;143m\u001b[48;5;184m▀\u001b[38;5;107m\u001b[48;5;143m▀\u001b[48;5;101m▀\u001b[38;5;101m▀\u001b[38;5;137m▀\u001b[38;5;136m▀\u001b[38;5;142m\u001b[48;5;142m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀\u001b[38;5;142m▀\u001b[38;5;100m\u001b[48;5;136m▀\u001b[48;5;100m▀▀▀▀\u001b[38;5;184m\u001b[48;5;220m▀\u001b[38;5;220m▀▀▀▀▀\u001b[38;5;178m\u001b[48;5;184m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[48;5;64m▀\u001b[38;5;64m▀▀▀\u001b[38;5;100m▀▀▀\u001b[38;5;64m\u001b[48;5;100m▀\u001b[48;5;64m▀\u001b[48;5;100m▀\u001b[48;5;142m▀\u001b[38;5;100m\u001b[48;5;220m▀\u001b[38;5;142m▀\u001b[38;5;178m▀▀\u001b[38;5;142m\u001b[48;5;136m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[38;5;64m▀\u001b[48;5;64m▀\u001b[38;5;100m▀\u001b[48;5;100m▀▀▀▀▀▀\u001b[48;5;64m▀\u001b[48;5;100m▀▀▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;172m\u001b[48;5;136m▀\u001b[48;5;172m▀\u001b[38;5;136m\u001b[48;5;136m▀▀▀\u001b[48;5;172m▀▀\u001b[38;5;172m\u001b[48;5;178m▀\u001b[38;5;178m▀▀\u001b[48;5;136m▀\u001b[38;5;142m▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀▀\u001b[48;5;101m▀\u001b[48;5;100m▀▀\u001b[38;5;64m▀\u001b[38;5;100m▀▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀\u001b[48;5;58m▀▀▀\u001b[38;5;100m\u001b[48;5;64m▀\u001b[38;5;101m\u001b[48;5;100m▀\u001b[38;5;142m\u001b[48;5;142m▀\u001b(B\u001b[m"] +[35.877427, "o", "\u001b[38;5;220m\u001b[48;5;220m▀▀\u001b[38;5;178m▀\u001b[38;5;101m\u001b[48;5;178m▀\u001b[48;5;101m▀▀\u001b[48;5;65m▀\u001b[38;5;136m\u001b[48;5;100m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀▀\u001b[38;5;184m▀\u001b[38;5;100m\u001b[48;5;178m▀\u001b[48;5;100m▀▀\u001b[38;5;142m\u001b[48;5;142m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[48;5;58m▀\u001b[38;5;58m▀▀\u001b[38;5;64m▀\u001b[48;5;64m▀\u001b[48;5;100m▀\u001b[48;5;142m▀\u001b[38;5;136m\u001b[48;5;220m▀\u001b[38;5;184m▀\u001b[38;5;220m▀▀▀▀\u001b[38;5;178m\u001b[48;5;136m▀\u001b[38;5;136m▀\u001b[38;5;100m\u001b[48;5;100m▀▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;100m▀▀\u001b[48;5;100m▀\u001b[48;5;64m▀▀\u001b[38;5;64m▀▀▀▀▀\u001b[38;5;100m▀\u001b[38;5;64m▀▀▀\u001b[48;5;58m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;136m\u001b[48;5;100m▀▀▀\u001b[48;5;136m▀\u001b[38;5;172m▀\u001b[38;5;178m▀▀\u001b[38;5;136m▀\u001b[48;5;100m▀▀\u001b[38;5;100m▀▀▀\u001b[48;5;106m▀\u001b[38;5;106m▀\u001b[38;5;107m\u001b[48;5;107m▀\u001b[38;5;101m▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀\u001b[48;5;64m▀▀▀\u001b[38;5;64m▀▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀\u001b[48;5;64m▀\u001b[38;5;64m▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀\u001b[38;5;178m▀\u001b[38;5;100m\u001b[48;5;184m▀\u001b(B\u001b[m"] +[35.877882, "o", "\u001b[38;5;65m\u001b[48;5;100m▀\u001b[38;5;100m\u001b[48;5;64m▀\u001b[38;5;220m\u001b[48;5;178m▀\u001b[48;5;220m▀▀▀▀▀▀\u001b[38;5;142m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;178m\u001b[48;5;178m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀▀▀▀\u001b[38;5;100m\u001b[48;5;142m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀\u001b[48;5;100m▀\u001b[38;5;100m\u001b[48;5;220m▀\u001b[38;5;178m▀\u001b[38;5;220m▀▀▀▀▀\u001b[48;5;178m▀\u001b[38;5;178m\u001b[48;5;100m▀\u001b[38;5;136m▀▀\u001b[38;5;100m\u001b[48;5;58m▀\u001b[38;5;64m▀\u001b[38;5;58m▀▀▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀▀▀\u001b[48;5;58m▀▀▀\u001b[48;5;64m▀▀▀▀▀▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;100m\u001b[48;5;100m▀▀▀▀\u001b[48;5;64m▀\u001b[48;5;58m▀▀\u001b[38;5;58m▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;100m\u001b[48;5;100m▀▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[38;5;142m\u001b[48;5;142m▀\u001b[38;5;143m▀\u001b[38;5;107m▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[38;5;100m\u001b[48;5;100m▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀▀▀▀\u001b[38;5;58m\u001b[48;5;65m▀▀\u001b[38;5;65m▀\u001b[48;5;101m▀\u001b[48;5;65m▀▀\u001b[38;5;64m\u001b[48;5;240m▀\u001b[38;5;178m\u001b[48;5;136m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀▀▀\u001b[38;5;136m▀\u001b[38;5;178m\u001b[48;5;178m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀\u001b(B\u001b[m\u001b[38;5;220m\u001b[48;5;220m▀▀▀\u001b[38;5;178m▀▀\u001b[38;5;220m▀▀▀▀▀▀▀\u001b[38;5;178m\u001b[48;5;178m▀\u001b[38;5;64m\u001b[48;5;64m▀▀\u001b[38;5;58m\u001b[48;5;100m▀\u001b[38;5;100m\u001b[48;5;220m▀\u001b[38;5;220m▀▀▀▀▀▀▀\u001b[48;5;178m▀\u001b[38;5;100m\u001b[48;5;58m▀\u001b[38;5;58m▀▀▀▀▀\u001b[48;5;100m▀\u001b[48;5;58m▀▀\u001b[48;5;64m▀▀\u001b[48;5;58m▀▀\u001b[48;5;64m▀▀\u001b[48;5;100m▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀▀▀\u001b[48;5;100m▀\u001b[38;5;100m▀▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;100m\u001b[48;5;100m▀▀▀\u001b[48;5;101m▀\u001b[38;5;64m\u001b[48;5;65m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;106m▀\u001b[38;5;142m\u001b[48;5;106m▀\u001b[48;5;142m▀▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[38;5;100m▀\u001b[48;5;100m▀\u001b[38;5;64m▀\u001b[48;5;64m▀\u001b[38;5;58m▀\u001b[48;5;58m▀\u001b[38;5;64m\u001b[48;5;65m▀\u001b[38;5;65m▀\u001b[38;5;101m\u001b[48;5;101m▀▀▀\u001b[38;5;65m\u001b[48;5;65m▀▀\u001b[38;5;240m\u001b[48;5;58m▀\u001b[38;5;58m▀\u001b[38;5;184m\u001b[48;5;136m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀▀▀▀\u001b[48;5;214m▀\u001b[48;5;220m▀▀▀▀▀▀▀\u001b[48;5;214m▀\u001b[38;5;214m▀\u001b[38;5;220m\u001b[48;5;220m▀\u001b[38;5;214m\u001b[48;5;214m▀\u001b[38;5;220m▀\u001b(B\u001b[m"] +[35.878086, "o", "\u001b[38;5;220m\u001b[48;5;214m▀\u001b[48;5;220m▀▀\u001b[38;5;184m\u001b[48;5;184m▀\u001b[38;5;64m\u001b[48;5;100m▀\u001b[38;5;100m\u001b[48;5;178m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀▀▀▀▀▀\u001b[38;5;136m\u001b[48;5;100m▀\u001b[38;5;58m\u001b[48;5;64m▀\u001b[48;5;136m▀\u001b[48;5;178m▀\u001b[38;5;100m\u001b[48;5;220m▀\u001b[38;5;142m▀\u001b[38;5;178m\u001b[48;5;136m▀\u001b[38;5;100m\u001b[48;5;58m▀\u001b[38;5;58m▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀▀\u001b[48;5;100m▀\u001b[38;5;100m▀▀▀▀▀▀▀▀▀▀▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;100m\u001b[48;5;100m▀▀\u001b[48;5;106m▀\u001b[38;5;101m\u001b[48;5;101m▀▀\u001b[38;5;240m\u001b[48;5;65m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀\u001b[48;5;65m▀\u001b[48;5;101m▀\u001b[38;5;64m\u001b[48;5;107m▀\u001b[38;5;100m\u001b[48;5;143m▀\u001b[38;5;106m▀\u001b[38;5;142m\u001b[48;5;142m▀▀▀▀\u001b[38;5;106m\u001b[48;5;106m▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀▀\u001b[38;5;58m\u001b[48;5;142m▀\u001b[38;5;65m▀▀\u001b[38;5;101m\u001b[48;5;100m▀▀\u001b[48;5;64m▀\u001b[38;5;65m▀\u001b[38;5;64m\u001b[48;5;58m▀\u001b[38;5;58m▀▀▀\u001b[38;5;184m\u001b[48;5;136m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀▀▀\u001b[38;5;214m\u001b[48;5;214m▀▀\u001b[38;5;220m▀\u001b[48;5;220m▀\u001b[48;5;214m▀▀\u001b[38;5;214m▀\u001b[38;5;220m▀\u001b[38;5;214m▀▀▀▀▀▀\u001b[38;5;220m▀\u001b[48;5;220m▀\u001b[38;5;184m▀\u001b[38;5;136m\u001b[48;5;214m▀\u001b[38;5;220m\u001b[48;5;220m▀▀\u001b(B\u001b[m"] +[35.878285, "o", "\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀▀▀▀\u001b[38;5;178m▀\u001b[38;5;136m▀\u001b[38;5;184m▀\u001b[38;5;220m▀▀\u001b[48;5;178m▀\u001b[38;5;142m\u001b[48;5;58m▀\u001b[38;5;58m\u001b[48;5;236m▀\u001b[48;5;58m▀▀▀▀\u001b[38;5;64m▀\u001b[48;5;64m▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀\u001b[38;5;136m\u001b[48;5;136m▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀\u001b[48;5;64m▀▀▀▀\u001b[38;5;64m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[48;5;107m▀\u001b[38;5;101m\u001b[48;5;101m▀▀\u001b[38;5;65m\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;239m\u001b[48;5;239m▀\u001b[38;5;65m\u001b[48;5;65m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;107m\u001b[48;5;143m▀\u001b[38;5;144m\u001b[48;5;144m▀▀\u001b[38;5;143m\u001b[48;5;143m▀▀\u001b[38;5;142m\u001b[48;5;142m▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[48;5;100m▀▀▀\u001b[38;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;100m\u001b[48;5;58m▀\u001b[38;5;220m\u001b[48;5;100m▀\u001b[48;5;220m▀▀▀▀\u001b[38;5;178m▀\u001b[38;5;142m▀\u001b[38;5;100m▀\u001b[38;5;58m\u001b[48;5;178m▀\u001b[48;5;136m▀\u001b[48;5;100m▀\u001b[48;5;58m▀\u001b[38;5;178m\u001b[48;5;100m▀\u001b[38;5;220m\u001b[48;5;220m▀▀\u001b[38;5;214m▀\u001b[38;5;220m\u001b[48;5;214m▀▀\u001b[48;5;220m▀\u001b[38;5;214m\u001b[48;5;214m▀▀▀▀▀▀▀▀▀▀\u001b[48;5;178m▀▀▀\u001b[48;5;214m▀\u001b[38;5;220m\u001b[48;5;220m▀\u001b[48;5;214m▀▀▀\u001b[38;5;214m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀▀\u001b[48;5;214m▀\u001b[48;5;220m▀▀\u001b(B\u001b[m"] +[35.878515, "o", "\u001b[38;5;220m\u001b[48;5;214m▀\u001b[48;5;220m▀▀\u001b[48;5;142m▀\u001b[38;5;94m\u001b[48;5;236m▀\u001b[38;5;235m\u001b[48;5;235m▀▀\u001b[38;5;236m▀\u001b[38;5;58m▀\u001b[48;5;58m▀▀▀▀\u001b[38;5;64m▀\u001b[38;5;100m\u001b[48;5;100m▀▀\u001b[38;5;136m▀\u001b[48;5;136m▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;101m\u001b[48;5;101m▀▀▀\u001b[38;5;64m▀\u001b[48;5;100m▀▀\u001b[48;5;64m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;106m\u001b[48;5;107m▀\u001b[38;5;107m▀\u001b[38;5;101m\u001b[48;5;101m▀▀\u001b[38;5;240m\u001b[48;5;240m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;239m▀\u001b[38;5;65m\u001b[48;5;239m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;143m\u001b[48;5;107m▀\u001b[38;5;144m\u001b[48;5;143m▀▀\u001b[38;5;143m▀\u001b[48;5;107m▀\u001b[38;5;106m\u001b[48;5;100m▀\u001b[38;5;100m\u001b[48;5;64m▀\u001b[38;5;64m\u001b[48;5;58m▀▀▀▀▀\u001b[38;5;58m▀▀\u001b[38;5;142m▀\u001b[38;5;220m\u001b[48;5;142m▀\u001b[48;5;220m▀▀▀▀▀▀▀▀\u001b[38;5;178m▀\u001b[38;5;142m▀▀\u001b[38;5;220m▀▀▀\u001b[38;5;214m\u001b[48;5;214m▀▀▀▀\u001b[38;5;208m▀\u001b[38;5;214m\u001b[48;5;172m▀\u001b[48;5;208m▀\u001b[48;5;214m▀\u001b[38;5;208m\u001b[48;5;172m▀\u001b[38;5;214m▀\u001b[48;5;214m▀\u001b[38;5;208m\u001b[48;5;172m▀\u001b[38;5;172m▀▀▀\u001b[38;5;214m\u001b[48;5;214m▀▀▀▀▀▀\u001b[38;5;220m▀▀▀\u001b[38;5;214m▀▀▀▀▀\u001b[38;5;220m▀\u001b[38;5;214m▀\u001b[48;5;136m▀\u001b[38;5;58m\u001b[48;5;236m▀\u001b[38;5;235m\u001b[48;5;235m▀▀\u001b[38;5;234m\u001b[48;5;234m▀\u001b[38;5;235m▀▀\u001b(B\u001b[m"] +[35.878718, "o", "\u001b[38;5;235m\u001b[48;5;235m▀\u001b[38;5;236m▀\u001b[38;5;58m▀\u001b[48;5;58m▀▀\u001b[38;5;64m▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀▀\u001b[48;5;101m▀\u001b[38;5;101m\u001b[48;5;143m▀\u001b[38;5;137m\u001b[48;5;142m▀\u001b[38;5;143m\u001b[48;5;178m▀\u001b[38;5;136m▀▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;101m▀\u001b[48;5;101m▀▀\u001b[48;5;65m▀\u001b[38;5;240m\u001b[48;5;58m▀\u001b[38;5;58m▀▀▀▀\u001b[38;5;65m▀\u001b[38;5;101m\u001b[48;5;64m▀▀\u001b[48;5;100m▀\u001b[38;5;100m\u001b[48;5;64m▀\u001b[38;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀▀▀▀▀▀\u001b[48;5;239m▀\u001b[38;5;142m\u001b[48;5;58m▀\u001b[38;5;220m\u001b[48;5;136m▀\u001b[48;5;220m▀▀▀▀\u001b[38;5;214m▀\u001b[48;5;214m▀\u001b[38;5;220m▀▀▀▀\u001b[38;5;214m▀▀▀▀▀\u001b[48;5;208m▀\u001b[48;5;172m▀\u001b[38;5;172m▀▀\u001b[38;5;208m▀\u001b[38;5;172m▀▀\u001b[48;5;136m▀\u001b[38;5;136m\u001b[48;5;94m▀\u001b[38;5;172m\u001b[48;5;130m▀\u001b[48;5;172m▀\u001b[48;5;136m▀\u001b[48;5;172m▀\u001b[48;5;136m▀\u001b[48;5;172m▀▀\u001b[38;5;214m\u001b[48;5;214m▀▀▀▀▀▀▀▀▀▀▀\u001b[48;5;136m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;235m\u001b[48;5;236m▀\u001b[48;5;235m▀▀▀\u001b[38;5;234m▀\u001b[48;5;234m▀▀▀\u001b[38;5;235m\u001b[48;5;235m▀\u001b[38;5;236m\u001b[48;5;236m▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;100m▀\u001b[48;5;100m▀\u001b(B\u001b[m"] +[35.878914, "o", "\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[38;5;142m\u001b[48;5;142m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀\u001b[48;5;214m▀\u001b[38;5;214m▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;100m▀▀\u001b[38;5;65m▀▀\u001b[38;5;58m\u001b[48;5;100m▀\u001b[48;5;136m▀▀\u001b[48;5;100m▀\u001b[48;5;64m▀▀▀\u001b[38;5;64m▀▀▀▀▀\u001b[38;5;58m▀\u001b[48;5;58m▀\u001b[48;5;100m▀\u001b[48;5;142m▀\u001b[48;5;178m▀▀▀▀▀\u001b[38;5;240m▀\u001b[38;5;64m\u001b[48;5;142m▀\u001b[38;5;100m▀\u001b[38;5;220m\u001b[48;5;178m▀\u001b[48;5;220m▀▀▀▀\u001b[38;5;214m▀\u001b[48;5;214m▀▀▀\u001b[48;5;178m▀\u001b[48;5;172m▀▀▀▀▀\u001b[38;5;172m▀▀\u001b[48;5;130m▀\u001b[38;5;130m▀\u001b[48;5;94m▀▀▀\u001b[38;5;94m▀▀\u001b[38;5;130m▀▀▀\u001b[38;5;94m▀\u001b[38;5;136m\u001b[48;5;130m▀\u001b[38;5;172m\u001b[48;5;172m▀▀\u001b[38;5;214m▀▀\u001b[38;5;178m▀\u001b[48;5;178m▀▀\u001b[38;5;214m▀▀\u001b[48;5;214m▀▀\u001b[38;5;178m\u001b[48;5;100m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[48;5;100m▀\u001b[38;5;236m▀\u001b[38;5;235m▀▀\u001b[48;5;94m▀\u001b[48;5;58m▀▀\u001b[48;5;235m▀▀▀\u001b[38;5;236m\u001b[48;5;236m▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;136m\u001b[48;5;136m▀▀\u001b[38;5;178m\u001b[48;5;172m▀▀▀▀\u001b[38;5;214m\u001b[48;5;178m▀▀\u001b[39m\u001b[49m\r\n\u001b[K"] +[35.879203, "o", "\u001b[38;5;136m\u001b[48;5;220m▀\u001b[38;5;100m\u001b[48;5;178m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;100m\u001b[48;5;178m▀\u001b[38;5;178m\u001b[48;5;220m▀\u001b[38;5;220m▀▀\u001b[38;5;178m\u001b[48;5;185m▀\u001b[38;5;107m\u001b[48;5;144m▀▀\u001b[48;5;143m▀▀\u001b[38;5;100m\u001b[48;5;142m▀\u001b[48;5;100m▀▀▀\u001b[38;5;64m▀\u001b[48;5;64m▀\u001b[38;5;100m▀\u001b[38;5;220m\u001b[48;5;142m▀\u001b[48;5;220m▀▀▀▀▀▀▀▀▀▀▀\u001b[38;5;214m▀\u001b[38;5;220m\u001b[48;5;214m▀▀\u001b[38;5;214m▀▀\u001b[48;5;178m▀\u001b[38;5;178m\u001b[48;5;172m▀\u001b[38;5;172m▀▀▀\u001b[48;5;136m▀\u001b[38;5;136m\u001b[48;5;130m▀\u001b[38;5;130m\u001b[48;5;94m▀▀\u001b[38;5;94m▀▀▀▀▀▀▀▀▀▀▀▀\u001b[38;5;130m▀▀\u001b[38;5;136m\u001b[48;5;130m▀\u001b[38;5;172m\u001b[48;5;172m▀▀▀\u001b[38;5;178m▀\u001b[48;5;214m▀\u001b[38;5;214m▀▀\u001b[38;5;178m\u001b[48;5;220m▀▀\u001b[38;5;220m\u001b[48;5;214m▀▀▀▀\u001b[48;5;220m▀▀▀\u001b[38;5;184m▀\u001b[38;5;178m▀\u001b[38;5;142m▀\u001b[38;5;100m▀▀▀\u001b[38;5;64m\u001b[48;5;178m▀▀\u001b[38;5;58m\u001b[48;5;136m▀\u001b[38;5;64m\u001b[48;5;100m▀\u001b[38;5;100m▀▀\u001b[38;5;136m\u001b[48;5;136m▀▀▀\u001b[38;5;130m\u001b[48;5;130m▀\u001b[48;5;94m▀\u001b[38;5;136m\u001b[48;5;130m▀\u001b[38;5;172m\u001b[48;5;136m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;220m\u001b[48;5;220m▀▀\u001b[38;5;100m\u001b[48;5;178m▀▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀\u001b(B\u001b[m"] +[35.879367, "o", "\u001b[38;5;221m\u001b[48;5;220m▀\u001b[38;5;186m\u001b[48;5;221m▀\u001b[38;5;185m\u001b[48;5;220m▀\u001b[38;5;221m▀\u001b[38;5;220m▀\u001b[38;5;178m\u001b[48;5;178m▀\u001b[38;5;136m\u001b[48;5;136m▀▀\u001b[38;5;100m▀\u001b[48;5;100m▀▀\u001b[38;5;64m▀\u001b[48;5;64m▀\u001b[38;5;178m▀\u001b[38;5;220m\u001b[48;5;178m▀\u001b[48;5;220m▀▀▀▀▀▀▀▀▀▀\u001b[48;5;214m▀\u001b[38;5;214m▀▀\u001b[48;5;172m▀\u001b[38;5;178m▀\u001b[38;5;172m▀▀▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[38;5;130m\u001b[48;5;130m▀\u001b[48;5;94m▀\u001b[38;5;94m▀▀▀▀▀▀▀▀▀▀▀▀▀▀\u001b[48;5;52m▀\u001b[48;5;88m▀\u001b[38;5;130m\u001b[48;5;94m▀\u001b[48;5;130m▀\u001b[38;5;172m\u001b[48;5;172m▀▀\u001b[38;5;178m\u001b[48;5;136m▀\u001b[38;5;172m\u001b[48;5;172m▀▀\u001b[38;5;214m▀\u001b[48;5;178m▀▀▀\u001b[48;5;214m▀▀▀▀▀\u001b[38;5;220m▀\u001b[48;5;220m▀▀▀▀\u001b[48;5;178m▀\u001b[48;5;136m▀\u001b[48;5;100m▀\u001b[38;5;178m\u001b[48;5;64m▀\u001b[38;5;136m▀\u001b[38;5;64m▀\u001b[38;5;100m\u001b[48;5;100m▀▀\u001b[38;5;136m▀\u001b[48;5;136m▀▀\u001b[38;5;130m▀▀▀\u001b[38;5;136m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;220m\u001b[48;5;220m▀▀\u001b[38;5;214m▀▀\u001b[38;5;220m▀▀▀▀▀▀▀▀\u001b[48;5;178m▀\u001b[38;5;172m\u001b[48;5;130m▀\u001b[38;5;136m\u001b[48;5;94m▀\u001b[48;5;136m▀\u001b(B\u001b[m"] +[35.87957, "o", "\u001b[38;5;136m\u001b[48;5;136m▀▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀\u001b[38;5;64m▀▀\u001b[38;5;142m\u001b[48;5;178m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀▀▀▀\u001b[48;5;214m▀\u001b[38;5;214m▀▀\u001b[48;5;178m▀▀\u001b[38;5;178m\u001b[48;5;172m▀\u001b[38;5;172m▀▀\u001b[38;5;130m\u001b[48;5;130m▀\u001b[48;5;94m▀\u001b[38;5;94m▀▀▀▀▀▀\u001b[48;5;52m▀\u001b[38;5;58m▀\u001b[38;5;94m▀\u001b[38;5;58m▀▀\u001b[38;5;52m▀\u001b[38;5;94m▀▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[48;5;94m▀\u001b[38;5;94m\u001b[48;5;58m▀\u001b[38;5;58m▀\u001b[38;5;52m\u001b[48;5;52m▀\u001b[38;5;94m\u001b[48;5;94m▀\u001b[48;5;52m▀▀\u001b[48;5;94m▀\u001b[38;5;130m\u001b[48;5;130m▀\u001b[38;5;172m\u001b[48;5;136m▀\u001b[48;5;172m▀▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀▀▀\u001b[38;5;214m\u001b[48;5;214m▀▀▀\u001b[38;5;220m\u001b[48;5;142m▀\u001b[38;5;178m\u001b[48;5;58m▀\u001b[38;5;136m▀\u001b[38;5;100m\u001b[48;5;64m▀\u001b[48;5;100m▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀▀▀\u001b[38;5;100m▀▀\u001b[48;5;100m▀▀▀▀\u001b[38;5;136m▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;214m\u001b[48;5;214m▀▀\u001b[38;5;220m▀▀▀▀▀▀▀▀▀\u001b[38;5;214m▀\u001b[38;5;178m▀\u001b[38;5;136m\u001b[48;5;220m▀\u001b[38;5;172m▀\u001b[38;5;178m▀▀\u001b[48;5;178m▀\u001b[38;5;142m\u001b[48;5;142m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[48;5;106m▀\u001b[38;5;142m\u001b[48;5;184m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀\u001b(B\u001b[m"] +[35.879769, "o", "\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀\u001b[48;5;214m▀▀\u001b[38;5;214m▀▀▀\u001b[38;5;178m▀\u001b[38;5;172m\u001b[48;5;178m▀\u001b[48;5;172m▀▀▀\u001b[38;5;130m\u001b[48;5;130m▀\u001b[48;5;94m▀\u001b[38;5;94m▀▀▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;52m\u001b[48;5;52m▀\u001b[48;5;235m▀\u001b[48;5;234m▀▀▀\u001b[38;5;235m▀▀▀\u001b[38;5;52m\u001b[48;5;235m▀\u001b[48;5;52m▀▀▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;52m▀\u001b[48;5;52m▀▀▀▀\u001b[38;5;94m\u001b[48;5;94m▀\u001b[38;5;130m\u001b[48;5;130m▀\u001b[38;5;136m\u001b[48;5;172m▀\u001b[38;5;172m▀▀\u001b[48;5;178m▀\u001b[38;5;178m▀▀\u001b[48;5;214m▀\u001b[38;5;214m\u001b[48;5;178m▀▀\u001b[38;5;178m\u001b[48;5;214m▀\u001b[38;5;214m▀▀\u001b[38;5;178m▀\u001b[48;5;220m▀▀\u001b[38;5;142m▀\u001b[38;5;136m▀\u001b[38;5;100m▀\u001b[48;5;178m▀\u001b[38;5;64m\u001b[48;5;142m▀\u001b[48;5;100m▀\u001b[48;5;64m▀\u001b[48;5;58m▀\u001b[38;5;58m▀▀▀▀▀\u001b[38;5;100m▀\u001b[48;5;64m▀\u001b[48;5;100m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;172m\u001b[48;5;136m▀\u001b[48;5;130m▀▀▀\u001b[38;5;214m\u001b[48;5;172m▀▀▀▀\u001b[48;5;178m▀▀\u001b[48;5;214m▀▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀\u001b[48;5;214m▀\u001b[38;5;178m\u001b[48;5;178m▀\u001b[38;5;142m\u001b[48;5;220m▀\u001b[38;5;184m▀\u001b[38;5;220m▀▀▀▀▀▀\u001b[48;5;214m▀▀▀▀▀▀\u001b[38;5;214m▀▀\u001b[48;5;172m▀\u001b(B\u001b[m"] +[35.880185, "o", "\u001b[38;5;214m\u001b[48;5;172m▀\u001b[38;5;178m▀\u001b[38;5;172m\u001b[48;5;130m▀\u001b[38;5;136m\u001b[48;5;94m▀\u001b[38;5;130m▀\u001b[38;5;94m▀▀▀\u001b[38;5;58m\u001b[48;5;52m▀\u001b[38;5;52m▀\u001b[48;5;234m▀\u001b[38;5;234m▀\u001b[48;5;233m▀\u001b[38;5;233m▀▀\u001b[38;5;234m\u001b[48;5;234m▀▀\u001b[48;5;233m▀▀\u001b[38;5;235m\u001b[48;5;234m▀\u001b[38;5;52m\u001b[48;5;235m▀\u001b[48;5;52m▀▀▀▀▀▀▀▀\u001b[38;5;94m▀\u001b[48;5;94m▀\u001b[38;5;172m\u001b[48;5;130m▀▀\u001b[48;5;136m▀\u001b[48;5;172m▀▀\u001b[38;5;178m▀\u001b[48;5;178m▀▀▀▀▀▀\u001b[48;5;214m▀\u001b[48;5;220m▀\u001b[38;5;214m▀▀\u001b[38;5;220m▀▀\u001b[38;5;214m▀▀\u001b[38;5;178m\u001b[48;5;136m▀\u001b[38;5;100m\u001b[48;5;58m▀\u001b[38;5;58m▀▀\u001b[38;5;236m\u001b[48;5;235m▀▀\u001b[38;5;58m\u001b[48;5;237m▀\u001b[48;5;58m▀▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;94m\u001b[48;5;94m▀\u001b[48;5;58m▀▀▀▀\u001b[38;5;130m▀\u001b[48;5;94m▀\u001b[38;5;166m▀\u001b[38;5;172m\u001b[48;5;130m▀\u001b[48;5;172m▀\u001b[38;5;214m\u001b[48;5;178m▀\u001b[48;5;214m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\u001b[38;5;214m▀▀\u001b[48;5;214m▀▀▀▀\u001b[38;5;178m▀\u001b[38;5;172m\u001b[48;5;178m▀\u001b[48;5;172m▀▀\u001b[38;5;130m\u001b[48;5;136m▀\u001b[48;5;130m▀\u001b[38;5;94m\u001b[48;5;94m▀▀▀\u001b[38;5;58m\u001b[48;5;52m▀\u001b[38;5;52m▀\u001b[38;5;234m\u001b[48;5;234m▀\u001b[48;5;233m▀\u001b(B\u001b[m\u001b[38;5;233m\u001b[48;5;233m▀\u001b[48;5;234m▀\u001b[38;5;234m▀▀▀▀▀\u001b[38;5;233m▀\u001b[38;5;234m▀▀\u001b[38;5;52m\u001b[48;5;235m▀\u001b[48;5;52m▀▀▀\u001b[38;5;58m▀\u001b[38;5;52m▀▀▀\u001b[38;5;94m▀\u001b[38;5;130m\u001b[48;5;130m▀\u001b[48;5;136m▀\u001b[38;5;136m\u001b[48;5;172m▀\u001b[38;5;172m▀▀\u001b[38;5;178m▀\u001b[48;5;178m▀▀▀▀▀▀▀\u001b[48;5;214m▀▀\u001b[38;5;214m\u001b[48;5;220m▀\u001b[38;5;220m▀\u001b[48;5;178m▀\u001b[48;5;136m▀\u001b[38;5;178m\u001b[48;5;64m▀\u001b[38;5;100m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀\u001b[38;5;235m\u001b[48;5;235m▀▀\u001b[38;5;236m\u001b[48;5;236m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;52m\u001b[48;5;52m▀▀▀▀▀▀▀\u001b[38;5;58m▀\u001b[38;5;94m\u001b[48;5;58m▀\u001b[38;5;130m\u001b[48;5;94m▀\u001b[38;5;172m\u001b[48;5;130m▀\u001b[38;5;178m\u001b[48;5;172m▀\u001b[38;5;214m▀\u001b[48;5;178m▀\u001b[48;5;214m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀▀\u001b[48;5;184m▀▀▀\u001b[48;5;220m▀▀\u001b[38;5;214m▀▀▀▀▀\u001b[48;5;214m▀▀▀\u001b[38;5;178m▀\u001b[38;5;172m▀▀\u001b[48;5;172m▀▀\u001b[38;5;130m\u001b[48;5;130m▀\u001b[38;5;94m\u001b[48;5;94m▀▀▀\u001b[38;5;52m\u001b[48;5;52m▀▀\u001b[38;5;234m\u001b[48;5;234m▀\u001b[38;5;233m\u001b[48;5;233m▀\u001b[48;5;234m▀\u001b[38;5;234m▀\u001b[38;5;235m▀\u001b[48;5;235m▀\u001b[48;5;236m▀\u001b[38;5;234m\u001b[48;5;234m▀▀\u001b[38;5;233m▀\u001b[38;5;234m\u001b[48;5;233m▀\u001b[48;5;234m▀\u001b[38;5;235m\u001b[48;5;235m▀\u001b(B\u001b[m"] +[35.880422, "o", "\u001b[38;5;52m\u001b[48;5;52m▀▀▀▀▀▀▀▀▀\u001b[38;5;94m\u001b[48;5;94m▀\u001b[38;5;172m\u001b[48;5;130m▀\u001b[48;5;172m▀\u001b[38;5;178m▀▀\u001b[48;5;178m▀\u001b[38;5;214m▀▀▀\u001b[48;5;136m▀\u001b[48;5;100m▀▀\u001b[48;5;58m▀\u001b[38;5;178m▀\u001b[38;5;142m\u001b[48;5;64m▀\u001b[38;5;100m▀\u001b[38;5;64m\u001b[48;5;65m▀\u001b[48;5;64m▀▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀▀\u001b[38;5;236m▀\u001b[48;5;237m▀\u001b[38;5;237m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;52m\u001b[48;5;52m▀\u001b[48;5;235m▀\u001b[38;5;235m\u001b[48;5;234m▀▀▀▀\u001b[38;5;52m\u001b[48;5;52m▀▀▀\u001b[38;5;58m▀\u001b[38;5;94m\u001b[48;5;94m▀\u001b[38;5;136m\u001b[48;5;130m▀\u001b[38;5;172m\u001b[48;5;172m▀\u001b[38;5;178m▀\u001b[38;5;214m\u001b[48;5;178m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀\u001b[48;5;178m▀\u001b[48;5;143m▀\u001b[38;5;179m\u001b[48;5;107m▀\u001b[38;5;143m▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[38;5;142m▀▀\u001b[48;5;100m▀\u001b[38;5;178m\u001b[48;5;106m▀\u001b[48;5;178m▀\u001b[38;5;214m\u001b[48;5;220m▀\u001b[38;5;220m▀\u001b[38;5;214m\u001b[48;5;214m▀▀\u001b[48;5;178m▀\u001b[48;5;172m▀▀\u001b[38;5;172m▀\u001b[48;5;136m▀\u001b[38;5;130m\u001b[48;5;130m▀▀\u001b[38;5;94m\u001b[48;5;94m▀▀\u001b[38;5;58m▀\u001b[38;5;52m\u001b[48;5;52m▀▀\u001b[38;5;234m\u001b[48;5;234m▀\u001b[38;5;233m\u001b[48;5;233m▀▀\u001b[38;5;234m▀\u001b[48;5;234m▀\u001b[38;5;235m▀▀\u001b[38;5;234m▀▀\u001b[48;5;233m▀\u001b[38;5;233m▀\u001b[38;5;234m\u001b[48;5;234m▀\u001b[48;5;235m▀\u001b[38;5;52m\u001b[48;5;52m▀▀▀▀▀▀▀\u001b[48;5;94m▀\u001b[38;5;94m\u001b[48;5;130m▀\u001b[38;5;130m▀\u001b[38;5;136m\u001b[48;5;172m▀\u001b[38;5;172m▀\u001b(B\u001b[m"] +[35.880599, "o", "\u001b[38;5;172m\u001b[48;5;172m▀\u001b[48;5;178m▀\u001b[38;5;178m▀▀▀▀▀\u001b[38;5;136m▀\u001b[38;5;58m▀\u001b[48;5;136m▀\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[48;5;65m▀\u001b[38;5;65m▀▀\u001b[38;5;58m▀\u001b[48;5;239m▀▀\u001b[48;5;65m▀▀\u001b[48;5;101m▀▀\u001b[48;5;65m▀\u001b[48;5;240m▀\u001b[48;5;58m▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;52m\u001b[48;5;52m▀\u001b[38;5;235m\u001b[48;5;235m▀\u001b[38;5;234m\u001b[48;5;234m▀▀▀▀\u001b[38;5;235m\u001b[48;5;235m▀\u001b[38;5;52m\u001b[48;5;52m▀▀▀\u001b[38;5;94m\u001b[48;5;94m▀\u001b[38;5;130m\u001b[48;5;130m▀\u001b[38;5;172m\u001b[48;5;172m▀▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀\u001b[38;5;142m\u001b[48;5;136m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;101m\u001b[48;5;64m▀▀▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[48;5;178m▀\u001b[38;5;142m\u001b[48;5;220m▀\u001b[38;5;178m▀\u001b[38;5;220m▀\u001b[48;5;214m▀\u001b[38;5;214m▀▀▀▀\u001b[38;5;178m\u001b[48;5;178m▀\u001b[38;5;172m▀▀\u001b[48;5;172m▀▀\u001b[38;5;136m▀\u001b[38;5;130m\u001b[48;5;136m▀\u001b[48;5;130m▀\u001b[38;5;94m\u001b[48;5;94m▀▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;52m\u001b[48;5;52m▀▀\u001b[38;5;234m\u001b[48;5;234m▀▀\u001b[38;5;233m\u001b[48;5;233m▀▀▀\u001b[38;5;234m▀▀\u001b[38;5;233m▀\u001b[48;5;234m▀\u001b[38;5;234m▀\u001b[48;5;235m▀\u001b[38;5;52m\u001b[48;5;52m▀▀▀▀▀▀▀▀▀\u001b[38;5;130m\u001b[48;5;94m▀\u001b[38;5;136m\u001b[48;5;172m▀\u001b[38;5;172m▀▀▀\u001b[48;5;178m▀\u001b[38;5;178m▀▀▀▀▀▀▀\u001b[38;5;214m▀\u001b[38;5;178m\u001b[48;5;214m▀\u001b(B\u001b[m"] +[35.88084, "o", "\u001b[38;5;136m\u001b[48;5;214m▀\u001b[38;5;101m\u001b[48;5;178m▀\u001b[48;5;143m▀\u001b[38;5;107m▀\u001b[38;5;101m\u001b[48;5;144m▀▀▀\u001b[38;5;107m▀▀▀\u001b[48;5;143m▀\u001b[38;5;101m▀\u001b[48;5;106m▀\u001b[38;5;64m\u001b[48;5;100m▀\u001b[38;5;58m▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;52m\u001b[48;5;52m▀▀\u001b[38;5;235m▀\u001b[38;5;234m▀\u001b[38;5;235m▀▀\u001b[38;5;52m▀▀▀\u001b[48;5;58m▀\u001b[38;5;94m\u001b[48;5;94m▀\u001b[38;5;130m\u001b[48;5;130m▀\u001b[38;5;172m\u001b[48;5;172m▀▀\u001b[38;5;178m\u001b[48;5;178m▀\u001b[38;5;214m\u001b[48;5;220m▀\u001b[38;5;220m▀▀\u001b[38;5;178m▀\u001b[38;5;136m\u001b[48;5;214m▀\u001b[38;5;100m\u001b[48;5;178m▀\u001b[38;5;142m\u001b[48;5;220m▀\u001b[38;5;220m▀▀▀▀▀▀▀▀\u001b[38;5;214m\u001b[48;5;214m▀▀\u001b[48;5;178m▀\u001b[38;5;178m▀\u001b[38;5;172m\u001b[48;5;172m▀\u001b[48;5;178m▀▀\u001b[48;5;172m▀\u001b[38;5;136m\u001b[48;5;130m▀\u001b[38;5;58m▀\u001b[38;5;94m\u001b[48;5;94m▀▀\u001b[38;5;58m▀\u001b[38;5;52m\u001b[48;5;58m▀\u001b[48;5;52m▀▀\u001b[38;5;235m▀\u001b[38;5;234m▀\u001b[48;5;234m▀▀\u001b[38;5;233m▀\u001b[38;5;234m▀▀\u001b[48;5;52m▀\u001b[38;5;235m▀\u001b[38;5;52m▀▀▀▀▀▀▀▀\u001b[48;5;94m▀▀\u001b[38;5;58m\u001b[48;5;130m▀\u001b[38;5;130m▀\u001b[38;5;172m\u001b[48;5;172m▀\u001b[48;5;178m▀▀▀\u001b[38;5;178m▀▀▀▀▀▀▀▀▀▀\u001b[48;5;214m▀▀▀\u001b[38;5;179m▀\u001b[38;5;180m\u001b[48;5;178m▀\u001b[38;5;150m\u001b[48;5;179m▀\u001b[48;5;186m▀▀▀\u001b(B\u001b[m"] +[35.881224, "o", "\u001b[38;5;143m\u001b[48;5;185m▀\u001b[48;5;179m▀\u001b[38;5;142m\u001b[48;5;178m▀▀\u001b[38;5;136m▀\u001b[48;5;142m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;52m\u001b[48;5;52m▀▀▀▀▀▀▀▀\u001b[48;5;94m▀\u001b[38;5;94m▀\u001b[38;5;130m\u001b[48;5;130m▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[38;5;172m\u001b[48;5;172m▀\u001b[38;5;178m\u001b[48;5;214m▀\u001b[38;5;214m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\u001b[38;5;214m\u001b[48;5;214m▀\u001b[48;5;178m▀\u001b[38;5;178m\u001b[48;5;172m▀\u001b[38;5;172m▀▀▀\u001b[38;5;130m\u001b[48;5;136m▀\u001b[48;5;130m▀\u001b[38;5;94m▀\u001b[48;5;94m▀\u001b[38;5;58m▀\u001b[38;5;52m\u001b[48;5;52m▀▀▀▀▀▀\u001b[38;5;235m▀\u001b[38;5;52m▀▀▀▀▀▀▀▀▀▀▀▀\u001b[38;5;94m\u001b[48;5;94m▀\u001b[38;5;130m\u001b[48;5;136m▀▀\u001b[38;5;136m\u001b[48;5;172m▀\u001b[38;5;172m▀▀\u001b[38;5;178m▀\u001b[48;5;178m▀▀▀▀▀▀▀▀▀▀▀▀▀▀\u001b[38;5;214m▀\u001b[38;5;178m\u001b[48;5;143m▀\u001b[48;5;144m▀\u001b[38;5;144m▀\u001b[38;5;150m▀\u001b[38;5;185m\u001b[48;5;143m▀\u001b[38;5;179m\u001b[48;5;179m▀\u001b[38;5;178m\u001b[48;5;178m▀\u001b[48;5;172m▀\u001b[48;5;136m▀▀\u001b[38;5;136m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;58m\u001b[48;5;94m▀▀\u001b[38;5;52m▀▀\u001b(B\u001b[m\u001b[38;5;52m\u001b[48;5;94m▀▀\u001b[38;5;58m▀\u001b[38;5;94m▀\u001b[48;5;130m▀\u001b[38;5;130m\u001b[48;5;136m▀\u001b[38;5;136m▀\u001b[38;5;172m\u001b[48;5;172m▀▀\u001b[38;5;178m\u001b[48;5;178m▀\u001b[38;5;214m▀\u001b[38;5;220m▀▀▀▀▀▀\u001b[48;5;184m▀\u001b[48;5;220m▀▀▀▀\u001b[38;5;226m\u001b[48;5;184m▀▀\u001b[38;5;220m\u001b[48;5;178m▀▀\u001b[48;5;214m▀\u001b[38;5;214m▀▀▀\u001b[48;5;178m▀\u001b[38;5;178m▀\u001b[38;5;172m▀\u001b[48;5;172m▀▀▀▀\u001b[38;5;130m\u001b[48;5;136m▀\u001b[38;5;94m\u001b[48;5;130m▀\u001b[48;5;94m▀\u001b[38;5;88m▀\u001b[38;5;52m\u001b[48;5;58m▀▀\u001b[48;5;52m▀▀▀▀▀▀▀▀▀▀▀▀▀\u001b[48;5;94m▀▀\u001b[38;5;94m▀\u001b[48;5;130m▀\u001b[38;5;172m▀\u001b[48;5;172m▀▀▀\u001b[48;5;178m▀\u001b[38;5;178m▀▀▀▀\u001b[38;5;214m▀\u001b[38;5;178m\u001b[48;5;220m▀\u001b[48;5;178m▀\u001b[48;5;100m▀\u001b[48;5;64m▀▀\u001b[48;5;100m▀\u001b[38;5;142m\u001b[48;5;106m▀▀▀\u001b[38;5;143m\u001b[48;5;143m▀▀▀\u001b[38;5;144m\u001b[48;5;144m▀▀▀\u001b[38;5;143m\u001b[48;5;143m▀\u001b[38;5;142m\u001b[48;5;137m▀\u001b[38;5;136m\u001b[48;5;100m▀\u001b[48;5;94m▀\u001b[38;5;94m\u001b[48;5;58m▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;130m\u001b[48;5;136m▀▀▀▀▀▀▀▀\u001b[38;5;136m▀\u001b[48;5;172m▀\u001b[38;5;172m▀▀▀\u001b(B\u001b[m"] +[35.881477, "o", "\u001b[38;5;172m\u001b[48;5;178m▀\u001b[38;5;178m▀\u001b[38;5;172m▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[38;5;94m\u001b[48;5;58m▀\u001b[38;5;58m\u001b[48;5;236m▀▀\u001b[38;5;237m▀\u001b[38;5;58m\u001b[48;5;237m▀▀\u001b[38;5;64m\u001b[48;5;238m▀\u001b[38;5;100m\u001b[48;5;58m▀\u001b[48;5;64m▀▀\u001b[48;5;100m▀\u001b[38;5;136m\u001b[48;5;178m▀\u001b[38;5;214m\u001b[48;5;214m▀▀\u001b[48;5;178m▀▀\u001b[38;5;178m▀▀▀▀\u001b[38;5;172m▀▀\u001b[48;5;172m▀▀▀\u001b[38;5;136m▀\u001b[38;5;130m▀\u001b[38;5;94m\u001b[48;5;130m▀▀\u001b[48;5;94m▀\u001b[38;5;52m▀\u001b[48;5;52m▀▀▀▀▀▀▀▀▀\u001b[48;5;58m▀▀\u001b[38;5;94m\u001b[48;5;130m▀▀\u001b[38;5;130m\u001b[48;5;136m▀\u001b[38;5;172m\u001b[48;5;172m▀▀\u001b[38;5;130m▀\u001b[38;5;172m▀▀\u001b[48;5;178m▀\u001b[38;5;178m▀▀▀▀▀▀\u001b[38;5;214m▀\u001b[38;5;220m\u001b[48;5;214m▀\u001b[38;5;142m▀\u001b[38;5;64m\u001b[48;5;136m▀\u001b[48;5;64m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;106m\u001b[48;5;106m▀▀\u001b[38;5;142m\u001b[48;5;142m▀▀\u001b[38;5;143m\u001b[48;5;143m▀▀\u001b[38;5;144m\u001b[48;5;150m▀▀\u001b[48;5;144m▀\u001b[38;5;143m\u001b[48;5;143m▀\u001b[38;5;101m\u001b[48;5;107m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;58m\u001b[48;5;64m▀\u001b[48;5;58m▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;136m\u001b[48;5;172m▀\u001b[48;5;136m▀▀▀\u001b[48;5;172m▀▀▀\u001b[48;5;136m▀▀\u001b[38;5;172m\u001b[48;5;172m▀▀▀\u001b[48;5;178m▀\u001b[38;5;178m▀▀▀\u001b[38;5;136m▀\u001b[38;5;100m\u001b[48;5;136m▀\u001b[38;5;58m\u001b[48;5;64m▀\u001b[48;5;58m▀\u001b[38;5;236m▀\u001b[48;5;236m▀\u001b[38;5;237m\u001b[48;5;237m▀\u001b(B\u001b[m"] +[35.881691, "o", "\u001b[38;5;238m\u001b[48;5;238m▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[38;5;64m\u001b[48;5;142m▀\u001b[38;5;178m\u001b[48;5;220m▀\u001b[38;5;220m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀▀▀▀▀▀▀▀\u001b[38;5;172m\u001b[48;5;172m▀▀▀▀▀\u001b[38;5;130m▀\u001b[48;5;136m▀▀\u001b[38;5;52m\u001b[48;5;130m▀\u001b[38;5;94m▀▀▀\u001b[38;5;52m\u001b[48;5;94m▀\u001b[38;5;88m▀\u001b[38;5;52m▀▀\u001b[38;5;94m▀\u001b[48;5;130m▀\u001b[38;5;130m\u001b[48;5;136m▀\u001b[38;5;172m\u001b[48;5;172m▀\u001b[38;5;136m▀\u001b[38;5;172m▀▀▀\u001b[48;5;178m▀▀\u001b[48;5;172m▀\u001b[38;5;178m▀\u001b[48;5;178m▀▀▀\u001b[38;5;214m▀▀\u001b[38;5;178m\u001b[48;5;214m▀▀\u001b[48;5;178m▀\u001b[38;5;214m▀\u001b[38;5;178m\u001b[48;5;214m▀\u001b[38;5;136m\u001b[48;5;178m▀\u001b[38;5;100m\u001b[48;5;142m▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[38;5;142m\u001b[48;5;142m▀▀▀▀\u001b[38;5;143m▀\u001b[48;5;143m▀\u001b[38;5;149m▀\u001b[38;5;143m▀▀\u001b[38;5;107m\u001b[48;5;106m▀\u001b[38;5;100m\u001b[48;5;100m▀▀\u001b[38;5;58m\u001b[48;5;64m▀\u001b[48;5;58m▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;136m\u001b[48;5;136m▀▀▀▀▀▀▀▀▀▀\u001b[38;5;172m\u001b[48;5;172m▀▀\u001b[38;5;178m\u001b[48;5;136m▀\u001b[38;5;142m▀\u001b[48;5;100m▀\u001b[38;5;178m\u001b[48;5;136m▀\u001b[38;5;142m▀\u001b[38;5;136m\u001b[48;5;106m▀\u001b[38;5;100m▀\u001b[38;5;64m\u001b[48;5;100m▀▀\u001b[38;5;58m\u001b[48;5;64m▀▀\u001b[48;5;58m▀▀\u001b[38;5;100m\u001b[48;5;178m▀\u001b[38;5;220m\u001b[48;5;220m▀\u001b[48;5;214m▀\u001b[38;5;214m\u001b[48;5;220m▀▀\u001b[38;5;178m\u001b[48;5;178m▀▀\u001b(B\u001b[m"] +[35.882078, "o", "\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀▀▀▀▀\u001b[38;5;172m▀▀▀\u001b[48;5;172m▀▀▀▀▀\u001b[38;5;130m▀\u001b[38;5;136m▀▀\u001b[38;5;172m▀\u001b[38;5;130m▀\u001b[48;5;130m▀\u001b[48;5;172m▀\u001b[48;5;136m▀\u001b[48;5;130m▀\u001b[48;5;136m▀\u001b[38;5;172m\u001b[48;5;172m▀\u001b[48;5;178m▀\u001b[48;5;172m▀▀▀\u001b[48;5;178m▀\u001b[38;5;178m▀▀\u001b[38;5;172m▀\u001b[48;5;172m▀▀\u001b[38;5;178m▀\u001b[48;5;178m▀▀▀▀\u001b[38;5;214m▀\u001b[48;5;214m▀\u001b[38;5;178m▀▀\u001b[38;5;214m▀▀\u001b[38;5;142m\u001b[48;5;184m▀\u001b[48;5;142m▀▀▀▀\u001b[48;5;106m▀\u001b[38;5;106m\u001b[48;5;100m▀▀▀▀▀\u001b[38;5;100m▀\u001b[48;5;64m▀\u001b[38;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[48;5;237m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;142m\u001b[48;5;143m▀\u001b[38;5;136m▀\u001b[48;5;142m▀\u001b[48;5;136m▀▀▀▀▀▀▀▀\u001b[38;5;178m▀\u001b[38;5;136m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;58m▀▀\u001b[38;5;100m\u001b[48;5;64m▀\u001b[38;5;106m\u001b[48;5;100m▀\u001b[48;5;106m▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;58m▀\u001b[38;5;136m\u001b[48;5;178m▀\u001b[38;5;220m\u001b[48;5;220m▀▀▀▀\u001b[48;5;178m▀\u001b[38;5;178m\u001b[48;5;142m▀▀\u001b[48;5;178m▀▀▀▀▀▀▀▀▀\u001b(B\u001b[m\u001b[38;5;178m\u001b[48;5;178m▀▀▀\u001b[38;5;172m▀▀\u001b[38;5;178m▀\u001b[38;5;172m\u001b[48;5;172m▀▀▀▀▀▀\u001b[38;5;130m▀\u001b[38;5;172m▀▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[38;5;172m\u001b[48;5;172m▀▀\u001b[38;5;178m\u001b[48;5;178m▀▀\u001b[38;5;172m▀\u001b[48;5;172m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀▀\u001b[38;5;172m\u001b[48;5;172m▀▀\u001b[48;5;178m▀\u001b[38;5;178m▀\u001b[38;5;214m▀\u001b[38;5;220m\u001b[48;5;214m▀\u001b[38;5;214m\u001b[48;5;220m▀\u001b[38;5;178m▀▀\u001b[38;5;214m\u001b[48;5;178m▀▀\u001b[38;5;220m\u001b[48;5;214m▀\u001b[48;5;220m▀\u001b[38;5;178m▀\u001b[38;5;142m\u001b[48;5;178m▀\u001b[48;5;142m▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[48;5;58m▀\u001b[38;5;58m▀\u001b[38;5;64m▀▀\u001b[38;5;100m\u001b[48;5;101m▀\u001b[38;5;101m▀\u001b[38;5;65m▀\u001b[38;5;240m\u001b[48;5;65m▀\u001b[38;5;238m\u001b[48;5;240m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;143m\u001b[48;5;143m▀▀\u001b[38;5;142m\u001b[48;5;136m▀\u001b[38;5;136m▀\u001b[48;5;100m▀▀\u001b[48;5;136m▀\u001b[48;5;100m▀\u001b[38;5;100m\u001b[48;5;58m▀\u001b[38;5;94m▀\u001b[38;5;100m▀▀▀\u001b[38;5;58m▀\u001b[48;5;22m▀\u001b[48;5;58m▀▀\u001b[38;5;100m\u001b[48;5;64m▀\u001b[38;5;106m\u001b[48;5;106m▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;100m▀\u001b[38;5;142m▀\u001b[48;5;64m▀\u001b[38;5;106m▀\u001b[38;5;100m▀\u001b[48;5;100m▀▀\u001b[38;5;142m\u001b[48;5;178m▀\u001b[38;5;178m▀▀▀▀▀▀▀▀▀▀▀▀▀▀\u001b[38;5;172m\u001b[48;5;172m▀▀\u001b[48;5;178m▀\u001b[38;5;178m▀\u001b(B\u001b[m"] +[35.882322, "o", "\u001b[38;5;172m\u001b[48;5;178m▀\u001b[38;5;178m▀▀\u001b[38;5;172m\u001b[48;5;172m▀▀▀\u001b[38;5;136m▀\u001b[38;5;172m▀▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀▀▀▀▀▀▀\u001b[38;5;172m▀\u001b[48;5;172m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀\u001b[38;5;220m▀▀\u001b[48;5;143m▀\u001b[48;5;185m▀▀\u001b[38;5;214m▀▀\u001b[38;5;178m\u001b[48;5;179m▀\u001b[38;5;142m\u001b[48;5;143m▀\u001b[38;5;107m\u001b[48;5;144m▀\u001b[38;5;65m\u001b[48;5;108m▀\u001b[38;5;239m\u001b[48;5;65m▀\u001b[38;5;237m\u001b[48;5;238m▀\u001b[48;5;237m▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[38;5;65m\u001b[48;5;64m▀\u001b[38;5;101m\u001b[48;5;101m▀▀\u001b[38;5;65m▀\u001b[48;5;65m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;143m\u001b[48;5;143m▀\u001b[38;5;100m\u001b[48;5;101m▀\u001b[48;5;58m▀\u001b[38;5;94m▀\u001b[38;5;58m▀▀\u001b[38;5;100m\u001b[48;5;64m▀\u001b[38;5;64m\u001b[48;5;58m▀\u001b[38;5;58m▀▀▀\u001b[38;5;235m▀\u001b[48;5;237m▀\u001b[48;5;65m▀\u001b[38;5;58m\u001b[48;5;107m▀\u001b[38;5;65m\u001b[48;5;144m▀\u001b[38;5;101m▀\u001b[38;5;100m▀\u001b[38;5;106m\u001b[48;5;143m▀▀\u001b[48;5;142m▀\u001b[38;5;100m\u001b[48;5;106m▀\u001b[38;5;64m\u001b[48;5;100m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀▀▀\u001b[38;5;142m\u001b[48;5;178m▀\u001b[38;5;178m▀▀▀▀▀\u001b[48;5;136m▀\u001b[48;5;178m▀▀▀▀▀▀▀▀\u001b[48;5;172m▀\u001b[38;5;172m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀▀▀\u001b[38;5;172m\u001b[48;5;172m▀▀▀▀▀\u001b[48;5;178m▀\u001b(B\u001b[m"] +[35.882541, "o", "\u001b[38;5;172m\u001b[48;5;172m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\u001b[38;5;185m▀\u001b[38;5;187m\u001b[48;5;187m▀▀▀▀▀▀▀▀\u001b[38;5;144m▀\u001b[38;5;101m\u001b[48;5;150m▀\u001b[38;5;65m\u001b[48;5;144m▀\u001b[38;5;58m\u001b[48;5;101m▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀\u001b[38;5;101m▀\u001b[38;5;65m\u001b[48;5;58m▀\u001b[38;5;64m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;143m\u001b[48;5;143m▀\u001b[38;5;107m▀\u001b[38;5;65m\u001b[48;5;101m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀▀▀▀▀\u001b[48;5;101m▀\u001b[38;5;240m▀\u001b[38;5;101m\u001b[48;5;144m▀\u001b[38;5;144m\u001b[48;5;187m▀\u001b[38;5;187m▀▀▀\u001b[38;5;186m▀\u001b[38;5;150m▀\u001b[38;5;149m\u001b[48;5;186m▀\u001b[38;5;143m\u001b[48;5;149m▀\u001b[38;5;142m\u001b[48;5;143m▀\u001b[38;5;100m\u001b[48;5;142m▀▀\u001b[48;5;100m▀\u001b[38;5;64m▀\u001b[48;5;58m▀\u001b[38;5;58m▀\u001b[38;5;64m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀\u001b[48;5;142m▀\u001b[38;5;142m\u001b[48;5;100m▀\u001b[38;5;100m\u001b[48;5;101m▀\u001b[48;5;136m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀▀▀▀▀\u001b[38;5;172m\u001b[48;5;172m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀▀▀▀\u001b[38;5;172m\u001b[48;5;172m▀▀▀▀▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀\u001b[48;5;172m▀\u001b[48;5;178m▀▀▀\u001b(B\u001b[m"] +[35.882752, "o", "\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[38;5;142m\u001b[48;5;100m▀\u001b[38;5;178m\u001b[48;5;136m▀\u001b[48;5;142m▀\u001b[48;5;178m▀▀▀\u001b[48;5;172m▀\u001b[38;5;179m\u001b[48;5;136m▀\u001b[38;5;144m\u001b[48;5;64m▀\u001b[48;5;100m▀\u001b[38;5;150m\u001b[48;5;101m▀\u001b[38;5;187m\u001b[48;5;107m▀\u001b[48;5;143m▀▀▀\u001b[48;5;144m▀▀\u001b[38;5;144m\u001b[48;5;143m▀\u001b[48;5;107m▀\u001b[38;5;107m\u001b[48;5;101m▀\u001b[38;5;101m▀\u001b[38;5;64m\u001b[48;5;58m▀\u001b[38;5;58m▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;143m\u001b[48;5;143m▀\u001b[38;5;137m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;58m\u001b[48;5;240m▀\u001b[48;5;58m▀▀▀▀\u001b[48;5;64m▀\u001b[38;5;101m\u001b[48;5;107m▀\u001b[38;5;143m\u001b[48;5;143m▀\u001b[48;5;107m▀\u001b[38;5;144m\u001b[48;5;101m▀▀\u001b[38;5;151m\u001b[48;5;108m▀\u001b[38;5;187m\u001b[48;5;144m▀▀▀▀\u001b[38;5;150m\u001b[48;5;107m▀\u001b[38;5;143m\u001b[48;5;101m▀\u001b[48;5;100m▀\u001b[38;5;142m\u001b[48;5;106m▀▀\u001b[38;5;106m\u001b[48;5;100m▀\u001b[38;5;100m\u001b[48;5;58m▀\u001b[38;5;58m▀▀\u001b[48;5;64m▀\u001b[38;5;136m\u001b[48;5;100m▀\u001b[38;5;178m▀\u001b[38;5;100m▀▀▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;142m\u001b[48;5;178m▀\u001b[38;5;178m\u001b[48;5;214m▀\u001b[48;5;178m▀▀▀▀\u001b[48;5;142m▀▀\u001b[48;5;178m▀▀▀▀▀▀▀▀\u001b[38;5;172m\u001b[48;5;172m▀▀\u001b[38;5;178m\u001b[48;5;178m▀\u001b[38;5;172m\u001b[48;5;172m▀▀▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀\u001b[38;5;172m▀\u001b[38;5;178m\u001b[48;5;172m▀\u001b[48;5;178m▀▀▀▀▀▀\u001b[38;5;142m▀\u001b[38;5;101m\u001b[48;5;143m▀\u001b(B\u001b[m"] +[35.883018, "o", "\u001b[38;5;100m\u001b[48;5;143m▀\u001b[38;5;106m\u001b[48;5;142m▀\u001b[38;5;142m▀▀\u001b[48;5;106m▀\u001b[38;5;136m\u001b[48;5;100m▀\u001b[38;5;100m\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;64m\u001b[48;5;64m▀▀\u001b[38;5;100m\u001b[48;5;106m▀\u001b[38;5;106m▀▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;101m\u001b[48;5;64m▀\u001b[38;5;65m\u001b[48;5;58m▀▀\u001b[38;5;58m▀▀▀\u001b[48;5;235m▀\u001b[38;5;235m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;106m\u001b[48;5;106m▀\u001b[38;5;142m▀\u001b[38;5;143m\u001b[48;5;143m▀▀\u001b[38;5;101m\u001b[48;5;137m▀\u001b[38;5;240m\u001b[48;5;101m▀\u001b[38;5;58m\u001b[48;5;239m▀\u001b[48;5;58m▀\u001b[48;5;239m▀\u001b[38;5;64m\u001b[48;5;240m▀\u001b[38;5;101m\u001b[48;5;64m▀\u001b[48;5;239m▀\u001b[38;5;65m\u001b[48;5;237m▀\u001b[38;5;240m\u001b[48;5;236m▀\u001b[38;5;239m▀▀\u001b[38;5;65m\u001b[48;5;58m▀\u001b[38;5;101m▀\u001b[48;5;64m▀▀\u001b[38;5;64m▀\u001b[48;5;58m▀▀▀▀\u001b[38;5;58m▀▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;100m▀\u001b[48;5;100m▀▀\u001b[48;5;64m▀\u001b[48;5;100m▀\u001b[38;5;101m▀\u001b[38;5;184m\u001b[48;5;184m▀\u001b[38;5;220m\u001b[48;5;220m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀\u001b[38;5;142m\u001b[48;5;100m▀\u001b[38;5;100m\u001b[48;5;64m▀\u001b[38;5;142m\u001b[48;5;100m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀▀▀▀▀▀▀\u001b[48;5;136m▀\u001b[38;5;136m\u001b[48;5;100m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀▀▀▀\u001b[38;5;136m\u001b[48;5;142m▀\u001b[48;5;143m▀\u001b[38;5;178m▀\u001b[48;5;178m▀▀▀▀▀\u001b[38;5;142m▀\u001b[38;5;143m\u001b[48;5;142m▀\u001b[38;5;142m\u001b[48;5;106m▀▀\u001b[38;5;106m\u001b[48;5;100m▀\u001b[48;5;64m▀\u001b[38;5;100m▀\u001b[38;5;64m\u001b[48;5;58m▀\u001b[38;5;58m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b(B\u001b[m"] +[35.883197, "o", "\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;106m\u001b[48;5;106m▀▀▀\u001b[48;5;101m▀\u001b[38;5;100m▀\u001b[38;5;101m▀\u001b[38;5;65m▀▀\u001b[38;5;58m\u001b[48;5;65m▀\u001b[48;5;58m▀▀\u001b[38;5;235m\u001b[48;5;235m▀\u001b[38;5;234m\u001b[48;5;234m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;100m\u001b[48;5;64m▀\u001b[38;5;106m▀▀\u001b[38;5;143m\u001b[48;5;101m▀\u001b[38;5;137m\u001b[48;5;143m▀\u001b[38;5;101m▀\u001b[38;5;240m\u001b[48;5;101m▀\u001b[38;5;239m\u001b[48;5;240m▀\u001b[38;5;240m\u001b[48;5;101m▀\u001b[38;5;65m▀\u001b[38;5;240m\u001b[48;5;65m▀\u001b[38;5;237m\u001b[48;5;58m▀\u001b[38;5;236m\u001b[48;5;236m▀\u001b[38;5;235m▀\u001b[48;5;235m▀▀\u001b[38;5;58m\u001b[48;5;236m▀\u001b[48;5;58m▀▀\u001b[38;5;64m▀\u001b[38;5;58m▀▀▀▀▀\u001b[38;5;235m▀\u001b[38;5;58m▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀▀▀▀▀▀\u001b[38;5;184m\u001b[48;5;178m▀\u001b[38;5;220m\u001b[48;5;220m▀\u001b[38;5;214m▀\u001b[38;5;178m\u001b[48;5;178m▀\u001b[38;5;100m\u001b[48;5;144m▀\u001b[38;5;101m\u001b[48;5;187m▀\u001b[38;5;100m\u001b[48;5;143m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;178m\u001b[48;5;100m▀\u001b[48;5;178m▀▀▀▀▀▀▀▀▀\u001b[38;5;136m\u001b[48;5;136m▀\u001b[38;5;64m\u001b[48;5;58m▀\u001b[38;5;142m\u001b[48;5;100m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀▀▀▀\u001b[38;5;144m\u001b[48;5;186m▀▀\u001b[38;5;143m▀\u001b[38;5;178m\u001b[48;5;144m▀\u001b[48;5;143m▀\u001b[48;5;178m▀▀\u001b[48;5;172m▀\u001b[38;5;100m\u001b[48;5;136m▀\u001b[48;5;64m▀\u001b[38;5;64m\u001b[48;5;58m▀▀\u001b[38;5;58m▀▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀\u001b[38;5;101m\u001b[48;5;101m▀▀▀▀\u001b(B\u001b[m"] +[35.883388, "o", "\u001b[38;5;101m\u001b[48;5;101m▀▀▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[38;5;235m\u001b[48;5;235m▀\u001b[38;5;234m\u001b[48;5;234m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;58m\u001b[48;5;237m▀\u001b[48;5;58m▀\u001b[48;5;64m▀\u001b[38;5;101m\u001b[48;5;100m▀\u001b[38;5;143m\u001b[48;5;143m▀\u001b[38;5;144m▀\u001b[38;5;101m\u001b[48;5;137m▀\u001b[48;5;101m▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;236m▀\u001b[48;5;236m▀▀▀▀▀\u001b[38;5;237m▀▀\u001b[38;5;239m\u001b[48;5;238m▀\u001b[48;5;58m▀\u001b[38;5;58m▀▀▀▀▀\u001b[48;5;64m▀▀\u001b[48;5;101m▀▀\u001b[48;5;107m▀\u001b[48;5;144m▀\u001b[38;5;64m\u001b[48;5;187m▀\u001b[38;5;65m▀\u001b[38;5;101m▀\u001b[38;5;142m\u001b[48;5;223m▀\u001b[38;5;220m\u001b[48;5;221m▀\u001b[48;5;222m▀\u001b[38;5;223m\u001b[48;5;231m▀\u001b[38;5;255m\u001b[48;5;230m▀\u001b[38;5;230m\u001b[48;5;144m▀\u001b[38;5;143m\u001b[48;5;64m▀\u001b[38;5;64m\u001b[48;5;58m▀\u001b[38;5;58m▀\u001b[38;5;142m▀\u001b[38;5;178m\u001b[48;5;178m▀▀▀▀▀▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;142m▀\u001b[38;5;178m\u001b[48;5;136m▀\u001b[48;5;178m▀▀▀▀▀\u001b[38;5;186m\u001b[48;5;186m▀\u001b[38;5;187m\u001b[48;5;187m▀\u001b[38;5;186m\u001b[48;5;186m▀\u001b[38;5;144m\u001b[48;5;143m▀\u001b[38;5;143m▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[48;5;64m▀\u001b[38;5;58m▀▀\u001b[48;5;58m▀▀▀\u001b[48;5;64m▀\u001b[38;5;64m▀\u001b[48;5;100m▀▀\u001b[38;5;100m▀▀\u001b[48;5;101m▀\u001b[38;5;101m▀\u001b[48;5;143m▀\u001b[38;5;143m▀▀\u001b[48;5;101m▀\u001b[38;5;101m▀▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[38;5;236m▀\u001b[38;5;235m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;237m\u001b[48;5;237m▀\u001b(B\u001b[m"] +[35.883608, "o", "\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;106m\u001b[48;5;142m▀\u001b[38;5;142m▀\u001b[38;5;143m\u001b[48;5;106m▀\u001b[38;5;101m\u001b[48;5;64m▀\u001b[38;5;64m\u001b[48;5;58m▀\u001b[38;5;101m\u001b[48;5;64m▀\u001b[38;5;100m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀\u001b[38;5;236m\u001b[48;5;236m▀▀\u001b[48;5;237m▀\u001b[38;5;237m▀\u001b[38;5;236m▀▀\u001b[48;5;65m▀\u001b[38;5;58m\u001b[48;5;101m▀▀\u001b[38;5;101m\u001b[48;5;150m▀\u001b[48;5;253m▀\u001b[38;5;65m▀\u001b[48;5;254m▀\u001b[38;5;101m\u001b[48;5;230m▀\u001b[38;5;150m▀\u001b[38;5;187m\u001b[48;5;231m▀\u001b[38;5;254m▀\u001b[38;5;255m▀▀\u001b[38;5;231m▀▀\u001b[48;5;230m▀▀▀\u001b[38;5;230m\u001b[48;5;255m▀\u001b[48;5;254m▀\u001b[38;5;253m\u001b[48;5;187m▀\u001b[38;5;144m\u001b[48;5;107m▀\u001b[38;5;64m\u001b[48;5;58m▀\u001b[38;5;58m▀▀▀\u001b[48;5;65m▀\u001b[38;5;136m\u001b[48;5;137m▀\u001b[38;5;178m\u001b[48;5;178m▀▀\u001b[48;5;136m▀\u001b[48;5;142m▀\u001b[48;5;214m▀\u001b[48;5;220m▀\u001b[48;5;178m▀\u001b[38;5;58m\u001b[48;5;64m▀\u001b[48;5;58m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[48;5;65m▀\u001b[38;5;94m\u001b[48;5;58m▀\u001b[38;5;178m\u001b[48;5;136m▀\u001b[48;5;178m▀▀▀▀\u001b[38;5;186m\u001b[48;5;186m▀\u001b[38;5;187m▀\u001b[38;5;186m\u001b[48;5;144m▀\u001b[38;5;143m\u001b[48;5;143m▀\u001b[48;5;107m▀\u001b[48;5;143m▀\u001b[48;5;142m▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[38;5;100m▀▀\u001b[38;5;64m\u001b[48;5;100m▀\u001b[48;5;64m▀▀▀▀▀\u001b[38;5;100m▀\u001b[48;5;100m▀▀▀\u001b[38;5;107m\u001b[48;5;142m▀\u001b[38;5;142m▀▀\u001b[48;5;100m▀▀\u001b[38;5;100m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;65m\u001b[48;5;240m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;236m\u001b[48;5;58m▀\u001b[38;5;58m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;142m\u001b[48;5;142m▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;58m\u001b[48;5;64m▀\u001b(B\u001b[m"] +[35.884053, "o", "\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[48;5;235m▀\u001b[38;5;235m▀\u001b[48;5;234m▀\u001b[38;5;236m\u001b[48;5;235m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀\u001b[38;5;101m▀\u001b[38;5;144m\u001b[48;5;64m▀\u001b[38;5;186m\u001b[48;5;100m▀▀\u001b[38;5;187m▀▀\u001b[38;5;186m▀\u001b[38;5;185m\u001b[48;5;106m▀\u001b[48;5;142m▀▀\u001b[38;5;187m▀\u001b[48;5;186m▀\u001b[38;5;255m\u001b[48;5;254m▀\u001b[38;5;231m\u001b[48;5;230m▀\u001b[38;5;255m\u001b[48;5;254m▀\u001b[38;5;230m\u001b[48;5;230m▀▀\u001b[48;5;253m▀\u001b[38;5;187m\u001b[48;5;187m▀\u001b[48;5;144m▀\u001b[38;5;108m\u001b[48;5;108m▀\u001b[38;5;107m\u001b[48;5;101m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[48;5;240m▀\u001b[38;5;239m\u001b[48;5;65m▀\u001b[38;5;240m▀\u001b[38;5;107m\u001b[48;5;107m▀\u001b[38;5;144m\u001b[48;5;187m▀\u001b[38;5;178m\u001b[48;5;186m▀\u001b[48;5;143m▀\u001b[38;5;101m▀\u001b[48;5;144m▀\u001b[38;5;178m\u001b[48;5;143m▀\u001b[38;5;220m\u001b[48;5;179m▀\u001b[38;5;143m\u001b[48;5;144m▀\u001b[38;5;65m\u001b[48;5;101m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;144m\u001b[48;5;107m▀\u001b[38;5;58m\u001b[48;5;65m▀\u001b[48;5;238m▀\u001b[38;5;136m\u001b[48;5;58m▀\u001b[38;5;178m\u001b[48;5;136m▀\u001b[48;5;172m▀\u001b[48;5;136m▀\u001b[38;5;180m\u001b[48;5;186m▀\u001b[38;5;186m▀\u001b[38;5;144m\u001b[48;5;144m▀\u001b[38;5;101m\u001b[48;5;101m▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[38;5;142m\u001b[48;5;142m▀▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀\u001b[38;5;64m▀\u001b[48;5;64m▀\u001b[38;5;100m\u001b[48;5;100m▀▀\u001b[48;5;106m▀\u001b[38;5;142m\u001b[48;5;142m▀▀\u001b[38;5;100m\u001b[48;5;106m▀▀\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;101m▀\u001b[38;5;58m▀\u001b[48;5;65m▀\u001b[48;5;58m▀▀▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;58m\u001b[48;5;100m▀\u001b[38;5;100m\u001b[48;5;106m▀\u001b[48;5;142m▀\u001b[38;5;142m▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[38;5;234m\u001b[48;5;235m▀\u001b[48;5;234m▀\u001b[48;5;235m▀\u001b[38;5;236m\u001b[48;5;58m▀\u001b(B\u001b[m\u001b[38;5;58m\u001b[48;5;58m▀\u001b[48;5;94m▀\u001b[38;5;64m\u001b[48;5;100m▀\u001b[38;5;58m\u001b[48;5;64m▀\u001b[48;5;58m▀▀\u001b[38;5;64m▀\u001b[48;5;64m▀▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀\u001b[48;5;235m▀\u001b[38;5;100m\u001b[48;5;239m▀\u001b[38;5;143m\u001b[48;5;101m▀\u001b[38;5;187m\u001b[48;5;144m▀\u001b[38;5;230m\u001b[48;5;187m▀\u001b[38;5;187m▀\u001b[38;5;253m\u001b[48;5;230m▀▀\u001b[48;5;187m▀\u001b[38;5;187m\u001b[48;5;186m▀\u001b[38;5;144m\u001b[48;5;65m▀\u001b[38;5;101m\u001b[48;5;58m▀\u001b[38;5;58m▀▀\u001b[38;5;65m\u001b[48;5;65m▀\u001b[38;5;101m\u001b[48;5;101m▀▀\u001b[48;5;100m▀\u001b[38;5;144m\u001b[48;5;107m▀\u001b[38;5;253m\u001b[48;5;187m▀\u001b[38;5;187m\u001b[48;5;230m▀\u001b[48;5;253m▀\u001b[48;5;254m▀\u001b[48;5;230m▀▀\u001b[48;5;254m▀\u001b[38;5;101m\u001b[48;5;143m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;144m\u001b[48;5;144m▀\u001b[48;5;187m▀\u001b[38;5;101m\u001b[48;5;151m▀\u001b[38;5;65m\u001b[48;5;144m▀▀\u001b[38;5;137m▀\u001b[38;5;143m▀\u001b[38;5;186m\u001b[48;5;150m▀\u001b[48;5;186m▀\u001b[38;5;144m\u001b[48;5;144m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;65m\u001b[48;5;65m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;106m\u001b[48;5;106m▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;100m\u001b[48;5;100m▀▀\u001b[38;5;142m▀\u001b[48;5;106m▀\u001b[48;5;143m▀\u001b[38;5;143m▀▀▀\u001b[38;5;107m▀\u001b[38;5;101m\u001b[48;5;107m▀\u001b[48;5;101m▀\u001b[38;5;239m\u001b[48;5;239m▀\u001b[38;5;237m\u001b[48;5;237m▀\u001b[38;5;236m\u001b[48;5;236m▀\u001b[38;5;58m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;106m\u001b[48;5;142m▀\u001b[38;5;142m▀▀▀▀\u001b[48;5;106m▀\u001b[38;5;100m\u001b[48;5;64m▀\u001b[38;5;64m▀\u001b[38;5;100m▀\u001b[38;5;64m\u001b[48;5;58m▀\u001b[38;5;58m▀\u001b[38;5;237m\u001b[48;5;239m▀\u001b[38;5;238m\u001b[48;5;65m▀\u001b[38;5;58m\u001b[48;5;101m▀▀\u001b[48;5;100m▀\u001b[38;5;94m▀\u001b[38;5;100m\u001b[48;5;136m▀▀\u001b[38;5;94m\u001b[48;5;100m▀\u001b[38;5;58m\u001b[48;5;94m▀"] +[35.884277, "o", "\u001b(B\u001b[m\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[38;5;64m▀\u001b[38;5;58m▀▀▀▀\u001b[38;5;235m▀\u001b[38;5;65m\u001b[48;5;101m▀\u001b[38;5;144m\u001b[48;5;150m▀\u001b[48;5;151m▀\u001b[48;5;187m▀\u001b[38;5;143m\u001b[48;5;150m▀\u001b[38;5;144m\u001b[48;5;101m▀\u001b[38;5;149m\u001b[48;5;100m▀\u001b[38;5;143m\u001b[48;5;101m▀\u001b[38;5;64m\u001b[48;5;58m▀\u001b[38;5;58m▀▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;100m▀\u001b[48;5;100m▀▀▀\u001b[38;5;143m▀\u001b[38;5;150m\u001b[48;5;143m▀\u001b[38;5;187m\u001b[48;5;186m▀\u001b[38;5;230m\u001b[48;5;230m▀\u001b[48;5;224m▀\u001b[48;5;186m▀\u001b[38;5;253m▀\u001b[38;5;143m\u001b[48;5;143m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;64m▀\u001b[38;5;151m\u001b[48;5;150m▀\u001b[38;5;253m\u001b[48;5;253m▀\u001b[38;5;187m\u001b[48;5;187m▀▀\u001b[38;5;151m▀\u001b[38;5;144m\u001b[48;5;151m▀▀\u001b[38;5;150m\u001b[48;5;187m▀\u001b[38;5;186m\u001b[48;5;186m▀\u001b[38;5;143m\u001b[48;5;143m▀\u001b[38;5;101m\u001b[48;5;101m▀▀\u001b[38;5;100m\u001b[48;5;100m▀▀\u001b[38;5;106m▀\u001b[38;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[48;5;64m▀▀\u001b[48;5;58m▀\u001b[38;5;101m\u001b[48;5;65m▀\u001b[38;5;107m▀\u001b[38;5;143m\u001b[48;5;101m▀▀\u001b[38;5;107m▀\u001b[38;5;101m\u001b[48;5;65m▀\u001b[38;5;65m\u001b[48;5;239m▀\u001b[38;5;239m\u001b[48;5;237m▀\u001b[38;5;237m\u001b[48;5;238m▀\u001b[48;5;239m▀\u001b[38;5;238m\u001b[48;5;240m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;106m\u001b[48;5;100m▀\u001b[38;5;142m\u001b[48;5;106m▀▀\u001b[38;5;106m\u001b[48;5;100m▀▀\u001b[38;5;100m▀\u001b[38;5;58m\u001b[48;5;64m▀\u001b[48;5;58m▀\u001b[48;5;236m▀▀\u001b[38;5;237m▀\u001b[38;5;239m\u001b[48;5;237m▀\u001b[38;5;101m\u001b[48;5;65m▀\u001b[38;5;107m\u001b[48;5;101m▀▀\u001b[38;5;101m▀\u001b[38;5;100m▀\u001b[38;5;136m\u001b[48;5;136m▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀▀▀▀\u001b(B\u001b[m"] +[35.884511, "o", "\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;187m\u001b[48;5;187m▀\u001b[48;5;254m▀\u001b[38;5;188m\u001b[48;5;230m▀\u001b[38;5;253m▀\u001b[38;5;186m\u001b[48;5;253m▀\u001b[38;5;101m\u001b[48;5;143m▀\u001b[48;5;101m▀\u001b[38;5;65m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀\u001b[38;5;64m▀\u001b[48;5;64m▀\u001b[38;5;100m▀▀▀\u001b[48;5;107m▀\u001b[38;5;107m\u001b[48;5;180m▀\u001b[38;5;143m\u001b[48;5;143m▀\u001b[38;5;186m\u001b[48;5;107m▀\u001b[38;5;143m\u001b[48;5;100m▀▀\u001b[48;5;101m▀\u001b[48;5;107m▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[38;5;144m\u001b[48;5;101m▀\u001b[38;5;187m\u001b[48;5;144m▀\u001b[48;5;107m▀\u001b[48;5;143m▀\u001b[48;5;144m▀▀▀▀\u001b[38;5;144m\u001b[48;5;101m▀\u001b[38;5;101m▀\u001b[48;5;100m▀\u001b[48;5;106m▀\u001b[38;5;106m▀\u001b[38;5;100m▀\u001b[48;5;64m▀\u001b[38;5;64m\u001b[48;5;58m▀\u001b[38;5;58m▀▀\u001b[48;5;64m▀▀\u001b[38;5;64m▀\u001b[48;5;100m▀▀▀\u001b[48;5;64m▀\u001b[38;5;58m▀\u001b[48;5;58m▀\u001b[38;5;237m▀\u001b[38;5;238m\u001b[48;5;236m▀▀▀▀\u001b[38;5;237m\u001b[48;5;235m▀▀\u001b[38;5;236m▀\u001b[48;5;237m▀\u001b[38;5;239m\u001b[48;5;240m▀\u001b[38;5;65m\u001b[48;5;101m▀\u001b[38;5;101m\u001b[48;5;144m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;58m\u001b[48;5;235m▀\u001b[38;5;64m\u001b[48;5;58m▀▀\u001b[48;5;65m▀\u001b[38;5;101m\u001b[48;5;107m▀\u001b[38;5;107m\u001b[48;5;144m▀\u001b[38;5;101m\u001b[48;5;107m▀\u001b[38;5;239m\u001b[48;5;240m▀\u001b[38;5;236m\u001b[48;5;236m▀▀▀▀\u001b[38;5;238m\u001b[48;5;237m▀\u001b[38;5;65m\u001b[48;5;239m▀\u001b[38;5;101m\u001b[48;5;65m▀\u001b[48;5;101m▀\u001b[38;5;107m\u001b[48;5;107m▀\u001b[38;5;143m\u001b[48;5;144m▀▀\u001b[38;5;136m\u001b[48;5;143m▀\u001b[38;5;100m\u001b[48;5;101m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;235m\u001b[48;5;234m▀▀\u001b[48;5;235m▀\u001b[38;5;58m\u001b[48;5;236m▀▀\u001b[48;5;58m▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;144m\u001b[48;5;106m▀\u001b[38;5;187m\u001b[48;5;143m▀\u001b[38;5;230m\u001b[48;5;187m▀\u001b[38;5;255m\u001b[48;5;255m▀\u001b[38;5;230m\u001b[48;5;231m▀\u001b[38;5;187m\u001b[48;5;230m▀\u001b(B\u001b[m"] +[35.884752, "o", "\u001b[38;5;101m\u001b[48;5;143m▀\u001b[38;5;107m\u001b[48;5;107m▀\u001b[38;5;101m\u001b[48;5;144m▀\u001b[38;5;58m\u001b[48;5;143m▀\u001b[48;5;64m▀\u001b[48;5;58m▀▀▀▀▀\u001b[48;5;137m▀\u001b[38;5;180m\u001b[48;5;187m▀\u001b[38;5;187m\u001b[48;5;186m▀\u001b[38;5;143m\u001b[48;5;101m▀\u001b[38;5;100m\u001b[48;5;58m▀\u001b[38;5;58m\u001b[48;5;22m▀▀\u001b[48;5;58m▀\u001b[38;5;101m\u001b[48;5;65m▀\u001b[38;5;58m▀\u001b[48;5;58m▀\u001b[38;5;101m\u001b[48;5;101m▀▀\u001b[38;5;65m\u001b[48;5;65m▀\u001b[38;5;64m\u001b[48;5;64m▀▀\u001b[38;5;100m▀\u001b[38;5;101m\u001b[48;5;101m▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[38;5;142m\u001b[48;5;142m▀▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[48;5;64m▀\u001b[38;5;64m\u001b[48;5;100m▀\u001b[38;5;100m▀▀▀▀▀▀\u001b[38;5;64m▀▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;236m\u001b[48;5;237m▀\u001b[48;5;236m▀▀\u001b[38;5;235m\u001b[48;5;239m▀\u001b[38;5;236m\u001b[48;5;101m▀\u001b[38;5;238m\u001b[48;5;144m▀\u001b[38;5;59m▀\u001b[38;5;101m▀▀\u001b[38;5;144m\u001b[48;5;187m▀\u001b[38;5;150m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;236m\u001b[48;5;101m▀▀\u001b[38;5;239m\u001b[48;5;107m▀\u001b[38;5;101m\u001b[48;5;144m▀\u001b[38;5;144m▀\u001b[48;5;107m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;240m\u001b[48;5;239m▀\u001b[38;5;237m\u001b[48;5;236m▀\u001b[38;5;236m▀▀\u001b[48;5;235m▀\u001b[48;5;236m▀\u001b[38;5;237m\u001b[48;5;237m▀\u001b[38;5;239m\u001b[48;5;239m▀\u001b[38;5;65m\u001b[48;5;65m▀\u001b[38;5;107m\u001b[48;5;101m▀\u001b[38;5;144m\u001b[48;5;144m▀\u001b[38;5;150m▀\u001b[38;5;144m▀\u001b[48;5;108m▀\u001b[38;5;59m\u001b[48;5;240m▀\u001b[38;5;235m\u001b[48;5;235m▀\u001b[38;5;234m\u001b[48;5;234m▀\u001b[38;5;235m▀▀▀\u001b[48;5;235m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;106m\u001b[48;5;106m▀▀\u001b[38;5;186m\u001b[48;5;142m▀\u001b[38;5;230m\u001b[48;5;143m▀\u001b[38;5;255m\u001b[48;5;187m▀\u001b[38;5;230m\u001b[48;5;223m▀\u001b[38;5;150m\u001b[48;5;186m▀\u001b[38;5;107m\u001b[48;5;101m▀\u001b[38;5;187m\u001b[48;5;186m▀\u001b[48;5;187m▀\u001b[38;5;107m\u001b[48;5;101m▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b(B\u001b[m"] +[35.884961, "o", "\u001b[38;5;236m\u001b[48;5;237m▀\u001b[48;5;239m▀\u001b[38;5;59m\u001b[48;5;144m▀\u001b[38;5;187m\u001b[48;5;187m▀\u001b[48;5;144m▀\u001b[38;5;143m\u001b[48;5;65m▀\u001b[38;5;58m\u001b[48;5;235m▀\u001b[38;5;22m\u001b[48;5;22m▀▀▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;65m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[48;5;143m▀\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;101m▀▀\u001b[38;5;100m▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[38;5;142m\u001b[48;5;142m▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[48;5;65m▀\u001b[38;5;101m\u001b[48;5;101m▀▀▀\u001b[38;5;137m▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀\u001b[38;5;142m\u001b[48;5;142m▀\u001b[38;5;106m▀\u001b[38;5;100m\u001b[48;5;106m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;236m\u001b[48;5;237m▀\u001b[38;5;240m\u001b[48;5;101m▀\u001b[38;5;245m\u001b[48;5;144m▀\u001b[38;5;144m\u001b[48;5;187m▀\u001b[38;5;187m\u001b[48;5;253m▀\u001b[48;5;254m▀\u001b[48;5;253m▀\u001b[48;5;187m▀▀\u001b[48;5;144m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;144m\u001b[48;5;144m▀\u001b[38;5;150m\u001b[48;5;187m▀▀\u001b[48;5;150m▀\u001b[38;5;144m\u001b[48;5;144m▀\u001b[38;5;107m\u001b[48;5;101m▀\u001b[38;5;65m\u001b[48;5;65m▀\u001b[38;5;239m\u001b[48;5;238m▀\u001b[38;5;236m\u001b[48;5;235m▀\u001b[38;5;235m▀\u001b[38;5;236m▀\u001b[38;5;235m▀▀\u001b[38;5;236m▀\u001b[38;5;237m▀\u001b[38;5;240m\u001b[48;5;237m▀\u001b[38;5;65m\u001b[48;5;239m▀\u001b[38;5;101m▀\u001b[48;5;238m▀\u001b[48;5;237m▀\u001b[38;5;59m\u001b[48;5;235m▀\u001b[38;5;236m\u001b[48;5;234m▀\u001b[38;5;234m\u001b[48;5;233m▀\u001b[38;5;233m▀\u001b[38;5;234m\u001b[48;5;234m▀▀\u001b[48;5;235m▀▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;106m\u001b[48;5;106m▀▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[48;5;58m▀\u001b[38;5;143m▀\u001b[38;5;186m\u001b[48;5;143m▀\u001b[38;5;143m▀\u001b[48;5;101m▀\u001b[38;5;144m▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[48;5;236m▀\u001b[38;5;237m\u001b[48;5;238m▀\u001b[38;5;101m\u001b[48;5;144m▀\u001b[38;5;187m\u001b[48;5;187m▀\u001b[38;5;186m\u001b[48;5;143m▀\u001b[38;5;101m\u001b[48;5;58m▀\u001b[38;5;236m\u001b[48;5;235m▀\u001b[38;5;234m\u001b[48;5;234m▀\u001b[38;5;235m\u001b[48;5;235m▀\u001b(B\u001b[m"] +[35.885174, "o", "\u001b[38;5;235m\u001b[48;5;235m▀\u001b[38;5;22m\u001b[48;5;22m▀▀\u001b[38;5;240m\u001b[48;5;65m▀\u001b[38;5;65m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;240m\u001b[48;5;240m▀\u001b[38;5;101m\u001b[48;5;107m▀\u001b[38;5;100m\u001b[48;5;100m▀▀\u001b[38;5;64m▀\u001b[48;5;64m▀\u001b[38;5;100m\u001b[48;5;65m▀\u001b[48;5;101m▀\u001b[38;5;64m▀\u001b[38;5;100m\u001b[48;5;107m▀\u001b[38;5;106m\u001b[48;5;143m▀\u001b[38;5;142m\u001b[48;5;106m▀\u001b[38;5;106m\u001b[48;5;64m▀\u001b[38;5;101m▀▀\u001b[38;5;65m\u001b[48;5;101m▀\u001b[48;5;107m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[48;5;241m▀\u001b[38;5;95m\u001b[48;5;238m▀\u001b[48;5;236m▀\u001b[38;5;94m▀\u001b[48;5;58m▀\u001b[38;5;100m\u001b[48;5;100m▀▀\u001b[38;5;106m\u001b[48;5;106m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;238m\u001b[48;5;238m▀\u001b[38;5;101m\u001b[48;5;65m▀\u001b[38;5;144m\u001b[48;5;144m▀\u001b[38;5;187m\u001b[48;5;150m▀\u001b[38;5;253m\u001b[48;5;187m▀▀\u001b[38;5;187m\u001b[48;5;144m▀\u001b[48;5;108m▀\u001b[38;5;144m\u001b[48;5;101m▀\u001b[38;5;108m\u001b[48;5;59m▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;101m\u001b[48;5;236m▀\u001b[38;5;144m\u001b[48;5;239m▀\u001b[48;5;65m▀▀\u001b[38;5;101m\u001b[48;5;59m▀\u001b[38;5;65m\u001b[48;5;238m▀\u001b[38;5;238m\u001b[48;5;237m▀\u001b[38;5;236m\u001b[48;5;236m▀\u001b[38;5;235m▀▀\u001b[48;5;235m▀\u001b[48;5;236m▀\u001b[48;5;235m▀▀▀▀\u001b[38;5;236m▀▀▀\u001b[38;5;235m▀\u001b[48;5;236m▀\u001b[38;5;234m▀▀▀\u001b[38;5;235m\u001b[48;5;58m▀▀\u001b[38;5;236m▀\u001b[38;5;58m▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;106m\u001b[48;5;106m▀▀\u001b[48;5;100m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[38;5;100m\u001b[48;5;64m▀\u001b[38;5;101m\u001b[48;5;100m▀\u001b[48;5;101m▀▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[38;5;237m\u001b[48;5;238m▀\u001b[38;5;101m\u001b[48;5;144m▀\u001b[38;5;187m\u001b[48;5;187m▀\u001b[38;5;186m\u001b[48;5;143m▀\u001b[38;5;101m\u001b[48;5;58m▀\u001b[38;5;58m\u001b[48;5;235m▀\u001b[38;5;235m▀\u001b[38;5;234m\u001b[48;5;234m▀\u001b[48;5;235m▀\u001b[38;5;235m▀\u001b[38;5;22m▀\u001b[48;5;58m▀\u001b[38;5;240m\u001b[48;5;101m▀\u001b[38;5;65m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;240m▀\u001b[38;5;101m\u001b[48;5;107m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b(B\u001b[m"] +[35.885387, "o", "\u001b[38;5;100m\u001b[48;5;64m▀\u001b[48;5;100m▀\u001b[38;5;64m▀\u001b[38;5;240m\u001b[48;5;58m▀\u001b[38;5;65m▀\u001b[38;5;58m\u001b[48;5;235m▀\u001b[38;5;239m\u001b[48;5;58m▀\u001b[38;5;64m\u001b[48;5;64m▀▀\u001b[38;5;58m▀\u001b[38;5;64m▀▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[48;5;64m▀▀\u001b[38;5;101m▀\u001b[38;5;238m\u001b[48;5;101m▀\u001b[38;5;235m\u001b[48;5;65m▀\u001b[48;5;237m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀\u001b[38;5;58m\u001b[48;5;58m▀▀\u001b[38;5;237m\u001b[48;5;236m▀\u001b[38;5;240m\u001b[48;5;238m▀\u001b[38;5;101m\u001b[48;5;58m▀\u001b[38;5;107m▀▀\u001b[38;5;101m▀\u001b[38;5;65m\u001b[48;5;236m▀\u001b[38;5;238m\u001b[48;5;235m▀\u001b[38;5;236m▀▀\u001b[39m\u001b[49m\r\n\u001b[K\u001b[38;5;233m\u001b[48;5;233m▀▀\u001b[38;5;235m▀\u001b[38;5;236m\u001b[48;5;234m▀\u001b[38;5;237m▀\u001b[38;5;236m\u001b[48;5;235m▀\u001b[48;5;236m▀\u001b[38;5;237m\u001b[48;5;238m▀\u001b[38;5;238m▀\u001b[38;5;237m▀\u001b[38;5;236m\u001b[48;5;236m▀▀▀\u001b[38;5;235m\u001b[48;5;235m▀▀▀▀▀▀\u001b[38;5;236m\u001b[48;5;237m▀\u001b[38;5;238m\u001b[48;5;238m▀\u001b[48;5;239m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀▀▀▀\u001b[38;5;100m\u001b[48;5;64m▀\u001b[38;5;106m\u001b[48;5;106m▀▀\u001b[38;5;100m\u001b[48;5;64m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[48;5;235m▀\u001b[48;5;58m▀\u001b[38;5;64m\u001b[48;5;64m▀\u001b[38;5;100m\u001b[48;5;100m▀\u001b[38;5;101m\u001b[48;5;101m▀▀\u001b[38;5;65m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;186m\u001b[48;5;186m▀\u001b[48;5;143m▀\u001b[38;5;101m\u001b[48;5;58m▀\u001b[38;5;58m\u001b[48;5;236m▀\u001b[38;5;235m\u001b[48;5;235m▀\u001b[38;5;234m\u001b[48;5;234m▀▀\u001b[38;5;235m\u001b[48;5;235m▀▀▀▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[38;5;65m\u001b[48;5;240m▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[48;5;239m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;64m\u001b[48;5;64m▀▀▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;239m\u001b[48;5;240m▀\u001b[38;5;236m\u001b[48;5;236m▀\u001b[38;5;235m▀\u001b[38;5;58m\u001b[48;5;58m▀▀▀▀\u001b[38;5;64m▀\u001b[48;5;64m▀▀\u001b(B\u001b[m"] +[35.885477, "o", "\u001b[38;5;64m\u001b[48;5;64m▀▀▀▀\u001b[38;5;100m▀\u001b[38;5;101m\u001b[48;5;101m▀\u001b[38;5;58m\u001b[48;5;65m▀\u001b[48;5;64m▀\u001b[38;5;100m\u001b[48;5;100m▀▀▀\u001b[38;5;58m\u001b[48;5;58m▀\u001b[48;5;236m▀\u001b[38;5;235m\u001b[48;5;235m▀\u001b[38;5;236m\u001b[48;5;236m▀▀\u001b[38;5;58m▀\u001b[48;5;235m▀\u001b[38;5;235m▀\u001b[48;5;234m▀\u001b[48;5;235m▀▀▀\u001b[39m\u001b[49m\r\u001b[5S\u001b[4A\u001b[2mImage URL: \u001b(B\u001b[m\u001b[K\r\n\u001b[2mhttps://evalstate-flux1-schnell.hf.space/--replicas/zrbxs/gradio_api/file=/tmp/gradio/3c2890688d5354e0584364bfe67225bdf3\u001b[32;1Hf409faa48f3a27173395a25ad64222/image.webp\u001b(B\u001b[m\u001b[K\r\n\u001b[2mSeed used for generation: 1824537418\u001b(B\u001b[m\u001b[K\r\n\u001b[K"] +[35.897333, "o", "\n\u001b[K"] +[35.897571, "o", "\n\u001b[A\u001b[2mLast turn: \u001b[36m\u001b[1m7\u001b(B\u001b[m\u001b[2m,\u001b[36m\u001b[1m482\u001b(B\u001b[m\u001b[2m Input, \u001b[36m\u001b[1m83\u001b(B\u001b[m\u001b[2m Output \u001b[1m(\u001b[36m2.8\u001b(B\u001b[m\u001b[2m%\u001b[1m)\u001b(B\u001b[m \u001b[92m*\u001b[39m\r\n\u001b[K"] +[35.904282, "o", "\u001b[K\u001b[93m❯\u001b[39m\r\u001b[5S\u001b[4A\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[29;3H"] +[35.908471, "o", "\u001b[34;1H\n\u001b[K\u001b[30m\u001b[47m\u001b[7m \u001b[34m\u001b[40m dev[S] \u001b[30m\u001b[47m \u001b[32m\u001b[40mTVD\u001b[30m\u001b[100m ▲ \u001b[42m⢠\u001b[43m⡆\u001b[47m \u001b[42m∞gpt-5.5\u001b[100m»⊕\u001b[47m | 2.78% | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | source/fast-agent-pr | fast-agent 0.7.11 \u001b[28;3H\u001b(B\u001b[m"] +[67.059272, "o", "/exit"] +[67.061735, "o", "\r\u001b[93m❯\u001b[39m /exit\u001b[34;1H \u001b[29;1H\u001b[J\u001b[A\u001b[K"] +[67.062372, "o", "\u001b[2m❯ \u001b[35m/\u001b[95mexit\r\n\u001b(B\u001b[m"] +[67.062818, "o", "\r\n\u001b[31m\u001b[1mUser requested exit:\r\n\u001b(B\u001b[m"] +[67.062933, "o", "User requested to exit fast-agent session\r\n"] +[67.063182, "o", "\r\n"] +[67.0635, "o", "\u001b[2m────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[34;1H\u001b(B\u001b[m\n\u001b[K"] +[67.063737, "o", "\u001b[2m▎\u001b(B\u001b[m\r\u001b[2S\u001b[32;2H \u001b[1m\u001b[2mUsage Summary\u001b(B\u001b[m\r\n\u001b[K\r\n\u001b[K"] +[67.06388, "o", "\n\u001b[A\u001b[2mAgent Input Output Total Turns Tools Context% Model \u001b(B\u001b[m\r\n\u001b[K"] +[67.064167, "o", "\n\u001b[A\u001b[2mdev \u001b[36m\u001b[1m24\u001b(B\u001b[m\u001b[2m,\u001b[36m\u001b[1m390\u001b(B\u001b[m\u001b[2m \u001b[36m\u001b[1m294\u001b(B\u001b[m\u001b[2m \u001b[1m \u001b[36m24\u001b[39m,\u001b[36m684\u001b(B\u001b[m\u001b[2m \u001b[36m\u001b[1m4\u001b(B\u001b[m\u001b[2m \u001b[36m\u001b[1m3\u001b(B\u001b[m\u001b[2m \u001b[36m\u001b[1m2.8\u001b(B\u001b[m\u001b[2m% gpt-\u001b[36m\u001b[1m5.5\u001b(B\u001b[m\u001b[2m \u001b(B\u001b[m\r\n\u001b[K\n\u001b[K"] diff --git a/docs/docs/guides/tui.md b/docs/docs/guides/tui.md index aac7c95ab..974817bc4 100644 --- a/docs/docs/guides/tui.md +++ b/docs/docs/guides/tui.md @@ -163,11 +163,12 @@ For example, use `LOGGER__TERMINAL_IMAGES__ENABLED=false` to disable terminal im The recording below is a review capture of image generation through the Hugging Face MCP server. It was recorded with `FAST_AGENT_KEYRING_NOTICE=0` so the OS keyring access notice does not appear -in the cast, and with `LOGGER__TERMINAL_IMAGES__ENABLED=true` so terminal image output is enabled: +in the cast, with `LOGGER__TERMINAL_IMAGES__ENABLED=true`, and with `LOGGER__TERMINAL_IMAGES__BACKEND=halfcell` so asciinema records ANSI/Unicode cells instead of terminal-specific image protocols: ```bash export FAST_AGENT_KEYRING_NOTICE=0 export LOGGER__TERMINAL_IMAGES__ENABLED=true +export LOGGER__TERMINAL_IMAGES__BACKEND=halfcell uv run fast-agent -x --model codexplan --url https://huggingface.co/mcp ``` @@ -177,9 +178,7 @@ Prompt: generate an image of a sunflower ``` -In this environment the terminal preview is captured by asciinema as SIXEL-style terminal frames -(`SIXEL IMAGE (...) +++++...`) rather than as a separate image asset. The Markdown image link and -source URL remain visible in the recording. +For docs recordings, `halfcell` is safer than `sixel` or `kitty`: it uses ANSI colour and Unicode block characters that asciinema-player can replay as ordinary terminal text. The Markdown image link and source URL remain visible in the recording as a fallback.
@@ -259,7 +258,7 @@ source URL remain visible in the recording. cols: 120, rows: 34, preload: true, - poster: "npt:1:24", + poster: "npt:0:36", speed: 1, idleTimeLimit: 1.3, fit: "width", diff --git a/docs/docs/ref/docs_automation.md b/docs/docs/ref/docs_automation.md index df435f51a..7b6854448 100644 --- a/docs/docs/ref/docs_automation.md +++ b/docs/docs/ref/docs_automation.md @@ -120,6 +120,7 @@ notice suppressed and terminal image rendering enabled: ```bash export FAST_AGENT_KEYRING_NOTICE=0 export LOGGER__TERMINAL_IMAGES__ENABLED=true +export LOGGER__TERMINAL_IMAGES__BACKEND=halfcell uv run fast-agent -x --model codexplan --url https://huggingface.co/mcp ``` @@ -130,15 +131,14 @@ generate an image of a sunflower ``` The Hugging Face MCP server invoked `evalstate/flux1_schnell` and returned an `image/webp` block, -an image URL, and a seed. In the asciinema cast, terminal image output is captured as terminal -frames rather than as a separate image asset. In this environment the inline preview appeared as -SIXEL-style text frames, for example: +an image URL, and a seed. In the asciinema cast, terminal image output is captured as terminal frames rather than as a separate image asset. Prefer the `halfcell` backend for committed recordings because it replays as ANSI colour and Unicode block characters. A typical captured output includes: ```text [IMAGE: image/webp, 81600 bytes] Image URL: https://evalstate-flux1-schnell.hf.space/.../image.webp Seed used for generation: 2131209976 -SIXEL IMAGE (96x33) +++++... +[IMAGE 1: image/webp, ... bytes] +ANSI/Unicode half-block image preview... ``` The URL and Markdown image link remain visible in the cast, so this is safe as a docs fallback even From 50c65fa1305881754bf208ee83c1a9c9e713a398 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Tue, 26 May 2026 21:56:50 +0100 Subject: [PATCH 52/58] streaming! --- src/fast_agent/a2a/remote_agent.py | 67 ++++++--- .../test_a2a_remote_agent_events.py | 129 +++++++++++++++++- 2 files changed, 173 insertions(+), 23 deletions(-) diff --git a/src/fast_agent/a2a/remote_agent.py b/src/fast_agent/a2a/remote_agent.py index 561de5139..be018d1c3 100644 --- a/src/fast_agent/a2a/remote_agent.py +++ b/src/fast_agent/a2a/remote_agent.py @@ -261,28 +261,57 @@ async def generate_impl( ) self._log_a2a_progress(ProgressAction.SENDING, details=self._transport_label()) - result = await self._consume_events(self._client.send_message(request)) - self._log_a2a_progress(ProgressAction.READY, details=result.state or "completed") - response_text = result.text or result.status_text or _state_message(result.state) - if result.state in _ERROR_STATES: - response_text = f"A2A task {result.state}: {response_text}" - stop_reason = ( - LlmStopReason.PAUSE - if result.state == _INPUT_REQUIRED_STATE - else LlmStopReason.END_TURN - ) - assistant_message = PromptMessageExtended( - role="assistant", - content=[TextContent(type="text", text=response_text)], - stop_reason=stop_reason, - ) - progress_display.pause(cancel_deferred_on_noop=True) - await self.display.show_assistant_message( - assistant_message, + remove_live_listener: Callable[[], None] | None = None + stream_emitted = False + preserve_streamed_frame = False + + with self.display.streaming_assistant_message( name=self.name, model="A2A", bottom_items=[self._transport_label()], - ) + ) as stream_handle: + + def update_live_stream(chunk: StreamChunk) -> None: + nonlocal stream_emitted + stream_emitted = True + stream_handle.update_chunk(chunk) + + remove_live_listener = self.add_stream_listener(update_live_stream) + try: + result = await self._consume_events(self._client.send_message(request)) + finally: + remove_live_listener() + remove_live_listener = None + + self._log_a2a_progress(ProgressAction.READY, details=result.state or "completed") + response_text = result.text or result.status_text or _state_message(result.state) + if result.state in _ERROR_STATES: + response_text = f"A2A task {result.state}: {response_text}" + stop_reason = ( + LlmStopReason.PAUSE + if result.state == _INPUT_REQUIRED_STATE + else LlmStopReason.END_TURN + ) + assistant_message = PromptMessageExtended( + role="assistant", + content=[TextContent(type="text", text=response_text)], + stop_reason=stop_reason, + ) + await stream_handle.wait_for_drain() + if stream_emitted and result.state not in _ERROR_STATES: + preserve_streamed_frame = stream_handle.preserve_final_frame() + stream_handle.finalize(assistant_message) + + if remove_live_listener is not None: + remove_live_listener() + progress_display.pause(cancel_deferred_on_noop=True) + if not preserve_streamed_frame: + await self.display.show_assistant_message( + assistant_message, + name=self.name, + model="A2A", + bottom_items=[self._transport_label()], + ) console.console.print() if use_history: self._persist_history(messages, assistant_message) diff --git a/tests/unit/fast_agent/test_a2a_remote_agent_events.py b/tests/unit/fast_agent/test_a2a_remote_agent_events.py index fffa158ca..103db985d 100644 --- a/tests/unit/fast_agent/test_a2a_remote_agent_events.py +++ b/tests/unit/fast_agent/test_a2a_remote_agent_events.py @@ -1,11 +1,20 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from contextlib import contextmanager +from typing import TYPE_CHECKING, Any, cast import pytest -from a2a.types import Artifact, Part, StreamResponse, Task, TaskState, TaskStatus +from a2a.types import ( + Artifact, + Part, + StreamResponse, + Task, + TaskArtifactUpdateEvent, + TaskState, + TaskStatus, +) from google.protobuf.json_format import MessageToDict -from mcp.types import EmbeddedResource, TextResourceContents +from mcp.types import EmbeddedResource, TextContent, TextResourceContents from pydantic import AnyUrl from fast_agent.a2a.config import A2AAgentConfig @@ -14,7 +23,9 @@ from fast_agent.types import PromptMessageExtended if TYPE_CHECKING: - from collections.abc import AsyncIterator + from collections.abc import AsyncIterator, Iterator + + from fast_agent.llm.stream_types import StreamChunk async def _events(*events: StreamResponse) -> AsyncIterator[StreamResponse]: @@ -29,6 +40,71 @@ def _remote_agent() -> A2ARemoteAgent: ) +class _FakeStreamHandle: + def __init__(self, *, preserve: bool) -> None: + self.preserve = preserve + self.chunks: list[str] = [] + self.finalized = False + + def update_chunk(self, chunk: StreamChunk) -> None: + self.chunks.append(chunk.text) + + async def wait_for_drain(self) -> None: + return + + def preserve_final_frame(self) -> bool: + return self.preserve and bool(self.chunks) + + def finalize(self, message: PromptMessageExtended) -> None: + del message + self.finalized = True + + +class _FakeDisplay: + def __init__(self, *, preserve: bool = True) -> None: + self.handle = _FakeStreamHandle(preserve=preserve) + self.assistant_messages: list[PromptMessageExtended] = [] + + def show_user_message(self, *_args: object, **_kwargs: object) -> None: + return + + @contextmanager + def streaming_assistant_message(self, **_kwargs: object) -> Iterator[_FakeStreamHandle]: + yield self.handle + + async def show_assistant_message( + self, + message: PromptMessageExtended, + **_kwargs: object, + ) -> None: + self.assistant_messages.append(message) + + +class _FakeClient: + def __init__(self, events: list[StreamResponse]) -> None: + self.events = events + + def send_message(self, _request: object) -> AsyncIterator[StreamResponse]: + return _events(*self.events) + + +def _artifact_update( + text: str, + *, + append: bool = False, + last_chunk: bool = False, +) -> StreamResponse: + return StreamResponse( + artifact_update=TaskArtifactUpdateEvent( + task_id="task-1", + context_id="ctx-1", + artifact=Artifact(name="response", parts=[Part(text=text)]), + append=append, + last_chunk=last_chunk, + ) + ) + + @pytest.mark.asyncio async def test_a2a_remote_agent_clears_task_id_for_terminal_full_task_event() -> None: agent = _remote_agent() @@ -102,6 +178,51 @@ def test_a2a_remote_agent_keeps_input_required_task_for_no_history_follow_up() - assert agent.last_task_state == "TASK_STATE_INPUT_REQUIRED" +@pytest.mark.asyncio +async def test_a2a_remote_agent_streams_chunks_to_live_display() -> None: + agent = _remote_agent() + display = _FakeDisplay(preserve=True) + agent.display = cast("Any", display) + agent._client = _FakeClient( + [ + _artifact_update("one "), + _artifact_update("two", append=True, last_chunk=True), + StreamResponse( + task=Task( + id="task-1", + context_id="ctx-1", + status=TaskStatus(state=TaskState.TASK_STATE_COMPLETED), + ) + ), + ] + ) + + response = await agent.generate_impl( + [PromptMessageExtended(role="user", content=[TextContent(type="text", text="stream")])] + ) + + assert response.all_text() == "one two" + assert display.handle.chunks == ["one ", "two"] + assert display.handle.finalized + assert display.assistant_messages == [] + + +@pytest.mark.asyncio +async def test_a2a_remote_agent_renders_final_message_when_live_display_cannot_preserve() -> None: + agent = _remote_agent() + display = _FakeDisplay(preserve=False) + agent.display = cast("Any", display) + agent._client = _FakeClient([_artifact_update("final", last_chunk=True)]) + + response = await agent.generate_impl( + [PromptMessageExtended(role="user", content=[TextContent(type="text", text="stream")])] + ) + + assert response.all_text() == "final" + assert display.handle.chunks == ["final"] + assert [message.all_text() for message in display.assistant_messages] == ["final"] + + def test_a2a_remote_agent_sends_json_text_resources_as_data_parts() -> None: parts = _parts_from_messages( [ From b9c3e7287c9c3172f4935d323d24ef5d69db76e9 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Tue, 26 May 2026 22:16:26 +0100 Subject: [PATCH 53/58] docs: refresh A2A client assets --- .../assets/a2a/a2a-real-llm-hf-streaming.cast | 783 ++++-------------- docs/docs/assets/social/a2a/host-on-hf.png | Bin 0 -> 27120 bytes docs/social_cards/contact-sheet.html | 8 +- 3 files changed, 173 insertions(+), 618 deletions(-) create mode 100644 docs/docs/assets/social/a2a/host-on-hf.png diff --git a/docs/docs/assets/a2a/a2a-real-llm-hf-streaming.cast b/docs/docs/assets/a2a/a2a-real-llm-hf-streaming.cast index a742ed9ce..b6beb34cf 100644 --- a/docs/docs/assets/a2a/a2a-real-llm-hf-streaming.cast +++ b/docs/docs/assets/a2a/a2a-real-llm-hf-streaming.cast @@ -1,614 +1,169 @@ -{"version": 2, "width": 120, "height": 32, "timestamp": 1779323555, "idle_time_limit": 1.3, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}, "title": "fast-agent A2A real LLM Hugging Face MCP streaming demo"} -[0.024469, "o", "\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?2004l\u001b[1;1H\u001b[1;32r\u001b[>c\u001b[>q\u001b[14;1H"] -[0.025159, "o", "\u001b[?25l\u001b[2A─────────────────────────────────────────────────────────────\u001b[32m───────────────────────────────────────────────────────────\u001b(B\u001b[m\u001b[1;1Hfast-agent A2A server ready\u001b[K\r\nmodel: codexresponses.gpt-5.4-mini\u001b[K\r\nMCP: https://hf.co/mcp\u001b[K\r\nlog: /tmp/a2a-real-llm-server.log\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[2BA2A card: http://127.0.0.1:41243/.well-known/agent-card.json\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[14d\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?2004l\u001b[1;1H\u001b[1;32r\u001b[14;1H\u001b[?25l\u001b[2A─────────────────────────────────────────────────────────────\u001b[32m───────────────────────────────────────────────────────────\u001b(B\u001b[m\u001b[1;1Hfast-agent A2A server ready\u001b[K\r\nmodel: codexresponses.gpt-5.4-mini\u001b[K\r\nMCP: https://hf.co/mcp\u001b[K\r\nlog: /tmp/a2a-real-llm-server.log\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[2BA2A card: http://127.0.0.1:41243/.well-known/agent-card.json\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[14d"] -[0.04037, "o", "{\r\n \"name\": \"hf-model-research\",\r\n \"description\": \"A fast-agent A2A server.\",\r\n \"supportedInterfaces\": [\r\n {\r\n \"url\": \"http://127.0.0.1:41243/a2a/jsonrpc\",\r\n \"protocolBinding\": \"JSONRPC\",\r\n \"protocolVersion\": \"1.0\"\r\n },\r\n {\r\n \"url\": \"http://127.0.0.1:41243/a2a/rest\",\r\n \"protocolBinding\": \"HTTP+JSON\",\r\n \"protocolVersion\": \"1.0\"\r\n }\r\n ],\r\n \"provider\": {\r\n \"url\": \"https://fast-agent.ai\",\r\n\u001b[13;32r\u001b[1;1H\u001b[4S\u001b[27d \"organization\": \"fast-agent\"\r\n },\r\n \"version\": \"0.7.8\",\u001b[K\r\n \"capabilities\": {\u001b[K\r\n \"streaming\": true,\u001b[K\r\n\u001b[K\u001b[1;32r\u001b[32;1H"] -[0.043338, "o", "\u001b[13;32r\u001b[1;1H\u001b[2S\u001b[31dinteractive A2A JSON-RPC client\u001b[K\r\n\u001b[K\u001b[1;32r\u001b[32;1H"] -[0.527263, "o", "\u001b[?25l\u001b[12d─────────────────────────────────────────────────────────────\u001b[32m───────────────────────────────────────────────────────────\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[32;1H"] -[1.026129, "o", "\u001b[?7727h"] -[2.169532, "o", "\u001b[?25l"] -[2.187965, "o", "\u001b[?12l\u001b[?25h"] -[2.197368, "o", "\u001b[13;32r\u001b[1;1H\u001b[3S\u001b[29d\u001b[2mUse \u001b[32m'/'\u001b[39m for commands, \u001b[32m'!'\u001b[39m for shell. \u001b[32m'#'\u001b[39m to query, \u001b[32m'@'\u001b[39m to switch agents\r\nCTRL+T multiline, CTRL+Y copy last message, CTRL+E external editor.\u001b(B\u001b[m\u001b[K\r\n\u001b[2mCTRL+Space or Tab for path completion. Use \u001b[35m/\u001b[95mattach\u001b[39m, `^file:`, or `^url:` for attachments. F10 to clear.\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[1;32r\u001b[32;1H"] -[2.197491, "o", "\u001b[13;32r\u001b[32;1H\n\u001b[K\u001b[1;32r\u001b[32;1H"] -[2.200535, "o", "\u001b[13;32r\u001b[32;1H\u001b[K❯\r\u001b[7S\u001b[6A\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[1;32r\u001b[25;3H\u001b[?2004h"] -[2.204388, "o", "\u001b[13;32r\u001b[32;1H\n\u001b[K\u001b[30m\u001b[47m\u001b[7m \u001b[35m\u001b[40m a2a_remote[A2A] \u001b[30m\u001b[47m \u001b[100m ▲ \u001b[47m \u001b[42mhf-model-research\u001b[47m | 000 | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | fast-agent 0.7.8 \u001b[32;1H\u001b[1;32r\u001b[24;3H\u001b(B\u001b[m"] -[3.570918, "o", "Use the Hugging Face MCP server if available. Answer in markdown: what models are trending on Hugging Face right now?\r\nInclude concise bullets and mention any uncertainty."] -[3.574149, "o", "\u001b[24;1H❯ \u001b[32;1H \u001b[K\u001b[25;53H"] -[3.574432, "o", "\u001b[13;32r\u001b[25;1H\u001b[J\u001b[A\u001b[K\u001b[1;32r\u001b[24;1H\u001b[?2004l"] -[3.574743, "o", "\u001b[A"] -[3.575061, "o", "\u001b[?25l"] -[3.575849, "o", "\r\n"] -[3.57623, "o", "\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m \u001b[34ma2a_remote\u001b[39m \u001b[2m──────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[25;1H\u001b(B\u001b[m"] -[3.576799, "o", "Use the Hugging Face MCP server if available. Answer in markdown: what models are trending on Hugging Face right now? \r\nInclude concise bullets and mention any uncertainty.\r\n"] -[3.577997, "o", "\u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[3.578381, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[3.676465, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[3.777234, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[3.878126, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[3.896019, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[3.896431, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[3.978868, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[4.079536, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[4.180286, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[4.281106, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[4.381781, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[4.482551, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[4.583144, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[4.684086, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[4.78485, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[4.885568, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[4.986237, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[5.086948, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[5.187858, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[5.288624, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[5.38933, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[5.489961, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[5.590855, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[5.691642, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[5.792418, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[5.893163, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[5.993885, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.094589, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.195364, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.284472, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.286844, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.287428, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.288685, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.295809, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.302287, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.303364, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.304045, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.304461, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.304906, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.30549, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.305965, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.306383, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.308467, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.310429, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.312391, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.313259, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.318022, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.318456, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.319966, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.323255, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.327462, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.329796, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.331294, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.333173, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.351392, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.352354, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.353348, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.354078, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.354325, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.3547, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.355195, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.355787, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.356284, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.356883, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.357163, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.396597, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.497407, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.598102, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.698808, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.79943, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[6.900203, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[7.000904, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[7.101527, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[7.20218, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[7.302868, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[7.403625, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[7.504553, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[7.605218, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[7.705965, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[7.806797, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[7.907536, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[8.008259, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[8.109062, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[8.20974, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[8.310584, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[8.411351, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[8.512302, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[8.612955, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[8.713788, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[8.814454, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[8.915386, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.016044, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.116718, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.217377, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.318249, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.418944, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.519597, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.565337, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.568087, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.571001, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.573388, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.57975, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.58016, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.581761, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.586139, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.590768, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.593236, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.595392, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.597281, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.599215, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.601009, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.604803, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.612336, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.612862, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.615799, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.616321, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.617374, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.620142, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.621249, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.622584, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.624818, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.626274, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.630165, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.634695, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.640682, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.643798, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.646002, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.649133, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.651386, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.653249, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.655885, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.660725, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.663332, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.665126, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.666878, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.669716, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.675527, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.676006, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.681943, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.684137, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.684857, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.687018, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.690254, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.69278, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.694093, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.697054, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.701088, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.705735, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.708494, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.710713, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.71247, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.714125, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.715671, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.718494, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.7206, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.725264, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.725708, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.728053, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.731071, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.732762, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.736476, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.73773, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.739179, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.741514, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.744319, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.749066, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.750473, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.75299, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.75495, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.757119, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.759231, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.761705, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.765178, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.769135, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.770849, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.773526, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.777311, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.780245, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.781803, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.784488, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.788582, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.793552, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.798131, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.800503, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.80334, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.806015, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.808911, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.809525, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.811611, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.814309, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.817687, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.820757, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.821192, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.823583, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.826296, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.827907, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.830099, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.836944, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.839396, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.847663, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.848562, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.850388, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.854323, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.855721, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.85768, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.858826, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.861377, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.865453, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.869254, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.871695, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.874704, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.87773, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.881312, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.884983, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.887754, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.892722, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.897053, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.899948, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.901361, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.903401, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.907653, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.909686, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.911787, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.920726, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.921157, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.921704, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.923607, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.925816, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.92779, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.929826, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.931728, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.934355, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.938305, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.943663, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.948586, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.94983, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.952418, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.954366, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.956578, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.959454, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.962553, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.9661, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.969565, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.973763, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.977303, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.982574, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.985629, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.991676, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[9.996274, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.008774, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.013768, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.018955, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.020367, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.022302, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.025894, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.031732, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.037332, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.041746, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.044739, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.046789, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.050216, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.053876, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.056451, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.05939, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.060881, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.065322, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.06902, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.076494, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.080851, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.081501, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.082951, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.086185, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.088643, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.090103, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.092814, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.096715, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.100603, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.104651, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.106563, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.108883, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.110515, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.112234, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.118917, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.119491, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.122937, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.123655, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.126673, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.129436, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.131612, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.133122, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.136048, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.138966, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.141257, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.144642, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.146693, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.149673, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.151798, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.155618, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.156273, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.158722, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.162717, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.166074, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.171221, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.173986, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.176031, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.180549, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.181509, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.186973, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.187395, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.191381, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.194411, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.196744, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.198989, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.20138, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.202683, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.204453, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.208491, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.212407, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.216277, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.223388, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.224556, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.225258, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.225694, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.226074, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.227652, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.231017, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.237852, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.239582, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.24234, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.245169, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.248396, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.25089, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.252284, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.255192, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.258318, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.262528, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.266441, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.268974, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.270974, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.276273, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.278673, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.283881, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.28601, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.288289, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.290182, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.292237, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.294559, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.296725, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.299044, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.301575, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.305601, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.309658, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.312387, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.316354, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.317507, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.321024, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.322599, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.323813, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.326927, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.330617, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.332773, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.33471, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.336911, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.337806, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.340693, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.343963, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.345134, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.348423, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.351267, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.353735, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.355982, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.358706, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.362331, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.362826, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.364482, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.367409, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.370554, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.374913, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.379874, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.383506, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.385537, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.386996, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.389941, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.390948, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.392408, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.396786, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.400913, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.401777, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.40561, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.406006, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.407622, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.409509, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.411318, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.414297, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.416716, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.420561, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.42316, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.42436, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.42631, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.429699, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.431793, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.43629, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.441067, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.445435, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.449339, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.452144, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.454448, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.456191, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.458148, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.460659, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.46374, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.467309, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.470916, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.474955, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.476083, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.478035, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.481267, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.483998, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.48818, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.492153, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.495635, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.49879, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.501566, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.509383, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.509787, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.510223, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.511254, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.515335, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.51905, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.521833, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.524892, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.526739, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.529581, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.53368, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.537669, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.542474, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.54763, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.550139, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.553301, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.557015, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.558501, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.560688, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.5622, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.566011, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.570012, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.572316, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.575806, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.57925, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.581036, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.58311, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.58717, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.592002, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.594606, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.597375, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.598476, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.600395, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.603894, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.605396, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.608548, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.613342, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.617564, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.619385, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.621432, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.624425, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.625333, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.626908, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.630239, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.6332, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.636512, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.640755, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.643309, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.646774, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.648563, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.650504, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.653233, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.656799, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.65983, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.663747, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.666872, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.669298, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.671953, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.674746, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.676648, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.679429, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.682182, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.684801, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.689402, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.691886, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.693732, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.696077, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.70161, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.70634, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.71586, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.720604, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.725912, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.730659, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.734795, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.739189, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.746592, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.749051, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.753031, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.757946, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.760662, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.764256, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.769773, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.772851, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.777345, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.778806, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.780819, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.785071, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.78796, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.793693, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.799555, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.802301, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.803119, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.805165, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.807966, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.81107, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.814747, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.821221, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.825312, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.826357, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.828497, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.830907, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.834001, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.837861, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.840889, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.845321, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.848912, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.852021, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.85666, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.860373, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.863257, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.86484, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.869219, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.86997, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.87329, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.876669, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.880619, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.885835, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.888985, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.893128, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.896476, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.903124, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.907867, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.909776, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.911612, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.914051, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.915707, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.917621, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.919235, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.921825, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.924201, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.926823, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.936293, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.936726, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.941992, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.942404, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.942857, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.946351, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.946759, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.951561, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.955904, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.956432, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.959772, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.960272, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.962362, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.963125, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.963582, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.964069, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.964588, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.965099, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.967358, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[10.971352, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[11.027772, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] -[11.052512, "o", "\r\u001b[K\u001b[?12l\u001b[?25h"] -[11.052945, "o", "\r\n"] -[11.053114, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m \u001b[32ma2a_remote\u001b[39m \u001b[2mA2A\r\n\u001b(B\u001b[m"] -[11.059437, "o", "Here are the \u001b[1mcurrently trending Hugging Face models\u001b(B\u001b[m I found via the Hub’s trending ranking. \u001b[1mUncertainty:\u001b(B\u001b[m “Trending” is \u001b[30;1Hdynamic and can shift by hour/day, so treat this as a snapshot from right now. \u001b[32;1H\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m —\u001b[13;32r\u001b[32;1H\n\u001b[31;30H any-to-any / multimodal \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m —\r\n\u001b[31;30H text-to-video \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4mopenbmb/MiniCPM-V-4.6\u001b(B\u001b[m —\r\n\u001b[31;27H image-text-to-text \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m —\r\n\u001b[31;28H text-to-speech \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4munsloth/Qwen3.6-27B-MTP-GGUF\u001b(B\u001b[m —\r\n\u001b[31;34H image-text-to-text \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4mcirclestone-labs/Anima\u001b(B\u001b[m —\r\n\u001b[31;28H diffusion-single-file \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4munsloth/Qwen3.6-35B-A3B-MTP-GGUF\u001b(B\u001b[m —\r\n\u001b[31;38H image-text-to-text \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4mResembleAI/Dramabox\u001b(B\u001b[m —\r\n\u001b[31;25H text-to-speech \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m —\r\n\u001b[31;28H text-generation \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b[94m\u001b[4mfroggeric/Qwen-Fixed-Chat-Templates\u001b(B\u001b[m —\r\u001b[4S\u001b[28;41H chat-template utilities \u001b[29;1H\u001b[K\r\nIf you want, I can also narrow this down to: \u001b[31;1H\u001b[K\r\n\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m•\u001b(B\u001b[m\r\n\u001b[31;3H\u001b[1m top open-weights LLMs\u001b(B\u001b[m \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m•\u001b(B\u001b[m\r\n\u001b[31;3H\u001b[1m top multimodal models\u001b(B\u001b[m \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m•\u001b(B\u001b[m\r\n\u001b[31;3H\u001b[1m top text-to-image/video/speech models\u001b(B\u001b[m \u001b[32;1H\u001b[K\u001b[1;32r\u001b[32;1H"] -[11.059537, "o", "\u001b[13;32r\u001b[32;1H\n\u001b[K\u001b[1;32r\u001b[32;1H"] -[11.191844, "o", "\u001b[13;32r\u001b[32;1H\u001b[K❯\r\u001b[7S\u001b[6A\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[1;32r\u001b[25;3H\u001b[?2004h"] -[11.195311, "o", "\u001b[13;32r\u001b[32;1H\n\u001b[K\u001b[30m\u001b[47m\u001b[7m \u001b[35m\u001b[40m a2a_remote[A2A] \u001b[30m\u001b[47m \u001b[100m ▲ \u001b[47m \u001b[42mhf-model-research\u001b[47m | 001 | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | fast-agent 0.7.8 \u001b[32;1H\u001b[1;32r\u001b[24;3H\u001b(B\u001b[m"] -[73.558241, "o", "\r❯ /exit\u001b[32;1H \u001b[K\u001b[24;8H"] -[73.558482, "o", "\u001b[13;32r\u001b[25;1H\u001b[J\u001b[A\u001b[K\u001b[1;32r\u001b[24;1H"] -[73.558661, "o", "\u001b[?2004l"] -[73.559305, "o", "\u001b[2m❯ \u001b[35m/\u001b[95mexit\r\n\u001b(B\u001b[m"] -[73.559746, "o", "\r\n\u001b[31m\u001b[1mUser requested exit:\r\n\u001b(B\u001b[m"] -[73.559913, "o", "User requested to exit fast-agent session\r\n"] -[74.056648, "o", "\u001b[?25l\u001b[Hfast-agent A2A server ready\u001b[K\r\nmodel: codexresponses.gpt-5.4-mini\u001b[K\r\nMCP: https://hf.co/mcp\u001b[K\r\nlog: /tmp/a2a-real-llm-server.log\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[6d"] -[74.308143, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] -[75.560495, "o", "\u001b[1;32r\u001b(B\u001b[m\u001b[?1l\u001b>\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?7727l\u001b[?1004l\u001b[?1049l\u001b[23;0;0t"] -[75.56079, "o", "[exited]\r\n"] +{"version": 2, "width": 120, "height": 32, "timestamp": 1779830028, "idle_time_limit": 1.3, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}, "title": "fast-agent A2A real LLM Hugging Face MCP streaming demo"} +[0.073334, "o", "\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004h\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;32r\u001b[c\u001b[>c\u001b[>q\u001b]10;?\u001b\\\u001b]11;?\u001b\\\u001b[32;1H"] +[0.073817, "o", "\u001b[?25l\u001b[12d─────────────────────────────────────────────────────────────\u001b[32m───────────────────────────────────────────────────────────\u001b(B\u001b[m\u001b[1;1Hfast-agent A2A server ready\u001b[K\r\nmodel: codexresponses.gpt-5.4-mini\u001b[K\r\nMCP: https://hf.co/mcp\u001b[K\r\nlog: /tmp/a2a-real-llm-server.log\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[2B \"url\": \"http://127.0.0.1:41243/a2a/jsonrpc\",\u001b[K\r\n \"protocolBinding\": \"JSONRPC\",\u001b[K\r\n \"protocolVersion\": \"1.0\"\u001b[K\r\n },\u001b[K\r\n {\u001b[K\r\n \"url\": \"http://127.0.0.1:41243/a2a/rest\",\u001b[K\r\n \"protocolBinding\": \"HTTP+JSON\",\u001b[K\r\n \"protocolVersion\": \"1.0\"\u001b[K\r\n }\u001b[K\r\n ],\u001b[K\r\n \"provider\": {\u001b[K\r\n \"url\": \"https://fast-agent.ai\",\u001b[K\r\n \"organization\": \"fast-agent\"\u001b[K\r\n },\u001b[K\r\n \"version\": \"0.7.12\",\u001b[K\r\n \"capabilities\": {\u001b[K\r\n \"streaming\": true,\u001b[K\r\n\u001b[K\r\ninteractive A2A JSON-RPC client\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;32r\u001b[32;1H\u001b[?25l\u001b[12d─────────────────────────────────────────────────────────────\u001b[32m───────────────────────────────────────────────────────────\u001b(B\u001b[m\u001b[1;1Hfast-agent A2A server ready\u001b[K\r\nmodel: codexresponses.gpt-5.4-mini\u001b[K\r\nMCP: https://hf.co/mcp\u001b[K\r\nlog: /tmp/a2a-real-llm-server.log\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[2B \"url\": \"http://127.0.0.1:41243/a2a/jsonrpc\",\u001b[K\r\n \"protocolBinding\": \"JSONRPC\",\u001b[K\r\n \"protocolVersion\": \"1.0\"\u001b[K\r\n },\u001b[K\r\n {\u001b[K\r\n \"url\": \"http://127.0.0.1:41243/a2a/rest\",\u001b[K\r\n \"protocolBinding\": \"HTTP+JSON\",\u001b[K\r\n \"protocolVersion\": \"1.0\"\u001b[K\r\n }\u001b[K\r\n ],\u001b[K\r\n \"provider\": {\u001b[K\r\n \"url\": \"https://fast-agent.ai\",\u001b[K\r\n \"organization\": \"fast-agent\"\u001b[K\r\n },\u001b[K\r\n \"version\": \"0.7.12\",\u001b[K\r\n \"capabilities\": {\u001b[K\r\n \"streaming\": true,\u001b[K\r\n\u001b[K\r\ninteractive A2A JSON-RPC client\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h"] +[0.576436, "o", "\u001b[?25l\u001b[12d─────────────────────────────────────────────────────────────\u001b[32m───────────────────────────────────────────────────────────\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[32;1H"] +[1.523996, "o", "\u001b[?25l"] +[1.643163, "o", "\u001b[?12l\u001b[?25h"] +[1.651248, "o", "\u001b[13;32r\u001b[1;1H\u001b[4S\u001b[28d\u001b[2mUse \u001b[32m'/'\u001b[39m for commands, \u001b[32m'!'\u001b[39m for shell. \u001b[32m'#'\u001b[39m to query, \u001b[32m'@'\u001b[39m to switch agents\r\nCTRL+T multiline, CTRL+Y copy last message, CTRL+E external editor.\u001b(B\u001b[m\u001b[K\r\n\u001b[2mCTRL+Space or Tab for path completion. Use \u001b[35m/\u001b[95mattach\u001b[39m, `^file:`, or `^url:` for attachments. F10 to clear.\u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[1.654661, "o", "\u001b[13;32r\u001b[32;1H\u001b[K❯\r\u001b[5S\u001b[4A\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[1;32r\u001b[27;3H"] +[1.658664, "o", "\u001b[13;32r\u001b[32;1H\n\u001b[K\u001b[30m\u001b[47m\u001b[7m \u001b[35m\u001b[40m a2a_remote[A2A] \u001b[30m\u001b[47m \u001b[100m ▲ \u001b[47m \u001b[42mhf-model-research\u001b[47m | 000 | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | fast-agent 0.7.12 \u001b[32;1H\u001b[1;32r\u001b[26;3H\u001b(B\u001b[m"] +[3.127208, "o", "Use the Hugging Face MCP server if available. Answer in markdown: what models are trending on Hugging Face right now?\r\nInclude concise bullets and mention any uncertainty."] +[3.130885, "o", "\u001b[26;1H❯ Use the Hugging Face MCP server if available. Answer in markdown: what models are trending on Hugging Face right now?\r\nInclude concise bullets and mention any uncertainty.\u001b[32;1H \u001b[K\u001b[27;53H"] +[3.131134, "o", "\u001b[13;32r\u001b[27;1H\u001b[J\u001b[A\u001b[K\u001b[1;32r\u001b[26;1H"] +[3.13133, "o", "\u001b[A"] +[3.131662, "o", "\u001b[?25l"] +[3.132647, "o", "\r\n"] +[3.132951, "o", "\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m \u001b[34ma2a_remote\u001b[39m \u001b[2m──────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[27;1H\u001b(B\u001b[m"] +[3.133658, "o", "Use the Hugging Face MCP server if available. Answer in markdown: what models are trending on Hugging Face right now? \r\nInclude concise bullets and mention any uncertainty.\r\n"] +[3.135369, "o", "\u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.135814, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.233021, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.333659, "o", "\r\u001b[K\u001b[34m▎\u001b[2m▶\u001b(B\u001b[m\u001b[34m Sending \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.363961, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.364466, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.435726, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.536464, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.637946, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.739535, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.842132, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[3.944595, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.04751, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.14976, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.251273, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.352838, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.454627, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.555196, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.657177, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.759326, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.861101, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[4.962693, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.064262, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.077852, "o", "\u001b[?7727h\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;32r\u001b[29;55H\u001b[?25l"] +[5.078327, "o", "\u001b[12;1H─────────────────────────────────────────────────────────────\u001b[32m───────────────────────────────────────────────────────────\u001b(B\u001b[m\u001b[1;1Hfast-agent A2A server ready\u001b[K\r\nmodel: codexresponses.gpt-5.4-mini\u001b[K\r\nMCP: https://hf.co/mcp\u001b[K\r\nlog: /tmp/a2a-real-llm-server.log\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[2B \"provider\": {\u001b[K\r\n \"url\": \"https://fast-agent.ai\",\u001b[K\r\n \"organization\": \"fast-agent\"\u001b[K\r\n },\u001b[K\r\n \"version\": \"0.7.12\",\u001b[K\r\n \"capabilities\": {\u001b[K\r\n \"streaming\": true,\u001b[K\r\n\u001b[K\r\ninteractive A2A JSON-RPC client\u001b[K\u001b[2m\r\nUse \u001b[32m'/'\u001b[39m for commands, \u001b[32m'!'\u001b[39m for shell. \u001b[32m'#'\u001b[39m to query, \u001b[32m'@'\u001b[39m to switch agents\u001b(B\u001b[m\u001b[K\u001b[2m\r\nCTRL+T multiline, CTRL+Y copy last message, CTRL+E external editor.\u001b(B\u001b[m\u001b[K\u001b[2m\r\nCTRL+Space or Tab for path completion. Use \u001b[35m/\u001b[95mattach\u001b[39m, `^file:`, or `^url:` for attachments. F10 to clear.\u001b(B\u001b[m\u001b[K\r\n\u001b[K\u001b[34m\r\n▎\u001b[2m▶\u001b(B\u001b[m \u001b[34ma2a_remote\u001b[39m \u001b[2m──────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b(B\u001b[m\u001b[27;1HUse the Hugging Face MCP server if available. Answer in markdown: what models are trending on Hugging Face right now? \u001b[K\r\nInclude concise bullets and mention any uncertainty.\u001b[K\u001b[37m\r\n▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[29;55H"] +[5.166327, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.268759, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.371287, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.473277, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.574318, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.67729, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.778088, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.879917, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[5.981723, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.083636, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.185365, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.287557, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.389484, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.490851, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.591307, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.693249, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.79348, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.895219, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[6.99585, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.097913, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.199735, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.302329, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.403473, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.504576, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.605069, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.705838, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.806409, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[7.909307, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.01064, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.112427, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.214289, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.315833, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.416458, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.518218, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.6189, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.72154, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.824324, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[8.926231, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.026645, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.128934, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.230088, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.331928, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.43245, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.533182, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.634504, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.737445, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠄\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.83751, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⡀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[9.93957, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⢀\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.040342, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠠\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.141221, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠐\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.242182, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠈\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.343214, "o", "\r\u001b[K\u001b[37m▎\u001b[2m•\u001b(B\u001b[m\u001b[37m Updated \u001b[32m⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.434606, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.43498, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠁\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.435459, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.435901, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.436433, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.437114, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.437557, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.437993, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.438436, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.438821, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.439349, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.439708, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.440196, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.440599, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.441089, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.441468, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.443559, "o", "\r\u001b[K\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[32m response ⠂\u001b[39m \u001b[34ma2a_remote\u001b[39m \u001b[37m\u001b[2m \u001b(B\u001b[m"] +[10.446937, "o", "\r\u001b[K\u001b[?12l\u001b[?25h"] +[10.447065, "o", "\u001b[?25l"] +[10.449357, "o", "\u001b[32m▎\u001b[2m◀\u001b(B\u001b[m\u001b[13;32r\u001b[32;1H\n\u001b[28;3H \u001b[32ma2a_remote\u001b[39m \u001b[2mA2A\u001b[30;1H\u001b(B\u001b[m\u001b[33m\u001b[4mTrending models on Hugging Face right now\u001b(B\u001b[m \u001b[32;1HBased on a live Hub search\u001b[K●\r\n\u001b[31;28H \r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[10.473681, "o", "\u001b[ABased on a live Hub search sorted by \u001b[1mtrending score\u001b(B\u001b[m at the time of my query, these are currently near● \r\n"] +[10.493251, "o", "\u001b[13;32r\u001b[32;1H\n\u001b[2ABased on a live Hub search sorted by \u001b[1mtrending score\u001b(B\u001b[m at the time of my query, these are currently near the top: \u001b[32;1H\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b(B\u001b[m**[bytedance-research/L●\r\n\u001b[31;28H \r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[10.511822, "o", "\u001b[A\u001b[1m • \u001b(B\u001b[m**[bytedance-research/Lance](https://hf.co/bytedance-research/L● \r\n"] +[10.529039, "o", "\u001b[A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multim● \r\n"] +[10.565659, "o", "\u001b[A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b(B\u001b[m**[NemoStation/Marlin●\u001b[13;32r\u001b[32;1H\n\u001b[31;26H \r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[10.581037, "o", "\u001b[2A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b(B\u001b[m**[NemoStation/Marlin-2● \r\n"] +[10.600694, "o", "\u001b[2A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m● \r\n"] +[10.621347, "o", "\u001b[2A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/c● \r\n"] +[10.643135, "o", "\u001b[2A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b(B\u001b[m**[meitu●\u001b[13;32r\u001b[32;1H\n\u001b[31;13H \r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[10.679775, "o", "\u001b[3A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b(B\u001b[m**[meituan-longcat/LongCat-Video-Avatar-1.5](https://hf.co/meituan-longcat● \r\n"] +[10.699712, "o", "\u001b[3A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b(B\u001b[m**[meituan-longcat/LongCat-Video-Avatar-1.5](https://hf.co/meituan-longcat/LongCat-Video-Avatar-1.5● \r\n"] +[10.718574, "o", "\u001b[3A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar● \r\n"] +[10.737952, "o", "\u001b[3A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b(B\u001b[m**[●\u001b[13;32r\u001b[32;1H\n\u001b[31;8H \r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[10.757963, "o", "\u001b[4A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b(B\u001b[m**[sapientinc/HRM-Text-1B](https● \r\n"] +[10.798746, "o", "\u001b[4A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m —● \r\n"] +[10.821085, "o", "\u001b[4A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b(B\u001b[m**[openbmb/MiniCP●\u001b[13;32r\u001b[32;1H\n\u001b[31;22H \r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[10.835477, "o", "\u001b[5A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b(B\u001b[m**[openbmb/MiniCPM5● \r\n"] +[10.869941, "o", "\u001b[5A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context● \r\n"] +[10.919711, "o", "\u001b[5A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b(B\u001b[m**[Supertone/supertonic-3](https://hf.co/Supertone●\u001b[13;32r\u001b[32;1H\n\u001b[31;55H \r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[10.939607, "o", "\u001b[6A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. -● \r\n"] +[10.960763, "o", "\u001b[6A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b(B\u001b[m**[HauhauCS/Qwen3.6-35B-A3●\u001b[13;32r\u001b[32;1H\n\u001b[31;31H \r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[10.985277, "o", "\u001b[7A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b(B\u001b[m**[HauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive](● \r\n"] +[11.056264, "o", "\u001b[7A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b(B\u001b[m**[CohereLabs●\u001b[13;32r\u001b[32;1H\n\u001b[31;18H \r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[11.123478, "o", "\u001b[8A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b(B\u001b[m**[CohereLabs/command-a-plus● \r\n"] +[11.187463, "o", "\u001b[8A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b(B\u001b[m**[CohereLabs/command-a-plus-05-2026-w4a● \r\n"] +[11.248955, "o", "\u001b[8A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b(B\u001b[m**[CohereLabs/command-a-plus-05-2026-w4a4](https://hf.co/CohereLabs/command-a-plus-05-2026-w● \r\n"] +[11.312543, "o", "\u001b[8A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m● \r\n"] +[11.378351, "o", "\u001b[8A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b(B\u001b[m**[SulphurAI/Sulphur-2-base](●\u001b[13;32r\u001b[32;1H\n\u001b[31;34H \r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[11.436153, "o", "\u001b[9A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b(B\u001b[m**[SulphurAI/Sulphur-2-base](https://hf.co/SulphurAI/Sulphur-● \r\n"] +[11.500605, "o", "\u001b[9A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b(B\u001b[m**●\u001b[13;32r\u001b[32;1H\n\u001b[31;7H \r\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[11.564845, "o", "\u001b[10A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b(B\u001b[m**[deepseek-ai/DeepSeek-V4-Pro](https://hf.co/de● \r\n"] +[11.626279, "o", "\u001b[10A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general● \r\n"] +[11.687321, "o", "\u001b[10A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m —\u001b[13;32r\u001b[1;1H\u001b[3S\u001b[28;33H general text-generation model. \u001b[30;1H\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \u001b[K\r\n\u001b[K\r\n\u001b[1m \u001b(B\u001b[m\u001b[K\u001b[1m• \u001b(B\u001b[mThis is a **● \u001b[1;32r\u001b[32;1H"] +[11.749654, "o", "\u001b[13A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general text-generation model. \u001b[30;1H\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \u001b[32;1H\u001b[1m • \u001b(B\u001b[mThis is a \u001b[1mlive snapshot\u001b(B\u001b[m, so “trending”● \r"] +[11.813091, "o", "\u001b[15dBased on a live Hub search sorted by \u001b[1mtrending score\u001b(B\u001b[m at the time of my query, these are currently near the top: \u001b[17;1H\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general text-generation model. \r\n\u001b[K\r\n\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \u001b[30;1H\u001b[1m • \u001b(B\u001b[mThis is a \u001b[1mlive snapshot\u001b(B\u001b[m, so “trending” can change quickly. \r\n\u001b[1m • \u001b(B\u001b[mHugging Face● \r\n\u001b[K\u001b[A"] +[11.87563, "o", "\u001b[14A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general text-generation model. \u001b[28;1H\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \u001b[30;1H\u001b[1m • \u001b(B\u001b[mThis is a \u001b[1mlive snapshot\u001b(B\u001b[m, so “trending” can change quickly. \r\n\u001b[1m • \u001b(B\u001b[mHugging Face trending is based on the Hub’s own● \r"] +[11.939569, "o", "\u001b[14A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general text-generation model. \u001b[28;1H\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \u001b[30;1H\u001b[1m • \u001b(B\u001b[mThis is a \u001b[1mlive snapshot\u001b(B\u001b[m, so “trending” can change quickly. \r\n\u001b[1m • \u001b(B\u001b[mHugging Face trending is based on the Hub’s own ranking signal, not a single universal popularity metric. -● \r"] +[12.002518, "o", "\u001b[15d\u001b[K\r\n\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general text-generation model. \r\n\u001b[K\r\n\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \r\n\u001b[K\r\n\u001b[1m • \u001b(B\u001b[mThis is a \u001b[1mlive snapshot\u001b(B\u001b[m, so “trending” can change quickly. \r\n\u001b[1m • \u001b(B\u001b[mHugging Face trending is based on the Hub’s own ranking signal, not a single universal popularity metric. \r\n\u001b[1m • \u001b(B\u001b[mSome models may● \r"] +[12.064367, "o", "\u001b[15A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general text-generation model. \u001b[27;1H\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \u001b[29;1H\u001b[1m • \u001b(B\u001b[mThis is a \u001b[1mlive snapshot\u001b(B\u001b[m, so “trending” can change quickly. \r\n\u001b[1m • \u001b(B\u001b[mHugging Face trending is based on the Hub’s own ranking signal, not a single universal popularity metric. \r\n\u001b[1m • \u001b(B\u001b[mSome models may trend due to \u001b[1mrecent releases\u001b(B\u001b[m, **● \r"] +[12.125296, "o", "\u001b[15A\u001b[1m • \u001b[94m\u001b[4mbytedance-research/Lance\u001b(B\u001b[m — multimodal any-to-any model; currently the highest trending score in this snapshot. \r\n\u001b[1m • \u001b[94m\u001b[4mNemoStation/Marlin-2B\u001b(B\u001b[m — video-text-to-text model focused on video understanding/captioning. \r\n\u001b[1m • \u001b[94m\u001b[4mmeituan-longcat/LongCat-Video-Avatar-1.5\u001b(B\u001b[m — audio-driven video/avatar generation. \r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general text-generation model. \u001b[27;1H\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \u001b[29;1H\u001b[1m • \u001b(B\u001b[mThis is a \u001b[1mlive snapshot\u001b(B\u001b[m, so “trending” can change quickly. \r\n\u001b[1m • \u001b(B\u001b[mHugging Face trending is based on the Hub’s own ranking signal, not a single universal popularity metric. \r\n\u001b[1m • \u001b(B\u001b[mSome models may trend due to \u001b[1mrecent releases\u001b(B\u001b[m, \u001b[1mdownload spikes\u001b(B\u001b[m, or \u001b[1mcommunity attention\u001b(B\u001b[m, so the● \r"] +[12.190698, "o", "\u001b[15dvideo/avatar generation. \r\n\u001b[K\r\n\u001b[1m • \u001b[94m\u001b[4msapientinc/HRM-Text-1B\u001b(B\u001b[m — text-generation model centered on hierarchical reasoning. \r\n\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general text-generation model. \r\n\u001b[K\r\n\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \u001b[27;1H\u001b[1m • \u001b(B\u001b[mThis is a \u001b[1mlive snapshot\u001b(B\u001b[m, so “trending” can change quickly. \r\n\u001b[1m • \u001b(B\u001b[mHugging Face trending is based on the Hub’s own ranking signal, not a single universal popularity metric. \r\n\u001b[1m • \u001b(B\u001b[mSome models may trend due to \u001b[1mrecent releases\u001b(B\u001b[m, \u001b[1mdownload spikes\u001b(B\u001b[m, or \u001b[1mcommunity attention\u001b(B\u001b[m, so the list may look \r\n\u001b[1m \u001b(B\u001b[mdifferent in a few minutes● \r\n\u001b[K"] +[12.253889, "o", "\u001b[15deasoning. \u001b[17;1H\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general text-generation model. \r\n\u001b[K\r\n\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \r\n\u001b[K\r\n\u001b[1m • \u001b(B\u001b[mThis is a \u001b[1mlive snapshot\u001b(B\u001b[m, so “trending” can change quickly. \r\n\u001b[1m • \u001b(B\u001b[mHugging Face trending is based on the Hub’s own ranking signal, not a single universal popularity metric. \r\n\u001b[1m • \u001b(B\u001b[mSome models may trend due to \u001b[1mrecent releases\u001b(B\u001b[m, \u001b[1mdownload spikes\u001b(B\u001b[m, or \u001b[1mcommunity attention\u001b(B\u001b[m, so the list may look \r\n\u001b[1m \u001b(B\u001b[mdifferent in a few minutes or hours. \r\n\u001b[K\r\nIf● \r"] +[12.313291, "o", "\u001b[14A\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general text-generation model. \u001b[24;1H\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \u001b[26;1H\u001b[1m • \u001b(B\u001b[mThis is a \u001b[1mlive snapshot\u001b(B\u001b[m, so “trending” can change quickly. \r\n\u001b[1m • \u001b(B\u001b[mHugging Face trending is based on the Hub’s own ranking signal, not a single universal popularity metric. \r\n\u001b[1m • \u001b(B\u001b[mSome models may trend due to \u001b[1mrecent releases\u001b(B\u001b[m, \u001b[1mdownload spikes\u001b(B\u001b[m, or \u001b[1mcommunity attention\u001b(B\u001b[m, so the list may look \r\n\u001b[1m \u001b(B\u001b[mdifferent in a few minutes or hours. \u001b[31;1HIf you want, I can also narrow this to \u001b[1monly text models\u001b(B\u001b[m,● \r"] +[12.375387, "o", "\u001b[14A\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general text-generation model. \u001b[24;1H\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \u001b[26;1H\u001b[1m • \u001b(B\u001b[mThis is a \u001b[1mlive snapshot\u001b(B\u001b[m, so “trending” can change quickly. \r\n\u001b[1m • \u001b(B\u001b[mHugging Face trending is based on the Hub’s own ranking signal, not a single universal popularity metric. \r\n\u001b[1m • \u001b(B\u001b[mSome models may trend due to \u001b[1mrecent releases\u001b(B\u001b[m, \u001b[1mdownload spikes\u001b(B\u001b[m, or \u001b[1mcommunity attention\u001b(B\u001b[m, so the list may look \r\n\u001b[1m \u001b(B\u001b[mdifferent in a few minutes or hours. \u001b[31;1HIf you want, I can also narrow this to \u001b[1monly text models\u001b(B\u001b[m, \u001b[1mopen-weight LLMs\u001b(B\u001b[m, or● \r"] +[12.436454, "o", "\u001b[14A\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general text-generation model. \u001b[24;1H\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \u001b[26;1H\u001b[1m • \u001b(B\u001b[mThis is a \u001b[1mlive snapshot\u001b(B\u001b[m, so “trending” can change quickly. \r\n\u001b[1m • \u001b(B\u001b[mHugging Face trending is based on the Hub’s own ranking signal, not a single universal popularity metric. \r\n\u001b[1m • \u001b(B\u001b[mSome models may trend due to \u001b[1mrecent releases\u001b(B\u001b[m, \u001b[1mdownload spikes\u001b(B\u001b[m, or \u001b[1mcommunity attention\u001b(B\u001b[m, so the list may look \r\n\u001b[1m \u001b(B\u001b[mdifferent in a few minutes or hours. \u001b[31;1HIf you want, I can also narrow this to \u001b[1monly text models\u001b(B\u001b[m, \u001b[1mopen-weight LLMs\u001b(B\u001b[m, or **the top 10 by● \r"] +[12.501122, "o", "\u001b[14A\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general text-generation model. \u001b[24;1H\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \u001b[26;1H\u001b[1m • \u001b(B\u001b[mThis is a \u001b[1mlive snapshot\u001b(B\u001b[m, so “trending” can change quickly. \r\n\u001b[1m • \u001b(B\u001b[mHugging Face trending is based on the Hub’s own ranking signal, not a single universal popularity metric. \r\n\u001b[1m • \u001b(B\u001b[mSome models may trend due to \u001b[1mrecent releases\u001b(B\u001b[m, \u001b[1mdownload spikes\u001b(B\u001b[m, or \u001b[1mcommunity attention\u001b(B\u001b[m, so the list may look \r\n\u001b[1m \u001b(B\u001b[mdifferent in a few minutes or hours. \u001b[31;1HIf you want, I can also narrow this to \u001b[1monly text models\u001b(B\u001b[m, \u001b[1mopen-weight LLMs\u001b(B\u001b[m, or \u001b[1mthe top 10 by downloads/likes\u001b(B\u001b[m instead.● \r"] +[12.503646, "o", "\u001b[14A\u001b[1m • \u001b[94m\u001b[4mopenbmb/MiniCPM5-1B\u001b(B\u001b[m — small long-context / tool-calling text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSupertone/supertonic-3\u001b(B\u001b[m — multilingual text-to-speech model. \r\n\u001b[1m • \u001b[94m\u001b[4mHauhauCS/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive\u001b(B\u001b[m — multimodal Qwen-based model. \r\n\u001b[1m • \u001b[94m\u001b[4mCohereLabs/command-a-plus-05-2026-w4a4\u001b(B\u001b[m — multimodal image-text-to-text model. \r\n\u001b[1m • \u001b[94m\u001b[4mSulphurAI/Sulphur-2-base\u001b(B\u001b[m — text-to-video model. \r\n\u001b[1m • \u001b[94m\u001b[4mdeepseek-ai/DeepSeek-V4-Pro\u001b(B\u001b[m — general text-generation model. \u001b[24;1H\u001b[33m\u001b[1mUncertainty\u001b(B\u001b[m \u001b[26;1H\u001b[1m • \u001b(B\u001b[mThis is a \u001b[1mlive snapshot\u001b(B\u001b[m, so “trending” can change quickly. \r\n\u001b[1m • \u001b(B\u001b[mHugging Face trending is based on the Hub’s own ranking signal, not a single universal popularity metric. \r\n\u001b[1m • \u001b(B\u001b[mSome models may trend due to \u001b[1mrecent releases\u001b(B\u001b[m, \u001b[1mdownload spikes\u001b(B\u001b[m, or \u001b[1mcommunity attention\u001b(B\u001b[m, so the list may look \r\n\u001b[1m \u001b(B\u001b[mdifferent in a few minutes or hours. \u001b[31;1HIf you want, I can also narrow this to \u001b[1monly text models\u001b(B\u001b[m, \u001b[1mopen-weight LLMs\u001b(B\u001b[m, or \u001b[1mthe top 10 by downloads/likes\u001b(B\u001b[m instead. \r\n\u001b[?12l\u001b[?25h\u001b[13;32r\u001b[32;1H\n\u001b[K\u001b[1;32r\u001b[32;1H"] +[12.509875, "o", "\u001b[13;32r\u001b[32;1H\u001b[K❯\r\u001b[5S\u001b[4A\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[1;32r\u001b[27;3H"] +[12.513589, "o", "\u001b[13;32r\u001b[32;1H\n\u001b[K\u001b[30m\u001b[47m\u001b[7m \u001b[35m\u001b[40m a2a_remote[A2A] \u001b[30m\u001b[47m \u001b[100m ▲ \u001b[47m \u001b[42mhf-model-research\u001b[47m | 001 | \u001b[32m\u001b[40m NRML \u001b[30m\u001b[47m | fast-agent 0.7.12 \u001b[32;1H\u001b[1;32r\u001b[26;3H\u001b(B\u001b[m"] +[73.109057, "o", "\r❯ /exit\u001b[32;1H \u001b[K\u001b[26;8H"] +[73.109361, "o", "\u001b[13;32r\u001b[27;1H\u001b[J\u001b[A\u001b[K\u001b[1;32r\u001b[26;1H"] +[73.110378, "o", "\u001b[2m❯ \u001b[35m/\u001b[95mexit\r\n\u001b(B\u001b[m"] +[73.111632, "o", "\r\n\u001b[31m\u001b[1mUser requested exit:\r\n\u001b(B\u001b[mUser requested to exit fast-agent session\r\n"] +[73.427316, "o", "\u001b[?25l\u001b[Hfast-agent A2A server ready\u001b[K\r\nmodel: codexresponses.gpt-5.4-mini\u001b[K\r\nMCP: https://hf.co/mcp\u001b[K\r\nlog: /tmp/a2a-real-llm-server.log\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[?12l\u001b[?25h\u001b[6d"] +[73.681045, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] diff --git a/docs/docs/assets/social/a2a/host-on-hf.png b/docs/docs/assets/social/a2a/host-on-hf.png new file mode 100644 index 0000000000000000000000000000000000000000..f5a59710326d7ef4fbff589faecd649610cb64aa GIT binary patch literal 27120 zcmZsC1z40p_b(Pwi!{>R3(`nScf+zEwR9uhU@TqI4I&K-EG?}|w{(LdT}mnKeZlYh z-}~HqdERH2XJ+0rr{>IW&YX?VR966Dkz=8up@EbXWwp`J9wO1u?t5W809t%u^w(VR!O7pByWiJ0zc0>?cFoN7^mg{NBAS|7n`#T2YSTK)+)oS8 zz89eNr^;5=l_E;>qNM~cf#1!AVcVJ5<5q5?5d;V@C+FyZ4eQsFUDf*2`r7%6ZV zC_xOAI1CgZ1_~T{3J^WeLXJaE4x$G>$#7`M$>=CRbmSmfau6K_4jnlTEjjRsO-F`9 zO9r9^29SYhfX}BmGz7R$$e&S@fvBH?sDOtQL`e#w06s}T6eJ*W5)d^R4)s$Us;4;A zq&QT-LxMv|ibF|)LqUo|L4rdLJj8?)#2|8F5E<|g0sr6-6OlY60+A8|4-PQ_h=c%# z2p>d<4s+NIQTEY1HF%GJ&YQ~%YWZtF76suiXxW?MZP$xb5m-R>l?jy|?tIgQ90=OKrCWxSjDqIxQo1Fj^|R;1c)A<3_ih;4S$ z*@8l!nx64*zh+E_9qx^gAd-i59~l+aPqkC$*O-Abku3Vqd^||Cgux5BX{%%o&V2Xi zYQr~yk%37ALdC_uW@ZNMM_;pZJ{>fX1$6ZY#lBPigU}+Sq`yAPccpQyBayW{&2dD& z8lBr!Z`y!6)-L+h(UM}4<*aBKk?AKri|-r z6Stv3v2T_0EwESBjVQyc)=PFi-M8&PszX}jaWM?6zCZ=(V;9`ZbfM^`RMa=ptRHBM zZHWJ#4w7Z-ef9U9_!+|Yoj6`^8q)H(rA0K_2{*V}=04{wv(}D%#1K4G&1$)6&4v~t zxwunXe}8i$MdJX>@g*a@CUORvG@%#jN*hyDQfAWTm#pq$tyCP*v^D$dg#{R6kmMmC z>|@jb1Hv))FN@yfy)aRgpSZ@hh1_JNri;hnEZ^?qLT(M;H5YqJTc0@y?!66?=P!Qu^Yf$t3+)1bc2fB zd5($hQT$X51`9OTvY*^lZ78ztx88%jh(Pvjd%@4TPaKO7SOdzS%gMCJT=rqe*la>J zze7V|_hbM)b!K)1`_PCQ%SLI9;_lvd^dp#_WExwONJt?j(res~fLRlpld}rp!u!Z- zKmTO@0lA4&;p;U?wER6wpu6#?~+&Q)J~ow0g}$jT4F*n>`7LB;OT~24}jmdKaz5TVRyG zK;QjEx>N4iEnP~aHEr!@qffSOb;)%&^}GBudA)m5`p7_xB&xfZP}ZR9)%HwP{WjI^ z`zLM7LG?{d&1Db0QBb*LEBn$m-Wq@8;19NpN<#w!;}x?MV^afFrXPHH5tsSR!5$WG zH2G8dcu3$@kImg=5KI^x!LQ{e7A1c=5}0x_uDVw@`6R?z3VQPBK)CEkG{kbFBv80Khkqi`JsSC zbu7j^-w*Nc2pV?L=wB|W8LX<%l4W{cwPsELRUMYh&CJgBPcfn;fo_sjzk7EbSbKq? z_R7=eLlb8xw!FJT^z+w-J|j=qah(tsFP{@91j=Qro6u^|CcDKI(By~gHmzvRW9b@Ls4Fe(3spVpKU4y77 z?EX1L+FWFhG-H?H(qhq3Z`xOR#T+(YO4I;_89r>^*#!Y+{%HI$(-@@Q-LGiP(B_UT z--!f8^nG@vBRO9grrCxIw7sZ>X6}t7d79+Zw^vJvwvg9pK5}$KR882wI@-7ZmJH=^ zL!z-ndc-T(IX#$39(OpY5VOXO3%zU|FLSTV_yB*7u76H*>+*!1(S1jd|7{ zv$A>|4`KqN;)NBi>g=Sw;^$9fq)X{j*)La(oNI7BV@U=i;+qBi=;NNAJCn`qPvl zPA@>v_N#>YeJ)(KOrV>IFSY75Zw&3Jb*o(PEIKOiG23uH>*S+ z*JJIz_`cH6pHEz2zM-KsV$rfW64_XfLeY;f9nAPCH8?AzpbaudA5VcTUjnwT19M9F zYRCRckBkskLzd7{)%HZsP0(Xy&~v@T-Nww!mJu&9oj^5hi~98=Wpl?O3T| z_~(@@n=dN%5)vv5M0(H%G8SJ-=QgkG>7JP^4OU1L6C>;(Uqonf{V!w=@Kd|-8FXMM zT}FcJm~KKcQB(zD87H2TpGqpG82L!uSb~0GJ z`OJE590Ut7$5!Fk-e01^7&KAj>dpv39u**MCBiWrc*xGRsR)C3DYLRoEgzv98C=;f zqZTK-e%YWnji44^`c$(ZOq}4Mjx+{b4E3-6I?QkL`oJ7g#@2^8huVy?%gvHrxvgZ8 z?}Z2%*9_9)geYB(!w<8eElK56@QPksG$OJRH%|I(Nl_+;J<@a^cvfb)00a2!n>piA2v@! zn56|c9w;Tq8n0=-fw`5HA^V%$urM50pO<5)P!UQ)z0B%JY?LK#)>gaye-lsV;Z5(x zBzK<|=fSL0X9Z4Zd9w`-R|4d!&L+rox2RY>P6W$hmu2As_z?-O>|k_CKZ`OkK2dRQ zO4>U*d;3LTSS!6kNmq5P^!c0E_`5R<1`3PI((qMpvrJTzH4d&b{=$ws>B!Iet&il0Jr~tF%oTXML@Ab^o^6c#DNkT_(!$c05NEbsVKOnF61(1l9AB@=?GEzk9IX~c>95QiLiZvUc26$GQAW11``$tdC`;B_ zW%#L||E0hmJ$4?IS~c$z6c$pGJv~7FZHn2S^Sy4Fu;91n?>;&D2~wWy*f(Z~ci~q< z9j$k+6pEg2&VeMWlB1GZBO^(}kB-g?yF)g|kP64=Bs65XZvH(s^ishsNAfMfucw+C z-n(ZRE1ghM9Pkd|xjF9my)h8&MX;?jXz zkZk(U?==CXnWk}L7WL(`S!p^y|1vPs_-uKJAJ{^MKq4@TLnZe@f%!?le z^in@)HDcrY@SMDu$@@8gXxOXl!oietbwpE5!kN5zZ#pqu1BC0k!U9`bJU(0bn1|_- zFK;Ccwd5ubBnJhb7LL9u%R!?m8o}Gdg4qRbP-6!XV=71&6GC(`0N`FjmOxsu!q%yO zah@2J+TMpxqLso8kqq{Yq1bKn`Ezk^pY@S?jziW_hXr z$qONcjskt`Bh1}cJy@yt<_mPM7jA42VQb}^H_;d?+aaD#o>4v#DqC9(Een4?%`6R1 z7{w{oow5afpt<)j6B42=!LABFv7rJHsMm8r#!@+c~wag_bk z`ia|S*;H~TEhD=yR`bH$qINa%I5$Y?N($j&iU}PNYAi9l2KY`6*^hZsn!iv^@?2ITD%lL*d5Xd z$d_uoB=OxoA?Dc+W!d_=9e7UBPl!_h2$Dna{4Kel>A zkF9`6#F^~VH8TZ|L(>* zJ@qhlL*=2@$|Z%dq%K+4l*;r7W04Nk9Ro|SDDxGV`&6vHHNJrs!N!h2%1r9;Vuw5Y zjm^_4i_?-!eH`py_PWDyGnay9EJa|E>?t`G+>Vnyq8Kvc6N0+JHu-yQo--`cTGQNI z)B2odGuJhW!Ry#@>g(67>*}#QXCB$f91!vJ*I&QhV<5Zyy+19C95`rYc@0{zJ z*}mZHZl;MXPMOh#agJyb3;!j<^to@*Nu5oHj((TjNXJkhz^X{-xH;ob zN5JJ)Xnj@&NT+d$r_Jf5;e{#YF>)Iv$Z_y?d&5xTfpxyn=+F@OaHNZMySYr9=s~!)hhYZdfZ~>DC^nQ|mEe<%p&x4VlLSkMlg30pDMy)m zZwwv2S-D`(e&+J!)qZt)yV6fO)h^VJd`3p?xITq9OG8Qzzy%R6z%A|-z!g#(0tBIjD^EN^XIEea4SUm)FCDbiBptIQ96uOhj#R1 zmGdY-C2pi@ym`Jdq9Vm&YHT%|&V6mSq__z%!%AJSF?WUGRxcSxlUnu1pB+m!HLho^ zv46jms`~qR(VW)}x_j;p73(rAa*t8pl6PTjr`H-!WEl;L4xKA_^gtpm(^Q#oW?Zq6 zx-B@^16tAP=;-yS)lpRu2Tx^alqGjmzUL=9ikuvKSS+voMTGH5M!x(- zZz;Rwy}`I<*GP@MNJBNA{8FIdljM(D-k}L4n;?u>)?*mx5vrOo6U4z;R0X5ZIq}RMUb&BveE_41}Equs||cj{#KiMv;Yg z%Xz5&b*g88IXE|O=cqLd4%PT^@?+GxFHLjL!zXKaMAZgOtz+J(xYwg$YwOz|om%|7 z-h!Pve$>&#;M=+`ehx$_G{BGRBAFeLm-oyrKv=~EBMfOze7j4y6|Mbkwr52RV5zkI z`eTip$^L7Cs%WS7Zu~Qn9-w!l?A?Hct6?#Qr{X#I)s~e!cXN=t3($z~5cmaL4qLdR zRZ?t?2d-Q>W|p)>k(~yT{EFcaJ2LSi@HFz7cJnXB-$}#yaxCHLf%F@}iX(D8ZPp6> z7!IGCk)dH>Q#I(4hmPEegHJypL*>JfIV`IhGJon(84=x^kyzMD-V_YJV;9;ZNmoBD zWucEa4X6Dvw=+%+EXFXa>EG;aaUKczb;m-ydWw1i#oFz?{h#CNL4SPts*gbXva&y^ zJSa*XQQc2z4%=6^K=fo|aby=Y-2e%;s1ET!@(3|KoB5XoQ8Ti#S~gK`vNo~Ek>e`~ zwZY&d25?;LvdPNUR*B&gDY(EPvG8t-OeC_zc-v|54FY)(7L*nJWRmqGeR(WLe2&!Dg6U zP!_59nOI~!>2@hV0( zR|51{0i70+VMPMuPSTN)!(mJi;=K7Ylr=f`sBoX@3*g%^k;~TaT0s-b4$4=o~ zl#+*yeXyq$9i){kVrj(PZT_OqKb1l}z4Z7CcUzbt{xqxjjOA)?=^;!H+WDs=QdLbZ zd%X`kIq5gV_Abf zps+$^@-XF~56CmmWwe+PKK#!=S|2?S{-oA14?0S)Z zgHD0}yc(rd`1`Yu11@P&(Lv63WUoG#+y;(4(=gv*!RaM&NqFFt#}Y~X2;g0b#;FTH1DfE z;U7;F!GM{wGAE<8v_%;*w6xlm+`;o5XUmm+rjoY{7^hc!k-V^CB^bltz>8(t&^aDe0?%a|!_C)% z%v!(E6XB)om-eS8II(~o$~Oucz4;w$T`ksBzNbW#K5xtEjTE(!HWBzp_Ep{e8`VeD zMG`UN^IFeeVv2`hHUu6cPcuA!LS{zDap5*OQC*k6cV`?uZIbovL_~S3CmJX@$t?4}`-XNJBg8Bpm7L z-$%0zW;LC+jpkce$b^K1U|#LT0BfWZFGUO5Jd%3CSf&Y?k0G` zHuE5N+nDMdKCqd=2s`LTi=Xa_Wd5yn1*@Vbdk|-yP3oKQ1dF^3XHg~mIk-!)Jrgh& zVN7iJMoNWSd$fp|JUO0fr992OD$~%?5}Ix*pU!aJYTXb@SIpIQS!CYGcB5gNsM1!hWHC)JS8bMq&3uV{J zbS))Mt~uu#p&Pp|8ZB`v$nwb=$$0MBGUP(POn_r&)r!AexHX+^a=Vm`~@aap< zK8_4bXfq=ejElp9#e@Nw&@shV(b&5;`WnS^Sg?q>uh9IUbq7-z3^qlXsq>DHX+axm zV6jgKt9Xy0!igdWjWR016RlHM_4HbU>Z@DRqSY{AV{c2>>rX*`e^t!|_ihv=_mPUt ziFta@2@W%fz67sfid&_UZ4>;8{~+^s!$qeqGZS$n7oEI846`pRI|yH*AC%mfQFY&I zFU4~3*t^+6s$^FiWDn2LWT)rtCSk%JZGV&qj*?~mgk+}YF>x1^6e9K@i?YD3Qh6Td ziRq-aKb+*~4!cId>(j!^8rL7rUGq?E8#}#nM>f_rH7oYWN<+H@Rrq;wtdH9i-d@;! zeR=kN=#uGBkDq{-P1!qQ?E*{fZFjW#C8tW>VRG)D8WjmXi!n<>_CtO|hi7#74YRTi7vPm+ty&(q~4i6;@w_OZE@CmBBYQSdGw9uc(>PhZ~% z64+Jc`9st=;tB^gM+j_%RWeX=7?loe-^nE*Z9UcyE*EOg_}P!iBM&Re*GZ!10nWUHJM;?3aiKclgU8&we4?ThFmDTgW8ARJjVU77m@qxP2QEk3-pFN<^+r){Yg#7pF2Tk2 zVv&bbHwGyLp0!IaIo0JT8*EX~c&2??)!^-2t=nd7P+6azu+Ius3qKvCBc9e)Cd2pQ zNkkNR<5=)yWEM}bV8FB%5QMNcWtW-=O4JtI*73)X*9JCJ$Gthz$Mz$@Ti>3&JH3*{qK7`h~@8I8;zW9`hn=T z8EjRCThdebBDwCYADZe91H4%Y{H1<&s`uE0AkVPIfeRiZXf-3*-%3P9#n}4GZQiJ1 zk`Mv%92L%rw)wf?A|x%ih0c5IB4ISi(FI0D2&4KsXGP*-vbk7rs<*r20~V#tx8N}c zOJ>*3UM>&~x;Y(N?QNHEk!Sq!&EmvO-JEzq`^|=sJXj<(EmuPeUks$-lNFnilHz64 zD1;X+8?0J1yE-E4Q|@7~EzIkNbJ1$fY?3xvg$GW~qPS;#B zK3@M^@GpZ#?c=L@R;#7O4~c@3xl9ZruT9e%=QLWOFQCt~RVb>Uyqd#JGQeeIbAz>V zLkAK!czLd%>8ES}m!ME~0U;3w=FdP7e;2*;$3MRdx5T=;1Q%LACXrYSOUB7{Bd{E; zL;8|F8Kj?HKFpRAe$FGME69V-9O~1fTwx1mj;?lywu ziaaXk=i)@^t2C_{r=h~=IltjIeW1a+}HydhLE=>mHDjzSdU{SO%*cT zr?i!a;LY6N%gL^M zUc5ZW5Y*bbNckG%^E|)@1a>adCcD}q+Q#-l1BF!u*wO@s)uE%U119A?-Wm+dU|E9 z4vh1{tYRuf+N#^zYlbv6Qu>qGqk=L?pRGkxHXna4oJGw4zvyTT=VIjv8kC(x5Nz!UKys=A@HW|E;OsdM}ZU%uG+$^c`b^4nIX z&&pfrE~zP#iQk*&*Cu4}6o93FNiq>o6CQJ__L~^W+PBs`Jg;@18igv=p5c|TE>={w-D!t#D9{C{hD9&e5 zW6ol{U#$kFw%koLygpz8A?uPyPZVGj3Kg-yC*F4@y;hZ`7&cSoz;36SJ9<5%Kvlx@ zM3=UXSw-rTOJ*;V(IX0!!ih2c!zu68X3;WMhZC7uM zCFJr%x~FYvc}3e^RCzg1czmOihyN}N1!7DUlK&m*M=(3Ph*{C|t8VV6I%n&o#-Ecb zHpKASGDQ{AjieUEvOT9cdSd0#{O3k%sjja0{QF10&pyPrq+(ZC9HWj`llr?uTrTky zyS$s!{P;T}!ggn>+)1yjYWtk>>4D)QU;E@$#$fWNc(rM{D*bVe0@Gz0Dk|!BQ86(Q z5fKuM(2vz!_c>S=7Gz#qxx_kH7g@f<=Aba&);&>?Fh0cXUDj(5)-A8Yxy~G|{EV*E zvXj{|H`|RA-v8R_BQ1`3{KKIqBShkC+A2a<}(<8rk<`+|f*!f;b zrL1)}3g29S1P(%iLuo% zky-9hcHTroErAnD`1VPsWLHl3K$Vko`BH#Qb4RYb;eh_+(uB|FPSKBG*EZfmM(W(m zsP2u84U<;InpMt&a`BidTJTGH;1p|sF*pQe=`u2eaL>~|w$Sb67WNpSi;&sU>*c2) zVzv#mO}he03&b~*P4@=YMn(>tmvsh$wL>Z3(4_99dZpz0x)P&DdX*BDNCTaSD%{_| z)d7QV(V7f~ioi5kl9h8sV1CPQch;?kIxoqxt?b|L1>iciQ4ySov3wsfx@uz8UBXKy zvMv*;Q~w>VY9Q)?*QrgymwAIn-rmuBM*%lCbOCzUz*V2&Yh*OJrrvvjiK-6kK-c?D$@kYE zBIMxcc2v~A47O_bEIB%G8bow<)cNqHk|8B_HG$cH#V%`}H4<^4!O}Sfbs_Vh(}k27 zNJow(Ub#ETOJ}Xx`B?3X(nLMBNn&bzETk+Nioi%l zTCQui(sVP!CAlqUH3B3aW!Jlyw76oJPT>MNij#q!tDfvC5qldtUGve%X-JFza*bCU zywYCpA7veF9MU(+6JF*C&|~Q1>@G`APoP+%mQZ-v-K7Tw?x0JBcQ6zGl8kQ8P!4tE zmD0H5hF&FK#{+B-!1dIfh}ZRX)B|Q)GwPVj@7pA?C4H`4Q&@rld)#eK1p}_f>|&6g z)H_6BZ-9wV_mQ_|LRgQF(`@UX4ctUq6s^q@r0DA8fD<9#luPP=WPdaJ3$L<&0N~_e zTEu+P^jsOU@*W~sT3_HDaAJCg2N_l#+}W3~5jW(K$uW-p5DDlbkQ`N}X16}2$R=Gb zrf_Mqj6-&#Y#+)rl!OCIo-o+(rbvGF#%tV-*Njh|TZb2}w-F7A&x}#_Y2Bk!@uwrw z1-af0)ibnWEkHZHP4L;!fze)ju5lTfV)HS{K+$w@0FGuptM&uch{U(I>;kuh9=%w9 zFQ#+Ebz69dW33#DL_>nY(%8sQ_dg5XCf^?bwUJP3&>e+Y^!~eVv|YyaQ0O2)=QHnZ zO^)QzTTWYV3|4q;!1xz5AdrRj-jaiW;P$9WM3n=rhz;T52-$dAeVH;2XF(mKC zHVwXIB6d-3*Gc@2v%+|zNUP2C1V9k>+jH^0*j;mX#6N;906{;BQ9wiYG+krYxeQ%? z{2Mz;`5*eb{}H4wo6VQ#RuBb%tA^}bu3p?1{ohh9SKi6h_X6nl`qz#AUnLBg-*FF2 zR`;4J?L-yVR zx=OsYj>vz;3|ahFhOvvM|D$BVJA)Z9rkc+=-1Rr@4I0-4Vf|N8E&mJ*@HlnHTTT4S zNUQR@DJ&EJnc3^s%oBH0{m>2(zygYD5x|=9qZq!^Pqz4fQ~-FPWa|^47kt}$dDp7> z=s%L-rBayh--u}U}(;onKO26|S@_*3+P+K%0)+SJ9d*{@WZh&rY$rY_J0nTNX zF4M%vq;S{E_{^~5@oi^q=z=@Y;`nYcJ)!q*H6#GVYy7tgh+a!iAiU#SYBA>lU?tMq zwEg}6a0u)`07{>oxuMVh-nY3->>Vp`oY?!lxe%|j6i-2g zn-$M(tz5|j^EHYlNP`_2@r-`bd+9oV-90oDdxJg_4k%Qg7Ll-ucc_jzIioqtcawt7 zpq4|w;Slf+_wmT>WtIgVBpHiC^gZ9{kfqK$%mdU$ZMWuAU7=ff*u~!Si7urMTesUk z-(<6uV66U}{snLq$oDr{={EBeM_*rl4Nx?H!*{D0HjHxi5GHiDn2j9Qax8nVPh!qC zg1J)(783ihqbC{DM!u>c-7mi{YA8eYCY2EM zF-gRbI4>C%KW|QYK*6?w*bd|I{yI6;S2c}es)n1lIV-n%(GR0LSZ0uJvQCN%5f zbzx-lALrr@jQv#yfePo2oDhLIqbm|p)BL6g%5{R2r+vPDcOm^8Vm<*La@Q9YSs1^{*B{o zi3qE_c-hP}rwA$7K3x-$L$Pzn`XKJl#bu@3-YH9hr>x%OjjR^59T{&n=pZgpZ_ffP zqEd2nijb7)gg!+};LS>bTvn=j?oa&Yh4EcgTL#a?+fz-vv855@)}(w)sVdMSpO|Wy z+M`URVhNvdj~?qpi9K%0I(|>6dJJd-uaYOcQB#9~C5lgr-i_u0TRgi@!Wa4db!A-m_9T03fEx1TS{ z4gdDVe)&W^2YD%SY~g4yYbHO=-^k98nh?=C2aI8>E3SBve?F8M&-7y5*PzJ?KWYC z22VDHGWXCw;Py_3Cnwh0gTJLCs{D@9NA1K!N#T!1Vu9c$M2EOS4V(=*|8@GEA_Gli zX=2hkO-?61vN|-R1;6qFc9PuJNG#wE@=%1F6a3QfKJ1hq`bTwIzmhQRC;V=*+oh+4 zQT_qBMZu-uej`k!%mlVE8C@F!ue-2&ymK`<&gPDI1iPnmyDi;^5#y6Qu@|eHE^6(p zBfu!1tFghlWbZgvPwRS%d@T%^E>0Q>fp`B}%Z&K8hdSDkL;OTIZQ4lOb_oBD?Ni(OaSn&wi-m`k-(UUctoOJMN`TY%1?~is-oB{y64ZGb` zt8d^|tqkgygYJ(~9k@-KiXNf}6kHCbzVS9)e@d$&Iu@|^UK3U$7}REvf}Vy0u~g=i z1)Mq;t+rpJ!b%|nK2FCN;X+swVxPN<>rCozG@=P+n-gfN#5{yeF#z{bD3n{KW!`nn zMUKSws!s*Rpq-o-L>roe%3(X;a2FC*kMF7(SHy!D*8sohIQC=#uQXjH+BM?@RvR~Z z$DOZvj1a2+*5?ipF!;*%>}BM|z+%9G4r8_Y?K^?D_N;CuOlkIzIq+DY^YDx6Z+kWn zow><895@kRXptVr7L#Mg+5Y)m(|JI#lDUB$BStyb?SA67ggKb#E%j7kB@7KB{Kxkg6FQkN7{{G_?Y54yBb{-u(ry;I<6O;AFU=(i~eW|c(oE}Vgs7xGFQXt1( zc;n-(Vb}n0zFaN|i?{9KUUgktPWo{XT;gSaRJCB|$0LK^ z#MB7NeQq5m5^$Ve2L<5l{tvK(TvX5euon2~99O0O*VWLLQPTz}{1!H@0-#jZTZ{jI zL-SAKkAdR`7vQMvk$2#>Bxr3UNeufI1o1rse&`_cUofRVdWS>>X&LpPuse*_UkDYw z!>O0R{UgbL(IL(4&$^}o4+yOPHwiXCkTUGHQR#ml9xmALAm(T4Xcc0}|C|q|{=s$e z+f$h*P(eM2%JAS95)`mFGSg&`Ex_WyfF+Zf=6I^#L$asp# zzD2$$yvJZLHHhRlY8390q_ZG2Y!=_@8 znyybqMqoe}4onLAS$^{JR!Q(jj&K0v3ef`dpzZbnz@8j6&NH{`)g<1IqBs|G){mPp z{Ya8_;%9U~?Q$OLB@H|G_qU}Wa+aWRD$ZH%e=B~$>q{(+k#WY4ycc)FlP z-2Y;@vR{m%l&Kn|7AxlVM>we?1tJZBeO}k9ox0=HJ(wxKA7 ztSN?S%)1DKV>4~|S$(E~u;Dg*U4WC@X}VW~YvM>p#&(N)0e#}Bxgr$1d{Z|D>E@r# zq5y60$+`(B!Wh&-?!FW;?1u}a7t^-OwPK%G~hKDnreIId}H{usA+v9F5o!WM^<6XcYLl-bS5VF4VYs z@|5}WeL|XjRa6F1{;Wyj6F~~Y7Oj`M>pVse1K11~Yzgv6cr$~RW~Kax{F;t&Q1$`~vw`#Zz}Z20NMBRbd4hM0gh+4_9sAT6uIGsw zClw-h4uYUNHQRg4kR=>6n~2-tO-IB*ykMt>=kEzoWmaok#{xwClcC5FlQ2&ROaP(_ zU5`WtI4h{=s0Uu#!L4xNR_=m3mkpE{SQbk@XjXb`ILL$mYzFL4oaJH2*Rifm?HL1;VMwDUogeGV%ro{ita5Qu z&^GJzv?4dm-7W>uDC7`BY z#KQVFg<qDzmvoQu&-e=~z39V&bfBG7oA4@R$ z+z<+75uZ1JTM5#SjPzL%rLC-qieQDnBuF1ey;yiU=gv?y6NQ`l5NBn7}I4=?yo7&nLn-JD87KgX`pFQ5M zi9K<4?M5yPTvYQpf&K0bqcd?xld{rWlEyzwPxRbW(C6LvzGgCjT}C2%IH})BFLH7U zmv7hxtxLW^f+;I>QAg{D$nQ-1W0sVxJCNc2v%tB9!ffF%2U`MtVP<3Das#wWI=~Fs z7x<9&WbyhawzSHtMI(>(P5InjZbc3she+*COEoA-EQB3q_ffcb;fJeedIqIDY~46j zQxt6yp)$MbA!3M3uveq?eRJ`uC>DM?9zg$AKJZaN$K32=_mE`QTt0-)qD8o`G8F`q&vAbqSW0o+%Y9=+^?9!Y}-RXBxwCu4w_5|u^yj<_T2ANa?)@=tK}Hj{k>eU zKQ_l@1gvUtAOsg0C<=<2jS#2ISvLs@G-g~3#F@BQB(S2&J|Ow~zoT1Rza^0DJtM<96*dKRCp^X}~wDlydM7krskH2DxDsAGy6 zuoMfumpd2`me}T;x={RcTR8Iq*hPO91ijZ~h7k)JVun~fKQ79NE=BSNj?_1#4psHRqLyCqP$r{oUjpwF0nY7R)V7wz+8Sf*mTSrqzvdgQg)z^v7D%13vXWQZ!37{9y_gS3V7RTcM*jNutMr z=+E*GR{O=Du0CbJ%=TvRhMxS*o*?yRuXSTlQo;Z=2n{&- zXwnS7fEJ~34bK$hMvh!<5b39nl+-9Z_#7RR*CI>dJ*Q!pTj5lHAC~Ia}O!ikcLgGxWgQQvcj7D1w02gp6yV69suz zhExJXC`(e?NRAJtV(YC9sSvy)xr(An2$KPNl z0|UdlKhcso0MpT+>yMd8*hk%~D?aMYu>u41`VYd5NbYE9Gcf!WF>F_;=9GVO*YMWu z0m8?#0SmZh5UAl%rq3P=W{5iyBVDjB6v=!9uuQJh2SWCg*BRW-9)D>eHh$j7D^5CR zpQn7+k7YnjmY05bBp&G)Upek|t0QUizk)pVK8?m0?jfQN!wEfCvZ(D5<2hO1G3W(yXLQ zHxf&ibVzqgO0zU9^{{|62-3AmEwI1}OS8atug`mZ*ZcqdchB5s&YbB}bB3X~ROneingK-EGg%u?G9#xN0u z^@t5?RC@wP<*6UHd_|9Ha9zJ%i)XB3)|brKGk3u#e3WxsFwF@&eL;M1U1jFeVrLZ? z<8t-rV0ax`@yp!Ia=)Azmcp<4q-o4R&cma1bg^3!fi^eEysMw%bS?oKIfg+N=gWni z1%>f*37NtR!W}HWu`Z3W!lQZJ2$C% z>Y^mWt*<CH-txEs|^jiUaF#qGkz;c^jcs~s{PQTl_A@6Xj=^w2DC z3PS}J_z@VoEqgr%#-C0a>YxV13ami6Ok5WxvVBuR^5yVqF0u<cOdYsDcT@&2HqwEp)6kgVnWo0zSHz3Vht$>~5ULg#Hn57~C%N5*$KNS6GoJ z!D9KkT!n{|s^~m9nPe|(HZAtz$;}3J4@nK=!enxtS~8qqmc_>Y6TjIt*Fs=VB~K@OBps&JpC z_a^Dc!+HUXipqe>7WsD1CH~^%Oc4#x5enBS<^`u{g9-$-(tPuK?+vBPFmm?sUt#O* zDV2gm-W#9gh8BsUE%_FO-PrA`Vr`eo&Hd2a{0*ZU$0pwNr+=7E!+TpJ88mirb@ zEfqPbVm+_W$-Lk_+5QCd)Y<{r8luwV8A)9jY+0>ln8;Xn-L?`#nkIF2PTdu%1D^21 zeC85|Gdfh*0alO{VW0!0-Bj3XRmAa>&u0Tj!4o9Ql$MO}5skbg*32k8yZDlMwuaz? zB~^pdDmdKKD}Y(b@^R{U^UIfN5120oh!Z&Th$1f_? z1dA8jY>hzn(Htzd@kU2Q2UkR*@GA0*4H^GTC|FkXZx2}RV4j9;x^l;lx2S|#TyOy# zwZcJ!&~#-@@4`Rfq{q5PiG9T7xwKgs8VVG-J2Q~3I-n9^7%Bd+5+IhO zEx2aH><$eWIk;Ssr*egAAO}IYeqy0yKFQeJ9LoMD**z=-gSP zmGPlpbP$}h5nHwDPaacK7hEkScOIZ0mxY{}iq@Uo2MfmD+@JWS^MIbzBdp`NxtiI@ykYD6=g}tpF%vuV} zhEJ1=7C$_f7`1k}@_NMRVu_ySaHDjjjkGiP?gUl@UBQBGZB|TwIXQ||X}Fw2nv8B~ zX|G}lZS$>Obk+#HIG6`?$}G!XLraOks*o!^CUclwv8W+Ubdu!}p`b{uX71jekEi|^ z<1kYPO*U|i^^|&R($lT(J`SUm|J(|`SroiqnN?bZnt`#HwNa!eGHrn zI@Z&Vg?G(#Y5%Rx^2>KyYAzw65H{1@@Kog*vNd!5d|(Es_EA7-|9A09g zNDI__+x^~`!)J6aw=<*O0&^sDg}vOMoJr7}dES}G3>Ggb$d|+4^=K!mhzVGe+K>Z- zw}H(om$HjG=^XP-WfV}rVCoZVC}w}~G}uLR_LZ13rE=l(ekG5cm0dBe8W->-Fwz^Z7iAt=b50hKC^GuM`-dMU zw;W4fATH{{R~|ZDXRJlVVbGRo0@`WbYPSL;XZ-3PduzF|_QjVodql;P;#p@%%76Ia zlg&&*T>WbRYtctVsrxM=$JzpHXOQ;BJzsBisy4TUyWgeRk2aH-t+3ya?U=*}V$7pI z^J;F*8sc`@LK1ti)ZihSlH;`Op8k{tle?0!cC=Hi#$IOH)BFPh!7P{QJhKnb2bWRO zez|A5gm-iiSbym{Au&Q8=K@^cGSnF!n|rqOGP|c>^D81~Z?O(K5I$$}Wuc)kyHs})AEByKO;Y*BbuE(jZ4(MDMX6i*$Dz;V`rL{_3Y!}?Wzo|W0(IS-P2wLUoVp5RjB8^>UadwNM5WJ zea)J4KS5`$2a-U>!NSmB&IU>b<`lgQ=w3hZBy05Q@)uU$KsC@%HlHB~c0{3HXQ*<; z{fea^?@%J^Mj)X~2H+3X`Z-89#7YNxu+7`HPS5cO0(Za?e?&7Rf0zGHDyUCl(qHp0 z8;I&kq6Y8j_z?i1sk8}QKi57WX2-m`bf~;Az{4@0b9wR9U@qMNGTeWHXyQ9>0`7!Q zBV=*x8NB&3B1!1m8{#BHCsgV$1ilUF23F$n#|gFbJlBA>+c3;H6uU@ z`|tcjp~dGjBZ?EMG1On5A`a;j%qHV@n3X*fJv+Tn3KD$0VtEdR!zKc z`s4d>OL)iO3G!q{Ac<(%%&4V)P}#b z%FDT9B9T&m<3B2z&($-m)||SA--7y>7~CiLP3G~Gd3lX)gW2lsqS!QS5Q1@FKG#JZ zO%Uw-_)r$~IMq)GyLN`|mut|91WKj>N>U?K9p&*-87`tZyJqJ4XcB+KXfrGj zu=u2321j_aW9+dG41gHA0Nb;7fJB6hYvlc$*!hHbrFd_9Qps1mQz|ddgQMv%r0#*9 zJ27mz1BqTD<=N6Firp6#&dJ#Ih6Z0ry;Jh-ek9Rq;|}(0l6@*1zDS$d*xE4k)zylf zgX=K|ByyU^Et=<1`LLS0AJj?8efGFDa+VKa`p0E)dU1a5V%ZJf&Vr3kufn~Ls`21# zfo{)NU;L{1ap7zQTIHJiIj0Yl`YEgP*ctsDa&Lia_m0kx;v)l=&|OpGRk^IfX>)FK zky77^`Ooz^j9*@I5DK%rB*?Mu|vzh2tgXxAWBz(<(6#~lA65EMBeYq3|#nL_`*a!>ue`9r1-Ke z5Na>2BrBTY{nVdqY$^r1Rqi{>^1w&`{Lbeh#ue|Seq9+04$k@wN!RZ@4OtLxtSygS z+es`pmr@(8--R}3U-=?!qxvi(Z05FKcj|M$=IL2S!^5cT_p@yh;e~dMH96z2tBtml z1euBmA|}6Xz5|0N)W3w->&3u_o{=^|&gDecOM0iAq(UH{{S8>kq&nl-4f;~J`WCLr zET=6R54P@<=^+uPY>NCn@#;ob>ZcyJ!SkVbkr1Y9&Z*B({d$x)-7)0nZ9)?|zi5w- zoquvl5J-FxZbPz)rs((}k@A|wO9e&7ZTD}x;WZ`pb+TpU;nmH}JZ^3hFfMNhz(R>1 zA*=N&DJd>n6gbH#QXiLTjKiFyLgfUXnk!En*-*AoqG(PkxXJ`_70S!xhdDU+5cfhX z$R<-_YOX(GN7elBm1hSb_-kAfRgTSBmFeESx{r%rBu!Si5rF>0X4dB-DQ$iG;Urxj zH16V8vedX4Z?}6GxUIFrHN&jmVYWl%#!-8hi{);I1kwHkNyS>nAKaY9I_(>t+Dz7a z%V!;zdmiW_Jiqg60LqYn>&L0$>GbrhE2Zl)r?xCw#BfpzLhYvp; zw0dQ;rnwwE+spTBR54?*BEl3rKxB8Dj|Iy$bHM(i(jLSSw@V|*UtU-ocgCF`WrdmNmfsE zyBNrG3po;?$<|O+-(pk-4cLNuyd3HlKnb)A^o*YPi!1war5}H-i4~mGule8jA0yiB z>&YInInWEaTZsV*rLNt3?n%iS1|I#5*RlIV`DI%8%3OAyHTT`c$c+nLr zkUm(trw#1sT?BZ;bXW+Mm@J@lSLSl(LrG@{v*zG#`LaRrKNu5s#j<{h8(THg>|-Ct zFnd_$ZobK$tJr+ydssd3xo=#u)-isW6RgXS7%L6XMHj&}J>V8pFL)qNiqt;I_iNO*f*07NS5!0* zSfC!SSPWBD*KuHk6G+YJ*lhkX2t&rpN zH2x(=of<~#VXCR`ybqNzT!2|+6D@6hBl1OOnls^LI2P;No;W_QXJWOZ3Tp5X60vS& z++&JsJ}E#*bDD`?0Wj5*e#x(%1xXi54s2(HB*%Ch0^MieE{e zBA*@4(2(%a)V8@*M|YMjE|c8+;GaP>dmA+QO0j2OPPf>?Z8~@3eDd)I`w$rXc+`8 zPe1CVw<*$^2tUz*(E-5_4Nr4B!&+Jf%Z&CU~jv>99&E0a6)2>@?RmTk%VHtkyH;b%4CKKy|HMxaWf3omHge#Q{sFGz(S-3z{9 zeaf_7dc=F>jw)#BKUZa9cH zmn-MTW_xEQMw;g-1ftm)uS-8~G>bgy=sY2ifF;AHn@th10-banU=l4Dk&J-{!ouQq z#4g>fQhx@iGU3V;5wg_!>3mML;<<3Ht-}_X`X_1oa#CR7#T5Ro(zxC+z53`C!xoDt zGd`V$U+RtUlGyWJ1?*(r7ujuG5B+oPrkO zqO%=Z?78PsE2nb1R3bG<>WxU!k>?qNPpcokutV~Ujh!IZ%@$Q8m3G~S9}3~yYLf|& zlVRz+0Nj#o!-Pq<6|joawNN?}8wXd|@;(uFbfJV^c&62C$IIlNA@WqxCMnR@lR1)S zpFT*6LO40WL{*$CrylA(>Fq*56f7cqgBnZVhybki;mK2HJE&Hb4t$O*H{=9yJ!L}Q zrBvQc4g>jev=%;UAl~g8n&#l2$%>HX*g8G@V>s2Wvq}H4w0f0nm;V_Mwv?DYtXM2O z4fP)6p!Y%XGaf{D```GXpz;k7-UkU$`=KOqZudfqIqbd$wSV$UZ2w5wHmYgr00?`k zxi&oNchptwhekhMoww|VOmD91nSoE>@N; zh7{`a{5gGKMC4HH6AN|xY8JR-p4%%Nka(ItK9vWZs}i2lJ7Ui-Y#iMqtJ^|5PqsN% zzn0rJUf=D*?J299xoUJ=6K&2@l%}jD@B)iJMgx|gch!IEtkB;xkm*ZQcG? zxAKP&GC#tD{RUg5npH&+!tYs34!vnlY@|(F6E#Ktt+#g&VLiRn0W8F9;~ee|f`CvkRIj*}&GuTN z0_(cowYTsISo|qSG%&3*`b1rFkq(Qv9CG9tH641u+kT;G1JEn8k3~heFB*)j#S^lW9N3Wr{!#H$E1D(I4%wzuq!D`w7m7&Da@ zfOC$n-~@)8*jA8+Y;0-poPvns9rZn^& z4*U_v8;l;}T@wF91dd8DFnb}6M^5yX&}abZ7)ZtqtjBs~cY{ndLl<_AnPi z|D8?tBZ;qA-_g0`CN)lH0wpXq&M{hsafu9v1MEFCjpFD15 zbj^ZXfo@GsTK9NOy8VNmZ5+ivlZ`9CZna8Cf*$a^zJB_5@jxnuj#G!cR zbzr2j`5rd2Kn9GFZ&6p8Qo$w_;B^Ij<7Q;llwq*I(%oChk%)nkP5mb%08TT&Va>z! zkdB~nwg6X$nUv#0yN(lmTq#4W*}hMP+^LdvS@rx#(z@FQ8b&6;uJZL;2NlO|B+3fGjVe+|*|#SI3v)e|wRT3aJw9`R#B# zpl0x0DA3EqY@{11NgylzF^spW06S3PgHSSH^OL9^)W!WL;P{Cc#(tG)(XbQ9-{i%5l+(NkpV!rajO3Fzne#b~xHF4nj zNnwx>I`elsT4_HUKMSY>$q%`%68_yfGM8>~=+qMeo^k5l6eTyj5?ttmzxOpZtXgmD z7PuQw01aHPRFPy{@f4sEOYi3eWtWF zaX&{wjt6r-GPh#z0c4O*LRahfaUMlttnUF&qPrXfKxPUQYbx@Z3tjv7%0~SkSzxBp z{kQ*#YOYoE`riLr37Zt0#w(5=M`Z?6G=!94v+N8b`Mfd+dsz%b$%Af7R&`s1YM;mD(5kX+_gZeu11dJnFA)|fgEMZwiR~q47Y++ zcmc@}k{L^BDy~M=zEm0=Gk||n)BHV#&cyNKI`s*m@n&j0cjeD}E}=l!ggU~u29p zyaV0Hj9utAv3i`GoU9CKS3tkyPg#(0XzcmV&C67#SS@*E&8;OEf+uK=pL6+L(PGsh zoC7h?CS``oU&qRnkzXB+3s$^7rTA=z$$_sP9Aq(6W~I$h=*d^efyV3DJSrH_h0E4b-iqW9N$lf?-r2-r8(A0qBjPr zQKXa&lJfk)bf+&x_@@H-Uv_ElUzh0U5h%Yh&ZRXYacv zE;(Z8BV0XwH+fs!(s#JHpN$#}HDmu!AP^6X);TjpBq`ghZNyHUkz9~~ zqko&DvY*?q)P)PosF?Q<`|u?B8S;`-*klrOF9G6FP6}(Jtn`Xmu`JyCha8s4T=uRx z3k!GUZ3)|{)~(4#QE3o%IVw9R( zGxWoUc7I&lMGKglEO_7Z9!DGf08>+Q73@-#cMoE~0(Tu90xS zmFg0}!BDyR4uT$P4e*q~1a(>ffk5cWpmW2-HJNxQv*X=n1+pa7w%1IRN{NH4iliu} zya6u>&ID+BUV3AM!J(|?P|J^(g`&+tQP7~F7N~v*|8vcK^f3bi?Lm*D5 z@{H*Y!<8P7fZu7cf#>D9dqa}{r~GfhZeRvZk+-O$(*()Eu}Ebqi6f#F%e1rD3+vOX zz|Aq=vL$~t$!YjB?||q<%u=%G@?|KBk7cCf*X8-W-t6W&FCOo~18G5FDVT@%K0VB5 z%iRRp%x&m1NNl)!cb;38H>d5B(fP&qy)nOC_k$+&Cs9Q{{E2D`7O%A!z_k;e*iUPIujK+80 z^YFP_t+6fRKdk?WQSX$x@d7-=M7$k_w|rx0bjj=UR1$^c7Z|-jZ@?2j6osP1t~QgX zOW;Gi>QfJ+iKuG)b(!G>v&1VI5fN$eQP(VQ_+|B-2ng&@O0I>8uQWp;xdh5d4@h;P z&nvHoRk2zuaPOMdAwdP#bz70BOC@`2Ph~Azb_v9{hbX{+Cl+2@@(c42rBwJ`zAuy? z53D1K8f1MFkjl$UMsc7rt0S?*5#Iw#$^u3y`rNib>7jhUwQSK6Aw$7Gt;95H-v;Os zj1fyk>#3MDe*1}~g4eZL;0 z{N_?Ev$+jUm~bF)CSZ=E>y5+0a=kH@cWCRbqQ(cGzVn ziVYJMXsPIdH~hVlDGA^yPC#tM(0yarOH+2gVo{PLkw;S{OE#*Pgd2AlgNd1hXUnBP z4R|PHmiHl$1>{{e>q>Z13 z%EcsiXoPOYdB(B&oP9-2TuSVV=^H=aN!#ihlG?Bjnb^0uIA0dpouScRm*uYrP$q0~ z36)dk;`a0&+)Co>CK3Ikkw*&Ney`3`KrCXD5#AyI79HZor&AYUwZN#1*NXHEW=3I^Sgp@AJ zG(baHSO&@MY1`r{uNcgI{(IRf%E+k#j)QaJlmh&FbPE=U$>dC`&=hegRd~CUvuQxC zPl}v!Jfj~G`11~_?%wFkAIS@n`~&vit#NH3noW)-EaFYuW*b4P6ugT2FC(#?2f+e0 z3ug3}SoD;E>sggVoQezRVo*0diq0YcF;zyi09YRprz(YAB?K$Ot?8B)m8Oaujy<%yP1-Fr+ykw4HgvvJ?yH7oG)Ou0MQ?}rz` zO*-&8O}P;u_WA2A Getting Started
-
-
missing
+
+ Host A2A on Hugging Face

Host A2A on Hugging Face

@@ -159,8 +159,8 @@

Host A2A on Hugging Face

Output
docs/assets/social/a2a/host-on-hf.png
Badge
DOCS
Theme
doc / protocol-grid
-
Status
missing
-
Size
— · —
+
Status
ok
+
Size
1200×630 · 26 KB
From 622e58447c437dbe8823539e7f29f35652c84346 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Tue, 26 May 2026 22:28:24 +0100 Subject: [PATCH 54/58] docs: fix A2A docs checks --- docs/docs/_generated/model_aliases_hf.md | 2 +- docs/docs/_generated/models_reference.md | 14 +++++++------- scripts/a2a_docs_pipeline.py | 20 +++++++++++++++++++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/docs/docs/_generated/model_aliases_hf.md b/docs/docs/_generated/model_aliases_hf.md index ac1304094..927128ece 100644 --- a/docs/docs/_generated/model_aliases_hf.md +++ b/docs/docs/_generated/model_aliases_hf.md @@ -1,7 +1,7 @@ | Model Alias | Maps to | | --- | --- | -| `deepseek-hf` | `hf.deepseek-ai/DeepSeek-V4-Pro:together` | | `deepseek-ai/deepseek-v4-pro` | `deepseek-ai/deepseek-v4-pro` | +| `deepseek-hf` | `hf.deepseek-ai/DeepSeek-V4-Pro:together` | | `deepseek32` | `hf.deepseek-ai/DeepSeek-V3.2:fireworks-ai` | | `deepseek4-hf` | `hf.deepseek-ai/DeepSeek-V4-Pro:together` | | `deepseek4pro-hf` | `hf.deepseek-ai/DeepSeek-V4-Pro:together` | diff --git a/docs/docs/_generated/models_reference.md b/docs/docs/_generated/models_reference.md index 1259e6b28..9b1528c86 100644 --- a/docs/docs/_generated/models_reference.md +++ b/docs/docs/_generated/models_reference.md @@ -27,11 +27,11 @@ | `opus46` | `anthropic` | Text, Vision, Document | `json` (schema) | effort: `auto`, `low`, `medium`, `high`, `max`, `off`
Example: `opus46.auto` | — | `web_search` (web_search_20260209)
`web_fetch` (web_fetch_20260209)
beta: `code-execution-web-tools-2026-02-09` | | `opus` | `anthropic` | Text, Vision, Document | `json` (schema) | effort: `auto`, `low`, `medium`, `high`, `xhigh`, `max`, `off`
Example: `opus.auto` | — | `web_search` (web_search_20260209)
`web_fetch` (web_fetch_20260209)
beta: `code-execution-web-tools-2026-02-09` | | `codexspark` | `codexresponses` | Text | `json` (schema) | — | — | — | -| `deepseek` | `deepseek` | Text | `json` (schema) | effort: `high`, `max`, `off`
Example: `deepseek.high` | — | — | | `deepseek-reasoner` | `deepseek` | Text | `json` (schema) | effort: `high`, `max`, `off`
Example: `deepseek-reasoner.high` | — | — | | `deepseek.deepseek-ai/deepseek-v3.1` | `deepseek` | Text | `json` (schema) | — | — | — | | `deepseek3` | `deepseek` | Text | `json` (schema) | — | — | — | | `deepseek4flash` | `deepseek` | Text | `json` (schema) | effort: `high`, `max`, `off`
Example: `deepseek4flash.high` | — | — | +| `deepseek` | `deepseek` | Text | `json` (schema) | effort: `high`, `max`, `off`
Example: `deepseek.high` | — | — | | `passthrough` | `fast-agent` | Text | `json` (schema) | — | — | — | | `playback` | `fast-agent` | Text | `json` (schema) | — | — | — | | `silent` | `fast-agent` | Text | `json` (schema) | — | — | — | @@ -49,8 +49,8 @@ | `moonshotai/kimi-k2-instruct-0905` | `groq` | Text | `json` (schema) | — | — | — | | `moonshotai/kimi-k2-thinking` | `groq` | Text | `json` (schema) | — | — | — | | `moonshotai/kimi-k2` | `groq` | Text | `json` (schema) | — | — | — | -| `deepseek32` | `hf` | Text | `json` (schema) | — | — | — | | `deepseek-hf` | `hf` | Text | `json` (schema) | — | — | — | +| `deepseek32` | `hf` | Text | `json` (schema) | — | — | — | | `glm47` | `hf` | Text | `json` (schema) | toggle: `on`, `off`
Example: `glm47?reasoning=off` | — | — | | `glm5` | `hf` | Text | `json` (schema) | toggle: `on`, `off`
Example: `glm5?reasoning=off` | — | — | | `glm` | `hf` | Text | `json` (schema) | toggle: `on`, `off`
Example: `glm?reasoning=off` | — | — | @@ -109,8 +109,8 @@ | `grok-4-1-fast-reasoning` | `xai` | Text, Vision | `json` (schema) | — | — | — | | `grok-4-fast-reasoning` | `xai` | Text, Vision | `json` (schema) | — | — | — | | `grok-4-fast` | `xai` | Text, Vision | `json` (schema) | — | — | — | -| `grok-4-latest` | `xai` | Text | `json` (schema) | effort: `none`, `low`, `medium`, `high`, `off`
Example: `grok-4-latest.low` | — | — | -| `grok-4.3-latest` | `xai` | Text | `json` (schema) | effort: `none`, `low`, `medium`, `high`, `off`
Example: `grok-4.3-latest.low` | — | — | -| `grok-4` | `xai` | Text | `json` (schema) | effort: `none`, `low`, `medium`, `high`, `off`
Example: `grok-4.low` | — | — | -| `grok` | `xai` | Text | `json` (schema) | effort: `none`, `low`, `medium`, `high`, `off`
Example: `grok.low` | — | — | -| `grok` | `xai` | Text | `json` (schema) | effort: `none`, `low`, `medium`, `high`, `off`
Example: `grok.low` | — | — | +| `grok-4-latest` | `xai` | Text, Vision | `json` (schema) | effort: `none`, `low`, `medium`, `high`, `off`
Example: `grok-4-latest.low` | — | — | +| `grok-4.3-latest` | `xai` | Text, Vision | `json` (schema) | effort: `none`, `low`, `medium`, `high`, `off`
Example: `grok-4.3-latest.low` | — | — | +| `grok-4` | `xai` | Text, Vision | `json` (schema) | effort: `none`, `low`, `medium`, `high`, `off`
Example: `grok-4.low` | — | — | +| `grok` | `xai` | Text, Vision | `json` (schema) | effort: `none`, `low`, `medium`, `high`, `off`
Example: `grok.low` | — | — | +| `grok` | `xai` | Text, Vision | `json` (schema) | effort: `none`, `low`, `medium`, `high`, `off`
Example: `grok.low` | — | — | diff --git a/scripts/a2a_docs_pipeline.py b/scripts/a2a_docs_pipeline.py index dad8f4608..a143122c2 100755 --- a/scripts/a2a_docs_pipeline.py +++ b/scripts/a2a_docs_pipeline.py @@ -15,6 +15,7 @@ from __future__ import annotations import argparse +import importlib.util import os import shutil import signal @@ -24,7 +25,24 @@ import urllib.request from pathlib import Path -from docs_assets import record_asciinema_cast, require_recording_tools + +def _load_docs_asset_helpers(): + try: + from docs_assets import record_asciinema_cast, require_recording_tools + + return record_asciinema_cast, require_recording_tools + except ModuleNotFoundError: + path = Path(__file__).resolve().parent / "docs_assets.py" + spec = importlib.util.spec_from_file_location("docs_assets", path) + if spec is None or spec.loader is None: + raise + module = importlib.util.module_from_spec(spec) + sys.modules[spec.name] = module + spec.loader.exec_module(module) + return module.record_asciinema_cast, module.require_recording_tools + + +record_asciinema_cast, require_recording_tools = _load_docs_asset_helpers() ROOT = Path(__file__).resolve().parent.parent DOCS_A2A = ROOT / "docs" / "docs" / "a2a" From a824b7f2bea0db51d25d07afad7b5e40277077aa Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Tue, 26 May 2026 22:32:29 +0100 Subject: [PATCH 55/58] test: expect HF Space ambient auth header --- tests/unit/fast_agent/commands/test_mcp_runtime_handlers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/fast_agent/commands/test_mcp_runtime_handlers.py b/tests/unit/fast_agent/commands/test_mcp_runtime_handlers.py index cc0d9fa6b..25c214bc7 100644 --- a/tests/unit/fast_agent/commands/test_mcp_runtime_handlers.py +++ b/tests/unit/fast_agent/commands/test_mcp_runtime_handlers.py @@ -889,7 +889,7 @@ async def test_handle_mcp_connect_hf_url_adds_hf_auth_from_env(monkeypatch) -> N assert any("Connected MCP server" in str(msg.text) for msg in outcome.messages) assert manager.last_config is not None assert manager.last_config.headers is not None - assert manager.last_config.headers.get("Authorization") == "Bearer hf_test_token" + assert "Authorization" not in manager.last_config.headers assert manager.last_config.headers.get("X-HF-Authorization") == "Bearer hf_test_token" From d2448c73f9f6fe4a26c76aa365b14c881612a210 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Tue, 26 May 2026 22:56:18 +0100 Subject: [PATCH 56/58] Align A2A client context handling with spec --- src/fast_agent/a2a/remote_agent.py | 25 +++++------ .../ui/interactive/command_dispatch.py | 2 +- .../a2a/test_fast_agent_a2a_server.py | 1 + .../test_a2a_remote_agent_events.py | 43 +++++++++++++++++-- .../ui/test_a2a_command_dispatch.py | 2 +- 5 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/fast_agent/a2a/remote_agent.py b/src/fast_agent/a2a/remote_agent.py index be018d1c3..1fe01ed83 100644 --- a/src/fast_agent/a2a/remote_agent.py +++ b/src/fast_agent/a2a/remote_agent.py @@ -82,7 +82,7 @@ class A2ADiagnostics: url: str transport: str | None remote_name: str | None - context_id: str + context_id: str | None current_task_id: str | None last_task_state: str | None selected_transport_class: str | None @@ -99,7 +99,7 @@ def __init__( ) -> None: super().__init__(config=config, context=context) self.a2a_config = a2a_config - self.context_id = str(uuid.uuid4()) + self.context_id: str | None = None self.current_task_id: str | None = None self.last_task_state: str | None = None self.remote_card: AgentCard | None = None @@ -220,7 +220,7 @@ def _build_oauth_provider_for_card(self, card: AgentCard) -> Any | None: ) def reset_a2a_state(self) -> None: - self.context_id = str(uuid.uuid4()) + self.context_id = None self.current_task_id = None self.last_task_state = None @@ -250,15 +250,16 @@ async def generate_impl( self._timestamp_messages(messages) self._display_user_messages(messages) user_text = _latest_text(messages) - request = SendMessageRequest( - message=Message( - role=Role.ROLE_USER, - message_id=str(uuid.uuid4()), - context_id=self.context_id, - task_id=self.current_task_id, - parts=_parts_from_messages(messages) or [Part(text=user_text)], - ) + message = Message( + role=Role.ROLE_USER, + message_id=str(uuid.uuid4()), + parts=_parts_from_messages(messages) or [Part(text=user_text)], ) + if self.context_id: + message.context_id = self.context_id + if self.current_task_id: + message.task_id = self.current_task_id + request = SendMessageRequest(message=message) self._log_a2a_progress(ProgressAction.SENDING, details=self._transport_label()) remove_live_listener: Callable[[], None] | None = None @@ -436,7 +437,7 @@ def _emit_stream(self, text: str) -> None: def _advance_task_state(self, *, state: str, task_id: str, context_id: str) -> None: self.last_task_state = state - self.context_id = context_id + self.context_id = context_id or None if state == _INPUT_REQUIRED_STATE: self.current_task_id = task_id return diff --git a/src/fast_agent/ui/interactive/command_dispatch.py b/src/fast_agent/ui/interactive/command_dispatch.py index 52ca7d06e..bf7d2e9ed 100644 --- a/src/fast_agent/ui/interactive/command_dispatch.py +++ b/src/fast_agent/ui/interactive/command_dispatch.py @@ -449,7 +449,7 @@ async def _dispatch_a2a_payload( rich_print(f" URL: {diagnostics.url}") rich_print(f" Transport: {diagnostics.transport or 'auto'}") rich_print(f" Remote: {diagnostics.remote_name or 'unresolved'}") - rich_print(f" Context: {diagnostics.context_id}") + rich_print(f" Context: {diagnostics.context_id or '-'}") rich_print(f" Task: {diagnostics.current_task_id or '-'}") rich_print(f" Last state: {diagnostics.last_task_state or '-'}") rich_print(f" Client transport: {diagnostics.selected_transport_class or '-'}") diff --git a/tests/integration/a2a/test_fast_agent_a2a_server.py b/tests/integration/a2a/test_fast_agent_a2a_server.py index 6152b4cab..2a6ee198e 100644 --- a/tests/integration/a2a/test_fast_agent_a2a_server.py +++ b/tests/integration/a2a/test_fast_agent_a2a_server.py @@ -546,6 +546,7 @@ async def test_a2a_remote_agent_without_history_uses_fresh_server_contexts( ] ) first_context_id = client.context_id + assert first_context_id second = await client.generate_impl( [ PromptMessageExtended( diff --git a/tests/unit/fast_agent/test_a2a_remote_agent_events.py b/tests/unit/fast_agent/test_a2a_remote_agent_events.py index 103db985d..dceb795bb 100644 --- a/tests/unit/fast_agent/test_a2a_remote_agent_events.py +++ b/tests/unit/fast_agent/test_a2a_remote_agent_events.py @@ -83,8 +83,10 @@ async def show_assistant_message( class _FakeClient: def __init__(self, events: list[StreamResponse]) -> None: self.events = events + self.requests: list[object] = [] - def send_message(self, _request: object) -> AsyncIterator[StreamResponse]: + def send_message(self, request: object) -> AsyncIterator[StreamResponse]: + self.requests.append(request) return _events(*self.events) @@ -105,6 +107,13 @@ def _artifact_update( ) +def test_a2a_remote_agent_starts_without_client_generated_context_id() -> None: + agent = _remote_agent() + + assert agent.context_id is None + assert agent.current_task_id is None + + @pytest.mark.asyncio async def test_a2a_remote_agent_clears_task_id_for_terminal_full_task_event() -> None: agent = _remote_agent() @@ -152,7 +161,7 @@ async def test_a2a_remote_agent_keeps_task_id_for_input_required_full_task_event assert agent.current_task_id == "input-task" -def test_a2a_remote_agent_resets_context_for_no_history_completed_turns() -> None: +def test_a2a_remote_agent_clears_context_for_no_history_completed_turns() -> None: agent = _remote_agent() agent.context_id = "ctx-completed" agent.current_task_id = None @@ -160,7 +169,7 @@ def test_a2a_remote_agent_resets_context_for_no_history_completed_turns() -> Non agent._prepare_turn_state(use_history=False) - assert agent.context_id != "ctx-completed" + assert agent.context_id is None assert agent.current_task_id is None assert agent.last_task_state is None @@ -178,6 +187,34 @@ def test_a2a_remote_agent_keeps_input_required_task_for_no_history_follow_up() - assert agent.last_task_state == "TASK_STATE_INPUT_REQUIRED" +@pytest.mark.asyncio +async def test_a2a_remote_agent_first_request_omits_context_and_task_ids() -> None: + agent = _remote_agent() + display = _FakeDisplay() + fake_client = _FakeClient( + [ + StreamResponse( + task=Task( + id="task-server", + context_id="ctx-server", + status=TaskStatus(state=TaskState.TASK_STATE_COMPLETED), + ) + ) + ] + ) + agent.display = cast("Any", display) + agent._client = fake_client + + await agent.generate_impl( + [PromptMessageExtended(role="user", content=[TextContent(type="text", text="hello")])] + ) + + request = cast("Any", fake_client.requests[0]) + assert request.message.context_id == "" + assert request.message.task_id == "" + assert agent.context_id == "ctx-server" + + @pytest.mark.asyncio async def test_a2a_remote_agent_streams_chunks_to_live_display() -> None: agent = _remote_agent() diff --git a/tests/unit/fast_agent/ui/test_a2a_command_dispatch.py b/tests/unit/fast_agent/ui/test_a2a_command_dispatch.py index c4f146fd8..9c08d801d 100644 --- a/tests/unit/fast_agent/ui/test_a2a_command_dispatch.py +++ b/tests/unit/fast_agent/ui/test_a2a_command_dispatch.py @@ -122,7 +122,7 @@ async def test_a2a_tui_dispatch_lists_and_resets_remote_agents( assert reset.handled assert " • remote" in printed assert all("local" not in line for line in printed) - assert remote.context_id != "ctx-current" + assert remote.context_id is None assert remote.current_task_id is None assert remote.last_task_state is None From b89dc485964d76774e36fc4d1b064fd6f8181044 Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Wed, 27 May 2026 17:50:07 +0100 Subject: [PATCH 57/58] a2a updates, init updates! --- src/fast_agent/__init__.py | 132 ++++++++++++------ src/fast_agent/a2a/__init__.py | 13 +- src/fast_agent/a2a/connect.py | 12 +- src/fast_agent/a2a/remote_agent.py | 2 + src/fast_agent/cli/__main__.py | 2 + src/fast_agent/cli/constants.py | 4 + src/fast_agent/cli/main.py | 31 ++++ src/fast_agent/cli/runtime/agent_setup.py | 109 +++++++++++---- .../llm/provider/openai/codex_oauth.py | 93 +++++++++++- .../llm/provider/openai/codex_responses.py | 2 + tests/integration/a2a/conftest.py | 70 +++++++--- tests/integration/a2a/fake_server.py | 57 +++++--- .../a2a/test_remote_agent_runtime.py | 5 +- .../commands/test_cli_completion_help.py | 23 ++- .../commands/test_cli_main_routing.py | 10 ++ .../test_runtime_model_picker_bootstrap.py | 28 +++- .../llm/providers/test_codex_oauth.py | 81 +++++++++++ .../test_a2a_remote_agent_events.py | 26 ++++ .../fast_agent/test_package_lazy_exports.py | 63 +++++++++ 19 files changed, 642 insertions(+), 121 deletions(-) create mode 100644 tests/unit/fast_agent/test_package_lazy_exports.py diff --git a/src/fast_agent/__init__.py b/src/fast_agent/__init__.py index da70dc4bb..41c7944cc 100644 --- a/src/fast_agent/__init__.py +++ b/src/fast_agent/__init__.py @@ -1,52 +1,60 @@ """fast-agent - An MCP native agent application framework""" +import importlib from typing import TYPE_CHECKING -from fast_agent.config import ( - AnthropicSettings, - AzureSettings, - BedrockSettings, - DeepSeekSettings, - GenericSettings, - GoogleSettings, - GroqSettings, - HuggingFaceSettings, - LoggerSettings, - MCPElicitationSettings, - MCPRootSettings, - MCPSamplingSettings, - MCPServerAuthSettings, - MCPServerSettings, - MCPSettings, - OpenAISettings, - OpenRouterSettings, - OpenTelemetrySettings, - Settings, - SkillsSettings, - TensorZeroSettings, - XAISettings, -) -from fast_agent.types import ( - ConversationSummary, - LlmStopReason, - PromptMessageExtended, - RequestParams, - ResourceLink, - audio_link, - extract_first, - extract_last, - find_matches, - image_link, - resource_link, - search_messages, - text_content, - video_link, -) +_CONFIG_EXPORTS = { + "AnthropicSettings", + "AzureSettings", + "BedrockSettings", + "DeepSeekSettings", + "GenericSettings", + "GoogleSettings", + "GroqSettings", + "HuggingFaceSettings", + "LoggerSettings", + "MCPElicitationSettings", + "MCPRootSettings", + "MCPSamplingSettings", + "MCPServerAuthSettings", + "MCPServerSettings", + "MCPSettings", + "OpenAISettings", + "OpenRouterSettings", + "OpenTelemetrySettings", + "Settings", + "SkillsSettings", + "TensorZeroSettings", + "XAISettings", +} + +_TYPE_EXPORTS = { + "ConversationSummary", + "LlmStopReason", + "PromptMessageExtended", + "RequestParams", + "ResourceLink", + "audio_link", + "extract_first", + "extract_last", + "find_matches", + "image_link", + "resource_link", + "search_messages", + "text_content", + "video_link", +} def __getattr__(name: str): """Lazy import heavy modules to avoid circular imports during package initialization.""" - if name == "Core": + if name in _CONFIG_EXPORTS: + module = importlib.import_module("fast_agent.config") + return getattr(module, name) + elif name in _TYPE_EXPORTS: + module = importlib.import_module("fast_agent.types") + return getattr(module, name) + elif name == "Core": from fast_agent.core import Core return Core @@ -113,10 +121,44 @@ def __getattr__(name: str): # Help static analyzers/IDEs resolve symbols and signatures without importing at runtime. if TYPE_CHECKING: # pragma: no cover - typing aid only # Provide a concrete import path for type checkers/IDEs + from fast_agent.config import AnthropicSettings as AnthropicSettings # noqa: F401 + from fast_agent.config import AzureSettings as AzureSettings # noqa: F401 + from fast_agent.config import BedrockSettings as BedrockSettings # noqa: F401 + from fast_agent.config import DeepSeekSettings as DeepSeekSettings # noqa: F401 + from fast_agent.config import GenericSettings as GenericSettings # noqa: F401 + from fast_agent.config import GoogleSettings as GoogleSettings # noqa: F401 + from fast_agent.config import GroqSettings as GroqSettings # noqa: F401 + from fast_agent.config import HuggingFaceSettings as HuggingFaceSettings # noqa: F401 + from fast_agent.config import LoggerSettings as LoggerSettings # noqa: F401 + from fast_agent.config import MCPElicitationSettings as MCPElicitationSettings # noqa: F401 + from fast_agent.config import MCPRootSettings as MCPRootSettings # noqa: F401 + from fast_agent.config import MCPSamplingSettings as MCPSamplingSettings # noqa: F401 + from fast_agent.config import MCPServerAuthSettings as MCPServerAuthSettings # noqa: F401 + from fast_agent.config import MCPServerSettings as MCPServerSettings # noqa: F401 + from fast_agent.config import MCPSettings as MCPSettings # noqa: F401 + from fast_agent.config import OpenAISettings as OpenAISettings # noqa: F401 + from fast_agent.config import OpenRouterSettings as OpenRouterSettings # noqa: F401 + from fast_agent.config import OpenTelemetrySettings as OpenTelemetrySettings # noqa: F401 + from fast_agent.config import Settings as Settings # noqa: F401 + from fast_agent.config import SkillsSettings as SkillsSettings # noqa: F401 + from fast_agent.config import TensorZeroSettings as TensorZeroSettings # noqa: F401 + from fast_agent.config import XAISettings as XAISettings # noqa: F401 from fast_agent.core.fastagent import FastAgent as FastAgent # noqa: F401 from fast_agent.mcp.prompt import Prompt as Prompt # noqa: F401 from fast_agent.types import ConversationSummary as ConversationSummary # noqa: F401 + from fast_agent.types import LlmStopReason as LlmStopReason # noqa: F401 from fast_agent.types import PromptMessageExtended as PromptMessageExtended # noqa: F401 + from fast_agent.types import RequestParams as RequestParams # noqa: F401 + from fast_agent.types import ResourceLink as ResourceLink # noqa: F401 + from fast_agent.types import audio_link as audio_link # noqa: F401 + from fast_agent.types import extract_first as extract_first # noqa: F401 + from fast_agent.types import extract_last as extract_last # noqa: F401 + from fast_agent.types import find_matches as find_matches # noqa: F401 + from fast_agent.types import image_link as image_link # noqa: F401 + from fast_agent.types import resource_link as resource_link # noqa: F401 + from fast_agent.types import search_messages as search_messages # noqa: F401 + from fast_agent.types import text_content as text_content # noqa: F401 + from fast_agent.types import video_link as video_link # noqa: F401 __all__ = [ @@ -125,7 +167,7 @@ def __getattr__(name: str): "Context", "ContextDependent", "ServerRegistry", - # Configuration and settings (eagerly loaded) + # Configuration and settings (lazy loaded) "Settings", "MCPSettings", "MCPServerSettings", @@ -151,19 +193,19 @@ def __getattr__(name: str): # Progress and event tracking (lazy loaded) "ProgressAction", "ProgressEvent", - # Type definitions and enums (eagerly loaded) + # Type definitions and enums (lazy loaded) "LlmStopReason", "RequestParams", "PromptMessageExtended", "ResourceLink", "ConversationSummary", - # Content helpers (eagerly loaded) + # Content helpers (lazy loaded) "text_content", "resource_link", "image_link", "video_link", "audio_link", - # Search utilities (eagerly loaded) + # Search utilities (lazy loaded) "search_messages", "find_matches", "extract_first", diff --git a/src/fast_agent/a2a/__init__.py b/src/fast_agent/a2a/__init__.py index 773fbeb79..8f43ee5d0 100644 --- a/src/fast_agent/a2a/__init__.py +++ b/src/fast_agent/a2a/__init__.py @@ -1,5 +1,16 @@ """A2A support for fast-agent.""" -from fast_agent.a2a.server import AgentA2AServer +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from fast_agent.a2a.server import AgentA2AServer as AgentA2AServer + + +def __getattr__(name: str): + if name == "AgentA2AServer": + from fast_agent.a2a.server import AgentA2AServer + + return AgentA2AServer + raise AttributeError(f"module '{__name__}' has no attribute '{name}'") __all__ = ["AgentA2AServer"] diff --git a/src/fast_agent/a2a/connect.py b/src/fast_agent/a2a/connect.py index 390523f4a..9bb0df631 100644 --- a/src/fast_agent/a2a/connect.py +++ b/src/fast_agent/a2a/connect.py @@ -5,9 +5,11 @@ import re import shlex from dataclasses import dataclass +from typing import TYPE_CHECKING from urllib.parse import urlsplit, urlunsplit -from fast_agent.config import MCPServerAuthSettings +if TYPE_CHECKING: + from fast_agent.config import MCPServerAuthSettings _TRANSPORT_ALIASES = { "jsonrpc": "JSONRPC", @@ -82,7 +84,7 @@ def parse_a2a_connect_arguments(arguments: str | None) -> tuple[A2AConnectReques name=name, transport=transport, auth=( - MCPServerAuthSettings(oauth=trigger_oauth) + _a2a_auth_settings(trigger_oauth) if trigger_oauth is not None else None ), @@ -92,6 +94,12 @@ def parse_a2a_connect_arguments(arguments: str | None) -> tuple[A2AConnectReques ) +def _a2a_auth_settings(oauth: bool) -> "MCPServerAuthSettings": + from fast_agent.config import MCPServerAuthSettings + + return MCPServerAuthSettings(oauth=oauth) + + def normalize_a2a_transport(value: str) -> str | None: return _TRANSPORT_ALIASES.get(value.strip().lower()) diff --git a/src/fast_agent/a2a/remote_agent.py b/src/fast_agent/a2a/remote_agent.py index 1fe01ed83..85af2b2fe 100644 --- a/src/fast_agent/a2a/remote_agent.py +++ b/src/fast_agent/a2a/remote_agent.py @@ -369,6 +369,8 @@ async def _consume_events(self, events: Any) -> "_A2AResult": async for event in events: if event.HasField("message"): + if event.message.context_id: + self.context_id = event.message.context_id text = _parts_text(event.message.parts) _append_text(message_chunks, text) self._emit_stream(text) diff --git a/src/fast_agent/cli/__main__.py b/src/fast_agent/cli/__main__.py index 3e49fde7d..fe54f38f9 100644 --- a/src/fast_agent/cli/__main__.py +++ b/src/fast_agent/cli/__main__.py @@ -21,6 +21,8 @@ "--watch", "--reload", "--smart", + "--a2a-oauth", + "--no-a2a-oauth", "-x", } diff --git a/src/fast_agent/cli/constants.py b/src/fast_agent/cli/constants.py index caae314d5..d04b560a6 100644 --- a/src/fast_agent/cli/constants.py +++ b/src/fast_agent/cli/constants.py @@ -49,6 +49,10 @@ def normalize_resume_flag_args(args: list[str], *, start_index: int = 0) -> None "--skills-dir", "--agent-cards", "--card", + "--a2a", + "--a2a-transport", + "--a2a-oauth", + "--no-a2a-oauth", "--env", "--noenv", "--no-env", diff --git a/src/fast_agent/cli/main.py b/src/fast_agent/cli/main.py index 4707ed390..d079e1cd0 100644 --- a/src/fast_agent/cli/main.py +++ b/src/fast_agent/cli/main.py @@ -37,9 +37,30 @@ "export": "fast_agent.cli.commands.export:app", } +LAZY_SUBCOMMAND_HELP: dict[str, str] = { + "acp": "Start fast-agent as an ACP stdio server (convenience wrapper for 'serve --transport acp').", + "auth": "Manage OAuth tokens stored in the OS keyring for MCP HTTP/SSE servers (identity = base URL).", + "batch": "Run batch processing jobs.", + "bootstrap": "Create fast-agent quickstarts", + "cards": "Manage card packs (list/add/remove/update/publish).", + "check": "Check and diagnose FastAgent configuration", + "config": "Configure fast-agent settings interactively.", + "demo": "Demo commands for UI features.", + "export": "Export persisted session traces.", + "go": "Run an interactive agent directly from the command line without creating an agent.py file", + "model": "Interactive model reference setup.", + "plugins": "Manage command plugins (list/add/remove/update).", + "quickstart": "Create fast-agent quickstarts", + "scaffold": "Initialize a new FastAgent project with configuration files and example agent.", + "serve": "Expose fast-agent to clients over MCP (http or stdio), ACP, or A2A, without writing an agent.py file", + "skills": "Manage skills (list/available/search/add/remove/update).", +} + class LazyGroup(TyperGroup): lazy_subcommands: dict[str, str] = {} + lazy_help: dict[str, str] = {} + _rendering_root_help: bool = False def parse_args(self, ctx: click.Context, args: list[str]) -> list[str]: if _first_root_command(args) == "go": @@ -53,6 +74,8 @@ def get_command(self, ctx: click.Context, cmd_name: str) -> click.Command | None target = self.lazy_subcommands.get(cmd_name) if not target: return None + if self._rendering_root_help: + return click.Command(cmd_name, help=self.lazy_help.get(cmd_name, "")) module_path, app_name = target.split(":", 1) module = importlib.import_module(module_path) typer_app = getattr(module, app_name) @@ -60,6 +83,13 @@ def get_command(self, ctx: click.Context, cmd_name: str) -> click.Command | None command.name = cmd_name return command + def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None: + self._rendering_root_help = True + try: + super().format_help(ctx, formatter) + finally: + self._rendering_root_help = False + app = typer.Typer( cls=LazyGroup, @@ -67,6 +97,7 @@ def get_command(self, ctx: click.Context, cmd_name: str) -> click.Command | None add_completion=False, # We'll add this later when we have more commands ) LazyGroup.lazy_subcommands = LAZY_SUBCOMMANDS +LazyGroup.lazy_help = LAZY_SUBCOMMAND_HELP def _first_root_command(args: list[str]) -> str | None: diff --git a/src/fast_agent/cli/runtime/agent_setup.py b/src/fast_agent/cli/runtime/agent_setup.py index 4eae5666a..ac0a7d54b 100644 --- a/src/fast_agent/cli/runtime/agent_setup.py +++ b/src/fast_agent/cli/runtime/agent_setup.py @@ -15,6 +15,7 @@ import typer from pydantic import BaseModel +from fast_agent.agents.agent_types import AgentConfig, AgentType from fast_agent.cli.command_support import get_settings_or_exit from fast_agent.cli.commands.server_helpers import add_servers_to_config from fast_agent.cli.constants import RESUME_LATEST_SENTINEL @@ -53,6 +54,10 @@ logger = get_logger(__name__) +_STARTUP_MODEL_DEFINED = "defined" +_STARTUP_MODEL_NOT_REQUIRED = "not_required" +_STARTUP_MODEL_UNSATISFIED = "unsatisfied" + async def _structured_call( agent_obj: Any, @@ -101,21 +106,17 @@ def _should_prompt_for_model_picker( return stdin_is_tty and stdout_is_tty -def _explicit_agent_cards_define_startup_model( - request: AgentRunRequest, - *, - model_references: Mapping[str, Mapping[str, str]] | None = None, -) -> bool: - if not request.agent_cards or request.target_agent_name: - return False +def _load_explicit_agent_cards(request: AgentRunRequest): + if not request.agent_cards: + return None try: - from fast_agent.core.agent_card_loader import load_agent_cards + from fast_agent.core.agent_card_loader import LoadedAgentCard, load_agent_cards from fast_agent.io.source_resolver import REMOTE_TEXT_SCHEMES, materialize_text_source except Exception: - return False + return None - loaded_cards = [] + loaded_cards: list[LoadedAgentCard] = [] temp_paths: list[Path] = [] try: for source in request.agent_cards: @@ -128,41 +129,99 @@ def _explicit_agent_cards_define_startup_model( path = materialize_text_source(source, label="AgentCard source") loaded_cards.extend(load_agent_cards(path)) except Exception: - return False + return None finally: for path in temp_paths: path.unlink(missing_ok=True) - runnable_configs = [] + return loaded_cards + + +def _selected_startup_agent_config(request: AgentRunRequest) -> AgentConfig | None: + loaded_cards = _load_explicit_agent_cards(request) + if not loaded_cards: + return None + + runnable_cards = [] for card in loaded_cards: if card.agent_data.get("tool_only", False): continue config = card.agent_data.get("config") - if config is None: + if not isinstance(config, AgentConfig): continue - runnable_configs.append(config) + runnable_cards.append((card, config)) - if len(runnable_configs) != 1: - return False + if request.target_agent_name: + runnable_cards = [ + (card, config) for card, config in runnable_cards if card.name == request.target_agent_name + ] + elif len(runnable_cards) > 1: + default_cards = [ + (card, config) for card, config in runnable_cards if config.default + ] + if len(default_cards) == 1: + runnable_cards = default_cards + + if len(runnable_cards) != 1: + return None + return runnable_cards[0][1] + + +def _explicit_agent_cards_startup_model_status( + request: AgentRunRequest, + *, + model_references: Mapping[str, Mapping[str, str]] | None = None, +) -> str: + config = _selected_startup_agent_config(request) + if config is None: + return _STARTUP_MODEL_UNSATISFIED - model = runnable_configs[0].model + if config.agent_type == AgentType.A2A: + return _STARTUP_MODEL_NOT_REQUIRED + + model = config.model if not isinstance(model, str): - return False + return _STARTUP_MODEL_UNSATISFIED model_spec = model.strip() if not model_spec: - return False + return _STARTUP_MODEL_UNSATISFIED if not model_spec.startswith("$"): - return True + return _STARTUP_MODEL_DEFINED try: from fast_agent.core.model_resolution import resolve_model_reference resolved_model = resolve_model_reference(model_spec, model_references) except ModelConfigError: - return False + return _STARTUP_MODEL_UNSATISFIED + + return _STARTUP_MODEL_DEFINED if resolved_model.strip() else _STARTUP_MODEL_UNSATISFIED - return bool(resolved_model.strip()) + +def _explicit_agent_cards_define_startup_model( + request: AgentRunRequest, + *, + model_references: Mapping[str, Mapping[str, str]] | None = None, +) -> bool: + return ( + _explicit_agent_cards_startup_model_status( + request, + model_references=model_references, + ) + == _STARTUP_MODEL_DEFINED + ) + + +def _explicit_agent_cards_satisfy_startup_model( + request: AgentRunRequest, + *, + model_references: Mapping[str, Mapping[str, str]] | None = None, +) -> bool: + return _explicit_agent_cards_startup_model_status( + request, + model_references=model_references, + ) in {_STARTUP_MODEL_DEFINED, _STARTUP_MODEL_NOT_REQUIRED} @@ -1134,7 +1193,7 @@ async def run_agent_request(request: AgentRunRequest) -> None: if request.model is None: settings = _load_request_settings(request) - startup_model_defined_by_card = _explicit_agent_cards_define_startup_model( + startup_model_satisfied_by_card = _explicit_agent_cards_satisfy_startup_model( request, model_references=getattr(settings, "model_references", None), ) @@ -1146,7 +1205,7 @@ async def run_agent_request(request: AgentRunRequest) -> None: if ( explicit_source is None - and not startup_model_defined_by_card + and not startup_model_satisfied_by_card and _should_prompt_for_model_picker( request, stdin_is_tty=sys.stdin.isatty(), @@ -1169,7 +1228,7 @@ async def run_agent_request(request: AgentRunRequest) -> None: model_spec=request.model, ) startup_model_source_override = "model picker" - elif explicit_source is None and not startup_model_defined_by_card: + elif explicit_source is None and not startup_model_satisfied_by_card: _, initial_model_spec = _resolve_model_picker_initial_selection( settings=settings, ) diff --git a/src/fast_agent/llm/provider/openai/codex_oauth.py b/src/fast_agent/llm/provider/openai/codex_oauth.py index f010b59da..7b06083a8 100644 --- a/src/fast_agent/llm/provider/openai/codex_oauth.py +++ b/src/fast_agent/llm/provider/openai/codex_oauth.py @@ -56,6 +56,8 @@ def delete_password(self, service: str, username: str) -> None: ... CODEX_TOKEN_META_KEY = f"{CODEX_TOKEN_KEY}:meta" CODEX_TOKEN_CHUNK_PREFIX = f"{CODEX_TOKEN_KEY}:chunk" CODEX_KEYRING_MAX_PAYLOAD_BYTES = 512 + + class CodexOAuthTokens(BaseModel): access_token: str refresh_token: str | None = None @@ -69,6 +71,17 @@ def is_expired(self, margin_seconds: int = 60) -> bool: return time.time() >= (self.expires_at - margin_seconds) +_AuthJsonFingerprint = tuple[int, int, int] | None +_KeyringFingerprint = str | None +_CodexTokenCacheKey = tuple[str, bool, _AuthJsonFingerprint, _KeyringFingerprint] +_CodexTokenCache = tuple[ + _CodexTokenCacheKey, + CodexOAuthTokens | None, + str | None, +] +_codex_token_cache: _CodexTokenCache | None = None + + @dataclass class _CallbackResult: authorization_code: str | None = None @@ -240,6 +253,26 @@ def _prefer_codex_cli_auth_path() -> bool: return _resolve_codex_cli_auth_path() != _default_codex_cli_auth_path() +def _auth_json_fingerprint(auth_path: Path) -> _AuthJsonFingerprint: + try: + stat = auth_path.stat() + except OSError: + return None + return (stat.st_mtime_ns, stat.st_size, stat.st_ino) + + +def _keyring_payload_fingerprint(payload: str | None) -> _KeyringFingerprint: + if payload is None: + return None + return hashlib.sha256(payload.encode("utf-8")).hexdigest() + + +def clear_codex_token_cache() -> None: + global _codex_token_cache + + _codex_token_cache = None + + def _safe_delete(keyring_module: _KeyringProtocol, username: str) -> None: try: keyring_module.delete_password(CODEX_KEYRING_SERVICE, username) @@ -458,21 +491,48 @@ def _save_codex_cli_tokens(tokens: CodexOAuthTokens) -> None: def _load_codex_tokens_with_source() -> tuple[CodexOAuthTokens | None, str | None]: - if _prefer_codex_cli_auth_path(): + global _codex_token_cache + + auth_path = _resolve_codex_cli_auth_path() + prefer_auth_json = _prefer_codex_cli_auth_path() + auth_json_fingerprint = _auth_json_fingerprint(auth_path) + if _codex_token_cache is not None: + cache_key, cached_tokens, cached_source = _codex_token_cache + cache_path, cache_prefer_auth_json, cache_auth_json_fingerprint, _ = cache_key + if ( + cache_path == str(auth_path) + and cache_prefer_auth_json == prefer_auth_json + and cache_auth_json_fingerprint == auth_json_fingerprint + ): + return cached_tokens, cached_source + + keyring_payload = None if prefer_auth_json else _get_keyring_password() + cache_key = ( + str(auth_path), + prefer_auth_json, + auth_json_fingerprint, + _keyring_payload_fingerprint(keyring_payload), + ) + if prefer_auth_json: tokens = _load_codex_cli_tokens() if tokens: + _codex_token_cache = (cache_key, tokens, "auth.json") return tokens, "auth.json" - payload = _get_keyring_password() - if payload: + if keyring_payload: try: - return CodexOAuthTokens.model_validate_json(payload), "keyring" + tokens = CodexOAuthTokens.model_validate_json(keyring_payload) + _codex_token_cache = (cache_key, tokens, "keyring") + return tokens, "keyring" except Exception: + _codex_token_cache = (cache_key, None, None) return None, None tokens = _load_codex_cli_tokens() if tokens: + _codex_token_cache = (cache_key, tokens, "auth.json") return tokens, "auth.json" + _codex_token_cache = (cache_key, None, None) return None, None @@ -488,13 +548,34 @@ def load_codex_tokens() -> CodexOAuthTokens | None: def save_codex_tokens(tokens: CodexOAuthTokens) -> None: - if _prefer_codex_cli_auth_path(): + global _codex_token_cache + + auth_path = _resolve_codex_cli_auth_path() + prefer_auth_json = _prefer_codex_cli_auth_path() + if prefer_auth_json: _save_codex_cli_tokens(tokens) + _codex_token_cache = ( + (str(auth_path), True, _auth_json_fingerprint(auth_path), None), + tokens, + "auth.json", + ) return - _set_keyring_password(tokens.model_dump_json()) + payload = tokens.model_dump_json() + _set_keyring_password(payload) + _codex_token_cache = ( + ( + str(auth_path), + False, + _auth_json_fingerprint(auth_path), + _keyring_payload_fingerprint(payload), + ), + tokens, + "keyring", + ) def clear_codex_tokens() -> bool: + clear_codex_token_cache() if not _keyring_payload_present(): return False try: diff --git a/src/fast_agent/llm/provider/openai/codex_responses.py b/src/fast_agent/llm/provider/openai/codex_responses.py index 1b8d6cb4e..c60b083e7 100644 --- a/src/fast_agent/llm/provider/openai/codex_responses.py +++ b/src/fast_agent/llm/provider/openai/codex_responses.py @@ -130,10 +130,12 @@ async def _create_websocket_connection( data={"url": url}, ) from fast_agent.llm.provider.openai.codex_oauth import ( + clear_codex_token_cache, load_codex_tokens, refresh_codex_tokens, save_codex_tokens, ) + clear_codex_token_cache() tokens = load_codex_tokens() if not tokens or not tokens.refresh_token: raise ProviderKeyError( diff --git a/tests/integration/a2a/conftest.py b/tests/integration/a2a/conftest.py index 235650302..15bad2e85 100644 --- a/tests/integration/a2a/conftest.py +++ b/tests/integration/a2a/conftest.py @@ -1,6 +1,7 @@ from __future__ import annotations import asyncio +import uuid from dataclasses import dataclass from typing import TYPE_CHECKING @@ -21,7 +22,9 @@ AgentInterface, AgentProvider, AgentSkill, + Message, Part, + Role, Task, TaskState, TaskStatus, @@ -67,6 +70,17 @@ def _is_help_query(query: str) -> bool: return normalized in {"help", "?", "commands", "menu"} or "what can you do" in normalized +def _agent_message(*, text: str, context_id: str | None) -> Message: + message = Message( + role=Role.ROLE_AGENT, + message_id=str(uuid.uuid4()), + parts=[Part(text=text)], + ) + if context_id: + message.context_id = context_id + return message + + @dataclass(frozen=True) class A2ATestServer: base_url: str @@ -89,7 +103,40 @@ async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None await updater.cancel() async def execute(self, context: RequestContext, event_queue: EventQueue) -> None: - if not context.message or not context.task_id or not context.context_id: + if not context.message: + return + query = context.get_user_input() + self.seen_queries.append(query) + self.seen_part_kinds.append( + [part.WhichOneof("content") or "unknown" for part in context.message.parts] + ) + + if _is_help_query(query) and context.task_id not in self.pending_input_tasks: + await event_queue.enqueue_event( + _agent_message(text=FAKE_A2A_HELP, context_id=context.context_id) + ) + return + + normalized_query = query.lower() + taskless_query = not any( + marker in normalized_query + for marker in [ + "long stream", + "stream", + "respond with files", + "artifact append", + "need input", + ] + ) + if context.task_id not in self.pending_input_tasks and taskless_query: + await asyncio.sleep(0.01) + summary = ",".join(self.seen_part_kinds[-1]) + await event_queue.enqueue_event( + _agent_message(text=f"echo: {query} [{summary}]", context_id=context.context_id) + ) + return + + if not context.task_id or not context.context_id: return await event_queue.enqueue_event( @@ -110,12 +157,6 @@ async def execute(self, context: RequestContext, event_queue: EventQueue) -> Non message=updater.new_agent_message(parts=[Part(text="working")]) ) - query = context.get_user_input() - self.seen_queries.append(query) - self.seen_part_kinds.append( - [part.WhichOneof("content") or "unknown" for part in context.message.parts] - ) - if _is_help_query(query): if context.task_id in self.pending_input_tasks: await updater.update_status( @@ -132,13 +173,6 @@ async def execute(self, context: RequestContext, event_queue: EventQueue) -> Non ), ) return - await updater.add_artifact( - parts=[Part(text=FAKE_A2A_HELP)], - name="help", - last_chunk=True, - ) - await updater.complete() - return if context.task_id in self.pending_input_tasks: self.pending_input_tasks.remove(context.task_id) @@ -237,14 +271,6 @@ async def execute(self, context: RequestContext, event_queue: EventQueue) -> Non ) return - await asyncio.sleep(0.01) - summary = ",".join(self.seen_part_kinds[-1]) - await updater.add_artifact( - parts=[Part(text=f"echo: {query} [{summary}]")], - name="response", - last_chunk=True, - ) - await updater.complete() @pytest_asyncio.fixture diff --git a/tests/integration/a2a/fake_server.py b/tests/integration/a2a/fake_server.py index 342401f76..1a03056ae 100644 --- a/tests/integration/a2a/fake_server.py +++ b/tests/integration/a2a/fake_server.py @@ -17,6 +17,7 @@ import argparse import asyncio import logging +import uuid from typing import TYPE_CHECKING import uvicorn @@ -31,7 +32,9 @@ AgentInterface, AgentProvider, AgentSkill, + Message, Part, + Role, Task, TaskState, TaskStatus, @@ -69,6 +72,17 @@ def _is_help_query(query: str) -> bool: return normalized in {"help", "?", "commands", "menu"} or "what can you do" in normalized +def _agent_message(*, text: str, context_id: str | None) -> Message: + message = Message( + role=Role.ROLE_AGENT, + message_id=str(uuid.uuid4()), + parts=[Part(text=text)], + ) + if context_id: + message.context_id = context_id + return message + + class FakeAgentExecutor(AgentExecutor): def __init__(self) -> None: self.pending_input_tasks: set[str] = set() @@ -82,7 +96,33 @@ async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None await updater.cancel() async def execute(self, context: RequestContext, event_queue: EventQueue) -> None: - if not context.message or not context.task_id or not context.context_id: + if not context.message: + return + + query = context.get_user_input() + if _is_help_query(query) and context.task_id not in self.pending_input_tasks: + await event_queue.enqueue_event( + _agent_message(text=FAKE_A2A_HELP, context_id=context.context_id) + ) + return + + taskless_query = not any( + marker in query.lower() + for marker in ["long stream", "stream", "files", "need input"] + ) + if context.task_id not in self.pending_input_tasks and taskless_query: + kinds = ",".join( + part.WhichOneof("content") or "unknown" for part in context.message.parts + ) + await event_queue.enqueue_event( + _agent_message( + text=f"fake echo: {query} [{kinds}]", + context_id=context.context_id, + ) + ) + return + + if not context.task_id or not context.context_id: return await event_queue.enqueue_event( @@ -100,7 +140,6 @@ async def execute(self, context: RequestContext, event_queue: EventQueue) -> Non ) await updater.start_work(message=updater.new_agent_message(parts=[Part(text="working")])) - query = context.get_user_input() if _is_help_query(query): if context.task_id in self.pending_input_tasks: await updater.update_status( @@ -117,13 +156,6 @@ async def execute(self, context: RequestContext, event_queue: EventQueue) -> Non ), ) return - await updater.add_artifact( - parts=[Part(text=FAKE_A2A_HELP)], - name="help", - last_chunk=True, - ) - await updater.complete() - return if context.task_id in self.pending_input_tasks: self.pending_input_tasks.remove(context.task_id) @@ -185,13 +217,6 @@ async def execute(self, context: RequestContext, event_queue: EventQueue) -> Non ) return - kinds = ",".join(part.WhichOneof("content") or "unknown" for part in context.message.parts) - await updater.add_artifact( - parts=[Part(text=f"fake echo: {query} [{kinds}]")], - name="response", - last_chunk=True, - ) - await updater.complete() def build_app(host: str, port: int) -> FastAPI: diff --git a/tests/integration/a2a/test_remote_agent_runtime.py b/tests/integration/a2a/test_remote_agent_runtime.py index eb5896f98..15e2c6a7b 100644 --- a/tests/integration/a2a/test_remote_agent_runtime.py +++ b/tests/integration/a2a/test_remote_agent_runtime.py @@ -33,7 +33,7 @@ async def _send_text(base_url: str, transport: str) -> A2ARemoteAgent: assert agent.remote_card is not None assert agent.remote_card.name == "fast-agent test A2A server" assert agent.context_id - assert agent.last_task_state == "TASK_STATE_COMPLETED" + assert agent.last_task_state is None assert agent.current_task_id is None return agent except Exception: @@ -127,6 +127,9 @@ async def test_a2a_fake_server_help_lists_available_prompts(a2a_test_server) -> await agent.shutdown() assert response.all_text() == FAKE_A2A_HELP + assert agent.context_id + assert agent.current_task_id is None + assert agent.last_task_state is None @pytest.mark.integration diff --git a/tests/unit/fast_agent/commands/test_cli_completion_help.py b/tests/unit/fast_agent/commands/test_cli_completion_help.py index c6a109ecf..4fc8865fc 100644 --- a/tests/unit/fast_agent/commands/test_cli_completion_help.py +++ b/tests/unit/fast_agent/commands/test_cli_completion_help.py @@ -1,5 +1,6 @@ from typer.testing import CliRunner +from fast_agent.cli import main as cli_main from fast_agent.cli.commands import ( acp, auth, @@ -14,6 +15,7 @@ serve, setup, ) +from fast_agent.cli.main import app as root_app def test_command_help_hides_typer_completion_options(): @@ -33,8 +35,25 @@ def test_command_help_hides_typer_completion_options(): quickstart.app, ] - for app in command_apps: - result = runner.invoke(app, ["--help"], terminal_width=160) + for command_app in command_apps: + result = runner.invoke(command_app, ["--help"], terminal_width=160) assert result.exit_code == 0 assert "--install-completion" not in result.output assert "--show-completion" not in result.output + + +def test_root_help_uses_lazy_command_metadata(monkeypatch): + imported_modules: list[str] = [] + + def fail_import(name: str): + imported_modules.append(name) + raise AssertionError(f"root help should not import lazy command module: {name}") + + monkeypatch.setattr(cli_main.importlib, "import_module", fail_import) + + result = CliRunner().invoke(root_app, ["--help"], terminal_width=160) + + assert result.exit_code == 0 + assert "go" in result.output + assert "Run an interactive agent" in result.output + assert imported_modules == [] diff --git a/tests/unit/fast_agent/commands/test_cli_main_routing.py b/tests/unit/fast_agent/commands/test_cli_main_routing.py index 02639049c..350776f23 100644 --- a/tests/unit/fast_agent/commands/test_cli_main_routing.py +++ b/tests/unit/fast_agent/commands/test_cli_main_routing.py @@ -90,6 +90,16 @@ def test_auto_routes_to_go_when_no_shell_used_at_root() -> None: assert "--no-shell" in output +def test_auto_routes_to_go_when_a2a_used_at_root() -> None: + result = _run_fast_agent_cli("--a2a", "http://localhost:8001", "--help") + output = strip_ansi(result.stdout) + + assert result.returncode == 0, result.stderr + assert "go [OPTIONS] COMMAND" in output + assert "--a2a" in output + assert "--a2a-transport" in output + + def test_resume_sentinel_is_not_added_for_batch( monkeypatch: pytest.MonkeyPatch, ) -> None: diff --git a/tests/unit/fast_agent/commands/test_runtime_model_picker_bootstrap.py b/tests/unit/fast_agent/commands/test_runtime_model_picker_bootstrap.py index 6e47366ff..be30044fa 100644 --- a/tests/unit/fast_agent/commands/test_runtime_model_picker_bootstrap.py +++ b/tests/unit/fast_agent/commands/test_runtime_model_picker_bootstrap.py @@ -20,6 +20,7 @@ from fast_agent.cli.runtime.agent_setup import ( _emit_model_picker_keyring_notice, _explicit_agent_cards_define_startup_model, + _explicit_agent_cards_satisfy_startup_model, _generic_model_prompt_default, _load_request_settings, _normalize_generic_model_spec, @@ -60,6 +61,7 @@ def _make_request( prompt_file: str | None = None, agent_cards: list[str] | None = None, card_tools: list[str] | None = None, + target_agent_name: str | None = None, ) -> AgentRunRequest: return AgentRunRequest( name="test", @@ -76,7 +78,7 @@ def _make_request( url_servers=None, stdio_servers=None, agent_name="agent", - target_agent_name=None, + target_agent_name=target_agent_name, skills_directory=None, environment_dir=None, noenv=False, @@ -191,6 +193,30 @@ def fake_read_text_source(source: str, *, label: str) -> str: assert _explicit_agent_cards_define_startup_model(request) is False +def test_explicit_a2a_agent_card_satisfies_startup_model_without_local_model( + tmp_path: Path, +) -> None: + card_path = tmp_path / "remote.yaml" + card_path.write_text( + "\n".join( + [ + "type: a2a", + "name: a2a_remote", + "url: http://127.0.0.1:41242", + "", + ] + ), + encoding="utf-8", + ) + request = _make_request( + agent_cards=[str(card_path)], + target_agent_name="a2a_remote", + ) + + assert _explicit_agent_cards_define_startup_model(request) is False + assert _explicit_agent_cards_satisfy_startup_model(request) is True + + @pytest.mark.parametrize( ("model_references", "expected"), [ diff --git a/tests/unit/fast_agent/llm/providers/test_codex_oauth.py b/tests/unit/fast_agent/llm/providers/test_codex_oauth.py index 3f0a7405e..f97ba5e24 100644 --- a/tests/unit/fast_agent/llm/providers/test_codex_oauth.py +++ b/tests/unit/fast_agent/llm/providers/test_codex_oauth.py @@ -42,6 +42,87 @@ def test_explicit_auth_json_path_overrides_keyring(monkeypatch, tmp_path: Path) assert tokens.access_token == "local-token" +def test_load_codex_tokens_reuses_parsed_tokens_for_unchanged_keyring_payload( + monkeypatch, + tmp_path: Path, +) -> None: + monkeypatch.delenv("CODEX_AUTH_JSON_PATH", raising=False) + monkeypatch.delenv("CODEX_HOME", raising=False) + monkeypatch.setattr(codex_oauth.Path, "home", lambda: tmp_path) + monkeypatch.setattr(codex_oauth, "_codex_token_cache", None) + calls = 0 + + def _load_keyring() -> str: + nonlocal calls + calls += 1 + return json.dumps({"access_token": "keyring-token", "token_type": "Bearer"}) + + monkeypatch.setattr(codex_oauth, "_get_keyring_password", _load_keyring) + + first = codex_oauth.load_codex_tokens() + second = codex_oauth.load_codex_tokens() + + assert first is not None + assert second is not None + assert first.access_token == "keyring-token" + assert second.access_token == "keyring-token" + assert first is second + assert calls == 1 + + +def test_load_codex_tokens_invalidates_cache_when_keyring_payload_changes( + monkeypatch, + tmp_path: Path, +) -> None: + monkeypatch.delenv("CODEX_AUTH_JSON_PATH", raising=False) + monkeypatch.delenv("CODEX_HOME", raising=False) + monkeypatch.setattr(codex_oauth.Path, "home", lambda: tmp_path) + monkeypatch.setattr(codex_oauth, "_codex_token_cache", None) + keyring_payload = json.dumps({"access_token": "initial-token", "token_type": "Bearer"}) + + def _load_keyring() -> str: + return keyring_payload + + monkeypatch.setattr(codex_oauth, "_get_keyring_password", _load_keyring) + + first = codex_oauth.load_codex_tokens() + keyring_payload = json.dumps({"access_token": "external-token", "token_type": "Bearer"}) + second = codex_oauth.load_codex_tokens() + codex_oauth.clear_codex_token_cache() + third = codex_oauth.load_codex_tokens() + + assert first is not None + assert second is not None + assert third is not None + assert first.access_token == "initial-token" + assert second.access_token == "initial-token" + assert third.access_token == "external-token" + + +def test_load_codex_tokens_invalidates_cache_when_auth_json_changes( + monkeypatch, + tmp_path: Path, +) -> None: + auth_path = tmp_path / "local-auth.json" + monkeypatch.setenv("CODEX_AUTH_JSON_PATH", str(auth_path)) + monkeypatch.delenv("CODEX_HOME", raising=False) + monkeypatch.setattr(codex_oauth, "_codex_token_cache", None) + + auth_path.write_text( + json.dumps({"tokens": {"access_token": "initial-token", "token_type": "Bearer"}}) + ) + first = codex_oauth.load_codex_tokens() + auth_path.write_text( + json.dumps({"tokens": {"access_token": "external-token", "token_type": "Bearer"}}) + ) + second = codex_oauth.load_codex_tokens() + + assert first is not None + assert second is not None + assert first.access_token == "initial-token" + assert second.access_token == "external-token" + + def test_save_codex_tokens_writes_local_auth_file_without_keyring(monkeypatch, tmp_path: Path) -> None: auth_path = tmp_path / ".codex" / "auth.json" auth_path.parent.mkdir(parents=True, exist_ok=True) diff --git a/tests/unit/fast_agent/test_a2a_remote_agent_events.py b/tests/unit/fast_agent/test_a2a_remote_agent_events.py index dceb795bb..d5a4fdba9 100644 --- a/tests/unit/fast_agent/test_a2a_remote_agent_events.py +++ b/tests/unit/fast_agent/test_a2a_remote_agent_events.py @@ -6,7 +6,9 @@ import pytest from a2a.types import ( Artifact, + Message, Part, + Role, StreamResponse, Task, TaskArtifactUpdateEvent, @@ -215,6 +217,30 @@ async def test_a2a_remote_agent_first_request_omits_context_and_task_ids() -> No assert agent.context_id == "ctx-server" +@pytest.mark.asyncio +async def test_a2a_remote_agent_message_only_response_updates_context_without_task_state() -> None: + agent = _remote_agent() + + result = await agent._consume_events( + _events( + StreamResponse( + message=Message( + role=Role.ROLE_AGENT, + message_id="message-only", + context_id="ctx-message", + parts=[Part(text="hello")], + ) + ) + ) + ) + + assert result.text == "hello" + assert result.state is None + assert agent.context_id == "ctx-message" + assert agent.current_task_id is None + assert agent.last_task_state is None + + @pytest.mark.asyncio async def test_a2a_remote_agent_streams_chunks_to_live_display() -> None: agent = _remote_agent() diff --git a/tests/unit/fast_agent/test_package_lazy_exports.py b/tests/unit/fast_agent/test_package_lazy_exports.py new file mode 100644 index 000000000..531dce2bf --- /dev/null +++ b/tests/unit/fast_agent/test_package_lazy_exports.py @@ -0,0 +1,63 @@ +from __future__ import annotations + +import importlib +import sys +from typing import TYPE_CHECKING + +import pytest + +if TYPE_CHECKING: + from collections.abc import Iterator + + +@pytest.fixture(autouse=True) +def restore_fast_agent_import_state() -> Iterator[None]: + original_modules = { + name: module for name, module in sys.modules.items() if name.startswith("fast_agent") + } + yield + for name in list(sys.modules): + if name.startswith("fast_agent"): + sys.modules.pop(name, None) + sys.modules.update(original_modules) + + +def test_package_import_defers_config_until_public_export_access() -> None: + sys.modules.pop("fast_agent", None) + sys.modules.pop("fast_agent.config", None) + + fast_agent = importlib.import_module("fast_agent") + + assert "fast_agent.config" not in sys.modules + assert fast_agent.Settings.__name__ == "Settings" + assert "fast_agent.config" in sys.modules + + +def test_package_import_defers_types_until_public_export_access() -> None: + sys.modules.pop("fast_agent", None) + sys.modules.pop("fast_agent.types", None) + + fast_agent = importlib.import_module("fast_agent") + + assert "fast_agent.types" not in sys.modules + assert fast_agent.RequestParams.__name__ == "RequestParams" + assert "fast_agent.types" in sys.modules + + +def test_a2a_package_import_defers_server_stack() -> None: + sys.modules.pop("fast_agent.a2a", None) + sys.modules.pop("fast_agent.a2a.server", None) + + importlib.import_module("fast_agent.a2a") + + assert "fast_agent.a2a.server" not in sys.modules + + +def test_a2a_connect_import_defers_config() -> None: + sys.modules.pop("fast_agent.a2a.connect", None) + sys.modules.pop("fast_agent.config", None) + + connect = importlib.import_module("fast_agent.a2a.connect") + + assert "fast_agent.config" not in sys.modules + assert connect.normalize_a2a_transport("jsonrpc") == "JSONRPC" From 4238621dd7f5c72d24b82135c37bc4dbbd005e4b Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Wed, 27 May 2026 17:50:32 +0100 Subject: [PATCH 58/58] temporary commit of facts example --- examples/a2a/README.md | 63 +++++++++++++++++++++++++++++++ examples/a2a/agent-cards/facts.md | 8 ++++ examples/a2a/facts_server.py | 40 ++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 examples/a2a/README.md create mode 100644 examples/a2a/agent-cards/facts.md create mode 100644 examples/a2a/facts_server.py diff --git a/examples/a2a/README.md b/examples/a2a/README.md new file mode 100644 index 000000000..99cfe28f8 --- /dev/null +++ b/examples/a2a/README.md @@ -0,0 +1,63 @@ +# A2A examples + +## Streaming facts server + +`facts_server.py` is the fast-agent equivalent of the ADK facts sample. It serves +a default `facts_agent` over A2A and streams model output to A2A clients. + +Run it: + +```bash +GOOGLE_API_KEY=... uv run python examples/a2a/facts_server.py +``` + +Defaults: + +- `HOST=0.0.0.0` +- `PORT=8001` +- `MODEL`/`FAST_AGENT_MODEL=gemini25` + +The server exposes: + +- AgentCard: `http://localhost:8001/.well-known/agent-card.json` +- JSON-RPC: `http://localhost:8001/a2a/jsonrpc` +- HTTP+JSON: `http://localhost:8001/a2a/rest` + +Test it with fast-agent as an A2A client: + +```bash +uv run fast-agent go \ + --a2a http://localhost:8001 \ + --a2a-transport JSONRPC \ + --message "Tell me three surprising facts about octopuses." +``` + +Streaming is handled by `fast.start_server(transport="a2a")`: fast-agent stream +listeners are converted into A2A `TaskArtifactUpdateEvent` updates. + +## Card-based facts server + +The same agent can be served without a Python wrapper using the AgentCard in +`agent-cards/facts.md`: + +```bash +GOOGLE_API_KEY=... uv run fast-agent serve a2a \ + --host 0.0.0.0 \ + --port 8001 \ + --name facts-a2a \ + --agent-cards examples/a2a/agent-cards/facts.md +``` + +Override the model from the CLI if desired: + +```bash +uv run fast-agent serve a2a \ + --port 8001 \ + --name facts-a2a \ + --agent-cards examples/a2a/agent-cards/facts.md \ + --model gemini25 +``` + +Here `facts-a2a` is the served A2A system name, while `facts` is the fast-agent +AgentCard/skill name. Keeping them distinct avoids the name clash/confusion with +the ADK sample's `facts_agent`. diff --git a/examples/a2a/agent-cards/facts.md b/examples/a2a/agent-cards/facts.md new file mode 100644 index 000000000..c8579ccaa --- /dev/null +++ b/examples/a2a/agent-cards/facts.md @@ -0,0 +1,8 @@ +--- +type: agent +name: facts +description: Agent to give interesting facts. +default: true +skills: [] +--- +You are a helpful agent who can provide interesting facts. diff --git a/examples/a2a/facts_server.py b/examples/a2a/facts_server.py new file mode 100644 index 000000000..2fa53365b --- /dev/null +++ b/examples/a2a/facts_server.py @@ -0,0 +1,40 @@ +import asyncio +import os + +from fast_agent import FastAgent + +HOST = os.getenv("HOST", "0.0.0.0") +PORT = int(os.getenv("PORT", "8001")) +MODEL = os.getenv("FAST_AGENT_MODEL", os.getenv("MODEL", "gemini25")) + +fast = FastAgent( + "fast-agent facts A2A server", + parse_cli_args=False, + quiet=True, +) + + +@fast.agent( + name="facts_agent", + model=MODEL, + instruction="You are a helpful agent who can provide interesting facts.", + default=True, +) +async def facts_agent() -> None: + """Default A2A facts agent.""" + pass + + +async def main() -> None: + await fast.start_server( + transport="a2a", + host=HOST, + port=PORT, + server_name="facts_agent", + server_description="Agent to give interesting facts.", + instance_scope="connection", + ) + + +if __name__ == "__main__": + asyncio.run(main())