Skip to content

feat: Report Band tool calls as turn activity - #841

Merged
AlexanderZ-Band merged 47 commits into
mainfrom
feat/python-sdk-report-activity-detail-to-the-platform-producers-INT-1744
Oct 21, 2026
Merged

AlexanderZ-Band merged 47 commits into
mainfrom
feat/python-sdk-report-activity-detail-to-the-platform-producers-INT-1744

Conversation

@AlexanderZ-Band

@AlexanderZ-Band AlexanderZ-Band commented Oct 18, 2026 •

Copy link
Copy Markdown
Collaborator

Why

#840 lets each turn carry room activity detail, but nothing reports it yet. Band's own tools (chat, contacts, memory, files and tasks) run through every adapter. Reporting them once, in the shared tool paths, gives every framework a visible tool_call with the tool's name before any adapter-specific mapping lands.

What

  • runtime/toolactivity.py is the single owner of what a tool shows:
    • tool_detail maps a tool name to its activity. Memory saves (store, supersede, archive), taken from the registry, show memory. Every other tool, including memory reads, shows tool_call with its name.
    • tool_activity reports a tool's start and end on the turn that ran it.
      • It resolves the observer once, so a tool always ends on the turn it started on.
      • It reports only from the outermost call (a ContextVar). A Band tool that calls other Band tools shows as itself until it ends.
      • Reports are best-effort. A failed observer update is logged at warning and never changes the tool's result; cancellation passes through.
    • @reports_tool_activity wraps every agent tool method except send_event, which adapters also call to post their own events. A model's send_event reports at the dispatcher.
  • activity_observer_of finds a tools object's observer with getattr_static. A duck-typed or mock tools object that never declared one runs unreported, instead of reporting to an auto-created attribute. DedupingAgentTools exposes its inner tools' observer.
  • Band tools report from every shared entry point:
    • AgentTools execution
    • MCP dispatch_tool
    • the Pydantic AI, CrewAI and Parlant Band-tool wrappers
    • Strands' Band-tool bridge
    • the Slack tee, including its own slack_send_message
  • Tests:
    • band.testing.ActivityRecorder (with observing(tools)) records what a turn observed. Producer tests assert through it.
    • One wire test runs a model band_send_message through a real ExecutionContext.
    • The new CrewAI and Parlant test files are listed in their lanes in ci.yml and in their coverage guards.

Scope

  • Shared producers and Band tools only.
  • Adapter-native tools, approvals and compaction come in the PRs stacked above. That includes custom tools on the MCP engine path (Claude SDK, OpenCode, Letta and the ACP client, all in the next PR) and Strands custom tools.
  • Parallel tools resolve "latest wins".
  • Second layer of INT-1744; stacked on feat: deliver compatible serialized activity detail #840.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DFmR3J53UqbsYDMmTUd3Rb

@AlexanderZ-Band
AlexanderZ-Band added this pull request to stack #842 October 18, 2026 08:05
@linear-code

linear-code Bot commented Oct 18, 2026

Copy link
Copy Markdown

INT-1744

@AlexanderZ-Band AlexanderZ-Band changed the title feat/python sdk report activity detail to the platform producers INT 1744 feat: Map provider and Band tool progress to room activity Oct 18, 2026
@AlexanderZ-Band
AlexanderZ-Band marked this pull request as ready for review October 18, 2026 08:09
@AlexanderZ-Band
AlexanderZ-Band force-pushed the feat/python-sdk-report-activity-detail-to-the-platform-producers-INT-1744 branch from 270fe17 to 191870e Compare October 18, 2026 08:12

@AlexanderZ-Band AlexanderZ-Band left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking — would be REQUEST_CHANGES on a PR by someone else. Cycle 1 found three verified issues: housekeeping acquisition, cancellation cleanup during initial reporting, and a missing terminal-clear assertion. Public runtime/MCP/REST reproductions and the mutation check confirmed them.

Comment thread src/band/runtime/turn.py Outdated
Comment thread src/band/runtime/turn.py Outdated
Comment thread tests/runtime/activityownership/test_detached_detail_feature.py Outdated
@AlexanderZ-Band
AlexanderZ-Band force-pushed the feat/python-sdk-report-activity-detail-to-the-platform-producers-INT-1744 branch from 191870e to dd716aa Compare October 18, 2026 08:42
@AlexanderZ-Band
AlexanderZ-Band requested review from a team and amit-gazal-band October 18, 2026 08:51
@AlexanderZ-Band
AlexanderZ-Band force-pushed the feat/python-sdk-report-activity-detail-to-the-platform-producers-INT-1744 branch from 42c90b0 to 0d3c24f Compare October 18, 2026 10:35
@AlexanderZ-Band
AlexanderZ-Band force-pushed the feat/python-sdk-report-activity-detail-to-the-platform-producers-INT-1744 branch from 0d3c24f to 1a6a291 Compare October 18, 2026 11:04
@AlexanderZ-Band
AlexanderZ-Band force-pushed the feat/python-sdk-report-activity-detail-to-the-platform-producers-INT-1744 branch from 1a6a291 to a674b67 Compare October 18, 2026 11:28
@AlexanderZ-Band AlexanderZ-Band changed the title feat: Map provider and Band tool progress to room activity feat: map provider and Band tool progress to room activity Oct 19, 2026

@bandzalkin bandzalkin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scope

Reviewed #841 at a674b67f6deeea036f7f4a55bf9a34b5d7e935f2 against #840 at 06d8124481475460782840b8854285cf7c0a2d92, plus the complete #839 → #840 → #841 stack from a96fb54d0c9e496b22fb80353eea48656294b0cb. Scope includes provider mappings, approval waits, registered Band tools, and the changed validation toolkit.

Constraints

Activity must describe actual work independently of chat narration, remain bound to its originating turn, and carry semantic names rather than private arguments/results. Cleanup must preserve borrowed resources and active sibling work. Provider mappings must match released wire contracts.

Decisions

Keep the single scope-owned, serialized reporter. Correct observation identity and provider/toolkit boundary handling rather than add another reporting owner. R1 and R2 expose observation-lifetime gaps within that design; the overall direction remains appropriate.

Findings and proof

Five new P2 findings, R1–R5, inline. Each has an independently failing offline behavioral probe: real compiled LangGraph parallel execution; MCP dispatch across Claude wrapper rebinding; released Codex compaction events through the adapter; actual Agno callable dispatch; and real Phoenix subscription ownership against a local fake server. Details and smallest corrections are in the inline discussions.

The three earlier findings remain fixed and are not reopened: housekeeping acquisition, initial-report cancellation, and terminal-clear assertion. Their regression coverage passed. Narration gating and compatibility deadline/fallback attacks did not establish additional defects.

Executed on the combined stack using locked, isolated Python 3.12 environments:

Suite Passed Skipped
Core activity, tools, adapters, delivery and conformance (dev) 1,466 69
Coding adapters, ACP and turn admission (dev) 1,372 10
CrewAI activity (dev-crewai) 2 0
Parlant activity (dev-parlant) 3 0
Strands activity and CI-selection checks (dev-strands-nooa) 5 0

These passing suites do not cover the five failing scenarios. Live platform/model acceptance and the full repository gate were not run. No product files were changed.

Architectural / merge verdict

HELD — the stack is not merge-ready until R1–R5 are corrected and verified. Also resolve #839's current conflict with main before integration.

Comment thread src/band/adapters/langgraph.py Outdated
Comment thread src/band/integrations/claude_sdk/dedup_tools.py Outdated
Comment thread src/band/adapters/codex.py Outdated
Comment thread tests/e2e/baseline/toolkit/tools.py
Comment thread tests/e2e/baseline/toolkit/activity.py Outdated
AlexanderZ-Band and others added 2 commits October 20, 2026 13:08
…t-activity-detail-to-the-platform-INT-1744

Keep main's BackendTurns ownership of OpenCode cancellation and register the
watcher as a turn worker so activity reporting outlives the handler. Reporter
unit tests move to tests/runtime/workingreporter; main's workingstate package
keeps the execution-level tests.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AgnNR4uiqD787Bg3yKdZpL
…detail-to-the-platform-INT-1744' into feat/python-sdk-report-activity-detail-to-the-platform-delivery-INT-1744

Port the startup-backlog claim-failure test edit to the split
tests/runtime/execution package.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AgnNR4uiqD787Bg3yKdZpL
AlexanderZ-Band and others added 2 commits October 21, 2026 18:34
Band tool methods show as tool_call with their name, or memory while
saving a memory, and return to reasoning when they end, even on failure
or cancellation. tool_activity resolves the turn observer once, so a tool
ends on the turn it started on. send_event reports only where a model
invoked it (execute_tool_call, MCP, Pydantic AI, CrewAI, Parlant). CrewAI
and Parlant custom tools report too. A tools object without a declared
observer stays unreported instead of conjuring one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFmR3J53UqbsYDMmTUd3Rb
Signed-off-by: Alexander Zaikman <alexander.zaikman@band.ai>
@AlexanderZ-Band AlexanderZ-Band changed the title feat: map provider and Band tool progress to room activity feat: Report Band tool calls as turn activity Oct 21, 2026
@AlexanderZ-Band
AlexanderZ-Band marked this pull request as ready for review October 21, 2026 15:40
@AlexanderZ-Band
AlexanderZ-Band force-pushed the feat/python-sdk-report-activity-detail-to-the-platform-producers-INT-1744 branch 2 times, most recently from d697f43 to 3f59acf Compare October 21, 2026 15:41
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFmR3J53UqbsYDMmTUd3Rb
Signed-off-by: Alexander Zaikman <alexander.zaikman@band.ai>

@AlexanderZ-Band AlexanderZ-Band left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking — would be REQUEST_CHANGES on a PR by someone else.

Cycle 1 of /my-code-review: nested Band tools overwrite the outer tool's activity, Strands' model send_event is unreported, and observer failures break tool calls. Test gaps cover the Slack tee, CrewAI/Parlant send_event, double reporting, real Pydantic AI runs, family coverage and a realistic multi-tool turn. Four dropped claims are posted as resolved no-fix records.

Comment thread src/band/runtime/turn.py Outdated
Comment thread docs/turn-outcome.md Outdated
Comment thread src/band/runtime/turn.py Outdated
Comment thread src/band/runtime/turn.py Outdated
Comment thread src/band/runtime/activity.py Outdated
Comment thread tests/runtime/toolactivity/conftest.py Outdated
Comment thread src/band/runtime/turn.py Outdated
Comment thread src/band/runtime/turn.py Outdated
Comment thread src/band/integrations/crewai/tools.py
Comment thread docs/turn-outcome.md Outdated
AlexanderZ-Band and others added 2 commits October 21, 2026 19:07
…t-activity-detail-to-the-platform-delivery-INT-1744

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFmR3J53UqbsYDMmTUd3Rb
Signed-off-by: Alexander Zaikman <alexander.zaikman@band.ai>
Only the outermost tool_activity reports, so a Band tool that calls other
Band tools (add/remove participant) shows as itself throughout. Every model
entry point (MCP, Pydantic AI, execute_tool_call, CrewAI, Parlant, Strands)
now wraps its call in tool_activity; the decorator's send_event exclusion is
the one predicate, and memory saves derive from the registry. Observer
updates are best-effort. The tool-activity producers move to
band.runtime.toolactivity.

Tests drive the real boundaries: an in-memory MCP session, a pydantic_ai
Agent with FunctionModel, a scripted Strands turn, the Slack tee, and the
CrewAI/Parlant send_event tools, plus a multi-tool turn sequence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFmR3J53UqbsYDMmTUd3Rb
Signed-off-by: Alexander Zaikman <alexander.zaikman@band.ai>
@bandzalkin
bandzalkin added this pull request to stack #904 October 21, 2026 16:23
bandzalkin added a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 21, 2026
Select upstream band-ai#841 (activity producers, carrying band-ai#839/band-ai#840 via
forward merges), band-ai#874 after 841 (tool-name emit gate with the I-08
name clamp), the host stack ahead of band-ai#763, band-ai#763 after 874 (native OMP
with the tool/permission activity hooks and omp_acp retirement), and
band-ai#854/band-ai#795/band-ai#848 after 763. Replayed from the branches' live heads.

@AlexanderZ-Band AlexanderZ-Band left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cycle 2 of /my-code-review found no in-scope issues. There are two out-of-scope gaps:

  • custom tools on the MCP engine and in Strands don't report activity;
  • the Slack tee's own slack_send_message doesn't report.

The rest are nits and test suggestions. The five dropped claims are posted as resolved no-fix records.

Comment thread src/band/integrations/mcp/engine.py
Comment thread src/band/integrations/slack/adapter.py
Comment thread src/band/runtime/toolactivity.py Outdated
Comment thread src/band/runtime/toolactivity.py
Comment thread tests/runtime/toolactivity/test_memory_tools.py Outdated
Comment thread src/band/runtime/toolactivity.py
Comment thread src/band/runtime/toolactivity.py
Comment thread src/band/integrations/mcp/engine.py
Comment thread src/band/integrations/claude_sdk/dedup_tools.py
Comment thread src/band/runtime/toolactivity.py
Base automatically changed from feat/python-sdk-report-activity-detail-to-the-platform-delivery-INT-1744 to main October 21, 2026 16:43
AlexanderZ-Band and others added 4 commits October 21, 2026 19:51
The Slack tee's own slack_send_message now reports through tool_activity.
The tools-class TypeVar is defined once beside agent_tool_methods, and the
start/end producers share one resolve-and-show helper.

Tests: failed and awaited memory saves, exact results and named failed
reports, a proxy that would conjure an observer, an intent-named Strands
turn helper, and a wire-level flow through a real ExecutionContext.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFmR3J53UqbsYDMmTUd3Rb
Signed-off-by: Alexander Zaikman <alexander.zaikman@band.ai>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFmR3J53UqbsYDMmTUd3Rb
Signed-off-by: Alexander Zaikman <alexander.zaikman@band.ai>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFmR3J53UqbsYDMmTUd3Rb
Signed-off-by: Alexander Zaikman <alexander.zaikman@band.ai>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFmR3J53UqbsYDMmTUd3Rb
Signed-off-by: Alexander Zaikman <alexander.zaikman@band.ai>
@AlexanderZ-Band
AlexanderZ-Band added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit a3c187e Oct 21, 2026
35 checks passed
@AlexanderZ-Band
AlexanderZ-Band deleted the feat/python-sdk-report-activity-detail-to-the-platform-producers-INT-1744 branch October 21, 2026 17:46
bandzalkin added a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 21, 2026
Select upstream band-ai#841 (activity producers, carrying band-ai#839/band-ai#840 via
forward merges), band-ai#874 after 841 (tool-name emit gate with the I-08
name clamp), the host stack ahead of band-ai#763, band-ai#763 after 874 (native OMP
with the tool/permission activity hooks and omp_acp retirement), and
band-ai#854/band-ai#795/band-ai#848 after 763. Replayed from the branches' live heads.
github-actions Bot pushed a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 21, 2026
Select upstream band-ai#841 (activity producers, carrying band-ai#839/band-ai#840 via
forward merges), band-ai#874 after 841 (tool-name emit gate with the I-08
name clamp), the host stack ahead of band-ai#763, band-ai#763 after 874 (native OMP
with the tool/permission activity hooks and omp_acp retirement), and
band-ai#854/band-ai#795/band-ai#848 after 763. Replayed from the branches' live heads.
github-actions Bot pushed a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 21, 2026
Select upstream band-ai#841 (activity producers, carrying band-ai#839/band-ai#840 via
forward merges), band-ai#874 after 841 (tool-name emit gate with the I-08
name clamp), the host stack ahead of band-ai#763, band-ai#763 after 874 (native OMP
with the tool/permission activity hooks and omp_acp retirement), and
band-ai#854/band-ai#795/band-ai#848 after 763. Replayed from the branches' live heads.
github-actions Bot pushed a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 21, 2026
Select upstream band-ai#841 (activity producers, carrying band-ai#839/band-ai#840 via
forward merges), band-ai#874 after 841 (tool-name emit gate with the I-08
name clamp), the host stack ahead of band-ai#763, band-ai#763 after 874 (native OMP
with the tool/permission activity hooks and omp_acp retirement), and
band-ai#854/band-ai#795/band-ai#848 after 763. Replayed from the branches' live heads.
github-actions Bot pushed a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 22, 2026
Select upstream band-ai#841 (activity producers, carrying band-ai#839/band-ai#840 via
forward merges), band-ai#874 after 841 (tool-name emit gate with the I-08
name clamp), the host stack ahead of band-ai#763, band-ai#763 after 874 (native OMP
with the tool/permission activity hooks and omp_acp retirement), and
band-ai#854/band-ai#795/band-ai#848 after 763. Replayed from the branches' live heads.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants