* telemetry: use session and user IDs in langfuse * test: update old span test * fix: disable langfuse in unit tests * fix: add post-loop synthesis span * refactor: address PR review feedback on langfuse tracing - Consolidate track_name onto LLMTelemetryContext as the sole home; remove the honcho_llm_call kwarg and update 4 callers to set it on telemetry directly. Sentry ai_track now reads telemetry.track_name. - Decouple escaped-stream self-stamping from run-context exit ordering: stream_final_response now resets _in_agent_run explicitly around drain. - Narrow langfuse_agent_step wrap in the tool loop — between-turn bookkeeping (iteration_callback, choice switch, increment) lifted outside the span so it scopes only the LLM call + tools. - Reword test conftest comment to behavior-only language. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: switch langfuse spans to imperative handles Replaces the context-manager-based langfuse_agent_run/step with imperative LangfuseAgentRun/Step handles so the run span can outlive the function that opens it. Streaming responses now own the run handle from construction and close it after drain, stamping the accumulated streamed text as trace output (previously blank). Multi-turn generations always stamp provider/model and step metadata, fixing the regression where only the first turn was annotated. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(llm): record effective prompt-only input on run span The run-level Langfuse span recorded the raw messages parameter, which is None for prompt-only calls. Mirror execute_tool_loop's handling and record the synthesized user message so the trace input isn't blank. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(llm): drop StreamingResponseWithMetadata.__anext__ to prevent span leak The standalone __anext__ delegated straight to the inner stream, bypassing the token-folding and Langfuse run-handle close that live only in the __aiter__ generator. Any caller driving the wrapper via anext() instead of `async for` would leak the run span and lose final-stream token accounting. Latent today (all callers use `async for`), removed to close the footgun. Add tests covering the run-handle drain path: full drain stamps the accumulated streamed text as the span output and closes once; an abandoned stream still closes via the finally rather than leaking. * chore(llm): document intentional empty-body propagate_attributes block The `with propagate_attributes(...): pass` stamps the active @observe trace root via the context manager's __enter__ side effect; the empty body reads as deletable dead code. Add a comment so it isn't removed. Addresses PR review. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(llm): restore api.py types after __anext__ removal Dropping StreamingResponseWithMetadata.__anext__ made it stop satisfying the AsyncIterator protocol, breaking the result annotation and the isinstance narrowing in honcho_llm_call. Widen the tool-less result annotation to include StreamingResponseWithMetadata and narrow positively to HonchoLLMCallResponse before reading .content. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Vineeth Voruganti <13438633+VVoruganti@users.noreply.github.com> |
||
|---|---|---|
| .. | ||
| test_cases | ||
| README.md | ||
| run.py | ||
| runner.py | ||
| schema.py | ||
README.md
Unified Honcho Test System
This system allows for defining comprehensive, step-based tests for Honcho in a unified JSON format. It supports testing configuration hierarchy, multi-turn interactions, and complex assertions including LLM-as-a-judge.
Running Tests
# Run all tests in the test_cases directory
python -m tests.unified.run
# Run a specific test file
python -m tests.unified.run --test-dir tests/unified/test_cases
Test Schema
Tests are defined in JSON files. A test definition consists of a name, optional description, and a list of steps.
Structure
{
"name": "my_test",
"workspace_config": { ... },
"steps": [
{ "step_type": "..." },
...
]
}
Actions
-
Configuration:
set_workspace_config: Update workspace settings.set_session_config: Update session settings.
-
Interaction:
create_session: Create a new session, optionally with peers and config.add_message: Add a single message.add_messages: Add multiple messages.
-
Waiting:
wait: Wait for duration or "queue_empty".
-
Querying & Assertions:
query: Perform an action and assert on the result.target: "chat", "get_context", "get_peer_card", "get_representation"
Assertions
llm_judge: Use Claude to evaluate the result against a natural language prompt.contains/not_contains: Substring matching.exact_match: Strict equality.json_match: specific key-value checks.
Example
{
"name": "demo_config_flow",
"steps": [
{
"step_type": "create_session",
"session_id": "s1",
"peer_configs": {
"user": { "observe_me": true },
"agent": { "observe_others": true }
}
},
{
"step_type": "add_message",
"session_id": "s1",
"peer_id": "user",
"content": "My name is Alice."
},
{
"step_type": "wait",
"target": "queue_empty"
},
{
"step_type": "query",
"target": "chat",
"peer_id": "agent",
"session_id": "s1",
"input": "Who am I?",
"assertions": [
{
"assertion_type": "contains",
"text": "Alice"
}
]
}
]
}