feat(core): add multi-agent patterns#11
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR adds multi-agent orchestration patterns to the JAF core library, introducing helper functions for sequential, parallel, coordinator, and redundant pipelines. The changes enable developers to compose multiple agents in sophisticated workflows beyond simple single-agent interactions.
- Implements four multi-agent patterns: sequential pipelines, parallel pipelines, coordinator routing, and parallel redundant evaluation
- Exports new multi-agent functions from core index for external use
- Creates comprehensive demo example with mock model provider to showcase all patterns
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/index.ts | Exports multi-agent module from core |
| src/core/multi-agent.ts | Implements four multi-agent orchestration patterns |
| examples/multi-agent-demo/tsconfig.json | TypeScript configuration for demo project |
| examples/multi-agent-demo/package.json | Package configuration with workspace dependency |
| examples/multi-agent-demo/index.ts | Demo showcasing all multi-agent patterns with mock agents |
| examples/multi-agent-demo/README.md | Documentation explaining demo usage and patterns |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| currentInput = outputToString(result.outcome.output); | ||
| } | ||
|
|
||
| return lastResult!; |
There was a problem hiding this comment.
Using non-null assertion operator on lastResult is unsafe. If agentNames is empty, lastResult will be undefined and this will throw a runtime error. Consider adding a guard clause or returning an appropriate error result for empty arrays.
| if (res3.outcome.status === 'error') { | ||
| return res3; | ||
| } | ||
| const combined = `${outputToString(res2.outcome.output)}\n${outputToString(res3.outcome.output)}`; |
There was a problem hiding this comment.
[nitpick] The output combination logic uses hardcoded newline separation. Consider making the separator configurable or using a more structured approach to combine outputs, as different use cases may require different formatting.
| End: input => `Final result: ${input}`, | ||
| Answer1: () => '42', | ||
| Answer2: () => '41', | ||
| Judge: input => (input.includes('Response from Answer1') ? '42' : '41') |
There was a problem hiding this comment.
[nitpick] The Judge behavior relies on hardcoded string matching which is brittle. This makes the demo fragile to changes in the evaluation input format. Consider using a more robust parsing approach or making the expected format explicit.
| Judge: input => (input.includes('Response from Answer1') ? '42' : '41') | |
| Judge: input => { | |
| // Parse responses from Answer1 and Answer2 | |
| // Expected format: "Response from Answer1: <answer1>\nResponse from Answer2: <answer2>" | |
| const answer1Match = input.match(/Response from Answer1: ([^\n]+)/); | |
| const answer2Match = input.match(/Response from Answer2: ([^\n]+)/); | |
| const answer1 = answer1Match ? answer1Match[1].trim() : null; | |
| const answer2 = answer2Match ? answer2Match[1].trim() : null; | |
| // Prefer answer1 if present, otherwise answer2 | |
| if (answer1) return answer1; | |
| if (answer2) return answer2; | |
| // Fallback if neither found | |
| return 'No valid answer found'; | |
| } |
7fbbb18 to
e05de49
Compare
Summary
Testing
pnpm test(fails: PostgreSQL artifact storage connection refused)https://chatgpt.com/codex/tasks/task_e_68bea714b4688327820c3eae3b2143ad