automation
暂无简介
- License 许可
- GPL-3.0
- 所属仓库
- ZMGID/kivio
- 最近更新
- 2026-11-12
- Stars
- ★ 585
- Forks
- 42
03 SKILL.md 正文
Kivio automations
Kivio automations are directed graphs: one trigger, then actions and logic, stored as JSON.
Not for scheduled tasks. When the user wants something done on a schedule in this conversation (定时任务, 提醒, "每天早上帮我…"), call schedule action=create instead. Build an automation only when the user explicitly asks for an automation/workflow.
Do this: activate this skill, automation action=list once, then automation action=upsert with a complete graph in one call.
Do not: glob the repo, invent node type names, or dry_run to discover the schema. dry_run is only for a finished candidate. This skill is the schema — automation action=upsert's tool description is short on purpose. Validation errors also return allowedNodeTypes + schemaHint.
Chat exposes one native automation tool with seven actions. It is an on-demand tool: when it is not in your tool list, read tool://automation for its schema and run it with write to tool://automation (content = JSON arguments, e.g. {"action":"list"}), or call automation directly by name. After creating a graph, tell the user to open #chat/automations/{id}.
Tools
automation action=list— ids, names, enabled, trigger type. Call this first to avoid duplicates.automation action=get— full graph for one id.automation action=upsert— create or replace the whole graph in one call. Omitidto create. Omit nodepositionto auto-layout.dry_run: trueonly after you already have a complete graph. Error-severity issues reject the save and returnallowedNodeTypes+schemaHint; fix those and resubmit the whole graph.automation action=set_enabled— start/stop schedule and hotkey registration (separate from upsert).automation action=run— blocking. Optionalinput(string or{ text, json }) becomes{{output}}/{{json.input.*}}for later nodes. Default wait 600s (max 1800). Timeout is not a failure: the run continues; poll withautomation action=runs.automation action=runs— recent summaries, or one run's per-node details whenrun_idis set.automation action=delete— permanent. Goes through normal approval.
Do not call these tools from inside an action.agent step. Workflow agents never receive automation tools.
After creating or changing a graph, tell the user to open #chat/automations/{id} (Extensions → Automations) to inspect the canvas.
Graph contract (schema v1)
{
"schemaVersion": 1,
"id": "",
"name": "Daily briefing",
"enabled": false,
"nodes": [],
"edges": [],
"viewport": { "x": 0, "y": 0, "zoom": 1 }
}
- Exactly one trigger recommended (
trigger.manual|trigger.schedule|trigger.hotkey). - Main-flow edges:
{ "id", "source", "target" }. Tree only — no cycles. - Agent slot edges (not part of the main flow):
sourceis the slot node,targetisaction.agent,sourceHandle:"slot",targetHandle:"runtime"|"context"|"tool"|"skill". - Node ids unique. Positions optional (auto-layout when every node is at
{x:0,y:0}). enabled: falseuntil the user asks to arm schedule/hotkey. Manual and agent runs still work.
Interpolation
Downstream templates:
{{output}}— previous node's text. Afterautomation action=runwith a string input, this is that string at the trigger.{{json.path}}— walk the previous JSON. Agent-run input is nested atjson.input.{{json.input.topic}}— a field fromautomation action=run{ "input": { "json": { "topic": "..." } } }.
No $json expressions, no $('Node') cross-references.
Node types and data
Every node: { "id", "type", "position"?, "data": { "label": "..." } }. Extra fields live under data.
Triggers
trigger.manual — editor / agent test runs only.
trigger.schedule
"data": {
"label": "Schedule",
"schedule": { "kind": "daily", "hour": 9, "minute": 0, "intervalMinutes": 60 }
}
kind: daily | weekdays | interval. For interval, intervalMinutes ≥ 1. hour 0–23, minute 0–59.
trigger.hotkey
"data": { "label": "Hotkey", "hotkey": { "accelerator": "CommandOrControl+Shift+B" } }
Modifiers: CommandOrControl, Control, Alt, Shift, Super.
Actions
action.agent — unattended model step. Put prompt/runtime/tools/skills on slot nodes, not inline.
action.notify — { "notify": { "body": "{{output}}" } }
action.http — { "http": { "method": "GET", "url": "https://…", "headers": "", "body": "" } }
method: GET|POST|PUT|PATCH|DELETE. URL required.
action.set — { "set": { "fields": [{ "key": "text", "value": "{{output}}" }] } }
action.clipboard — { "clipboard": { "op": "copy", "text": "{{output}}" } } (copy | read)
action.file — { "file": { "op": "write", "path": "notes.md", "content": "{{output}}" } } (read | write; path required)
action.command — { "command": { "command": "echo hi", "cwd": "", "timeoutSeconds": 30, "continueOnFail": false } }
Logic
logic.if — { "if": { "op": "contains", "value": "ok" } }
op: contains | equals | notEmpty. Outgoing sourceHandle: "true" | "false".
logic.switch — { "switch": { "cases": [{ "id": "1", "op": "equals", "value": "a" }] } }
Outgoing handles: each case id, plus "default".
logic.delay — { "delay": { "seconds": 5 } } (integer ≥ 1)
Agent slots (plug into action.agent)
Slot node data.agent:
agent.runtime
"agent": {
"runtimeKind": "builtin",
"providerId": "",
"model": "",
"externalAgentId": null,
"externalModel": null
}
runtimeKind: builtin | chat | external. External needs externalAgentId (claude, codex, cursor, …).
agent.context — { "agent": { "prompt": "Summarize {{output}} in 5 bullets." } }
agent.tool — { "agent": { "toolIds": ["web_search", "web_fetch"] } }
Empty = read-only tools + skill loader. Never include automation or memory tools.
agent.skill — { "agent": { "skillIds": ["<installed-skill-id>"] } }(只写当前已启用技能的 id)
Best practices
automation action=listbefore create. Reuse an id with upsert to replace.dry_run: truefirst. Fix everyseverity: "error"(nodeId+message).- Leave
enabled: falseuntil the user wants the schedule/hotkey live; thenautomation action=set_enabled. - Only when the user explicitly wants an automation:
trigger.schedule+action.agent+action.notifyfits “every morning, do X and ping me”. A plain timed prompt is a scheduled task (schedule action=create). - For “take this problem and run my workflow”,
automation action=runwithinput; do not rebuild the graph each time. - After save, tell the user the name, id, and to open the Automations page.
Example 1 — daily agent briefing
{
"name": "Daily briefing",
"enabled": false,
"nodes": [
{ "id": "t", "type": "trigger.schedule", "data": { "label": "09:00", "schedule": { "kind": "daily", "hour": 9, "minute": 0, "intervalMinutes": 60 } } },
{ "id": "a", "type": "action.agent", "data": { "label": "Brief" } },
{ "id": "ctx", "type": "agent.context", "data": { "label": "Prompt", "agent": { "prompt": "Write a short morning briefing from {{output}}." } } },
{ "id": "rt", "type": "agent.runtime", "data": { "label": "Runtime", "agent": { "runtimeKind": "builtin" } } },
{ "id": "n", "type": "action.notify", "data": { "label": "Notify", "notify": { "body": "{{output}}" } } }
],
"edges": [
{ "id": "e1", "source": "t", "target": "a" },
{ "id": "e2", "source": "a", "target": "n" },
{ "id": "er", "source": "rt", "target": "a", "sourceHandle": "slot", "targetHandle": "runtime" },
{ "id": "ec", "source": "ctx", "target": "a", "sourceHandle": "slot", "targetHandle": "context" }
]
}
Example 2 — run with input
Existing graph: manual trigger → agent (prompt uses {{output}}) → notify.
automation action=run id=<id> input="Draft a reply to this email: …"
The trigger text becomes that string; the agent prompt interpolates it.
Example 3 — HTTP then branch
{
"name": "Health ping",
"nodes": [
{ "id": "t", "type": "trigger.manual", "data": { "label": "Manual" } },
{ "id": "h", "type": "action.http", "data": { "label": "GET", "http": { "method": "GET", "url": "https://example.com/health", "headers": "", "body": "" } } },
{ "id": "i", "type": "logic.if", "data": { "label": "OK?", "if": { "op": "contains", "value": "ok" } } },
{ "id": "yes", "type": "action.notify", "data": { "label": "Up", "notify": { "body": "healthy: {{output}}" } } },
{ "id": "no", "type": "action.notify", "data": { "label": "Down", "notify": { "body": "unhealthy: {{output}}" } } }
],
"edges": [
{ "id": "e1", "source": "t", "target": "h" },
{ "id": "e2", "source": "h", "target": "i" },
{ "id": "e3", "source": "i", "target": "yes", "sourceHandle": "true" },
{ "id": "e4", "source": "i", "target": "no", "sourceHandle": "false" }
]
}
04 同仓库更多 Skills
example
Demonstrate loading a plugin skill from its original directory.
review
检查代码改动的逻辑错误与遗漏
kivio-configuration-guide
配置与排查 Kivio 自身:模型、提示词、Skills、插件、MCP、Hooks、斜杠命令及运行时。用户要求安装扩展、调整配置或解决不生效问题时使用;普通项目开发不触发。
wecom-cli
Work with WeCom through the official wecom-cli and the skills shipped by WeComTeam/wecom-cli.
wecom-cli-setup
Install the official wecom-cli and its published skills, then verify scan-code login with one read-only identity call.
feishu-cli
Work with Feishu messages, documents, Base, sheets, calendar, tasks and other services through the official lark-cli and its embedded domain guidance.