文件历史

提交图

201 次代码提交

作者 SHA1 备注 提交日期
tjb-tech 7af409300b feat: add configurable image generation tool 2026-05-09 04:56:30 +00:00
Jiabin Tang 225e87f7d7 fix: recover from dangling tool call history (#239) 2026-05-08 18:25:36 +08:00
tjb-tech 18fc6dea13 feat(skills): discover Claude and project skills 2026-05-08 03:49:02 +00:00
tjb-tech b22d5e9368 fix(cli): allow updating provider API keys 2026-05-07 10:05:31 +00:00
tjb-tech 0e557a65d3 feat(skills): expose user-invocable skills as slash commands 2026-05-06 13:43:39 +00:00
tjb-tech ffc50221df feat(skills): add skill creator bundled skill 2026-05-06 13:05:03 +00:00
tjb-tech 807e3ecd47 fix(ohmo): respect Feishu group mention policy 2026-05-06 12:46:28 +00:00
tjb-tech d2489758f0 fix(config): add NVIDIA NIM provider profile
Add a built-in NVIDIA NIM OpenAI-compatible workflow that reads NVIDIA_API_KEY, document the backend, and cover auth/profile materialization. Also make Windows shell resolution skip discovered bash executables that cannot run commands, and update the macOS Terminal backspace troubleshooting note to reflect the current fix.
2026-05-06 11:06:35 +00:00
tjb-tech 373147907a test(mcp): use built-in exception groups on Python 3.11 2026-05-06 10:17:11 +00:00
tjb-tech e0860bd3bd Merge branch 'review/pr-229' into review/security-mcp-windows-skills
# Conflicts:
#	CHANGELOG.md
2026-05-06 10:06:20 +00:00
tjb-tech 2ab4fdb2f7 Merge branch 'review/pr-231' into review/security-mcp-windows-skills 2026-05-06 10:05:20 +00:00
tjb-tech 0f7e9a20f4 Merge branch 'review/pr-237' into review/security-mcp-windows-skills 2026-05-06 10:05:20 +00:00
tjb-tech 57a9134997 test(swarm): accept versioned Python executables 2026-05-06 10:05:11 +00:00
tjb-tech d5b1977fab Merge remote-tracking branch 'origin/main' into review/pr-229 2026-05-06 10:02:01 +00:00
tjb-tech 30d4fb3ebf Merge remote-tracking branch 'origin/main' into review/pr-232 2026-05-06 10:02:01 +00:00
tjb-tech 626ad2daf4 Merge remote-tracking branch 'origin/main' into review/pr-237 2026-05-06 10:02:01 +00:00
tjb-tech ffa7d9c06a Merge remote-tracking branch 'origin/main' into review/pr-231 2026-05-06 10:02:01 +00:00
tjb-tech 0528a7a2c2 fix(ohmo): isolate group command context 2026-05-06 09:55:38 +00:00
tjb-tech 8f30deffe9 feat(ohmo): add gateway-scoped model provider commands 2026-05-06 09:10:38 +00:00
tjb-tech 52a0551569 feat(ohmo): add Feishu group creation flow
Add an ohmo-only /group flow for Feishu private chats, persist managed group metadata, and route shared-chat sessions safely. Also update Feishu reply handling and gateway tests for private/group behavior.
2026-05-06 08:44:17 +00:00
Litianhui888 a98292b814 fix(mcp): isolate startup from failed servers
Treat per-server initialization cancellation as a connection failure instead of aborting overall startup, and suppress cleanup-time exception groups from half-open MCP sessions.
2026-05-06 10:13:35 +08:00
hinotoi-agent 4e33118c48 fix(commands): keep config auth commands local-only 2026-05-05 13:32:29 +08:00
David Whatley 5f97b2416e fix(swarm,tasks): direct-exec teammate spawn, bypass shell on Windows (#230)
Teammate spawn (`agent` tool, `task_create`) failed on Windows with exit
127 and "command not found" against a backslash-mangled Python path,
even though the same `bash -lc "..."` command worked interactively.

Root cause: `subprocess_backend.spawn` built a single shell command
string with a `KEY='val' python ...` env-prefix, then routed through
`bash -lc` via `asyncio.create_subprocess_exec`. Two failures stacked:

  1. The env-prefix string used Python `repr()` for values, and Git
     Bash's `-lc` argument parser consumed backslashes inside the
     quoted segments as escape sequences (`\U` -> `U`).
  2. Even with proper `shlex.quote` of every command part — keeping
     backslashes intact — Git Bash launched via
     `asyncio.create_subprocess_exec` could not exec a Windows-pathed
     Python interpreter, returning `command not found` for the same
     argv that interactive bash exec'd fine.

Fix: don't use a shell at all for teammate spawn.

  * Add `argv: list[str] | None` to `TaskRecord` plus matching kwargs
    on `BackgroundTaskManager.create_shell_task` /
    `create_agent_task`. Either `command` (shell) or `argv` (direct
    exec) must be supplied; both is rejected.
  * `_start_process` runs the argv path via
    `asyncio.create_subprocess_exec(*argv, env=...)` directly, with no
    bash wrapper.
  * `subprocess_backend.spawn` builds an argv list (via
    `get_teammate_command()` plus inherited CLI flags) and hands it to
    `create_agent_task(argv=..., env=...)`. Inherited env vars now
    flow through `env=` rather than being embedded in the command
    string.
  * The legacy shell-evaluated `command=` path is preserved verbatim
    for callers (e.g. `BashTool`) that legitimately want shell
    semantics — only teammate spawn migrates to direct exec.

Tests: 5 new unit tests in `tests/test_swarm/test_subprocess_backend.py`
and 3 in `tests/test_tasks/test_manager.py` lock in the contract — env
plumbed via `env=` kwarg, argv list preserves Windows backslashed
paths, command/argv mutual exclusion, direct-exec round-trip.

Validated end-to-end on Windows 11 against a real CEO/Lead workflow:
CEO successfully calls `agent` tool, Lead spawns at depth=1 and
issues 29 tool calls. Same path was producing exit-127 task logs
before this change.
2026-05-04 16:21:40 -05:00
voidborne-d a857455fd0 fix(skills): use yaml.safe_load for bundled SKILL.md frontmatter
PR #96 fixed the user-skill loader to use yaml.safe_load instead of
naive line-by-line splitting, so YAML block scalars (`>`, `|`),
quoted values, and other standard constructs parse correctly. The
bundled skill loader still used the old parser, so a bundled skill
with a folded description like

    ---
    name: my-skill
    description: >
      A long folded description
      that spans multiple lines.
    ---

would emit `description='>'` (just the marker character) instead of
the expanded text.

Extract the YAML-aware parser into `openharness.skills._frontmatter`
and have both `skills/loader.py::_parse_skill_markdown` and
`skills/bundled/__init__.py::_parse_frontmatter` delegate to it. The
bundled loader keeps its `Bundled skill: <name>` fallback prefix via
the `fallback_template` argument.

Add five regression tests in `tests/test_skills/test_loader.py`
covering folded scalars, literal scalars, inline descriptions, the
"Bundled skill:" fallback, and the heading-plus-paragraph fallback
on the bundled side.
2026-05-05 03:38:47 +08:00
tjb-tech 7873f0d109 fix(engine): clamp oversized token budgets 2026-05-03 09:03:05 +00:00
tjb-tech f10d8875ee feat(ui): make mode switching and stop explicit 2026-05-03 09:02:47 +00:00
Mcy0618 d611d6ddf6 feat(vision): add image-to-text fallback for text-only models (#227)
* feat(provider): add ModelScope inference API support

* fix(cli/auth): wire ModelScope into CLI and auth manager

* feat(vision): add image-to-text fallback for non-multimodal models

* fix: remove leftover merge conflict marker in query.py

* test: fix cross-platform test failures

* test: remove unused os import in test_environment.py
2026-05-03 16:47:56 +08:00
Mcy0618 e536394812 feat(provider): add ModelScope inference API support (#224)
* feat(provider): add ModelScope inference API support

* fix(cli/auth): wire ModelScope into CLI and auth manager
2026-05-02 22:07:45 +08:00
tjb-tech 47e0e93387 fix(gateway): degrade image attachments for text-only models
Support absolute glob patterns without crashing and retry ohmo channel messages without ImageBlocks when a provider rejects image input.\n\nFixes #225\nFixes #226
2026-05-02 14:04:25 +00:00
tjb-tech c835d7cf2e feat(model): manage profile model allowlists
Add /model list/add/remove/clear so a single provider profile can expose multiple switchable models in the TUI selector. Also add regression coverage for invalid grep regexes in the Python fallback.\n\nFixes #222\nRefs #218
2026-05-01 12:38:48 +00:00
José Maia 11faa13d63 fix(auth): avoid shell execution for Windows browser open (#217)
DeviceCodeFlow._try_open_browser previously called
``subprocess.Popen(["start", "", url], shell=True)`` on Windows.  Because
``shell=True`` routes through cmd.exe, a URL returned by the GitHub
device-flow endpoint (or a user-configured enterprise endpoint) that
contained ``&``/``|``/``^`` would have its trailing tokens interpreted as
command separators — e.g. ``https://x.com&calc.exe`` would launch
calc.exe alongside the browser.

Replace the Windows branch with ``os.startfile``, which calls
ShellExecuteW directly and hands the full URL to the registered
URL handler verbatim.  Also reject any non-http(s) scheme up front so
``file:`` / ``javascript:`` / bare executable tokens cannot reach any
platform launcher.  macOS and Linux/WSL paths are unchanged (they were
already shell=False).

Adds tests/test_auth/test_flows.py covering the four platform branches
plus the scheme guard, including an explicit regression assertion that
shell=True is never set on the Popen calls.

Co-authored-by: José Maia <glitch-ux@users.noreply.github.com>
2026-05-01 20:29:30 +08:00
tjb-tech 1bcdc62a50 test(ohmo): harden memory prompt isolation coverage 2026-04-29 08:51:02 +00:00
tjb-tech cc825efb83 fix(ohmo): isolate personal memory from project memory 2026-04-29 08:47:58 +00:00
Hinotobi df348b6335 test(gateway): cover remote bridge spawn block (#209) 2026-04-29 16:38:33 +08:00
tjb-tech 1498a87806 fix(compact): bound large tool result history 2026-04-28 13:28:01 +00:00
tjb-tech 726b3ee028 fix(compact): handle local vision context pressure 2026-04-28 07:04:43 +00:00
hinotoi-agent 438e373097 fix: keep bridge command local-only by default 2026-04-28 11:51:44 +08:00
tjb-tech 380bab4d7b test(api): lock bearer auth for openai-compatible providers 2026-04-28 02:52:36 +00:00
tjb-tech 6bfc5c50d0 Merge branch 'pr-207' into review/206-207 2026-04-28 02:52:03 +00:00
tjb-tech 9a8a14331d fix(tasks): preserve multiline prompts for task workers 2026-04-28 02:41:33 +00:00
tjb-tech 25f2043f53 Merge branch 'pr-201' into merge/rest-20260428 2026-04-28 02:35:11 +00:00
tjb-tech 1fb617d4f4 Merge branch 'pr-200' into merge/rest-20260428 2026-04-28 02:35:11 +00:00
tjb-tech b618f639d7 Merge branch 'pr-205' into merge/rest-20260428 2026-04-28 02:35:11 +00:00
tjb-tech a24a28b38a Merge branch 'pr-197' into merge/rest-20260428 2026-04-28 02:35:11 +00:00
Hinotobi bed1e4777e fix(plugins): reject traversal names on uninstall (#198) 2026-04-28 10:34:31 +08:00
hzb be66e015bf feat(providers): add Qwen (DashScope) to default provider profiles
Add qwen profile to default_provider_profiles() with dashscope provider.
Uses OpenAI-compatible API format at dashscope.aliyuncs.com with
qwen-plus as the default model and DASHSCOPE_API_KEY for auth.

The ProviderSpec for dashscope already existed in registry.py but lacked
a ProviderProfile, making it unavailable via 'oh provider list/use'.
2026-04-28 10:19:39 +08:00
yl-jiang 593dcbcaeb fix(bridge): session_runner 将 stderr 合并到 stdout 流
将子进程 stderr=PIPE 改为 stderr=STDOUT,确保 stderr
输出不会因无人读取而阻塞子进程,同时简化调用方对输出流的处理

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-27 22:57:31 +08:00
yl-jiang 0305dfb3ec fix(tools): subprocess stderr 改为 DEVNULL 并为 bash_tool 添加读取超时
glob/grep 工具的 rg 子进程 stderr 由 PIPE 改为 DEVNULL,
防止 stderr buffer 写满时子进程阻塞造成管道死锁;
bash_tool 的 _read_remaining_output 加 2s 超时,
避免进程退出后读取残余输出时无限挂起

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-27 22:57:31 +08:00
ancietyding b731c3ede1 fix(tui): allow escape to interrupt active runs
Add an explicit frontend-to-backend interrupt request so Esc can stop the current agent turn without relying on platform-specific terminal signals.
2026-04-27 14:17:49 +08:00
José Maia 3e09dde114 fix(ui): drain coordinator async agents in interactive backends
Issue #195: in coordinator mode, the React TUI and Textual app never
injected `<task-notification>` envelopes after a worker finished.
`run_print_mode` had `_drain_coordinator_async_agents` wired in, but
`ReactBackendHost._process_line` and `TextualApp._process_line` only
called `handle_line` and returned, leaving the contract documented in
the coordinator system prompt (results arrive between turns) unmet.

Extract the drain helpers into `openharness.ui.coordinator_drain` and
invoke `drain_coordinator_async_agents` from both interactive hosts
after `handle_line` when coordinator mode is active. The shared module
also avoids a circular import between `ui.app` and `ui.backend_host`.
2026-04-27 00:45:43 +01:00