honcho/tests
Vineeth Voruganti 2f3a478948
fix(llm): stop capturing live LLM clients in Langfuse generation spans (#849)
* fix(llm): stop capturing live LLM clients in Langfuse generation spans

honcho_llm_call_inner is the @observe generation boundary, and default
auto-capture serialized every argument into the span input -- including
client_override (a live AsyncOpenAI/genai client) and selected_config
(which carries api_key). Auto-capture deep-copies the client into a
half-constructed object whose teardown raises:

  - AsyncHttpxClientWrapper ... no attribute '_state'      (OpenAI, stderr flood)
  - BaseApiClient ... no attribute '_http_options'         (Gemini, HONCHO-4HA)

and it leaked ModelConfig.api_key into traces.

Switch from auto-capture (denylist) to explicit annotation (allowlist):
disable capture_input/capture_output on the decorator and stamp curated,
serializable input (messages) and output (HonchoLLMCallResponse) via the
new annotate_current_generation_io helper. Full trace fidelity is
preserved; no client object or secret can reach a trace.

Fixes HONCHO-4HA

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(llm): track call tuning knobs as Langfuse model_parameters

Restore full trace fidelity after disabling @observe auto-capture: surface
every tuning knob (temperature, max_tokens, tools, reasoning effort, ...) on
the generation via model_parameters, sourced from the resolved effective
config instead of the raw function args.

Use a deny-list, not an allow-list: dump the whole ModelConfig and exclude
only secret-bearing fields (api_key, base_url, fallback, provider_params), so
new config knobs are traced automatically without keeping a hand-written list
in sync. The live client is never passed -- there is no useful trace
representation of it and serializing it is what triggered HONCHO-4HA.

Adds a deny-list test proving secrets never leak even when the config carries
a real api_key/base_url/provider_params (the production override-client path).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(llm): duplicate token usage to Langfuse + skip payload build when disabled

Mirror per-call token usage (input, output, prompt-cache read/creation) onto
the Langfuse generation via usage_details, so Langfuse renders native tokens
and cost in addition to the CloudEvents accounting.

Also guard both generation-annotation blocks behind settings.LANGFUSE_PUBLIC_KEY
so the model_dump-backed model_parameters payload (and the usage dict) are only
built when Langfuse is actually configured (addresses CodeRabbit: the annotate
helper no-ops when disabled, but the payload was still being constructed every
call).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 11:25:26 -04:00
..
alembic feat: make session_name nullable for documents and update related SDKs (#347) 2026-01-26 13:33:11 -05:00
bench feat: add new cloudevents for api routes (#637) 2026-05-20 18:25:30 -04:00
crud fix(dedup): reinforce times_derived on duplicate detection (#768) 2026-06-11 12:37:19 -04:00
deriver Filter noisy sentry traces/profiles (#834) 2026-06-22 21:14:55 -04:00
dialectic Refactor clients.py to add modern features and more flexible configuration (#459) 2026-04-20 02:46:37 -04:00
dreamer Fix surprisal tree kwarg mismatch (#749) 2026-06-19 13:49:04 -04:00
integration feat: defer embedding messages (#704) 2026-06-11 10:31:04 -04:00
live_llm feat: add model config option for json_object mode (#820) 2026-06-23 10:42:03 -04:00
llm feat: send OpenRouter app-attribution headers on OpenAI-compatible clients (#805) 2026-06-23 16:11:36 -04:00
reconciler fix: Various Codex Audits (#386) 2026-02-13 12:00:15 -05:00
routes Fix scoped JWTs (#679) 2026-06-22 17:30:00 -04:00
scripts feat: add new cloudevents for api routes (#637) 2026-05-20 18:25:30 -04:00
sdk fix(sdk): add peer field to session creation methods (#705) 2026-05-21 12:31:53 -04:00
sdk_typescript add read db (#773) 2026-06-10 13:28:36 -04:00
startup add read db (#773) 2026-06-10 13:28:36 -04:00
telemetry Filter noisy sentry traces/profiles (#834) 2026-06-22 21:14:55 -04:00
unified chore: use git tags to fetch secrets for unified test (#838) 2026-06-24 10:29:52 -04:00
utils fix(llm): stop capturing live LLM clients in Langfuse generation spans (#849) 2026-06-26 11:25:26 -04:00
vector_store Make embeddings configurable (#678) 2026-05-14 15:03:35 -04:00
webhooks Tighten Transaction Scopes (#525) 2026-04-08 11:14:50 -04:00
__init__.py Refactor clients.py to add modern features and more flexible configuration (#459) 2026-04-20 02:46:37 -04:00
conftest.py Track user and session ID on Langfuse traces (#814) 2026-06-23 00:03:21 -04:00
test_advanced_filters.py feat: honcho 3.0, sdks 2.0, excise stainless, update v3 docs, changelogs (#331) 2026-01-22 15:16:28 -05:00
test_config.py feat(deriver): age-flush stalled representation batches (#826) 2026-06-22 17:49:08 -04:00
test_datetime_parsing.py Make embeddings configurable (#678) 2026-05-14 15:03:35 -04:00
test_db_resilience.py add read db (#773) 2026-06-10 13:28:36 -04:00
test_dependencies.py add read db (#773) 2026-06-10 13:28:36 -04:00
test_generate_jwt_script.py feat: add generate_jwt.py script for creating scoped JWTs (#757) 2026-06-09 13:49:55 -04:00
test_models_vector_dim.py feat: add new cloudevents for api routes (#637) 2026-05-20 18:25:30 -04:00
test_schema_validations.py Align API contract with DB contract for IDs (#684) 2026-05-14 16:37:39 -04:00
test_search.py Tighten Transaction Scopes (#525) 2026-04-08 11:14:50 -04:00
test_security.py Fix scoped JWTs (#679) 2026-06-22 17:30:00 -04:00