mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
fix(grok): record a usage session for interactive intake/secretary (M1+M7)
_spawn_intake_container / _spawn_secretary_container built the AgentInstance by hand and never recorded an agent_spawn_sessions row, so the reap finalizer had no usage_session_id to look up — every interactive session (Claude or Grok) finalized at 0 tokens / $0 in the rollups. Record the session (task_id=None) and pin its id on the instance, mirroring _launch_spawn; the GROK path reads opencode.db by this id, the Claude path reads the transcript. Also correct the grok_intake_main docstring (M7): it claimed the serve process was "gateway-wired" with an "MCP gateway", but interactive intake mounts no gateway — its only tool is propose_draft, registered by the intake-tools.js plugin.
This commit is contained in:
@@ -3,10 +3,13 @@
|
||||
The Grok analogue of ``intake_main``: the same in-container ``POST /turn``
|
||||
receiver and the same relay sink to ``/api/prompter/live/{id}/events``, but the
|
||||
held-open session is an :class:`OpencodeServeSession` (``opencode serve``)
|
||||
instead of a ``ClaudeSDKClient``. ``opencode.json`` (xAI provider + MCP gateway +
|
||||
system prompt) is rendered first so the serve process is gateway-wired exactly
|
||||
like the one-shot Grok path. The ``IntakeDriver`` loop, message source, and relay
|
||||
are reused unchanged — only the ``SessionFactory`` differs.
|
||||
instead of a ``ClaudeSDKClient``. ``opencode.json`` (xAI provider + system
|
||||
prompt) is rendered first. Intake is a human-only interviewer (no gateway verbs);
|
||||
its one action tool, ``propose_draft``, is registered by the ``intake-tools.js``
|
||||
opencode plugin (baked into the grok-prompter image, wired via
|
||||
``ROBOCO_OPENCODE_EXTRA_PLUGINS``) and the driver turns that tool call into the
|
||||
panel's draft card. The ``IntakeDriver`` loop, message source, and relay are
|
||||
reused unchanged — only the ``SessionFactory`` differs.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -3074,6 +3074,14 @@ class AgentOrchestrator:
|
||||
instance.last_activity = datetime.now(UTC)
|
||||
self._instances[INTAKE_AGENT_ID] = instance
|
||||
|
||||
# Record a usage session (task_id=None) and pin its id on the instance so
|
||||
# the reap finalizer can look up token usage — without this an interactive
|
||||
# session finalizes at 0 tokens / $0 (the GROK path reads opencode.db by
|
||||
# this id; the Claude path reads the transcript). Mirrors _launch_spawn.
|
||||
usage_session_id = await self._record_spawn_session(config, None)
|
||||
if usage_session_id is not None:
|
||||
instance.usage_session_id = usage_session_id
|
||||
|
||||
# The relay was already opened on the request path (start_intake_session /
|
||||
# spawn_intake_session) BEFORE the panel connected its SSE stream. Do NOT
|
||||
# re-open here: a second open would swap in a fresh queue and orphan that
|
||||
@@ -3237,6 +3245,12 @@ class AgentOrchestrator:
|
||||
instance.last_activity = datetime.now(UTC)
|
||||
self._instances[SECRETARY_AGENT_ID] = instance
|
||||
|
||||
# Pin a usage session id so the reap finalizer can attribute token usage
|
||||
# (else $0); see the matching note in _spawn_intake_container.
|
||||
usage_session_id = await self._record_spawn_session(config, None)
|
||||
if usage_session_id is not None:
|
||||
instance.usage_session_id = usage_session_id
|
||||
|
||||
logger.info(
|
||||
"Secretary session spawned",
|
||||
session_id=session_id,
|
||||
|
||||
Reference in New Issue
Block a user