struere 0.12.3 → 0.12.5
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/dist/bin/struere.js +91 -423
- package/dist/cli/commands/deploy.d.ts.map +1 -1
- package/dist/cli/commands/docs.d.ts.map +1 -1
- package/dist/cli/commands/pull.d.ts.map +1 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/sync.d.ts.map +1 -1
- package/dist/cli/index.js +91 -423
- package/dist/cli/utils/convex.d.ts +31 -19
- package/dist/cli/utils/convex.d.ts.map +1 -1
- package/dist/cli/utils/extractor.d.ts +12 -9
- package/dist/cli/utils/extractor.d.ts.map +1 -1
- package/dist/cli/utils/generator.d.ts +2 -10
- package/dist/cli/utils/generator.d.ts.map +1 -1
- package/dist/cli/utils/plugin.d.ts +1 -1
- package/dist/cli/utils/plugin.d.ts.map +1 -1
- package/dist/cli/utils/triggers.d.ts +6 -2
- package/dist/cli/utils/triggers.d.ts.map +1 -1
- package/dist/define/trigger.d.ts.map +1 -1
- package/dist/index.js +25 -4
- package/dist/types.d.ts +23 -7
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/bin/struere.js
CHANGED
|
@@ -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,
|
|
@@ -1682,8 +1683,13 @@ function defineTrigger(config) {
|
|
|
1682
1683
|
if (!config.name) throw new Error('Trigger name is required')
|
|
1683
1684
|
if (!config.slug) throw new Error('Trigger slug is required')
|
|
1684
1685
|
if (!config.on) throw new Error('Trigger "on" configuration is required')
|
|
1685
|
-
if (
|
|
1686
|
-
|
|
1686
|
+
if (config.on.schedule) {
|
|
1687
|
+
const parts = config.on.schedule.trim().split(/s+/)
|
|
1688
|
+
if (parts.length !== 5) throw new Error('Invalid cron expression: expected 5 fields, got ' + parts.length)
|
|
1689
|
+
} else {
|
|
1690
|
+
if (!config.on.entityType) throw new Error('Trigger entityType is required')
|
|
1691
|
+
if (!config.on.action || !VALID_ACTIONS.includes(config.on.action)) throw new Error('Trigger action must be one of: ' + VALID_ACTIONS.join(', '))
|
|
1692
|
+
}
|
|
1687
1693
|
if (!config.actions || config.actions.length === 0) throw new Error('Trigger must have at least one action')
|
|
1688
1694
|
for (const action of config.actions) {
|
|
1689
1695
|
if (!action.tool) throw new Error('Trigger action tool is required')
|
|
@@ -2195,7 +2201,8 @@ function buildProjectContext(orgName, resources) {
|
|
|
2195
2201
|
lines.push("");
|
|
2196
2202
|
lines.push(`### Triggers (${resources.triggers.length})`);
|
|
2197
2203
|
for (const trigger of resources.triggers) {
|
|
2198
|
-
|
|
2204
|
+
const onDesc = "schedule" in trigger.on ? `cron \`${trigger.on.schedule}\`` : `\`${trigger.on.entityType}.${trigger.on.action}\``;
|
|
2205
|
+
lines.push(`- **${trigger.name}** (\`${trigger.slug}\`) \u2014 on ${onDesc}`);
|
|
2199
2206
|
}
|
|
2200
2207
|
}
|
|
2201
2208
|
if (resources.customTools.length > 0) {
|
|
@@ -2722,6 +2729,13 @@ function extractSyncPayload(resources) {
|
|
|
2722
2729
|
customToolsMap.set(tool.name, tool);
|
|
2723
2730
|
}
|
|
2724
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;
|
|
2725
2739
|
const entityTypes = resources.entityTypes.map((et) => ({
|
|
2726
2740
|
name: et.name,
|
|
2727
2741
|
slug: et.slug,
|
|
@@ -2775,21 +2789,26 @@ function extractSyncPayload(resources) {
|
|
|
2775
2789
|
contextParams: c.contextParams
|
|
2776
2790
|
}))
|
|
2777
2791
|
})) : undefined;
|
|
2778
|
-
const triggers = resources.triggers.length > 0 ? resources.triggers.map((t) =>
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2792
|
+
const triggers = resources.triggers.length > 0 ? resources.triggers.map((t) => {
|
|
2793
|
+
const isScheduled = "schedule" in t.on && typeof t.on.schedule === "string";
|
|
2794
|
+
return {
|
|
2795
|
+
name: t.name,
|
|
2796
|
+
slug: t.slug,
|
|
2797
|
+
description: t.description,
|
|
2798
|
+
entityType: isScheduled ? undefined : t.on.entityType,
|
|
2799
|
+
action: isScheduled ? undefined : t.on.action,
|
|
2800
|
+
condition: isScheduled ? undefined : t.on.condition,
|
|
2801
|
+
cronSchedule: isScheduled ? t.on.schedule : undefined,
|
|
2802
|
+
cronTimezone: isScheduled ? t.on.timezone : undefined,
|
|
2803
|
+
actions: t.actions.map((a) => ({
|
|
2804
|
+
tool: a.tool,
|
|
2805
|
+
args: a.args,
|
|
2806
|
+
as: a.as
|
|
2807
|
+
})),
|
|
2808
|
+
schedule: t.schedule,
|
|
2809
|
+
retry: t.retry
|
|
2810
|
+
};
|
|
2811
|
+
}) : undefined;
|
|
2793
2812
|
const routers = resources.routers.length > 0 ? resources.routers.map((r) => ({
|
|
2794
2813
|
name: r.name,
|
|
2795
2814
|
slug: r.slug,
|
|
@@ -2829,7 +2848,7 @@ function extractSyncPayload(resources) {
|
|
|
2829
2848
|
metadata: r.metadata
|
|
2830
2849
|
}))
|
|
2831
2850
|
})) : undefined;
|
|
2832
|
-
return { agents, entityTypes, roles, evalSuites, triggers, routers, fixtures };
|
|
2851
|
+
return { agents, entityTypes, roles, tools, evalSuites, triggers, routers, fixtures };
|
|
2833
2852
|
}
|
|
2834
2853
|
function extractAgentPayload(agent, customToolsMap) {
|
|
2835
2854
|
let systemPrompt;
|
|
@@ -2844,25 +2863,11 @@ function extractAgentPayload(agent, customToolsMap) {
|
|
|
2844
2863
|
}
|
|
2845
2864
|
const tools = (agent.tools || []).map((toolName) => {
|
|
2846
2865
|
const isBuiltin = BUILTIN_TOOLS.includes(toolName);
|
|
2847
|
-
if (isBuiltin) {
|
|
2848
|
-
return {
|
|
2849
|
-
name: toolName,
|
|
2850
|
-
description: getBuiltinToolDescription(toolName),
|
|
2851
|
-
parameters: getBuiltinToolParameters(toolName)
|
|
2852
|
-
};
|
|
2853
|
-
}
|
|
2854
|
-
const customTool = customToolsMap.get(toolName);
|
|
2855
|
-
if (!customTool) {
|
|
2866
|
+
if (!isBuiltin && !customToolsMap.has(toolName)) {
|
|
2856
2867
|
const available = customToolsMap.size > 0 ? `Available custom tools: ${Array.from(customToolsMap.keys()).join(", ")}` : "No custom tools were loaded from tools/index.ts";
|
|
2857
2868
|
throw new Error(`Agent "${agent.name}" references tool "${toolName}" but it was not found. ${available}`);
|
|
2858
2869
|
}
|
|
2859
|
-
return
|
|
2860
|
-
name: customTool.name,
|
|
2861
|
-
description: customTool.description,
|
|
2862
|
-
parameters: customTool.parameters || { type: "object", properties: {} },
|
|
2863
|
-
handlerCode: extractHandlerCode(customTool._originalHandler || customTool.handler),
|
|
2864
|
-
...customTool.templateOnly && { templateOnly: true }
|
|
2865
|
-
};
|
|
2870
|
+
return toolName;
|
|
2866
2871
|
});
|
|
2867
2872
|
return {
|
|
2868
2873
|
name: agent.name,
|
|
@@ -2880,352 +2885,6 @@ function extractAgentPayload(agent, customToolsMap) {
|
|
|
2880
2885
|
tools
|
|
2881
2886
|
};
|
|
2882
2887
|
}
|
|
2883
|
-
function getBuiltinToolDescription(name) {
|
|
2884
|
-
const descriptions = {
|
|
2885
|
-
"entity.create": "Create a new entity of a specified type",
|
|
2886
|
-
"entity.get": "Get an entity by its ID",
|
|
2887
|
-
"entity.query": "Query entities by type with optional filters",
|
|
2888
|
-
"entity.update": "Update an existing entity by ID",
|
|
2889
|
-
"entity.delete": "Delete an entity by ID",
|
|
2890
|
-
"calendar.list": "List Google Calendar events for a user within a time range",
|
|
2891
|
-
"calendar.create": "Create a Google Calendar event on a user's calendar",
|
|
2892
|
-
"calendar.update": "Update an existing Google Calendar event",
|
|
2893
|
-
"calendar.delete": "Delete a Google Calendar event",
|
|
2894
|
-
"calendar.freeBusy": "Check free/busy availability on a user's Google Calendar",
|
|
2895
|
-
"whatsapp.send": "Send a text message via WhatsApp",
|
|
2896
|
-
"whatsapp.sendTemplate": "Send a pre-approved template message via WhatsApp (works outside 24h window)",
|
|
2897
|
-
"whatsapp.sendInteractive": "Send an interactive button message via WhatsApp (max 3 buttons)",
|
|
2898
|
-
"whatsapp.sendMedia": "Send an image or audio message via WhatsApp",
|
|
2899
|
-
"whatsapp.listTemplates": "List available WhatsApp message templates",
|
|
2900
|
-
"whatsapp.getConversation": "Get WhatsApp conversation history with a phone number",
|
|
2901
|
-
"whatsapp.getStatus": "Get WhatsApp connection status for this organization",
|
|
2902
|
-
"agent.chat": "Send a message to another agent and get its response",
|
|
2903
|
-
"airtable.listBases": "List all Airtable bases accessible with the configured token",
|
|
2904
|
-
"airtable.listTables": "List all tables in an Airtable base",
|
|
2905
|
-
"airtable.listRecords": "List records from an Airtable table with optional filtering and sorting",
|
|
2906
|
-
"airtable.getRecord": "Get a single record from an Airtable table by ID",
|
|
2907
|
-
"airtable.createRecords": "Create up to 10 records in an Airtable table",
|
|
2908
|
-
"airtable.updateRecords": "Update up to 10 records in an Airtable table",
|
|
2909
|
-
"airtable.deleteRecords": "Delete up to 10 records from an Airtable table",
|
|
2910
|
-
"email.send": "Send an email via Resend",
|
|
2911
|
-
"payment.create": "Create a payment link via Flow.cl and return the URL",
|
|
2912
|
-
"payment.getStatus": "Check the current status of a payment",
|
|
2913
|
-
"web.search": "Search the web and return relevant results with snippets",
|
|
2914
|
-
"web.fetch": "Fetch a web page and return its content as clean markdown"
|
|
2915
|
-
};
|
|
2916
|
-
return descriptions[name] || name;
|
|
2917
|
-
}
|
|
2918
|
-
function getBuiltinToolParameters(name) {
|
|
2919
|
-
const schemas = {
|
|
2920
|
-
"entity.create": {
|
|
2921
|
-
type: "object",
|
|
2922
|
-
properties: {
|
|
2923
|
-
type: { type: "string", description: 'The entity type slug (e.g., "customer", "order")' },
|
|
2924
|
-
data: { type: "object", description: "The entity data matching the entity type schema" },
|
|
2925
|
-
status: { type: "string", description: 'Optional status (defaults to "active")' }
|
|
2926
|
-
},
|
|
2927
|
-
required: ["type", "data"]
|
|
2928
|
-
},
|
|
2929
|
-
"entity.get": {
|
|
2930
|
-
type: "object",
|
|
2931
|
-
properties: {
|
|
2932
|
-
id: { type: "string", description: "The entity ID to retrieve" }
|
|
2933
|
-
},
|
|
2934
|
-
required: ["id"]
|
|
2935
|
-
},
|
|
2936
|
-
"entity.query": {
|
|
2937
|
-
type: "object",
|
|
2938
|
-
properties: {
|
|
2939
|
-
type: { type: "string", description: 'The entity type slug to query (e.g., "customer", "order")' },
|
|
2940
|
-
filters: { type: "object", description: 'Optional filters to apply (e.g., {"data.status": "active"})' },
|
|
2941
|
-
status: { type: "string", description: "Filter by entity status" },
|
|
2942
|
-
limit: { type: "number", description: "Maximum number of results (default 100)" }
|
|
2943
|
-
},
|
|
2944
|
-
required: ["type"]
|
|
2945
|
-
},
|
|
2946
|
-
"entity.update": {
|
|
2947
|
-
type: "object",
|
|
2948
|
-
properties: {
|
|
2949
|
-
id: { type: "string", description: "The entity ID to update" },
|
|
2950
|
-
type: { type: "string", description: 'The entity type slug (e.g., "session", "teacher"). Must match the actual type of the entity being updated.' },
|
|
2951
|
-
data: { type: "object", description: "The fields to update (merged with existing data)" },
|
|
2952
|
-
status: { type: "string", description: "Optional new status" }
|
|
2953
|
-
},
|
|
2954
|
-
required: ["id", "type", "data"]
|
|
2955
|
-
},
|
|
2956
|
-
"entity.delete": {
|
|
2957
|
-
type: "object",
|
|
2958
|
-
properties: {
|
|
2959
|
-
id: { type: "string", description: "The entity ID to delete" }
|
|
2960
|
-
},
|
|
2961
|
-
required: ["id"]
|
|
2962
|
-
},
|
|
2963
|
-
"calendar.list": {
|
|
2964
|
-
type: "object",
|
|
2965
|
-
properties: {
|
|
2966
|
-
userId: { type: "string", description: "User ID (Convex or Clerk) whose calendar to query" },
|
|
2967
|
-
timeMin: { type: "string", description: "Start of time range (ISO 8601 datetime)" },
|
|
2968
|
-
timeMax: { type: "string", description: "End of time range (ISO 8601 datetime)" },
|
|
2969
|
-
maxResults: { type: "number", description: "Maximum number of events to return" }
|
|
2970
|
-
},
|
|
2971
|
-
required: ["userId", "timeMin", "timeMax"]
|
|
2972
|
-
},
|
|
2973
|
-
"calendar.create": {
|
|
2974
|
-
type: "object",
|
|
2975
|
-
properties: {
|
|
2976
|
-
userId: { type: "string", description: "User ID (Convex or Clerk) whose calendar to create the event on" },
|
|
2977
|
-
summary: { type: "string", description: "Event title" },
|
|
2978
|
-
startTime: { type: "string", description: "Event start time (ISO 8601 datetime)" },
|
|
2979
|
-
endTime: { type: "string", description: "Event end time (ISO 8601 datetime). Provide either endTime or durationMinutes" },
|
|
2980
|
-
durationMinutes: { type: "number", description: "Duration in minutes. Used to calculate endTime if endTime is not provided" },
|
|
2981
|
-
description: { type: "string", description: "Event description" },
|
|
2982
|
-
attendees: { type: "array", items: { type: "string" }, description: "List of attendee email addresses" },
|
|
2983
|
-
timeZone: { type: "string", description: 'Time zone (e.g., "America/Santiago")' },
|
|
2984
|
-
addGoogleMeet: { type: "boolean", description: "Set to true to automatically create a Google Meet video conference link for this event" }
|
|
2985
|
-
},
|
|
2986
|
-
required: ["userId", "summary", "startTime"]
|
|
2987
|
-
},
|
|
2988
|
-
"calendar.update": {
|
|
2989
|
-
type: "object",
|
|
2990
|
-
properties: {
|
|
2991
|
-
userId: { type: "string", description: "User ID (Convex or Clerk) whose calendar contains the event" },
|
|
2992
|
-
eventId: { type: "string", description: "Google Calendar event ID to update" },
|
|
2993
|
-
summary: { type: "string", description: "New event title" },
|
|
2994
|
-
startTime: { type: "string", description: "New start time (ISO 8601 datetime)" },
|
|
2995
|
-
endTime: { type: "string", description: "New end time (ISO 8601 datetime)" },
|
|
2996
|
-
description: { type: "string", description: "New event description" },
|
|
2997
|
-
attendees: { type: "array", items: { type: "string" }, description: "Updated list of attendee emails" },
|
|
2998
|
-
status: { type: "string", description: "Event status (confirmed, tentative, cancelled)" }
|
|
2999
|
-
},
|
|
3000
|
-
required: ["userId", "eventId"]
|
|
3001
|
-
},
|
|
3002
|
-
"calendar.delete": {
|
|
3003
|
-
type: "object",
|
|
3004
|
-
properties: {
|
|
3005
|
-
userId: { type: "string", description: "User ID (Convex or Clerk) whose calendar contains the event" },
|
|
3006
|
-
eventId: { type: "string", description: "Google Calendar event ID to delete" }
|
|
3007
|
-
},
|
|
3008
|
-
required: ["userId", "eventId"]
|
|
3009
|
-
},
|
|
3010
|
-
"calendar.freeBusy": {
|
|
3011
|
-
type: "object",
|
|
3012
|
-
properties: {
|
|
3013
|
-
userId: { type: "string", description: "User ID (Convex or Clerk) whose availability to check" },
|
|
3014
|
-
timeMin: { type: "string", description: "Start of time range (ISO 8601 datetime)" },
|
|
3015
|
-
timeMax: { type: "string", description: "End of time range (ISO 8601 datetime)" }
|
|
3016
|
-
},
|
|
3017
|
-
required: ["userId", "timeMin", "timeMax"]
|
|
3018
|
-
},
|
|
3019
|
-
"whatsapp.send": {
|
|
3020
|
-
type: "object",
|
|
3021
|
-
properties: {
|
|
3022
|
-
to: { type: "string", description: 'Recipient phone number in E.164 format (e.g., "+15551234567")' },
|
|
3023
|
-
text: { type: "string", description: "The text message to send" }
|
|
3024
|
-
},
|
|
3025
|
-
required: ["to", "text"]
|
|
3026
|
-
},
|
|
3027
|
-
"whatsapp.sendTemplate": {
|
|
3028
|
-
type: "object",
|
|
3029
|
-
properties: {
|
|
3030
|
-
to: { type: "string", description: 'Recipient phone number in E.164 format (e.g., "+15551234567")' },
|
|
3031
|
-
templateName: { type: "string", description: "Name of the approved template to send" },
|
|
3032
|
-
language: { type: "string", description: 'Template language code (e.g., "en_US")' },
|
|
3033
|
-
components: {
|
|
3034
|
-
type: "array",
|
|
3035
|
-
description: "Optional template components with parameter values",
|
|
3036
|
-
items: {
|
|
3037
|
-
type: "object",
|
|
3038
|
-
properties: {
|
|
3039
|
-
type: { type: "string", description: 'Component type (e.g., "body", "header")' },
|
|
3040
|
-
parameters: {
|
|
3041
|
-
type: "array",
|
|
3042
|
-
items: {
|
|
3043
|
-
type: "object",
|
|
3044
|
-
properties: {
|
|
3045
|
-
type: { type: "string", description: 'Parameter type (e.g., "text")' },
|
|
3046
|
-
text: { type: "string", description: "Parameter text value" },
|
|
3047
|
-
parameterName: { type: "string", description: "Named parameter name (for NAMED format templates)" }
|
|
3048
|
-
},
|
|
3049
|
-
required: ["type"]
|
|
3050
|
-
}
|
|
3051
|
-
}
|
|
3052
|
-
},
|
|
3053
|
-
required: ["type", "parameters"]
|
|
3054
|
-
}
|
|
3055
|
-
}
|
|
3056
|
-
},
|
|
3057
|
-
required: ["to", "templateName", "language"]
|
|
3058
|
-
},
|
|
3059
|
-
"whatsapp.sendInteractive": {
|
|
3060
|
-
type: "object",
|
|
3061
|
-
properties: {
|
|
3062
|
-
to: { type: "string", description: 'Recipient phone number in E.164 format (e.g., "+15551234567")' },
|
|
3063
|
-
bodyText: { type: "string", description: "The message body text" },
|
|
3064
|
-
buttons: {
|
|
3065
|
-
type: "array",
|
|
3066
|
-
description: "Action buttons (1-3 buttons, max 20 chars per title)",
|
|
3067
|
-
items: {
|
|
3068
|
-
type: "object",
|
|
3069
|
-
properties: {
|
|
3070
|
-
id: { type: "string", description: "Unique button identifier returned on click" },
|
|
3071
|
-
title: { type: "string", description: "Button label shown to user (max 20 characters)" }
|
|
3072
|
-
},
|
|
3073
|
-
required: ["id", "title"]
|
|
3074
|
-
}
|
|
3075
|
-
},
|
|
3076
|
-
footerText: { type: "string", description: "Optional footer text below the buttons" }
|
|
3077
|
-
},
|
|
3078
|
-
required: ["to", "bodyText", "buttons"]
|
|
3079
|
-
},
|
|
3080
|
-
"whatsapp.sendMedia": {
|
|
3081
|
-
type: "object",
|
|
3082
|
-
properties: {
|
|
3083
|
-
to: { type: "string", description: 'Recipient phone number in E.164 format (e.g., "+15551234567")' },
|
|
3084
|
-
mediaUrl: { type: "string", description: "Public URL of the media file to send" },
|
|
3085
|
-
mediaType: { type: "string", enum: ["image", "audio"], description: "Type of media to send" },
|
|
3086
|
-
caption: { type: "string", description: "Optional caption (only supported for images)" }
|
|
3087
|
-
},
|
|
3088
|
-
required: ["to", "mediaUrl", "mediaType"]
|
|
3089
|
-
},
|
|
3090
|
-
"whatsapp.listTemplates": {
|
|
3091
|
-
type: "object",
|
|
3092
|
-
properties: {}
|
|
3093
|
-
},
|
|
3094
|
-
"whatsapp.getConversation": {
|
|
3095
|
-
type: "object",
|
|
3096
|
-
properties: {
|
|
3097
|
-
phoneNumber: { type: "string", description: "Phone number to get conversation history for" },
|
|
3098
|
-
limit: { type: "number", description: "Maximum number of messages to return" }
|
|
3099
|
-
},
|
|
3100
|
-
required: ["phoneNumber"]
|
|
3101
|
-
},
|
|
3102
|
-
"whatsapp.getStatus": {
|
|
3103
|
-
type: "object",
|
|
3104
|
-
properties: {}
|
|
3105
|
-
},
|
|
3106
|
-
"agent.chat": {
|
|
3107
|
-
type: "object",
|
|
3108
|
-
properties: {
|
|
3109
|
-
agent: { type: "string", description: "Target agent slug to communicate with" },
|
|
3110
|
-
message: { type: "string", description: "The message to send to the agent" },
|
|
3111
|
-
context: { type: "object", description: "Optional context data to pass to the target agent" }
|
|
3112
|
-
},
|
|
3113
|
-
required: ["agent", "message"]
|
|
3114
|
-
},
|
|
3115
|
-
"airtable.listBases": {
|
|
3116
|
-
type: "object",
|
|
3117
|
-
properties: {}
|
|
3118
|
-
},
|
|
3119
|
-
"airtable.listTables": {
|
|
3120
|
-
type: "object",
|
|
3121
|
-
properties: {
|
|
3122
|
-
baseId: { type: "string", description: 'Airtable base ID (e.g., "appXXXXXXXXXXXXXX")' }
|
|
3123
|
-
},
|
|
3124
|
-
required: ["baseId"]
|
|
3125
|
-
},
|
|
3126
|
-
"airtable.listRecords": {
|
|
3127
|
-
type: "object",
|
|
3128
|
-
properties: {
|
|
3129
|
-
baseId: { type: "string", description: "Airtable base ID" },
|
|
3130
|
-
tableIdOrName: { type: "string", description: "Table ID or name" },
|
|
3131
|
-
pageSize: { type: "number", description: "Number of records per page (max 100)" },
|
|
3132
|
-
offset: { type: "string", description: "Pagination offset from a previous response" },
|
|
3133
|
-
filterByFormula: { type: "string", description: `Airtable formula to filter records (e.g., "{Status} = 'Active'")` },
|
|
3134
|
-
sort: { type: "array", items: { type: "object", properties: { field: { type: "string" }, direction: { type: "string", enum: ["asc", "desc"] } }, required: ["field"] }, description: "Sort configuration" },
|
|
3135
|
-
fields: { type: "array", items: { type: "string" }, description: "Only return specific field names" },
|
|
3136
|
-
view: { type: "string", description: "Name or ID of an Airtable view to use" }
|
|
3137
|
-
},
|
|
3138
|
-
required: ["baseId", "tableIdOrName"]
|
|
3139
|
-
},
|
|
3140
|
-
"airtable.getRecord": {
|
|
3141
|
-
type: "object",
|
|
3142
|
-
properties: {
|
|
3143
|
-
baseId: { type: "string", description: "Airtable base ID" },
|
|
3144
|
-
tableIdOrName: { type: "string", description: "Table ID or name" },
|
|
3145
|
-
recordId: { type: "string", description: 'Record ID (e.g., "recXXXXXXXXXXXXXX")' }
|
|
3146
|
-
},
|
|
3147
|
-
required: ["baseId", "tableIdOrName", "recordId"]
|
|
3148
|
-
},
|
|
3149
|
-
"airtable.createRecords": {
|
|
3150
|
-
type: "object",
|
|
3151
|
-
properties: {
|
|
3152
|
-
baseId: { type: "string", description: "Airtable base ID" },
|
|
3153
|
-
tableIdOrName: { type: "string", description: "Table ID or name" },
|
|
3154
|
-
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)" }
|
|
3155
|
-
},
|
|
3156
|
-
required: ["baseId", "tableIdOrName", "records"]
|
|
3157
|
-
},
|
|
3158
|
-
"airtable.updateRecords": {
|
|
3159
|
-
type: "object",
|
|
3160
|
-
properties: {
|
|
3161
|
-
baseId: { type: "string", description: "Airtable base ID" },
|
|
3162
|
-
tableIdOrName: { type: "string", description: "Table ID or name" },
|
|
3163
|
-
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)" }
|
|
3164
|
-
},
|
|
3165
|
-
required: ["baseId", "tableIdOrName", "records"]
|
|
3166
|
-
},
|
|
3167
|
-
"airtable.deleteRecords": {
|
|
3168
|
-
type: "object",
|
|
3169
|
-
properties: {
|
|
3170
|
-
baseId: { type: "string", description: "Airtable base ID" },
|
|
3171
|
-
tableIdOrName: { type: "string", description: "Table ID or name" },
|
|
3172
|
-
recordIds: { type: "array", items: { type: "string" }, description: "Array of record IDs to delete (max 10)" }
|
|
3173
|
-
},
|
|
3174
|
-
required: ["baseId", "tableIdOrName", "recordIds"]
|
|
3175
|
-
},
|
|
3176
|
-
"email.send": {
|
|
3177
|
-
type: "object",
|
|
3178
|
-
properties: {
|
|
3179
|
-
to: { type: "string", description: "Recipient email address" },
|
|
3180
|
-
subject: { type: "string", description: "Email subject line" },
|
|
3181
|
-
html: { type: "string", description: "HTML body content" },
|
|
3182
|
-
text: { type: "string", description: "Plain text body content" },
|
|
3183
|
-
replyTo: { type: "string", description: "Reply-to email address" }
|
|
3184
|
-
},
|
|
3185
|
-
required: ["to", "subject"]
|
|
3186
|
-
},
|
|
3187
|
-
"payment.create": {
|
|
3188
|
-
type: "object",
|
|
3189
|
-
properties: {
|
|
3190
|
-
amount: { type: "number", description: "Payment amount in the smallest currency unit" },
|
|
3191
|
-
description: { type: "string", description: "Description of the payment" },
|
|
3192
|
-
currency: { type: "string", description: "Currency code (defaults to CLP)" },
|
|
3193
|
-
customerEmail: { type: "string", description: "Customer email address" },
|
|
3194
|
-
entityId: { type: "string", description: "Optional entity ID to link the payment to" }
|
|
3195
|
-
},
|
|
3196
|
-
required: ["amount", "description"]
|
|
3197
|
-
},
|
|
3198
|
-
"payment.getStatus": {
|
|
3199
|
-
type: "object",
|
|
3200
|
-
properties: {
|
|
3201
|
-
entityId: { type: "string", description: "Payment entity ID to check status for" }
|
|
3202
|
-
},
|
|
3203
|
-
required: ["entityId"]
|
|
3204
|
-
},
|
|
3205
|
-
"web.search": {
|
|
3206
|
-
type: "object",
|
|
3207
|
-
properties: {
|
|
3208
|
-
query: { type: "string", description: "Search query" },
|
|
3209
|
-
maxResults: { type: "number", description: "Maximum number of results (default: 5, max: 20)" },
|
|
3210
|
-
site: { type: "array", items: { type: "string" }, description: "Only include results from these domains" },
|
|
3211
|
-
gl: { type: "string", description: 'Country code for localized results (e.g., "US", "GB")' },
|
|
3212
|
-
hl: { type: "string", description: 'Language code (ISO 639-1, e.g., "en", "es")' }
|
|
3213
|
-
},
|
|
3214
|
-
required: ["query"]
|
|
3215
|
-
},
|
|
3216
|
-
"web.fetch": {
|
|
3217
|
-
type: "object",
|
|
3218
|
-
properties: {
|
|
3219
|
-
url: { type: "string", description: "URL of the page to fetch" },
|
|
3220
|
-
targetSelector: { type: "string", description: "CSS selector to extract specific content from the page" },
|
|
3221
|
-
removeSelector: { type: "string", description: "CSS selector to remove elements from the page before extraction" },
|
|
3222
|
-
tokenBudget: { type: "number", description: "Maximum number of tokens in the response content" }
|
|
3223
|
-
},
|
|
3224
|
-
required: ["url"]
|
|
3225
|
-
}
|
|
3226
|
-
};
|
|
3227
|
-
return schemas[name] || { type: "object", properties: {} };
|
|
3228
|
-
}
|
|
3229
2888
|
function extractHandlerCode(handler) {
|
|
3230
2889
|
const code = handler.toString();
|
|
3231
2890
|
const arrowBlockMatch = code.match(/(?:async\s*)?\([^)]*\)\s*=>\s*\{([\s\S]*)\}\s*$/);
|
|
@@ -3255,6 +2914,7 @@ ${resources.errors.join(`
|
|
|
3255
2914
|
const payload = extractSyncPayload(resources);
|
|
3256
2915
|
const devResult = await syncOrganization({
|
|
3257
2916
|
agents: payload.agents,
|
|
2917
|
+
tools: payload.tools,
|
|
3258
2918
|
entityTypes: payload.entityTypes,
|
|
3259
2919
|
roles: payload.roles,
|
|
3260
2920
|
triggers: payload.triggers,
|
|
@@ -3269,6 +2929,7 @@ ${resources.errors.join(`
|
|
|
3269
2929
|
if (hasEvalContent) {
|
|
3270
2930
|
const evalResult = await syncOrganization({
|
|
3271
2931
|
agents: payload.agents,
|
|
2932
|
+
tools: payload.tools,
|
|
3272
2933
|
entityTypes: payload.entityTypes,
|
|
3273
2934
|
roles: payload.roles,
|
|
3274
2935
|
evalSuites: payload.evalSuites,
|
|
@@ -3961,6 +3622,7 @@ var deployCommand = new Command7("deploy").description("Deploy all resources to
|
|
|
3961
3622
|
try {
|
|
3962
3623
|
const syncResult = await syncOrganization({
|
|
3963
3624
|
agents: payload.agents,
|
|
3625
|
+
tools: payload.tools,
|
|
3964
3626
|
entityTypes: payload.entityTypes,
|
|
3965
3627
|
roles: payload.roles,
|
|
3966
3628
|
triggers: payload.triggers,
|
|
@@ -4445,6 +4107,8 @@ var statusCommand = new Command11("status").description("Compare local vs remote
|
|
|
4445
4107
|
const devEntityTypeSlugs = new Set(devState.entityTypes.map((et) => et.slug));
|
|
4446
4108
|
const localRoleNames = new Set(localResources.roles.map((r) => r.name));
|
|
4447
4109
|
const devRoleNames = new Set(devState.roles.map((r) => r.name));
|
|
4110
|
+
const localToolNames = new Set(localResources.customTools.map((t) => t.name));
|
|
4111
|
+
const devToolNames = new Set((devState.tools || []).map((t) => t.name));
|
|
4448
4112
|
const localRouterSlugs = new Set(localResources.routers.map((r) => r.slug));
|
|
4449
4113
|
const devRouterSlugs = new Set((devState.routers || []).map((r) => r.slug));
|
|
4450
4114
|
if (opts.json) {
|
|
@@ -4551,6 +4215,26 @@ var statusCommand = new Command11("status").description("Compare local vs remote
|
|
|
4551
4215
|
}
|
|
4552
4216
|
}
|
|
4553
4217
|
console.log();
|
|
4218
|
+
console.log(chalk12.bold("Custom Tools"));
|
|
4219
|
+
console.log(chalk12.gray("\u2500".repeat(60)));
|
|
4220
|
+
if (localResources.customTools.length === 0 && (devState.tools || []).length === 0) {
|
|
4221
|
+
console.log(chalk12.gray(" No custom tools"));
|
|
4222
|
+
} else {
|
|
4223
|
+
for (const tool of localResources.customTools) {
|
|
4224
|
+
const remote = (devState.tools || []).find((t) => t.name === tool.name);
|
|
4225
|
+
if (remote) {
|
|
4226
|
+
console.log(` ${chalk12.green("\u25CF")} ${chalk12.cyan(tool.name)}`);
|
|
4227
|
+
} else {
|
|
4228
|
+
console.log(` ${chalk12.blue("+")} ${chalk12.cyan(tool.name)} - ${chalk12.blue("new")}`);
|
|
4229
|
+
}
|
|
4230
|
+
}
|
|
4231
|
+
for (const remote of devState.tools || []) {
|
|
4232
|
+
if (!localToolNames.has(remote.name)) {
|
|
4233
|
+
console.log(` ${chalk12.red("-")} ${remote.name} - ${chalk12.red("will be deleted")}`);
|
|
4234
|
+
}
|
|
4235
|
+
}
|
|
4236
|
+
}
|
|
4237
|
+
console.log();
|
|
4554
4238
|
console.log(chalk12.gray("Legend:"));
|
|
4555
4239
|
console.log(chalk12.gray(" "), chalk12.green("\u25CF"), "Synced", chalk12.yellow("\u25CB"), "Not in production", chalk12.blue("+"), "New", chalk12.red("-"), "Will be deleted");
|
|
4556
4240
|
console.log();
|
|
@@ -4569,16 +4253,6 @@ import { join as join9 } from "path";
|
|
|
4569
4253
|
init_convex();
|
|
4570
4254
|
|
|
4571
4255
|
// src/cli/utils/generator.ts
|
|
4572
|
-
var BUILTIN_TOOLS2 = [
|
|
4573
|
-
"entity.create",
|
|
4574
|
-
"entity.get",
|
|
4575
|
-
"entity.query",
|
|
4576
|
-
"entity.update",
|
|
4577
|
-
"entity.delete",
|
|
4578
|
-
"agent.chat",
|
|
4579
|
-
"web.search",
|
|
4580
|
-
"web.fetch"
|
|
4581
|
-
];
|
|
4582
4256
|
function escapeTemplateLiteral(str) {
|
|
4583
4257
|
return str.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
4584
4258
|
}
|
|
@@ -4614,8 +4288,7 @@ ${" ".repeat(indent)}}`;
|
|
|
4614
4288
|
return JSON.stringify(value);
|
|
4615
4289
|
}
|
|
4616
4290
|
function generateAgentFile(agent) {
|
|
4617
|
-
const
|
|
4618
|
-
const toolsArray = toolNames.map((n) => ` "${n}"`).join(`,
|
|
4291
|
+
const toolsArray = agent.tools.map((n) => ` "${n}"`).join(`,
|
|
4619
4292
|
`);
|
|
4620
4293
|
const modelParts = [
|
|
4621
4294
|
` model: "${agent.model.model}"`
|
|
@@ -4776,12 +4449,18 @@ ${toolEntries.join(`,
|
|
|
4776
4449
|
`;
|
|
4777
4450
|
}
|
|
4778
4451
|
function generateTriggerFile(trigger) {
|
|
4779
|
-
const onParts = [
|
|
4780
|
-
|
|
4781
|
-
`
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4452
|
+
const onParts = [];
|
|
4453
|
+
if (trigger.cronSchedule) {
|
|
4454
|
+
onParts.push(` schedule: "${trigger.cronSchedule}"`);
|
|
4455
|
+
if (trigger.cronTimezone) {
|
|
4456
|
+
onParts.push(` timezone: "${trigger.cronTimezone}"`);
|
|
4457
|
+
}
|
|
4458
|
+
} else {
|
|
4459
|
+
onParts.push(` entityType: "${trigger.entityType}"`);
|
|
4460
|
+
onParts.push(` action: "${trigger.action}"`);
|
|
4461
|
+
if (trigger.condition && Object.keys(trigger.condition).length > 0) {
|
|
4462
|
+
onParts.push(` condition: ${stringifyValue(trigger.condition, 4)}`);
|
|
4463
|
+
}
|
|
4785
4464
|
}
|
|
4786
4465
|
const actionLines = trigger.actions.map((a) => {
|
|
4787
4466
|
const aParts = [
|
|
@@ -4884,22 +4563,6 @@ function generateIndexFile(type, slugs) {
|
|
|
4884
4563
|
`) + `
|
|
4885
4564
|
`;
|
|
4886
4565
|
}
|
|
4887
|
-
function collectCustomTools(agents) {
|
|
4888
|
-
const seen = new Map;
|
|
4889
|
-
for (const agent of agents) {
|
|
4890
|
-
for (const tool of agent.tools) {
|
|
4891
|
-
if (!BUILTIN_TOOLS2.includes(tool.name) && !seen.has(tool.name)) {
|
|
4892
|
-
seen.set(tool.name, {
|
|
4893
|
-
name: tool.name,
|
|
4894
|
-
description: tool.description,
|
|
4895
|
-
parameters: tool.parameters,
|
|
4896
|
-
handlerCode: tool.handlerCode
|
|
4897
|
-
});
|
|
4898
|
-
}
|
|
4899
|
-
}
|
|
4900
|
-
}
|
|
4901
|
-
return Array.from(seen.values());
|
|
4902
|
-
}
|
|
4903
4566
|
|
|
4904
4567
|
// src/cli/commands/pull.ts
|
|
4905
4568
|
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) => {
|
|
@@ -5040,7 +4703,7 @@ var pullCommand = new Command12("pull").description("Pull remote resources to lo
|
|
|
5040
4703
|
const content = generateRouterFile(router);
|
|
5041
4704
|
writeOrSkip(`routers/${router.slug}.ts`, content);
|
|
5042
4705
|
}
|
|
5043
|
-
const customTools =
|
|
4706
|
+
const customTools = state.tools || [];
|
|
5044
4707
|
if (customTools.length > 0) {
|
|
5045
4708
|
const content = generateToolsFile(customTools);
|
|
5046
4709
|
writeOrSkip("tools/index.ts", content);
|
|
@@ -7735,8 +7398,7 @@ triggersCommand.command("list", { isDefault: true }).description("List all trigg
|
|
|
7735
7398
|
renderTable([
|
|
7736
7399
|
{ key: "name", label: "Name", width: 20 },
|
|
7737
7400
|
{ key: "slug", label: "Slug", width: 18 },
|
|
7738
|
-
{ key: "
|
|
7739
|
-
{ key: "action", label: "Action", width: 10 },
|
|
7401
|
+
{ key: "type", label: "Type", width: 18 },
|
|
7740
7402
|
{ key: "enabled", label: "Enabled", width: 8 },
|
|
7741
7403
|
{ key: "lastRun", label: "Last Run", width: 12 },
|
|
7742
7404
|
{ key: "lastError", label: "Last Error", width: 25 },
|
|
@@ -7744,8 +7406,7 @@ triggersCommand.command("list", { isDefault: true }).description("List all trigg
|
|
|
7744
7406
|
], filtered.map((t) => ({
|
|
7745
7407
|
name: t.name ?? "",
|
|
7746
7408
|
slug: t.slug ?? "",
|
|
7747
|
-
|
|
7748
|
-
action: t.action ?? "",
|
|
7409
|
+
type: t.cronSchedule ? `cron ${t.cronSchedule}` : `${t.entityType ?? ""}.${t.action ?? ""}`,
|
|
7749
7410
|
enabled: t.enabled ? chalk20.green("\u2713") : chalk20.red("\u2717"),
|
|
7750
7411
|
lastRun: statuses[t.slug] ? statusColor4(statuses[t.slug].status) : chalk20.gray("-"),
|
|
7751
7412
|
lastError: statuses[t.slug]?.status === "failed" ? chalk20.red((statuses[t.slug].error ?? "").slice(0, 23)) : "",
|
|
@@ -7785,8 +7446,15 @@ triggersCommand.command("get <slug>").description("View trigger details").option
|
|
|
7785
7446
|
console.log(` ${chalk20.gray("Name:")} ${chalk20.cyan(trigger.name)}`);
|
|
7786
7447
|
console.log(` ${chalk20.gray("Slug:")} ${chalk20.cyan(trigger.slug)}`);
|
|
7787
7448
|
console.log(` ${chalk20.gray("Description:")} ${chalk20.cyan(trigger.description || "-")}`);
|
|
7788
|
-
|
|
7789
|
-
|
|
7449
|
+
if (trigger.cronSchedule) {
|
|
7450
|
+
console.log(` ${chalk20.gray("Schedule:")} ${chalk20.cyan(trigger.cronSchedule)}`);
|
|
7451
|
+
if (trigger.cronTimezone) {
|
|
7452
|
+
console.log(` ${chalk20.gray("Timezone:")} ${chalk20.cyan(trigger.cronTimezone)}`);
|
|
7453
|
+
}
|
|
7454
|
+
} else {
|
|
7455
|
+
console.log(` ${chalk20.gray("Entity Type:")} ${chalk20.cyan(trigger.entityType)}`);
|
|
7456
|
+
console.log(` ${chalk20.gray("Action:")} ${chalk20.cyan(trigger.action)}`);
|
|
7457
|
+
}
|
|
7790
7458
|
console.log(` ${chalk20.gray("Enabled:")} ${trigger.enabled ? chalk20.green("\u2713") : chalk20.red("\u2717")}`);
|
|
7791
7459
|
console.log(` ${chalk20.gray("Created:")} ${chalk20.cyan(relativeTime2(trigger.createdAt ?? Date.now()))}`);
|
|
7792
7460
|
console.log(` ${chalk20.gray("Updated:")} ${chalk20.cyan(relativeTime2(trigger.updatedAt ?? Date.now()))}`);
|
|
@@ -9041,7 +8709,7 @@ whatsappCommand.command("set-agent <connection> <agent-slug>").description("Assi
|
|
|
9041
8709
|
// package.json
|
|
9042
8710
|
var package_default = {
|
|
9043
8711
|
name: "struere",
|
|
9044
|
-
version: "0.12.
|
|
8712
|
+
version: "0.12.5",
|
|
9045
8713
|
description: "Build, test, and deploy AI agents",
|
|
9046
8714
|
keywords: [
|
|
9047
8715
|
"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,
|
|
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"}
|