goatchain 0.0.14 → 0.0.16

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
@@ -3,7 +3,6 @@
3
3
  > A TypeScript SDK for building AI agents with streaming support, tool calling, and middleware pattern.
4
4
 
5
5
  [![npm version](https://badge.fury.io/js/goatchain.svg)](https://badge.fury.io/js/goatchain)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
6
 
8
7
  ## 📦 Installation
9
8
 
@@ -86,11 +85,11 @@ const session = await agent.createSession({
86
85
 
87
86
  ```typescript
88
87
  interface SessionConfigOverride {
89
- maxIterations?: number // Max agent loop iterations (default: 5)
88
+ maxIterations?: number // Max agent loop iterations (default: 5)
90
89
  maxConcurrentToolCalls?: number // Max parallel tool calls (default: 5)
91
- temperature?: number // Model temperature
92
- maxTokens?: number // Max output tokens
93
- topP?: number // Nucleus sampling parameter
90
+ temperature?: number // Model temperature
91
+ maxTokens?: number // Max output tokens
92
+ topP?: number // Nucleus sampling parameter
94
93
  }
95
94
  ```
96
95
 
@@ -123,25 +122,25 @@ for await (const event of session.receive()) {
123
122
  // Partial text from LLM
124
123
  process.stdout.write(event.delta)
125
124
  break
126
-
125
+
127
126
  case 'tool_call_start':
128
127
  console.log(`\nCalling tool: ${event.name}`)
129
128
  break
130
-
129
+
131
130
  case 'tool_result':
132
131
  console.log(`Tool result: ${event.result}`)
133
132
  break
134
-
133
+
135
134
  case 'iteration_end':
136
135
  console.log(`\nIteration ${event.iteration} complete`)
137
136
  console.log(`Tokens used: ${event.usage?.totalTokens}`)
138
137
  break
139
-
138
+
140
139
  case 'done':
141
140
  console.log(`\nConversation done: ${event.stopReason}`)
142
141
  console.log(`Total tokens: ${event.usage?.totalTokens}`)
143
142
  break
144
-
143
+
145
144
  case 'error':
146
145
  console.error(`Error: ${event.error}`)
147
146
  break
@@ -151,20 +150,20 @@ for await (const event of session.receive()) {
151
150
 
152
151
  ### Session Event Types
153
152
 
154
- | Event Type | Description | Key Fields |
155
- |------------|-------------|------------|
156
- | `iteration_start` | Agent loop iteration begins | `iteration` |
157
- | `text_delta` | Partial text response | `delta` |
158
- | `thinking_start` | Reasoning phase begins | - |
159
- | `thinking_delta` | Reasoning content | `delta` |
160
- | `thinking_end` | Reasoning phase ends | - |
161
- | `tool_call_start` | Tool invocation begins | `name`, `id` |
162
- | `tool_call_delta` | Tool arguments stream | `delta` |
163
- | `tool_call_end` | Tool call complete | `name`, `args` |
164
- | `tool_result` | Tool execution result | `result`, `error` |
165
- | `iteration_end` | Iteration complete | `usage`, `iteration` |
166
- | `done` | Stream finished | `stopReason`, `usage` |
167
- | `error` | Error occurred | `error` |
153
+ | Event Type | Description | Key Fields |
154
+ | ----------------- | --------------------------- | --------------------- |
155
+ | `iteration_start` | Agent loop iteration begins | `iteration` |
156
+ | `text_delta` | Partial text response | `delta` |
157
+ | `thinking_start` | Reasoning phase begins | - |
158
+ | `thinking_delta` | Reasoning content | `delta` |
159
+ | `thinking_end` | Reasoning phase ends | - |
160
+ | `tool_call_start` | Tool invocation begins | `name`, `id` |
161
+ | `tool_call_delta` | Tool arguments stream | `delta` |
162
+ | `tool_call_end` | Tool call complete | `name`, `args` |
163
+ | `tool_result` | Tool execution result | `result`, `error` |
164
+ | `iteration_end` | Iteration complete | `usage`, `iteration` |
165
+ | `done` | Stream finished | `stopReason`, `usage` |
166
+ | `error` | Error occurred | `error` |
168
167
 
169
168
  ### Session State Management
170
169
 
@@ -184,7 +183,7 @@ console.log(session.usage)
184
183
  // }
185
184
 
186
185
  // Session metadata
187
- console.log(session.id) // Session ID
186
+ console.log(session.id) // Session ID
188
187
  console.log(session.createdAt) // Creation timestamp
189
188
  console.log(session.updatedAt) // Last update timestamp
190
189
  ```
@@ -303,14 +302,14 @@ const agent = new Agent({
303
302
 
304
303
  ```typescript
305
304
  interface AgentOptions {
306
- name: string // Agent name
307
- systemPrompt: string // System instructions
308
- model: ModelClient | ModelRef // LLM client or reference
309
- tools?: BaseTool[] // Custom tools
310
- stateStore?: StateStore // Persistence layer
311
- maxIterations?: number // Max agent loop iterations (default: 5)
312
- maxConcurrentToolCalls?: number // Max parallel tool calls (default: 5)
313
- modelSwapWhitelist?: string[] // Allowed model IDs for runtime switching
305
+ name: string // Agent name
306
+ systemPrompt: string // System instructions
307
+ model: ModelClient | ModelRef // LLM client or reference
308
+ tools?: BaseTool[] // Custom tools
309
+ stateStore?: StateStore // Persistence layer
310
+ maxIterations?: number // Max agent loop iterations (default: 5)
311
+ maxConcurrentToolCalls?: number // Max parallel tool calls (default: 5)
312
+ modelSwapWhitelist?: string[] // Allowed model IDs for runtime switching
314
313
  }
315
314
  ```
316
315
 
@@ -348,10 +347,10 @@ await sessionManager.destroy('session-id')
348
347
  GoatChain includes 23 built-in tools:
349
348
 
350
349
  ```typescript
351
- import {
352
- ReadTool,
353
- WriteTool,
354
- EditTool,
350
+ import {
351
+ ReadTool,
352
+ WriteTool,
353
+ EditTool,
355
354
  BashTool,
356
355
  GrepTool,
357
356
  GlobTool,
@@ -384,7 +383,7 @@ import { BaseTool } from 'goatchain'
384
383
  class MyCustomTool extends BaseTool {
385
384
  name = 'my_tool'
386
385
  description = 'Does something useful'
387
-
386
+
388
387
  parameters = {
389
388
  type: 'object',
390
389
  properties: {
@@ -395,7 +394,7 @@ class MyCustomTool extends BaseTool {
395
394
  },
396
395
  required: ['input'],
397
396
  }
398
-
397
+
399
398
  async execute(args: { input: string }) {
400
399
  // Your tool logic here
401
400
  return `Processed: ${args.input}`
@@ -449,9 +448,9 @@ outer:before → inner:before → exec (model.stream) → inner:after → outer:
449
448
  agent.use(async (state, next) => {
450
449
  const start = Date.now()
451
450
  console.log(`[${state.iteration}] Before model call`)
452
-
451
+
453
452
  const nextState = await next(state) // Execute next middleware/model
454
-
453
+
455
454
  console.log(`[${state.iteration}] After model call (${Date.now() - start}ms)`)
456
455
  return nextState
457
456
  }, 'logging')
@@ -480,10 +479,12 @@ import { createPlanModeMiddleware } from 'goatchain'
480
479
  agent.use(createPlanModeMiddleware())
481
480
 
482
481
  // With custom configuration
483
- agent.use(createPlanModeMiddleware({
484
- name: 'my-plan', // Custom name
485
- planPrompt: 'Create a detailed plan...', // Custom prompt
486
- }))
482
+ agent.use(
483
+ createPlanModeMiddleware({
484
+ name: 'my-plan', // Custom name
485
+ planPrompt: 'Create a detailed plan...', // Custom prompt
486
+ }),
487
+ )
487
488
  ```
488
489
 
489
490
  #### Context Compression Middleware
@@ -494,17 +495,19 @@ Automatically compresses context when token limit is reached using a two-stage s
494
495
  import { createContextCompressionMiddleware } from 'goatchain'
495
496
 
496
497
  // Automatically named 'context-compression'
497
- agent.use(createContextCompressionMiddleware({
498
- maxTokens: 128000,
499
- protectedTurns: 2, // Keep last 2 conversation turns
500
- model: model,
501
- stateStore: agent.stateStore,
502
- toolCompressionTarget: 0.45, // Compress to 45% of maxTokens
503
- minKeepToolResults: 5, // Keep last 5 tool results
504
- // Optional: Enable detailed logging
505
- enableLogging: true,
506
- logFilePath: 'compression-logs.jsonl',
507
- }))
498
+ agent.use(
499
+ createContextCompressionMiddleware({
500
+ maxTokens: 128000,
501
+ protectedTurns: 2, // Keep last 2 conversation turns
502
+ model: model,
503
+ stateStore: agent.stateStore,
504
+ toolCompressionTarget: 0.45, // Compress to 45% of maxTokens
505
+ minKeepToolResults: 5, // Keep last 5 tool results
506
+ // Optional: Enable detailed logging
507
+ enableLogging: true,
508
+ logFilePath: 'compression-logs.jsonl',
509
+ }),
510
+ )
508
511
  ```
509
512
 
510
513
  See [Context Compression Logging Guide](./docs/context-compression-logging.md) for details on monitoring compression behavior.
@@ -519,14 +522,14 @@ agent.use(async (state, next) => {
519
522
  messages: state.messages.length,
520
523
  pendingTools: state.pendingToolCalls.length,
521
524
  })
522
-
525
+
523
526
  const result = await next(state)
524
-
527
+
525
528
  console.log(`Completed iteration ${state.iteration}:`, {
526
529
  shouldContinue: result.shouldContinue,
527
530
  usage: result.usage,
528
531
  })
529
-
532
+
530
533
  return result
531
534
  }, 'logger')
532
535
  ```
@@ -565,19 +568,19 @@ agent.use(async (state, next) => {
565
568
  ```typescript
566
569
  agent.use(async (state, next) => {
567
570
  let retries = 3
568
-
571
+
569
572
  while (retries > 0) {
570
573
  try {
571
574
  return await next(state)
572
575
  } catch (error) {
573
576
  retries--
574
577
  if (retries === 0) throw error
575
-
578
+
576
579
  console.log(`Retrying... (${retries} attempts left)`)
577
- await new Promise(resolve => setTimeout(resolve, 1000))
580
+ await new Promise((resolve) => setTimeout(resolve, 1000))
578
581
  }
579
582
  }
580
-
583
+
581
584
  return state
582
585
  }, 'retry')
583
586
  ```
@@ -588,15 +591,15 @@ The `AgentLoopState` object passed to middleware:
588
591
 
589
592
  ```typescript
590
593
  interface AgentLoopState {
591
- sessionId: string // Current session ID
592
- messages: Message[] // Conversation history
593
- iteration: number // Current iteration number
594
+ sessionId: string // Current session ID
595
+ messages: Message[] // Conversation history
596
+ iteration: number // Current iteration number
594
597
  pendingToolCalls: ToolCallWithResult[] // Pending tool executions
595
- currentResponse: string // Current LLM response
596
- shouldContinue: boolean // Whether to continue loop
597
- stopReason?: string // Reason for stopping
598
- usage?: Usage // Token usage
599
- error?: Error // Error if any
598
+ currentResponse: string // Current LLM response
599
+ shouldContinue: boolean // Whether to continue loop
600
+ stopReason?: string // Reason for stopping
601
+ usage?: Usage // Token usage
602
+ error?: Error // Error if any
600
603
  }
601
604
  ```
602
605
 
@@ -621,13 +624,13 @@ const model = createModel({
621
624
 
622
625
  ```typescript
623
626
  interface OpenAIAdapterOptions {
624
- defaultModelId?: string // Default model ID
625
- apiKey?: string // OpenAI API key
626
- baseURL?: string // Custom API endpoint
627
- organization?: string // OpenAI organization ID
627
+ defaultModelId?: string // Default model ID
628
+ apiKey?: string // OpenAI API key
629
+ baseURL?: string // Custom API endpoint
630
+ organization?: string // OpenAI organization ID
628
631
  defaultHeaders?: Record<string, string> // Custom headers
629
- timeout?: number // Request timeout (ms)
630
- maxRetries?: number // Max retry attempts (default: 2)
632
+ timeout?: number // Request timeout (ms)
633
+ maxRetries?: number // Max retry attempts (default: 2)
631
634
  }
632
635
  ```
633
636
 
@@ -659,10 +662,10 @@ Implement custom model adapters:
659
662
  ```typescript
660
663
  interface ModelClient {
661
664
  modelId: string
662
-
665
+
663
666
  // Streaming API (required)
664
667
  stream(request: ModelRequest): AsyncIterable<ModelStreamEvent>
665
-
668
+
666
669
  // Non-streaming API (optional)
667
670
  run?(request: ModelRequest): Promise<ModelRunResult>
668
671
  }
@@ -687,8 +690,8 @@ Persist agent state to filesystem:
687
690
  import { FileStateStore } from 'goatchain'
688
691
 
689
692
  const stateStore = new FileStateStore({
690
- dir: './checkpoints', // Storage directory
691
- deleteOnComplete: true, // Auto-delete successful completions
693
+ dir: './checkpoints', // Storage directory
694
+ deleteOnComplete: true, // Auto-delete successful completions
692
695
  })
693
696
 
694
697
  const agent = new Agent({
@@ -718,7 +721,7 @@ Implement custom state stores:
718
721
  ```typescript
719
722
  interface StateStore {
720
723
  deleteOnComplete: boolean
721
-
724
+
722
725
  saveCheckpoint(checkpoint: AgentLoopCheckpoint): Promise<void>
723
726
  loadCheckpoint(sessionId: string): Promise<AgentLoopCheckpoint | null>
724
727
  deleteCheckpoint(sessionId: string): Promise<void>
@@ -792,9 +795,9 @@ for await (const event of session.receive()) {
792
795
  ### Example 2: Agent with Tools
793
796
 
794
797
  ```typescript
795
- import {
796
- Agent,
797
- createModel,
798
+ import {
799
+ Agent,
800
+ createModel,
798
801
  createOpenAIAdapter,
799
802
  ReadTool,
800
803
  WriteTool,
@@ -812,11 +815,7 @@ const agent = new Agent({
812
815
  name: 'File Assistant',
813
816
  systemPrompt: 'You help users manage their files.',
814
817
  model,
815
- tools: [
816
- new ReadTool(),
817
- new WriteTool(),
818
- new BashTool(),
819
- ],
818
+ tools: [new ReadTool(), new WriteTool(), new BashTool()],
820
819
  })
821
820
 
822
821
  const session = await agent.createSession()
@@ -836,9 +835,9 @@ for await (const event of session.receive()) {
836
835
  ### Example 3: Persistent Sessions
837
836
 
838
837
  ```typescript
839
- import {
840
- Agent,
841
- createModel,
838
+ import {
839
+ Agent,
840
+ createModel,
842
841
  createOpenAIAdapter,
843
842
  FileStateStore,
844
843
  } from 'goatchain'
@@ -886,9 +885,9 @@ for await (const event of session.receive()) {
886
885
  ### Example 4: Session with Middleware
887
886
 
888
887
  ```typescript
889
- import {
890
- Agent,
891
- createModel,
888
+ import {
889
+ Agent,
890
+ createModel,
892
891
  createOpenAIAdapter,
893
892
  createPlanModeMiddleware,
894
893
  } from 'goatchain'
@@ -950,15 +949,15 @@ const session = await agent.createSession()
950
949
  async function chat(message: string) {
951
950
  console.log(`\nUser: ${message}`)
952
951
  console.log('Assistant: ')
953
-
952
+
954
953
  session.send(message)
955
-
954
+
956
955
  for await (const event of session.receive()) {
957
956
  if (event.type === 'text_delta') {
958
957
  process.stdout.write(event.delta)
959
958
  }
960
959
  }
961
-
960
+
962
961
  console.log('\n')
963
962
  }
964
963
 
@@ -983,6 +982,7 @@ new Agent(options: AgentOptions)
983
982
  ```
984
983
 
985
984
  **Options:**
985
+
986
986
  - `name: string` - Agent name (required)
987
987
  - `systemPrompt: string` - System instructions (required)
988
988
  - `model: ModelClient | ModelRef` - LLM client (required)
@@ -1000,8 +1000,9 @@ Create a new session.
1000
1000
 
1001
1001
  ```typescript
1002
1002
  const session = await agent.createSession({
1003
- id: 'custom-id', // Optional custom ID
1004
- configOverride: { // Optional config overrides
1003
+ id: 'custom-id', // Optional custom ID
1004
+ configOverride: {
1005
+ // Optional config overrides
1005
1006
  maxIterations: 10,
1006
1007
  temperature: 0.7,
1007
1008
  },
@@ -1133,7 +1134,7 @@ session.restoreFromSnapshot(snapshot)
1133
1134
  interface Message {
1134
1135
  role: 'system' | 'user' | 'assistant' | 'tool'
1135
1136
  content: string | ToolCall[] | ToolResult[]
1136
- name?: string // For tool messages
1137
+ name?: string // For tool messages
1137
1138
  toolCallId?: string // For tool messages
1138
1139
  }
1139
1140
  ```
@@ -1151,7 +1152,7 @@ interface Usage {
1151
1152
  ### AgentEvent Types
1152
1153
 
1153
1154
  ```typescript
1154
- type AgentEvent =
1155
+ type AgentEvent =
1155
1156
  | TextDeltaEvent
1156
1157
  | ToolCallStartEvent
1157
1158
  | ToolCallDeltaEvent
@@ -1278,6 +1279,7 @@ dim
1278
1279
  ```
1279
1280
 
1280
1281
  **Features:**
1282
+
1281
1283
  - Interactive chat interface
1282
1284
  - Session management
1283
1285
  - Tool approval system
@@ -1314,11 +1316,3 @@ See [docs/acp-server.md](./docs/acp-server.md) for details.
1314
1316
  - [CLI Documentation](./docs/cli.md) - Terminal UI features and usage
1315
1317
  - [ACP Server Guide](./docs/acp-server.md) - Editor integration setup
1316
1318
  - [Examples](./examples/) - Sample implementations
1317
-
1318
- ## 🤝 Contributing
1319
-
1320
- Contributions are welcome! Please read our contributing guidelines before submitting PRs.
1321
-
1322
- ## 📄 License
1323
-
1324
- MIT © [Simon He](https://github.com/Simon-He95)
package/dist/index.d.ts CHANGED
@@ -24,7 +24,7 @@ export { FileStateStore, InMemoryStateStore, StateKeys, StateStore, } from './st
24
24
  export type { CompressionState, FileStateStoreOptions, StateKey, StateStoreOptions, } from './state';
25
25
  export * from './subagent';
26
26
  export { BaseTool, errorContent, FilteredToolRegistry, imageContent, textContent, ToolRegistry } from './tool';
27
- export { AskUserTool, AstGrepReplaceTool, AstGrepSearchTool, BashTool, EditTool, GlobTool, GrepTool, ReadTool, TodoPlanTool, TodoWriteTool, WebSearchTool, WriteTool, } from './tool';
27
+ export { AskUserTool, AstGrepReplaceTool, AstGrepSearchTool, BashTool, EditTool, GlobTool, GrepTool, ReadTool, TodoPlanTool, TodoWriteTool, WebFetchTool, WebSearchTool, WriteTool, } from './tool';
28
28
  export type { BashArgs, BashResult, RiskLevel, ToolApprovalResult, ToolApprovalSettings, ToolApprovalStrategy, ToolExecutionContext, ToolExecutionContextInput, ToolRunUsage, } from './tool';
29
- export type { AskUserArgs, AskUserResult, AstGrepMatch, AstGrepReplaceArgs, AstGrepReplaceResult, AstGrepSearchArgs, AstGrepSearchResult, EditArgs, EditResult, GlobArgs, GlobResult, GrepArgs, GrepOutputMode, GrepResult, Question, QuestionOption, ReadArgs, ReadResult, TodoItem, TodoPlanArgs, TodoPlanResult, TodoStatus, TodoWriteArgs, TodoWriteResult, WebSearchArgs, WebSearchResult, WriteArgs, WriteResult, } from './tool';
29
+ export type { AskUserArgs, AskUserResult, AstGrepMatch, AstGrepReplaceArgs, AstGrepReplaceResult, AstGrepSearchArgs, AstGrepSearchResult, EditArgs, EditResult, FetchFormat, GlobArgs, GlobResult, GrepArgs, GrepOutputMode, GrepResult, Question, QuestionOption, ReadArgs, ReadResult, TodoItem, TodoPlanArgs, TodoPlanResult, TodoStatus, TodoWriteArgs, TodoWriteResult, WebFetchArgs, WebFetchResult, WebSearchArgs, WebSearchResult, WriteArgs, WriteResult, } from './tool';
30
30
  export type { AgentEvent, AgentEventType, AgentLoopCheckpoint, AssistantMessage, BaseEvent, CallToolResult, ContentBlock, DoneEvent, ImageContent, IterationEndEvent, IterationStartEvent, JSONSchemaProperty, Message, MessageContent, MessageRole, SystemMessage, TextContent, TextDeltaEvent, TextEndEvent, TextStartEvent, ThinkingDeltaEvent, Tool, ToolCall, ToolCallDeltaEvent, ToolCallEndEvent, ToolCallStartEvent, ToolMessage, ToolResultEvent, Usage, UserMessage, } from './types';