feat(ui): configure maxParallelToolCalls for factory-created agents

The acp and stdio-agent plugins only forwarded `model` into their created
agents, so every factory/ACP deployment was pinned to the agent-loop default
parallel cap with no cordis.yml override. Add a `maxParallelToolCalls` config
field (positive-integer validated) to both, threaded through the existing
per-agent options path — symmetric with `model`.
This commit is contained in:
Dudu-0223
2026-07-14 11:55:39 +08:00
parent 8c8e5fdd24
commit eae8b8ce2e
7 changed files with 50 additions and 3 deletions

View File

@@ -248,6 +248,12 @@ function stringArrayContent(
export interface AcpConfig {
/** Model name for created agents (must have a registered adapter). */
model?: string
/**
* Maximum tool calls each created agent runs concurrently within one assistant
* step (a positive integer; the agent loop defaults it when omitted). `1`
* preserves fully serial execution.
*/
maxParallelToolCalls?: number
/**
* Transport stream override. Production omits this (the plugin wires
* `process.stdin`/`process.stdout` via `ndJsonStream`). Tests inject an
@@ -260,6 +266,9 @@ export interface AcpConfig {
export const Config: Schema<AcpConfig> = Schema.object({
model: Schema.string(),
// A positive integer; a bad value (0, negative, fractional) fails config
// validation here rather than being silently dropped from cordis.yml.
maxParallelToolCalls: Schema.number().step(1).min(1),
})
/**
@@ -1010,12 +1019,13 @@ export function apply(ctx: Context, config: AcpConfig): void {
* Build per-agent options from the plugin config, omitting absent fields
* (exactOptionalPropertyTypes: never assign `undefined` to an optional key).
* Exported for unit coverage of both the present and absent branches.
* @param config - the plugin config carrying the optional model name.
* @returns the per-agent options, with `model` present only when configured.
* @param config - the plugin config carrying the optional model name and parallel cap.
* @returns the per-agent options, with each field present only when configured.
*/
export function agentOptions(config: AcpConfig): { model?: string } {
export function agentOptions(config: AcpConfig): { model?: string; maxParallelToolCalls?: number } {
return {
...config.model !== undefined ? { model: config.model } : {},
...config.maxParallelToolCalls !== undefined ? { maxParallelToolCalls: config.maxParallelToolCalls } : {},
}
}