feat: enhance CoordinatorConfig with toolPreset and disallowedTools options
This commit is contained in:
parent
30369b0597
commit
0b57ffe3e9
|
|
@ -885,7 +885,9 @@ export class OpenMultiAgent {
|
||||||
maxTurns: coordinatorOverrides?.maxTurns ?? 3,
|
maxTurns: coordinatorOverrides?.maxTurns ?? 3,
|
||||||
maxTokens: coordinatorOverrides?.maxTokens,
|
maxTokens: coordinatorOverrides?.maxTokens,
|
||||||
temperature: coordinatorOverrides?.temperature,
|
temperature: coordinatorOverrides?.temperature,
|
||||||
|
toolPreset: coordinatorOverrides?.toolPreset,
|
||||||
tools: coordinatorOverrides?.tools,
|
tools: coordinatorOverrides?.tools,
|
||||||
|
disallowedTools: coordinatorOverrides?.disallowedTools,
|
||||||
loopDetection: coordinatorOverrides?.loopDetection,
|
loopDetection: coordinatorOverrides?.loopDetection,
|
||||||
timeoutMs: coordinatorOverrides?.timeoutMs,
|
timeoutMs: coordinatorOverrides?.timeoutMs,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -449,8 +449,12 @@ export interface CoordinatorConfig {
|
||||||
readonly maxTurns?: number
|
readonly maxTurns?: number
|
||||||
readonly maxTokens?: number
|
readonly maxTokens?: number
|
||||||
readonly temperature?: number
|
readonly temperature?: number
|
||||||
|
/** Predefined tool preset for common coordinator use cases. */
|
||||||
|
readonly toolPreset?: 'readonly' | 'readwrite' | 'full'
|
||||||
/** Tool names available to the coordinator. */
|
/** Tool names available to the coordinator. */
|
||||||
readonly tools?: readonly string[]
|
readonly tools?: readonly string[]
|
||||||
|
/** Tool names explicitly denied to the coordinator. */
|
||||||
|
readonly disallowedTools?: readonly string[]
|
||||||
readonly loopDetection?: LoopDetectionConfig
|
readonly loopDetection?: LoopDetectionConfig
|
||||||
readonly timeoutMs?: number
|
readonly timeoutMs?: number
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,7 @@ describe('OpenMultiAgent', () => {
|
||||||
expect(coordinatorPrompt).not.toContain('You are a task coordinator responsible')
|
expect(coordinatorPrompt).not.toContain('You are a task coordinator responsible')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('applies advanced coordinator options (maxTokens, temperature, tools)', async () => {
|
it('applies advanced coordinator options (maxTokens, temperature, tools, disallowedTools)', async () => {
|
||||||
mockAdapterResponses = [
|
mockAdapterResponses = [
|
||||||
'```json\n[{"title": "Inspect", "description": "Inspect", "assignee": "worker-a"}]\n```',
|
'```json\n[{"title": "Inspect", "description": "Inspect", "assignee": "worker-a"}]\n```',
|
||||||
'worker output',
|
'worker output',
|
||||||
|
|
@ -343,7 +343,8 @@ describe('OpenMultiAgent', () => {
|
||||||
maxTurns: 5,
|
maxTurns: 5,
|
||||||
maxTokens: 1234,
|
maxTokens: 1234,
|
||||||
temperature: 0,
|
temperature: 0,
|
||||||
tools: ['file_read'],
|
tools: ['file_read', 'grep'],
|
||||||
|
disallowedTools: ['grep'],
|
||||||
timeoutMs: 1500,
|
timeoutMs: 1500,
|
||||||
loopDetection: { maxRepetitions: 2, loopDetectionWindow: 3 },
|
loopDetection: { maxRepetitions: 2, loopDetectionWindow: 3 },
|
||||||
},
|
},
|
||||||
|
|
@ -353,6 +354,34 @@ describe('OpenMultiAgent', () => {
|
||||||
expect(capturedChatOptions[0]?.temperature).toBe(0)
|
expect(capturedChatOptions[0]?.temperature).toBe(0)
|
||||||
expect(capturedChatOptions[0]?.tools).toBeDefined()
|
expect(capturedChatOptions[0]?.tools).toBeDefined()
|
||||||
expect(capturedChatOptions[0]?.tools?.map((t) => t.name)).toContain('file_read')
|
expect(capturedChatOptions[0]?.tools?.map((t) => t.name)).toContain('file_read')
|
||||||
|
expect(capturedChatOptions[0]?.tools?.map((t) => t.name)).not.toContain('grep')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('supports coordinator.toolPreset and intersects with tools allowlist', async () => {
|
||||||
|
mockAdapterResponses = [
|
||||||
|
'```json\n[{"title": "Inspect", "description": "Inspect", "assignee": "worker-a"}]\n```',
|
||||||
|
'worker output',
|
||||||
|
'final synthesis',
|
||||||
|
]
|
||||||
|
|
||||||
|
const oma = new OpenMultiAgent({
|
||||||
|
defaultModel: 'mock-model',
|
||||||
|
defaultProvider: 'openai',
|
||||||
|
})
|
||||||
|
const team = oma.createTeam('t', teamCfg([
|
||||||
|
{ ...agentConfig('worker-a'), model: 'worker-model' },
|
||||||
|
]))
|
||||||
|
|
||||||
|
await oma.runTeam(team, 'First inspect project, then produce output', {
|
||||||
|
coordinator: {
|
||||||
|
toolPreset: 'readonly',
|
||||||
|
tools: ['file_read', 'bash'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const coordinatorToolNames = capturedChatOptions[0]?.tools?.map((t) => t.name) ?? []
|
||||||
|
expect(coordinatorToolNames).toContain('file_read')
|
||||||
|
expect(coordinatorToolNames).not.toContain('bash')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue