π fix: fix group broadcast trigger tool use#11646
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Reviewer's GuideAdds a disableTools flag to agent runtime and group orchestration broadcast flows so that broadcasted agents respond without invoking tools, wires this through the streaming executor, and strengthens tests around toolManifestMap behavior and group orchestration supervisor instructions. Also cleans up task status switch formatting and messaging. Sequence diagram for broadcast group orchestration with disableToolssequenceDiagram
participant Supervisor as GroupOrchestrationSupervisor
participant Store as GroupOrchestrationExecutors
participant ChatSlice as StreamingExecutor
participant ToolsEngine as AgentToolsEngine
Note over Supervisor,Store: Supervisor decides to broadcast to multiple agents
Supervisor->>Store: parallel_call_agents(instruction)
Store->>Store: Extract agentIds, disableTools, toolMessageId
Store->>Store: Prepare messageContext and messagesWithInstruction
loop For each agentId
Store->>ChatSlice: internal_execAgentRuntime({context.subAgentId=agentId, disableTools=true, messages, parentMessageId})
ChatSlice->>ChatSlice: internal_execAgentRuntime extracts disableTools and context
ChatSlice->>ChatSlice: streamingExecutor({disableTools, messages, parentMessageId, agentId, topicId, threadId})
alt disableTools is false
ChatSlice->>ToolsEngine: createAgentToolsEngine(model, provider)
ChatSlice->>ToolsEngine: generateToolsDetailed(model, provider, pluginIds)
ToolsEngine-->>ChatSlice: enabledToolIds
ChatSlice->>ToolsEngine: getEnabledPluginManifests(enabledToolIds)
ToolsEngine-->>ChatSlice: toolManifestMap
ChatSlice->>ChatSlice: Execute agent runtime with tools
else disableTools is true
ChatSlice->>ChatSlice: Skip tools generation
ChatSlice->>ChatSlice: Execute agent runtime without tools
end
end
Class diagram for updated group orchestration and streaming executor typesclassDiagram
class GroupOrchestrationSupervisor {
-config
+handleParallelCallAgents(params)
}
class SupervisorInstructionParallelCallAgentsPayload {
+string[] agentIds
+bool disableTools
+string instruction
+string toolMessageId
}
class SupervisorInstructionParallelCallAgents {
+SupervisorInstructionParallelCallAgentsPayload payload
}
class GroupOrchestrationExecutors {
+parallel_call_agents(instruction, state) GroupOrchestrationExecutorOutput
}
class StreamingExecutorAction {
+string operationId
+ConversationContext context
+string agentId
+bool disableTools
+string topicId
+string threadId
+unknown initialState
+string parentMessageId
+string parentMessageType
+Message[] messages
}
class InternalExecAgentRuntimeParams {
+ConversationContext context
+bool disableTools
+Message[] messages
+string parentMessageId
+string parentMessageType
+unknown initialState
}
class StreamingExecutor {
+streamingExecutor(action StreamingExecutorAction) Promise~void~
+internal_execAgentRuntime(params InternalExecAgentRuntimeParams) Promise~void~
}
class AgentToolsEngine {
+generateToolsDetailed(model, provider, toolIds) ToolsDetailed
+getEnabledPluginManifests(enabledToolIds) Map~string, PluginManifest~
}
class ConversationContext {
+string agentId
+string topicId
+string threadId
+string groupId
+string subAgentId
+string scope
}
GroupOrchestrationSupervisor --> SupervisorInstructionParallelCallAgents : constructs
SupervisorInstructionParallelCallAgents *-- SupervisorInstructionParallelCallAgentsPayload : payload
GroupOrchestrationSupervisor --> GroupOrchestrationExecutors : sends instructions
GroupOrchestrationExecutors --> StreamingExecutor : internal_execAgentRuntime
InternalExecAgentRuntimeParams --> ConversationContext : uses
StreamingExecutorAction --> ConversationContext : context
StreamingExecutor ..> AgentToolsEngine : uses when disableTools is false
StreamingExecutorAction --> StreamingExecutor : input to streamingExecutor
InternalExecAgentRuntimeParams --> StreamingExecutor : input to internal_execAgentRuntime
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
TestGru AssignmentSummary
Files
Tip You can |
Codecov Reportβ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## next #11646 +/- ##
==========================================
- Coverage 82.82% 74.08% -8.75%
==========================================
Files 85 1188 +1103
Lines 2358 94707 +92349
Branches 361 10867 +10506
==========================================
+ Hits 1953 70162 +68209
- Misses 397 24455 +24058
- Partials 8 90 +82
Flags with carried forward coverage won't be shown. Click here to find out more.
π New features to boost your workflow:
|
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- In
streamingExecutor.internal_createAgentState, the localenabledToolIdsvariable is assigned but never used, so consider either wiring it into the returned state (if needed) or removing it to avoid dead code. - In the new
internal_createAgentState with disableToolstests, thevi.spyOn(agentConfigResolver, 'resolveAgentConfig')mock is not restored, which can leak state into other tests; consider callingmockRestore()or usingvi.restoreAllMocks()in anafterEach.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `streamingExecutor.internal_createAgentState`, the local `enabledToolIds` variable is assigned but never used, so consider either wiring it into the returned state (if needed) or removing it to avoid dead code.
- In the new `internal_createAgentState with disableTools` tests, the `vi.spyOn(agentConfigResolver, 'resolveAgentConfig')` mock is not restored, which can leak state into other tests; consider calling `mockRestore()` or using `vi.restoreAllMocks()` in an `afterEach`.
## Individual Comments
### Comment 1
<location> `src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts:1419-1428` </location>
<code_context>
+ describe('internal_createAgentState with disableTools', () => {
</code_context>
<issue_to_address>
**suggestion (testing):** Strengthen the `disableTools: true` test by ensuring tools are actually configured but still not used.
This test only checks that `toolManifestMap` is `{}` when `disableTools` is `true`, but it never configures any plugins/tools. As a result, it would also pass if there were simply no tools available. To better validate the behavior, mock `resolveAgentConfig` (as in the second test) to return at least one plugin and assert that `toolManifestMap` remains empty. That will confirm tools are skipped specifically due to `disableTools`.
Suggested implementation:
```typescript
describe('internal_createAgentState with disableTools', () => {
it('should return empty toolManifestMap when disableTools is true', async () => {
act(() => {
useChatStore.setState({ internal_execAgentRuntime: realExecAgentRuntime });
});
// Ensure tools/plugins are configured but should be ignored due to disableTools
const resolveAgentConfigMock = resolveAgentConfig as jest.MockedFunction<typeof resolveAgentConfig>;
resolveAgentConfigMock.mockResolvedValue({
plugins: [
{
id: 'test-plugin',
name: 'Test Plugin',
tools: [
{
name: 'test-tool',
displayName: 'Test Tool',
description: 'A test tool to ensure tools are configured',
parameters: {
type: 'object',
properties: {},
},
},
],
},
],
} as any);
const { result } = renderHook(() => useChatStore());
const userMessage = {
id: TEST_IDS.USER_MESSAGE_ID,
role: 'user',
content: TEST_CONTENT.USER_MESSAGE,
```
1. The snippet above assumes:
- `resolveAgentConfig` is imported into this test file.
- Jest is being used, and `resolveAgentConfig` can be treated as `jest.MockedFunction`.
2. You already mentioned there is a second test in this file that mocks `resolveAgentConfig`. To stay consistent with the existing test suite:
- Use the same import source and mocking style as that second test (e.g., `jest.spyOn(module, 'resolveAgentConfig')` or `vi.spyOn` if using Vitest).
- If the other test uses `jest.spyOn`, replace the `const resolveAgentConfigMock = ...` line with the same pattern, for example:
```ts
const resolveAgentConfigMock = jest.spyOn(agentConfigModule, 'resolveAgentConfig');
resolveAgentConfigMock.mockResolvedValue(/* same object as above */);
```
3. After the code that calls `internal_createAgentState`, add/ensure an assertion exists that checks `toolManifestMap` is empty, e.g.:
```ts
expect(agentState.toolManifestMap).toEqual({});
```
If you already had such an assertion, no additional change is needed beyond the mock itself.
4. If your test framework is Vitest instead of Jest, replace `jest.MockedFunction` and `jest.spyOn` with the corresponding `vi` APIs to match the rest of the file.
</issue_to_address>
### Comment 2
<location> `src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts:1447-1456` </location>
<code_context>
+ it('should include tools in toolManifestMap when disableTools is false or undefined', async () => {
</code_context>
<issue_to_address>
**suggestion (testing):** Also assert that the toolManifestMap is non-empty when tools are enabled to better prove the behavior.
Right now the test would still pass if both maps were empty (e.g., if no tools were actually enabled). Please add an assertion that `toolManifestMap` is non-empty (for example, `expect(Object.keys(stateWithoutDisable.toolManifestMap).length).toBeGreaterThan(0);`) so the test verifies that tools are truly configured when `disableTools` is not true.
Suggested implementation:
```typescript
const stateWithoutDisable = useChatStore.getState();
expect(Object.keys(stateWithoutDisable.toolManifestMap).length).toBeGreaterThan(0);
```
If the variable holding the state in this test is not named `stateWithoutDisable`, replace `stateWithoutDisable` in the new expectation with the actual state variable name used in the `"should include tools in toolManifestMap when disableTools is false or undefined"` test. The new assertion should be placed after the state is read and before the test's final expectations/return.
</issue_to_address>Help me be more useful! Please click π or π on each comment and I'll use the feedback to improve your reviews.
c9519fe to
abed2c7
Compare
abed2c7 to
e476c6a
Compare
|
β€οΈ Great PR @arvinxx β€οΈ The growth of the project is inseparable from user feedback and contributions. Thanks for your contribution! If you are interested in the lobehub developer community, please join our discord and then dm @arvinxx or @canisminor1990. They will invite you to our private developer channel. We are talking about lobe-chat development and sharing AI news from around the world.
Original Contentβ€οΈ Great PR @arvinxx β€οΈ The growth of project is inseparable from user feedback and contribution, thanks for your contribution! If you are interesting with the lobehub developer community, please join our discord and then dm @arvinxx or @canisminor1990. They will invite you to our private developer channel. We are talking about the lobe-chat development or sharing ai newsletter around the world. |
## [Version 2.0.0-next.339](v2.0.0-next.338...v2.0.0-next.339) <sup>Released on **2026-01-22**</sup> #### β» Code Refactoring - **misc**: Move vercel-react-best-practices skills to .agents directory. #### β¨ Features - **misc**: Skill setting page and skill store. #### π Bug Fixes - **model-runtime**: Filter unsupported image types (SVG) before sending to vision models. - **misc**: Fix group broadcast trigger tool use, fix local system tools. <br/> <details> <summary><kbd>Improvements and Fixes</kbd></summary> #### Code refactoring * **misc**: Move vercel-react-best-practices skills to .agents directory, closes [#11703](#11703) ([6df7731](6df7731)) #### What's improved * **misc**: Skill setting page and skill store, closes [#11665](#11665) ([d8c0c26](d8c0c26)) #### What's fixed * **model-runtime**: Filter unsupported image types (SVG) before sending to vision models, closes [#11698](#11698) ([c0c99a7](c0c99a7)) * **misc**: Fix group broadcast trigger tool use, closes [#11646](#11646) ([831a9b3](831a9b3)) * **misc**: Fix local system tools, closes [#11702](#11702) ([6548fc7](6548fc7)) </details> <div align="right"> [](#readme-top) </div>
|
π This PR is included in version 2.0.0-next.339 π The release is available on: Your semantic-release bot π¦π |
## [Version 1.153.0](v1.152.0...v1.153.0) <sup>Released on **2026-01-23**</sup> #### β» Code Refactoring - **auth**: Remove NEXT_PUBLIC_AUTH_URL env variable. - **model-select**: Migrate FunctionCallingModelSelect to LobeSelect. - **ModelSwitchPanel**: Migrate from Popover to DropdownMenu with virtual scrolling. - **userMemories**: Removed un-used code. - **misc**: Improve memory data with experience and identity, move vercel-react-best-practices skills to .agents directory. #### β¨ Features - **database**: Added user memory activity. - **desktop**: Add legacy local database detection and migration guidance. - **misc**: Add platform-aware download client menu option, add server version check for desktop app, remove Clerk authentication code, skill setting page and skill store, support agent group unpublish agents, support client tasks mode, update the sandbox preinstall libs in sys role. #### π Bug Fixes - **copilot**: Pass correct scope when creating new session in PageEditor. - **desktop**: Gracefully handle missing update manifest 404 errors. - **model-runtime**: Filter unsupported image types (SVG) before sending to vision models. - **pdf**: Upgrade pdfjs-dist and react-pdf to v5.x. - **sidebar-drawer**: Fix drawer positioning and title style. - **misc**: Fix group broadcast trigger tool use, fix local system tools, fix memory schema, fix multi agent tasks issue, fix multi tasks no summary issue, fix scope issue, fix tool argument scape and improve multi task run, fixed the sandbox tools call when error should use right callback, improve e2e server and complete i18n resources, slove the agent group editor not focus in editdata area, slove the agents header switch agents the lobeAI not show problem, sloved the old removeSessionTopics not work, TypewriterEffect not refreshing on language change, updata cron job ui & fixed commnuity pagenation goto error, update the agentbuilder tools not always use humanIntervention. #### π Styles - **misc**: Improve auto scroll and group profile, update og, update share style. <br/> <details> <summary><kbd>Improvements and Fixes</kbd></summary> #### Code refactoring * **auth**: Remove NEXT_PUBLIC_AUTH_URL env variable, closes [lobehub#11658](https://github.com/jaworldwideorg/OneJA-Bot/issues/11658) ([c0f9875](c0f9875)) * **model-select**: Migrate FunctionCallingModelSelect to LobeSelect, closes [lobehub#11664](https://github.com/jaworldwideorg/OneJA-Bot/issues/11664) ([ad51305](ad51305)) * **ModelSwitchPanel**: Migrate from Popover to DropdownMenu with virtual scrolling, closes [lobehub#11663](https://github.com/jaworldwideorg/OneJA-Bot/issues/11663) ([c9d9dff](c9d9dff)) * **userMemories**: Removed un-used code, closes [lobehub#11713](https://github.com/jaworldwideorg/OneJA-Bot/issues/11713) ([89750fc](89750fc)) * **misc**: Improve memory data with experience and identity, closes [lobehub#11717](https://github.com/jaworldwideorg/OneJA-Bot/issues/11717) ([bdb3eb4](bdb3eb4)) * **misc**: Move vercel-react-best-practices skills to .agents directory, closes [lobehub#11703](https://github.com/jaworldwideorg/OneJA-Bot/issues/11703) ([6df7731](6df7731)) #### What's improved * **database**: Added user memory activity, closes [lobehub#11680](https://github.com/jaworldwideorg/OneJA-Bot/issues/11680) ([0160fbd](0160fbd)) * **desktop**: Add legacy local database detection and migration guidance, closes [lobehub#11682](https://github.com/jaworldwideorg/OneJA-Bot/issues/11682) ([5664b84](5664b84)) * **misc**: Add platform-aware download client menu option, closes [lobehub#11676](https://github.com/jaworldwideorg/OneJA-Bot/issues/11676) ([55abddc](55abddc)) * **misc**: Add server version check for desktop app, closes [lobehub#11710](https://github.com/jaworldwideorg/OneJA-Bot/issues/11710) ([0cf2723](0cf2723)) * **misc**: Remove Clerk authentication code, closes [lobehub#11711](https://github.com/jaworldwideorg/OneJA-Bot/issues/11711) ([395595a](395595a)) * **misc**: Skill setting page and skill store, closes [lobehub#11665](https://github.com/jaworldwideorg/OneJA-Bot/issues/11665) ([d8c0c26](d8c0c26)) * **misc**: Support agent group unpublish agents, closes [lobehub#11687](https://github.com/jaworldwideorg/OneJA-Bot/issues/11687) ([4e060be](4e060be)) * **misc**: Support client tasks mode, closes [lobehub#11666](https://github.com/jaworldwideorg/OneJA-Bot/issues/11666) ([98cf57b](98cf57b)) * **misc**: Update the sandbox preinstall libs in sys role, closes [lobehub#11688](https://github.com/jaworldwideorg/OneJA-Bot/issues/11688) ([404c577](404c577)) #### What's fixed * **copilot**: Pass correct scope when creating new session in PageEditor, closes [lobehub#11714](https://github.com/jaworldwideorg/OneJA-Bot/issues/11714) ([0259270](0259270)) * **desktop**: Gracefully handle missing update manifest 404 errors, closes [lobehub#11625](https://github.com/jaworldwideorg/OneJA-Bot/issues/11625) ([13e95b9](13e95b9)) * **model-runtime**: Filter unsupported image types (SVG) before sending to vision models, closes [lobehub#11698](https://github.com/jaworldwideorg/OneJA-Bot/issues/11698) ([c0c99a7](c0c99a7)) * **pdf**: Upgrade pdfjs-dist and react-pdf to v5.x, closes [lobehub#11686](https://github.com/jaworldwideorg/OneJA-Bot/issues/11686) ([2b620df](2b620df)) * **sidebar-drawer**: Fix drawer positioning and title style, closes [lobehub#11655](https://github.com/jaworldwideorg/OneJA-Bot/issues/11655) ([cf5320e](cf5320e)) * **misc**: Fix group broadcast trigger tool use, closes [lobehub#11646](https://github.com/jaworldwideorg/OneJA-Bot/issues/11646) ([831a9b3](831a9b3)) * **misc**: Fix local system tools, closes [lobehub#11702](https://github.com/jaworldwideorg/OneJA-Bot/issues/11702) ([6548fc7](6548fc7)) * **misc**: Fix memory schema, closes [lobehub#11645](https://github.com/jaworldwideorg/OneJA-Bot/issues/11645) ([3baf780](3baf780)) * **misc**: Fix multi agent tasks issue, closes [lobehub#11672](https://github.com/jaworldwideorg/OneJA-Bot/issues/11672) ([9de773b](9de773b)) * **misc**: Fix multi tasks no summary issue, closes [lobehub#11685](https://github.com/jaworldwideorg/OneJA-Bot/issues/11685) ([26ce317](26ce317)) * **misc**: Fix scope issue, closes [lobehub#11719](https://github.com/jaworldwideorg/OneJA-Bot/issues/11719) ([17adde8](17adde8)) * **misc**: Fix tool argument scape and improve multi task run, closes [lobehub#11691](https://github.com/jaworldwideorg/OneJA-Bot/issues/11691) ([b13bb8a](b13bb8a)) * **misc**: Fixed the sandbox tools call when error should use right callback, closes [lobehub#11721](https://github.com/jaworldwideorg/OneJA-Bot/issues/11721) ([e8fce68](e8fce68)) * **misc**: Improve e2e server and complete i18n resources, closes [lobehub#11678](https://github.com/jaworldwideorg/OneJA-Bot/issues/11678) ([d450dd9](d450dd9)) * **misc**: Slove the agent group editor not focus in editdata area, closes [lobehub#11677](https://github.com/jaworldwideorg/OneJA-Bot/issues/11677) ([9ac84e6](9ac84e6)) * **misc**: Slove the agents header switch agents the lobeAI not show problem, closes [lobehub#11726](https://github.com/jaworldwideorg/OneJA-Bot/issues/11726) ([f45f508](f45f508)) * **misc**: Sloved the old removeSessionTopics not work, closes [lobehub#11671](https://github.com/jaworldwideorg/OneJA-Bot/issues/11671) ([06d41e5](06d41e5)) * **misc**: TypewriterEffect not refreshing on language change, closes [lobehub#11657](https://github.com/jaworldwideorg/OneJA-Bot/issues/11657) ([ba30f46](ba30f46)) * **misc**: Updata cron job ui & fixed commnuity pagenation goto error, closes [lobehub#11700](https://github.com/jaworldwideorg/OneJA-Bot/issues/11700) ([42ad2a0](42ad2a0)) * **misc**: Update the agentbuilder tools not always use humanIntervention, closes [lobehub#11696](https://github.com/jaworldwideorg/OneJA-Bot/issues/11696) ([0d3017b](0d3017b)) #### Styles * **misc**: Improve auto scroll and group profile, closes [lobehub#11725](https://github.com/jaworldwideorg/OneJA-Bot/issues/11725) ([550acc2](550acc2)) * **misc**: Update og, closes [lobehub#11709](https://github.com/jaworldwideorg/OneJA-Bot/issues/11709) ([01cf4e4](01cf4e4)) * **misc**: Update share style, closes [lobehub#11716](https://github.com/jaworldwideorg/OneJA-Bot/issues/11716) ([3c70dfa](3c70dfa)) </details> <div align="right"> [](#readme-top) </div>
π» Change Type
π Related Issue
π Description of Change
π§ͺ How to Test
πΈ Screenshots / Videos
π Additional Information
Summary by Sourcery
Propagate a new disableTools flag through agent runtime and group orchestration so broadcasted agent calls run without tools by default, and add tests to validate tool disabling behavior.
New Features:
Bug Fixes:
Enhancements:
Tests: