| refactor(swarm): harden teardown logging and simplify approval gate
- team_harness: log post_run teardown failures instead of swallowing
- agent_configurator: extract can_request_approval for readability
- member_runtime: fix module-level spacing
Refs: #751
| 4 小时前 |
| chore(agent_teams): add copyright headers to all Python files
Add Huawei copyright header to all 67 Python files in the agent_teams
directory that were missing it. Standardizes copyright declarations
across the module to match project conventions.
Refs: #751
| 25 天前 |
| docs(swarm): record worker TeamHarness + run_once + structured_output
Update workflow/CLAUDE.md (worker is now a teammate-equivalent
TeamHarness via run_once; structured_output rename), harness/CLAUDE.md
(run_once surface), and S_18 swarmflow spec; archive F_36.
Refs: #751
| 4 小时前 |
| feat(swarm): simplify native harness surface and gate first-start message
Two independent changes landed together (overlapping doc hunks prevent
clean separation):
- Harness surface: internalize prepare/prepare_config into construction
and merge on_state_changed/on_round into a single
subscribe(on_state=, on_round=) across NativeHarness / TeamHarness /
ExternalCliRuntime / MemberRuntime. Team-specific public additions
shrink from 11 to 8.
- Spawn first-start: only inject the initial message on first start;
empty query just subscribes, so restart/recover/resume no longer
replay the join prompt.
Refs: #751
| 4 小时前 |
| refactor(swarm): harden teardown logging and simplify approval gate
- team_harness: log post_run teardown failures instead of swallowing
- agent_configurator: extract can_request_approval for readability
- member_runtime: fix module-level spacing
Refs: #751
| 4 小时前 |
| docs(swarm): archive F_28 + sync specs for NativeHarness team adoption
Add F_28 (decisions + rejected alternatives for the adoption). Revise S_18 to
the landed two-layer contract (HarnessProtocol + MemberRuntime, TeamHarness
composing NativeHarness, CLI runtimes, event/retry/resume semantics). Update
S_05/S_16/S_17 and the agent/runtime/interaction CLAUDE.md files to drop
run_streaming / FirstIterationGate references and describe the forward-layer
StreamController and start/outputs/send surface.
Refs: #984
| 4 小时前 |
| feat(swarm): split external access into operator / member scopes
Two scenarios picked from the join descriptor's scope (orthogonal to team
role), resolved at first connect:
- member: a spawned third-party CLI team member. ExternalTeamClient builds a
minimal TeamBackend and create_team_tools(role="teammate"), exposing the real
view_task / claim_task / send_message TeamTools (same schema + map_result
text as a native teammate) + the external-only read_inbox. The MCP server's
member instructions are empty — the team system prompt is already injected
into the CLI at spawn time.
- operator (default): an external, non-member team-control interface; keeps the
broad op set and adds create_task.
The MCP server moves from FastMCP to the low-level mcp.server.lowlevel.Server
so member tools advertise their own card.input_params schema and return their
map_result text verbatim; tool set + instructions branch on client.scope, with
session/language re-bound per call. The CLI branches subcommands on scope; the
single SKILL.md splits into SKILL_member.md + SKILL_operator.md. The spawn path
sets scope="member" and its join prompt uses claim_task(status="completed").
Refs: #751
| 4 小时前 |
| fix(codecheck): fix ruff F821 codecheck error
Refs: #930
Co-authored-by: tangfei0306<tangfei45@h-partners.com>
# message auto-generated for no-merge-commit merge:
!1491 fix(codecheck): fix ruff F821 codecheck error
From: @tangfei0306
Reviewed-by: @iamcandiceguo, @deyang
See merge request: openJiuwen/agent-core!1491 | 9 天前 |
| chore(agent_teams): add copyright headers to all Python files
Add Huawei copyright header to all 67 Python files in the agent_teams
directory that were missing it. Standardizes copyright declarations
across the module to match project conventions.
Refs: #751
| 25 天前 |
| fix(agent_teams): serialise ByModelNameAllocator counters as list
state_dict() used to dump _inner_indexes as a dict keyed by model_name,
so configurations with names containing '.' or '[' (e.g. "glm-5.1",
"claude-3.5-sonnet") tripped the session persistence layer's
nested-path parsing and crashed when sibling keys shared a prefix.
Switch to a list of {model_name, index} records so model names are
never interpreted as paths. load_state_dict() still accepts the legacy
"inner_indexes" dict format so sessions persisted by older versions
load without resetting rotation counters.
Refs: #751
| 20 天前 |
| feature(team): team plan mode
Refs: #822
Co-authored-by: weichenhao<weichenhao3@huawei.com>
# message auto-generated for no-merge-commit merge:
!1434 feature(team): team plan mode
From: @weichenhao
Reviewed-by: @alan_cheng, @chenchunzhou
See merge request: openJiuwen/agent-core!1434 | 10 天前 |
| feat(harness/worktree): persist worktree across session with validation fixes
- Persist active worktree across agent Session lifecycle
- Move workspace symlink view to team workspace
- Close fail-closed gap in exit validation
- Add single-deepagent e2e worktree example docs
| 25 天前 |
| docs(swarm): record worker TeamHarness + run_once + structured_output
Update workflow/CLAUDE.md (worker is now a teammate-equivalent
TeamHarness via run_once; structured_output rename), harness/CLAUDE.md
(run_once surface), and S_18 swarmflow spec; archive F_36.
Refs: #751
| 4 小时前 |
| feat(swarm): run swarmflow workers as teammate-equivalent TeamHarness
Add a non-streaming TeamHarness.run_once / NativeHarness.run_once: one
DeepAgent.invoke (no supervisor, no steer), returning the Runner.run_agent
dict; the spec's enable_task_loop decides single-round vs self-driven
task loop, so DeepAgent todo planning is preserved.
Each swarmflow worker is now a TeamHarness derived from the team's
teammate spec (or leader spec) — keeping teammate capabilities (model /
tools / skills / workspace / sys_operation / task planning) but, being
built from the raw spec, carrying no team collaboration tools. The base
spec is threaded leader -> inject_team_handles(SWARMFLOW_WORKER_BASE_SPEC)
-> TeamToolRail -> create_team_tools -> SwarmflowTool -> run_swarmflow.
Rename SubmitResultTool -> StructuredOutputTool (kept as an object) and
move its + SwarmflowTool descriptions/params to the tools/locales i18n
infra. The tool is appended to the worker spec and managed by the
harness ability manager (owner-qualified id, teardown_tools cleanup) —
the backend no longer hand-registers/removes it. Worker model resolution
returns a TeamModelConfig (spec build path) instead of a built Model.
Refs: #751
| 4 小时前 |
| refactor(swarm): build team rails fresh per cycle, inject reusable state
Team rail provider factories cached their rail instance on the build
context so a native rebuild reused it. Combined with each rebuild owning
a freshly constructed ability_manager, the cached TeamToolRail's
idempotent init skipped re-binding its tool cards onto the new manager,
so tools like send_message became unresolvable from the second run cycle
on (Ability not found in resource_mgr: send_message).
Drop rail caching entirely: every factory mints a fresh rail each cycle,
matching the provider registration pattern. State that must outlive a
rebuild now rides as a reused object on the build context and is wrapped
by the fresh rail — ReliabilityRail's detector windows, remediator and
leader sink collapse into a reliability_components bundle the configurator
builds once, while TeamPolicyRail's mtime cache and TeamToolRail's tools
rebuild per cycle from their source of truth (DB / create_team_tools).
| 4 小时前 |
| fix(swarm): de-duplicate team tool registration across native rebuilds
- sys_operation: get-or-create instead of strict add; NativeHarness.dispose
removes it on permanent teardown so a discarded member does not leak it
- factory: auto SkillUseRail.include_tools defers to a mounted SysOperationRail
so read_file/bash/code are not double-registered
- runtime: drop the eager recover_team from the COLD_RECOVER / NEW_TEAM_IN_SESSION
cold paths (coordination.start owns teammate recovery) and make recover_team
idempotent via spawn_manager.has_live_handle, so teammates build once
- team_tool_rail / experience_rail: register through ability_manager.add_ability
so ids are owner-qualified and teardown_tools drops them at round-end instead
of refresh-warning on every rebuild
- update cold-recover runtime test expectation
Refs: #751
| 4 小时前 |
| fix(swarm): de-duplicate team tool registration across native rebuilds
- sys_operation: get-or-create instead of strict add; NativeHarness.dispose
removes it on permanent teardown so a discarded member does not leak it
- factory: auto SkillUseRail.include_tools defers to a mounted SysOperationRail
so read_file/bash/code are not double-registered
- runtime: drop the eager recover_team from the COLD_RECOVER / NEW_TEAM_IN_SESSION
cold paths (coordination.start owns teammate recovery) and make recover_team
idempotent via spawn_manager.has_live_handle, so teammates build once
- team_tool_rail / experience_rail: register through ability_manager.add_ability
so ids are owner-qualified and teardown_tools drops them at round-end instead
of refresh-warning on every rebuild
- update cold-recover runtime test expectation
Refs: #751
| 4 小时前 |
| feat(swarm): split external access into operator / member scopes
Two scenarios picked from the join descriptor's scope (orthogonal to team
role), resolved at first connect:
- member: a spawned third-party CLI team member. ExternalTeamClient builds a
minimal TeamBackend and create_team_tools(role="teammate"), exposing the real
view_task / claim_task / send_message TeamTools (same schema + map_result
text as a native teammate) + the external-only read_inbox. The MCP server's
member instructions are empty — the team system prompt is already injected
into the CLI at spawn time.
- operator (default): an external, non-member team-control interface; keeps the
broad op set and adds create_task.
The MCP server moves from FastMCP to the low-level mcp.server.lowlevel.Server
so member tools advertise their own card.input_params schema and return their
map_result text verbatim; tool set + instructions branch on client.scope, with
session/language re-bound per call. The CLI branches subcommands on scope; the
single SKILL.md splits into SKILL_member.md + SKILL_operator.md. The spawn path
sets scope="member" and its join prompt uses claim_task(status="completed").
Refs: #751
| 4 小时前 |
| feat(swarm): simplify native harness surface and gate first-start message
Two independent changes landed together (overlapping doc hunks prevent
clean separation):
- Harness surface: internalize prepare/prepare_config into construction
and merge on_state_changed/on_round into a single
subscribe(on_state=, on_round=) across NativeHarness / TeamHarness /
ExternalCliRuntime / MemberRuntime. Team-specific public additions
shrink from 11 to 8.
- Spawn first-start: only inject the initial message on first start;
empty query just subscribes, so restart/recover/resume no longer
replay the join prompt.
Refs: #751
| 4 小时前 |
| fix(tools): fix shell tool issues
Refs: #871
Co-authored-by: weichenhao<weichenhao3@huawei.com>
# message auto-generated for no-merge-commit merge:
!1341 fix(bug):Cluster mode, the "read_file" tool reports an error. This is because the "file_path" does not match the actual path where the generated file is located, and thus the generated.md file cannot
From: @weichenhao
Reviewed-by: @iamcandiceguo, @alan_cheng, @chenchunzhou
See merge request: openJiuwen/agent-core!1341 | 20 天前 |
| feat(swarm): run swarmflow workers as teammate-equivalent TeamHarness
Add a non-streaming TeamHarness.run_once / NativeHarness.run_once: one
DeepAgent.invoke (no supervisor, no steer), returning the Runner.run_agent
dict; the spec's enable_task_loop decides single-round vs self-driven
task loop, so DeepAgent todo planning is preserved.
Each swarmflow worker is now a TeamHarness derived from the team's
teammate spec (or leader spec) — keeping teammate capabilities (model /
tools / skills / workspace / sys_operation / task planning) but, being
built from the raw spec, carrying no team collaboration tools. The base
spec is threaded leader -> inject_team_handles(SWARMFLOW_WORKER_BASE_SPEC)
-> TeamToolRail -> create_team_tools -> SwarmflowTool -> run_swarmflow.
Rename SubmitResultTool -> StructuredOutputTool (kept as an object) and
move its + SwarmflowTool descriptions/params to the tools/locales i18n
infra. The tool is appended to the worker spec and managed by the
harness ability manager (owner-qualified id, teardown_tools cleanup) —
the backend no longer hand-registers/removes it. Worker model resolution
returns a TeamModelConfig (spec build path) instead of a built Model.
Refs: #751
| 4 小时前 |
| docs(swarm): record worker TeamHarness + run_once + structured_output
Update workflow/CLAUDE.md (worker is now a teammate-equivalent
TeamHarness via run_once; structured_output rename), harness/CLAUDE.md
(run_once surface), and S_18 swarmflow spec; archive F_36.
Refs: #751
| 4 小时前 |
| docs(swarm): record team rails are never cached; reusable state injected
Update F_32 and the module CLAUDE.md: rails are provider-built fresh each
native rebuild, and cross-rebuild state rides as a reused object on the
build context (reliability_components) wrapped by the fresh rail, replacing
the removed team_rail_cache.
| 4 小时前 |
| feat(swarm): add reliability framework for member health monitoring
Rail-collected lifecycle signals, seven anomaly detectors, and a tiered remediation policy (leader report / reversible local steer / user escalation). Opt-in via TeamAgentSpec.reliability.
Refs: #751
| 4 小时前 |
| feat(agent-teams): add Human-in-the-Team (HITT) mode
Introduce a reserved human_agent member so a real human can join the
team as a first-class peer alongside leader and teammates. Enabled via
TeamAgentSpec.enable_hitt or the build_team(enable_hitt=true) tool
parameter.
Guarantees enforced in code and reinforced in prompts:
- human_agent stays READY; owns only send_message.
- Leader cannot cancel or reassign a task claimed by human_agent;
batch cancel_all preserves those tasks too.
- Messages addressed to human_agent (direct or broadcast) are
auto-marked read, so the dispatcher never spins on a human backlog.
- Plain-text output from the leader to human_agent is rejected at the
prompt layer; all cross-talk must go through send_message.
Extract the @mention router and user-facing delivery into a new
openjiuwen/agent_teams/interaction/ module, with UserInbox and
HumanAgentInbox as the two external entry points. Reserved member
names (user, team_leader, human_agent) live in a new constants.py.
Refs: #751
| 1 个月前 |
| fix(swarm): mirror team session id into logging trace_id contextvar
The logger renders trace_id from core's _trace_id_context (logging/utils),
but every team session binding (bind_session, team_runner, team_monitor,
spawn, external client, team_agent) only wrote agent_teams.context's
separate _session_id_context. The two contextvars never met, so core logs
emitted during team setup — resource registration, tag tagging — always
showed the "default_trace_id" placeholder while member_id rendered
correctly (it goes through core's set_member_id).
Bridge at the single chokepoint: agent_teams.context.set_session_id now
mirrors the session id into the core logging trace_id contextvar, and
reset_session_id restores the mirror to the now-current session id (or the
default placeholder when none). All team session-binding paths funnel
through this function, so every core log under a bound session now renders
the real trace id. The mirror is cosmetic and intentionally not
Token-tracked; topic routing still relies solely on _session_id_context.
Refs: #751
| 4 小时前 |
| feat(swarm): add native-harness async-tool framework and port swarmflow
Introduce a two-phase async background-tool framework scoped to NativeHarness
(AsyncTool / AsyncToolRuntime): invoke returns launched(task_id) immediately to
close the tool_use/ToolMessage pair, and the real result is injected later via
harness.send(immediate=False) — never as a suspended tool_result. Zero TeamAgent
dependency; tools reach the harness through a parent_agent reference.
Port swarmflow onto it as the first implementation: SwarmflowTool becomes an
AsyncTool whose run_background returns the full run summary + script result, fed
back complete (no truncation) on completion and as an error on failure. Phase
progress still streams via WORKFLOW_PROGRESS; workflow_completed is no longer
narrated. Remove TeamAgent._launch_swarmflow / run_swarmflow_background and the
swarmflow_active / swarmflow_tasks state; worker-model resolution and the
single-instance guard move into the tool/runtime.
Refs: #751
| 4 小时前 |
| feat(team_memory): Implement team memory functionality and related components
Refs: #751
Co-authored-by: white2025<baiyanxing@huawei.com>
# message auto-generated for no-merge-commit merge:
!1162 feat(team_memory): Implement team memory functionality and related components
From: @xiaoyifan
Reviewed-by: @alan_cheng, @iamcandiceguo
See merge request: openJiuwen/agent-core!1162 | 1 个月前 |
| feat(swarm): render absolute+relative time in agent-facing text
Message and task timestamps were stored (ms UTC epoch) but dropped at the
rendering layer, so agents could not judge recency, ordering, or delay.
Add timefmt.format_time_context to render '<local time> (<relative diff>)'
across message/task-board/stale nudges, external/MCP/CLI rendering, and
view_task output. Storage is unchanged; TaskSummary gains updated_at so the
list view can show relative time.
Refs: #751
| 5 天前 |
| chore(agent_teams): add copyright headers to all Python files
Add Huawei copyright header to all 67 Python files in the agent_teams
directory that were missing it. Standardizes copyright declarations
across the module to match project conventions.
Refs: #751
| 25 天前 |