Some OpenAI-compatible proxies finish tool-call streams with delta=None and
a full message payload; accessing delta.tool_calls crashed tool rounds.
Co-authored-by: Cursor <cursoragent@cursor.com>
Copy bridge files when starting WhatsApp sidecar, enforce group policy only in gateway with richer @ detection, and log skipped group messages for debugging.
Co-authored-by: Cursor <cursoragent@cursor.com>
Match bot mentions across JID/LID formats, accept reply-to-bot triggers, keep raw quote participants, and fall back to plain text when quoted sends fail.
Co-authored-by: Cursor <cursoragent@cursor.com>
Infer group chats from @g.us JIDs, drop (silent)/NO_REPLY outbound text, and @ plus quote the asker when replying in groups.
Co-authored-by: Cursor <cursoragent@cursor.com>
Stop replying to every group message by filtering on @bot/triggers in the sidecar and gateway, and map group chats to one shared session while preserving per-sender identity.
Co-authored-by: Cursor <cursoragent@cursor.com>
Preserve tool_call event_type when hydrating WS final messages, never render main-channel process notes as assistant body text, and prefer structured message content over stream buffer on finalize.
Co-authored-by: Cursor <cursoragent@cursor.com>
Fix trace_id/run_id initialization so async turns persist messages. Pass skill_binding_role through the worker and route video/image experts synchronously for the DashScope legacy lane.
Co-authored-by: Cursor <cursoragent@cursor.com>
Add ops specialist tools to list/get managed NEs and execute read-only CLI via netx.
Document the new managed-NE workflow in role prompts, env example, and a dedicated ops skill with tests.
Co-authored-by: Cursor <cursoragent@cursor.com>
Raise Admin/UI defaults and backend clamps for AIA_TURN_MAX_TOOL_ROUNDS across gateway, worker, and direct loop paths.
Co-authored-by: Cursor <cursoragent@cursor.com>
Add last-chance DSML promote on combined content+reasoning and parse again before protocol_mismatch so split-field DeepSeek output runs real tools and produces tool_result rows.
Co-authored-by: Cursor <cursoragent@cursor.com>
Parse DSML from combined content+reasoning when markers span fields; show a clear mismatch message when parse fails; run finalize synthesis when tools executed but the assistant body is empty.
Co-authored-by: Cursor <cursoragent@cursor.com>
Parse <||DSML||> markup, add DSML recovery to openai_responses transport, and avoid persisting raw DSML as plain assistant text when promotion fails.
Co-authored-by: Cursor <cursoragent@cursor.com>
Promote DSML markup from assistant text into native tool calls during streaming and completion, filter DSML from UI tokens, and document AIA_DSML_TEXT_TOOLS for local vLLM proxies.
Co-authored-by: Cursor <cursoragent@cursor.com>
Append english_output_guard when lang=en, strengthen ops/generalist EN role prompts,
pass NETX_TOOL_LANG into netx tools, and map Chinese protocol buckets to English.
Co-authored-by: Cursor <cursoragent@cursor.com>
Detect language from user message before UI hint, load ops ROLE_SYSTEM.en.md when en, and wire user_text through WS/HTTP/worker paths.
Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve runtime language from ui_lang and chat.send lang instead of hardcoding zh.
Align generalist/ops prompts with user language and require host_name (not ne_id) in ops outputs.
Co-authored-by: Cursor <cursoragent@cursor.com>
Ignore skills/_workspace/generalist/knowledge-base-manager/ and remove SKILL.md from the index; file remains on disk for local use only.
Co-authored-by: Cursor <cursoragent@cursor.com>
Migrator: only refuse import when SQLite and PG both have rows for a table (PG seed rows ok when SQLite empty). Add unit test for conflict helper.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Add grep_tool: ripgrep with Python fallback; avoid --json with -l/-c.
- Add workspace_profile_tool: scan, languages, tests, packages, git, CI hints; tests.
- write_file: resolve relative paths via workspace root (no data/workspace prefix).
- Update path guard and local public tool tests for new write behavior.
Co-authored-by: Cursor <cursoragent@cursor.com>
Apply strict:true to every tools[].function by default; disable with
AIA_TOOL_FUNCTION_STRICT=0. Keep AIA_DEEPSEEK_STRICT_TOOL_MODE=0 as legacy opt-out when primary unset.
Co-authored-by: Cursor <cursoragent@cursor.com>
Match DeepSeek Tool Calls docs: set strict:true on each tools[].function.
Remove non-documented strict_tool_mode extra_body. Keep AIA_DEEPSEEK_STRICT_TOOL_MODE=0 to opt out.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Rename platform/ to svc/ to avoid shadowing stdlib platform.
- Replace from oclaw.* with from svc/runtime/interfaces; update -m CLI paths.
- tests/conftest: prepend repo root to sys.path (no parent-folder package name).
- CI: paths and offline_eval script under repo root.
- Ops scripts: PYTHONPATH must be repo root for python -m runtime.* (fixes gateway/WhatsApp sidecar startup).
- Fix default oclaw.json path in tabular/file attachment limits; stabilize attachment test config.
Co-authored-by: Cursor <cursoragent@cursor.com>
Merge strict_tool_mode: true into extra_body when tools are used and the
endpoint/model looks like DeepSeek. Opt out with AIA_DEEPSEEK_STRICT_TOOL_MODE=0.
Add unit tests.
Co-authored-by: Cursor <cursoragent@cursor.com>
Add dsml_tool_parse per upstream HF encoding README (invoke/parameter,
string true|false, JSON for non-strings). Normalize <||DSML|| gateways.
Wire into run_oclaw_direct_loop when AIA_DSML_TEXT_TOOLS is on or
base_url/model suggests DeepSeek; skip DSML repair retry in that mode.
Strip the first tool_calls block from persisted assistant body. Finalize
pass keeps DSML disabled so no tools run after the no-tool round.
Tests cover parser variants and direct_loop execution for DeepSeek URL
and forced env.
Co-authored-by: Cursor <cursoragent@cursor.com>
- _buildRenderRows: include assistant content for event_type=tool_call as
assistant_text items with assistantEventType=tool_call (was omitted).
- Tag other assistant_text slices with assistantEventType for clarity.
- _buildAggregatedAssistantBubble: for tool_call slices, add non-redundant
main-channel text to the reasoning fold under reasoning.processNotes;
skip when already covered by reasoning blocks (whitespace-normalized
substring). Inline markdown for those process lines is omitted to avoid
duplicate display. Bump chat.js cache query.
Co-authored-by: Cursor <cursoragent@cursor.com>