Skip to content

feat: add bulk execute/submit support for multiple pending tool calls - #3843

Merged
Pratham-Mishra04 merged 1 commit into
devfrom
05-28-feat_allow_executing_multiple_tools_in_the_prompt_playground
May 28, 2026
Merged

feat: add bulk execute/submit support for multiple pending tool calls#3843
Pratham-Mishra04 merged 1 commit into
devfrom
05-28-feat_allow_executing_multiple_tools_in_the_prompt_playground

Conversation

@impoiler

@impoiler impoiler commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

When a model returns multiple tool calls in a single message, users previously had to execute or respond to each one individually. This PR adds bulk "Execute all" and "Add manually" actions for messages containing multiple pending tool calls, allowing all results to be submitted in a single operation before continuing the conversation.

Changes

  • Added handleSubmitAllToolResults to the prompt context, which inserts all tool result messages at once and then triggers a single streaming completion request.
  • Added handleExecuteAllToolCalls to the prompt context, which runs all pending tool calls in parallel via Promise.all and then delegates to handleSubmitAllToolResults.
  • Updated ToolCallMessageView to detect when there are multiple pending tool calls and render a unified action bar below all tool call cards instead of per-card action bars. The unified bar offers "Execute all" and "Add manually" (which opens inline textareas on each card simultaneously) with a "Submit all results" button that activates once every textarea is filled.
  • Single tool call behavior is unchanged — the existing per-card execute/manual-entry flow is preserved when only one tool call is pending.
  • Removed the now-redundant JSDoc block from ToolCallMessageView.

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

  1. Open a prompt that uses a model and tools configured to return multiple tool calls in one response.
  2. Send a message that triggers two or more tool calls simultaneously.
  3. Verify the unified action bar appears below the tool call cards with "Execute all" and "Add manually" buttons.
  4. Click Execute all — confirm all tools execute in parallel and the conversation continues with a single follow-up completion.
  5. Repeat and click Add manually — confirm inline textareas appear on each card, the "Submit all results" button remains disabled until all fields are filled, and submitting sends all results and resumes the conversation.
  6. Verify that a message with only a single tool call still shows the original per-card execute/manual-entry UI.
cd ui
pnpm i
pnpm build

Screenshots/Recordings

image.png

Breaking changes

  • Yes
  • No

Related issues

Security considerations

No new auth, secrets, or PII handling introduced. Tool execution follows the same executeToolCall path as the existing single-call flow.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (3)
  • ui/components/prompts/components/messagesView/rootMessageView.tsx is excluded by none and included by none
  • ui/components/prompts/components/messagesView/toolCallView.tsx is excluded by none and included by none
  • ui/components/prompts/context.tsx is excluded by none and included by none

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6cb2eb44-80c1-4e80-9a53-320aa57ad519

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 05-28-feat_allow_executing_multiple_tools_in_the_prompt_playground

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@impoiler impoiler self-assigned this May 28, 2026
@impoiler
impoiler force-pushed the 05-28-feat_allow_executing_multiple_tools_in_the_prompt_playground branch 2 times, most recently from 0b30609 to 75b33cb Compare May 28, 2026 12:27
@impoiler
impoiler force-pushed the 05-28-feat_allow_executing_multiple_tools_in_the_prompt_playground branch from 75b33cb to 1d9f099 Compare May 28, 2026 12:35
@impoiler
impoiler marked this pull request as ready for review May 28, 2026 12:36

Pratham-Mishra04 commented May 28, 2026

Copy link
Copy Markdown
Collaborator

Merge activity

  • May 28, 12:38 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • May 28, 12:39 PM UTC: @Pratham-Mishra04 merged this pull request with Graphite.

@greptile-apps

greptile-apps Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 3/5

Two behavioral gaps in the new parallel execution paths need fixing before this ships: silent failures on per-card execution and all-or-nothing result loss when any tool in a batch fails.

The single-call path is untouched and safe. The new multi-call paths have two distinct gaps: handleExecuteOne in the component has no error handling at all, so a failing tool leaves the spinner gone and no feedback given; and handleExecuteAllToolCalls uses Promise.all, which discards results from successfully completed tools if any one tool throws.

toolCallView.tsx and context.tsx both need attention for the error-handling gaps in the multi-mode execution paths.

Important Files Changed

Filename Overview
ui/components/prompts/context.tsx Adds handleSubmitAllToolResults, handleExecuteAllToolCalls, and fetchToolResult. The parallel execution path uses Promise.all with fail-fast semantics, so any single tool failure discards all successful results. Also adds another crypto.randomUUID() call consistent with the pre-existing pattern.
ui/components/prompts/components/messagesView/toolCallView.tsx Adds bulk UI with unified action bar for multiple pending tool calls. handleExecuteOne (per-card execution in multi-mode) has no error handling — if fetchToolResult rejects, the error is silently lost with no user feedback. Single-call behavior and existing data-testid attributes are preserved.
ui/components/prompts/components/messagesView/rootMessageView.tsx Passes three new props (onSubmitAllToolResults, onExecuteAllToolCalls, fetchToolResult) from context down to ToolCallMessageView. Straightforward wiring with no issues.

Reviews (1): Last reviewed commit: "feat: Allow executing multiple tools in ..." | Re-trigger Greptile

Comment thread ui/components/prompts/components/messagesView/toolCallView.tsx
Comment on lines +697 to +712
setMessages((prev) => {
const withoutPlaceholder = prev.slice(0, -1);
return [...withoutPlaceholder, Message.error(error)];
});
},
onFinally: () => {
if (!isActive()) return;
setIsStreaming(false);
},
},
abortController.signal,
);
},
[messages, provider, model, modelParams, apiKeyId, variables, customHeaders, handleSubmitToolResult],
);

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.

P1 Promise.all fail-fast discards partial results

Promise.all rejects on the first tool failure, which means all results from tools that successfully completed before the failure are thrown away. The outer catch only shows a generic toast. If a user has 5 tool calls and 4 succeed but 1 fails, they must re-execute all 5. The per-card handleExecuteOne path avoids this by storing results independently, but handleExecuteAll — the one-click flow — has no recovery mechanism for partial failures. Consider Promise.allSettled and propagating individual errors per-call while still submitting the successful results.

insertAt++;
}
for (const { toolCallId, content } of results) {
const toolResultMsg = new Message(crypto.randomUUID(), 0, MessageType.ToolResult, {

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.

P2 Browser crypto API usage in handleSubmitAllToolResults

crypto.randomUUID() is a browser crypto API that fails in non-HTTPS contexts (such as plain http:// deployments). The existing handleSubmitToolResult (line 537) already uses this pattern, but this PR adds another call site in handleSubmitAllToolResults. If this UI is ever served over plain HTTP in a non-localhost environment, ID generation will throw a NotSupportedError here.

Rule Used: Alert when frontend code uses browser crypto APIs ... (source)

@Pratham-Mishra04
Pratham-Mishra04 merged commit b0c3f45 into dev May 28, 2026
15 checks passed
@Pratham-Mishra04
Pratham-Mishra04 deleted the 05-28-feat_allow_executing_multiple_tools_in_the_prompt_playground branch May 28, 2026 12:39
akshaydeo pushed a commit that referenced this pull request May 29, 2026
…#3843)

## Summary

When a model returns multiple tool calls in a single message, users previously had to execute or respond to each one individually. This PR adds bulk "Execute all" and "Add manually" actions for messages containing multiple pending tool calls, allowing all results to be submitted in a single operation before continuing the conversation.

## Changes

- Added `handleSubmitAllToolResults` to the prompt context, which inserts all tool result messages at once and then triggers a single streaming completion request.
- Added `handleExecuteAllToolCalls` to the prompt context, which runs all pending tool calls in parallel via `Promise.all` and then delegates to `handleSubmitAllToolResults`.
- Updated `ToolCallMessageView` to detect when there are multiple pending tool calls and render a unified action bar below all tool call cards instead of per-card action bars. The unified bar offers "Execute all" and "Add manually" (which opens inline textareas on each card simultaneously) with a "Submit all results" button that activates once every textarea is filled.
- Single tool call behavior is unchanged — the existing per-card execute/manual-entry flow is preserved when only one tool call is pending.
- Removed the now-redundant JSDoc block from `ToolCallMessageView`.

## Type of change

- [ ] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [ ] Core (Go)
- [ ] Transports (HTTP)
- [ ] Providers/Integrations
- [ ] Plugins
- [x] UI (React)
- [ ] Docs

## How to test

1. Open a prompt that uses a model and tools configured to return multiple tool calls in one response.
2. Send a message that triggers two or more tool calls simultaneously.
3. Verify the unified action bar appears below the tool call cards with "Execute all" and "Add manually" buttons.
4. Click **Execute all** — confirm all tools execute in parallel and the conversation continues with a single follow-up completion.
5. Repeat and click **Add manually** — confirm inline textareas appear on each card, the "Submit all results" button remains disabled until all fields are filled, and submitting sends all results and resumes the conversation.
6. Verify that a message with only a single tool call still shows the original per-card execute/manual-entry UI.

```sh
cd ui
pnpm i
pnpm build
```

## Screenshots/Recordings

![image.png](https://app.graphite.com/user-attachments/assets/efb2bc96-9d10-470e-80fe-742d7f53d191.png)



## Breaking changes

- [ ] Yes
- [x] No

## Related issues

## Security considerations

No new auth, secrets, or PII handling introduced. Tool execution follows the same `executeToolCall` path as the existing single-call flow.

## Checklist

- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [ ] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [ ] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
@akshaydeo akshaydeo mentioned this pull request May 29, 2026
18 tasks
akshaydeo added a commit that referenced this pull request May 29, 2026
## Summary

This PR releases **core v1.5.14**, **framework v1.3.14**, **transports v1.5.6**, and bumps all dependent plugins to their respective `.14` patch versions. It delivers a broad set of new capabilities across MCP authentication, key rotation, OTel metrics, Bedrock/Anthropic compatibility, and UI improvements, alongside a number of targeted bug fixes and refactors.

## Changes

- **Direct API Key Header** — Providers can now receive an API key passed directly via a request header (#3817)
- **MCP Per-User Auth** — Introduced `MCPCredentialStore` abstraction, per-user MCP credential reconciliation, and a new per-user header auth type with lazy-auth submission flow (#3656, #3702, #3703, #3704, #3705)
- **MCP TLS Configuration** — Added configurable TLS (`insecureSkipVerify`, `caCertPem`) for HTTP/SSE MCP client connections (#3779, #3783)
- **MCP Sessions Management** — Filter, search, and pagination on the MCP sessions list API and table, plus a `can_reauth` identity gate (#3823, #3824, #3825)
- **Key Rotation** — Keys now rotate on 401/402/403 responses; returns `502 upstream_credentials_exhausted` when all keys are permanently exhausted. Added `triggered_rotation` to `KeyAttemptRecord` and tightened `bifrost_key_rotation_events_total` semantics (#3430, #3491)
- **OTel Metrics** — Added OTel spec-compatible metrics (backward compatible) with provider cache and semantic cache attributes in metrics export (#3865, #3816)
- **Opus 4.8 Support** — System message handling and general compatibility for Opus 4.8 (#3868, #3878)
- **Dimension Rankings** — New `GetDimensionRankings` API and dashboard tabs for team, customer, BU, and user rankings (#3766)
- **Model Pricing Attributes** — `additional_attributes` field on model pricing rows with management API and UI editor (#3829)
- **Prompt Cache Retention** — Added prompt cache retention parameter on responses requests (#3810)
- **Tool Call Execution UI** — Inline tool-call execution, stop streaming, bulk execute/submit, and a redesigned tool-call UI (#3837, #3843)
- **Sheet Navigation** — Prev/next keyboard navigation and URL state across virtual key, MCP client, and routing rule sheets (#3739, #3740, #3744, #3745)
- **Bedrock Tool Name Truncation** — Truncate Bedrock function/tool names to the provider length limit
- **Bedrock Guardrails** — Set guardrail config in Bedrock requests built from responses (#3862)
- **Anthropic Tool Use** — Default `tool_use` input to `{}` when arguments are absent (#3880)
- **Responses Streaming** — Fixed responses stream events (#3838)
- **Compat Flow** — Fixed missing parameter parsing on the compat flow (#3881)
- **Passthrough API Version** — Set a default API version in passthrough requests as a fallback (#3853)
- **Virtual Key Updates** — Avoid overriding optional fields during virtual key update (#3855)
- **User-Mode Flows** — Gate user-mode flows on caller `user_id`, skip temp token mint, and unify flow/credential kind filtering for pending flows (#3841, #3859)
- **Partial Tool Calls** — Handle partial tool call execution failures and return successful results (#3849)
- **URL Query Escaping** — Support escaped characters in URL query parameters (#3826)
- **MCP Auth Errors** — Inline banner and retry support for MCP auth-required errors (#3856)
- **Renamed Resolvers** — `staticHeadersResolver`/`serverOAuthResolver` renamed to `sharedHeadersResolver`/`sharedOAuthResolver` (#3840)
- **Starlark Nested Tool Calls** — Exposed `RunWithPluginPipeline` on `ClientManager` and routed Starlark nested tool calls through the canonical plugin gate (#3794)
- **Deferred-Fill OAuth Removed** — Removed deferred-fill user-mode OAuth flow support (#3839)
- **Go 1.26.3** — Upgraded toolchain to Go 1.26.3 (#3782)

## Type of change

- [x] Bug fix
- [x] Feature
- [x] Refactor
- [ ] Documentation
- [x] Chore/CI

## Affected areas

- [x] Core (Go)
- [x] Transports (HTTP)
- [x] Providers/Integrations
- [x] Plugins
- [x] UI (React)
- [ ] Docs

## How to test

```sh
# Core/Transports
go version  # should report go1.26.3
go test ./...

# UI
cd ui
pnpm i || npm i
pnpm test || npm test
pnpm build || npm run build
```

- Validate MCP per-user auth by configuring a per-user header auth type and confirming credentials are stored and reconciled on virtual key and MCP client changes.
- Validate key rotation by triggering a 401/402/403 from an upstream provider and confirming rotation occurs; exhaust all keys and confirm a `502 upstream_credentials_exhausted` is returned.
- Validate OTel metrics output includes `provider_cache` and `semantic_cache` attributes.
- Validate Bedrock requests with tool names exceeding the provider limit are truncated correctly.
- Validate Opus 4.8 system message handling by sending a request with a system message to an Opus 4.8 endpoint.

## Breaking changes

- [x] Yes
- [ ] No

The deferred-fill user-mode OAuth flow has been removed (#3839). Any integrations relying on that flow must migrate to the new per-user credential store approach. The `staticHeadersResolver` and `serverOAuthResolver` identifiers have been renamed to `sharedHeadersResolver` and `sharedOAuthResolver` respectively (#3840); any direct references must be updated.

## Related issues

#3817, #3656, #3702, #3703, #3704, #3705, #3779, #3783, #3823, #3824, #3825, #3430, #3491, #3865, #3816, #3868, #3878, #3766, #3829, #3810, #3837, #3843, #3739, #3740, #3744, #3745, #3862, #3880, #3838, #3881, #3853, #3855, #3841, #3859, #3849, #3826, #3856, #3840, #3794, #3839, #3782, #3724, #3814, #3836, #3869, #3886

## Security considerations

- MCP per-user credentials are stored via the new `MCPCredentialStore` abstraction; ensure the backing store is appropriately access-controlled and that credential values are encrypted at rest.
- The direct API key header feature passes provider secrets via HTTP headers; ensure TLS is enforced on all ingress paths and that headers are not logged in plaintext.
- User-mode flows are now gated on `caller user_id` and temp token minting is skipped where appropriate, reducing the surface for privilege escalation.
- TLS configuration for MCP HTTP/SSE connections supports `insecureSkipVerify`; this should only be enabled in controlled environments.

## Checklist

- [x] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [x] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [x] I verified the CI pipeline passes locally if applicable
@akshaydeo akshaydeo mentioned this pull request May 29, 2026
akshaydeo added a commit that referenced this pull request May 29, 2026
## ✨ Features

- **Direct API Key Header** - Pass a provider API key directly via
request header (#3817)
- **MCP Per-User Authentication** - New per-user header auth type with
credential storage
  and lazy-auth submission flow (#3703, #3704, #3705)
- **MCP TLS Configuration** - Configurable TLS (insecureSkipVerify,
caCertPem) for HTTP/SSE
  MCP client connections (#3779, #3783)
- **MCP Sessions Management** - Filter, search, and pagination on the
MCP sessions list API
  and table, plus a can_reauth identity gate (#3823, #3824, #3825)
- **Tool Call Execution UI** - Inline tool-call execution, stop
streaming, bulk
  execute/submit, and a redesigned tool-call UI (#3837, #3843)
- **Dimension Rankings Dashboard** - New dashboard tabs for team,
customer, BU, and user
  rankings, backed by a GetDimensionRankings API (#3766)
- **Model Pricing Attributes** - additional_attributes on model pricing
rows with management
  API and UI editor (#3829)
- **Prompt Cache Retention** - Prompt cache retention parameter on
responses requests
  (#3810)
- **Opus 4.8 Support** - System message handling and compatibility for
Opus 4.8 (#3878,
  #3868)
  - **Key Rotation** - Rotate keys on 401/402/403 and return 502
upstream_credentials_exhausted when all keys are permanently dead
(#3491)
- **OTel Metrics** - OTel spec compatible metrics plus provider and
semantic cache
  attributes in metrics export (#3865, #3816)
- **Sheet Navigation** - Prev/next keyboard navigation and URL state
across virtual key, MCP
  client, and routing rule sheets (#3739, #3740, #3744, #3745)
  - **Go 1.26.3** - Upgraded toolchain to Go 1.26.3 (#3782)

  ## 🐞 Fixed

- **Bedrock Tool Names** - Truncate Bedrock function/tool names to the
provider length limit
- **Bedrock Guardrails** - Set guardrail config in Bedrock request built
from responses
  (#3862)
- **Anthropic Tool Use** - Default Anthropic tool_use input to {} when
arguments are absent
  (#3880)
  - **Responses Streaming** - Fixed responses stream events (#3838)
- **Compat Flow** - Fixed missing parameter parsing on the compat flow
(#3881)
- **Passthrough API Version** - Set a default API version in passthrough
requests as a
  fallback (#3853)
- **Virtual Key Updates** - Avoid overriding optional fields during
virtual key update
  (#3855)
- **User-Mode Flows** - Gate user-mode flows on caller user_id, skip
temp token mint, and
  unify flow/credential kind filtering for pending flows (#3841, #3859)
- **Partial Tool Calls** - Handle partial tool call execution failures
and return successful
  results (#3849)
- **URL Query Escaping** - Support escaped characters in URL query
parameters (#3826)
- **MCP Auth Errors** - Inline banner and retry support for MCP
auth-required errors (#3856)
- **JSON Editor Height** - Cap JSON editor max height at 400px in
message views (#3842)
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