Commit Graph

2 Commits

Author SHA1 Message Date
Jordan Ritter 99136fc64d fix(showcase/langroid): address CR round 3 findings (unified sanitization, narrow excepts, ParsedArgs)
Changes to src/agents/agui_adapter.py:
- Extract _execute_backend_tool / _run_backend_tool helpers so the
  oai_tool_calls path and the content-JSON path share one sanitization
  contract. The _try_parse_tool backend-tool path no longer runs
  .handle() barefoot — it goes through _execute_backend_tool which
  catches the narrowed (pydantic.ValidationError, ValueError), logs
  the traceback server-side, and returns a sanitized JSON error payload.
- Narrow tool-execution except from
  (RuntimeError, ValueError, TypeError, KeyError, pydantic.ValidationError)
  to (pydantic.ValidationError, ValueError). RuntimeError/KeyError from
  unrelated libraries or real config drift now propagate as real bugs
  rather than being misclassified as user-facing tool failures.
- Replace dict | None three-way return of _parse_tool_args with a
  ParsedArgs dataclass (args + status: 'ok' / 'empty' / 'malformed' +
  .usable helper). Call sites pattern-match on status explicitly.
- Treat empty-string raw_args (legacy function_call path) as 'malformed'
  instead of 'ok with {}' — firing a tool with empty args produces a
  meaningless UI card, same rationale as the oai path.
- Drop TypeError from the json.loads except in _try_parse_tool (it
  signals a programmer bug, not plain text). Add an
  isinstance(content, (str, bytes, bytearray)) guard that logs a
  WARNING rather than silencing the case.
- Drop pydantic.errors.PydanticUserError from tool-instantiation except
  lists — it signals malformed model *definitions*, not runtime data
  errors, and must surface loudly at startup.
- Freeze _TOOL_BY_NAME behind types.MappingProxyType so post-import
  mutation raises TypeError (e.g. accidental monkeypatch / shadowing).

Changes to tests/python/conftest.py:
- Tighten the docstring cross-reference to src/agent_server.py (the
  real entry point confirmed to import agents.agui_adapter identically).

Changes to tests/python/test_agui_adapter.py:
- Update helper tests to assert on ParsedArgs.status / .usable / .args.
- Flip empty-string expectation to 'malformed' per the new contract.
- Add: bytes-input parse, unknown-type 'empty' status, MappingProxyType
  frozen-ness of _TOOL_BY_NAME, unified-helper happy path, helper-level
  sanitization + traceback capture, helper propagates non-narrowed
  RuntimeError, _try_parse_tool non-str/bytes guard warns and returns
  None, and str(exc) never appears anywhere in the SSE stream bytes.
- Switch sanitized-error test's raise to ValueError (narrowed except
  covers it) — previously RuntimeError leaked through by accident.

24/24 tests pass (16 existing + 8 new).
2026-04-18 20:44:37 -07:00
Jordan Ritter 7c2d9aa445 fix(showcase/langroid): address CR round 1 findings (thread_id, logging, tests)
- agui_adapter: compute thread_id once so RUN_STARTED/RUN_FINISHED never
  disagree when the caller omits it.
- Narrow silent `except Exception: pass` sites, log parse/tool failures
  with sanitized context, and drop the dead `agent.agent_response` path
  (returns ChatDocument, not ToolMessage).
- Extract `_emit_text_block` helper DRYing the empty-delta guard, and a
  `_parse_tool_args` helper with explicit warning on malformed input.
- Assert tool-class request-name uniqueness at import so collisions fail
  loudly instead of silently shadowing.
- Replace `str(response)` fallback with documented empty default.
- Add unit tests covering the OAI tool-calls happy path, malformed args,
  legacy function_call shape, empty-content skip, thread_id stability,
  and tool-class uniqueness (red-green verified).
2026-04-18 20:44:35 -07:00