Commit graph

140 commits

Author SHA1 Message Date
900e3d0d3e feat(whatsapp): gate group replies on mention and share group sessions
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>
2026-06-04 18:49:59 +08:00
bc1b45a8fd fix(chat,channels): admin session delete, weixin inbound, PG and docs
- List/delete chat sessions for administrator by username (cross-tenant UUID)

- Return 404 when delete does not remove a session; add tests

- Weixin: dispatch lang, inbound attachments, reply persist, native reply timeout

- PG compat scrub and administrator session delete repo path

- RUNBOOK: WhatsApp re-bind with Remove-Item auth; weixin poll diag scripts

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-03 01:36:45 +08:00
39fd1905b6 fix(chat): keep tool-call process notes out of visible body
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>
2026-05-31 12:41:12 +08:00
4610989d72 fix(mcp): preflight python module check and surface install errors
- Verify python -m module import in preflight with fix hints

- Pass env_schema defaults in health/sync; catch JSON install exceptions in UI

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-30 23:42:44 +08:00
8787adc3cc fix(chat): repair async worker and video specialist routing
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>
2026-05-30 22:53:49 +08:00
a0a3f4b65f feat(mcp): integrate netx via netx_mcp and improve MCP install
- Gate builtin netx tools; ops docs/skills use mcp__netx__*

- Import Cursor mcpServers JSON; pass env_schema defaults to subprocess

- Allow source_type=local; UTF-8 MCP stdio on Windows

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-30 15:44:34 +08:00
bbd7b0300f feat(ops): add netx managed NE query and exec tools
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>
2026-05-28 22:12:57 +08:00
8233db93db Increase default tool rounds to 100 with 300 cap.
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>
2026-05-28 11:34:20 +08:00
89b295293d Raise default tool rounds to 30 and cap at 100 per turn.
Update gateway, worker, direct_loop, and Admin tool policy UI/docs for AIA_TURN_MAX_TOOL_ROUNDS.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 17:34:39 +08:00
aea02cea3e Execute tools after DSML promote instead of stopping at tool_call.
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>
2026-05-27 17:24:37 +08:00
5325b2d9bc Fix split-field DSML promote and silent turn end after tools.
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>
2026-05-27 17:08:51 +08:00
c31e6ad4b7 Fix double-pipe DSML variant and promote on Responses API.
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>
2026-05-27 16:42:29 +08:00
43f6a792eb Fix spaced DSML variant parsing and reasoning stream filtering.
Support < | | DSML | | ...> markup from vLLM gateways, filter DSML in reasoning_content during streaming, and fix invoke parse false negatives.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 16:25:58 +08:00
97d5c1744a Add DeepSeek DSML-to-tool_calls conversion at transport and runtime layers.
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>
2026-05-27 15:39:11 +08:00
6f754ee5ea ops: use host_name as primary key for alarm NE display
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 00:04:33 +08:00
1366459ee0 feat(ops): enforce English-only replies and localize netx protocol labels
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>
2026-05-19 23:35:46 +08:00
0de5f7bc98 fix(ops): English replies from English prompts and ROLE_SYSTEM.en
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>
2026-05-19 22:41:46 +08:00
f1626195f7 fix(chat): honor ui_lang on WebSocket turns; ops NE display by host_name
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>
2026-05-19 22:14:44 +08:00
3a467704d6 chore(cursor): add Trilium MCP template and ignore local secrets
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-17 12:16:46 +08:00
428eed7ae4 chore(admin): remove netx ops tools sidebar link
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-17 12:11:43 +08:00
921447086f chore(skills): stop tracking local-only knowledge-base-manager
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>
2026-05-16 22:32:30 +08:00
807679aaaa feat: 更新 knowledge-base-manager skill,添加完整 ID 映射和严格目录限制 2026-05-16 22:27:57 +08:00
acfb2cf73b fix(chat): compress-history on PostgreSQL dict rows
- Normalize select id,content rows from dict_row vs sqlite Row in history_tool_result_compact.

- Expand memory_wiki_search ToolSpec to match wiki_search parameters; add schema regression test.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-15 19:22:45 +08:00
0dc0c4663f docs(pg): slim migration guide to shell one-liners
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>
2026-05-14 15:15:08 +08:00
1caf96e694 fix: harden assistant SQLite/PostgreSQL dual-backend (singleton, timeouts, warnings)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 10:24:23 +08:00
1490bd5f24 feat: unify runtime logging (rotating files, log root, scripts, desktop)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 10:11:51 +08:00
86d4bad107 docs: add assistant PostgreSQL migration guide and link from README
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 09:42:08 +08:00
d14e9d3596 feat(persistence): PostgreSQL assistant store, chat persist fixes, gateway scripts
- Add SQLAlchemy Core repos, pg adapter/compat, assistant_store factory, Alembic bootstrap and migration/cutover scripts.

- Harden chat_message writes (NUL scrub for PG), turn_uuid on attempt failure, WS turn_runner fallbacks and gateway executed_turn_uuid init.

- start_gateway: log paths, PS7 stderr handling via cmd, background stdout/stderr redirect; runtime assistant_runtime_log_dir export.

- Ops: clear_all_chat_sessions with PG-only --postgresql and env-gated wipe; clear_postgres_chat_sessions.ps1.

- Tests: SA repos, pg compat, persist fallback, smoke env isolation; CI and docs touch-ups.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 09:33:50 +08:00
2b32d11f43 feat(tools): add grep and workspace profile, fix write path
- 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>
2026-05-13 23:02:52 +08:00
48190afbc1 docs: document AIA_TOOL_FUNCTION_STRICT and add env example
Add ENVIRONMENT_VARIABLES entry, changelog note, and _local/system.env.example placeholder for OpenAI-style tools function.strict toggling.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 15:09:17 +08:00
1d7282a0a2 chore(llm): drop AIA_DEEPSEEK_STRICT_TOOL_MODE legacy knob
Only AIA_TOOL_FUNCTION_STRICT=0 disables function.strict injection.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 15:04:14 +08:00
81163371bd feat(llm): default function.strict on all OpenAI-style tool calls
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>
2026-05-13 15:01:58 +08:00
6ba3234a87 fix(llm): DeepSeek strict tools via function.strict, not extra_body
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>
2026-05-13 14:59:24 +08:00
420abac9f1 refactor: root-package imports (svc/runtime/interfaces) and fix PYTHONPATH
- 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>
2026-05-13 14:51:17 +08:00
7941b27f58 feat(llm): send strict_tool_mode for DeepSeek OpenAI-compat tool calls
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>
2026-05-13 09:22:22 +08:00
7ea0d59512 fix(db): prune rows referencing deleted chat_session on init
Remove orphan chat_message, tool_log, oclaw_*, and attachment_acl rows
when session_id no longer exists (e.g. legacy deletes without FK).
Add regression tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 01:01:49 +08:00
289cac4dd6 feat: parse DeepSeek V4 DSML tool_calls from assistant text
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>
2026-05-13 00:51:22 +08:00
4ea26a022b fix(chat): fold tool_call main-channel text and fix aggregate row loss
- _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>
2026-05-13 00:02:18 +08:00
5efac74f87 fix(chat): always persist reasoning_content on assistant event_payload
Non-thinking profiles previously wrote model reasoning only as separate
event_type=reasoning rows whose event_payload held chunk_index metadata, so
JSON inspection showed tool payloads but no reasoning_content key.

Store the full merged reasoning blob on the primary assistant row whenever
present (same shape as thinking mode). Update instruction-leak filtering to
scan event_payload.reasoning_content as well as legacy reasoning rows.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 23:02:38 +08:00
c938147fdb fix(chat): default reasoning fold on for new browsers and bump chat.js cache
The reasoning/tool collapsed bundle is gated by adminChatShowToolOutput,
which was only read from localStorage with default false. A fresh browser
therefore hid persisted reasoning in the fold while streaming still showed
tokens. Default to true and bump chat.html asset version so deployments pick
up the script.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 20:29:58 +08:00
a3365b77fa fix(chat): persist reasoning for Responses stream and WS final snapshot
- Parse reasoning_summary_text (and related) SSE events in OpenAI Responses
  streaming; forward deltas to on_token and return reasoning_content on
  LLMResponse so thinking-mode rows get event_payload in the store.
- When emitting chat/final from turn_runner, include event_type/event_payload
  and merge reasoning_content from earlier assistant rows in the same
  turn_uuid so the collapsed reasoning fold matches what streamed.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 20:18:15 +08:00
46ebfeb54f fix(chat): persist/split <thinking>/<thought> blocks like stream UI
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 19:32:19 +08:00
7ea02e66ca fix(chat): show thinking_mode reasoning in folded bundle from event_payload
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 19:28:03 +08:00
5b2f182ae4 fix(admin): run_command toggle GET matches DB absent; add disabled hint
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 19:17:13 +08:00
274a9b8ddd feat(mcp): pass all mcp_local.env keys to subprocess; allowlist supplements host-only
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 18:51:07 +08:00
48d5e468e6 feat(mcp): allowlist EXTRA merges with default; add Trilium keys to default
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 17:39:14 +08:00
d16791fb7d skills: add excalidraw-diagram for Trilium Excalidraw notes
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 15:44:27 +08:00
f367779ad1 Docs: UME NE keyword matches host_name (netx-side)
Align ops playbook and netx_query_ume_ne_inventory description with netx API.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 17:27:26 +08:00
1c90a3570e Add netx UME NE inventory tools for ops
Expose netx_query_ume_ne_inventory and netx_get_ume_ne (GET /v1/ume/inventory/ne and /ne/{id}). Update ops playbook, ROLE_SYSTEM, env example comment, and unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 17:24:57 +08:00
939a734e76 Bust executor prompt cache on workspace SKILL.md layout changes
Add workspace_skills_layout_signature (hash of paths + mtimes + sizes) and fold it into get_executor_prompt_static and manager prebuild cache keys. Add tests for signature drift and cache invalidation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 16:28:16 +08:00