@compilr-dev/agents 0.0.1
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 +1277 -0
- package/dist/agent.d.ts +1272 -0
- package/dist/agent.js +1912 -0
- package/dist/anchors/builtin.d.ts +24 -0
- package/dist/anchors/builtin.js +61 -0
- package/dist/anchors/index.d.ts +6 -0
- package/dist/anchors/index.js +5 -0
- package/dist/anchors/manager.d.ts +115 -0
- package/dist/anchors/manager.js +412 -0
- package/dist/anchors/types.d.ts +168 -0
- package/dist/anchors/types.js +10 -0
- package/dist/context/index.d.ts +12 -0
- package/dist/context/index.js +10 -0
- package/dist/context/manager.d.ts +224 -0
- package/dist/context/manager.js +770 -0
- package/dist/context/types.d.ts +377 -0
- package/dist/context/types.js +7 -0
- package/dist/costs/index.d.ts +8 -0
- package/dist/costs/index.js +7 -0
- package/dist/costs/tracker.d.ts +121 -0
- package/dist/costs/tracker.js +295 -0
- package/dist/costs/types.d.ts +157 -0
- package/dist/costs/types.js +8 -0
- package/dist/errors.d.ts +178 -0
- package/dist/errors.js +249 -0
- package/dist/guardrails/builtin.d.ts +27 -0
- package/dist/guardrails/builtin.js +223 -0
- package/dist/guardrails/index.d.ts +6 -0
- package/dist/guardrails/index.js +5 -0
- package/dist/guardrails/manager.d.ts +117 -0
- package/dist/guardrails/manager.js +288 -0
- package/dist/guardrails/types.d.ts +159 -0
- package/dist/guardrails/types.js +7 -0
- package/dist/hooks/index.d.ts +31 -0
- package/dist/hooks/index.js +29 -0
- package/dist/hooks/manager.d.ts +147 -0
- package/dist/hooks/manager.js +600 -0
- package/dist/hooks/types.d.ts +368 -0
- package/dist/hooks/types.js +12 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +73 -0
- package/dist/mcp/client.d.ts +93 -0
- package/dist/mcp/client.js +287 -0
- package/dist/mcp/errors.d.ts +60 -0
- package/dist/mcp/errors.js +78 -0
- package/dist/mcp/index.d.ts +43 -0
- package/dist/mcp/index.js +45 -0
- package/dist/mcp/manager.d.ts +120 -0
- package/dist/mcp/manager.js +276 -0
- package/dist/mcp/tools.d.ts +54 -0
- package/dist/mcp/tools.js +99 -0
- package/dist/mcp/types.d.ts +150 -0
- package/dist/mcp/types.js +40 -0
- package/dist/memory/index.d.ts +8 -0
- package/dist/memory/index.js +7 -0
- package/dist/memory/loader.d.ts +114 -0
- package/dist/memory/loader.js +463 -0
- package/dist/memory/types.d.ts +182 -0
- package/dist/memory/types.js +8 -0
- package/dist/messages/index.d.ts +82 -0
- package/dist/messages/index.js +155 -0
- package/dist/permissions/index.d.ts +5 -0
- package/dist/permissions/index.js +4 -0
- package/dist/permissions/manager.d.ts +125 -0
- package/dist/permissions/manager.js +379 -0
- package/dist/permissions/types.d.ts +162 -0
- package/dist/permissions/types.js +7 -0
- package/dist/providers/claude.d.ts +90 -0
- package/dist/providers/claude.js +348 -0
- package/dist/providers/index.d.ts +8 -0
- package/dist/providers/index.js +11 -0
- package/dist/providers/mock.d.ts +133 -0
- package/dist/providers/mock.js +204 -0
- package/dist/providers/types.d.ts +168 -0
- package/dist/providers/types.js +4 -0
- package/dist/rate-limit/index.d.ts +45 -0
- package/dist/rate-limit/index.js +47 -0
- package/dist/rate-limit/limiter.d.ts +104 -0
- package/dist/rate-limit/limiter.js +326 -0
- package/dist/rate-limit/provider-wrapper.d.ts +112 -0
- package/dist/rate-limit/provider-wrapper.js +201 -0
- package/dist/rate-limit/retry.d.ts +108 -0
- package/dist/rate-limit/retry.js +287 -0
- package/dist/rate-limit/types.d.ts +181 -0
- package/dist/rate-limit/types.js +22 -0
- package/dist/rehearsal/file-analyzer.d.ts +22 -0
- package/dist/rehearsal/file-analyzer.js +351 -0
- package/dist/rehearsal/git-analyzer.d.ts +22 -0
- package/dist/rehearsal/git-analyzer.js +472 -0
- package/dist/rehearsal/index.d.ts +35 -0
- package/dist/rehearsal/index.js +36 -0
- package/dist/rehearsal/manager.d.ts +100 -0
- package/dist/rehearsal/manager.js +290 -0
- package/dist/rehearsal/types.d.ts +235 -0
- package/dist/rehearsal/types.js +8 -0
- package/dist/skills/index.d.ts +160 -0
- package/dist/skills/index.js +282 -0
- package/dist/state/agent-state.d.ts +41 -0
- package/dist/state/agent-state.js +88 -0
- package/dist/state/checkpointer.d.ts +110 -0
- package/dist/state/checkpointer.js +362 -0
- package/dist/state/errors.d.ts +66 -0
- package/dist/state/errors.js +88 -0
- package/dist/state/index.d.ts +35 -0
- package/dist/state/index.js +37 -0
- package/dist/state/serializer.d.ts +55 -0
- package/dist/state/serializer.js +172 -0
- package/dist/state/types.d.ts +312 -0
- package/dist/state/types.js +14 -0
- package/dist/tools/builtin/bash-output.d.ts +61 -0
- package/dist/tools/builtin/bash-output.js +90 -0
- package/dist/tools/builtin/bash.d.ts +150 -0
- package/dist/tools/builtin/bash.js +354 -0
- package/dist/tools/builtin/edit.d.ts +50 -0
- package/dist/tools/builtin/edit.js +215 -0
- package/dist/tools/builtin/glob.d.ts +62 -0
- package/dist/tools/builtin/glob.js +244 -0
- package/dist/tools/builtin/grep.d.ts +74 -0
- package/dist/tools/builtin/grep.js +363 -0
- package/dist/tools/builtin/index.d.ts +44 -0
- package/dist/tools/builtin/index.js +69 -0
- package/dist/tools/builtin/kill-shell.d.ts +44 -0
- package/dist/tools/builtin/kill-shell.js +80 -0
- package/dist/tools/builtin/read-file.d.ts +57 -0
- package/dist/tools/builtin/read-file.js +184 -0
- package/dist/tools/builtin/shell-manager.d.ts +176 -0
- package/dist/tools/builtin/shell-manager.js +337 -0
- package/dist/tools/builtin/task.d.ts +202 -0
- package/dist/tools/builtin/task.js +350 -0
- package/dist/tools/builtin/todo.d.ts +207 -0
- package/dist/tools/builtin/todo.js +453 -0
- package/dist/tools/builtin/utils.d.ts +27 -0
- package/dist/tools/builtin/utils.js +70 -0
- package/dist/tools/builtin/web-fetch.d.ts +96 -0
- package/dist/tools/builtin/web-fetch.js +290 -0
- package/dist/tools/builtin/write-file.d.ts +54 -0
- package/dist/tools/builtin/write-file.js +147 -0
- package/dist/tools/define.d.ts +60 -0
- package/dist/tools/define.js +65 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.js +37 -0
- package/dist/tools/registry.d.ts +79 -0
- package/dist/tools/registry.js +151 -0
- package/dist/tools/types.d.ts +59 -0
- package/dist/tools/types.js +4 -0
- package/dist/tracing/hooks.d.ts +58 -0
- package/dist/tracing/hooks.js +377 -0
- package/dist/tracing/index.d.ts +51 -0
- package/dist/tracing/index.js +55 -0
- package/dist/tracing/logging.d.ts +78 -0
- package/dist/tracing/logging.js +310 -0
- package/dist/tracing/manager.d.ts +160 -0
- package/dist/tracing/manager.js +468 -0
- package/dist/tracing/otel.d.ts +102 -0
- package/dist/tracing/otel.js +246 -0
- package/dist/tracing/types.d.ts +346 -0
- package/dist/tracing/types.js +38 -0
- package/dist/utils/index.d.ts +23 -0
- package/dist/utils/index.js +44 -0
- package/package.json +79 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State Serializers
|
|
3
|
+
*
|
|
4
|
+
* Implementations for serializing/deserializing AgentState.
|
|
5
|
+
*/
|
|
6
|
+
import { CURRENT_STATE_VERSION } from './types.js';
|
|
7
|
+
import { StateError } from './errors.js';
|
|
8
|
+
/**
|
|
9
|
+
* JSON-based state serializer.
|
|
10
|
+
* Handles standard JSON serialization with validation.
|
|
11
|
+
*/
|
|
12
|
+
export class JsonSerializer {
|
|
13
|
+
version = '1.0';
|
|
14
|
+
/**
|
|
15
|
+
* Serialize agent state to JSON string
|
|
16
|
+
*/
|
|
17
|
+
serialize(state) {
|
|
18
|
+
try {
|
|
19
|
+
return JSON.stringify(state, null, 2);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
throw StateError.serialization('Failed to serialize state to JSON', error instanceof Error ? error : undefined);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Deserialize JSON string to agent state
|
|
27
|
+
*/
|
|
28
|
+
deserialize(data) {
|
|
29
|
+
let parsed;
|
|
30
|
+
try {
|
|
31
|
+
parsed = JSON.parse(data);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
throw StateError.deserialization('Invalid JSON format', error instanceof Error ? error : undefined);
|
|
35
|
+
}
|
|
36
|
+
this.validateParsed(parsed);
|
|
37
|
+
return parsed;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Validate state before serialization (public interface method).
|
|
41
|
+
* This is called by checkpointers before saving to prevent corrupted checkpoints.
|
|
42
|
+
* @throws StateError if state is invalid
|
|
43
|
+
*/
|
|
44
|
+
validate(state) {
|
|
45
|
+
this.validateParsed(state);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Validate that parsed data is a valid AgentState
|
|
49
|
+
*/
|
|
50
|
+
validateParsed(data) {
|
|
51
|
+
if (!data || typeof data !== 'object') {
|
|
52
|
+
throw StateError.invalidState('State must be an object');
|
|
53
|
+
}
|
|
54
|
+
const state = data;
|
|
55
|
+
// Required string fields
|
|
56
|
+
const requiredStrings = ['sessionId', 'systemPrompt', 'createdAt', 'updatedAt'];
|
|
57
|
+
for (const field of requiredStrings) {
|
|
58
|
+
if (typeof state[field] !== 'string') {
|
|
59
|
+
throw StateError.invalidState(`Missing or invalid field: ${field}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Messages array
|
|
63
|
+
if (!Array.isArray(state.messages)) {
|
|
64
|
+
throw StateError.invalidState('messages must be an array');
|
|
65
|
+
}
|
|
66
|
+
// Todos array
|
|
67
|
+
if (!Array.isArray(state.todos)) {
|
|
68
|
+
throw StateError.invalidState('todos must be an array');
|
|
69
|
+
}
|
|
70
|
+
// Numeric fields
|
|
71
|
+
if (typeof state.currentIteration !== 'number') {
|
|
72
|
+
throw StateError.invalidState('currentIteration must be a number');
|
|
73
|
+
}
|
|
74
|
+
if (typeof state.totalTokensUsed !== 'number') {
|
|
75
|
+
throw StateError.invalidState('totalTokensUsed must be a number');
|
|
76
|
+
}
|
|
77
|
+
if (typeof state.version !== 'number') {
|
|
78
|
+
throw StateError.invalidState('version must be a number');
|
|
79
|
+
}
|
|
80
|
+
// Version check - safe to cast since we validated it's a number
|
|
81
|
+
const version = state.version;
|
|
82
|
+
if (version > CURRENT_STATE_VERSION) {
|
|
83
|
+
throw StateError.versionMismatch(CURRENT_STATE_VERSION, version);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Migrate from older versions (currently no-op for v1)
|
|
88
|
+
*/
|
|
89
|
+
migrate(data, fromVersion) {
|
|
90
|
+
// Parse to validate JSON format
|
|
91
|
+
JSON.parse(data);
|
|
92
|
+
// Currently only version 1, no migration needed
|
|
93
|
+
if (fromVersion === '1.0') {
|
|
94
|
+
return data;
|
|
95
|
+
}
|
|
96
|
+
throw StateError.versionMismatch(CURRENT_STATE_VERSION, parseFloat(fromVersion) || 0);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Compact JSON serializer (no pretty printing).
|
|
101
|
+
* Useful for storage-constrained environments.
|
|
102
|
+
*/
|
|
103
|
+
export class CompactJsonSerializer {
|
|
104
|
+
version = '1.0';
|
|
105
|
+
serialize(state) {
|
|
106
|
+
try {
|
|
107
|
+
return JSON.stringify(state);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
throw StateError.serialization('Failed to serialize state to compact JSON', error instanceof Error ? error : undefined);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
deserialize(data) {
|
|
114
|
+
let parsed;
|
|
115
|
+
try {
|
|
116
|
+
parsed = JSON.parse(data);
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
throw StateError.deserialization('Invalid JSON format', error instanceof Error ? error : undefined);
|
|
120
|
+
}
|
|
121
|
+
this.validateParsed(parsed);
|
|
122
|
+
return parsed;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Validate state before serialization (public interface method).
|
|
126
|
+
* This is called by checkpointers before saving to prevent corrupted checkpoints.
|
|
127
|
+
* @throws StateError if state is invalid
|
|
128
|
+
*/
|
|
129
|
+
validate(state) {
|
|
130
|
+
this.validateParsed(state);
|
|
131
|
+
}
|
|
132
|
+
validateParsed(data) {
|
|
133
|
+
if (!data || typeof data !== 'object') {
|
|
134
|
+
throw StateError.invalidState('State must be an object');
|
|
135
|
+
}
|
|
136
|
+
const state = data;
|
|
137
|
+
// Required string fields
|
|
138
|
+
const requiredStrings = ['sessionId', 'systemPrompt', 'createdAt', 'updatedAt'];
|
|
139
|
+
for (const field of requiredStrings) {
|
|
140
|
+
if (typeof state[field] !== 'string') {
|
|
141
|
+
throw StateError.invalidState(`Missing or invalid field: ${field}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Messages array
|
|
145
|
+
if (!Array.isArray(state.messages)) {
|
|
146
|
+
throw StateError.invalidState('messages must be an array');
|
|
147
|
+
}
|
|
148
|
+
// Todos array
|
|
149
|
+
if (!Array.isArray(state.todos)) {
|
|
150
|
+
throw StateError.invalidState('todos must be an array');
|
|
151
|
+
}
|
|
152
|
+
// Numeric fields
|
|
153
|
+
if (typeof state.currentIteration !== 'number') {
|
|
154
|
+
throw StateError.invalidState('currentIteration must be a number');
|
|
155
|
+
}
|
|
156
|
+
if (typeof state.totalTokensUsed !== 'number') {
|
|
157
|
+
throw StateError.invalidState('totalTokensUsed must be a number');
|
|
158
|
+
}
|
|
159
|
+
if (typeof state.version !== 'number') {
|
|
160
|
+
throw StateError.invalidState('version must be a number');
|
|
161
|
+
}
|
|
162
|
+
// Version check - safe to cast since we validated it's a number
|
|
163
|
+
const version = state.version;
|
|
164
|
+
if (version > CURRENT_STATE_VERSION) {
|
|
165
|
+
throw StateError.versionMismatch(CURRENT_STATE_VERSION, version);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Default serializer instance
|
|
171
|
+
*/
|
|
172
|
+
export const defaultSerializer = new JsonSerializer();
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State Management Types
|
|
3
|
+
*
|
|
4
|
+
* Core types and interfaces for conversation persistence.
|
|
5
|
+
* Inspired by LangGraph's checkpointer pattern.
|
|
6
|
+
*/
|
|
7
|
+
import type { Message } from '../providers/types.js';
|
|
8
|
+
import type { TodoItem } from '../tools/builtin/todo.js';
|
|
9
|
+
/**
|
|
10
|
+
* Serializable snapshot of an agent's current state.
|
|
11
|
+
* Contains everything needed to resume a conversation.
|
|
12
|
+
*/
|
|
13
|
+
export interface AgentState {
|
|
14
|
+
/**
|
|
15
|
+
* Unique session identifier
|
|
16
|
+
*/
|
|
17
|
+
sessionId: string;
|
|
18
|
+
/**
|
|
19
|
+
* Conversation messages
|
|
20
|
+
*/
|
|
21
|
+
messages: Message[];
|
|
22
|
+
/**
|
|
23
|
+
* System prompt (needed for resume)
|
|
24
|
+
*/
|
|
25
|
+
systemPrompt: string;
|
|
26
|
+
/**
|
|
27
|
+
* Model identifier (optional, for resume)
|
|
28
|
+
*/
|
|
29
|
+
model?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Todo items state
|
|
32
|
+
*/
|
|
33
|
+
todos: TodoItem[];
|
|
34
|
+
/**
|
|
35
|
+
* Current iteration count
|
|
36
|
+
*/
|
|
37
|
+
currentIteration: number;
|
|
38
|
+
/**
|
|
39
|
+
* Total tokens used in the session
|
|
40
|
+
*/
|
|
41
|
+
totalTokensUsed: number;
|
|
42
|
+
/**
|
|
43
|
+
* When the session was created (ISO 8601)
|
|
44
|
+
*/
|
|
45
|
+
createdAt: string;
|
|
46
|
+
/**
|
|
47
|
+
* When the session was last updated (ISO 8601)
|
|
48
|
+
*/
|
|
49
|
+
updatedAt: string;
|
|
50
|
+
/**
|
|
51
|
+
* Schema version for migration support
|
|
52
|
+
*/
|
|
53
|
+
version: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Metadata stored alongside state for listing/filtering.
|
|
57
|
+
*/
|
|
58
|
+
export interface SessionMetadata {
|
|
59
|
+
/**
|
|
60
|
+
* Session identifier
|
|
61
|
+
*/
|
|
62
|
+
sessionId: string;
|
|
63
|
+
/**
|
|
64
|
+
* User-friendly session name
|
|
65
|
+
*/
|
|
66
|
+
name?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Creation timestamp (ISO 8601)
|
|
69
|
+
*/
|
|
70
|
+
createdAt: string;
|
|
71
|
+
/**
|
|
72
|
+
* Last update timestamp (ISO 8601)
|
|
73
|
+
*/
|
|
74
|
+
updatedAt: string;
|
|
75
|
+
/**
|
|
76
|
+
* Number of messages in the conversation
|
|
77
|
+
*/
|
|
78
|
+
messageCount: number;
|
|
79
|
+
/**
|
|
80
|
+
* Truncated preview of last user message
|
|
81
|
+
*/
|
|
82
|
+
lastUserMessage?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Truncated preview of last assistant message
|
|
85
|
+
*/
|
|
86
|
+
lastAssistantMessage?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Tags for organization
|
|
89
|
+
*/
|
|
90
|
+
tags?: string[];
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Lightweight session info for listing (without full state).
|
|
94
|
+
*/
|
|
95
|
+
export interface SessionInfo {
|
|
96
|
+
/**
|
|
97
|
+
* Session identifier
|
|
98
|
+
*/
|
|
99
|
+
sessionId: string;
|
|
100
|
+
/**
|
|
101
|
+
* User-friendly session name
|
|
102
|
+
*/
|
|
103
|
+
name?: string;
|
|
104
|
+
/**
|
|
105
|
+
* Creation timestamp (ISO 8601)
|
|
106
|
+
*/
|
|
107
|
+
createdAt: string;
|
|
108
|
+
/**
|
|
109
|
+
* Last update timestamp (ISO 8601)
|
|
110
|
+
*/
|
|
111
|
+
updatedAt: string;
|
|
112
|
+
/**
|
|
113
|
+
* Number of messages
|
|
114
|
+
*/
|
|
115
|
+
messageCount: number;
|
|
116
|
+
/**
|
|
117
|
+
* Preview text (last message truncated)
|
|
118
|
+
*/
|
|
119
|
+
preview?: string;
|
|
120
|
+
/**
|
|
121
|
+
* Tags for organization
|
|
122
|
+
*/
|
|
123
|
+
tags?: string[];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Handles conversion between AgentState and string representation.
|
|
127
|
+
*/
|
|
128
|
+
export interface StateSerializer {
|
|
129
|
+
/**
|
|
130
|
+
* Serialize agent state to string
|
|
131
|
+
*/
|
|
132
|
+
serialize(state: AgentState): string;
|
|
133
|
+
/**
|
|
134
|
+
* Deserialize string back to agent state
|
|
135
|
+
* @throws StateError if data is invalid
|
|
136
|
+
*/
|
|
137
|
+
deserialize(data: string): AgentState;
|
|
138
|
+
/**
|
|
139
|
+
* Validate state before serialization.
|
|
140
|
+
* Called by checkpointers before saving to prevent corrupted checkpoints.
|
|
141
|
+
* @throws StateError if state is invalid
|
|
142
|
+
*/
|
|
143
|
+
validate(state: AgentState): void;
|
|
144
|
+
/**
|
|
145
|
+
* Version identifier for migration support
|
|
146
|
+
*/
|
|
147
|
+
readonly version: string;
|
|
148
|
+
/**
|
|
149
|
+
* Optional migration from older versions
|
|
150
|
+
*/
|
|
151
|
+
migrate?(data: string, fromVersion: string): string;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Options for listing sessions.
|
|
155
|
+
*/
|
|
156
|
+
export interface ListSessionsOptions {
|
|
157
|
+
/**
|
|
158
|
+
* Maximum number of sessions to return
|
|
159
|
+
*/
|
|
160
|
+
limit?: number;
|
|
161
|
+
/**
|
|
162
|
+
* Number of sessions to skip (for pagination)
|
|
163
|
+
*/
|
|
164
|
+
offset?: number;
|
|
165
|
+
/**
|
|
166
|
+
* Field to sort by
|
|
167
|
+
*/
|
|
168
|
+
orderBy?: 'createdAt' | 'updatedAt';
|
|
169
|
+
/**
|
|
170
|
+
* Sort direction
|
|
171
|
+
*/
|
|
172
|
+
order?: 'asc' | 'desc';
|
|
173
|
+
/**
|
|
174
|
+
* Filter by tags (sessions must have all specified tags)
|
|
175
|
+
*/
|
|
176
|
+
tags?: string[];
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Core persistence interface. Implementations handle actual storage.
|
|
180
|
+
*/
|
|
181
|
+
export interface Checkpointer {
|
|
182
|
+
/**
|
|
183
|
+
* Save agent state to storage
|
|
184
|
+
* @param sessionId - Unique session identifier
|
|
185
|
+
* @param state - Complete agent state to save
|
|
186
|
+
* @param metadata - Optional metadata overrides
|
|
187
|
+
*/
|
|
188
|
+
save(sessionId: string, state: AgentState, metadata?: Partial<SessionMetadata>): Promise<void>;
|
|
189
|
+
/**
|
|
190
|
+
* Load agent state from storage
|
|
191
|
+
* @param sessionId - Session to load
|
|
192
|
+
* @returns AgentState if found, null if not exists
|
|
193
|
+
*/
|
|
194
|
+
load(sessionId: string): Promise<AgentState | null>;
|
|
195
|
+
/**
|
|
196
|
+
* List all saved sessions
|
|
197
|
+
* @param options - Optional filtering/sorting options
|
|
198
|
+
* @returns Array of session info (without full state)
|
|
199
|
+
*/
|
|
200
|
+
list(options?: ListSessionsOptions): Promise<SessionInfo[]>;
|
|
201
|
+
/**
|
|
202
|
+
* Delete a saved session
|
|
203
|
+
* @param sessionId - Session to delete
|
|
204
|
+
* @returns true if deleted, false if not found
|
|
205
|
+
*/
|
|
206
|
+
delete(sessionId: string): Promise<boolean>;
|
|
207
|
+
/**
|
|
208
|
+
* Check if a session exists
|
|
209
|
+
* @param sessionId - Session to check
|
|
210
|
+
*/
|
|
211
|
+
exists(sessionId: string): Promise<boolean>;
|
|
212
|
+
/**
|
|
213
|
+
* Get session metadata without loading full state
|
|
214
|
+
* @param sessionId - Session to query
|
|
215
|
+
*/
|
|
216
|
+
getMetadata(sessionId: string): Promise<SessionMetadata | null>;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Pending write from incomplete tool execution.
|
|
220
|
+
* Used for fault-tolerant checkpointing.
|
|
221
|
+
*/
|
|
222
|
+
export interface PendingWrite {
|
|
223
|
+
/**
|
|
224
|
+
* Tool call ID
|
|
225
|
+
*/
|
|
226
|
+
toolCallId: string;
|
|
227
|
+
/**
|
|
228
|
+
* Tool name
|
|
229
|
+
*/
|
|
230
|
+
toolName: string;
|
|
231
|
+
/**
|
|
232
|
+
* Tool execution result
|
|
233
|
+
*/
|
|
234
|
+
result: {
|
|
235
|
+
success: boolean;
|
|
236
|
+
result?: unknown;
|
|
237
|
+
error?: string;
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* When the write was completed (ISO 8601)
|
|
241
|
+
*/
|
|
242
|
+
completedAt: string;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Extended checkpointer with fault tolerance support.
|
|
246
|
+
* Tracks pending writes for recovery from mid-step failures.
|
|
247
|
+
*/
|
|
248
|
+
export interface CheckpointerWithPending extends Checkpointer {
|
|
249
|
+
/**
|
|
250
|
+
* Save pending writes (incomplete tool executions)
|
|
251
|
+
*/
|
|
252
|
+
savePending(sessionId: string, writes: PendingWrite[]): Promise<void>;
|
|
253
|
+
/**
|
|
254
|
+
* Load pending writes for a session
|
|
255
|
+
*/
|
|
256
|
+
loadPending(sessionId: string): Promise<PendingWrite[]>;
|
|
257
|
+
/**
|
|
258
|
+
* Clear pending writes (called after step completion)
|
|
259
|
+
*/
|
|
260
|
+
clearPending(sessionId: string): Promise<void>;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Options for resuming an agent from a checkpoint.
|
|
264
|
+
*/
|
|
265
|
+
export interface ResumeOptions {
|
|
266
|
+
/**
|
|
267
|
+
* LLM provider to use
|
|
268
|
+
*/
|
|
269
|
+
provider: unknown;
|
|
270
|
+
/**
|
|
271
|
+
* Checkpointer to load from
|
|
272
|
+
*/
|
|
273
|
+
checkpointer: Checkpointer;
|
|
274
|
+
/**
|
|
275
|
+
* Override saved system prompt
|
|
276
|
+
*/
|
|
277
|
+
systemPrompt?: string;
|
|
278
|
+
/**
|
|
279
|
+
* Override saved tools
|
|
280
|
+
*/
|
|
281
|
+
tools?: unknown[];
|
|
282
|
+
/**
|
|
283
|
+
* Event handler
|
|
284
|
+
*/
|
|
285
|
+
onEvent?: (event: unknown) => void;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Options for creating agent from exported state.
|
|
289
|
+
*/
|
|
290
|
+
export interface FromStateOptions {
|
|
291
|
+
/**
|
|
292
|
+
* LLM provider to use
|
|
293
|
+
*/
|
|
294
|
+
provider: unknown;
|
|
295
|
+
/**
|
|
296
|
+
* Optional checkpointer for subsequent saves
|
|
297
|
+
*/
|
|
298
|
+
checkpointer?: Checkpointer;
|
|
299
|
+
/**
|
|
300
|
+
* Override saved tools
|
|
301
|
+
*/
|
|
302
|
+
tools?: unknown[];
|
|
303
|
+
/**
|
|
304
|
+
* Event handler
|
|
305
|
+
*/
|
|
306
|
+
onEvent?: (event: unknown) => void;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Current schema version for AgentState.
|
|
310
|
+
* Increment when making breaking changes to the schema.
|
|
311
|
+
*/
|
|
312
|
+
export declare const CURRENT_STATE_VERSION = 1;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State Management Types
|
|
3
|
+
*
|
|
4
|
+
* Core types and interfaces for conversation persistence.
|
|
5
|
+
* Inspired by LangGraph's checkpointer pattern.
|
|
6
|
+
*/
|
|
7
|
+
// ============================================================
|
|
8
|
+
// Current State Version
|
|
9
|
+
// ============================================================
|
|
10
|
+
/**
|
|
11
|
+
* Current schema version for AgentState.
|
|
12
|
+
* Increment when making breaking changes to the schema.
|
|
13
|
+
*/
|
|
14
|
+
export const CURRENT_STATE_VERSION = 1;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BashOutput Tool - Retrieve output from background shells
|
|
3
|
+
*/
|
|
4
|
+
import type { Tool } from '../types.js';
|
|
5
|
+
import { type ShellManager } from './shell-manager.js';
|
|
6
|
+
/**
|
|
7
|
+
* Input parameters for bashOutput tool
|
|
8
|
+
*/
|
|
9
|
+
export interface BashOutputInput {
|
|
10
|
+
/**
|
|
11
|
+
* The ID of the background shell to retrieve output from
|
|
12
|
+
*/
|
|
13
|
+
bash_id: string;
|
|
14
|
+
/**
|
|
15
|
+
* Optional regular expression to filter output lines
|
|
16
|
+
* Only lines matching this regex will be included
|
|
17
|
+
*/
|
|
18
|
+
filter?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Result of bashOutput tool
|
|
22
|
+
*/
|
|
23
|
+
export interface BashOutputResult {
|
|
24
|
+
/**
|
|
25
|
+
* Shell ID
|
|
26
|
+
*/
|
|
27
|
+
id: string;
|
|
28
|
+
/**
|
|
29
|
+
* Current status of the shell
|
|
30
|
+
*/
|
|
31
|
+
status: 'running' | 'completed' | 'failed' | 'killed';
|
|
32
|
+
/**
|
|
33
|
+
* Standard output (new since last read)
|
|
34
|
+
*/
|
|
35
|
+
stdout: string;
|
|
36
|
+
/**
|
|
37
|
+
* Standard error (new since last read)
|
|
38
|
+
*/
|
|
39
|
+
stderr: string;
|
|
40
|
+
/**
|
|
41
|
+
* Whether the shell is still running and may produce more output
|
|
42
|
+
*/
|
|
43
|
+
hasMore: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Exit code (if completed)
|
|
46
|
+
*/
|
|
47
|
+
exitCode?: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* BashOutput tool definition
|
|
51
|
+
*/
|
|
52
|
+
export declare const bashOutputTool: Tool<BashOutputInput>;
|
|
53
|
+
/**
|
|
54
|
+
* Factory function to create a bashOutput tool with custom shell manager
|
|
55
|
+
*/
|
|
56
|
+
export declare function createBashOutputTool(options?: {
|
|
57
|
+
/**
|
|
58
|
+
* Custom shell manager to use
|
|
59
|
+
*/
|
|
60
|
+
shellManager?: ShellManager;
|
|
61
|
+
}): Tool<BashOutputInput>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BashOutput Tool - Retrieve output from background shells
|
|
3
|
+
*/
|
|
4
|
+
import { defineTool, createSuccessResult, createErrorResult } from '../define.js';
|
|
5
|
+
import { getDefaultShellManager } from './shell-manager.js';
|
|
6
|
+
/**
|
|
7
|
+
* BashOutput tool definition
|
|
8
|
+
*/
|
|
9
|
+
export const bashOutputTool = defineTool({
|
|
10
|
+
name: 'bash_output',
|
|
11
|
+
description: 'Retrieve output from a running or completed background bash shell. ' +
|
|
12
|
+
'Returns only new output since the last check. ' +
|
|
13
|
+
'Use this to monitor long-running commands started with run_in_background.',
|
|
14
|
+
inputSchema: {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
bash_id: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: 'The ID of the background shell to retrieve output from',
|
|
20
|
+
},
|
|
21
|
+
filter: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
description: 'Optional regular expression to filter output lines. ' +
|
|
24
|
+
'Only lines matching this regex will be included.',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
required: ['bash_id'],
|
|
28
|
+
},
|
|
29
|
+
execute: (input) => {
|
|
30
|
+
const manager = getDefaultShellManager();
|
|
31
|
+
return Promise.resolve(executeBashOutput(input, manager));
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* Execute the bashOutput tool
|
|
36
|
+
*/
|
|
37
|
+
function executeBashOutput(input, manager) {
|
|
38
|
+
const { bash_id, filter } = input;
|
|
39
|
+
// Parse filter regex if provided
|
|
40
|
+
let filterRegex;
|
|
41
|
+
if (filter) {
|
|
42
|
+
try {
|
|
43
|
+
filterRegex = new RegExp(filter);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return createErrorResult(`Invalid filter regex: ${filter}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Get output from shell
|
|
50
|
+
const output = manager.getOutput(bash_id, filterRegex);
|
|
51
|
+
if (!output) {
|
|
52
|
+
return createErrorResult(`Shell '${bash_id}' not found. It may have been cleaned up or never existed.`);
|
|
53
|
+
}
|
|
54
|
+
return createSuccessResult({
|
|
55
|
+
id: output.id,
|
|
56
|
+
status: output.status,
|
|
57
|
+
stdout: output.stdout,
|
|
58
|
+
stderr: output.stderr,
|
|
59
|
+
hasMore: output.hasMore,
|
|
60
|
+
...(output.exitCode !== undefined && { exitCode: output.exitCode }),
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Factory function to create a bashOutput tool with custom shell manager
|
|
65
|
+
*/
|
|
66
|
+
export function createBashOutputTool(options) {
|
|
67
|
+
const manager = options?.shellManager ?? getDefaultShellManager();
|
|
68
|
+
return defineTool({
|
|
69
|
+
name: 'bash_output',
|
|
70
|
+
description: 'Retrieve output from a running or completed background bash shell. ' +
|
|
71
|
+
'Returns only new output since the last check. ' +
|
|
72
|
+
'Use this to monitor long-running commands started with run_in_background.',
|
|
73
|
+
inputSchema: {
|
|
74
|
+
type: 'object',
|
|
75
|
+
properties: {
|
|
76
|
+
bash_id: {
|
|
77
|
+
type: 'string',
|
|
78
|
+
description: 'The ID of the background shell to retrieve output from',
|
|
79
|
+
},
|
|
80
|
+
filter: {
|
|
81
|
+
type: 'string',
|
|
82
|
+
description: 'Optional regular expression to filter output lines. ' +
|
|
83
|
+
'Only lines matching this regex will be included.',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
required: ['bash_id'],
|
|
87
|
+
},
|
|
88
|
+
execute: (input) => Promise.resolve(executeBashOutput(input, manager)),
|
|
89
|
+
});
|
|
90
|
+
}
|