@providerprotocol/agents 0.0.2 → 0.0.4
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/LICENSE +21 -0
- package/dist/checkpoint/index.d.ts +43 -0
- package/dist/checkpoint/index.js +73 -0
- package/dist/checkpoint/index.js.map +1 -0
- package/{src/execution/loop.ts → dist/chunk-4ESYN66B.js} +54 -162
- package/dist/chunk-4ESYN66B.js.map +1 -0
- package/dist/chunk-EKRXMSDX.js +8 -0
- package/dist/chunk-EKRXMSDX.js.map +1 -0
- package/dist/chunk-T47B3VAF.js +427 -0
- package/dist/chunk-T47B3VAF.js.map +1 -0
- package/dist/execution/index.d.ts +105 -0
- package/dist/execution/index.js +679 -0
- package/dist/execution/index.js.map +1 -0
- package/dist/index-qsPwbY86.d.ts +65 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.js +218 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/index.d.ts +23 -0
- package/dist/middleware/index.js +82 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/thread-tree/index.d.ts +115 -0
- package/dist/thread-tree/index.js +4 -0
- package/dist/thread-tree/index.js.map +1 -0
- package/dist/types-2Vsthzyu.d.ts +163 -0
- package/dist/types-BiyEVOnf.d.ts +65 -0
- package/dist/types-D1egxttz.d.ts +270 -0
- package/dist/types-DChRdQoX.d.ts +98 -0
- package/package.json +41 -9
- package/.claude/settings.local.json +0 -29
- package/AGENTS.md +0 -681
- package/CLAUDE.md +0 -681
- package/bun.lock +0 -472
- package/eslint.config.js +0 -75
- package/index.ts +0 -1
- package/llms.md +0 -796
- package/specs/UAP-1.0.md +0 -2355
- package/src/agent/index.ts +0 -384
- package/src/agent/types.ts +0 -91
- package/src/checkpoint/file.ts +0 -126
- package/src/checkpoint/index.ts +0 -40
- package/src/checkpoint/types.ts +0 -95
- package/src/execution/index.ts +0 -37
- package/src/execution/plan.ts +0 -497
- package/src/execution/react.ts +0 -340
- package/src/execution/tool-ordering.ts +0 -186
- package/src/execution/types.ts +0 -315
- package/src/index.ts +0 -80
- package/src/middleware/index.ts +0 -7
- package/src/middleware/logging.ts +0 -123
- package/src/middleware/types.ts +0 -69
- package/src/state/index.ts +0 -301
- package/src/state/types.ts +0 -173
- package/src/thread-tree/index.ts +0 -249
- package/src/thread-tree/types.ts +0 -29
- package/src/utils/uuid.ts +0 -7
- package/tests/live/agent-anthropic.test.ts +0 -288
- package/tests/live/agent-strategy-hooks.test.ts +0 -268
- package/tests/live/checkpoint.test.ts +0 -243
- package/tests/live/execution-strategies.test.ts +0 -255
- package/tests/live/plan-strategy.test.ts +0 -160
- package/tests/live/subagent-events.live.test.ts +0 -249
- package/tests/live/thread-tree.test.ts +0 -186
- package/tests/unit/agent.test.ts +0 -703
- package/tests/unit/checkpoint.test.ts +0 -232
- package/tests/unit/execution/equivalence.test.ts +0 -402
- package/tests/unit/execution/loop.test.ts +0 -437
- package/tests/unit/execution/plan.test.ts +0 -590
- package/tests/unit/execution/react.test.ts +0 -604
- package/tests/unit/execution/subagent-events.test.ts +0 -235
- package/tests/unit/execution/tool-ordering.test.ts +0 -310
- package/tests/unit/middleware/logging.test.ts +0 -276
- package/tests/unit/state.test.ts +0 -573
- package/tests/unit/thread-tree.test.ts +0 -249
- package/tsconfig.json +0 -29
package/src/execution/types.ts
DELETED
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
LLMInstance,
|
|
3
|
-
Message,
|
|
4
|
-
Tool,
|
|
5
|
-
Turn,
|
|
6
|
-
ToolCall,
|
|
7
|
-
ToolExecution,
|
|
8
|
-
StreamEvent,
|
|
9
|
-
TokenUsage,
|
|
10
|
-
} from '@providerprotocol/ai';
|
|
11
|
-
import type { AgentState, PlanStep } from '../state/index.ts';
|
|
12
|
-
import type { CheckpointStore } from '../checkpoint/types.ts';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Result of agent generation.
|
|
16
|
-
*/
|
|
17
|
-
export interface GenerateResult {
|
|
18
|
-
/** Standard UPP Turn */
|
|
19
|
-
turn: Turn;
|
|
20
|
-
/** New immutable state */
|
|
21
|
-
state: AgentState;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Agent lifecycle hooks for execution control.
|
|
26
|
-
*/
|
|
27
|
-
export interface AgentStrategy {
|
|
28
|
-
/** Evaluate if execution should stop */
|
|
29
|
-
stopCondition?: (state: AgentState) => boolean | Promise<boolean>;
|
|
30
|
-
/** Called when step begins */
|
|
31
|
-
onStepStart?: (step: number, state: AgentState) => void;
|
|
32
|
-
/** Called during reasoning phase (ReAct) */
|
|
33
|
-
onReason?: (step: number, reasoning: string) => void;
|
|
34
|
-
/** Called during action phase */
|
|
35
|
-
onAct?: (step: number, actions: ToolCall[]) => void;
|
|
36
|
-
/** Called during observation phase */
|
|
37
|
-
onObserve?: (step: number, observations: ToolExecution[]) => void;
|
|
38
|
-
/** Called when step completes */
|
|
39
|
-
onStepEnd?: (step: number, result: { turn: Turn; state: AgentState }) => void;
|
|
40
|
-
/** Called when execution completes */
|
|
41
|
-
onComplete?: (result: GenerateResult) => void;
|
|
42
|
-
/** Called on execution error */
|
|
43
|
-
onError?: (error: Error, state: AgentState) => void | GenerateResult;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Forward declaration of Agent for use in ExecutionContext.
|
|
48
|
-
* The actual Agent interface is defined in agent/types.ts.
|
|
49
|
-
*/
|
|
50
|
-
export interface AgentRef {
|
|
51
|
-
id: string;
|
|
52
|
-
system?: string;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Context passed to execution strategies.
|
|
57
|
-
*/
|
|
58
|
-
export interface ExecutionContext {
|
|
59
|
-
/** The agent being executed */
|
|
60
|
-
agent: AgentRef;
|
|
61
|
-
/** The bound LLM instance */
|
|
62
|
-
llm: LLMInstance;
|
|
63
|
-
/** The user input message */
|
|
64
|
-
input: Message;
|
|
65
|
-
/** Current immutable state */
|
|
66
|
-
state: AgentState;
|
|
67
|
-
/** Resolved tools */
|
|
68
|
-
tools: Tool[];
|
|
69
|
-
/** Agent lifecycle hooks */
|
|
70
|
-
strategy: AgentStrategy;
|
|
71
|
-
/** Abort signal for cancellation */
|
|
72
|
-
signal?: AbortSignal;
|
|
73
|
-
/** Checkpoint store for persistence (optional) */
|
|
74
|
-
checkpoints?: CheckpointStore;
|
|
75
|
-
/** Session ID for checkpointing */
|
|
76
|
-
sessionId?: string;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Result from execution strategy.
|
|
81
|
-
*/
|
|
82
|
-
export interface ExecutionResult {
|
|
83
|
-
/** The complete UPP Turn */
|
|
84
|
-
turn: Turn;
|
|
85
|
-
/** New immutable state */
|
|
86
|
-
state: AgentState;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* UAP-level event types for streaming.
|
|
91
|
-
*/
|
|
92
|
-
export type UAPEventType =
|
|
93
|
-
| 'step_start'
|
|
94
|
-
| 'step_end'
|
|
95
|
-
| 'reasoning'
|
|
96
|
-
| 'action'
|
|
97
|
-
| 'observation'
|
|
98
|
-
| 'plan_created'
|
|
99
|
-
| 'plan_step_start'
|
|
100
|
-
| 'plan_step_end'
|
|
101
|
-
| 'subagent_start'
|
|
102
|
-
| 'subagent_event'
|
|
103
|
-
| 'subagent_end';
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Agent stream event - wraps both UAP and UPP events.
|
|
107
|
-
*/
|
|
108
|
-
export interface AgentStreamEvent {
|
|
109
|
-
/** Event source */
|
|
110
|
-
source: 'uap' | 'upp';
|
|
111
|
-
|
|
112
|
-
/** Present when source === 'uap' */
|
|
113
|
-
uap?: {
|
|
114
|
-
type: UAPEventType;
|
|
115
|
-
step: number;
|
|
116
|
-
agentId: string;
|
|
117
|
-
data: Record<string, unknown>;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
/** Present when source === 'upp' */
|
|
121
|
-
upp?: StreamEvent;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Streaming result from agent execution.
|
|
126
|
-
*/
|
|
127
|
-
export interface AgentStreamResult {
|
|
128
|
-
/** Async iterator for stream events */
|
|
129
|
-
[Symbol.asyncIterator](): AsyncIterator<AgentStreamEvent>;
|
|
130
|
-
/** Resolves to final result after stream completes */
|
|
131
|
-
result: Promise<GenerateResult>;
|
|
132
|
-
/** Abort the stream */
|
|
133
|
-
abort(): void;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Execution strategy interface.
|
|
138
|
-
* Strategies define HOW an agent executes (loop, react, plan).
|
|
139
|
-
*/
|
|
140
|
-
export interface ExecutionStrategy {
|
|
141
|
-
/** Strategy name */
|
|
142
|
-
name: string;
|
|
143
|
-
/** Execute the strategy */
|
|
144
|
-
execute(context: ExecutionContext): Promise<ExecutionResult>;
|
|
145
|
-
/** Execute with streaming */
|
|
146
|
-
stream(context: ExecutionContext): AgentStreamResult;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Options for loop() strategy.
|
|
151
|
-
*/
|
|
152
|
-
export interface LoopOptions {
|
|
153
|
-
/** Maximum tool execution rounds. Default: Infinity */
|
|
154
|
-
maxIterations?: number;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Options for react() strategy.
|
|
159
|
-
*/
|
|
160
|
-
export interface ReactOptions {
|
|
161
|
-
/** Maximum reason-act-observe cycles. Default: Infinity */
|
|
162
|
-
maxSteps?: number;
|
|
163
|
-
/** Prompt suffix for reasoning phase */
|
|
164
|
-
reasoningPrompt?: string;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Options for plan() strategy.
|
|
169
|
-
*/
|
|
170
|
-
export interface PlanOptions {
|
|
171
|
-
/** Maximum steps in a plan. Default: Infinity */
|
|
172
|
-
maxPlanSteps?: number;
|
|
173
|
-
/** Allow replanning on failure. Default: true */
|
|
174
|
-
allowReplan?: boolean;
|
|
175
|
-
/** Schema for plan structure */
|
|
176
|
-
planSchema?: Record<string, unknown>;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Internal plan structure used by plan() strategy.
|
|
181
|
-
*/
|
|
182
|
-
export interface ExecutionPlan {
|
|
183
|
-
steps: PlanStep[];
|
|
184
|
-
currentStepIndex: number;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Tool dependency options for execution ordering.
|
|
189
|
-
* These extend the base UPP Tool interface with UAP-specific fields.
|
|
190
|
-
*
|
|
191
|
-
* @see UAP-1.0 Spec Section 8.5
|
|
192
|
-
*/
|
|
193
|
-
export interface ToolDependencyOptions {
|
|
194
|
-
/**
|
|
195
|
-
* If true, this tool must complete before other tools start.
|
|
196
|
-
* Sequential tools create a barrier in parallel execution.
|
|
197
|
-
*/
|
|
198
|
-
sequential?: boolean;
|
|
199
|
-
/**
|
|
200
|
-
* Tool names that must complete before this tool can execute.
|
|
201
|
-
* Used for explicit dependency chains.
|
|
202
|
-
*/
|
|
203
|
-
dependsOn?: string[];
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Extended Tool interface with UAP dependency options.
|
|
208
|
-
* Use this type when defining tools that need execution ordering.
|
|
209
|
-
*
|
|
210
|
-
* @example
|
|
211
|
-
* ```typescript
|
|
212
|
-
* const readTool: ToolWithDependencies = {
|
|
213
|
-
* name: 'read_file',
|
|
214
|
-
* description: 'Read a file',
|
|
215
|
-
* parameters: { ... },
|
|
216
|
-
* sequential: true, // Must complete before other tools
|
|
217
|
-
* run: async (params) => { ... },
|
|
218
|
-
* };
|
|
219
|
-
*
|
|
220
|
-
* const writeTool: ToolWithDependencies = {
|
|
221
|
-
* name: 'write_file',
|
|
222
|
-
* description: 'Write a file',
|
|
223
|
-
* parameters: { ... },
|
|
224
|
-
* dependsOn: ['read_file'], // Waits for read_file to complete
|
|
225
|
-
* run: async (params) => { ... },
|
|
226
|
-
* };
|
|
227
|
-
* ```
|
|
228
|
-
*/
|
|
229
|
-
export interface ToolWithDependencies extends Tool, ToolDependencyOptions {}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Model-driven tool call with optional execution order hint.
|
|
233
|
-
* Models MAY include an `after` field to signal dependencies.
|
|
234
|
-
*
|
|
235
|
-
* @see UAP-1.0 Spec Section 8.6
|
|
236
|
-
*/
|
|
237
|
-
export interface OrderedToolCall extends ToolCall {
|
|
238
|
-
/** Tool call IDs that must complete before this call executes */
|
|
239
|
-
after?: string[];
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Sub-agent event types for hierarchical agent execution.
|
|
244
|
-
*
|
|
245
|
-
* @see UAP-1.0 Spec Section 8.7
|
|
246
|
-
*/
|
|
247
|
-
export type SubagentEventType = 'subagent_start' | 'subagent_event' | 'subagent_end';
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Base fields present in all subagent events.
|
|
251
|
-
*/
|
|
252
|
-
export interface SubagentEventBase {
|
|
253
|
-
/** Unique ID of the sub-agent instance */
|
|
254
|
-
subagentId: string;
|
|
255
|
-
/** Type/name of the sub-agent (e.g., "explorer", "planner") */
|
|
256
|
-
subagentType: string;
|
|
257
|
-
/** The parent tool call ID that spawned this sub-agent */
|
|
258
|
-
parentToolCallId: string;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Event emitted when a sub-agent starts execution.
|
|
263
|
-
*/
|
|
264
|
-
export interface SubagentStartEvent extends SubagentEventBase {
|
|
265
|
-
type: 'subagent_start';
|
|
266
|
-
/** The task/prompt given to the sub-agent */
|
|
267
|
-
prompt: string;
|
|
268
|
-
/** Start timestamp in milliseconds */
|
|
269
|
-
timestamp: number;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Event emitted for forwarded events from sub-agent execution.
|
|
274
|
-
*/
|
|
275
|
-
export interface SubagentInnerEvent extends SubagentEventBase {
|
|
276
|
-
type: 'subagent_event';
|
|
277
|
-
/** The actual event from the sub-agent */
|
|
278
|
-
innerEvent: AgentStreamEvent;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Event emitted when a sub-agent completes execution.
|
|
283
|
-
*/
|
|
284
|
-
export interface SubagentEndEvent extends SubagentEventBase {
|
|
285
|
-
type: 'subagent_end';
|
|
286
|
-
/** Whether the sub-agent completed successfully */
|
|
287
|
-
success: boolean;
|
|
288
|
-
/** Sub-agent's response text (if successful) */
|
|
289
|
-
result?: string;
|
|
290
|
-
/** Error message (if failed) */
|
|
291
|
-
error?: string;
|
|
292
|
-
/** End timestamp in milliseconds */
|
|
293
|
-
timestamp: number;
|
|
294
|
-
/** Tools used by the sub-agent */
|
|
295
|
-
toolExecutions?: Array<{
|
|
296
|
-
toolName: string;
|
|
297
|
-
arguments: Record<string, unknown>;
|
|
298
|
-
result: string;
|
|
299
|
-
}>;
|
|
300
|
-
/** Token usage for this sub-agent run */
|
|
301
|
-
usage?: TokenUsage;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Union type for all sub-agent events.
|
|
306
|
-
*
|
|
307
|
-
* @see UAP-1.0 Spec Section 8.7
|
|
308
|
-
*/
|
|
309
|
-
export type SubagentEvent = SubagentStartEvent | SubagentInnerEvent | SubagentEndEvent;
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Callback type for receiving sub-agent events.
|
|
313
|
-
* Tools that spawn sub-agents SHOULD accept this callback.
|
|
314
|
-
*/
|
|
315
|
-
export type OnSubagentEvent = (event: SubagentEvent) => void;
|
package/src/index.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @providerprotocol/agents - Unified Agent Protocol (UAP) 1.0 Implementation
|
|
3
|
-
*
|
|
4
|
-
* UAP provides agent abstractions built on @providerprotocol/ai (UPP-1.2):
|
|
5
|
-
* - Functional state management with immutable AgentState
|
|
6
|
-
* - Decoupled execution strategies (loop, react, plan)
|
|
7
|
-
* - Middleware pipeline for cross-cutting concerns
|
|
8
|
-
* - Thread trees for branching conversations
|
|
9
|
-
*
|
|
10
|
-
* Core Philosophy: "UAP is a pipe, not a nanny."
|
|
11
|
-
* The protocol provides orchestration primitives; the developer provides the constraints.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```typescript
|
|
15
|
-
* import { agent, AgentState } from '@providerprotocol/agents';
|
|
16
|
-
* import { react } from '@providerprotocol/agents/execution';
|
|
17
|
-
* import { logging } from '@providerprotocol/agents/middleware';
|
|
18
|
-
* import { anthropic } from '@providerprotocol/ai/anthropic';
|
|
19
|
-
*
|
|
20
|
-
* const coder = agent({
|
|
21
|
-
* model: anthropic('claude-sonnet-4-20250514'),
|
|
22
|
-
* execution: react(),
|
|
23
|
-
* tools: [Bash, Read, Write],
|
|
24
|
-
* system: 'You are an expert software engineer.',
|
|
25
|
-
* middleware: [logging({ level: 'info' })],
|
|
26
|
-
* });
|
|
27
|
-
*
|
|
28
|
-
* const state = AgentState.initial();
|
|
29
|
-
* const { turn, state: newState } = await coder.generate('Fix the bug', state);
|
|
30
|
-
* console.log(turn.response.text);
|
|
31
|
-
* ```
|
|
32
|
-
*
|
|
33
|
-
* @packageDocumentation
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
// Main exports
|
|
37
|
-
export { agent } from './agent/index.ts';
|
|
38
|
-
export { AgentState } from './state/index.ts';
|
|
39
|
-
|
|
40
|
-
// Type exports from agent
|
|
41
|
-
export type {
|
|
42
|
-
Agent,
|
|
43
|
-
AgentOptions,
|
|
44
|
-
GenerateResult,
|
|
45
|
-
AgentStreamResult,
|
|
46
|
-
AgentStreamEvent,
|
|
47
|
-
UAPEventType,
|
|
48
|
-
AgentStrategy,
|
|
49
|
-
// Sub-agent event types (Section 8.7)
|
|
50
|
-
SubagentEventType,
|
|
51
|
-
SubagentEventBase,
|
|
52
|
-
SubagentStartEvent,
|
|
53
|
-
SubagentInnerEvent,
|
|
54
|
-
SubagentEndEvent,
|
|
55
|
-
SubagentEvent,
|
|
56
|
-
OnSubagentEvent,
|
|
57
|
-
} from './agent/index.ts';
|
|
58
|
-
|
|
59
|
-
// Type exports from state
|
|
60
|
-
export type {
|
|
61
|
-
AgentStateInterface,
|
|
62
|
-
AgentStateJSON,
|
|
63
|
-
PlanStep,
|
|
64
|
-
PlanStepStatus,
|
|
65
|
-
SubagentExecutionTrace,
|
|
66
|
-
SubagentExecutionTraceJSON,
|
|
67
|
-
ToolExecutionTrace,
|
|
68
|
-
} from './state/index.ts';
|
|
69
|
-
|
|
70
|
-
// Thread tree exports (Level 3 - optional)
|
|
71
|
-
export { ThreadTree, ThreadNode } from './thread-tree/index.ts';
|
|
72
|
-
export type { ThreadTreeJSON, ThreadNodeJSON } from './thread-tree/index.ts';
|
|
73
|
-
|
|
74
|
-
// Checkpoint exports (Section 12.4)
|
|
75
|
-
export type {
|
|
76
|
-
CheckpointStore,
|
|
77
|
-
FileCheckpointOptions,
|
|
78
|
-
CheckpointMetadata,
|
|
79
|
-
CheckpointData,
|
|
80
|
-
} from './checkpoint/index.ts';
|
package/src/middleware/index.ts
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import type { Middleware, LoggingOptions, MiddlewareContext } from './types.ts';
|
|
2
|
-
import type { GenerateResult } from '../execution/types.ts';
|
|
3
|
-
|
|
4
|
-
const DEFAULT_LOGGING_OPTIONS: Required<LoggingOptions> = {
|
|
5
|
-
level: 'info',
|
|
6
|
-
logger: console.log,
|
|
7
|
-
includeMessages: false,
|
|
8
|
-
includeTiming: true,
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const LOG_LEVELS = {
|
|
12
|
-
debug: 0,
|
|
13
|
-
info: 1,
|
|
14
|
-
warn: 2,
|
|
15
|
-
error: 3,
|
|
16
|
-
} as const;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Create a logging middleware.
|
|
20
|
-
*
|
|
21
|
-
* Logs agent execution with configurable detail level:
|
|
22
|
-
* - Execution start/end
|
|
23
|
-
* - Timing information (if enabled)
|
|
24
|
-
* - Message content (if enabled)
|
|
25
|
-
* - Errors
|
|
26
|
-
*
|
|
27
|
-
* @param options - Logging configuration options
|
|
28
|
-
* @returns Middleware
|
|
29
|
-
*/
|
|
30
|
-
export function logging(options: LoggingOptions = {}): Middleware {
|
|
31
|
-
const opts = { ...DEFAULT_LOGGING_OPTIONS, ...options };
|
|
32
|
-
const currentLevel = LOG_LEVELS[opts.level];
|
|
33
|
-
|
|
34
|
-
function shouldLog(level: keyof typeof LOG_LEVELS): boolean {
|
|
35
|
-
return LOG_LEVELS[level] >= currentLevel;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function log(level: keyof typeof LOG_LEVELS, message: string): void {
|
|
39
|
-
if (shouldLog(level)) {
|
|
40
|
-
const prefix = `[UAP:${level.toUpperCase()}]`;
|
|
41
|
-
opts.logger(`${prefix} ${message}`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function formatContext(context: MiddlewareContext): string {
|
|
46
|
-
const parts = [`agent=${context.agent.id}`];
|
|
47
|
-
|
|
48
|
-
if (opts.includeMessages) {
|
|
49
|
-
parts.push(`messages=${context.state.messages.length}`);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return parts.join(' ');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return {
|
|
56
|
-
name: 'logging',
|
|
57
|
-
|
|
58
|
-
async before(context: MiddlewareContext): Promise<MiddlewareContext | void> {
|
|
59
|
-
log('info', `Execution started: ${formatContext(context)}`);
|
|
60
|
-
|
|
61
|
-
if (opts.includeTiming) {
|
|
62
|
-
context.metadata.set('_logging_startTime', Date.now());
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (opts.includeMessages && shouldLog('debug')) {
|
|
66
|
-
log('debug', `Input: ${JSON.stringify(context.input)}`);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return context;
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
async after(
|
|
73
|
-
context: MiddlewareContext,
|
|
74
|
-
result: GenerateResult,
|
|
75
|
-
): Promise<GenerateResult> {
|
|
76
|
-
let message = 'Execution completed';
|
|
77
|
-
|
|
78
|
-
if (opts.includeTiming) {
|
|
79
|
-
const startTime = context.metadata.get('_logging_startTime') as number | undefined;
|
|
80
|
-
if (startTime) {
|
|
81
|
-
const duration = Date.now() - startTime;
|
|
82
|
-
message += ` in ${duration}ms`;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
message += `: ${formatContext(context)}`;
|
|
87
|
-
|
|
88
|
-
if (result.turn.usage) {
|
|
89
|
-
message += ` tokens=${result.turn.usage.totalTokens}`;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
log('info', message);
|
|
93
|
-
|
|
94
|
-
if (opts.includeMessages && shouldLog('debug')) {
|
|
95
|
-
log('debug', `Response: ${result.turn.response.text.substring(0, 200)}...`);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return result;
|
|
99
|
-
},
|
|
100
|
-
|
|
101
|
-
async onError(
|
|
102
|
-
context: MiddlewareContext,
|
|
103
|
-
error: Error,
|
|
104
|
-
): Promise<GenerateResult | void> {
|
|
105
|
-
let message = `Execution failed: ${error.message}`;
|
|
106
|
-
|
|
107
|
-
if (opts.includeTiming) {
|
|
108
|
-
const startTime = context.metadata.get('_logging_startTime') as number | undefined;
|
|
109
|
-
if (startTime) {
|
|
110
|
-
const duration = Date.now() - startTime;
|
|
111
|
-
message += ` after ${duration}ms`;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
message += `: ${formatContext(context)}`;
|
|
116
|
-
|
|
117
|
-
log('error', message);
|
|
118
|
-
|
|
119
|
-
// Let the error propagate
|
|
120
|
-
return undefined;
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
}
|
package/src/middleware/types.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import type { Message } from '@providerprotocol/ai';
|
|
2
|
-
import type { AgentState } from '../state/index.ts';
|
|
3
|
-
import type { GenerateResult } from '../execution/types.ts';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Forward declaration of Agent for use in MiddlewareContext.
|
|
7
|
-
*/
|
|
8
|
-
export interface AgentRef {
|
|
9
|
-
id: string;
|
|
10
|
-
system?: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Context passed to middleware functions.
|
|
15
|
-
*/
|
|
16
|
-
export interface MiddlewareContext {
|
|
17
|
-
/** The agent being executed */
|
|
18
|
-
agent: AgentRef;
|
|
19
|
-
/** User input message */
|
|
20
|
-
input: Message;
|
|
21
|
-
/** Current state */
|
|
22
|
-
state: AgentState;
|
|
23
|
-
/** Request metadata (mutable within middleware) */
|
|
24
|
-
metadata: Map<string, unknown>;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Middleware interface for cross-cutting concerns.
|
|
29
|
-
*
|
|
30
|
-
* Middleware executes in order for `before`, reverse order for `after`:
|
|
31
|
-
* - before: first -> second -> third
|
|
32
|
-
* - after: third -> second -> first
|
|
33
|
-
*/
|
|
34
|
-
export interface Middleware {
|
|
35
|
-
/** Middleware name */
|
|
36
|
-
name: string;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Called before agent execution.
|
|
40
|
-
* Can modify context or short-circuit by returning a modified context.
|
|
41
|
-
*/
|
|
42
|
-
before?(context: MiddlewareContext): Promise<MiddlewareContext | void>;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Called after agent execution.
|
|
46
|
-
* Can modify the result before returning.
|
|
47
|
-
*/
|
|
48
|
-
after?(context: MiddlewareContext, result: GenerateResult): Promise<GenerateResult>;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Called when an error occurs during execution.
|
|
52
|
-
* Can return a result to recover, or void to let the error propagate.
|
|
53
|
-
*/
|
|
54
|
-
onError?(context: MiddlewareContext, error: Error): Promise<GenerateResult | void>;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Options for the logging middleware.
|
|
59
|
-
*/
|
|
60
|
-
export interface LoggingOptions {
|
|
61
|
-
/** Log level. Default: 'info' */
|
|
62
|
-
level?: 'debug' | 'info' | 'warn' | 'error';
|
|
63
|
-
/** Custom logger function. Default: console.log */
|
|
64
|
-
logger?: (message: string) => void;
|
|
65
|
-
/** Include full message content. Default: false */
|
|
66
|
-
includeMessages?: boolean;
|
|
67
|
-
/** Include execution timing. Default: true */
|
|
68
|
-
includeTiming?: boolean;
|
|
69
|
-
}
|