Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions plugins/kapso/skills/automate-whatsapp/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ Notes:
- Non-decide nodes have 0 or 1 outgoing `next` edge
- Decide edge labels must match `conditions[].label`
- Edge keys are `source`/`target`/`label` (not `from`/`to`)
- Agent nodes require `config.provider_model_id` — run `node scripts/list-provider-models.js` and set it (plus a non-empty `config.system_prompt`) before saving. `validate-graph.js` errors on a missing model id.

For full schema details, see `references/graph-contract.md`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ Use `automate-whatsapp` function scripts to find function IDs and update code.
```

Notes:
- `provider_model_id` is required. Use `scripts/list-provider-models.js` to find it.
- `provider_model_id` is required. Run `node scripts/list-provider-models.js` to get a valid id and set it in `config.provider_model_id` **before** saving the node. `scripts/validate-graph.js` errors when an agent node is missing it, so validate the graph before `update-graph.js`.
- `system_prompt` should be non-empty. `validate-graph.js` warns when it is blank.
- Agent tool arrays live inside `data.config` (not at the `data` root).
- `message_delivery_mode` controls user-visible text:
- `auto_send_assistant_text` sends normal assistant text automatically.
Expand Down
23 changes: 21 additions & 2 deletions plugins/kapso/skills/automate-whatsapp/scripts/validate-graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ function validateDefinition(definition) {
}

if (!nodes || !edges) {
return { errors, warnings, stats: { nodes: 0, edges: 0, decideNodes: 0 } };
return { errors, warnings, stats: { nodes: 0, edges: 0, decideNodes: 0, agentNodes: 0 } };
}

const nodeIds = new Set();
Expand Down Expand Up @@ -154,12 +154,30 @@ function validateDefinition(definition) {
});

let decideNodes = 0;
let agentNodes = 0;
nodes.forEach((node) => {
if (!node || typeof node !== 'object') return;
const nodeId = node.id;
const nodeType = nodeTypes[nodeId];
const outgoing = outgoingEdges[nodeId] || [];

if (nodeType === 'agent') {
agentNodes += 1;
const config = (node.data || {}).config || {};

const providerModelId = config.provider_model_id;
if (typeof providerModelId !== 'string' || providerModelId.trim() === '') {
errors.push(
`agent node ${nodeId} is missing config.provider_model_id (required). Use scripts/list-provider-models.js to find a model id.`
);
}

const systemPrompt = config.system_prompt;
if (typeof systemPrompt !== 'string' || systemPrompt.trim() === '') {
warnings.push(`agent node ${nodeId} has an empty config.system_prompt`);
}
}

if (nodeType === 'decide') {
decideNodes += 1;
const config = (node.data || {}).config || {};
Expand Down Expand Up @@ -207,7 +225,8 @@ function validateDefinition(definition) {
stats: {
nodes: nodes.length,
edges: edges.length,
decideNodes
decideNodes,
agentNodes
}
};
}
Expand Down
Loading