@looopy-ai/core 2.1.16 → 2.1.17

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.
@@ -1,5 +1,7 @@
1
1
  import { concat, defer, filter, map, mergeMap, shareReplay } from 'rxjs';
2
2
  import { startLLMCallSpan, startLoopIterationSpan } from '../observability/spans';
3
+ import { toolErrorEvent } from '../tools/tool-result-events';
4
+ import { safeValidateToolCall } from '../types/tools';
3
5
  import { getSystemPrompts } from '../utils/prompt';
4
6
  import { runToolCall } from './tools';
5
7
  export const runIteration = (context, config, history) => {
@@ -35,7 +37,35 @@ export const runIteration = (context, config, history) => {
35
37
  stream: true,
36
38
  sessionId: context.taskId,
37
39
  })
38
- .pipe(finishLLMCallSpan, map((event) => ({
40
+ .pipe(finishLLMCallSpan, map((event) => {
41
+ if (event.kind === 'tool-call') {
42
+ const validation = safeValidateToolCall({
43
+ id: event.toolCallId,
44
+ type: 'function',
45
+ function: {
46
+ name: event.toolName,
47
+ arguments: event.arguments,
48
+ },
49
+ });
50
+ if (!validation.success) {
51
+ const errorMessage = `Invalid tool call format: ${(validation.errors || []).map((e) => `${e.path.join('.')}: ${e.message}`).join(', ')}`;
52
+ context.logger.error({
53
+ toolCallId: event.toolCallId,
54
+ toolName: event.toolName,
55
+ errors: validation.errors,
56
+ }, 'Invalid tool call from LLM - tool name must match ^[a-zA-Z0-9_-]+$');
57
+ return toolErrorEvent({
58
+ id: event.toolCallId,
59
+ type: 'function',
60
+ function: {
61
+ name: event.toolName,
62
+ arguments: event.arguments,
63
+ },
64
+ }, errorMessage);
65
+ }
66
+ }
67
+ return event;
68
+ }), map((event) => ({
39
69
  contextId: context.contextId,
40
70
  taskId: context.taskId,
41
71
  path: undefined,
@@ -41,8 +41,9 @@ export declare function validateToolDefinitions(tools: unknown): ToolDefinition[
41
41
  export declare function safeValidateToolDefinitions(tools: unknown): {
42
42
  success: boolean;
43
43
  data?: ToolDefinition[];
44
- errors?: z.ZodIssue[];
44
+ errors?: z.core.$ZodIssue[];
45
45
  };
46
+ export declare const toolFunctionNameRegex: RegExp;
46
47
  export declare const ToolCallSchema: z.ZodObject<{
47
48
  id: z.ZodString;
48
49
  type: z.ZodLiteral<"function">;
@@ -55,5 +56,5 @@ export declare function validateToolCall(toolCall: unknown): ToolCall;
55
56
  export declare function safeValidateToolCall(toolCall: unknown): {
56
57
  success: boolean;
57
58
  data?: ToolCall;
58
- errors?: z.ZodIssue[];
59
+ errors?: z.core.$ZodIssue[];
59
60
  };
@@ -44,13 +44,14 @@ export function safeValidateToolDefinitions(tools) {
44
44
  }
45
45
  return { success: false, errors: result.error.issues };
46
46
  }
47
+ export const toolFunctionNameRegex = /^[a-zA-Z0-9_-]+$/;
47
48
  export const ToolCallSchema = z.object({
48
49
  id: z.string(),
49
50
  type: z.literal('function'),
50
51
  function: z.object({
51
52
  name: z
52
53
  .string()
53
- .regex(/^[a-zA-Z0-9_-]+$/, 'Tool name must contain only alphanumeric characters, underscores, and hyphens'),
54
+ .regex(toolFunctionNameRegex, 'Tool name must contain only alphanumeric characters, underscores, and hyphens'),
54
55
  arguments: z.record(z.string(), z.unknown()),
55
56
  }),
56
57
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@looopy-ai/core",
3
- "version": "2.1.16",
3
+ "version": "2.1.17",
4
4
  "description": "RxJS-based AI agent framework",
5
5
  "repository": {
6
6
  "url": "https://github.com/looopy-ai/lib"