forked from JackChen-me/open-multi-agent
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path01-single-agent.ts
More file actions
131 lines (111 loc) · 4.43 KB
/
01-single-agent.ts
File metadata and controls
131 lines (111 loc) · 4.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
* Example 01 — Single Agent
*
* The simplest possible usage: one agent with bash and file tools, running
* a coding task. Then shows streaming output using the Agent class directly.
*
* Run:
* npx tsx examples/01-single-agent.ts
*
* Prerequisites:
* ANTHROPIC_API_KEY env var must be set.
*/
import { OpenMultiAgent, Agent, ToolRegistry, ToolExecutor, registerBuiltInTools } from '../src/index.js'
import type { OrchestratorEvent } from '../src/types.js'
// ---------------------------------------------------------------------------
// Part 1: Single agent via OpenMultiAgent (simplest path)
// ---------------------------------------------------------------------------
const orchestrator = new OpenMultiAgent({
defaultModel: 'claude-sonnet-4-6',
onProgress: (event: OrchestratorEvent) => {
if (event.type === 'agent_start') {
console.log(`[start] agent=${event.agent}`)
} else if (event.type === 'agent_complete') {
console.log(`[complete] agent=${event.agent}`)
}
},
})
console.log('Part 1: runAgent() — single one-shot task\n')
const result = await orchestrator.runAgent(
{
name: 'coder',
model: 'claude-sonnet-4-6',
systemPrompt: `You are a focused TypeScript developer.
When asked to implement something, write clean, minimal code with no extra commentary.
Use the bash tool to run commands and the file tools to read/write files.`,
tools: ['bash', 'file_read', 'file_write'],
maxTurns: 8,
},
`Create a small TypeScript utility function in /tmp/greet.ts that:
1. Exports a function named greet(name: string): string
2. Returns "Hello, <name>!"
3. Adds a brief usage comment at the top of the file.
Then add a default call greet("World") at the bottom and run the file with: npx tsx /tmp/greet.ts`,
)
if (result.success) {
console.log('\nAgent output:')
console.log('─'.repeat(60))
console.log(result.output)
console.log('─'.repeat(60))
} else {
console.error('Agent failed:', result.output)
process.exit(1)
}
console.log('\nToken usage:')
console.log(` input: ${result.tokenUsage.input_tokens}`)
console.log(` output: ${result.tokenUsage.output_tokens}`)
console.log(` tool calls made: ${result.toolCalls.length}`)
// ---------------------------------------------------------------------------
// Part 2: Streaming via Agent directly
//
// OpenMultiAgent.runAgent() is a convenient wrapper. When you need streaming, use
// the Agent class directly with an injected ToolRegistry + ToolExecutor.
// ---------------------------------------------------------------------------
console.log('\n\nPart 2: Agent.stream() — incremental text output\n')
// Build a registry with all built-in tools registered
const registry = new ToolRegistry()
registerBuiltInTools(registry)
const executor = new ToolExecutor(registry)
const streamingAgent = new Agent(
{
name: 'explainer',
model: 'claude-sonnet-4-6',
systemPrompt: 'You are a concise technical writer. Keep explanations brief.',
maxTurns: 3,
},
registry,
executor,
)
process.stdout.write('Streaming: ')
for await (const event of streamingAgent.stream(
'In two sentences, explain what a TypeScript generic constraint is.',
)) {
if (event.type === 'text' && typeof event.data === 'string') {
process.stdout.write(event.data)
} else if (event.type === 'done') {
process.stdout.write('\n')
} else if (event.type === 'error') {
console.error('\nStream error:', event.data)
}
}
// ---------------------------------------------------------------------------
// Part 3: Multi-turn conversation via Agent.prompt()
// ---------------------------------------------------------------------------
console.log('\nPart 3: Agent.prompt() — multi-turn conversation\n')
const conversationAgent = new Agent(
{
name: 'tutor',
model: 'claude-sonnet-4-6',
systemPrompt: 'You are a TypeScript tutor. Give short, direct answers.',
maxTurns: 2,
},
new ToolRegistry(), // no tools needed for this conversation
new ToolExecutor(new ToolRegistry()),
)
const turn1 = await conversationAgent.prompt('What is a type guard in TypeScript?')
console.log('Turn 1:', turn1.output.slice(0, 200))
const turn2 = await conversationAgent.prompt('Give me one concrete code example of what you just described.')
console.log('\nTurn 2:', turn2.output.slice(0, 300))
// History is retained between prompt() calls
console.log(`\nConversation history length: ${conversationAgent.getHistory().length} messages`)
console.log('\nDone.')