@looopy-ai/core 1.2.0 → 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.
Files changed (37) hide show
  1. package/dist/core/agent.d.ts +2 -2
  2. package/dist/core/iteration.d.ts +2 -2
  3. package/dist/core/iteration.js +17 -12
  4. package/dist/core/loop.d.ts +2 -2
  5. package/dist/core/loop.js +1 -13
  6. package/dist/core/tools.d.ts +2 -2
  7. package/dist/core/tools.js +37 -59
  8. package/dist/core/types.d.ts +0 -1
  9. package/dist/events/utils.d.ts +25 -25
  10. package/dist/observability/spans/agent-turn.d.ts +2 -2
  11. package/dist/observability/spans/iteration.d.ts +2 -2
  12. package/dist/observability/spans/llm-call.d.ts +2 -1
  13. package/dist/observability/spans/llm-call.js +2 -1
  14. package/dist/observability/spans/loop.d.ts +2 -2
  15. package/dist/observability/spans/tool.d.ts +3 -3
  16. package/dist/observability/spans/tool.js +20 -3
  17. package/dist/providers/litellm-provider.d.ts +2 -2
  18. package/dist/server/event-buffer.d.ts +3 -3
  19. package/dist/server/event-router.d.ts +4 -4
  20. package/dist/server/sse.d.ts +3 -3
  21. package/dist/skills/registry.js +1 -0
  22. package/dist/stores/artifacts/internal-event-artifact-store.d.ts +2 -2
  23. package/dist/tools/agent-tool-provider.d.ts +36 -0
  24. package/dist/tools/agent-tool-provider.js +156 -0
  25. package/dist/tools/client-tool-provider.d.ts +1 -1
  26. package/dist/tools/client-tool-provider.js +31 -26
  27. package/dist/tools/index.d.ts +2 -0
  28. package/dist/tools/index.js +2 -0
  29. package/dist/tools/local-tools.js +4 -2
  30. package/dist/tools/mcp-tool-provider.d.ts +2 -3
  31. package/dist/tools/mcp-tool-provider.js +36 -35
  32. package/dist/tools/tool-result-events.d.ts +6 -0
  33. package/dist/tools/tool-result-events.js +33 -0
  34. package/dist/types/event.d.ts +5 -53
  35. package/dist/types/llm.d.ts +2 -2
  36. package/dist/types/tools.d.ts +3 -2
  37. package/package.json +2 -2
@@ -3,7 +3,7 @@ import type { SkillRegistry } from '../skills';
3
3
  import type { MessageStore } from '../stores/messages/interfaces';
4
4
  import type { AgentState, AgentStore } from '../types/agent';
5
5
  import type { AuthContext } from '../types/context';
6
- import type { AnyEvent } from '../types/event';
6
+ import type { ContextAnyEvent } from '../types/event';
7
7
  import type { LLMProvider } from '../types/llm';
8
8
  import type { Message } from '../types/message';
9
9
  import type { ToolProvider } from '../types/tools';
@@ -39,7 +39,7 @@ export declare class Agent {
39
39
  startTurn(userMessage: string | null, options?: {
40
40
  authContext?: AuthContext;
41
41
  taskId?: string;
42
- }): Promise<Observable<AnyEvent>>;
42
+ }): Promise<Observable<ContextAnyEvent>>;
43
43
  private executeInternal;
44
44
  shutdown(): Promise<void>;
45
45
  getMessages(options?: GetMessagesOptions): Promise<Message[]>;
@@ -1,5 +1,5 @@
1
1
  import { type Observable } from 'rxjs';
2
- import type { AnyEvent } from '../types/event';
2
+ import type { ContextAnyEvent } from '../types/event';
3
3
  import type { Message } from '../types/message';
4
4
  import type { IterationConfig, LoopContext } from './types';
5
- export declare const runIteration: (context: LoopContext, config: IterationConfig, history: Message[]) => Observable<AnyEvent>;
5
+ export declare const runIteration: (context: LoopContext, config: IterationConfig, history: Message[]) => Observable<ContextAnyEvent>;
@@ -10,11 +10,15 @@ export const runIteration = (context, config, history) => {
10
10
  const { traceContext: iterationContext, tapFinish: finishIterationSpan } = startLoopIterationSpan({ ...context, logger }, config.iterationNumber);
11
11
  const llmEvents$ = defer(async () => {
12
12
  const systemPrompt = await getSystemPrompt(context.systemPrompt);
13
- const messages = await prepareMessages(systemPrompt, context.skillPrompts, history);
13
+ const messages = await prepareMessages(systemPrompt, context.skillRegistry, history);
14
14
  const tools = await prepareTools(context.toolProviders);
15
+ logger.debug({
16
+ messages: messages.length,
17
+ tools: tools.map((t) => t.name).join(', '),
18
+ }, 'Prepared messages and tools for LLM call');
15
19
  return { messages, tools, systemPrompt };
16
20
  }).pipe(mergeMap(({ messages, tools, systemPrompt }) => {
17
- const { tapFinish: finishLLMCallSpan } = startLLMCallSpan({ ...context, parentContext: iterationContext }, systemPrompt, messages);
21
+ const { tapFinish: finishLLMCallSpan } = startLLMCallSpan({ ...context, parentContext: iterationContext }, systemPrompt, messages, tools);
18
22
  return config.llmProvider
19
23
  .call({
20
24
  messages,
@@ -22,11 +26,11 @@ export const runIteration = (context, config, history) => {
22
26
  stream: true,
23
27
  sessionId: context.taskId,
24
28
  })
25
- .pipe(map((event) => ({
29
+ .pipe(finishLLMCallSpan, map((event) => ({
26
30
  contextId: context.contextId,
27
31
  taskId: context.taskId,
28
32
  ...event,
29
- })), finishLLMCallSpan);
33
+ })));
30
34
  }), shareReplay({ refCount: true }));
31
35
  const toolEvents$ = llmEvents$.pipe(filter((event) => event.kind === 'tool-call'), mergeMap((event) => runToolCall({
32
36
  ...context,
@@ -35,22 +39,23 @@ export const runIteration = (context, config, history) => {
35
39
  }, event)));
36
40
  return concat(llmEvents$.pipe(filter((event) => event.kind !== 'tool-call')), toolEvents$).pipe(finishIterationSpan);
37
41
  };
38
- const prepareMessages = async (systemPrompt, skillPrompts, history) => {
42
+ const prepareMessages = async (systemPrompt, skillRegistry, history) => {
39
43
  const messages = [];
40
44
  if (systemPrompt) {
41
45
  messages.push({
42
46
  role: 'system',
43
47
  content: systemPrompt.prompt,
44
- name: systemPrompt.name || 'system-prompt',
45
48
  });
46
49
  }
47
- if (skillPrompts) {
48
- for (const [name, content] of Object.entries(skillPrompts)) {
49
- messages.push({
50
+ if (skillRegistry) {
51
+ const skills = skillRegistry.list();
52
+ if (skills.length > 0) {
53
+ const skillList = skills.map((s) => `- **${s.name}**: ${s.description}`).join('\n');
54
+ const skillMessage = {
50
55
  role: 'system',
51
- content,
52
- name,
53
- });
56
+ content: `You can learn new skills by using the 'learn_skill' tool. Available skills:\n\n${skillList}`,
57
+ };
58
+ messages.push(skillMessage);
54
59
  }
55
60
  }
56
61
  return messages.concat(history);
@@ -1,4 +1,4 @@
1
- import type { AnyEvent } from '../types/event';
1
+ import type { ContextAnyEvent } from '../types/event';
2
2
  import type { Message } from '../types/message';
3
3
  import type { LoopConfig, TurnContext } from './types';
4
- export declare const runLoop: (context: TurnContext, config: LoopConfig, history: Message[]) => import("rxjs").Observable<AnyEvent>;
4
+ export declare const runLoop: (context: TurnContext, config: LoopConfig, history: Message[]) => import("rxjs").Observable<ContextAnyEvent>;
package/dist/core/loop.js CHANGED
@@ -27,20 +27,8 @@ export const runLoop = (context, config, history) => {
27
27
  status: 'working',
28
28
  metadata: {},
29
29
  });
30
- const initialMessages = [...history];
31
- if (context.skillRegistry) {
32
- const skills = context.skillRegistry.list();
33
- if (skills.length > 0) {
34
- const skillList = skills.map((s) => `- **${s.name}**: ${s.description}`).join('\n');
35
- const skillMessage = {
36
- role: 'system',
37
- content: `You can learn new skills by using the 'learn_skill' tool. Available skills:\n\n${skillList}`,
38
- };
39
- initialMessages.unshift(skillMessage);
40
- }
41
- }
42
30
  const merged$ = recursiveMerge({
43
- messages: initialMessages,
31
+ messages: history,
44
32
  completed: false,
45
33
  iteration: 0,
46
34
  }, (state) => runIteration({ ...context, parentContext: loopContext }, {
@@ -1,4 +1,4 @@
1
1
  import { type Observable } from 'rxjs';
2
- import type { InternalToolMessageEvent, ToolCallEvent, ToolExecutionEvent } from '../types/event';
2
+ import type { ContextAnyEvent, ContextEvent, ToolCallEvent } from '../types/event';
3
3
  import type { IterationContext } from './types';
4
- export declare const runToolCall: (context: IterationContext, toolCall: ToolCallEvent) => Observable<ToolExecutionEvent | InternalToolMessageEvent>;
4
+ export declare const runToolCall: (context: IterationContext, toolCall: ContextEvent<ToolCallEvent>) => Observable<ContextAnyEvent>;
@@ -1,5 +1,6 @@
1
- import { catchError, concat, defer, EMPTY, from, mergeMap, of, shareReplay, } from 'rxjs';
1
+ import { catchError, concat, defer, mergeMap, of, tap } from 'rxjs';
2
2
  import { startToolExecuteSpan } from '../observability/spans';
3
+ import { toolErrorEvent } from '../tools/tool-result-events';
3
4
  export const runToolCall = (context, toolCall) => {
4
5
  const logger = context.logger.child({
5
6
  component: 'tool-call',
@@ -28,66 +29,43 @@ export const runToolCall = (context, toolCall) => {
28
29
  arguments: toolCall.arguments,
29
30
  timestamp: new Date().toISOString(),
30
31
  };
32
+ const toolCallInput = {
33
+ id: toolCall.toolCallId,
34
+ type: 'function',
35
+ function: {
36
+ name: toolCall.toolName,
37
+ arguments: toolCall.arguments,
38
+ },
39
+ };
31
40
  const { tapFinish } = startToolExecuteSpan(context, toolCall);
32
- const toolResults$ = defer(async () => {
33
- logger.trace({ providerName: provider.name }, 'Executing tool');
34
- return await provider.execute({
35
- id: toolCall.toolCallId,
36
- type: 'function',
37
- function: {
38
- name: toolCall.toolName,
39
- arguments: toolCall.arguments,
40
- },
41
- }, context);
42
- }).pipe(tapFinish, shareReplay({ refCount: true }));
43
- const toolCompleteEvents$ = toolResults$.pipe(mergeMap((result) => {
44
- if (result.success) {
45
- logger.trace({ providerName: provider.name, success: true }, 'Tool execution complete');
46
- return of(createToolCompleteEvent(context, toolCall, result.result));
41
+ const execution$ = defer(() => {
42
+ try {
43
+ logger.trace({ providerName: provider.name }, 'Executing tool');
44
+ return provider.execute(toolCallInput, context).pipe(tap((event) => {
45
+ if (event.kind !== 'tool-complete') {
46
+ return;
47
+ }
48
+ logger.trace({ providerName: provider.name, success: event.success }, 'Tool execution complete');
49
+ }), tapFinish, catchError((error) => {
50
+ const err = error instanceof Error ? error : new Error(String(error));
51
+ logger.error({
52
+ providerName: provider.name,
53
+ error: err.message,
54
+ stack: err.stack,
55
+ }, 'Tool execution error');
56
+ return of(toolErrorEvent(context, toolCallInput, err.message));
57
+ }));
47
58
  }
48
- else {
49
- logger.trace({ providerName: provider.name, success: false }, 'Tool execution failed');
50
- return of(createToolErrorEvent(context, toolCall, result.error || 'Unknown error'));
59
+ catch (error) {
60
+ const err = error instanceof Error ? error : new Error(String(error));
61
+ logger.error({
62
+ providerName: provider.name,
63
+ error: err.message,
64
+ stack: err.stack,
65
+ }, 'Tool execution error');
66
+ return of(toolErrorEvent(context, toolCallInput, err.message));
51
67
  }
52
- }), catchError((error) => {
53
- const err = error instanceof Error ? error : new Error(String(error));
54
- logger.error({
55
- providerName: provider.name,
56
- error: err.message,
57
- stack: err.stack,
58
- }, 'Tool execution error');
59
- return of(createToolErrorEvent(context, toolCall, err.message));
60
- }));
61
- const toolMessageEvents$ = toolResults$.pipe(mergeMap((result) => result.success && result.messages
62
- ? from(result.messages?.map((message) => ({
63
- kind: 'internal:tool-message',
64
- message,
65
- timestamp: new Date().toISOString(),
66
- })))
67
- : EMPTY), catchError(() => {
68
- return EMPTY;
69
- }));
70
- return concat(of(toolStartEvent), toolCompleteEvents$, toolMessageEvents$);
68
+ });
69
+ return concat(of(toolStartEvent), execution$);
71
70
  }).pipe(mergeMap((obs) => obs));
72
71
  };
73
- const createToolCompleteEvent = (context, toolCall, result) => ({
74
- kind: 'tool-complete',
75
- contextId: context.contextId,
76
- taskId: context.taskId,
77
- toolCallId: toolCall.toolCallId,
78
- toolName: toolCall.toolName,
79
- success: true,
80
- result: result,
81
- timestamp: new Date().toISOString(),
82
- });
83
- const createToolErrorEvent = (context, toolCall, errorMessage) => ({
84
- kind: 'tool-complete',
85
- contextId: context.contextId,
86
- taskId: context.taskId,
87
- toolCallId: toolCall.toolCallId,
88
- toolName: toolCall.toolName,
89
- success: false,
90
- result: null,
91
- error: errorMessage,
92
- timestamp: new Date().toISOString(),
93
- });
@@ -13,7 +13,6 @@ export type AgentContext = {
13
13
  logger: pino.Logger;
14
14
  systemPrompt?: SystemPromptProp;
15
15
  skillRegistry?: SkillRegistry;
16
- skillPrompts?: Record<string, string>;
17
16
  metadata?: Record<string, unknown>;
18
17
  };
19
18
  export type TurnContext = AgentContext & {
@@ -1,4 +1,4 @@
1
- import type { AnyEvent, AuthCompletedEvent, AuthRequiredEvent, AuthType, ContentCompleteEvent, ContentDeltaEvent, DatasetWriteEvent, DataWriteEvent, FileWriteEvent, FinishReason, InputProvider, InputReceivedEvent, InputRequiredEvent, InputType, InternalCheckpointEvent, InternalLLMCallEvent, InternalThoughtProcessEvent, JSONSchema, SubtaskCreatedEvent, TaskCompleteEvent, TaskCreatedEvent, TaskInitiator, TaskStatus, TaskStatusEvent, ThoughtStreamEvent, ThoughtType, ThoughtVerbosity, ToolCompleteEvent, ToolProgressEvent, ToolStartEvent } from '../types/event';
1
+ import type { AuthCompletedEvent, AuthRequiredEvent, AuthType, ContentCompleteEvent, ContentDeltaEvent, ContextAnyEvent, ContextEvent, DatasetWriteEvent, DataWriteEvent, FileWriteEvent, FinishReason, InputProvider, InputReceivedEvent, InputRequiredEvent, InputType, InternalCheckpointEvent, InternalLLMCallEvent, InternalThoughtProcessEvent, JSONSchema, SubtaskCreatedEvent, TaskCompleteEvent, TaskCreatedEvent, TaskInitiator, TaskStatus, TaskStatusEvent, ThoughtStreamEvent, ThoughtType, ThoughtVerbosity, ToolCompleteEvent, ToolProgressEvent, ToolStartEvent } from '../types/event';
2
2
  export declare function generateEventId(): string;
3
3
  export interface CreateTaskCreatedEventOptions {
4
4
  contextId: string;
@@ -11,7 +11,7 @@ export interface CreateTaskCreatedEventOptions {
11
11
  [key: string]: unknown;
12
12
  };
13
13
  }
14
- export declare function createTaskCreatedEvent(options: CreateTaskCreatedEventOptions): TaskCreatedEvent;
14
+ export declare function createTaskCreatedEvent(options: CreateTaskCreatedEventOptions): ContextEvent<TaskCreatedEvent>;
15
15
  export interface CreateTaskStatusEventOptions {
16
16
  contextId: string;
17
17
  taskId: string;
@@ -23,7 +23,7 @@ export interface CreateTaskStatusEventOptions {
23
23
  [key: string]: unknown;
24
24
  };
25
25
  }
26
- export declare function createTaskStatusEvent(options: CreateTaskStatusEventOptions): TaskStatusEvent;
26
+ export declare function createTaskStatusEvent(options: CreateTaskStatusEventOptions): ContextEvent<TaskStatusEvent>;
27
27
  export interface CreateTaskCompleteEventOptions {
28
28
  contextId: string;
29
29
  taskId: string;
@@ -36,21 +36,21 @@ export interface CreateTaskCompleteEventOptions {
36
36
  [key: string]: unknown;
37
37
  };
38
38
  }
39
- export declare function createTaskCompleteEvent(options: CreateTaskCompleteEventOptions): TaskCompleteEvent;
39
+ export declare function createTaskCompleteEvent(options: CreateTaskCompleteEventOptions): ContextEvent<TaskCompleteEvent>;
40
40
  export interface CreateContentDeltaEventOptions {
41
41
  contextId: string;
42
42
  taskId: string;
43
43
  delta: string;
44
44
  index: number;
45
45
  }
46
- export declare function createContentDeltaEvent(options: CreateContentDeltaEventOptions): ContentDeltaEvent;
46
+ export declare function createContentDeltaEvent(options: CreateContentDeltaEventOptions): ContextEvent<ContentDeltaEvent>;
47
47
  export interface CreateContentCompleteEventOptions {
48
48
  contextId: string;
49
49
  taskId: string;
50
50
  content: string;
51
51
  finishReason?: FinishReason;
52
52
  }
53
- export declare function createContentCompleteEvent(options: CreateContentCompleteEventOptions): ContentCompleteEvent;
53
+ export declare function createContentCompleteEvent(options: CreateContentCompleteEventOptions): ContextEvent<ContentCompleteEvent>;
54
54
  export interface CreateToolStartEventOptions {
55
55
  contextId: string;
56
56
  taskId: string;
@@ -63,7 +63,7 @@ export interface CreateToolStartEventOptions {
63
63
  [key: string]: unknown;
64
64
  };
65
65
  }
66
- export declare function createToolStartEvent(options: CreateToolStartEventOptions): ToolStartEvent;
66
+ export declare function createToolStartEvent(options: CreateToolStartEventOptions): ContextEvent<ToolStartEvent>;
67
67
  export interface CreateToolProgressEventOptions {
68
68
  contextId: string;
69
69
  taskId: string;
@@ -77,7 +77,7 @@ export interface CreateToolProgressEventOptions {
77
77
  [key: string]: unknown;
78
78
  };
79
79
  }
80
- export declare function createToolProgressEvent(options: CreateToolProgressEventOptions): ToolProgressEvent;
80
+ export declare function createToolProgressEvent(options: CreateToolProgressEventOptions): ContextEvent<ToolProgressEvent>;
81
81
  export interface CreateToolCompleteEventOptions {
82
82
  contextId: string;
83
83
  taskId: string;
@@ -93,7 +93,7 @@ export interface CreateToolCompleteEventOptions {
93
93
  [key: string]: unknown;
94
94
  };
95
95
  }
96
- export declare function createToolCompleteEvent(options: CreateToolCompleteEventOptions): ToolCompleteEvent;
96
+ export declare function createToolCompleteEvent(options: CreateToolCompleteEventOptions): ContextEvent<ToolCompleteEvent>;
97
97
  export interface CreateInputRequiredEventOptions {
98
98
  contextId: string;
99
99
  taskId: string;
@@ -105,7 +105,7 @@ export interface CreateInputRequiredEventOptions {
105
105
  options?: unknown[];
106
106
  metadata?: Record<string, unknown>;
107
107
  }
108
- export declare function createInputRequiredEvent(options: CreateInputRequiredEventOptions): InputRequiredEvent;
108
+ export declare function createInputRequiredEvent(options: CreateInputRequiredEventOptions): ContextEvent<InputRequiredEvent>;
109
109
  export interface CreateInputReceivedEventOptions {
110
110
  contextId: string;
111
111
  taskId: string;
@@ -118,7 +118,7 @@ export interface CreateInputReceivedEventOptions {
118
118
  [key: string]: unknown;
119
119
  };
120
120
  }
121
- export declare function createInputReceivedEvent(options: CreateInputReceivedEventOptions): InputReceivedEvent;
121
+ export declare function createInputReceivedEvent(options: CreateInputReceivedEventOptions): ContextEvent<InputReceivedEvent>;
122
122
  export interface CreateAuthRequiredEventOptions {
123
123
  contextId: string;
124
124
  taskId: string;
@@ -133,7 +133,7 @@ export interface CreateAuthRequiredEventOptions {
133
133
  [key: string]: unknown;
134
134
  };
135
135
  }
136
- export declare function createAuthRequiredEvent(options: CreateAuthRequiredEventOptions): AuthRequiredEvent;
136
+ export declare function createAuthRequiredEvent(options: CreateAuthRequiredEventOptions): ContextEvent<AuthRequiredEvent>;
137
137
  export interface CreateAuthCompletedEventOptions {
138
138
  contextId: string;
139
139
  taskId: string;
@@ -144,7 +144,7 @@ export interface CreateAuthCompletedEventOptions {
144
144
  [key: string]: unknown;
145
145
  };
146
146
  }
147
- export declare function createAuthCompletedEvent(options: CreateAuthCompletedEventOptions): AuthCompletedEvent;
147
+ export declare function createAuthCompletedEvent(options: CreateAuthCompletedEventOptions): ContextEvent<AuthCompletedEvent>;
148
148
  export interface CreateFileWriteEventOptions {
149
149
  contextId: string;
150
150
  taskId: string;
@@ -162,7 +162,7 @@ export interface CreateFileWriteEventOptions {
162
162
  [key: string]: unknown;
163
163
  };
164
164
  }
165
- export declare function createFileWriteEvent(options: CreateFileWriteEventOptions): FileWriteEvent;
165
+ export declare function createFileWriteEvent(options: CreateFileWriteEventOptions): ContextEvent<FileWriteEvent>;
166
166
  export interface CreateDataWriteEventOptions {
167
167
  contextId: string;
168
168
  taskId: string;
@@ -176,7 +176,7 @@ export interface CreateDataWriteEventOptions {
176
176
  [key: string]: unknown;
177
177
  };
178
178
  }
179
- export declare function createDataWriteEvent(options: CreateDataWriteEventOptions): DataWriteEvent;
179
+ export declare function createDataWriteEvent(options: CreateDataWriteEventOptions): ContextEvent<DataWriteEvent>;
180
180
  export interface CreateDatasetWriteEventOptions {
181
181
  contextId: string;
182
182
  taskId: string;
@@ -194,7 +194,7 @@ export interface CreateDatasetWriteEventOptions {
194
194
  [key: string]: unknown;
195
195
  };
196
196
  }
197
- export declare function createDatasetWriteEvent(options: CreateDatasetWriteEventOptions): DatasetWriteEvent;
197
+ export declare function createDatasetWriteEvent(options: CreateDatasetWriteEventOptions): ContextEvent<DatasetWriteEvent>;
198
198
  export interface CreateSubtaskCreatedEventOptions {
199
199
  contextId: string;
200
200
  taskId: string;
@@ -202,7 +202,7 @@ export interface CreateSubtaskCreatedEventOptions {
202
202
  agentId?: string;
203
203
  prompt: string;
204
204
  }
205
- export declare function createSubtaskCreatedEvent(options: CreateSubtaskCreatedEventOptions): SubtaskCreatedEvent;
205
+ export declare function createSubtaskCreatedEvent(options: CreateSubtaskCreatedEventOptions): ContextEvent<SubtaskCreatedEvent>;
206
206
  export interface CreateThoughtStreamEventOptions {
207
207
  contextId: string;
208
208
  taskId: string;
@@ -218,7 +218,7 @@ export interface CreateThoughtStreamEventOptions {
218
218
  [key: string]: unknown;
219
219
  };
220
220
  }
221
- export declare function createThoughtStreamEvent(options: CreateThoughtStreamEventOptions): ThoughtStreamEvent;
221
+ export declare function createThoughtStreamEvent(options: CreateThoughtStreamEventOptions): ContextEvent<ThoughtStreamEvent>;
222
222
  export interface CreateInternalThoughtProcessEventOptions {
223
223
  contextId: string;
224
224
  taskId: string;
@@ -227,7 +227,7 @@ export interface CreateInternalThoughtProcessEventOptions {
227
227
  reasoning: string;
228
228
  state: Record<string, unknown>;
229
229
  }
230
- export declare function createInternalThoughtProcessEvent(options: CreateInternalThoughtProcessEventOptions): InternalThoughtProcessEvent;
230
+ export declare function createInternalThoughtProcessEvent(options: CreateInternalThoughtProcessEventOptions): ContextEvent<InternalThoughtProcessEvent>;
231
231
  export interface CreateInternalLLMCallEventOptions {
232
232
  contextId: string;
233
233
  taskId: string;
@@ -235,16 +235,16 @@ export interface CreateInternalLLMCallEventOptions {
235
235
  messageCount: number;
236
236
  toolCount: number;
237
237
  }
238
- export declare function createInternalLLMCallEvent(options: CreateInternalLLMCallEventOptions): InternalLLMCallEvent;
238
+ export declare function createInternalLLMCallEvent(options: CreateInternalLLMCallEventOptions): ContextEvent<InternalLLMCallEvent>;
239
239
  export interface CreateInternalCheckpointEventOptions {
240
240
  contextId: string;
241
241
  taskId: string;
242
242
  iteration: number;
243
243
  }
244
- export declare function createInternalCheckpointEvent(options: CreateInternalCheckpointEventOptions): InternalCheckpointEvent;
245
- export declare function filterExternalEvents(events: AnyEvent[]): AnyEvent[];
246
- export declare function filterByTaskId(events: AnyEvent[], taskId: string): AnyEvent[];
247
- export declare function filterByContextId(events: AnyEvent[], contextId: string): AnyEvent[];
248
- export declare function filterByKind<K extends AnyEvent['kind']>(events: AnyEvent[], kind: K): Extract<AnyEvent, {
244
+ export declare function createInternalCheckpointEvent(options: CreateInternalCheckpointEventOptions): ContextEvent<InternalCheckpointEvent>;
245
+ export declare function filterExternalEvents(events: ContextAnyEvent[]): ContextAnyEvent[];
246
+ export declare function filterByTaskId(events: ContextAnyEvent[], taskId: string): ContextAnyEvent[];
247
+ export declare function filterByContextId(events: ContextAnyEvent[], contextId: string): ContextAnyEvent[];
248
+ export declare function filterByKind<K extends ContextAnyEvent['kind']>(events: ContextAnyEvent[], kind: K): Extract<ContextAnyEvent, {
249
249
  kind: K;
250
250
  }>[];
@@ -1,5 +1,5 @@
1
1
  import { type Context, type Span } from '@opentelemetry/api';
2
- import type { AnyEvent } from '../../types/event';
2
+ import type { ContextAnyEvent } from '../../types/event';
3
3
  export interface AgentTurnSpanParams {
4
4
  agentId: string;
5
5
  taskId: string;
@@ -10,7 +10,7 @@ export interface AgentTurnSpanParams {
10
10
  export declare const startAgentTurnSpan: (params: AgentTurnSpanParams) => {
11
11
  span: Span;
12
12
  traceContext: Context;
13
- tapFinish: import("rxjs").MonoTypeOperatorFunction<AnyEvent>;
13
+ tapFinish: import("rxjs").MonoTypeOperatorFunction<ContextAnyEvent>;
14
14
  };
15
15
  export declare function addMessagesLoadedEvent(span: Span, count: number): void;
16
16
  export declare function addMessagesCompactedEvent(span: Span): void;
@@ -1,5 +1,5 @@
1
1
  import type { LoopContext } from '../../core/types';
2
- import type { AnyEvent } from '../../types/event';
2
+ import type { ContextAnyEvent } from '../../types/event';
3
3
  export interface LoopIterationSpanParams {
4
4
  agentId: string;
5
5
  contextId: string;
@@ -10,5 +10,5 @@ export interface LoopIterationSpanParams {
10
10
  export declare const startLoopIterationSpan: (context: LoopContext, iteration: number) => {
11
11
  span: import("@opentelemetry/api").Span;
12
12
  traceContext: import("@opentelemetry/api").Context;
13
- tapFinish: import("rxjs").MonoTypeOperatorFunction<AnyEvent>;
13
+ tapFinish: import("rxjs").MonoTypeOperatorFunction<ContextAnyEvent>;
14
14
  };
@@ -1,3 +1,4 @@
1
+ import type { ToolDefinition } from '../..';
1
2
  import type { LoopContext } from '../../core/types';
2
3
  import type { AnyEvent } from '../../types/event';
3
4
  import type { Message } from '../../types/message';
@@ -8,7 +9,7 @@ export interface LLMCallSpanParams {
8
9
  messages: Message[];
9
10
  parentContext: import('@opentelemetry/api').Context;
10
11
  }
11
- export declare const startLLMCallSpan: (context: LoopContext, systemPrompt: SystemPrompt | undefined, messages: Message[]) => {
12
+ export declare const startLLMCallSpan: (context: LoopContext, systemPrompt: SystemPrompt | undefined, messages: Message[], tools: ToolDefinition[]) => {
12
13
  span: import("@opentelemetry/api").Span;
13
14
  traceContext: import("@opentelemetry/api").Context;
14
15
  tapFinish: import("rxjs").MonoTypeOperatorFunction<AnyEvent>;
@@ -1,7 +1,7 @@
1
1
  import { SpanStatusCode, trace } from '@opentelemetry/api';
2
2
  import { tap } from 'rxjs/internal/operators/tap';
3
3
  import { SpanAttributes, SpanNames } from '../tracing';
4
- export const startLLMCallSpan = (context, systemPrompt, messages) => {
4
+ export const startLLMCallSpan = (context, systemPrompt, messages, tools) => {
5
5
  const tracer = trace.getTracer('looopy');
6
6
  const span = tracer.startSpan(SpanNames.LLM_CALL, {
7
7
  attributes: {
@@ -11,6 +11,7 @@ export const startLLMCallSpan = (context, systemPrompt, messages) => {
11
11
  [SpanAttributes.LANGFUSE_OBSERVATION_TYPE]: 'generation',
12
12
  [SpanAttributes.LANGFUSE_PROMPT_NAME]: systemPrompt?.name,
13
13
  [SpanAttributes.LANGFUSE_PROMPT_VERSION]: systemPrompt?.version,
14
+ 'tools.available': tools.map((t) => t.name),
14
15
  },
15
16
  }, context.parentContext);
16
17
  const traceContext = trace.setSpan(context.parentContext, span);
@@ -1,5 +1,5 @@
1
1
  import { type Context } from '@opentelemetry/api';
2
- import type { AnyEvent } from '../../types/event';
2
+ import type { ContextAnyEvent } from '../../types/event';
3
3
  export interface AgentLoopSpanParams {
4
4
  agentId: string;
5
5
  taskId: string;
@@ -10,5 +10,5 @@ export interface AgentLoopSpanParams {
10
10
  export declare const startAgentLoopSpan: (params: AgentLoopSpanParams) => {
11
11
  span: import("@opentelemetry/api").Span;
12
12
  traceContext: Context;
13
- tapFinish: import("rxjs").MonoTypeOperatorFunction<AnyEvent>;
13
+ tapFinish: import("rxjs").MonoTypeOperatorFunction<ContextAnyEvent>;
14
14
  };
@@ -1,6 +1,6 @@
1
1
  import type { IterationContext } from '../../core/types';
2
- import type { ToolCallEvent } from '../../types/event';
3
- import type { ToolCall, ToolResult } from '../../types/tools';
2
+ import type { ContextAnyEvent, ToolCallEvent } from '../../types/event';
3
+ import type { ToolCall } from '../../types/tools';
4
4
  export interface ToolExecutionSpanParams {
5
5
  agentId: string;
6
6
  taskId: string;
@@ -10,5 +10,5 @@ export interface ToolExecutionSpanParams {
10
10
  export declare const startToolExecuteSpan: (context: IterationContext, toolStart: ToolCallEvent) => {
11
11
  span: import("@opentelemetry/api").Span;
12
12
  traceContext: import("@opentelemetry/api").Context;
13
- tapFinish: import("rxjs").MonoTypeOperatorFunction<ToolResult>;
13
+ tapFinish: import("rxjs").MonoTypeOperatorFunction<ContextAnyEvent>;
14
14
  };
@@ -1,5 +1,5 @@
1
1
  import { context as otelContext, SpanStatusCode, trace } from '@opentelemetry/api';
2
- import { tap } from 'rxjs/internal/operators/tap';
2
+ import { tap } from 'rxjs';
3
3
  import { SpanAttributes, SpanNames } from '../tracing';
4
4
  export const startToolExecuteSpan = (context, toolStart) => {
5
5
  const tracer = trace.getTracer('looopy');
@@ -19,8 +19,22 @@ export const startToolExecuteSpan = (context, toolStart) => {
19
19
  traceContext,
20
20
  tapFinish: tap({
21
21
  next: (event) => {
22
- span.setAttribute('output', JSON.stringify(event.result));
23
- span.setStatus({ code: SpanStatusCode.OK });
22
+ if (!isToolCompleteEvent(event)) {
23
+ return;
24
+ }
25
+ try {
26
+ span.setAttribute('output', JSON.stringify(event.result));
27
+ }
28
+ catch {
29
+ }
30
+ if (event.success) {
31
+ span.setStatus({ code: SpanStatusCode.OK });
32
+ return;
33
+ }
34
+ span.setStatus({
35
+ code: SpanStatusCode.ERROR,
36
+ message: event.error ?? 'Tool execution failed',
37
+ });
24
38
  },
25
39
  complete: () => span.end(),
26
40
  error: (err) => {
@@ -31,3 +45,6 @@ export const startToolExecuteSpan = (context, toolStart) => {
31
45
  }),
32
46
  };
33
47
  };
48
+ const isToolCompleteEvent = (event) => {
49
+ return event.kind === 'tool-complete';
50
+ };
@@ -1,5 +1,5 @@
1
1
  import { Observable } from 'rxjs';
2
- import type { AnyEvent, LLMEvent } from '../types/event';
2
+ import type { AnyEvent } from '../types/event';
3
3
  import type { LLMProvider } from '../types/llm';
4
4
  import type { Message } from '../types/message';
5
5
  import type { ToolDefinition } from '../types/tools';
@@ -23,7 +23,7 @@ export declare class LiteLLMProvider implements LLMProvider {
23
23
  messages: Message[];
24
24
  tools?: ToolDefinition[];
25
25
  sessionId?: string;
26
- }): Observable<LLMEvent<AnyEvent>>;
26
+ }): Observable<AnyEvent>;
27
27
  private debugLogRawChunk;
28
28
  private debugLog;
29
29
  private createSSEStream;
@@ -1,7 +1,7 @@
1
- import type { AnyEvent } from '../types/event';
1
+ import type { ContextAnyEvent } from '../types/event';
2
2
  export interface BufferedEvent {
3
3
  id: string;
4
- event: AnyEvent;
4
+ event: ContextAnyEvent;
5
5
  timestamp: number;
6
6
  }
7
7
  export interface EventBufferConfig {
@@ -19,7 +19,7 @@ export declare class EventBuffer {
19
19
  private readonly autoCleanup;
20
20
  private readonly cleanupInterval;
21
21
  constructor(config?: EventBufferConfig);
22
- add(contextId: string, event: AnyEvent): string;
22
+ add(contextId: string, event: ContextAnyEvent): string;
23
23
  getEventsSince(contextId: string, lastEventId: string): BufferedEvent[];
24
24
  getAll(contextId: string): BufferedEvent[];
25
25
  clear(contextId: string): void;
@@ -1,5 +1,5 @@
1
- import type { AnyEvent } from '../types/event';
2
- export type EventFilter = (event: AnyEvent) => boolean;
1
+ import type { ContextAnyEvent } from '../types/event';
2
+ export type EventFilter = (event: ContextAnyEvent) => boolean;
3
3
  export interface SubscriptionConfig {
4
4
  contextId: string;
5
5
  taskId?: string;
@@ -11,14 +11,14 @@ export interface SubscriptionConfig {
11
11
  export interface Subscriber {
12
12
  id: string;
13
13
  config: SubscriptionConfig;
14
- send(event: AnyEvent, eventId: string): void;
14
+ send(event: ContextAnyEvent, eventId: string): void;
15
15
  close(): void;
16
16
  }
17
17
  export declare class EventRouter {
18
18
  private subscribers;
19
19
  subscribe(subscriber: Subscriber): void;
20
20
  unsubscribe(subscriberId: string, contextId: string): void;
21
- route(contextId: string, event: AnyEvent, eventId: string): number;
21
+ route(contextId: string, event: ContextAnyEvent, eventId: string): number;
22
22
  private shouldSendToSubscriber;
23
23
  getSubscriberCount(contextId: string): number;
24
24
  getActiveContexts(): string[];