Skip to content

Commit 3c9d3c4

Browse files
author
Paul C
committed
v22.7.2: local-AI tool-calling fixes + AI bubble visibility on restart
Three urgent fixes targeting the Discord reports about local AI not working in WolfStack despite working via curl, plus Gary's restart bubble bug. 1. Local-model tool calling — recover from content-string emissions Reproduced live on this box against Ollama's qwen2.5-coder:32b: the model emits tool calls as JSON *inside* `message.content` instead of in the structured `tool_calls` array. WolfStack's previous parser only read `tool_calls`, so users got raw JSON as the "AI's reply" and tool dispatch never fired. Common with smaller / not- tool-fine-tuned local models (qwen2.5 below 7B, llama3.2 variants, gemma tunes, FunctionGemma). New `extract_tool_calls_from_content` in `src/ai/mod.rs` recognises six common content-side wire formats and translates them into the same bracket-tag pipeline the rest of the code uses: • bare `{"name": "fn", "arguments": {…}}` object • bare array `[{"name": "fn", "arguments": {…}}, …]` • OpenAI-shape `{"function": {…}}` inside content • Fenced ```json blocks • `<tool_call>…</tool_call>` and `<function_call>…</function_call>` XML wrappers (FunctionGemma + qwen tool-call dialect) • Mistral's `[TOOL_CALLS]` prefix **Critical safety property**: takes an `allowed_tool_names` param and drops any extracted call whose name isn't on the caller's allowlist. Without that, prose like `{"name": "nginx", "status": "stopped"}` (a model explaining service state) would synthesise a phantom tool call — on a sysadmin platform that's potential command-injection-via-AI-response. The allowlist closes that. `MAIN_AI_TOOLS` constant gates the chat path; WolfAgents passes each agent's `allowed_tools` set. `<tool_call>` XML stripper anchored at position 0 of the trimmed string so a mid-prose echo can't trigger extraction. Fenced-block close detected with proper `rfind("```")` instead of trim-end-all- backticks. 14 unit tests across `content_tool_call_tests` covering every wire format, the rejection cases, and two regression guards pinned by name (`unknown_tool_name_is_dropped`, `mid_prose_xml_wrapper_does_not_match`). 2. WolfAgents same recovery path `src/wolfagents/agent_loop.rs::openai_tool_loop` had the same blind spot — model's content-side tool calls returned to the user as raw JSON. Recovery synthesises into the existing `tool_calls_json` so the rest of the multi-round loop works unchanged. Tool-call IDs use `call_{:016x}` (timestamp + counter + agent-id-length mix) so a future swap to OpenAI proper, which validates the ID shape, doesn't reject the recovered turn's history. 3. AI chat bubble visibility on restart (Gary KO4BSR) `web/index.html`'s page-load visibility check only inspected `has_claude_key || has_gemini_key` — Local / OpenAI / OpenRouter users lost the red AI bubble every wolfstack restart and had to re-save Settings → AI Agent to bring it back (the Save handler force-shows it). Now checks all five provider fields. Diagnostic logging - `call_local`: previously-debug-only logs escalated to info/warn so the next "local AI not responding" report has actionable signal at default log levels. - Empty-response error message now includes finish_reason + body_size so context-overflow on small models is identifiable from the UI. - Body-size measurement at debug level (RUST_LOG=wolfstack::ai=debug to enable) — surfaces the #1 small-model failure mode. Independent code-reviewer pass: two BLOCKERs (mid-prose XML match, unrestricted tool-name acceptance) + four MAJORs (synthetic ID format, fenced-block stripping, info-log flooding) all addressed before commit. All findings have negative-case regression tests pinning the fix.
1 parent 99cd14e commit 3c9d3c4

4 files changed

Lines changed: 440 additions & 20 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "wolfstack"
3-
version = "22.7.1"
3+
version = "22.7.2"
44
edition = "2024"
55
authors = ["Wolf Software Systems Ltd"]
66
description = "Server management platform for the Wolf software suite"

0 commit comments

Comments
 (0)