langchain 1.x removed the langchain.prompts module, so a fresh install of
requirements.txt (which leaves langchain unpinned) fails at startup with
ModuleNotFoundError: No module named 'langchain.prompts'.
PromptTemplate lives in langchain_core.prompts, which is already listed in
requirements.txt and works with both langchain 0.3 and 1.x.
Fixes Bugs 9 and 10 of #1194.
Bug 9 - guardrails:
- The 38-example ChainOfThought classifier was never called, so the
examples never reached the model. Attach them as demos on the
classifier that actually runs (duplicates removed).
- Parse Yes/No verdicts tolerantly ("Yes.", "**Yes**", "Yes, this is
math"), and log unclear verdicts instead of silently rejecting.
Bug 10 - web fallback:
- query_web: add a request timeout and raise_for_status, catch request
and JSON errors, and treat a missing/null answer as no result
instead of passing "No answer found." or "None" to the model.
- Label the answer source correctly when web search is unavailable.
- Re-validate the retried answer; if it fails again, return it with a
clear "could not be verified" warning.
- Benchmark: match the gold answer as a standalone token. The substring
test counted gold "C" as correct for any reply containing the letter
c, and "12" inside "112" or "0.12".
Fixes Bugs 3, 5 and 6 of #1194.
Bug 3 - endpoint errors:
- Wrap the model call in GovernedAgent.run so a 429/400/404/500, timeout
or dropped connection returns "Model call failed: ..." instead of
ending the demo with a traceback.
- Read the model from OPENAI_MODEL (default stays gpt-4).
Bug 5 - truncated tool arguments:
- Parse tool calls with ast instead of splitting on ", ". Values with
commas, quotes or leading/trailing spaces are kept intact, and
malformed calls are rejected with a parse error instead of being
silently truncated and executed.
- Accept only literal keyword arguments. Positional args are rejected
because the policies look up kwargs such as "path" and "url".
Bug 6 - approval prompt swallowed in headless runs:
- Treat EOFError from the approval prompt as a denial with a clear
reason ("No human available to approve") instead of "Tool error: ".
- Record the human approval outcome (allow/deny) in the audit log.
- Include the exception type in generic "Tool error" messages.
Fixes Bugs 1 and 2 of #1194.
- Guard the response envelope: a reply with no/null `choices` no longer
raises IndexError/TypeError outside the request's try block.
- Do not save empty, null or whitespace-only replies as a diagnosis.
- Do not save replies truncated by the token limit (finish_reason ==
"length") or replies missing the mandated "Primary pattern" section.
- In each case, print why the report was not saved and continue the loop.
A reply of just a code fence raised IndexError outside the try block. Extract fence stripping into a helper so it falls through to the existing JSONDecodeError handling.
Part of #1194 (Bug 7)
Adds a "Thanks to our sponsors" section after "Run one now" with the
TinyFish Community Programs banner (Students + Ambassadors), and removes
the Unwind AI image banner from the top of the README.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The model-suggestions dropdown (and the README env-override example) offered
gemini-3-pro-preview, which the live Gemini API now returns 404 for
("no longer available ... use models/gemini-3.1-pro-preview"). A user picking
it, or an operator setting GEMINI_MODEL to it, hits a 500 with a misleading
"check your API key" message even though the key is valid.
Swap it for gemini-3.1-pro-preview, the replacement Google's own 404 names,
verified working against the live API (analyze + generate). The default stays
gemini-3.8-flash. Test fixtures that used the id are updated to match.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The model was hardcoded as gemini-3-flash-preview in the optimizer, so
changing it meant editing code. The default is now gemini-3.8-flash, the
GEMINI_MODEL environment variable overrides it on the server, and the UI
has a model field next to the API key whose value is sent with analyze,
regenerate and start. GET /api/models reports the current default and
suggested ids so the field shows the real default; a value that does not
look like a model id is refused with a 400 instead of silently replaced.
The running step shows the model the backend reports.
A request without a model, as the old UI sends, still works and runs on
the server default. Backend tests cover every new path with a fake
optimizer, so they need no API key.
Closes#1200