struere 0.12.4 → 0.12.6

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.
@@ -181,6 +181,7 @@ async function syncViaHttp(apiKey, payload) {
181
181
  },
182
182
  body: JSON.stringify({
183
183
  agents: payload.agents,
184
+ tools: payload.tools,
184
185
  entityTypes: payload.entityTypes,
185
186
  roles: payload.roles,
186
187
  evalSuites: payload.evalSuites,
@@ -2728,6 +2729,13 @@ function extractSyncPayload(resources) {
2728
2729
  customToolsMap.set(tool.name, tool);
2729
2730
  }
2730
2731
  const agents = resources.agents.map((agent) => extractAgentPayload(agent, customToolsMap));
2732
+ const tools = resources.customTools.length > 0 ? resources.customTools.map((tool) => ({
2733
+ name: tool.name,
2734
+ description: tool.description,
2735
+ parameters: tool.parameters || { type: "object", properties: {} },
2736
+ handlerCode: extractHandlerCode(tool._originalHandler || tool.handler),
2737
+ ...tool.templateOnly && { templateOnly: true }
2738
+ })) : undefined;
2731
2739
  const entityTypes = resources.entityTypes.map((et) => ({
2732
2740
  name: et.name,
2733
2741
  slug: et.slug,
@@ -2840,7 +2848,7 @@ function extractSyncPayload(resources) {
2840
2848
  metadata: r.metadata
2841
2849
  }))
2842
2850
  })) : undefined;
2843
- return { agents, entityTypes, roles, evalSuites, triggers, routers, fixtures };
2851
+ return { agents, entityTypes, roles, tools, evalSuites, triggers, routers, fixtures };
2844
2852
  }
2845
2853
  function extractAgentPayload(agent, customToolsMap) {
2846
2854
  let systemPrompt;
@@ -2855,25 +2863,11 @@ function extractAgentPayload(agent, customToolsMap) {
2855
2863
  }
2856
2864
  const tools = (agent.tools || []).map((toolName) => {
2857
2865
  const isBuiltin = BUILTIN_TOOLS.includes(toolName);
2858
- if (isBuiltin) {
2859
- return {
2860
- name: toolName,
2861
- description: getBuiltinToolDescription(toolName),
2862
- parameters: getBuiltinToolParameters(toolName)
2863
- };
2864
- }
2865
- const customTool = customToolsMap.get(toolName);
2866
- if (!customTool) {
2866
+ if (!isBuiltin && !customToolsMap.has(toolName)) {
2867
2867
  const available = customToolsMap.size > 0 ? `Available custom tools: ${Array.from(customToolsMap.keys()).join(", ")}` : "No custom tools were loaded from tools/index.ts";
2868
2868
  throw new Error(`Agent "${agent.name}" references tool "${toolName}" but it was not found. ${available}`);
2869
2869
  }
2870
- return {
2871
- name: customTool.name,
2872
- description: customTool.description,
2873
- parameters: customTool.parameters || { type: "object", properties: {} },
2874
- handlerCode: extractHandlerCode(customTool._originalHandler || customTool.handler),
2875
- ...customTool.templateOnly && { templateOnly: true }
2876
- };
2870
+ return toolName;
2877
2871
  });
2878
2872
  return {
2879
2873
  name: agent.name,
@@ -2891,352 +2885,6 @@ function extractAgentPayload(agent, customToolsMap) {
2891
2885
  tools
2892
2886
  };
2893
2887
  }
2894
- function getBuiltinToolDescription(name) {
2895
- const descriptions = {
2896
- "entity.create": "Create a new entity of a specified type",
2897
- "entity.get": "Get an entity by its ID",
2898
- "entity.query": "Query entities by type with optional filters",
2899
- "entity.update": "Update an existing entity by ID",
2900
- "entity.delete": "Delete an entity by ID",
2901
- "calendar.list": "List Google Calendar events for a user within a time range",
2902
- "calendar.create": "Create a Google Calendar event on a user's calendar",
2903
- "calendar.update": "Update an existing Google Calendar event",
2904
- "calendar.delete": "Delete a Google Calendar event",
2905
- "calendar.freeBusy": "Check free/busy availability on a user's Google Calendar",
2906
- "whatsapp.send": "Send a text message via WhatsApp",
2907
- "whatsapp.sendTemplate": "Send a pre-approved template message via WhatsApp (works outside 24h window)",
2908
- "whatsapp.sendInteractive": "Send an interactive button message via WhatsApp (max 3 buttons)",
2909
- "whatsapp.sendMedia": "Send an image or audio message via WhatsApp",
2910
- "whatsapp.listTemplates": "List available WhatsApp message templates",
2911
- "whatsapp.getConversation": "Get WhatsApp conversation history with a phone number",
2912
- "whatsapp.getStatus": "Get WhatsApp connection status for this organization",
2913
- "agent.chat": "Send a message to another agent and get its response",
2914
- "airtable.listBases": "List all Airtable bases accessible with the configured token",
2915
- "airtable.listTables": "List all tables in an Airtable base",
2916
- "airtable.listRecords": "List records from an Airtable table with optional filtering and sorting",
2917
- "airtable.getRecord": "Get a single record from an Airtable table by ID",
2918
- "airtable.createRecords": "Create up to 10 records in an Airtable table",
2919
- "airtable.updateRecords": "Update up to 10 records in an Airtable table",
2920
- "airtable.deleteRecords": "Delete up to 10 records from an Airtable table",
2921
- "email.send": "Send an email via Resend",
2922
- "payment.create": "Create a payment link via Flow.cl and return the URL",
2923
- "payment.getStatus": "Check the current status of a payment",
2924
- "web.search": "Search the web and return relevant results with snippets",
2925
- "web.fetch": "Fetch a web page and return its content as clean markdown"
2926
- };
2927
- return descriptions[name] || name;
2928
- }
2929
- function getBuiltinToolParameters(name) {
2930
- const schemas = {
2931
- "entity.create": {
2932
- type: "object",
2933
- properties: {
2934
- type: { type: "string", description: 'The entity type slug (e.g., "customer", "order")' },
2935
- data: { type: "object", description: "The entity data matching the entity type schema" },
2936
- status: { type: "string", description: 'Optional status (defaults to "active")' }
2937
- },
2938
- required: ["type", "data"]
2939
- },
2940
- "entity.get": {
2941
- type: "object",
2942
- properties: {
2943
- id: { type: "string", description: "The entity ID to retrieve" }
2944
- },
2945
- required: ["id"]
2946
- },
2947
- "entity.query": {
2948
- type: "object",
2949
- properties: {
2950
- type: { type: "string", description: 'The entity type slug to query (e.g., "customer", "order")' },
2951
- filters: { type: "object", description: 'Optional filters to apply (e.g., {"data.status": "active"})' },
2952
- status: { type: "string", description: "Filter by entity status" },
2953
- limit: { type: "number", description: "Maximum number of results (default 100)" }
2954
- },
2955
- required: ["type"]
2956
- },
2957
- "entity.update": {
2958
- type: "object",
2959
- properties: {
2960
- id: { type: "string", description: "The entity ID to update" },
2961
- type: { type: "string", description: 'The entity type slug (e.g., "session", "teacher"). Must match the actual type of the entity being updated.' },
2962
- data: { type: "object", description: "The fields to update (merged with existing data)" },
2963
- status: { type: "string", description: "Optional new status" }
2964
- },
2965
- required: ["id", "type", "data"]
2966
- },
2967
- "entity.delete": {
2968
- type: "object",
2969
- properties: {
2970
- id: { type: "string", description: "The entity ID to delete" }
2971
- },
2972
- required: ["id"]
2973
- },
2974
- "calendar.list": {
2975
- type: "object",
2976
- properties: {
2977
- userId: { type: "string", description: "User ID (Convex or Clerk) whose calendar to query" },
2978
- timeMin: { type: "string", description: "Start of time range (ISO 8601 datetime)" },
2979
- timeMax: { type: "string", description: "End of time range (ISO 8601 datetime)" },
2980
- maxResults: { type: "number", description: "Maximum number of events to return" }
2981
- },
2982
- required: ["userId", "timeMin", "timeMax"]
2983
- },
2984
- "calendar.create": {
2985
- type: "object",
2986
- properties: {
2987
- userId: { type: "string", description: "User ID (Convex or Clerk) whose calendar to create the event on" },
2988
- summary: { type: "string", description: "Event title" },
2989
- startTime: { type: "string", description: "Event start time (ISO 8601 datetime)" },
2990
- endTime: { type: "string", description: "Event end time (ISO 8601 datetime). Provide either endTime or durationMinutes" },
2991
- durationMinutes: { type: "number", description: "Duration in minutes. Used to calculate endTime if endTime is not provided" },
2992
- description: { type: "string", description: "Event description" },
2993
- attendees: { type: "array", items: { type: "string" }, description: "List of attendee email addresses" },
2994
- timeZone: { type: "string", description: 'Time zone (e.g., "America/Santiago")' },
2995
- addGoogleMeet: { type: "boolean", description: "Set to true to automatically create a Google Meet video conference link for this event" }
2996
- },
2997
- required: ["userId", "summary", "startTime"]
2998
- },
2999
- "calendar.update": {
3000
- type: "object",
3001
- properties: {
3002
- userId: { type: "string", description: "User ID (Convex or Clerk) whose calendar contains the event" },
3003
- eventId: { type: "string", description: "Google Calendar event ID to update" },
3004
- summary: { type: "string", description: "New event title" },
3005
- startTime: { type: "string", description: "New start time (ISO 8601 datetime)" },
3006
- endTime: { type: "string", description: "New end time (ISO 8601 datetime)" },
3007
- description: { type: "string", description: "New event description" },
3008
- attendees: { type: "array", items: { type: "string" }, description: "Updated list of attendee emails" },
3009
- status: { type: "string", description: "Event status (confirmed, tentative, cancelled)" }
3010
- },
3011
- required: ["userId", "eventId"]
3012
- },
3013
- "calendar.delete": {
3014
- type: "object",
3015
- properties: {
3016
- userId: { type: "string", description: "User ID (Convex or Clerk) whose calendar contains the event" },
3017
- eventId: { type: "string", description: "Google Calendar event ID to delete" }
3018
- },
3019
- required: ["userId", "eventId"]
3020
- },
3021
- "calendar.freeBusy": {
3022
- type: "object",
3023
- properties: {
3024
- userId: { type: "string", description: "User ID (Convex or Clerk) whose availability to check" },
3025
- timeMin: { type: "string", description: "Start of time range (ISO 8601 datetime)" },
3026
- timeMax: { type: "string", description: "End of time range (ISO 8601 datetime)" }
3027
- },
3028
- required: ["userId", "timeMin", "timeMax"]
3029
- },
3030
- "whatsapp.send": {
3031
- type: "object",
3032
- properties: {
3033
- to: { type: "string", description: 'Recipient phone number in E.164 format (e.g., "+15551234567")' },
3034
- text: { type: "string", description: "The text message to send" }
3035
- },
3036
- required: ["to", "text"]
3037
- },
3038
- "whatsapp.sendTemplate": {
3039
- type: "object",
3040
- properties: {
3041
- to: { type: "string", description: 'Recipient phone number in E.164 format (e.g., "+15551234567")' },
3042
- templateName: { type: "string", description: "Name of the approved template to send" },
3043
- language: { type: "string", description: 'Template language code (e.g., "en_US")' },
3044
- components: {
3045
- type: "array",
3046
- description: "Optional template components with parameter values",
3047
- items: {
3048
- type: "object",
3049
- properties: {
3050
- type: { type: "string", description: 'Component type (e.g., "body", "header")' },
3051
- parameters: {
3052
- type: "array",
3053
- items: {
3054
- type: "object",
3055
- properties: {
3056
- type: { type: "string", description: 'Parameter type (e.g., "text")' },
3057
- text: { type: "string", description: "Parameter text value" },
3058
- parameterName: { type: "string", description: "Named parameter name (for NAMED format templates)" }
3059
- },
3060
- required: ["type"]
3061
- }
3062
- }
3063
- },
3064
- required: ["type", "parameters"]
3065
- }
3066
- }
3067
- },
3068
- required: ["to", "templateName", "language"]
3069
- },
3070
- "whatsapp.sendInteractive": {
3071
- type: "object",
3072
- properties: {
3073
- to: { type: "string", description: 'Recipient phone number in E.164 format (e.g., "+15551234567")' },
3074
- bodyText: { type: "string", description: "The message body text" },
3075
- buttons: {
3076
- type: "array",
3077
- description: "Action buttons (1-3 buttons, max 20 chars per title)",
3078
- items: {
3079
- type: "object",
3080
- properties: {
3081
- id: { type: "string", description: "Unique button identifier returned on click" },
3082
- title: { type: "string", description: "Button label shown to user (max 20 characters)" }
3083
- },
3084
- required: ["id", "title"]
3085
- }
3086
- },
3087
- footerText: { type: "string", description: "Optional footer text below the buttons" }
3088
- },
3089
- required: ["to", "bodyText", "buttons"]
3090
- },
3091
- "whatsapp.sendMedia": {
3092
- type: "object",
3093
- properties: {
3094
- to: { type: "string", description: 'Recipient phone number in E.164 format (e.g., "+15551234567")' },
3095
- mediaUrl: { type: "string", description: "Public URL of the media file to send" },
3096
- mediaType: { type: "string", enum: ["image", "audio"], description: "Type of media to send" },
3097
- caption: { type: "string", description: "Optional caption (only supported for images)" }
3098
- },
3099
- required: ["to", "mediaUrl", "mediaType"]
3100
- },
3101
- "whatsapp.listTemplates": {
3102
- type: "object",
3103
- properties: {}
3104
- },
3105
- "whatsapp.getConversation": {
3106
- type: "object",
3107
- properties: {
3108
- phoneNumber: { type: "string", description: "Phone number to get conversation history for" },
3109
- limit: { type: "number", description: "Maximum number of messages to return" }
3110
- },
3111
- required: ["phoneNumber"]
3112
- },
3113
- "whatsapp.getStatus": {
3114
- type: "object",
3115
- properties: {}
3116
- },
3117
- "agent.chat": {
3118
- type: "object",
3119
- properties: {
3120
- agent: { type: "string", description: "Target agent slug to communicate with" },
3121
- message: { type: "string", description: "The message to send to the agent" },
3122
- context: { type: "object", description: "Optional context data to pass to the target agent" }
3123
- },
3124
- required: ["agent", "message"]
3125
- },
3126
- "airtable.listBases": {
3127
- type: "object",
3128
- properties: {}
3129
- },
3130
- "airtable.listTables": {
3131
- type: "object",
3132
- properties: {
3133
- baseId: { type: "string", description: 'Airtable base ID (e.g., "appXXXXXXXXXXXXXX")' }
3134
- },
3135
- required: ["baseId"]
3136
- },
3137
- "airtable.listRecords": {
3138
- type: "object",
3139
- properties: {
3140
- baseId: { type: "string", description: "Airtable base ID" },
3141
- tableIdOrName: { type: "string", description: "Table ID or name" },
3142
- pageSize: { type: "number", description: "Number of records per page (max 100)" },
3143
- offset: { type: "string", description: "Pagination offset from a previous response" },
3144
- filterByFormula: { type: "string", description: `Airtable formula to filter records (e.g., "{Status} = 'Active'")` },
3145
- sort: { type: "array", items: { type: "object", properties: { field: { type: "string" }, direction: { type: "string", enum: ["asc", "desc"] } }, required: ["field"] }, description: "Sort configuration" },
3146
- fields: { type: "array", items: { type: "string" }, description: "Only return specific field names" },
3147
- view: { type: "string", description: "Name or ID of an Airtable view to use" }
3148
- },
3149
- required: ["baseId", "tableIdOrName"]
3150
- },
3151
- "airtable.getRecord": {
3152
- type: "object",
3153
- properties: {
3154
- baseId: { type: "string", description: "Airtable base ID" },
3155
- tableIdOrName: { type: "string", description: "Table ID or name" },
3156
- recordId: { type: "string", description: 'Record ID (e.g., "recXXXXXXXXXXXXXX")' }
3157
- },
3158
- required: ["baseId", "tableIdOrName", "recordId"]
3159
- },
3160
- "airtable.createRecords": {
3161
- type: "object",
3162
- properties: {
3163
- baseId: { type: "string", description: "Airtable base ID" },
3164
- tableIdOrName: { type: "string", description: "Table ID or name" },
3165
- records: { type: "array", items: { type: "object", properties: { fields: { type: "object", description: "Field values for the record" } }, required: ["fields"] }, description: "Array of records to create (max 10)" }
3166
- },
3167
- required: ["baseId", "tableIdOrName", "records"]
3168
- },
3169
- "airtable.updateRecords": {
3170
- type: "object",
3171
- properties: {
3172
- baseId: { type: "string", description: "Airtable base ID" },
3173
- tableIdOrName: { type: "string", description: "Table ID or name" },
3174
- records: { type: "array", items: { type: "object", properties: { id: { type: "string", description: "Record ID to update" }, fields: { type: "object", description: "Field values to update" } }, required: ["id", "fields"] }, description: "Array of records to update (max 10)" }
3175
- },
3176
- required: ["baseId", "tableIdOrName", "records"]
3177
- },
3178
- "airtable.deleteRecords": {
3179
- type: "object",
3180
- properties: {
3181
- baseId: { type: "string", description: "Airtable base ID" },
3182
- tableIdOrName: { type: "string", description: "Table ID or name" },
3183
- recordIds: { type: "array", items: { type: "string" }, description: "Array of record IDs to delete (max 10)" }
3184
- },
3185
- required: ["baseId", "tableIdOrName", "recordIds"]
3186
- },
3187
- "email.send": {
3188
- type: "object",
3189
- properties: {
3190
- to: { type: "string", description: "Recipient email address" },
3191
- subject: { type: "string", description: "Email subject line" },
3192
- html: { type: "string", description: "HTML body content" },
3193
- text: { type: "string", description: "Plain text body content" },
3194
- replyTo: { type: "string", description: "Reply-to email address" }
3195
- },
3196
- required: ["to", "subject"]
3197
- },
3198
- "payment.create": {
3199
- type: "object",
3200
- properties: {
3201
- amount: { type: "number", description: "Payment amount in the smallest currency unit" },
3202
- description: { type: "string", description: "Description of the payment" },
3203
- currency: { type: "string", description: "Currency code (defaults to CLP)" },
3204
- customerEmail: { type: "string", description: "Customer email address" },
3205
- entityId: { type: "string", description: "Optional entity ID to link the payment to" }
3206
- },
3207
- required: ["amount", "description"]
3208
- },
3209
- "payment.getStatus": {
3210
- type: "object",
3211
- properties: {
3212
- entityId: { type: "string", description: "Payment entity ID to check status for" }
3213
- },
3214
- required: ["entityId"]
3215
- },
3216
- "web.search": {
3217
- type: "object",
3218
- properties: {
3219
- query: { type: "string", description: "Search query" },
3220
- maxResults: { type: "number", description: "Maximum number of results (default: 5, max: 20)" },
3221
- site: { type: "array", items: { type: "string" }, description: "Only include results from these domains" },
3222
- gl: { type: "string", description: 'Country code for localized results (e.g., "US", "GB")' },
3223
- hl: { type: "string", description: 'Language code (ISO 639-1, e.g., "en", "es")' }
3224
- },
3225
- required: ["query"]
3226
- },
3227
- "web.fetch": {
3228
- type: "object",
3229
- properties: {
3230
- url: { type: "string", description: "URL of the page to fetch" },
3231
- targetSelector: { type: "string", description: "CSS selector to extract specific content from the page" },
3232
- removeSelector: { type: "string", description: "CSS selector to remove elements from the page before extraction" },
3233
- tokenBudget: { type: "number", description: "Maximum number of tokens in the response content" }
3234
- },
3235
- required: ["url"]
3236
- }
3237
- };
3238
- return schemas[name] || { type: "object", properties: {} };
3239
- }
3240
2888
  function extractHandlerCode(handler) {
3241
2889
  const code = handler.toString();
3242
2890
  const arrowBlockMatch = code.match(/(?:async\s*)?\([^)]*\)\s*=>\s*\{([\s\S]*)\}\s*$/);
@@ -3266,6 +2914,7 @@ ${resources.errors.join(`
3266
2914
  const payload = extractSyncPayload(resources);
3267
2915
  const devResult = await syncOrganization({
3268
2916
  agents: payload.agents,
2917
+ tools: payload.tools,
3269
2918
  entityTypes: payload.entityTypes,
3270
2919
  roles: payload.roles,
3271
2920
  triggers: payload.triggers,
@@ -3280,6 +2929,7 @@ ${resources.errors.join(`
3280
2929
  if (hasEvalContent) {
3281
2930
  const evalResult = await syncOrganization({
3282
2931
  agents: payload.agents,
2932
+ tools: payload.tools,
3283
2933
  entityTypes: payload.entityTypes,
3284
2934
  roles: payload.roles,
3285
2935
  evalSuites: payload.evalSuites,
@@ -3341,6 +2991,7 @@ ${resources.errors.join(`
3341
2991
  if (environment === "eval") {
3342
2992
  const result = await syncOrganization({
3343
2993
  agents: payload.agents,
2994
+ tools: payload.tools,
3344
2995
  entityTypes: payload.entityTypes,
3345
2996
  roles: payload.roles,
3346
2997
  evalSuites: payload.evalSuites,
@@ -3421,7 +3072,7 @@ var syncCommand = new Command5("sync").description("Sync resources to Convex and
3421
3072
  process.exit(1);
3422
3073
  }
3423
3074
  if (!jsonMode && !options.dryRun)
3424
- output.succeed(`Loaded ${resources.agents.length} agents, ${resources.entityTypes.length} data types, ${resources.roles.length} roles`);
3075
+ output.succeed(`Loaded ${resources.agents.length} agents, ${resources.entityTypes.length} data types, ${resources.roles.length} roles, ${resources.customTools.length} custom tools`);
3425
3076
  } catch (error) {
3426
3077
  if (jsonMode) {
3427
3078
  console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : String(error) }));
@@ -3972,6 +3623,7 @@ var deployCommand = new Command7("deploy").description("Deploy all resources to
3972
3623
  try {
3973
3624
  const syncResult = await syncOrganization({
3974
3625
  agents: payload.agents,
3626
+ tools: payload.tools,
3975
3627
  entityTypes: payload.entityTypes,
3976
3628
  roles: payload.roles,
3977
3629
  triggers: payload.triggers,
@@ -4456,6 +4108,8 @@ var statusCommand = new Command11("status").description("Compare local vs remote
4456
4108
  const devEntityTypeSlugs = new Set(devState.entityTypes.map((et) => et.slug));
4457
4109
  const localRoleNames = new Set(localResources.roles.map((r) => r.name));
4458
4110
  const devRoleNames = new Set(devState.roles.map((r) => r.name));
4111
+ const localToolNames = new Set(localResources.customTools.map((t) => t.name));
4112
+ const devToolNames = new Set((devState.tools || []).map((t) => t.name));
4459
4113
  const localRouterSlugs = new Set(localResources.routers.map((r) => r.slug));
4460
4114
  const devRouterSlugs = new Set((devState.routers || []).map((r) => r.slug));
4461
4115
  if (opts.json) {
@@ -4562,6 +4216,26 @@ var statusCommand = new Command11("status").description("Compare local vs remote
4562
4216
  }
4563
4217
  }
4564
4218
  console.log();
4219
+ console.log(chalk12.bold("Custom Tools"));
4220
+ console.log(chalk12.gray("\u2500".repeat(60)));
4221
+ if (localResources.customTools.length === 0 && (devState.tools || []).length === 0) {
4222
+ console.log(chalk12.gray(" No custom tools"));
4223
+ } else {
4224
+ for (const tool of localResources.customTools) {
4225
+ const remote = (devState.tools || []).find((t) => t.name === tool.name);
4226
+ if (remote) {
4227
+ console.log(` ${chalk12.green("\u25CF")} ${chalk12.cyan(tool.name)}`);
4228
+ } else {
4229
+ console.log(` ${chalk12.blue("+")} ${chalk12.cyan(tool.name)} - ${chalk12.blue("new")}`);
4230
+ }
4231
+ }
4232
+ for (const remote of devState.tools || []) {
4233
+ if (!localToolNames.has(remote.name)) {
4234
+ console.log(` ${chalk12.red("-")} ${remote.name} - ${chalk12.red("will be deleted")}`);
4235
+ }
4236
+ }
4237
+ }
4238
+ console.log();
4565
4239
  console.log(chalk12.gray("Legend:"));
4566
4240
  console.log(chalk12.gray(" "), chalk12.green("\u25CF"), "Synced", chalk12.yellow("\u25CB"), "Not in production", chalk12.blue("+"), "New", chalk12.red("-"), "Will be deleted");
4567
4241
  console.log();
@@ -4580,16 +4254,6 @@ import { join as join9 } from "path";
4580
4254
  init_convex();
4581
4255
 
4582
4256
  // src/cli/utils/generator.ts
4583
- var BUILTIN_TOOLS2 = [
4584
- "entity.create",
4585
- "entity.get",
4586
- "entity.query",
4587
- "entity.update",
4588
- "entity.delete",
4589
- "agent.chat",
4590
- "web.search",
4591
- "web.fetch"
4592
- ];
4593
4257
  function escapeTemplateLiteral(str) {
4594
4258
  return str.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
4595
4259
  }
@@ -4625,8 +4289,7 @@ ${" ".repeat(indent)}}`;
4625
4289
  return JSON.stringify(value);
4626
4290
  }
4627
4291
  function generateAgentFile(agent) {
4628
- const toolNames = agent.tools.map((t) => t.name);
4629
- const toolsArray = toolNames.map((n) => ` "${n}"`).join(`,
4292
+ const toolsArray = agent.tools.map((n) => ` "${n}"`).join(`,
4630
4293
  `);
4631
4294
  const modelParts = [
4632
4295
  ` model: "${agent.model.model}"`
@@ -4901,22 +4564,6 @@ function generateIndexFile(type, slugs) {
4901
4564
  `) + `
4902
4565
  `;
4903
4566
  }
4904
- function collectCustomTools(agents) {
4905
- const seen = new Map;
4906
- for (const agent of agents) {
4907
- for (const tool of agent.tools) {
4908
- if (!BUILTIN_TOOLS2.includes(tool.name) && !seen.has(tool.name)) {
4909
- seen.set(tool.name, {
4910
- name: tool.name,
4911
- description: tool.description,
4912
- parameters: tool.parameters,
4913
- handlerCode: tool.handlerCode
4914
- });
4915
- }
4916
- }
4917
- }
4918
- return Array.from(seen.values());
4919
- }
4920
4567
 
4921
4568
  // src/cli/commands/pull.ts
4922
4569
  var pullCommand = new Command12("pull").description("Pull remote resources to local files").option("--force", "Overwrite existing local files").option("--env <environment>", "Environment to pull from", "development").option("--dry-run", "Show what would be written without writing").option("--json", "Output raw JSON").action(async (options) => {
@@ -5057,7 +4704,7 @@ var pullCommand = new Command12("pull").description("Pull remote resources to lo
5057
4704
  const content = generateRouterFile(router);
5058
4705
  writeOrSkip(`routers/${router.slug}.ts`, content);
5059
4706
  }
5060
- const customTools = collectCustomTools(state.agents);
4707
+ const customTools = state.tools || [];
5061
4708
  if (customTools.length > 0) {
5062
4709
  const content = generateToolsFile(customTools);
5063
4710
  writeOrSkip("tools/index.ts", content);
@@ -9063,7 +8710,7 @@ whatsappCommand.command("set-agent <connection> <agent-slug>").description("Assi
9063
8710
  // package.json
9064
8711
  var package_default = {
9065
8712
  name: "struere",
9066
- version: "0.12.4",
8713
+ version: "0.12.6",
9067
8714
  description: "Build, test, and deploy AI agents",
9068
8715
  keywords: [
9069
8716
  "ai",
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAcnC,eAAO,MAAM,aAAa,SAqUtB,CAAA"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAcnC,eAAO,MAAM,aAAa,SAsUtB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/pull.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAuBnC,eAAO,MAAM,WAAW,SA0OpB,CAAA"}
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/pull.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAsBnC,eAAO,MAAM,WAAW,SA0OpB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAWnC,eAAO,MAAM,aAAa,SAgQtB,CAAA"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAWnC,eAAO,MAAM,aAAa,SA0RtB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKnC,OAAO,EAAkC,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AACnG,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAMxE,KAAK,WAAW,GAAG,WAAW,CAAC,aAAa,CAAC,CAAA;AAE7C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAwC7F;AAED,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,eAAe,EAC1B,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC,eAAe,EAAE,CAAC,CAsC5B;AAwCD,eAAO,MAAM,WAAW,SA2MpB,CAAA"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKnC,OAAO,EAAkC,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AACnG,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAMxE,KAAK,WAAW,GAAG,WAAW,CAAC,aAAa,CAAC,CAAA;AAE7C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA0C7F;AAED,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,eAAe,EAC1B,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC,eAAe,EAAE,CAAC,CAsC5B;AAyCD,eAAO,MAAM,WAAW,SA2MpB,CAAA"}