@looopy-ai/core 1.2.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,156 @@
1
+ import { consumeSSEStream } from '@geee-be/sse-stream-parser';
2
+ import { Observable } from 'rxjs';
3
+ import z from 'zod';
4
+ import { getLogger } from '../core';
5
+ import { toolErrorEvent } from './tool-result-events';
6
+ const cardSchema = z.object({
7
+ name: z.string(),
8
+ description: z.string().optional(),
9
+ url: z.url(),
10
+ icon: z.string().optional(),
11
+ skills: z
12
+ .array(z.object({
13
+ name: z.string(),
14
+ description: z.string().optional(),
15
+ }))
16
+ .optional(),
17
+ auth: z
18
+ .object({
19
+ issuer: z.string(),
20
+ audience: z.string(),
21
+ scopes: z.array(z.string()),
22
+ })
23
+ .optional(),
24
+ });
25
+ const safeName = (name) => name.replace(/[^a-zA-Z0-9-]+/g, '-').toLowerCase();
26
+ export class AgentToolProvider {
27
+ card;
28
+ getHeaders;
29
+ static fromUrl = (cardUrl, getHeaders) => {
30
+ return fetch(cardUrl)
31
+ .then((response) => response.json())
32
+ .then((card) => {
33
+ return AgentToolProvider.from(card, getHeaders);
34
+ });
35
+ };
36
+ static from = (card, getHeaders) => {
37
+ const parsed = cardSchema.parse(card);
38
+ return new AgentToolProvider(parsed, getHeaders);
39
+ };
40
+ agentName;
41
+ name;
42
+ tools;
43
+ logger;
44
+ constructor(card, getHeaders) {
45
+ this.card = card;
46
+ this.getHeaders = getHeaders;
47
+ this.agentName = safeName(card.name);
48
+ this.name = `agent__${this.agentName}`;
49
+ this.logger = getLogger({ component: 'agent-tool-provider', agentName: this.agentName });
50
+ this.tools = [
51
+ {
52
+ name: `${this.name}__invoke`,
53
+ description: `Invoke the ${card.name} agent.\n\n${card.description}` ||
54
+ `Invoke the ${card.name} agent`,
55
+ icon: card.icon,
56
+ parameters: {
57
+ type: 'object',
58
+ properties: {
59
+ prompt: {
60
+ type: 'string',
61
+ description: 'The prompt to send to the agent. This will call or invoke the agent sending this prompt as the input. This will start or continue a conversation "turn" with this agent. Example: "What is the weather today?"',
62
+ },
63
+ },
64
+ additionalProperties: false,
65
+ },
66
+ },
67
+ ];
68
+ }
69
+ getTool(toolName) {
70
+ const tool = this.tools.find((t) => t.name === toolName);
71
+ return Promise.resolve(tool);
72
+ }
73
+ getTools() {
74
+ return Promise.resolve(this.tools);
75
+ }
76
+ execute(toolCall, context) {
77
+ this.logger.debug({ toolCallId: toolCall.id, toolName: toolCall.function.name }, 'Executing agent tool call');
78
+ return new Observable((subscriber) => {
79
+ const abortController = new AbortController();
80
+ const run = async () => {
81
+ const tool = await this.getTool(toolCall.function.name);
82
+ if (!tool) {
83
+ this.logger.error({ toolName: toolCall.function.name }, 'Tool not found');
84
+ subscriber.next(toolErrorEvent(context, toolCall, `Tool not found: ${toolCall.function.name}`));
85
+ subscriber.complete();
86
+ return;
87
+ }
88
+ const prompt = toolCall.function.arguments.prompt;
89
+ if (!prompt || typeof prompt !== 'string') {
90
+ this.logger.error('Invalid tool call arguments');
91
+ subscriber.next(toolErrorEvent(context, toolCall, 'Tool argument must include "prompt" and it must be a string'));
92
+ subscriber.complete();
93
+ return;
94
+ }
95
+ const res = await fetch(`${this.card.url}/invocations?qualifier=DEFAULT`, {
96
+ method: 'POST',
97
+ headers: {
98
+ Accept: 'text/event-stream',
99
+ 'X-Amzn-Bedrock-AgentCore-Runtime-Session-Id': context.contextId,
100
+ ...(await this.getHeaders?.(context)),
101
+ },
102
+ body: JSON.stringify({ prompt }),
103
+ signal: abortController.signal,
104
+ });
105
+ if (!res.ok) {
106
+ this.logger.error({ status: res.status, statusText: res.statusText }, 'Agent call failed');
107
+ subscriber.next(toolErrorEvent(context, toolCall, `Agent endpoint responded with ${res.status} ${res.statusText}`));
108
+ subscriber.complete();
109
+ return;
110
+ }
111
+ const body = res.body;
112
+ if (!body) {
113
+ this.logger.error('Agent response has no body');
114
+ subscriber.next(toolErrorEvent(context, toolCall, 'Agent returned no response body'));
115
+ subscriber.complete();
116
+ return;
117
+ }
118
+ await consumeSSEStream(body, (e) => {
119
+ if (subscriber.closed)
120
+ return;
121
+ subscriber.next({
122
+ kind: e.event,
123
+ parentTaskId: context.taskId,
124
+ ...JSON.parse(e.data),
125
+ });
126
+ this.logger.debug({ event: e.event }, 'Received SSE event');
127
+ }, () => {
128
+ if (!subscriber.closed) {
129
+ const toolCompleteEvent = {
130
+ kind: 'tool-complete',
131
+ contextId: context.contextId,
132
+ taskId: context.taskId,
133
+ toolCallId: toolCall.id,
134
+ toolName: toolCall.function.name,
135
+ success: true,
136
+ result: 'Complete',
137
+ timestamp: new Date().toISOString(),
138
+ };
139
+ subscriber.next(toolCompleteEvent);
140
+ subscriber.complete();
141
+ this.logger.debug('Tool execution complete');
142
+ }
143
+ });
144
+ };
145
+ run().catch((err) => {
146
+ this.logger.error({ err }, 'Tool execution error');
147
+ if (!subscriber.closed) {
148
+ subscriber.error(err);
149
+ }
150
+ });
151
+ return () => {
152
+ abortController.abort();
153
+ };
154
+ });
155
+ }
156
+ }
@@ -11,7 +11,7 @@ export declare class ClientToolProvider implements ToolProvider {
11
11
  private readonly onInputRequired;
12
12
  constructor(config: ClientToolConfig);
13
13
  getTools(): Promise<ToolDefinition[]>;
14
- execute(toolCall: ToolCall, context: ExecutionContext): Promise<ToolResult>;
14
+ execute(toolCall: ToolCall, context: ExecutionContext): import("rxjs").Observable<import("..").ContextAnyEvent | import("..").ContextEvent<import("..").ToolCompleteEvent>>;
15
15
  getTool(name: string): Promise<ToolDefinition | undefined>;
16
16
  validateToolArguments(toolCall: ToolCall): Promise<{
17
17
  valid: boolean;
@@ -1,4 +1,6 @@
1
+ import { catchError, defer, mergeMap, of } from 'rxjs';
1
2
  import { validateToolDefinitions, } from '../types/tools';
3
+ import { toolErrorEvent, toolResultToEvents } from './tool-result-events';
2
4
  export class ClientToolProvider {
3
5
  name = 'client-tool-provider';
4
6
  tools;
@@ -25,39 +27,42 @@ export class ClientToolProvider {
25
27
  async getTools() {
26
28
  return [...this.tools];
27
29
  }
28
- async execute(toolCall, context) {
29
- const tool = await this.getTool(toolCall.function.name);
30
- if (!tool) {
31
- return {
32
- toolCallId: toolCall.id,
33
- toolName: toolCall.function.name,
34
- success: false,
35
- result: null,
36
- error: `Tool ${toolCall.function.name} not found in client tools`,
37
- };
38
- }
39
- try {
40
- if (typeof toolCall.function.arguments !== 'object' || toolCall.function.arguments === null) {
30
+ execute(toolCall, context) {
31
+ return defer(async () => {
32
+ const tool = await this.getTool(toolCall.function.name);
33
+ if (!tool) {
41
34
  return {
42
35
  toolCallId: toolCall.id,
43
36
  toolName: toolCall.function.name,
44
37
  success: false,
45
38
  result: null,
46
- error: `Invalid tool arguments: must be an object.`,
39
+ error: `Tool ${toolCall.function.name} not found in client tools`,
47
40
  };
48
41
  }
49
- const result = await this.onInputRequired(toolCall, context);
50
- return result;
51
- }
52
- catch (error) {
53
- return {
54
- toolCallId: toolCall.id,
55
- toolName: toolCall.function.name,
56
- success: false,
57
- result: null,
58
- error: error instanceof Error ? error.message : String(error),
59
- };
60
- }
42
+ try {
43
+ if (typeof toolCall.function.arguments !== 'object' ||
44
+ toolCall.function.arguments === null) {
45
+ return {
46
+ toolCallId: toolCall.id,
47
+ toolName: toolCall.function.name,
48
+ success: false,
49
+ result: null,
50
+ error: `Invalid tool arguments: must be an object.`,
51
+ };
52
+ }
53
+ const result = await this.onInputRequired(toolCall, context);
54
+ return result;
55
+ }
56
+ catch (error) {
57
+ return {
58
+ toolCallId: toolCall.id,
59
+ toolName: toolCall.function.name,
60
+ success: false,
61
+ result: null,
62
+ error: error instanceof Error ? error.message : String(error),
63
+ };
64
+ }
65
+ }).pipe(mergeMap((result) => toolResultToEvents(context, toolCall, result)), catchError((error) => of(toolErrorEvent(context, toolCall, error instanceof Error ? error.message : String(error)))));
61
66
  }
62
67
  async getTool(name) {
63
68
  return this.tools.find((t) => t.name === name);
@@ -1,4 +1,6 @@
1
+ export * from './agent-tool-provider';
1
2
  export * from './artifact-tools';
2
3
  export * from './client-tool-provider';
3
4
  export * from './local-tools';
4
5
  export * from './mcp-tool-provider';
6
+ export * from './tool-result-events';
@@ -1,4 +1,6 @@
1
+ export * from './agent-tool-provider';
1
2
  export * from './artifact-tools';
2
3
  export * from './client-tool-provider';
3
4
  export * from './local-tools';
4
5
  export * from './mcp-tool-provider';
6
+ export * from './tool-result-events';
@@ -1,4 +1,6 @@
1
+ import { catchError, defer, mergeMap, of } from 'rxjs';
1
2
  import { z } from 'zod';
3
+ import { toolErrorEvent, toolResultToEvents } from './tool-result-events';
2
4
  export function tool(definition) {
3
5
  return { ...definition };
4
6
  }
@@ -38,7 +40,7 @@ export function localTools(tools) {
38
40
  parameters: zodToJsonSchema(toolDef.schema),
39
41
  };
40
42
  },
41
- execute: async (toolCall, context) => {
43
+ execute: (toolCall, context) => defer(async () => {
42
44
  const toolDef = toolMap.get(toolCall.function.name);
43
45
  if (!toolDef) {
44
46
  return {
@@ -80,6 +82,6 @@ export function localTools(tools) {
80
82
  error: err.message,
81
83
  };
82
84
  }
83
- },
85
+ }).pipe(mergeMap((result) => toolResultToEvents(context, toolCall, result)), catchError((error) => of(toolErrorEvent(context, toolCall, error instanceof Error ? error.message : String(error))))),
84
86
  };
85
87
  }
@@ -1,5 +1,5 @@
1
1
  import type { AuthContext, ExecutionContext } from '../types/context';
2
- import type { ToolCall, ToolDefinition, ToolProvider, ToolResult } from '../types/tools';
2
+ import type { ToolCall, ToolDefinition, ToolProvider } from '../types/tools';
3
3
  export interface MCPProviderConfig {
4
4
  serverId: string;
5
5
  serverUrl: string;
@@ -17,8 +17,7 @@ export declare class McpToolProvider implements ToolProvider {
17
17
  private ongoingRequest;
18
18
  constructor(config: MCPProviderConfig);
19
19
  getTool(toolName: string): Promise<ToolDefinition | undefined>;
20
- executeBatch(toolCalls: ToolCall[], context: ExecutionContext): Promise<ToolResult[]>;
21
20
  getTools(): Promise<ToolDefinition[]>;
22
- execute(toolCall: ToolCall, context: ExecutionContext): Promise<ToolResult>;
21
+ execute(toolCall: ToolCall, context: ExecutionContext): import("rxjs").Observable<import("..").ContextAnyEvent | import("..").ContextEvent<import("..").ToolCompleteEvent>>;
23
22
  private convertMCPTool;
24
23
  }
@@ -1,4 +1,6 @@
1
+ import { catchError, defer, mergeMap, of } from 'rxjs';
1
2
  import { MCPClient } from './mcp-client';
3
+ import { toolErrorEvent, toolResultToEvents } from './tool-result-events';
2
4
  export const mcp = (config) => {
3
5
  return new McpToolProvider(config);
4
6
  };
@@ -22,9 +24,6 @@ export class McpToolProvider {
22
24
  const tools = await this.getTools();
23
25
  return tools.find((tool) => tool.name === toolName);
24
26
  }
25
- async executeBatch(toolCalls, context) {
26
- return Promise.all(toolCalls.map((call) => this.execute(call, context)));
27
- }
28
27
  async getTools() {
29
28
  if (this.toolCache.size > 0 && this.cacheExpiry && Date.now() < this.cacheExpiry) {
30
29
  return Array.from(this.toolCache.values());
@@ -48,38 +47,40 @@ export class McpToolProvider {
48
47
  });
49
48
  return this.ongoingRequest;
50
49
  }
51
- async execute(toolCall, context) {
52
- const { name, arguments: args } = toolCall.function;
53
- if (typeof args !== 'object' || args === null) {
54
- return {
55
- toolCallId: toolCall.id,
56
- toolName: name,
57
- success: false,
58
- error: 'Tool arguments must be an object',
59
- result: null,
60
- };
61
- }
62
- try {
63
- const response = await this.client.callTool({
64
- name,
65
- arguments: args,
66
- }, context.authContext);
67
- return {
68
- toolCallId: toolCall.id,
69
- toolName: name,
70
- success: true,
71
- result: response.result,
72
- };
73
- }
74
- catch (error) {
75
- return {
76
- toolCallId: toolCall.id,
77
- toolName: name,
78
- success: false,
79
- error: error instanceof Error ? error.message : String(error),
80
- result: null,
81
- };
82
- }
50
+ execute(toolCall, context) {
51
+ return defer(async () => {
52
+ const { name, arguments: args } = toolCall.function;
53
+ if (typeof args !== 'object' || args === null) {
54
+ return {
55
+ toolCallId: toolCall.id,
56
+ toolName: name,
57
+ success: false,
58
+ error: 'Tool arguments must be an object',
59
+ result: null,
60
+ };
61
+ }
62
+ try {
63
+ const response = await this.client.callTool({
64
+ name,
65
+ arguments: args,
66
+ }, context.authContext);
67
+ return {
68
+ toolCallId: toolCall.id,
69
+ toolName: name,
70
+ success: true,
71
+ result: response.result,
72
+ };
73
+ }
74
+ catch (error) {
75
+ return {
76
+ toolCallId: toolCall.id,
77
+ toolName: name,
78
+ success: false,
79
+ error: error instanceof Error ? error.message : String(error),
80
+ result: null,
81
+ };
82
+ }
83
+ }).pipe(mergeMap((result) => toolResultToEvents(context, toolCall, result)), catchError((error) => of(toolErrorEvent(context, toolCall, error instanceof Error ? error.message : String(error)))));
83
84
  }
84
85
  convertMCPTool = (mcpTool) => {
85
86
  return {
@@ -0,0 +1,6 @@
1
+ import { type Observable } from 'rxjs';
2
+ import type { ExecutionContext } from '../types/context';
3
+ import type { ContextAnyEvent, ContextEvent, ToolCompleteEvent } from '../types/event';
4
+ import type { ToolCall, ToolResult } from '../types/tools';
5
+ export declare const toolErrorEvent: (context: ExecutionContext, toolCall: ToolCall, errorMessage: string) => ContextEvent<ToolCompleteEvent>;
6
+ export declare const toolResultToEvents: (context: ExecutionContext, _toolCall: ToolCall, result: ToolResult) => Observable<ContextAnyEvent>;
@@ -0,0 +1,33 @@
1
+ import { concat, EMPTY, from, of } from 'rxjs';
2
+ export const toolErrorEvent = (context, toolCall, errorMessage) => ({
3
+ kind: 'tool-complete',
4
+ contextId: context.contextId,
5
+ taskId: context.taskId,
6
+ toolCallId: toolCall.id,
7
+ toolName: toolCall.function.name,
8
+ success: false,
9
+ result: null,
10
+ error: errorMessage,
11
+ timestamp: new Date().toISOString(),
12
+ });
13
+ export const toolResultToEvents = (context, _toolCall, result) => {
14
+ const toolCompleteEvent = {
15
+ kind: 'tool-complete',
16
+ contextId: context.contextId,
17
+ taskId: context.taskId,
18
+ toolCallId: result.toolCallId,
19
+ toolName: result.toolName,
20
+ success: result.success,
21
+ result: result.result,
22
+ error: result.error,
23
+ timestamp: new Date().toISOString(),
24
+ };
25
+ const messageEvents = result.messages?.map((message) => ({
26
+ kind: 'internal:tool-message',
27
+ contextId: context.contextId,
28
+ taskId: context.taskId,
29
+ message,
30
+ timestamp: new Date().toISOString(),
31
+ })) ?? [];
32
+ return concat(of(toolCompleteEvent), messageEvents.length > 0 ? from(messageEvents) : EMPTY);
33
+ };
@@ -17,8 +17,6 @@ export interface JSONSchema {
17
17
  }
18
18
  export interface TaskCreatedEvent {
19
19
  kind: 'task-created';
20
- contextId: string;
21
- taskId: string;
22
20
  parentTaskId?: string;
23
21
  initiator: TaskInitiator;
24
22
  timestamp: string;
@@ -30,8 +28,6 @@ export interface TaskCreatedEvent {
30
28
  }
31
29
  export interface TaskStatusEvent {
32
30
  kind: 'task-status';
33
- contextId: string;
34
- taskId: string;
35
31
  status: TaskStatus;
36
32
  message?: string;
37
33
  timestamp: string;
@@ -43,8 +39,6 @@ export interface TaskStatusEvent {
43
39
  }
44
40
  export interface TaskCompleteEvent {
45
41
  kind: 'task-complete';
46
- contextId: string;
47
- taskId: string;
48
42
  content?: string;
49
43
  artifacts?: string[];
50
44
  timestamp: string;
@@ -58,8 +52,6 @@ export interface TaskCompleteEvent {
58
52
  export type TaskLifecycleEvent = TaskCreatedEvent | TaskStatusEvent | TaskCompleteEvent;
59
53
  export interface ContentDeltaEvent {
60
54
  kind: 'content-delta';
61
- contextId: string;
62
- taskId: string;
63
55
  delta: string;
64
56
  index: number;
65
57
  timestamp: string;
@@ -67,8 +59,6 @@ export interface ContentDeltaEvent {
67
59
  export type FinishReason = 'stop' | 'length' | 'tool_calls' | 'content_filter';
68
60
  export interface ContentCompleteEvent {
69
61
  kind: 'content-complete';
70
- contextId: string;
71
- taskId: string;
72
62
  content: string;
73
63
  finishReason: FinishReason;
74
64
  toolCalls?: Array<{
@@ -84,8 +74,6 @@ export interface ContentCompleteEvent {
84
74
  export type ContentStreamingEvent = ContentDeltaEvent | ContentCompleteEvent;
85
75
  export interface ToolCallEvent {
86
76
  kind: 'tool-call';
87
- contextId: string;
88
- taskId: string;
89
77
  toolCallId: string;
90
78
  toolName: string;
91
79
  arguments: Record<string, unknown>;
@@ -96,8 +84,6 @@ export interface ToolCallEvent {
96
84
  }
97
85
  export interface ToolStartEvent {
98
86
  kind: 'tool-start';
99
- contextId: string;
100
- taskId: string;
101
87
  toolCallId: string;
102
88
  icon?: string;
103
89
  toolName: string;
@@ -111,8 +97,6 @@ export interface ToolStartEvent {
111
97
  }
112
98
  export interface ToolProgressEvent {
113
99
  kind: 'tool-progress';
114
- contextId: string;
115
- taskId: string;
116
100
  toolCallId: string;
117
101
  icon?: string;
118
102
  progress: number;
@@ -127,8 +111,6 @@ export interface ToolProgressEvent {
127
111
  }
128
112
  export interface ToolCompleteEvent {
129
113
  kind: 'tool-complete';
130
- contextId: string;
131
- taskId: string;
132
114
  toolCallId: string;
133
115
  icon?: string;
134
116
  toolName: string;
@@ -146,8 +128,6 @@ export interface ToolCompleteEvent {
146
128
  export type ToolExecutionEvent = ToolCallEvent | ToolStartEvent | ToolProgressEvent | ToolCompleteEvent;
147
129
  export interface InputRequiredEvent {
148
130
  kind: 'input-required';
149
- contextId: string;
150
- taskId: string;
151
131
  inputId: string;
152
132
  requireUser?: boolean;
153
133
  inputType: InputType;
@@ -164,8 +144,6 @@ export interface InputRequiredEvent {
164
144
  }
165
145
  export interface InputReceivedEvent {
166
146
  kind: 'input-received';
167
- contextId: string;
168
- taskId: string;
169
147
  inputId: string;
170
148
  providedBy: InputProvider;
171
149
  userId?: string;
@@ -179,8 +157,6 @@ export interface InputReceivedEvent {
179
157
  export type InputRequestEvent = InputRequiredEvent | InputReceivedEvent;
180
158
  export interface AuthRequiredEvent {
181
159
  kind: 'auth-required';
182
- contextId: string;
183
- taskId: string;
184
160
  authId: string;
185
161
  authType: AuthType;
186
162
  provider?: string;
@@ -195,8 +171,6 @@ export interface AuthRequiredEvent {
195
171
  }
196
172
  export interface AuthCompletedEvent {
197
173
  kind: 'auth-completed';
198
- contextId: string;
199
- taskId: string;
200
174
  authId: string;
201
175
  userId: string;
202
176
  timestamp: string;
@@ -208,8 +182,6 @@ export interface AuthCompletedEvent {
208
182
  export type AuthenticationEvent = AuthRequiredEvent | AuthCompletedEvent;
209
183
  export interface FileWriteEvent {
210
184
  kind: 'file-write';
211
- contextId: string;
212
- taskId: string;
213
185
  artifactId: string;
214
186
  data: string;
215
187
  index: number;
@@ -227,8 +199,6 @@ export interface FileWriteEvent {
227
199
  }
228
200
  export interface DataWriteEvent {
229
201
  kind: 'data-write';
230
- contextId: string;
231
- taskId: string;
232
202
  artifactId: string;
233
203
  name?: string;
234
204
  description?: string;
@@ -242,8 +212,6 @@ export interface DataWriteEvent {
242
212
  }
243
213
  export interface DatasetWriteEvent {
244
214
  kind: 'dataset-write';
245
- contextId: string;
246
- taskId: string;
247
215
  artifactId: string;
248
216
  rows: Record<string, unknown>[];
249
217
  index: number;
@@ -262,8 +230,6 @@ export interface DatasetWriteEvent {
262
230
  export type ArtifactEvent = FileWriteEvent | DataWriteEvent | DatasetWriteEvent;
263
231
  export interface SubtaskCreatedEvent {
264
232
  kind: 'subtask-created';
265
- contextId: string;
266
- taskId: string;
267
233
  subtaskId: string;
268
234
  agentId?: string;
269
235
  prompt: string;
@@ -272,8 +238,6 @@ export interface SubtaskCreatedEvent {
272
238
  export type SubAgentEvent = SubtaskCreatedEvent;
273
239
  export interface ThoughtStreamEvent {
274
240
  kind: 'thought-stream';
275
- contextId: string;
276
- taskId: string;
277
241
  thoughtId: string;
278
242
  thoughtType: ThoughtType;
279
243
  verbosity: ThoughtVerbosity;
@@ -290,8 +254,6 @@ export interface ThoughtStreamEvent {
290
254
  }
291
255
  export interface InternalThoughtProcessEvent {
292
256
  kind: 'internal:thought-process';
293
- contextId: string;
294
- taskId: string;
295
257
  iteration: number;
296
258
  stage: 'pre-llm' | 'post-llm' | 'pre-tool' | 'post-tool';
297
259
  reasoning: string;
@@ -300,8 +262,6 @@ export interface InternalThoughtProcessEvent {
300
262
  }
301
263
  export interface InternalLLMCallEvent {
302
264
  kind: 'internal:llm-call';
303
- contextId: string;
304
- taskId: string;
305
265
  iteration: number;
306
266
  messageCount: number;
307
267
  toolCount: number;
@@ -309,30 +269,22 @@ export interface InternalLLMCallEvent {
309
269
  }
310
270
  export interface InternalToolMessageEvent {
311
271
  kind: 'internal:tool-message';
312
- contextId: string;
313
- taskId: string;
314
272
  message: SystemMessage;
315
273
  timestamp: string;
316
274
  }
317
275
  export interface InternalCheckpointEvent {
318
276
  kind: 'internal:checkpoint';
319
- contextId: string;
320
- taskId: string;
321
277
  iteration: number;
322
278
  timestamp: string;
323
279
  }
324
280
  export interface InternalToolStartEvent {
325
281
  kind: 'internal:tool-start';
326
- contextId: string;
327
- taskId: string;
328
282
  toolCallId: string;
329
283
  toolName: string;
330
284
  timestamp: string;
331
285
  }
332
286
  export interface InternalToolCompleteEvent {
333
287
  kind: 'internal:tool-complete';
334
- contextId: string;
335
- taskId: string;
336
288
  toolCallId: string;
337
289
  toolName: string;
338
290
  success: boolean;
@@ -342,8 +294,6 @@ export interface InternalToolCompleteEvent {
342
294
  export type InternalDebugEvent = InternalLLMCallEvent | InternalToolMessageEvent | InternalCheckpointEvent | InternalToolStartEvent | InternalToolCompleteEvent | InternalThoughtProcessEvent;
343
295
  export interface LLMUsageEvent {
344
296
  kind: 'llm-usage';
345
- contextId: string;
346
- taskId: string;
347
297
  model: string;
348
298
  prompt_tokens?: number;
349
299
  completion_tokens?: number;
@@ -357,13 +307,15 @@ export interface LLMUsageEvent {
357
307
  export type UsageEvent = LLMUsageEvent;
358
308
  export interface MessageEvent {
359
309
  kind: 'message';
360
- contextId: string;
361
- taskId: string;
362
310
  message: Message;
363
311
  timestamp: string;
364
312
  }
365
313
  export type AnyEvent = TaskLifecycleEvent | ContentStreamingEvent | ToolExecutionEvent | InputRequestEvent | AuthenticationEvent | ArtifactEvent | SubAgentEvent | ThoughtStreamEvent | InternalDebugEvent | UsageEvent | MessageEvent;
366
- export type LLMEvent<T> = Omit<T, 'contextId' | 'taskId'>;
314
+ export type ContextEvent<T> = T & {
315
+ contextId: string;
316
+ taskId: string;
317
+ };
318
+ export type ContextAnyEvent = ContextEvent<AnyEvent>;
367
319
  export type ExternalEvent = Exclude<AnyEvent, InternalDebugEvent>;
368
320
  export type DebugEvent = InternalDebugEvent;
369
321
  export declare function isExternalEvent(event: AnyEvent): event is ExternalEvent;
@@ -1,5 +1,5 @@
1
1
  import type { Observable } from 'rxjs';
2
- import type { AnyEvent, LLMEvent } from './event';
2
+ import type { AnyEvent } from './event';
3
3
  import type { Message } from './message';
4
4
  import type { ToolCall, ToolDefinition } from './tools';
5
5
  export interface LLMProvider {
@@ -8,7 +8,7 @@ export interface LLMProvider {
8
8
  tools?: ToolDefinition[];
9
9
  stream?: boolean;
10
10
  sessionId?: string;
11
- }): Observable<LLMEvent<AnyEvent>>;
11
+ }): Observable<AnyEvent>;
12
12
  }
13
13
  export interface LLMResponse {
14
14
  message: Message;