@looopy-ai/core 2.1.14 → 2.1.16

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.
@@ -3,6 +3,7 @@ import { isChildTaskEvent } from '../events/utils';
3
3
  import { startToolExecuteSpan } from '../observability/spans';
4
4
  import { toolErrorEvent } from '../tools/tool-result-events';
5
5
  import { isToolPlugin } from '../types/core';
6
+ import { safeValidateToolCall } from '../types/tools';
6
7
  export const runToolCall = (context, toolCall) => {
7
8
  const logger = context.logger.child({
8
9
  component: 'tool-call',
@@ -10,6 +11,24 @@ export const runToolCall = (context, toolCall) => {
10
11
  toolName: toolCall.toolName,
11
12
  });
12
13
  return defer(async () => {
14
+ const toolCallInput = {
15
+ id: toolCall.toolCallId,
16
+ type: 'function',
17
+ function: {
18
+ name: toolCall.toolName,
19
+ arguments: toolCall.arguments,
20
+ },
21
+ };
22
+ const validation = safeValidateToolCall(toolCallInput);
23
+ if (!validation.success) {
24
+ const errorMessage = `Invalid tool call format: ${(validation.errors || []).map((e) => `${e.path.join('.')}: ${e.message}`).join(', ')}`;
25
+ logger.error({
26
+ toolCallId: toolCall.toolCallId,
27
+ toolName: toolCall.toolName,
28
+ errors: validation.errors,
29
+ }, 'Invalid tool call from LLM - tool name must match ^[a-zA-Z0-9_-]+$');
30
+ return of(toolErrorEvent(toolCallInput, errorMessage));
31
+ }
13
32
  const matchingPlugins = await Promise.all(context.plugins.filter(isToolPlugin).map(async (p) => ({
14
33
  plugin: p,
15
34
  tool: await p.getTool?.(toolCall.toolName),
@@ -29,14 +48,6 @@ export const runToolCall = (context, toolCall) => {
29
48
  arguments: toolCall.arguments,
30
49
  timestamp: new Date().toISOString(),
31
50
  };
32
- const toolCallInput = {
33
- id: toolCall.toolCallId,
34
- type: 'function',
35
- function: {
36
- name: toolCall.toolName,
37
- arguments: toolCall.arguments,
38
- },
39
- };
40
51
  const { tapFinish } = startToolExecuteSpan(context, toolCall);
41
52
  const execution$ = defer(() => {
42
53
  try {
@@ -13,10 +13,9 @@ export declare const cardSchema: z.ZodObject<{
13
13
  description: z.ZodOptional<z.ZodString>;
14
14
  }, z.core.$strip>>>;
15
15
  auth: z.ZodOptional<z.ZodObject<{
16
- issuer: z.ZodString;
17
- audience: z.ZodString;
16
+ token_endpoint: z.ZodString;
18
17
  scopes: z.ZodArray<z.ZodString>;
19
- }, z.core.$strip>>;
18
+ }, z.core.$loose>>;
20
19
  }, z.core.$strip>;
21
20
  export type AgentCard = z.infer<typeof cardSchema>;
22
21
  export declare class AgentToolProvider<AuthContext> implements Plugin<AuthContext> {
@@ -17,10 +17,10 @@ export const cardSchema = z.object({
17
17
  .optional(),
18
18
  auth: z
19
19
  .object({
20
- issuer: z.string(),
21
- audience: z.string(),
20
+ token_endpoint: z.string(),
22
21
  scopes: z.array(z.string()),
23
22
  })
23
+ .loose()
24
24
  .optional(),
25
25
  });
26
26
  const safeName = (name) => name.replace(/[^a-zA-Z0-9-]+/g, '-').toLowerCase();
@@ -51,3 +51,9 @@ export declare const ToolCallSchema: z.ZodObject<{
51
51
  arguments: z.ZodRecord<z.ZodString, z.ZodUnknown>;
52
52
  }, z.core.$strip>;
53
53
  }, z.core.$strip>;
54
+ export declare function validateToolCall(toolCall: unknown): ToolCall;
55
+ export declare function safeValidateToolCall(toolCall: unknown): {
56
+ success: boolean;
57
+ data?: ToolCall;
58
+ errors?: z.ZodIssue[];
59
+ };
@@ -48,7 +48,19 @@ export const ToolCallSchema = z.object({
48
48
  id: z.string(),
49
49
  type: z.literal('function'),
50
50
  function: z.object({
51
- name: z.string(),
51
+ name: z
52
+ .string()
53
+ .regex(/^[a-zA-Z0-9_-]+$/, 'Tool name must contain only alphanumeric characters, underscores, and hyphens'),
52
54
  arguments: z.record(z.string(), z.unknown()),
53
55
  }),
54
56
  });
57
+ export function validateToolCall(toolCall) {
58
+ return ToolCallSchema.parse(toolCall);
59
+ }
60
+ export function safeValidateToolCall(toolCall) {
61
+ const result = ToolCallSchema.safeParse(toolCall);
62
+ if (result.success) {
63
+ return { success: true, data: result.data };
64
+ }
65
+ return { success: false, errors: result.error.issues };
66
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@looopy-ai/core",
3
- "version": "2.1.14",
3
+ "version": "2.1.16",
4
4
  "description": "RxJS-based AI agent framework",
5
5
  "repository": {
6
6
  "url": "https://github.com/looopy-ai/lib"