@applica-software-guru/persona-sdk 0.1.63 → 0.1.65

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/src/tools.ts ADDED
@@ -0,0 +1,211 @@
1
+ export type ToolParameterType = 'string' | 'number' | 'boolean' | 'object' | 'array';
2
+
3
+ export interface ToolParameter {
4
+ type: ToolParameterType;
5
+ description: string;
6
+ required?: boolean;
7
+ properties?: Record<string, ToolParameter>;
8
+ items?: ToolParameter;
9
+ }
10
+
11
+ export interface ToolSchema {
12
+ type: 'local';
13
+ name: string;
14
+ description: string;
15
+ config: {
16
+ timeout: number;
17
+ parameters: {
18
+ type: 'object';
19
+ title: string;
20
+ required: string[];
21
+ properties: Record<string, ToolParameter>;
22
+ };
23
+ output: {
24
+ type: 'object';
25
+ title: string;
26
+ properties: Record<string, ToolParameter>;
27
+ };
28
+ };
29
+ }
30
+
31
+ export interface ToolDefinition {
32
+ name: string;
33
+ description: string;
34
+ title?: string;
35
+ timeout?: number;
36
+ parameters: Record<string, ToolParameter>;
37
+ output: Record<string, ToolParameter>;
38
+ implementation: (...args: any[]) => any;
39
+ }
40
+
41
+ /**
42
+ * Create a tool parameter definition
43
+ */
44
+ export function createParameter(
45
+ type: ToolParameterType,
46
+ description: string,
47
+ options?: {
48
+ required?: boolean;
49
+ properties?: Record<string, ToolParameter>;
50
+ items?: ToolParameter;
51
+ },
52
+ ): ToolParameter {
53
+ return {
54
+ type,
55
+ description,
56
+ ...options,
57
+ };
58
+ }
59
+
60
+ /**
61
+ * Generate a tool schema from a tool definition
62
+ */
63
+ export function generateToolSchema(definition: ToolDefinition): ToolSchema {
64
+ const requiredParams = Object.entries(definition.parameters)
65
+ .filter(([_, param]) => param.required)
66
+ .map(([name]) => name);
67
+
68
+ return {
69
+ type: 'local',
70
+ name: definition.name,
71
+ description: definition.description,
72
+ config: {
73
+ timeout: definition.timeout || 60,
74
+ parameters: {
75
+ type: 'object',
76
+ title: definition.title || `${definition.name} parameters`,
77
+ required: requiredParams,
78
+ properties: definition.parameters,
79
+ },
80
+ output: {
81
+ type: 'object',
82
+ title: `${definition.name} output`,
83
+ properties: definition.output,
84
+ },
85
+ },
86
+ };
87
+ }
88
+
89
+ export type ToolInstance = { schema: ToolSchema; implementation: (...args: any[]) => any };
90
+
91
+ /**
92
+ * Create a complete tool definition with schema and implementation
93
+ */
94
+ export function createTool(definition: ToolDefinition): ToolInstance {
95
+ return {
96
+ schema: generateToolSchema(definition),
97
+ implementation: definition.implementation,
98
+ };
99
+ }
100
+
101
+ /**
102
+ * Extract function signature and generate schema from a JavaScript function
103
+ * This is a utility to help convert existing functions to tool schemas
104
+ */
105
+ export function createToolFromFunction(
106
+ name: string,
107
+ description: string,
108
+ fn: (...args: any[]) => any,
109
+ parameterTypes: Record<string, ToolParameter>,
110
+ outputTypes: Record<string, ToolParameter>,
111
+ options?: {
112
+ title?: string;
113
+ timeout?: number;
114
+ },
115
+ ): ToolInstance {
116
+ const definition: ToolDefinition = {
117
+ name,
118
+ description,
119
+ title: options?.title,
120
+ timeout: options?.timeout,
121
+ parameters: parameterTypes,
122
+ output: outputTypes,
123
+ implementation: fn,
124
+ };
125
+
126
+ return createTool(definition);
127
+ }
128
+
129
+ // Example usage for the sum function you provided:
130
+ export const sumTool = createToolFromFunction(
131
+ 'sum',
132
+ 'Sum two numbers',
133
+ function sum(a: number, b: number) {
134
+ const result = a + b;
135
+ return { result };
136
+ },
137
+ {
138
+ a: createParameter('number', 'First number to sum', { required: true }),
139
+ b: createParameter('number', 'Second number to sum', { required: true }),
140
+ },
141
+ {
142
+ result: createParameter('number', 'Sum of two numbers'),
143
+ },
144
+ );
145
+
146
+ // Example for the navigate_to function as shown in the user's request:
147
+ export const navigateToToolExample = createTool({
148
+ name: 'navigate_to',
149
+ description: 'Allow agent to redirect user to specific sub page like /foo or #/foo or anything like that',
150
+ title: 'Sum two numbers', // As per the user's example
151
+ timeout: 60,
152
+ parameters: {
153
+ a: createParameter('number', 'First number to sum'),
154
+ b: createParameter('number', 'Seconth number to sum'), // Keeping the typo as in the original
155
+ },
156
+ output: {
157
+ result: createParameter('number', 'Sum of two numbers'),
158
+ },
159
+ implementation: function navigateTo(a: number, b: number) {
160
+ // This is just an example - you would implement actual navigation logic here
161
+ const result = a + b;
162
+ return { result };
163
+ },
164
+ });
165
+
166
+ // Helper function to create multiple tools at once
167
+ export function createToolRegistry(tools: ToolDefinition[]): {
168
+ schemas: ToolSchema[];
169
+ implementations: Record<string, (...args: any[]) => any>;
170
+ } {
171
+ const schemas: ToolSchema[] = [];
172
+ const implementations: Record<string, (...args: any[]) => any> = {};
173
+
174
+ tools.forEach((tool) => {
175
+ const { schema, implementation } = createTool(tool);
176
+ schemas.push(schema);
177
+ implementations[tool.name] = implementation;
178
+ });
179
+
180
+ return { schemas, implementations };
181
+ }
182
+
183
+ // Utility to validate tool parameters at runtime
184
+ export function validateToolParameters(parameters: Record<string, any>, schema: ToolSchema): boolean {
185
+ const { required, properties } = schema.config.parameters;
186
+
187
+ // Check required parameters
188
+ for (const requiredParam of required) {
189
+ if (!(requiredParam in parameters)) {
190
+ throw new Error(`Missing required parameter: ${requiredParam}`);
191
+ }
192
+ }
193
+
194
+ // Type checking (basic)
195
+ for (const [paramName, paramValue] of Object.entries(parameters)) {
196
+ const paramSchema = properties[paramName];
197
+ if (paramSchema) {
198
+ if (paramSchema.type === 'number' && typeof paramValue !== 'number') {
199
+ throw new Error(`Parameter ${paramName} should be a number`);
200
+ }
201
+ if (paramSchema.type === 'string' && typeof paramValue !== 'string') {
202
+ throw new Error(`Parameter ${paramName} should be a string`);
203
+ }
204
+ if (paramSchema.type === 'boolean' && typeof paramValue !== 'boolean') {
205
+ throw new Error(`Parameter ${paramName} should be a boolean`);
206
+ }
207
+ }
208
+ }
209
+
210
+ return true;
211
+ }
package/src/types.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { PersonaTools } from 'src/protocol';
2
2
  import { PersonaLogger } from './logging';
3
3
  import { ReactNode } from 'react';
4
+ import type { ToolInstance } from './tools';
4
5
 
5
6
  export type ReadonlyJSONObject = {
6
7
  readonly [key: string]: string | number | boolean | null | ReadonlyJSONObject | ReadonlyArray<ReadonlyJSONObject>;
@@ -79,7 +80,7 @@ export type PersonaSource = {
79
80
  };
80
81
 
81
82
  export type PersonaCommand = {
82
- command: 'get_mcp_assets' | 'set_initial_context';
83
+ command: 'get_mcp_assets' | 'set_initial_context' | 'set_local_tools';
83
84
  arguments: Record<string, unknown>;
84
85
  };
85
86
 
@@ -182,5 +183,8 @@ export type PersonaConfig = PersonaBaseConfig &
182
183
  websocket?: PersonaProtocolBaseConfig | boolean;
183
184
  };
184
185
 
185
- tools?: PersonaTools;
186
+ /**
187
+ * Tools can be provided as an object (legacy) or as an array of { schema, implementation } (recommended)
188
+ */
189
+ tools?: PersonaTools | ToolInstance[];
186
190
  };