@alexnetrebskii/hive-agent 0.7.0 → 0.8.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 CHANGED
@@ -8,9 +8,11 @@ Minimal TypeScript agent framework inspired by Claude Code architecture.
8
8
  - **No built-in tools** - You define your own tools
9
9
  - **External history** - Accepts/returns conversation history (for Firestore, etc.)
10
10
  - **Sub-agents** - Spawn specialized agents for complex tasks
11
+ - **Structured I/O** - Type-safe input/output schemas for sub-agents
11
12
  - **Multi-provider** - Claude and OpenAI support, easily extensible
12
13
  - **Interactive** - Built-in `__ask_user__` tool for clarifying questions
13
14
  - **Progress tracking** - Todo lists and real-time progress callbacks
15
+ - **Execution tracing** - Full hierarchy tracking with cost breakdown
14
16
  - **Prompt caching** - Claude prompt caching for cost reduction
15
17
 
16
18
  ## Installation
@@ -118,6 +120,176 @@ const agent = new Hive({
118
120
  })
119
121
  ```
120
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'
129
+
130
+ const nutritionAgent: SubAgentConfig = {
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
+
121
293
  ## Conversation History
122
294
 
123
295
  ### Automatic (with Repository Provider)
@@ -360,19 +532,12 @@ const agent = new Hive({
360
532
 
361
533
  Reduce costs by up to 90% with Claude's prompt caching. Cached tokens are billed at 1/10th the price of regular input tokens.
362
534
 
363
- Configure caching at the provider level:
364
-
365
535
  ```typescript
366
- import { ClaudeProvider, type CacheConfig } from '@alexnetrebskii/hive-agent'
536
+ import { ClaudeProvider } from '@alexnetrebskii/hive-agent'
367
537
 
368
538
  const provider = new ClaudeProvider({
369
539
  apiKey: process.env.ANTHROPIC_API_KEY,
370
- cache: {
371
- enabled: true,
372
- cacheSystemPrompt: true, // Cache system prompt (default: true)
373
- cacheTools: true, // Cache tool definitions (default: true)
374
- cacheHistory: true // Cache conversation history (default: true)
375
- }
540
+ cache: true // Enable caching for system prompt, tools, and history
376
541
  })
377
542
 
378
543
  const agent = new Hive({
@@ -396,14 +561,7 @@ if (result.usage) {
396
561
  - **Subsequent requests**: Tokens are read from cache (`cacheReadInputTokens`) at 1/10th cost
397
562
  - **Cache TTL**: 5 minutes (automatically extended on each hit)
398
563
 
399
- ### Cache Breakpoints
400
-
401
- The framework automatically places cache breakpoints at optimal positions:
402
- - End of system prompt
403
- - End of tool definitions
404
- - Last user message in conversation history
405
-
406
- This ensures maximum cache reuse across conversation turns.
564
+ Cache breakpoints are automatically placed at optimal positions (system prompt, tools, last user message).
407
565
 
408
566
  ## Configuration
409
567
 
@@ -425,6 +583,23 @@ interface HiveConfig {
425
583
  thinkingBudget?: number
426
584
 
427
585
  review?: ReviewConfig
586
+
587
+ // Tracing
588
+ trace?: TraceProvider // Enable execution tracing
589
+ agentName?: string // Name for root agent span (default: 'agent')
590
+ modelPricing?: Record<string, ModelPricing> // Custom pricing overrides
591
+ }
592
+
593
+ interface SubAgentConfig {
594
+ name: string
595
+ description: string
596
+ systemPrompt: string
597
+ tools: Tool[]
598
+ model?: string // Override model for this agent
599
+ llm?: LLMProvider // Override provider for this agent
600
+ maxIterations?: number // Override max iterations
601
+ inputSchema?: JSONSchema // Structured input parameters
602
+ outputSchema?: JSONSchema // Structured output data
428
603
  }
429
604
  ```
430
605
 
@@ -439,12 +614,7 @@ const provider = new ClaudeProvider({
439
614
  apiKey: process.env.ANTHROPIC_API_KEY,
440
615
  model: 'claude-sonnet-4-20250514', // Default
441
616
  maxTokens: 8192,
442
- cache: { // Optional: enable prompt caching
443
- enabled: true,
444
- cacheSystemPrompt: true,
445
- cacheTools: true,
446
- cacheHistory: true
447
- }
617
+ cache: true // Enable prompt caching
448
618
  })
449
619
  ```
450
620
 
@@ -484,6 +654,14 @@ interface AgentResult {
484
654
  cacheCreationInputTokens?: number
485
655
  cacheReadInputTokens?: number
486
656
  }
657
+ usageByModel?: Record<string, { // Usage by provider:model
658
+ inputTokens: number
659
+ outputTokens: number
660
+ cacheCreationInputTokens?: number
661
+ cacheReadInputTokens?: number
662
+ calls: number
663
+ }>
664
+ trace?: Trace // Execution trace (if TraceProvider configured)
487
665
  }
488
666
  ```
489
667
 
package/dist/agent.d.ts CHANGED
@@ -4,6 +4,15 @@
4
4
  * Main agent class that orchestrates tool execution, sub-agents, and context management.
5
5
  */
6
6
  import type { HiveConfig, RunOptions, AgentResult } from './types.js';
7
+ import { TraceBuilder } from './trace.js';
8
+ /** Usage by model type */
9
+ type UsageByModel = Record<string, {
10
+ inputTokens: number;
11
+ outputTokens: number;
12
+ cacheCreationInputTokens?: number;
13
+ cacheReadInputTokens?: number;
14
+ calls: number;
15
+ }>;
7
16
  /**
8
17
  * Hive Agent Class
9
18
  */
@@ -11,7 +20,28 @@ export declare class Hive {
11
20
  readonly config: HiveConfig;
12
21
  private contextManager;
13
22
  private tools;
23
+ /** Accumulated sub-agent usage (for merging into final result) */
24
+ private subAgentUsage;
25
+ /** Current trace builder (set during run, used by __task__ tool) */
26
+ private currentTraceBuilder?;
14
27
  constructor(config: HiveConfig);
28
+ /**
29
+ * Merge sub-agent usage into accumulated usage
30
+ * Called by __task__ tool after sub-agent completes
31
+ */
32
+ mergeSubAgentUsage(usage: UsageByModel | undefined): void;
33
+ /**
34
+ * Get accumulated sub-agent usage and reset for next run
35
+ */
36
+ getAndResetSubAgentUsage(): UsageByModel;
37
+ /**
38
+ * Get the current trace builder (used by __task__ tool for sub-agent tracing)
39
+ */
40
+ getCurrentTraceBuilder(): TraceBuilder | undefined;
41
+ /**
42
+ * Set the current trace builder (called at start of run)
43
+ */
44
+ setCurrentTraceBuilder(builder: TraceBuilder | undefined): void;
15
45
  /**
16
46
  * Get tools including internal tools for a specific run
17
47
  */
@@ -21,4 +51,5 @@ export declare class Hive {
21
51
  */
22
52
  run(message: string, options?: RunOptions): Promise<AgentResult>;
23
53
  }
54
+ export {};
24
55
  //# sourceMappingURL=agent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,UAAU,EAGV,UAAU,EACV,WAAW,EAIZ,MAAM,YAAY,CAAA;AA8KnB;;GAEG;AACH,qBAAa,IAAI;IACf,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,KAAK,CAAQ;gBAET,MAAM,EAAE,UAAU;IA2B9B;;OAEG;IACH,OAAO,CAAC,WAAW;IAanB;;OAEG;IACG,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,WAAW,CAAC;CAmH3E"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,UAAU,EAGV,UAAU,EACV,WAAW,EAIZ,MAAM,YAAY,CAAA;AAKnB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AA+TzC,0BAA0B;AAC1B,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,KAAK,EAAE,MAAM,CAAA;CACd,CAAC,CAAA;AAEF;;GAEG;AACH,qBAAa,IAAI;IACf,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,KAAK,CAAQ;IACrB,kEAAkE;IAClE,OAAO,CAAC,aAAa,CAAmB;IACxC,oEAAoE;IACpE,OAAO,CAAC,mBAAmB,CAAC,CAAc;gBAE9B,MAAM,EAAE,UAAU;IA2B9B;;;OAGG;IACH,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI;IAoBzD;;OAEG;IACH,wBAAwB,IAAI,YAAY;IAMxC;;OAEG;IACH,sBAAsB,IAAI,YAAY,GAAG,SAAS;IAIlD;;OAEG;IACH,sBAAsB,CAAC,OAAO,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI;IAI/D;;OAEG;IACH,OAAO,CAAC,WAAW;IAanB;;OAEG;IACG,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,WAAW,CAAC;CAmK3E"}