goatchain 0.0.28 → 0.0.30
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 +244 -18
- package/dist/acp-adapter/history-normalizer.d.ts +10 -0
- package/dist/acp-adapter/index.d.ts +2 -0
- package/dist/acp-adapter/types.d.ts +4 -0
- package/dist/agent/agent.d.ts +14 -3
- package/dist/agent/hooks/index.d.ts +1 -1
- package/dist/agent/hooks/manager.d.ts +23 -6
- package/dist/agent/hooks/prompt-executor.d.ts +28 -0
- package/dist/agent/hooks/types.d.ts +32 -9
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/middleware.d.ts +10 -2
- package/dist/agent/types.d.ts +12 -0
- package/dist/index.d.ts +10 -10
- package/dist/index.js +532 -510
- package/dist/middleware/contextCompressionMiddleware.d.ts +27 -18
- package/dist/middleware/longRunningMiddleware.d.ts +6 -0
- package/dist/middleware/parallelSubagentMiddleware.d.ts +7 -1
- package/dist/middleware/skillsMiddleware.d.ts +11 -1
- package/dist/model/anthropic/createAnthropicAdapter.d.ts +5 -0
- package/dist/session/executors/ToolExecutor.d.ts +4 -0
- package/dist/session/index.d.ts +1 -0
- package/dist/session/session.d.ts +36 -3
- package/dist/session/types/index.d.ts +1 -0
- package/dist/session/types/messageQueue.d.ts +29 -0
- package/dist/session/utils/MessageQueue.d.ts +23 -0
- package/dist/state/types.d.ts +62 -0
- package/dist/tool/builtin/grep.d.ts +3 -0
- package/dist/types/common.d.ts +12 -0
- package/dist/types/event.d.ts +63 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/snapshot.d.ts +11 -0
- package/package.json +22 -22
package/README.md
CHANGED
|
@@ -117,6 +117,10 @@ interface CreateSessionOptions {
|
|
|
117
117
|
model?: ModelRef // Optional model override
|
|
118
118
|
maxIterations?: number // Max agent loop iterations (default: 1000)
|
|
119
119
|
cwd?: string // Working directory for file operations
|
|
120
|
+
messageQueueConfig?: {
|
|
121
|
+
autoProcessQueue?: boolean // Auto-process queued messages (default: true)
|
|
122
|
+
maxQueueSize?: number // Optional queue length limit
|
|
123
|
+
}
|
|
120
124
|
requestParams?: {
|
|
121
125
|
temperature?: number // Model temperature
|
|
122
126
|
maxTokens?: number // Max output tokens
|
|
@@ -161,13 +165,70 @@ session.send('What is the weather today?')
|
|
|
161
165
|
|
|
162
166
|
// Multiple messages in sequence
|
|
163
167
|
session.send('First question')
|
|
164
|
-
// Wait for response...
|
|
165
168
|
session.send('Follow-up question')
|
|
166
169
|
```
|
|
167
170
|
|
|
168
171
|
#### Send Options
|
|
169
172
|
|
|
170
|
-
You can pass options to `send()` to control tool execution, approval, and more:
|
|
173
|
+
You can pass options to `send()` to control priority, tool execution, approval, and more:
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
// Higher priority messages are processed first (smaller number = higher priority)
|
|
177
|
+
session.send('Low priority', { priority: 10 })
|
|
178
|
+
session.send('High priority', { priority: 1 })
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
`send()` returns a message ID that can be used for queue management:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
const messageId = session.send('Can be cancelled later')
|
|
185
|
+
session.cancelQueuedMessage(messageId)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### Message Queue
|
|
189
|
+
|
|
190
|
+
Session now supports queue-based messaging by default. You can enqueue multiple messages safely even while a previous `receive()` is running.
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
const session = await agent.createSession()
|
|
194
|
+
|
|
195
|
+
session.send('First message')
|
|
196
|
+
session.send('Second message')
|
|
197
|
+
|
|
198
|
+
// Batch enqueue with priority
|
|
199
|
+
session.sendBatch([
|
|
200
|
+
{ input: 'Task A', priority: 2 },
|
|
201
|
+
{ input: 'Task B', priority: 1 },
|
|
202
|
+
])
|
|
203
|
+
|
|
204
|
+
// Inspect queue state
|
|
205
|
+
const queue = session.getQueueStatus()
|
|
206
|
+
console.log(queue.length, queue.isProcessing)
|
|
207
|
+
|
|
208
|
+
// Remove queued messages
|
|
209
|
+
session.clearQueue()
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Manual queue mode:
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
const session = await agent.createSession({
|
|
216
|
+
messageQueueConfig: { autoProcessQueue: false },
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
session.send('Message 1')
|
|
220
|
+
session.send('Message 2')
|
|
221
|
+
|
|
222
|
+
for await (const event of session.receive()) {
|
|
223
|
+
// only Message 1
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
for await (const event of session.receive()) {
|
|
227
|
+
// Message 2
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Tool context and approval options still work as before:
|
|
171
232
|
|
|
172
233
|
```typescript
|
|
173
234
|
// Auto-approve all tools for this request
|
|
@@ -677,23 +738,48 @@ interface AgentHooks {
|
|
|
677
738
|
sessionStart?: (ctx: SessionStartContext) => Promise<void>
|
|
678
739
|
sessionEnd?: (ctx: SessionEndContext) => Promise<void>
|
|
679
740
|
stop?: (ctx: StopContext) => Promise<void>
|
|
680
|
-
userPromptSubmit?:
|
|
741
|
+
userPromptSubmit?:
|
|
742
|
+
| ((ctx: UserPromptSubmitContext) => Promise<UserPromptSubmitResult>)
|
|
743
|
+
| PromptHookEntry
|
|
744
|
+
| Array<((ctx: UserPromptSubmitContext) => Promise<UserPromptSubmitResult>) | PromptHookEntry>
|
|
681
745
|
|
|
682
746
|
// Tool lifecycle
|
|
683
747
|
// - Can modify tool call with modifiedToolCall
|
|
684
|
-
preToolUse?:
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
748
|
+
preToolUse?:
|
|
749
|
+
| ((ctx: ToolHookContext) => Promise<PreToolUseResult | void>)
|
|
750
|
+
| PromptHookEntry
|
|
751
|
+
| Array<((ctx: ToolHookContext) => Promise<PreToolUseResult | void>) | PromptHookEntry>
|
|
752
|
+
permissionRequest?:
|
|
753
|
+
| ((ctx: ToolHookContext) => Promise<PermissionRequestResult>)
|
|
754
|
+
| PromptHookEntry
|
|
755
|
+
| Array<((ctx: ToolHookContext) => Promise<PermissionRequestResult>) | PromptHookEntry>
|
|
756
|
+
postToolUse?:
|
|
757
|
+
| ((ctx: ToolHookContext, result: unknown) => Promise<void>)
|
|
758
|
+
| PromptHookEntry
|
|
759
|
+
| Array<((ctx: ToolHookContext, result: unknown) => Promise<void>) | PromptHookEntry>
|
|
760
|
+
postToolUseFailure?:
|
|
761
|
+
| ((ctx: ToolHookContext, error: Error) => Promise<void>)
|
|
762
|
+
| PromptHookEntry
|
|
763
|
+
| Array<((ctx: ToolHookContext, error: Error) => Promise<void>) | PromptHookEntry>
|
|
688
764
|
|
|
689
765
|
// Subagent lifecycle (used by parallel task/subagent middleware)
|
|
690
766
|
subagentStart?: (ctx: SubagentStartContext) => Promise<void>
|
|
691
|
-
subagentStop?:
|
|
767
|
+
subagentStop?:
|
|
768
|
+
| ((ctx: SubagentStopContext) => Promise<void>)
|
|
769
|
+
| PromptHookEntry
|
|
770
|
+
| Array<((ctx: SubagentStopContext) => Promise<void>) | PromptHookEntry>
|
|
692
771
|
}
|
|
693
772
|
|
|
694
773
|
// Backward-compatible alias
|
|
695
774
|
type ToolHooks = AgentHooks
|
|
696
775
|
|
|
776
|
+
interface PromptHookEntry {
|
|
777
|
+
type: 'prompt'
|
|
778
|
+
prompt: string // use $ARGUMENTS to inject serialized input
|
|
779
|
+
model?: { provider: string; modelId: string }
|
|
780
|
+
timeoutMs?: number // default: 30000
|
|
781
|
+
}
|
|
782
|
+
|
|
697
783
|
interface BaseHookContext {
|
|
698
784
|
sessionId: string
|
|
699
785
|
}
|
|
@@ -710,9 +796,6 @@ interface ToolHookContext extends BaseHookContext {
|
|
|
710
796
|
toolContext: ToolExecutionContext
|
|
711
797
|
}
|
|
712
798
|
|
|
713
|
-
// `HookContext` is kept as a backward-compatible alias of ToolHookContext
|
|
714
|
-
type HookContext = ToolHookContext
|
|
715
|
-
|
|
716
799
|
interface PermissionRequestResult {
|
|
717
800
|
// If true, passes permission checks and skips approval flow
|
|
718
801
|
// (tool still goes through normal middleware/disabled checks)
|
|
@@ -785,6 +868,113 @@ interface SubagentStopContext extends BaseHookContext {
|
|
|
785
868
|
}
|
|
786
869
|
```
|
|
787
870
|
|
|
871
|
+
### Prompt Hook Evaluation
|
|
872
|
+
|
|
873
|
+
Prompt hooks are evaluation-only in current SDK behavior:
|
|
874
|
+
|
|
875
|
+
- Prompt evaluation does not change execution decisions or mutate input/tool calls
|
|
876
|
+
- Supported prompt hooks: `userPromptSubmit`, `preToolUse`, `permissionRequest`, `postToolUse`, `postToolUseFailure`, `subagentStop`
|
|
877
|
+
- `permissionRequest` prompt evaluation only runs when the approval path is entered
|
|
878
|
+
- Each evaluation is persisted in `session.metadata._hookEvaluations`
|
|
879
|
+
|
|
880
|
+
Prompt evaluation emits `hook_evaluation` stream events with `phase`:
|
|
881
|
+
|
|
882
|
+
- `start`
|
|
883
|
+
- `stream` (text delta)
|
|
884
|
+
- `end` (status/result/error)
|
|
885
|
+
|
|
886
|
+
`hook_evaluation` event shape:
|
|
887
|
+
|
|
888
|
+
```typescript
|
|
889
|
+
interface HookEvaluationEvent extends BaseEvent {
|
|
890
|
+
type: 'hook_evaluation'
|
|
891
|
+
evaluationId: string
|
|
892
|
+
hookName:
|
|
893
|
+
| 'permissionRequest'
|
|
894
|
+
| 'preToolUse'
|
|
895
|
+
| 'postToolUse'
|
|
896
|
+
| 'postToolUseFailure'
|
|
897
|
+
| 'subagentStop'
|
|
898
|
+
| 'userPromptSubmit'
|
|
899
|
+
phase: 'start' | 'stream' | 'end'
|
|
900
|
+
prompt?: string
|
|
901
|
+
input?: unknown
|
|
902
|
+
delta?: string
|
|
903
|
+
rawResponse?: string
|
|
904
|
+
result?: unknown
|
|
905
|
+
usage?: Usage
|
|
906
|
+
durationMs?: number
|
|
907
|
+
status?: 'success' | 'error' | 'timeout'
|
|
908
|
+
error?: { code?: string; message: string }
|
|
909
|
+
toolCallId?: string
|
|
910
|
+
}
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
Metadata persistence shape:
|
|
914
|
+
|
|
915
|
+
```typescript
|
|
916
|
+
session.metadata._hookEvaluations = {
|
|
917
|
+
preToolUse: [
|
|
918
|
+
{
|
|
919
|
+
evaluationId: '...',
|
|
920
|
+
timestamp: 1730000000000,
|
|
921
|
+
hookName: 'preToolUse',
|
|
922
|
+
prompt: '...',
|
|
923
|
+
input: { ... },
|
|
924
|
+
status: 'success',
|
|
925
|
+
durationMs: 120,
|
|
926
|
+
rawResponse: '{"ok":true}',
|
|
927
|
+
result: { ok: true },
|
|
928
|
+
usage: { promptTokens: 100, completionTokens: 20, totalTokens: 120 },
|
|
929
|
+
toolCallId: 'call_123',
|
|
930
|
+
},
|
|
931
|
+
],
|
|
932
|
+
}
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
Complete prompt hook example (function hook + prompt hook + event handling):
|
|
936
|
+
|
|
937
|
+
```typescript
|
|
938
|
+
import { Agent } from 'goatchain'
|
|
939
|
+
import type { HookEvaluationEvent } from 'goatchain'
|
|
940
|
+
|
|
941
|
+
const session = await agent.createSession({
|
|
942
|
+
hooks: {
|
|
943
|
+
preToolUse: [
|
|
944
|
+
async (ctx) => {
|
|
945
|
+
// normal behavior hook
|
|
946
|
+
return undefined
|
|
947
|
+
},
|
|
948
|
+
{
|
|
949
|
+
type: 'prompt',
|
|
950
|
+
prompt: 'Analyze this tool call: $ARGUMENTS',
|
|
951
|
+
},
|
|
952
|
+
],
|
|
953
|
+
permissionRequest: {
|
|
954
|
+
type: 'prompt',
|
|
955
|
+
prompt: 'Review approval context: $ARGUMENTS',
|
|
956
|
+
},
|
|
957
|
+
},
|
|
958
|
+
})
|
|
959
|
+
|
|
960
|
+
session.send('Do the task', {
|
|
961
|
+
toolContext: {
|
|
962
|
+
approval: { strategy: 'high_risk' },
|
|
963
|
+
},
|
|
964
|
+
})
|
|
965
|
+
|
|
966
|
+
for await (const event of session.receive()) {
|
|
967
|
+
if (event.type === 'hook_evaluation') {
|
|
968
|
+
const ev = event as HookEvaluationEvent
|
|
969
|
+
if (ev.phase === 'end') {
|
|
970
|
+
console.log('hook evaluation done:', ev.hookName, ev.status, ev.result)
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
console.log(session.metadata?._hookEvaluations)
|
|
976
|
+
```
|
|
977
|
+
|
|
788
978
|
### Hook Execution Order
|
|
789
979
|
|
|
790
980
|
Typical order in one run:
|
|
@@ -1827,12 +2017,39 @@ agent.setModel({ provider: 'openai', modelId: 'gpt-4o-mini' })
|
|
|
1827
2017
|
|
|
1828
2018
|
#### Methods
|
|
1829
2019
|
|
|
1830
|
-
**`send(input):
|
|
2020
|
+
**`send(input, options?): string`**
|
|
1831
2021
|
|
|
1832
|
-
|
|
2022
|
+
Enqueue a message and return its queue message ID.
|
|
1833
2023
|
|
|
1834
2024
|
```typescript
|
|
1835
|
-
session.send('Hello!')
|
|
2025
|
+
const id = session.send('Hello!')
|
|
2026
|
+
```
|
|
2027
|
+
|
|
2028
|
+
**`sendBatch(messages): string[]`**
|
|
2029
|
+
|
|
2030
|
+
Batch enqueue messages and return queue message IDs.
|
|
2031
|
+
|
|
2032
|
+
```typescript
|
|
2033
|
+
const ids = session.sendBatch([
|
|
2034
|
+
{ input: 'task-1', priority: 1 },
|
|
2035
|
+
{ input: 'task-2', priority: 2 },
|
|
2036
|
+
])
|
|
2037
|
+
```
|
|
2038
|
+
|
|
2039
|
+
**`cancelQueuedMessage(messageId): boolean`**
|
|
2040
|
+
|
|
2041
|
+
Cancel a queued message by ID.
|
|
2042
|
+
|
|
2043
|
+
```typescript
|
|
2044
|
+
session.cancelQueuedMessage(id)
|
|
2045
|
+
```
|
|
2046
|
+
|
|
2047
|
+
**`getQueueStatus(): MessageQueueStatus`**
|
|
2048
|
+
|
|
2049
|
+
Query queue length, preview list, processing status, and config.
|
|
2050
|
+
|
|
2051
|
+
```typescript
|
|
2052
|
+
console.log(session.getQueueStatus())
|
|
1836
2053
|
```
|
|
1837
2054
|
|
|
1838
2055
|
**`receive(options?): AsyncGenerator<AgentEvent>`**
|
|
@@ -2026,7 +2243,7 @@ classDiagram
|
|
|
2026
2243
|
+status: SessionStatus
|
|
2027
2244
|
+messages: Message[]
|
|
2028
2245
|
+usage: Usage
|
|
2029
|
-
+send(input):
|
|
2246
|
+
+send(input, options?): string
|
|
2030
2247
|
+receive(): AsyncGenerator~AgentEvent~
|
|
2031
2248
|
+save(): Promise~void~
|
|
2032
2249
|
}
|
|
@@ -2078,7 +2295,13 @@ See [docs/cli.md](./docs/cli.md) and [docs/server.md](./docs/server.md) for deta
|
|
|
2078
2295
|
Expose DimCode as an Agent Client Protocol server for editor integrations:
|
|
2079
2296
|
|
|
2080
2297
|
```bash
|
|
2081
|
-
|
|
2298
|
+
dim acp
|
|
2299
|
+
```
|
|
2300
|
+
|
|
2301
|
+
For source checkouts, use a cwd-independent command:
|
|
2302
|
+
|
|
2303
|
+
```bash
|
|
2304
|
+
node /absolute/path/to/GoatChain/scripts/acpx-agent.mjs
|
|
2082
2305
|
```
|
|
2083
2306
|
|
|
2084
2307
|
**Configuration for Zed** (`settings.json`):
|
|
@@ -2087,13 +2310,16 @@ bun run acp-server
|
|
|
2087
2310
|
{
|
|
2088
2311
|
"agent_servers": {
|
|
2089
2312
|
"dimcode": {
|
|
2090
|
-
"command": "
|
|
2091
|
-
"args": ["
|
|
2313
|
+
"command": "/absolute/path/to/dim",
|
|
2314
|
+
"args": ["acp"]
|
|
2092
2315
|
}
|
|
2093
2316
|
}
|
|
2094
2317
|
}
|
|
2095
2318
|
```
|
|
2096
2319
|
|
|
2320
|
+
For OpenClaw `acpx`, use either `/absolute/path/to/dim acp` or `node /absolute/path/to/GoatChain/scripts/acpx-agent.mjs`.
|
|
2321
|
+
Do not use `bun run acp-server` there; it depends on the launcher cwd being the GoatChain repo root.
|
|
2322
|
+
|
|
2097
2323
|
See [docs/acp-server.md](./docs/acp-server.md) for details.
|
|
2098
2324
|
|
|
2099
2325
|
## 📚 Documentation
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Message } from '../types';
|
|
2
|
+
import type { ACPMessage } from './types';
|
|
3
|
+
export type NormalizeAcpHistoryOptions = Readonly<{
|
|
4
|
+
dropTrailingPendingUserInput?: boolean;
|
|
5
|
+
}>;
|
|
6
|
+
type SessionLikeMessage = Exclude<Message, {
|
|
7
|
+
role: 'system';
|
|
8
|
+
}>;
|
|
9
|
+
export declare function normalizeAcpHistoryToSessionMessages(acpMessages: readonly ACPMessage[], options?: NormalizeAcpHistoryOptions): SessionLikeMessage[];
|
|
10
|
+
export {};
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* @packageDocumentation
|
|
8
8
|
*/
|
|
9
9
|
export { ACPAgent } from './ACPAgent';
|
|
10
|
+
export { normalizeAcpHistoryToSessionMessages } from './history-normalizer';
|
|
11
|
+
export type { NormalizeAcpHistoryOptions } from './history-normalizer';
|
|
10
12
|
export { ProtocolConverter } from './ProtocolConverter';
|
|
11
13
|
export { SessionRouter } from './SessionRouter';
|
|
12
14
|
export type { ACPAgentOptions, ACPContent, ACPMessage, ACPMetadata, ACPRole, ACPToolCall, ExtendedAgentEvent, SessionContext, SubagentMetadata, } from './types';
|
package/dist/agent/agent.d.ts
CHANGED
|
@@ -95,8 +95,11 @@ export declare class Agent {
|
|
|
95
95
|
* Middleware follows an immutable pattern - it receives state and returns new state via next().
|
|
96
96
|
*
|
|
97
97
|
* If the middleware provides a `__createTools` function, the tools will be automatically
|
|
98
|
-
* registered with a namespace prefix (`<middlewareName>_<toolName>`) and
|
|
99
|
-
* unregistered when the middleware is removed.
|
|
98
|
+
* registered with a namespace prefix (`<middlewareName>_<toolName>`) by default and
|
|
99
|
+
* automatically unregistered when the middleware is removed.
|
|
100
|
+
*
|
|
101
|
+
* If middleware sets `__toolNamespacePrefix = false`, tools are registered with their
|
|
102
|
+
* original names (`tool.name`) without `<middlewareName>_` prefix.
|
|
100
103
|
*
|
|
101
104
|
* @param fn - Middleware function
|
|
102
105
|
* @param name - Optional name for the middleware. If not provided:
|
|
@@ -120,13 +123,21 @@ export declare class Agent {
|
|
|
120
123
|
* // Override default name
|
|
121
124
|
* await agent.use(createPlanModeMiddleware(), 'my_plan_mode');
|
|
122
125
|
*
|
|
123
|
-
* // Middleware with tools (auto-registers tools with namespace)
|
|
126
|
+
* // Middleware with tools (auto-registers tools with namespace by default)
|
|
124
127
|
* const middleware: Middleware = async (state, next) => next(state);
|
|
125
128
|
* middleware.__middlewareName = 'plan_mode';
|
|
126
129
|
* middleware.__createTools = async () => [new EnterPlanModeTool()];
|
|
127
130
|
* await agent.use(middleware);
|
|
128
131
|
* // Tool registered as: 'plan_mode_EnterPlanMode'
|
|
129
132
|
*
|
|
133
|
+
* // Register middleware tool without prefix
|
|
134
|
+
* const subagentMiddleware: Middleware = async (state, next) => next(state);
|
|
135
|
+
* subagentMiddleware.__middlewareName = 'parallel_subagent';
|
|
136
|
+
* subagentMiddleware.__toolNamespacePrefix = false;
|
|
137
|
+
* subagentMiddleware.__createTools = async () => [new TaskTool()];
|
|
138
|
+
* await agent.use(subagentMiddleware);
|
|
139
|
+
* // Tool registered as: 'Task'
|
|
140
|
+
*
|
|
130
141
|
* // Anonymous middleware (auto-named)
|
|
131
142
|
* const unsubscribe = await agent.use(async (state, next) => {
|
|
132
143
|
* const compressed = { ...state, messages: compress(state.messages) };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { HookManager } from './manager';
|
|
2
|
-
export type { AgentHooks, BaseHookContext,
|
|
2
|
+
export type { AgentHooks, BaseHookContext, PermissionRequestHook, PermissionRequestHookEntry, PermissionRequestResult, PostToolUseFailureHook, PostToolUseFailureHookEntry, PostToolUseHook, PostToolUseHookEntry, PreToolUseHook, PreToolUseHookEntry, PreToolUseResult, PromptHookEntry, SessionEndContext, SessionEndHook, SessionStartContext, SessionStartHook, StopContext, StopHook, SubagentStartContext, SubagentStartHook, SubagentStopContext, SubagentStopHook, SubagentStopHookEntry, ToolHookContext, ToolHooks, UserPromptSubmitContext, UserPromptSubmitHook, UserPromptSubmitHookEntry, UserPromptSubmitResult, } from './types';
|
|
@@ -1,15 +1,32 @@
|
|
|
1
|
-
import type { AgentHooks,
|
|
1
|
+
import type { AgentHooks, PermissionRequestResult, PreToolUseResult, SessionEndContext, SessionStartContext, SubagentStartContext, StopContext, SubagentStopContext, ToolHookContext, UserPromptSubmitContext, UserPromptSubmitResult } from './types';
|
|
2
|
+
import type { ModelClient } from '../../model/types';
|
|
3
|
+
import type { HookEvaluationEvent } from '../../types';
|
|
4
|
+
interface HookManagerOptions {
|
|
5
|
+
modelClient?: ModelClient;
|
|
6
|
+
emitEvent?: (event: Omit<HookEvaluationEvent, 'sessionId'>) => void;
|
|
7
|
+
getSessionMetadata?: () => Record<string, unknown>;
|
|
8
|
+
}
|
|
2
9
|
export declare class HookManager {
|
|
3
10
|
private readonly hooks;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
11
|
+
private readonly modelClient?;
|
|
12
|
+
private readonly emitEvent?;
|
|
13
|
+
private readonly getSessionMetadata?;
|
|
14
|
+
constructor(hooks?: AgentHooks, options?: HookManagerOptions);
|
|
15
|
+
hasPermissionRequestFunction(): boolean;
|
|
16
|
+
private toCompactUsage;
|
|
17
|
+
private getToolCallIdFromInput;
|
|
18
|
+
private recordEvaluation;
|
|
19
|
+
private evaluatePromptHook;
|
|
20
|
+
executePermissionRequest(context: ToolHookContext): Promise<PermissionRequestResult>;
|
|
21
|
+
evaluatePermissionRequestPrompt(context: ToolHookContext): Promise<void>;
|
|
22
|
+
executePreToolUse(context: ToolHookContext): Promise<PreToolUseResult | void>;
|
|
7
23
|
executeUserPromptSubmit(context: UserPromptSubmitContext): Promise<UserPromptSubmitResult>;
|
|
8
24
|
executeSessionStart(context: SessionStartContext): Promise<void>;
|
|
9
25
|
executeSessionEnd(context: SessionEndContext): Promise<void>;
|
|
10
|
-
executePostToolUse(context:
|
|
11
|
-
executePostToolUseFailure(context:
|
|
26
|
+
executePostToolUse(context: ToolHookContext, result: unknown): Promise<void>;
|
|
27
|
+
executePostToolUseFailure(context: ToolHookContext, error: Error): Promise<void>;
|
|
12
28
|
executeStop(context: StopContext): Promise<void>;
|
|
13
29
|
executeSubagentStart(context: SubagentStartContext): Promise<void>;
|
|
14
30
|
executeSubagentStop(context: SubagentStopContext): Promise<void>;
|
|
15
31
|
}
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ModelClient } from '../../model/types';
|
|
2
|
+
import type { HookEvaluationEvent, Usage } from '../../types';
|
|
3
|
+
import type { PromptHookEntry } from './types';
|
|
4
|
+
export type PromptEvaluableHookName = 'permissionRequest' | 'preToolUse' | 'postToolUse' | 'postToolUseFailure' | 'subagentStop' | 'userPromptSubmit';
|
|
5
|
+
export interface ExecutePromptHookOptions {
|
|
6
|
+
hookName: PromptEvaluableHookName;
|
|
7
|
+
sessionId: string;
|
|
8
|
+
input: unknown;
|
|
9
|
+
entry: PromptHookEntry;
|
|
10
|
+
modelClient?: ModelClient;
|
|
11
|
+
toolCallId?: string;
|
|
12
|
+
emitEvent?: (event: Omit<HookEvaluationEvent, 'sessionId'>) => void;
|
|
13
|
+
}
|
|
14
|
+
export interface PromptHookExecutionResult {
|
|
15
|
+
evaluationId: string;
|
|
16
|
+
hookName: PromptEvaluableHookName;
|
|
17
|
+
renderedPrompt: string;
|
|
18
|
+
status: 'success' | 'error' | 'timeout';
|
|
19
|
+
durationMs: number;
|
|
20
|
+
rawResponse?: string;
|
|
21
|
+
result?: unknown;
|
|
22
|
+
usage?: Usage;
|
|
23
|
+
error?: {
|
|
24
|
+
code?: string;
|
|
25
|
+
message: string;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export declare function executePromptHook(options: ExecutePromptHookOptions): Promise<PromptHookExecutionResult>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ModelStopReason } from '../../model/types';
|
|
2
|
+
import type { ModelRef } from '../../model/types';
|
|
2
3
|
import type { ToolExecutionContext } from '../../tool';
|
|
3
4
|
import type { Message, MessageContent, ToolCall, Usage } from '../../types';
|
|
4
5
|
export interface BaseHookContext {
|
|
@@ -6,14 +7,11 @@ export interface BaseHookContext {
|
|
|
6
7
|
}
|
|
7
8
|
/**
|
|
8
9
|
* Context for tool-level hooks (PermissionRequest, PreToolUse, PostToolUse, PostToolUseFailure).
|
|
9
|
-
* Also exported as `HookContext` for backward compatibility.
|
|
10
10
|
*/
|
|
11
11
|
export interface ToolHookContext extends BaseHookContext {
|
|
12
12
|
toolCall: ToolCall;
|
|
13
13
|
toolContext: ToolExecutionContext;
|
|
14
14
|
}
|
|
15
|
-
/** @deprecated Use `ToolHookContext` instead. Kept for backward compatibility. */
|
|
16
|
-
export type HookContext = ToolHookContext;
|
|
17
15
|
export interface SessionStartContext extends BaseHookContext {
|
|
18
16
|
/** Whether this run starts from a new session or a resumed state/checkpoint. */
|
|
19
17
|
startReason: 'new' | 'resume';
|
|
@@ -84,6 +82,25 @@ export interface UserPromptSubmitResult {
|
|
|
84
82
|
allow: boolean;
|
|
85
83
|
modifiedInput?: MessageContent;
|
|
86
84
|
}
|
|
85
|
+
export interface PromptHookEntry {
|
|
86
|
+
type: 'prompt';
|
|
87
|
+
/**
|
|
88
|
+
* Prompt template used for evaluation.
|
|
89
|
+
* `$ARGUMENTS` (if present) will be replaced with serialized hook input.
|
|
90
|
+
* If absent, serialized hook input is appended to the end of the prompt.
|
|
91
|
+
*/
|
|
92
|
+
prompt: string;
|
|
93
|
+
/**
|
|
94
|
+
* Optional model override for this hook evaluation.
|
|
95
|
+
* Defaults to the session's configured model.
|
|
96
|
+
*/
|
|
97
|
+
model?: ModelRef;
|
|
98
|
+
/**
|
|
99
|
+
* Optional timeout in milliseconds for this evaluation.
|
|
100
|
+
* Defaults to 30_000ms.
|
|
101
|
+
*/
|
|
102
|
+
timeoutMs?: number;
|
|
103
|
+
}
|
|
87
104
|
export type PermissionRequestHook = (ctx: ToolHookContext) => Promise<PermissionRequestResult>;
|
|
88
105
|
export type PreToolUseHook = (ctx: ToolHookContext) => Promise<PreToolUseResult | void>;
|
|
89
106
|
export type PostToolUseHook = (ctx: ToolHookContext, result: unknown) => Promise<void>;
|
|
@@ -94,17 +111,23 @@ export type SessionEndHook = (ctx: SessionEndContext) => Promise<void>;
|
|
|
94
111
|
export type SubagentStartHook = (ctx: SubagentStartContext) => Promise<void>;
|
|
95
112
|
export type SubagentStopHook = (ctx: SubagentStopContext) => Promise<void>;
|
|
96
113
|
export type UserPromptSubmitHook = (ctx: UserPromptSubmitContext) => Promise<UserPromptSubmitResult>;
|
|
114
|
+
export type PermissionRequestHookEntry = PermissionRequestHook | PromptHookEntry;
|
|
115
|
+
export type PreToolUseHookEntry = PreToolUseHook | PromptHookEntry;
|
|
116
|
+
export type PostToolUseHookEntry = PostToolUseHook | PromptHookEntry;
|
|
117
|
+
export type PostToolUseFailureHookEntry = PostToolUseFailureHook | PromptHookEntry;
|
|
118
|
+
export type SubagentStopHookEntry = SubagentStopHook | PromptHookEntry;
|
|
119
|
+
export type UserPromptSubmitHookEntry = UserPromptSubmitHook | PromptHookEntry;
|
|
97
120
|
export interface AgentHooks {
|
|
98
121
|
sessionStart?: SessionStartHook;
|
|
99
|
-
permissionRequest?:
|
|
100
|
-
preToolUse?:
|
|
101
|
-
postToolUse?:
|
|
102
|
-
postToolUseFailure?:
|
|
122
|
+
permissionRequest?: PermissionRequestHookEntry | PermissionRequestHookEntry[];
|
|
123
|
+
preToolUse?: PreToolUseHookEntry | PreToolUseHookEntry[];
|
|
124
|
+
postToolUse?: PostToolUseHookEntry | PostToolUseHookEntry[];
|
|
125
|
+
postToolUseFailure?: PostToolUseFailureHookEntry | PostToolUseFailureHookEntry[];
|
|
103
126
|
sessionEnd?: SessionEndHook;
|
|
104
127
|
stop?: StopHook;
|
|
105
128
|
subagentStart?: SubagentStartHook;
|
|
106
|
-
subagentStop?:
|
|
107
|
-
userPromptSubmit?:
|
|
129
|
+
subagentStop?: SubagentStopHookEntry | SubagentStopHookEntry[];
|
|
130
|
+
userPromptSubmit?: UserPromptSubmitHookEntry | UserPromptSubmitHookEntry[];
|
|
108
131
|
}
|
|
109
132
|
/** @deprecated Use `AgentHooks` instead. Kept for backward compatibility. */
|
|
110
133
|
export type ToolHooks = AgentHooks;
|
package/dist/agent/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export type { ToCheckpointOptions } from '../session/handlers/CheckpointManager'
|
|
|
6
6
|
export { Agent } from './agent';
|
|
7
7
|
export { AgentAbortError, AgentMaxIterationsError, AgentPauseError, ensureNotAborted } from './errors';
|
|
8
8
|
export { HookManager } from './hooks';
|
|
9
|
-
export type { AgentHooks, BaseHookContext,
|
|
9
|
+
export type { AgentHooks, BaseHookContext, PermissionRequestHook, PermissionRequestHookEntry, PermissionRequestResult, PostToolUseFailureHook, PostToolUseFailureHookEntry, PostToolUseHook, PostToolUseHookEntry, PreToolUseHook, PreToolUseHookEntry, PreToolUseResult, PromptHookEntry, SessionEndContext, SessionEndHook, SessionStartContext, SessionStartHook, StopContext, StopHook, SubagentStartContext, SubagentStartHook, SubagentStopContext, SubagentStopHook, SubagentStopHookEntry, ToolHookContext, ToolHooks, UserPromptSubmitContext, UserPromptSubmitHook, UserPromptSubmitHookEntry, UserPromptSubmitResult, } from './hooks';
|
|
10
10
|
export { compose } from './middleware';
|
|
11
11
|
export type { Middleware, NamedMiddleware, NextFunction } from './middleware';
|
|
12
12
|
export { countContentTokens, countMessagesTokens, countMessageTokens, countTokens, createCachedTokenCounter, estimateMessagesTokens, estimateTokens, } from './tokenCounter';
|
|
@@ -49,9 +49,11 @@ export interface Middleware<State = AgentLoopState> {
|
|
|
49
49
|
/**
|
|
50
50
|
* Optional factory function that creates tools to be registered with this middleware.
|
|
51
51
|
* When the middleware is registered via agent.use(), this function will be called
|
|
52
|
-
* and the returned tools will be automatically registered with a namespace prefix
|
|
52
|
+
* and the returned tools will be automatically registered with a namespace prefix
|
|
53
|
+
* by default.
|
|
53
54
|
*
|
|
54
|
-
* Tools will be namespaced as: `<middlewareName>_<toolName
|
|
55
|
+
* Tools will be namespaced as: `<middlewareName>_<toolName>`.
|
|
56
|
+
* If `__toolNamespacePrefix === false`, tools are registered with original `tool.name`.
|
|
55
57
|
* When the middleware is removed, all associated tools are automatically unregistered.
|
|
56
58
|
*
|
|
57
59
|
* Can be synchronous or asynchronous to support dynamic tool creation.
|
|
@@ -70,6 +72,12 @@ export interface Middleware<State = AgentLoopState> {
|
|
|
70
72
|
* ```
|
|
71
73
|
*/
|
|
72
74
|
__createTools?: () => BaseTool[] | Promise<BaseTool[]>;
|
|
75
|
+
/**
|
|
76
|
+
* Optional flag to control middleware tool namespace prefixing.
|
|
77
|
+
* Defaults to true/undefined, which registers tools as `<middlewareName>_<toolName>`.
|
|
78
|
+
* Set to false to register tools with their original `tool.name` (no middleware prefix).
|
|
79
|
+
*/
|
|
80
|
+
__toolNamespacePrefix?: boolean;
|
|
73
81
|
/**
|
|
74
82
|
* Optional function that returns a list of tool names to block for the given state.
|
|
75
83
|
* This allows middleware to dynamically control which tools should be unavailable
|
package/dist/agent/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { McpServerConfig } from '../mcp-client';
|
|
2
2
|
import type { ModelClient, ModelRef } from '../model';
|
|
3
3
|
import type { ModelStopReason } from '../model/types';
|
|
4
|
+
import type { MessageQueueConfig } from '../session/types';
|
|
4
5
|
import type { StateStore } from '../state';
|
|
5
6
|
import type { ToolExecutionContextInput, ToolRegistry } from '../tool';
|
|
6
7
|
import type { CheckpointRequestParams, Message, MessageContent, ToolCall, Usage } from '../types';
|
|
@@ -294,10 +295,21 @@ export interface CreateSessionOptions extends SessionHandleOptions {
|
|
|
294
295
|
* This value is persisted in session snapshots and restored on resume.
|
|
295
296
|
*/
|
|
296
297
|
cwd?: string;
|
|
298
|
+
/**
|
|
299
|
+
* Optional message queue configuration for this session.
|
|
300
|
+
*/
|
|
301
|
+
messageQueueConfig?: Partial<MessageQueueConfig>;
|
|
297
302
|
}
|
|
298
303
|
export interface SendOptions {
|
|
299
304
|
/**
|
|
300
305
|
* Optional tool execution context input
|
|
301
306
|
*/
|
|
302
307
|
toolContext?: ToolExecutionContextInput;
|
|
308
|
+
/**
|
|
309
|
+
* Controls how receive() handles existing checkpoints.
|
|
310
|
+
* - auto: preserve current behavior
|
|
311
|
+
* - explicit_only: do not auto-resume a pending checkpoint
|
|
312
|
+
* - force_resume: require resuming from checkpoint flow first
|
|
313
|
+
*/
|
|
314
|
+
resumeMode?: 'auto' | 'explicit_only' | 'force_resume';
|
|
303
315
|
}
|