6"""Run tools locally and track results in ~/.aquin/commands/."""
7from __future__
import annotations
14def _resolve_card(tool_name: str, result: Any, card: dict[str, Any] |
None) -> dict[str, Any] |
None:
17 if not isinstance(result, dict):
19 existing = result.get(
"card")
20 if isinstance(existing, dict):
24 mapped = card_mapper.to_card(tool_name, result)
25 if mapped
is not None:
27 if result.get(
"type")
and "data" in result:
32def _result_content(tool_name: str, result: Any, card: dict[str, Any] |
None) -> Any:
33 raw = result.get(
"content", result)
if isinstance(result, dict)
else result
34 if isinstance(raw, dict):
37 return slim_tool_result_for_sync(tool_name, raw, card)
47 card: dict[str, Any] |
None,
53 slim =
_result_content(tool_name, result, card)
if isinstance(result, dict)
else result
60 duration_ms=duration_ms,
66 print(f
"[tracked] {name} -> {record_id[:8]}", flush=
True)
74 card: dict[str, Any] |
None =
None,
75 command: str |
None =
None,
76 label: str |
None =
None,
78 """Track a standalone CLI command result locally."""
81 exit_ok =
not (isinstance(result, dict)
and result.get(
"error"))
91 name = command
or tool_name
100 command: str |
None =
None,
106 t0 = time.perf_counter()
108 result = dispatch(name, args, ctx)
110 except Exception
as exc:
111 result = {
"error": str(exc)}
115 duration_ms = int((time.perf_counter() - t0) * 1000)
122 duration_ms=duration_ms,
123 exit_ok=exit_ok
and not (isinstance(result, dict)
and result.get(
"error")),
126 return result
if isinstance(result, dict)
else {
"content": result}
131 args: dict[str, Any],
135 command: str |
None =
None,
139 exit_ok =
not (isinstance(result, dict)
and result.get(
"error"))
152 return result
if isinstance(result, dict)
else {
"content": result}
157 args: dict[str, Any],
160 command: str |
None =
None,
162 """Run catalog/session tools that never touch GPU weights."""
165 if tool_requires_model(name):
166 raise ValueError(f
"dispatch_model_free called for GPU tool: {name}")
172 result = dispatch(name, args, ctx)
173 except Exception
as exc:
176 result = {
"error": friendly_message(exc)}
183 args: dict[str, Any],
186 command: str |
None =
None,
187 ensure_model: str |
None =
None,
188 timeout: float = 1800,
191 Run a tool through the persistent model daemon when it is available, else load
192 in-process and run locally. Either way the result is tracked locally so the
193 user sees the [tracked] line with their own context.
197 if not tool_requires_model(name):
206 if model_daemon.is_running():
207 data = model_daemon.dispatch(name, args, ctx, timeout=timeout)
208 if isinstance(data, dict):
210 result = data.get(
"result")
212 elif "error" in data:
213 err = str(data.get(
"error")
or "")
215 if "not yet ported" in low
or "unknown tool" in low:
219 result = {
"error": err}
228 load_model(resolve_model_id(ensure_model))
229 except Exception
as exc:
232 result = {
"error": friendly_message(exc)}
238 result = dispatch(name, args, ctx)
239 except Exception
as exc:
242 result = {
"error": friendly_message(exc)}
248dispatch_with_sync = dispatch_with_tracking
254 args: dict[str, Any],
257 card: dict[str, Any] |
None =
None,
258 command: str |
None =
None,
260 """Track a catalog/sync CLI result. ``ctx`` is accepted for API compat (session sync is optional)."""
265 command = _TOOL_TO_CLI.get(tool_name, tool_name)
270 """Auth + base URL from engine state (optional session id if present)."""
275 state = _load_state()
276 sid = (state.get(
"active_session_id")
or "").strip()
277 api_key = resolve_api_key(allow_missing=
True)
279 state.get(
"base_url")
or os.environ.get(
"AQUIN_BASE_URL",
"https://api.aquin.app")
281 return {
"session_id": sid,
"api_key": api_key,
"base_url": base_url}
285 """Only required for aquin chat agent API — not for compute."""
290 api_key = (ctx.get(
"api_key")
or resolve_api_key(allow_missing=
True)).strip()
292 print(f
"[auth] {label} needs a cloud session token — not available in local framework mode.", file=sys.stderr)
294 sid = (ctx.get(
"session_id")
or "").strip()
297 f
"[chat] Session id required for {label}.\n"
298 " Open a session tab in the web app and run:\n"
299 " aquin config send-session <session-uuid>",
307 """No-op for compute — kept so old imports don't break."""
312 """Legacy — track locally instead of pushing to cloud."""
313 tool_call_id = kwargs.get(
"tool_call_id")
or str(uuid.uuid4())
316 kwargs.get(
"tool_name")
or "tool",
317 kwargs.get(
"args")
or {},
318 kwargs.get(
"result"),
319 card=kwargs.get(
"card"),
None sync_cli_result(dict[str, Any] ctx, str tool_name, dict[str, Any] args, Any result, *, dict[str, Any]|None card=None, str|None command=None)
None _emit_tracked(str name, str record_id)
None require_active_session(dict[str, Any] ctx, *, str label="this command")
dict[str, Any] run_dispatch(str name, dict[str, Any] args, dict[str, Any] ctx, *, str|None command=None, str|None ensure_model=None, float timeout=1800)
Any _result_content(str tool_name, Any result, dict[str, Any]|None card)
dict[str, Any]|None _resolve_card(str tool_name, Any result, dict[str, Any]|None card)
dict[str, str] session_ctx_from_state()
None track_cli_result(str tool_name, dict[str, Any] args, Any result, *, dict[str, Any]|None card=None, str|None command=None, str|None label=None)
bool push_tool_pair(**Any kwargs)
dict[str, Any] dispatch_model_free(str name, dict[str, Any] args, dict[str, Any] ctx, *, str|None command=None)
dict[str, str] require_session_ctx(*, str label)
str _track(*, str tool_name, str|None command, dict[str, Any] args, Any result, dict[str, Any]|None card, int duration_ms, bool exit_ok)
dict[str, Any] _finish_tracked_dispatch(str name, dict[str, Any] args, dict[str, Any] ctx, Any result, *, str|None command=None)
dict[str, Any] dispatch_with_tracking(str name, dict[str, Any] args, dict[str, Any] ctx, *, str|None command=None)