Skip to content

feat(agents): add chat-mode CLI with sessions + streaming #5

@BjornMelin

Description

@BjornMelin

Background / Motivation

  • We now support: (a) coordinator + specialist agents for every workflow, and (b) direct Exa tools (exa_search, exa_contents, exa_answer, exa_find_similar, exa_search_and_contents, exa_find_similar_and_contents, exa_context) through the OpenAI Agents SDK.
  • Users need an interactive chat-like CLI to iterate naturally, keep conversation context (Sessions), and see streamed results and tool activity without writing code.

User Stories

  • As a developer, I can run exa agents chat and have a persistent conversation that calls search → contents → synthesis automatically.
  • As an operator, I can switch on JSON-lines mode to pipe structured events to other tools.
  • As a researcher, I can resume a thread using --session-id and review usage (tokens/requests) at the end.

Functional Requirements

  • New command: exa agents chat.
    • Flags: --model, --specialist-model, --session-id, --session-backend [none|sqlite|advanced_sqlite], --session-db, --json-lines.
    • Reads from stdin in a loop; Ctrl-C or EOF exits cleanly.
    • Supports concurrent streaming: print assistant deltas and tool events as they arrive.
  • Session handling:
    • Defaults to sqlite when a --session-id (or EXA_DIRECT_AGENTS_SESSION_ID) is present; otherwise none.
    • Honors EXA_DIRECT_AGENTS_SESSION_BACKEND and EXA_DIRECT_AGENTS_SESSION_DB.
  • Output modes:
    • Pretty (default): minimal, readable lines summarizing events; collapse verbose payloads unless requested.
    • JSON-lines: emit each event as one JSON line (no extra whitespace) for machine consumption.
  • Usage summary (optional in a follow-up; see separate issue) printed at exit.

Non-Functional

  • No per-call service closes; lifecycle stays outside tool calls.
  • Zero hidden network calls beyond the Agents SDK.
  • Error messages actionable (toggle reminders, missing env, session problems).

Execution Model

  • Use Agents SDK Runner.run_streamed to get streaming items.
  • Render items:
    • assistant deltas → write text as it arrives (pretty) or events (json-lines).
    • tool calls/results → print tool name, minimal args, and success/fail markers; redact large payloads unless json-lines.

CLI Spec (initial)

  • exa agents chat --input-file is out-of-scope for v1 (stdin only). Resume via --session-id.
  • --json-lines implies raw event printing, including model deltas and tool call events.

Edge Cases

  • Disabled integrations (EXA_DIRECT_ENABLE_OPENAI != 1): show friendly error and exit code 1.
  • Nonexistent AdvancedSQLiteSession module: fallback to SQLiteSession if requested; else error.
  • Long outputs: truncate in pretty mode; never truncate json-lines.

File Impact Map

  • src/exa_direct/cli.py
    • Add _register_agents_chat and _handle_agents_chat.
    • Shared code for session construction and coordinator build (reuse from agents run).
  • src/exa_direct/integrations/agents.py
    • Add run_coordinator_streamed(prompt, settings, context, session...) wrapping Runner.run_streamed.
  • docs/users/agentic_workflows.md
    • Add “Chat Mode” section with examples and tips.
  • tests/unit/cli/test_agents_chat_cli.py
    • Parse flags; stream stub events; toggle disabled; json-lines output.

Step-by-Step Implementation

  1. CLI parse & guards: add chat subcommand; check toggle; parse flags; reuse session and model env logic.
  2. Session construction: sqlite/advanced_sqlite using the same env/args precedence as agents run.
  3. Runner.run_streamed call: iterate events; in pretty mode print compact summaries; in --json-lines print raw events.
  4. Exit behavior: on EOF/Ctrl-C exit 0; ensure no unflushed streams.
  5. Docs: examples (pretty vs json-lines), session usage, sample transcript, and troubleshooting.

Test Strategy

  • Unit-only (no network). Provide a stub or monkeypatch a run_coordinator_streamed generator to produce plausible event objects.
  • Verify:
    • pretty mode prints summary lines and exits 0.
    • json-lines mode outputs one valid JSON per line.
    • disabled toggle exits 1 with actionable message.
    • session flags pass through without raising.

Gherkin Acceptance
Feature: Chat mode for Agents
Scenario: Start a chat and stream model output
Given EXA_DIRECT_ENABLE_OPENAI=1 and a valid OPENAI_API_KEY
When I run exa agents chat --session-id demo
And I enter "Summarize latest RAG eval frameworks"
Then I see streamed assistant output
And the prompt loop continues until I exit

Scenario: JSON-lines mode
When I run exa agents chat --json-lines --session-id demo
Then each stdout line is valid JSON with an event field

References

Deliverables

  • Working exa agents chat command, documented and tested.
  • No regressions to exa agents run.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions