@alexnetrebskii/hive-agent 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -676
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +4 -0
- package/dist/agent.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/providers/env/memory.d.ts +14 -0
- package/dist/providers/env/memory.d.ts.map +1 -0
- package/dist/providers/env/memory.js +19 -0
- package/dist/providers/env/memory.js.map +1 -0
- package/dist/shell/commands/curl.d.ts.map +1 -1
- package/dist/shell/commands/curl.js +65 -7
- package/dist/shell/commands/curl.js.map +1 -1
- package/dist/shell/commands/env.d.ts +8 -0
- package/dist/shell/commands/env.d.ts.map +1 -0
- package/dist/shell/commands/env.js +41 -0
- package/dist/shell/commands/env.js.map +1 -0
- package/dist/shell/commands/index.d.ts +2 -1
- package/dist/shell/commands/index.d.ts.map +1 -1
- package/dist/shell/commands/index.js +4 -2
- package/dist/shell/commands/index.js.map +1 -1
- package/dist/shell/shell.d.ts +8 -0
- package/dist/shell/shell.d.ts.map +1 -1
- package/dist/shell/shell.js +14 -3
- package/dist/shell/shell.js.map +1 -1
- package/dist/shell/types.d.ts +2 -0
- package/dist/shell/types.d.ts.map +1 -1
- package/dist/tools/shell.d.ts.map +1 -1
- package/dist/tools/shell.js +11 -5
- package/dist/tools/shell.js.map +1 -1
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/workspace.d.ts +6 -1
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +7 -0
- package/dist/workspace.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,715 +1,109 @@
|
|
|
1
1
|
# Hive Agent
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Claude Code-like AI agent for your own application. Add a few lines — get a multi-agent system that asks clarifying questions, plans tasks, and works with your data.**
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- **Stateless design** - Works in Firebase Functions, serverless environments
|
|
8
|
-
- **No built-in tools** - You define your own tools
|
|
9
|
-
- **External history** - Accepts/returns conversation history (for Firestore, etc.)
|
|
10
|
-
- **Sub-agents** - Spawn specialized agents for complex tasks
|
|
11
|
-
- **Structured I/O** - Type-safe input/output schemas for sub-agents
|
|
12
|
-
- **Multi-provider** - Claude and OpenAI support, easily extensible
|
|
13
|
-
- **Interactive** - Built-in `__ask_user__` tool for clarifying questions
|
|
14
|
-
- **Progress tracking** - Todo lists and real-time progress callbacks
|
|
15
|
-
- **Execution tracing** - Full hierarchy tracking with cost breakdown
|
|
16
|
-
- **Prompt caching** - Claude prompt caching for cost reduction
|
|
17
|
-
|
|
18
|
-
## Installation
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
pnpm add @alexnetrebskii/hive-agent
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Quick Start
|
|
25
|
-
|
|
26
|
-
```typescript
|
|
27
|
-
import { Hive, ClaudeProvider } from '@alexnetrebskii/hive-agent'
|
|
28
|
-
|
|
29
|
-
const provider = new ClaudeProvider({
|
|
30
|
-
apiKey: process.env.ANTHROPIC_API_KEY
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
const agent = new Hive({
|
|
34
|
-
systemPrompt: 'You are a helpful assistant.',
|
|
35
|
-
tools: [],
|
|
36
|
-
llm: provider
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
const result = await agent.run('Hello!')
|
|
40
|
-
console.log(result.response)
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Defining Tools
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
import type { Tool } from '@alexnetrebskii/hive-agent'
|
|
47
|
-
|
|
48
|
-
const weatherTool: Tool = {
|
|
49
|
-
name: 'get_weather',
|
|
50
|
-
description: 'Get current weather for a city',
|
|
51
|
-
parameters: {
|
|
52
|
-
type: 'object',
|
|
53
|
-
properties: {
|
|
54
|
-
city: { type: 'string', description: 'City name' }
|
|
55
|
-
},
|
|
56
|
-
required: ['city']
|
|
57
|
-
},
|
|
58
|
-
execute: async ({ city }) => {
|
|
59
|
-
const weather = await fetchWeather(city)
|
|
60
|
-
return { success: true, data: weather }
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const agent = new Hive({
|
|
65
|
-
systemPrompt: 'You help users check weather.',
|
|
66
|
-
tools: [weatherTool],
|
|
67
|
-
llm: provider
|
|
68
|
-
})
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Sub-Agents
|
|
72
|
-
|
|
73
|
-
Spawn specialized agents for complex tasks:
|
|
74
|
-
|
|
75
|
-
```typescript
|
|
76
|
-
import type { SubAgentConfig } from '@alexnetrebskii/hive-agent'
|
|
77
|
-
|
|
78
|
-
const researchAgent: SubAgentConfig = {
|
|
79
|
-
name: 'researcher',
|
|
80
|
-
description: 'Research topics in depth using web search',
|
|
81
|
-
systemPrompt: 'You research topics thoroughly and summarize findings.',
|
|
82
|
-
tools: [webSearchTool, readUrlTool]
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const agent = new Hive({
|
|
86
|
-
systemPrompt: 'You help users with various tasks.',
|
|
87
|
-
tools: [calculatorTool],
|
|
88
|
-
agents: [researchAgent],
|
|
89
|
-
llm: provider
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
// Agent can now use __task__ tool to delegate to researcher
|
|
93
|
-
const result = await agent.run('Research the latest AI developments')
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### Per-Agent Providers
|
|
97
|
-
|
|
98
|
-
Each sub-agent can use different models or providers:
|
|
99
|
-
|
|
100
|
-
```typescript
|
|
101
|
-
import { ClaudeProvider, OpenAIProvider } from '@alexnetrebskii/hive-agent'
|
|
102
|
-
|
|
103
|
-
const claudeProvider = new ClaudeProvider({ apiKey: '...' })
|
|
104
|
-
const openaiProvider = new OpenAIProvider({ apiKey: '...', model: 'gpt-4o' })
|
|
105
|
-
|
|
106
|
-
const fastAgent: SubAgentConfig = {
|
|
107
|
-
name: 'fast_helper',
|
|
108
|
-
description: 'Quick tasks using GPT-4o',
|
|
109
|
-
systemPrompt: '...',
|
|
110
|
-
tools: [...],
|
|
111
|
-
llm: openaiProvider, // Uses OpenAI instead of parent's Claude
|
|
112
|
-
maxIterations: 5
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const agent = new Hive({
|
|
116
|
-
systemPrompt: '...',
|
|
117
|
-
tools: [...],
|
|
118
|
-
agents: [fastAgent],
|
|
119
|
-
llm: claudeProvider // Main agent uses Claude
|
|
120
|
-
})
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### Structured Sub-Agents
|
|
124
|
-
|
|
125
|
-
Define input/output schemas for type-safe, cost-efficient sub-agent communication:
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
import type { SubAgentConfig } from '@alexnetrebskii/hive-agent'
|
|
5
|
+
Claude Code is impressive: you open a terminal, ask it to code something, and it plans, clarifies, executes. But it's locked to the terminal and local filesystem. What if you need that same intelligence inside your SaaS product, web app, or serverless function — working with your database, your blob storage, your users' data?
|
|
129
6
|
|
|
130
|
-
|
|
131
|
-
name: 'nutrition_counter',
|
|
132
|
-
description: 'Log food and calculate nutrition values',
|
|
133
|
-
|
|
134
|
-
// Input schema - parent provides structured parameters
|
|
135
|
-
inputSchema: {
|
|
136
|
-
type: 'object',
|
|
137
|
-
properties: {
|
|
138
|
-
food: { type: 'string', description: 'Food item to log' },
|
|
139
|
-
portionGrams: { type: 'number', description: 'Portion size in grams' },
|
|
140
|
-
meal: { type: 'string', description: 'Meal type: breakfast, lunch, dinner, snack' }
|
|
141
|
-
},
|
|
142
|
-
required: ['food', 'portionGrams', 'meal']
|
|
143
|
-
},
|
|
144
|
-
|
|
145
|
-
// Output schema - sub-agent returns structured data via __output__ tool
|
|
146
|
-
outputSchema: {
|
|
147
|
-
type: 'object',
|
|
148
|
-
properties: {
|
|
149
|
-
logged: { type: 'boolean', description: 'Whether food was logged' },
|
|
150
|
-
calories: { type: 'number', description: 'Total calories' },
|
|
151
|
-
protein: { type: 'number', description: 'Protein in grams' }
|
|
152
|
-
},
|
|
153
|
-
required: ['logged', 'calories']
|
|
154
|
-
},
|
|
155
|
-
|
|
156
|
-
systemPrompt: `You log food nutrition. Use __output__ to return results.`,
|
|
157
|
-
tools: [searchFoodTool, logMealTool]
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const agent = new Hive({
|
|
161
|
-
systemPrompt: 'You are a nutrition consultant.',
|
|
162
|
-
tools: [],
|
|
163
|
-
agents: [nutritionAgent],
|
|
164
|
-
llm: provider
|
|
165
|
-
})
|
|
166
|
-
|
|
167
|
-
// Main agent calls sub-agent with structured input:
|
|
168
|
-
// __task__({ agent: "nutrition_counter", food: "pasta", portionGrams: 250, meal: "lunch" })
|
|
169
|
-
//
|
|
170
|
-
// Sub-agent returns structured output:
|
|
171
|
-
// { summary: "Logged 250g pasta...", data: { logged: true, calories: 350, protein: 12 } }
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
## Execution Tracing
|
|
175
|
-
|
|
176
|
-
Track the full execution hierarchy with cost breakdown:
|
|
177
|
-
|
|
178
|
-
```typescript
|
|
179
|
-
import { Hive, ClaudeProvider, ConsoleTraceProvider } from '@alexnetrebskii/hive-agent'
|
|
180
|
-
|
|
181
|
-
const agent = new Hive({
|
|
182
|
-
systemPrompt: '...',
|
|
183
|
-
tools: [...],
|
|
184
|
-
agents: [...],
|
|
185
|
-
llm: new ClaudeProvider({ apiKey: '...' }),
|
|
186
|
-
trace: new ConsoleTraceProvider({ showCosts: true }),
|
|
187
|
-
agentName: 'my_agent'
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
const result = await agent.run('Do something complex')
|
|
191
|
-
|
|
192
|
-
// ConsoleTraceProvider outputs execution tree to console:
|
|
193
|
-
// [TRACE START] trace_abc123 - my_agent
|
|
194
|
-
// [AGENT START] my_agent
|
|
195
|
-
// [LLM] claude:claude-sonnet-4-20250514 - 1250 in / 89 out - $0.0042
|
|
196
|
-
// [TOOL] search_food (125ms)
|
|
197
|
-
// [AGENT START] nutrition_counter
|
|
198
|
-
// [LLM] claude:claude-3-haiku-20240307 - 800 in / 45 out - $0.0003
|
|
199
|
-
// [TOOL] log_meal (52ms)
|
|
200
|
-
// [AGENT END] nutrition_counter - complete
|
|
201
|
-
// [AGENT END] my_agent - complete
|
|
202
|
-
// [TRACE END] trace_abc123 - 2.3s - $0.0045
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### Custom Trace Provider
|
|
206
|
-
|
|
207
|
-
Implement `TraceProvider` for custom logging (database, observability platforms):
|
|
208
|
-
|
|
209
|
-
```typescript
|
|
210
|
-
import type { TraceProvider, Trace, AgentSpan, LLMCallEvent, ToolCallEvent } from '@alexnetrebskii/hive-agent'
|
|
211
|
-
|
|
212
|
-
class DatadogTraceProvider implements TraceProvider {
|
|
213
|
-
onTraceStart(trace: Trace): void {
|
|
214
|
-
// Start a Datadog trace
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
onTraceEnd(trace: Trace): void {
|
|
218
|
-
// End trace, record total cost
|
|
219
|
-
datadogClient.gauge('agent.cost', trace.totalCost)
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
onAgentStart(span: AgentSpan, trace: Trace): void {
|
|
223
|
-
// Start agent span
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
onAgentEnd(span: AgentSpan, trace: Trace): void {
|
|
227
|
-
// End agent span with status
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
onLLMCall(event: LLMCallEvent, span: AgentSpan, trace: Trace): void {
|
|
231
|
-
// Record LLM call metrics
|
|
232
|
-
datadogClient.increment('agent.llm_calls', { model: event.modelId })
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
onToolCall(event: ToolCallEvent, span: AgentSpan, trace: Trace): void {
|
|
236
|
-
// Record tool call metrics
|
|
237
|
-
datadogClient.histogram('agent.tool_duration', event.durationMs)
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
### Accessing Trace Data
|
|
243
|
-
|
|
244
|
-
The trace is available in the result for programmatic access:
|
|
245
|
-
|
|
246
|
-
```typescript
|
|
247
|
-
const result = await agent.run(message)
|
|
248
|
-
|
|
249
|
-
if (result.trace) {
|
|
250
|
-
console.log(`Total cost: $${result.trace.totalCost.toFixed(4)}`)
|
|
251
|
-
console.log(`Duration: ${result.trace.durationMs}ms`)
|
|
252
|
-
|
|
253
|
-
// Walk the execution tree
|
|
254
|
-
function printSpan(span: AgentSpan, depth = 0) {
|
|
255
|
-
const indent = ' '.repeat(depth)
|
|
256
|
-
console.log(`${indent}${span.agentName}: ${span.events.length} events`)
|
|
257
|
-
for (const child of span.children) {
|
|
258
|
-
printSpan(child, depth + 1)
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
printSpan(result.trace.rootSpan)
|
|
262
|
-
}
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
### Usage by Model
|
|
266
|
-
|
|
267
|
-
Track token usage broken down by provider and model:
|
|
268
|
-
|
|
269
|
-
```typescript
|
|
270
|
-
const result = await agent.run(message)
|
|
271
|
-
|
|
272
|
-
// Aggregated usage by model (includes sub-agents)
|
|
273
|
-
if (result.usageByModel) {
|
|
274
|
-
for (const [modelId, usage] of Object.entries(result.usageByModel)) {
|
|
275
|
-
console.log(`${modelId}:`)
|
|
276
|
-
console.log(` ${usage.inputTokens} input / ${usage.outputTokens} output`)
|
|
277
|
-
console.log(` ${usage.calls} API calls`)
|
|
278
|
-
if (usage.cacheReadInputTokens) {
|
|
279
|
-
console.log(` ${usage.cacheReadInputTokens} tokens from cache`)
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
// Output:
|
|
284
|
-
// claude:claude-sonnet-4-20250514:
|
|
285
|
-
// 2500 input / 180 output
|
|
286
|
-
// 2 API calls
|
|
287
|
-
// claude:claude-3-haiku-20240307:
|
|
288
|
-
// 800 input / 45 output
|
|
289
|
-
// 1 API calls
|
|
290
|
-
// 650 tokens from cache
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
## Conversation History
|
|
294
|
-
|
|
295
|
-
### Automatic (with Repository Provider)
|
|
296
|
-
|
|
297
|
-
Pass a `conversationId` and Hive automatically loads/saves history:
|
|
298
|
-
|
|
299
|
-
```typescript
|
|
300
|
-
import { Hive, ClaudeProvider, MemoryRepository } from '@alexnetrebskii/hive-agent'
|
|
301
|
-
|
|
302
|
-
const agent = new Hive({
|
|
303
|
-
systemPrompt: '...',
|
|
304
|
-
tools: [...],
|
|
305
|
-
llm: new ClaudeProvider({ apiKey: '...' }),
|
|
306
|
-
repository: new MemoryRepository() // Or your custom provider
|
|
307
|
-
})
|
|
308
|
-
|
|
309
|
-
// Hive automatically loads and saves history using conversationId
|
|
310
|
-
const result = await agent.run(userMessage, {
|
|
311
|
-
conversationId: 'user-123-chat-456' // Identity for the conversation
|
|
312
|
-
})
|
|
313
|
-
|
|
314
|
-
// Next message continues the conversation automatically
|
|
315
|
-
const result2 = await agent.run(nextMessage, {
|
|
316
|
-
conversationId: 'user-123-chat-456'
|
|
317
|
-
})
|
|
318
|
-
```
|
|
7
|
+
Hive gives you exactly that. A powerful, multi-agent framework you plug into your application. Your users get an AI that feels custom-built. You get a library that handles the hard parts.
|
|
319
8
|
|
|
320
|
-
|
|
9
|
+
## You Need Hive Agent If
|
|
321
10
|
|
|
322
|
-
|
|
11
|
+
- You want your own AI agent in your app that codes, manages documents, or works with any workspace you share with it
|
|
12
|
+
- You're building on Firebase, Vercel, AWS Lambda, or any serverless platform — Hive is stateless by design
|
|
13
|
+
- You're building a SaaS and want to give users a smart AI chat without building an agent framework from scratch
|
|
14
|
+
- Your data lives in databases, blob storage, or APIs — not just the local filesystem
|
|
15
|
+
- You want Claude Code-level intelligence but inside a web application, without VMs or infrastructure to manage
|
|
16
|
+
- You don't want to spend time teaching AI how to work well — Hive handles planning, task tracking, clarifying questions, and tool use out of the box
|
|
323
17
|
|
|
324
|
-
|
|
325
|
-
import type { RepositoryProvider, Message } from '@alexnetrebskii/hive-agent'
|
|
326
|
-
|
|
327
|
-
class FirestoreRepository implements RepositoryProvider {
|
|
328
|
-
constructor(private db: Firestore) {}
|
|
329
|
-
|
|
330
|
-
async getHistory(conversationId: string): Promise<Message[]> {
|
|
331
|
-
const doc = await this.db.collection('chats').doc(conversationId).get()
|
|
332
|
-
return doc.exists ? doc.data()?.messages || [] : []
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
async saveHistory(conversationId: string, messages: Message[]): Promise<void> {
|
|
336
|
-
await this.db.collection('chats').doc(conversationId).set({ messages })
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
const agent = new Hive({
|
|
341
|
-
systemPrompt: '...',
|
|
342
|
-
tools: [...],
|
|
343
|
-
llm: provider,
|
|
344
|
-
repository: new FirestoreRepository(db)
|
|
345
|
-
})
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
### Redis Repository Example
|
|
349
|
-
|
|
350
|
-
```typescript
|
|
351
|
-
import type { RepositoryProvider, Message } from '@alexnetrebskii/hive-agent'
|
|
352
|
-
import { Redis } from 'ioredis'
|
|
353
|
-
|
|
354
|
-
class RedisRepository implements RepositoryProvider {
|
|
355
|
-
constructor(private redis: Redis, private ttlSeconds = 86400) {}
|
|
356
|
-
|
|
357
|
-
async getHistory(conversationId: string): Promise<Message[]> {
|
|
358
|
-
const data = await this.redis.get(`chat:${conversationId}`)
|
|
359
|
-
return data ? JSON.parse(data) : []
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
async saveHistory(conversationId: string, messages: Message[]): Promise<void> {
|
|
363
|
-
await this.redis.setex(
|
|
364
|
-
`chat:${conversationId}`,
|
|
365
|
-
this.ttlSeconds,
|
|
366
|
-
JSON.stringify(messages)
|
|
367
|
-
)
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
### PostgreSQL Repository Example
|
|
373
|
-
|
|
374
|
-
```typescript
|
|
375
|
-
import type { RepositoryProvider, Message } from '@alexnetrebskii/hive-agent'
|
|
376
|
-
import { Pool } from 'pg'
|
|
377
|
-
|
|
378
|
-
class PostgresRepository implements RepositoryProvider {
|
|
379
|
-
constructor(private pool: Pool) {}
|
|
380
|
-
|
|
381
|
-
async getHistory(conversationId: string): Promise<Message[]> {
|
|
382
|
-
const result = await this.pool.query(
|
|
383
|
-
'SELECT messages FROM conversations WHERE id = $1',
|
|
384
|
-
[conversationId]
|
|
385
|
-
)
|
|
386
|
-
return result.rows[0]?.messages || []
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
async saveHistory(conversationId: string, messages: Message[]): Promise<void> {
|
|
390
|
-
await this.pool.query(
|
|
391
|
-
`INSERT INTO conversations (id, messages, updated_at)
|
|
392
|
-
VALUES ($1, $2, NOW())
|
|
393
|
-
ON CONFLICT (id) DO UPDATE SET messages = $2, updated_at = NOW()`,
|
|
394
|
-
[conversationId, JSON.stringify(messages)]
|
|
395
|
-
)
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
### Manual History Management
|
|
401
|
-
|
|
402
|
-
Alternatively, manage history yourself:
|
|
403
|
-
|
|
404
|
-
```typescript
|
|
405
|
-
// Load history from database
|
|
406
|
-
const history = await db.collection('chats').doc(chatId).get()
|
|
407
|
-
|
|
408
|
-
// Run agent with history
|
|
409
|
-
const result = await agent.run(userMessage, {
|
|
410
|
-
history: history.data()?.messages || []
|
|
411
|
-
})
|
|
412
|
-
|
|
413
|
-
// Save updated history
|
|
414
|
-
await db.collection('chats').doc(chatId).set({
|
|
415
|
-
messages: result.history
|
|
416
|
-
})
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
## Interactive Questions
|
|
420
|
-
|
|
421
|
-
Agent can pause to ask clarifying questions:
|
|
422
|
-
|
|
423
|
-
```typescript
|
|
424
|
-
const result = await agent.run('Create a database schema')
|
|
18
|
+
## Features
|
|
425
19
|
|
|
426
|
-
|
|
427
|
-
// Show questions to user
|
|
428
|
-
for (const q of result.pendingQuestion!.questions) {
|
|
429
|
-
console.log(q.question)
|
|
430
|
-
console.log(q.options)
|
|
431
|
-
}
|
|
20
|
+
### Agent Intelligence
|
|
432
21
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
```
|
|
22
|
+
- **Built-in planning & exploration sub-agents** — AI plans its work before executing, just like Claude Code
|
|
23
|
+
- **Task generation & tracking** — AI generates tasks and follows them, showing progress in real time
|
|
24
|
+
- **Clarifying questions** — AI asks one question or a series of questions when it needs more context
|
|
25
|
+
- **Interruption mode** — Correct the AI mid-execution if it goes in the wrong direction, just like Claude Code
|
|
26
|
+
- **Optimized built-in prompts** — Carefully tuned prompts for better results across all providers
|
|
439
27
|
|
|
440
|
-
|
|
28
|
+
### Built-in Capabilities
|
|
441
29
|
|
|
442
|
-
|
|
30
|
+
- **Workspace** — Like projects in Claude Code. Hive works with workspace files (virtual or real) the same way Claude Code works with your project
|
|
31
|
+
- **Large file processing** — AI reads files >256KB in chunks, just like Claude Code does
|
|
32
|
+
- **Web browsing** — Navigate websites, extract data, interact with pages
|
|
33
|
+
- **API requests with authentication** — Make HTTP requests to external services
|
|
443
34
|
|
|
444
|
-
###
|
|
35
|
+
### Multi-Provider
|
|
445
36
|
|
|
446
|
-
|
|
447
|
-
|
|
37
|
+
- **Claude** (Anthropic) — First-class support with caching and extended thinking
|
|
38
|
+
- **OpenAI** — GPT-4o and other models
|
|
39
|
+
- **OpenRouter** — Access to 100+ models via [openrouter.ai](https://openrouter.ai), with optimized prompts so non-Claude models use built-in tools effectively
|
|
448
40
|
|
|
449
|
-
|
|
450
|
-
const resultPromise = agent.run(message, {
|
|
451
|
-
conversationId,
|
|
452
|
-
signal: controller.signal
|
|
453
|
-
})
|
|
41
|
+
### Cost & Performance
|
|
454
42
|
|
|
455
|
-
|
|
456
|
-
|
|
43
|
+
- **Prompt caching** — Up to 90% cost reduction with Claude's prompt caching
|
|
44
|
+
- **Chat history summarization** — Automatic summarization of long conversations to stay within context limits
|
|
45
|
+
- **Execution tracing** — Full cost breakdown per request, per model, per sub-agent
|
|
457
46
|
|
|
458
|
-
|
|
459
|
-
if (result.status === 'interrupted') {
|
|
460
|
-
console.log(`Stopped after ${result.interrupted?.iterationsCompleted} iterations`)
|
|
461
|
-
// result.history contains partial work
|
|
462
|
-
}
|
|
463
|
-
```
|
|
47
|
+
### Production-Ready
|
|
464
48
|
|
|
465
|
-
|
|
49
|
+
- **Stateless design** — Works in Firebase Functions, AWS Lambda, any serverless environment
|
|
50
|
+
- **Conversation history management** — Automatic load/save with pluggable repository providers
|
|
51
|
+
- **Secrets management** — Keep credentials for external systems outside AI context. AI can use them without seeing actual values
|
|
52
|
+
- **Interruption & cancellation** — AbortController support, Firestore-based stop signals, graceful partial results
|
|
466
53
|
|
|
467
|
-
|
|
468
|
-
// Start task and store reference
|
|
469
|
-
const taskRef = db.collection('tasks').doc(taskId)
|
|
470
|
-
await taskRef.set({ status: 'running', chatId })
|
|
54
|
+
### Extensibility
|
|
471
55
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
}
|
|
478
|
-
})
|
|
56
|
+
- **Custom tools** — Define any tool with typed parameters and execution logic
|
|
57
|
+
- **Custom sub-agents** — Spawn specialized agents with their own tools, prompts, and even different LLM providers
|
|
58
|
+
- **Pluggable storage** — Bring your own chat history provider (Firestore, Redis, Postgres, anything)
|
|
59
|
+
- **Pluggable logging & tracing** — Integrate with Datadog, custom dashboards, or any observability platform
|
|
60
|
+
- **Pluggable workspaces** — Virtual file systems, database-backed storage, or real file system
|
|
479
61
|
|
|
480
|
-
|
|
481
|
-
if (result.status === 'interrupted') {
|
|
482
|
-
// User stopped or sent new message
|
|
483
|
-
await sendMessage(chatId, 'Task stopped')
|
|
484
|
-
} else {
|
|
485
|
-
await sendMessage(chatId, result.response)
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
// --- In another handler (when user clicks Stop or sends new message) ---
|
|
489
|
-
await taskRef.update({ status: 'stopped' })
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
### Continuing Partial Work
|
|
493
|
-
|
|
494
|
-
When interrupted, `result.history` contains the work done so far:
|
|
495
|
-
|
|
496
|
-
```typescript
|
|
497
|
-
const result = await agent.run(message, { signal })
|
|
498
|
-
|
|
499
|
-
if (result.status === 'interrupted') {
|
|
500
|
-
// Option 1: Discard partial work, start fresh
|
|
501
|
-
const fresh = await agent.run(newMessage, { conversationId })
|
|
62
|
+
## Installation
|
|
502
63
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
history: result.history // Include partial work
|
|
506
|
-
})
|
|
507
|
-
}
|
|
64
|
+
```bash
|
|
65
|
+
npm install @alexnetrebskii/hive-agent
|
|
508
66
|
```
|
|
509
67
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
Get real-time feedback during execution:
|
|
513
|
-
|
|
514
|
-
```typescript
|
|
515
|
-
import { ConsoleLogger } from '@alexnetrebskii/hive-agent'
|
|
516
|
-
|
|
517
|
-
const logger = {
|
|
518
|
-
...new ConsoleLogger({ level: 'info' }),
|
|
519
|
-
onProgress: (update) => {
|
|
520
|
-
// update.type: 'thinking' | 'tool_start' | 'tool_end' | 'sub_agent_start' | 'sub_agent_end'
|
|
521
|
-
console.log(`${update.type}: ${update.message}`)
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
const agent = new Hive({
|
|
526
|
-
systemPrompt: '...',
|
|
527
|
-
tools: [...],
|
|
528
|
-
llm: provider,
|
|
529
|
-
logger
|
|
530
|
-
})
|
|
68
|
+
```bash
|
|
69
|
+
pnpm add @alexnetrebskii/hive-agent
|
|
531
70
|
```
|
|
532
71
|
|
|
533
|
-
##
|
|
534
|
-
|
|
535
|
-
Reduce costs by up to 90% with Claude's prompt caching. Cached tokens are billed at 1/10th the price of regular input tokens.
|
|
72
|
+
## Quick Start
|
|
536
73
|
|
|
537
74
|
```typescript
|
|
538
|
-
import { ClaudeProvider } from '@alexnetrebskii/hive-agent'
|
|
539
|
-
|
|
540
|
-
const provider = new ClaudeProvider({
|
|
541
|
-
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
542
|
-
cache: true // Enable caching for system prompt, tools, and history
|
|
543
|
-
})
|
|
75
|
+
import { Hive, ClaudeProvider } from '@alexnetrebskii/hive-agent'
|
|
544
76
|
|
|
545
77
|
const agent = new Hive({
|
|
546
|
-
systemPrompt: '
|
|
547
|
-
tools: [
|
|
548
|
-
llm:
|
|
549
|
-
})
|
|
550
|
-
|
|
551
|
-
const result = await agent.run(message)
|
|
552
|
-
|
|
553
|
-
// Check cache usage
|
|
554
|
-
if (result.usage) {
|
|
555
|
-
console.log(`Cache write: ${result.usage.cacheCreationInputTokens || 0} tokens`)
|
|
556
|
-
console.log(`Cache read: ${result.usage.cacheReadInputTokens || 0} tokens`)
|
|
557
|
-
}
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
### How It Works
|
|
561
|
-
|
|
562
|
-
- **First request**: Tokens are written to cache (`cacheCreationInputTokens`)
|
|
563
|
-
- **Subsequent requests**: Tokens are read from cache (`cacheReadInputTokens`) at 1/10th cost
|
|
564
|
-
- **Cache TTL**: 5 minutes (automatically extended on each hit)
|
|
565
|
-
|
|
566
|
-
Cache breakpoints are automatically placed at optimal positions (system prompt, tools, last user message).
|
|
567
|
-
|
|
568
|
-
## Configuration
|
|
569
|
-
|
|
570
|
-
```typescript
|
|
571
|
-
interface HiveConfig {
|
|
572
|
-
systemPrompt: string
|
|
573
|
-
tools: Tool[]
|
|
574
|
-
agents?: SubAgentConfig[]
|
|
575
|
-
|
|
576
|
-
llm: LLMProvider
|
|
577
|
-
logger?: LogProvider
|
|
578
|
-
repository?: RepositoryProvider
|
|
579
|
-
|
|
580
|
-
maxIterations?: number // Default: 50
|
|
581
|
-
maxContextTokens?: number // Default: 100000
|
|
582
|
-
contextStrategy?: 'truncate_old' | 'summarize' | 'error'
|
|
583
|
-
|
|
584
|
-
thinkingMode?: 'none' | 'enabled'
|
|
585
|
-
thinkingBudget?: number
|
|
586
|
-
|
|
587
|
-
review?: ReviewConfig
|
|
588
|
-
|
|
589
|
-
// Tracing
|
|
590
|
-
trace?: TraceProvider // Enable execution tracing
|
|
591
|
-
agentName?: string // Name for root agent span (default: 'agent')
|
|
592
|
-
modelPricing?: Record<string, ModelPricing> // Custom pricing overrides
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
interface SubAgentConfig {
|
|
596
|
-
name: string
|
|
597
|
-
description: string
|
|
598
|
-
systemPrompt: string
|
|
599
|
-
tools: Tool[]
|
|
600
|
-
model?: string // Override model for this agent
|
|
601
|
-
llm?: LLMProvider // Override provider for this agent
|
|
602
|
-
maxIterations?: number // Override max iterations
|
|
603
|
-
inputSchema?: JSONSchema // Structured input parameters
|
|
604
|
-
outputSchema?: JSONSchema // Structured output data
|
|
605
|
-
}
|
|
606
|
-
```
|
|
607
|
-
|
|
608
|
-
## Providers
|
|
609
|
-
|
|
610
|
-
### Claude (Anthropic)
|
|
611
|
-
|
|
612
|
-
```typescript
|
|
613
|
-
import { ClaudeProvider } from '@alexnetrebskii/hive-agent'
|
|
614
|
-
|
|
615
|
-
const provider = new ClaudeProvider({
|
|
616
|
-
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
617
|
-
model: 'claude-sonnet-4-20250514', // Default
|
|
618
|
-
maxTokens: 8192,
|
|
619
|
-
cache: true // Enable prompt caching
|
|
620
|
-
})
|
|
621
|
-
```
|
|
622
|
-
|
|
623
|
-
### OpenAI
|
|
624
|
-
|
|
625
|
-
```typescript
|
|
626
|
-
import { OpenAIProvider } from '@alexnetrebskii/hive-agent'
|
|
627
|
-
|
|
628
|
-
const provider = new OpenAIProvider({
|
|
629
|
-
apiKey: process.env.OPENAI_API_KEY,
|
|
630
|
-
model: 'gpt-4o', // Default
|
|
631
|
-
maxTokens: 4096,
|
|
632
|
-
baseURL: 'https://api.openai.com/v1' // Optional, for proxies
|
|
78
|
+
systemPrompt: 'You are a helpful assistant.',
|
|
79
|
+
tools: [myTool],
|
|
80
|
+
llm: new ClaudeProvider({ apiKey: process.env.ANTHROPIC_API_KEY })
|
|
633
81
|
})
|
|
634
|
-
```
|
|
635
|
-
|
|
636
|
-
## API Reference
|
|
637
82
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
```typescript
|
|
641
|
-
interface AgentResult {
|
|
642
|
-
response: string // Final text response
|
|
643
|
-
history: Message[] // Full conversation history
|
|
644
|
-
toolCalls: ToolCallLog[] // Log of all tool invocations
|
|
645
|
-
thinking?: string[] // Thinking blocks (if enabled)
|
|
646
|
-
todos?: TodoItem[] // Current todo list
|
|
647
|
-
pendingQuestion?: PendingQuestion // If status is 'needs_input'
|
|
648
|
-
status: 'complete' | 'needs_input' | 'interrupted'
|
|
649
|
-
interrupted?: {
|
|
650
|
-
reason: 'aborted' | 'stopped' | 'max_iterations'
|
|
651
|
-
iterationsCompleted: number
|
|
652
|
-
}
|
|
653
|
-
usage?: {
|
|
654
|
-
totalInputTokens: number
|
|
655
|
-
totalOutputTokens: number
|
|
656
|
-
cacheCreationInputTokens?: number
|
|
657
|
-
cacheReadInputTokens?: number
|
|
658
|
-
}
|
|
659
|
-
usageByModel?: Record<string, { // Usage by provider:model
|
|
660
|
-
inputTokens: number
|
|
661
|
-
outputTokens: number
|
|
662
|
-
cacheCreationInputTokens?: number
|
|
663
|
-
cacheReadInputTokens?: number
|
|
664
|
-
calls: number
|
|
665
|
-
}>
|
|
666
|
-
trace?: Trace // Execution trace (if TraceProvider configured)
|
|
667
|
-
}
|
|
668
|
-
```
|
|
669
|
-
|
|
670
|
-
### Tool
|
|
671
|
-
|
|
672
|
-
```typescript
|
|
673
|
-
interface Tool {
|
|
674
|
-
name: string
|
|
675
|
-
description: string
|
|
676
|
-
parameters: JSONSchema
|
|
677
|
-
execute: (params: Record<string, unknown>, context: ToolContext) => Promise<ToolResult>
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
interface ToolResult {
|
|
681
|
-
success: boolean
|
|
682
|
-
data?: unknown
|
|
683
|
-
error?: string
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
interface ToolContext {
|
|
687
|
-
remainingTokens: number
|
|
688
|
-
conversationId?: string
|
|
689
|
-
userId?: string
|
|
690
|
-
metadata?: Record<string, unknown>
|
|
691
|
-
}
|
|
83
|
+
const result = await agent.run('Hello!')
|
|
84
|
+
console.log(result.response)
|
|
692
85
|
```
|
|
693
86
|
|
|
694
|
-
|
|
87
|
+
## Examples
|
|
695
88
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
// Required: Load conversation history
|
|
699
|
-
getHistory(conversationId: string): Promise<Message[]>
|
|
700
|
-
|
|
701
|
-
// Required: Save conversation history
|
|
702
|
-
saveHistory(conversationId: string, messages: Message[]): Promise<void>
|
|
89
|
+
- [**Coder**](examples/coder) — AI software developer that creates projects from scratch using built-in shell, workspace, planning, and task tracking. Zero custom tools.
|
|
90
|
+
- [**Eating Consultant**](examples/eating-consultant) — Nutrition assistant with custom tools (OpenFoodFacts API), sub-agents (meal planner), workspace persistence, and run recording.
|
|
703
91
|
|
|
704
|
-
|
|
705
|
-
getState?(conversationId: string): Promise<Record<string, unknown> | null>
|
|
706
|
-
saveState?(conversationId: string, state: Record<string, unknown>): Promise<void>
|
|
92
|
+
## Documentation
|
|
707
93
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
94
|
+
- [Quick Start Guide](docs/quickstart.md)
|
|
95
|
+
- [Configuration](docs/configuration.md)
|
|
96
|
+
- [Defining Tools](docs/tools.md)
|
|
97
|
+
- [Sub-Agents](docs/sub-agents.md)
|
|
98
|
+
- [Workspace](docs/workspace.md)
|
|
99
|
+
- [Conversation History](docs/history.md)
|
|
100
|
+
- [Interactive Questions](docs/interactive.md)
|
|
101
|
+
- [Interruption & Cancellation](docs/interruption.md)
|
|
102
|
+
- [Execution Tracing](docs/tracing.md)
|
|
103
|
+
- [Prompt Caching](docs/caching.md)
|
|
104
|
+
- [Task Management](docs/task-management.md)
|
|
105
|
+
- [Plan Mode](docs/plan-mode.md)
|
|
106
|
+
- [Providers](docs/providers.md)
|
|
713
107
|
|
|
714
108
|
## License
|
|
715
109
|
|