@rune-kit/rune 2.8.0 → 2.11.0
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/LICENSE +21 -21
- package/README.md +68 -34
- package/agents/adversary.md +27 -0
- package/agents/architect.md +19 -29
- package/agents/asset-creator.md +18 -4
- package/agents/audit.md +25 -4
- package/agents/autopsy.md +19 -4
- package/agents/ba.md +35 -0
- package/agents/brainstorm.md +31 -4
- package/agents/browser-pilot.md +21 -4
- package/agents/coder.md +21 -29
- package/agents/completion-gate.md +20 -4
- package/agents/constraint-check.md +18 -4
- package/agents/context-engine.md +22 -4
- package/agents/context-pack.md +32 -0
- package/agents/cook.md +41 -4
- package/agents/db.md +19 -4
- package/agents/debug.md +33 -4
- package/agents/dependency-doctor.md +20 -4
- package/agents/deploy.md +27 -4
- package/agents/design.md +22 -4
- package/agents/doc-processor.md +27 -0
- package/agents/docs-seeker.md +19 -4
- package/agents/docs.md +31 -0
- package/agents/fix.md +37 -4
- package/agents/git.md +29 -0
- package/agents/hallucination-guard.md +20 -4
- package/agents/incident.md +21 -4
- package/agents/integrity-check.md +18 -4
- package/agents/journal.md +19 -4
- package/agents/launch.md +32 -4
- package/agents/logic-guardian.md +26 -11
- package/agents/marketing.md +23 -4
- package/agents/mcp-builder.md +26 -0
- package/agents/neural-memory.md +30 -0
- package/agents/onboard.md +22 -4
- package/agents/perf.md +21 -4
- package/agents/plan.md +29 -4
- package/agents/preflight.md +22 -4
- package/agents/problem-solver.md +20 -4
- package/agents/rescue.md +23 -4
- package/agents/research.md +19 -4
- package/agents/researcher.md +19 -29
- package/agents/retro.md +32 -0
- package/agents/review-intake.md +20 -4
- package/agents/review.md +32 -4
- package/agents/reviewer.md +20 -28
- package/agents/safeguard.md +19 -4
- package/agents/sast.md +18 -4
- package/agents/scaffold.md +41 -0
- package/agents/scanner.md +19 -28
- package/agents/scope-guard.md +18 -4
- package/agents/scout.md +23 -4
- package/agents/sentinel-env.md +26 -0
- package/agents/sentinel.md +33 -4
- package/agents/sequential-thinking.md +20 -4
- package/agents/session-bridge.md +24 -4
- package/agents/skill-forge.md +22 -4
- package/agents/skill-router.md +26 -4
- package/agents/slides.md +24 -0
- package/agents/surgeon.md +19 -4
- package/agents/team.md +30 -4
- package/agents/test.md +36 -4
- package/agents/trend-scout.md +17 -4
- package/agents/verification.md +20 -4
- package/agents/video-creator.md +20 -4
- package/agents/watchdog.md +19 -4
- package/agents/worktree.md +17 -4
- package/commands/rune.md +168 -168
- package/compiler/__tests__/analytics.test.js +370 -0
- package/compiler/adapters/openclaw.js +2 -2
- package/compiler/analytics.js +385 -0
- package/compiler/bin/rune.js +68 -2
- package/compiler/dashboard.js +883 -0
- package/compiler/transforms/branding.js +1 -1
- package/contexts/dev.md +34 -34
- package/contexts/research.md +43 -43
- package/contexts/review.md +55 -55
- package/extensions/ai-ml/PACK.md +88 -88
- package/extensions/ai-ml/skills/ai-agents.md +172 -172
- package/extensions/ai-ml/skills/code-sandbox.md +187 -187
- package/extensions/ai-ml/skills/deep-research.md +146 -146
- package/extensions/ai-ml/skills/embedding-search.md +66 -66
- package/extensions/ai-ml/skills/fine-tuning-guide.md +74 -74
- package/extensions/ai-ml/skills/llm-architect.md +125 -125
- package/extensions/ai-ml/skills/llm-integration.md +64 -64
- package/extensions/ai-ml/skills/prompt-patterns.md +72 -72
- package/extensions/ai-ml/skills/rag-patterns.md +66 -66
- package/extensions/ai-ml/skills/web-extraction.md +114 -114
- package/extensions/analytics/PACK.md +92 -92
- package/extensions/analytics/skills/ab-testing.md +72 -72
- package/extensions/analytics/skills/dashboard-patterns.md +83 -83
- package/extensions/analytics/skills/data-validation.md +68 -68
- package/extensions/analytics/skills/funnel-analysis.md +81 -81
- package/extensions/analytics/skills/sql-patterns.md +57 -57
- package/extensions/analytics/skills/statistical-analysis.md +79 -79
- package/extensions/analytics/skills/tracking-setup.md +71 -71
- package/extensions/backend/PACK.md +104 -104
- package/extensions/backend/skills/api-patterns.md +84 -84
- package/extensions/backend/skills/async-pipeline.md +193 -193
- package/extensions/backend/skills/auth-patterns.md +97 -97
- package/extensions/backend/skills/background-jobs.md +133 -133
- package/extensions/backend/skills/caching-patterns.md +108 -108
- package/extensions/backend/skills/cli-generation.md +133 -133
- package/extensions/backend/skills/database-patterns.md +87 -87
- package/extensions/backend/skills/middleware-patterns.md +104 -104
- package/extensions/chrome-ext/PACK.md +93 -93
- package/extensions/chrome-ext/skills/cws-preflight.md +143 -143
- package/extensions/chrome-ext/skills/cws-publish.md +104 -104
- package/extensions/chrome-ext/skills/ext-ai-integration.md +251 -251
- package/extensions/chrome-ext/skills/ext-messaging.md +139 -139
- package/extensions/chrome-ext/skills/ext-storage.md +133 -133
- package/extensions/chrome-ext/skills/mv3-scaffold.md +164 -164
- package/extensions/content/PACK.md +96 -96
- package/extensions/content/skills/blog-patterns.md +88 -88
- package/extensions/content/skills/cms-integration.md +131 -131
- package/extensions/content/skills/content-scoring.md +107 -107
- package/extensions/content/skills/i18n.md +83 -83
- package/extensions/content/skills/mdx-authoring.md +137 -137
- package/extensions/content/skills/reference.md +1014 -1014
- package/extensions/content/skills/seo-patterns.md +67 -67
- package/extensions/content/skills/video-repurpose.md +153 -153
- package/extensions/devops/PACK.md +101 -101
- package/extensions/devops/skills/chaos-testing.md +67 -67
- package/extensions/devops/skills/ci-cd.md +75 -75
- package/extensions/devops/skills/docker.md +58 -58
- package/extensions/devops/skills/edge-serverless.md +163 -163
- package/extensions/devops/skills/infra-as-code.md +158 -158
- package/extensions/devops/skills/kubernetes.md +110 -110
- package/extensions/devops/skills/monitoring.md +57 -57
- package/extensions/devops/skills/server-setup.md +64 -64
- package/extensions/devops/skills/ssl-domain.md +42 -42
- package/extensions/ecommerce/PACK.md +116 -116
- package/extensions/ecommerce/skills/cart-system.md +79 -79
- package/extensions/ecommerce/skills/inventory-mgmt.md +102 -102
- package/extensions/ecommerce/skills/order-management.md +126 -126
- package/extensions/ecommerce/skills/payment-integration.md +472 -472
- package/extensions/ecommerce/skills/shopify-dev.md +69 -69
- package/extensions/ecommerce/skills/subscription-billing.md +93 -93
- package/extensions/ecommerce/skills/tax-compliance.md +117 -117
- package/extensions/gamedev/PACK.md +142 -142
- package/extensions/gamedev/skills/asset-pipeline.md +74 -74
- package/extensions/gamedev/skills/audio-system.md +129 -129
- package/extensions/gamedev/skills/camera-system.md +87 -87
- package/extensions/gamedev/skills/ecs.md +98 -98
- package/extensions/gamedev/skills/game-loops.md +72 -72
- package/extensions/gamedev/skills/input-system.md +199 -199
- package/extensions/gamedev/skills/multiplayer.md +180 -180
- package/extensions/gamedev/skills/particles.md +105 -105
- package/extensions/gamedev/skills/physics-engine.md +89 -89
- package/extensions/gamedev/skills/scene-management.md +146 -146
- package/extensions/gamedev/skills/threejs-patterns.md +90 -90
- package/extensions/gamedev/skills/webgl.md +71 -71
- package/extensions/mobile/PACK.md +106 -106
- package/extensions/mobile/skills/app-store-connect.md +152 -152
- package/extensions/mobile/skills/app-store-prep.md +66 -66
- package/extensions/mobile/skills/deep-linking.md +109 -109
- package/extensions/mobile/skills/flutter.md +60 -60
- package/extensions/mobile/skills/ios-build-pipeline.md +142 -142
- package/extensions/mobile/skills/native-bridge.md +66 -66
- package/extensions/mobile/skills/ota-updates.md +97 -97
- package/extensions/mobile/skills/push-notifications.md +111 -111
- package/extensions/mobile/skills/react-native.md +82 -82
- package/extensions/saas/PACK.md +116 -116
- package/extensions/saas/skills/billing-integration.md +200 -200
- package/extensions/saas/skills/feature-flags.md +130 -130
- package/extensions/saas/skills/multi-tenant.md +103 -103
- package/extensions/saas/skills/onboarding-flow.md +139 -139
- package/extensions/saas/skills/subscription-flow.md +95 -95
- package/extensions/saas/skills/team-management.md +144 -144
- package/extensions/security/PACK.md +99 -99
- package/extensions/security/skills/api-security.md +140 -140
- package/extensions/security/skills/compliance.md +68 -68
- package/extensions/security/skills/owasp-audit.md +64 -64
- package/extensions/security/skills/pentest-patterns.md +77 -77
- package/extensions/security/skills/secret-mgmt.md +65 -65
- package/extensions/security/skills/supply-chain.md +65 -65
- package/extensions/trading/PACK.md +80 -80
- package/extensions/trading/skills/chart-components.md +55 -55
- package/extensions/trading/skills/experiment-loop.md +125 -125
- package/extensions/trading/skills/fintech-patterns.md +47 -47
- package/extensions/trading/skills/indicator-library.md +58 -58
- package/extensions/trading/skills/quant-analysis.md +111 -111
- package/extensions/trading/skills/realtime-data.md +58 -58
- package/extensions/trading/skills/trade-logic.md +104 -104
- package/extensions/ui/PACK.md +130 -130
- package/extensions/ui/skills/a11y-audit.md +91 -91
- package/extensions/ui/skills/animation-patterns.md +127 -106
- package/extensions/ui/skills/component-patterns.md +100 -75
- package/extensions/ui/skills/design-decision.md +108 -108
- package/extensions/ui/skills/design-system.md +68 -68
- package/extensions/ui/skills/landing-patterns.md +155 -155
- package/extensions/ui/skills/palette-picker.md +173 -173
- package/extensions/ui/skills/react-health.md +90 -90
- package/extensions/ui/skills/type-system.md +125 -125
- package/extensions/ui/skills/web-vitals.md +153 -153
- package/extensions/zalo/PACK.md +145 -145
- package/extensions/zalo/skills/zalo-oa-mcp.md +317 -317
- package/extensions/zalo/skills/zalo-oa-messaging.md +429 -429
- package/extensions/zalo/skills/zalo-oa-setup.md +236 -236
- package/extensions/zalo/skills/zalo-oa-webhook.md +189 -189
- package/extensions/zalo/skills/zalo-personal-messaging.md +194 -194
- package/extensions/zalo/skills/zalo-personal-setup.md +153 -153
- package/extensions/zalo/skills/zalo-rate-guard.md +219 -219
- package/hooks/auto-format/index.cjs +48 -48
- package/hooks/context-watch/index.cjs +95 -68
- package/hooks/hooks.json +111 -111
- package/hooks/metrics-collector/index.cjs +86 -42
- package/hooks/post-session-reflect/index.cjs +189 -153
- package/hooks/pre-compact/index.cjs +95 -95
- package/hooks/run-hook.cmd +1 -1
- package/hooks/secrets-scan/index.cjs +100 -100
- package/hooks/session-start/index.cjs +71 -65
- package/hooks/typecheck/index.cjs +65 -65
- package/package.json +63 -63
- package/references/ui-pro-max-data/LICENSE-UI-PRO-MAX +21 -21
- package/references/ui-pro-max-data/charts.csv +26 -26
- package/references/ui-pro-max-data/colors.csv +161 -161
- package/references/ui-pro-max-data/styles.csv +68 -68
- package/references/ui-pro-max-data/typography.csv +74 -74
- package/references/ui-pro-max-data/ui-reasoning.csv +162 -162
- package/references/ui-pro-max-data/ux-guidelines.csv +99 -99
- package/skills/adversary/SKILL.md +283 -283
- package/skills/asset-creator/SKILL.md +157 -157
- package/skills/audit/SKILL.md +148 -2
- package/skills/autopsy/SKILL.md +335 -259
- package/skills/autopsy/references/repo-analysis-patterns.md +113 -0
- package/skills/ba/SKILL.md +72 -2
- package/skills/brainstorm/SKILL.md +342 -341
- package/skills/browser-pilot/SKILL.md +168 -168
- package/skills/constraint-check/SKILL.md +165 -165
- package/skills/context-engine/SKILL.md +404 -404
- package/skills/cook/SKILL.md +917 -834
- package/skills/cook/references/output-format.md +33 -0
- package/skills/db/SKILL.md +273 -272
- package/skills/debug/SKILL.md +465 -443
- package/skills/dependency-doctor/SKILL.md +265 -235
- package/skills/deploy/SKILL.md +274 -231
- package/skills/design/DESIGN-REFERENCE.md +365 -365
- package/skills/design/SKILL.md +589 -482
- package/skills/doc-processor/SKILL.md +254 -254
- package/skills/docs/SKILL.md +374 -373
- package/skills/docs-seeker/SKILL.md +177 -177
- package/skills/fix/SKILL.md +330 -308
- package/skills/git/SKILL.md +339 -339
- package/skills/graft/SKILL.md +352 -0
- package/skills/graft/references/challenge-framework.md +98 -0
- package/skills/graft/references/mode-decision.md +44 -0
- package/skills/hallucination-guard/SKILL.md +219 -219
- package/skills/incident/SKILL.md +254 -251
- package/skills/integrity-check/SKILL.md +169 -169
- package/skills/journal/SKILL.md +240 -238
- package/skills/launch/SKILL.md +344 -342
- package/skills/logic-guardian/SKILL.md +251 -251
- package/skills/marketing/SKILL.md +290 -245
- package/skills/mcp-builder/SKILL.md +425 -423
- package/skills/mcp-builder/references/auto-discovery-pattern.md +169 -0
- package/skills/neural-memory/SKILL.md +362 -362
- package/skills/onboard/SKILL.md +404 -403
- package/skills/perf/SKILL.md +346 -346
- package/skills/plan/SKILL.md +433 -370
- package/skills/plan/references/feature-map.md +84 -0
- package/skills/preflight/SKILL.md +415 -396
- package/skills/problem-solver/SKILL.md +380 -284
- package/skills/rescue/SKILL.md +474 -450
- package/skills/retro/SKILL.md +5 -1
- package/skills/review/SKILL.md +612 -535
- package/skills/review-intake/SKILL.md +249 -249
- package/skills/safeguard/SKILL.md +200 -200
- package/skills/sast/SKILL.md +190 -190
- package/skills/scaffold/SKILL.md +328 -286
- package/skills/scope-guard/SKILL.md +180 -162
- package/skills/scout/SKILL.md +263 -263
- package/skills/sentinel/SKILL.md +382 -353
- package/skills/sentinel-env/SKILL.md +254 -254
- package/skills/sequential-thinking/SKILL.md +234 -234
- package/skills/session-bridge/SKILL.md +543 -397
- package/skills/skill-forge/SKILL.md +581 -539
- package/skills/skill-router/{skill.md → SKILL.md} +30 -2
- package/skills/surgeon/SKILL.md +215 -215
- package/skills/team/SKILL.md +556 -514
- package/skills/test/SKILL.md +614 -587
- package/skills/trend-scout/SKILL.md +145 -145
- package/skills/verification/SKILL.md +326 -325
- package/skills/video-creator/SKILL.md +201 -201
- package/skills/watchdog/SKILL.md +168 -168
- package/skills/worktree/SKILL.md +140 -140
|
@@ -1,172 +1,172 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: "ai-agents"
|
|
3
|
-
pack: "@rune/ai-ml"
|
|
4
|
-
description: "Stateful AI agent architecture — persistent state, callable RPC methods, scheduling, multi-agent coordination, MCP server integration, and real-time client communication via WebSocket."
|
|
5
|
-
model: sonnet
|
|
6
|
-
tools: [Read, Edit, Write, Grep, Glob, Bash]
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# ai-agents
|
|
10
|
-
|
|
11
|
-
Stateful AI agent architecture — persistent state, callable RPC methods, scheduling, multi-agent coordination, MCP server integration, and real-time client communication via WebSocket. Covers agent lifecycle, state management patterns, tool registration, human-in-the-loop approval flows, and durable workflow orchestration for long-running agent tasks.
|
|
12
|
-
|
|
13
|
-
#### Workflow
|
|
14
|
-
|
|
15
|
-
**Step 1 — Classify agent type**
|
|
16
|
-
Identify what the agent needs to do and map to an architecture:
|
|
17
|
-
|
|
18
|
-
| Agent Type | Key Characteristics | Platform Options |
|
|
19
|
-
|---|---|---|
|
|
20
|
-
| Stateless tool-caller | Single request → tool calls → response. No memory between requests. | Any LLM API + function calling |
|
|
21
|
-
| Conversational with memory | Multi-turn dialogue. Needs chat history persistence. | Session store (Redis, KV) + LLM |
|
|
22
|
-
| Stateful autonomous | Persistent state, scheduled tasks, reacts to events. Long-lived. | Cloudflare Agents SDK, LangGraph, CrewAI |
|
|
23
|
-
| Multi-agent coordinator | Multiple specialized agents collaborating on a task. | LangGraph, AutoGen, custom orchestrator |
|
|
24
|
-
| MCP server | Exposes tools/resources to any MCP-compatible client. | Cloudflare McpAgent, custom MCP server |
|
|
25
|
-
|
|
26
|
-
**Step 2 — Design state management**
|
|
27
|
-
For stateful agents, define the state contract:
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
// State must be serializable (JSON-safe) — no functions, no circular refs
|
|
31
|
-
interface AgentState {
|
|
32
|
-
// Domain state
|
|
33
|
-
conversations: ConversationEntry[];
|
|
34
|
-
preferences: Record<string, string>;
|
|
35
|
-
taskQueue: ScheduledTask[];
|
|
36
|
-
|
|
37
|
-
// Metadata
|
|
38
|
-
createdAt: string;
|
|
39
|
-
lastActiveAt: string;
|
|
40
|
-
version: number;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// State validation — reject invalid transitions
|
|
44
|
-
function validateStateChange(current: AgentState, next: AgentState): void {
|
|
45
|
-
if (next.version < current.version) {
|
|
46
|
-
throw new Error('State version cannot decrease — concurrent modification detected');
|
|
47
|
-
}
|
|
48
|
-
if (next.conversations.length > 10_000) {
|
|
49
|
-
throw new Error('Conversation limit exceeded — archive old entries first');
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
**Step 3 — Implement tool registration**
|
|
55
|
-
Define agent capabilities as typed, callable methods:
|
|
56
|
-
|
|
57
|
-
```typescript
|
|
58
|
-
// Tools as typed RPC methods (Cloudflare Agents SDK pattern)
|
|
59
|
-
import { Agent, callable } from 'agents';
|
|
60
|
-
|
|
61
|
-
export class ResearchAgent extends Agent<Env, ResearchState> {
|
|
62
|
-
initialState: ResearchState = { findings: [], status: 'idle' };
|
|
63
|
-
|
|
64
|
-
@callable()
|
|
65
|
-
async search(query: string): Promise<SearchResult[]> {
|
|
66
|
-
this.setState({ ...this.state, status: 'searching' });
|
|
67
|
-
const results = await this.env.AI.run('@cf/meta/llama-3-8b-instruct', {
|
|
68
|
-
prompt: `Search for: ${query}`,
|
|
69
|
-
});
|
|
70
|
-
const findings = parseResults(results);
|
|
71
|
-
this.setState({
|
|
72
|
-
...this.state,
|
|
73
|
-
findings: [...this.state.findings, ...findings],
|
|
74
|
-
status: 'idle',
|
|
75
|
-
});
|
|
76
|
-
return findings;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
@callable()
|
|
80
|
-
async summarize(): Promise<string> {
|
|
81
|
-
if (this.state.findings.length === 0) {
|
|
82
|
-
throw new Error('No findings to summarize — run search first');
|
|
83
|
-
}
|
|
84
|
-
return generateSummary(this.state.findings);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
**Step 4 — Add scheduling and durability**
|
|
90
|
-
For agents that need to perform work on a schedule or survive restarts:
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
// Scheduled tasks — one-time, recurring, and cron
|
|
94
|
-
@callable()
|
|
95
|
-
async scheduleDigest(userId: string) {
|
|
96
|
-
// Daily digest at 9 AM
|
|
97
|
-
await this.schedule('0 9 * * *', 'sendDigest', { userId });
|
|
98
|
-
|
|
99
|
-
// One-time reminder in 1 hour
|
|
100
|
-
await this.schedule(3600, 'sendReminder', { userId, message: 'Check results' });
|
|
101
|
-
|
|
102
|
-
// Recurring every 30 minutes
|
|
103
|
-
await this.scheduleEvery(1800, 'pollDataSource');
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Handler runs when scheduled time arrives — even if agent was hibernated
|
|
107
|
-
async onScheduledTask(task: ScheduledTask) {
|
|
108
|
-
switch (task.type) {
|
|
109
|
-
case 'sendDigest':
|
|
110
|
-
await this.compileAndSendDigest(task.payload.userId);
|
|
111
|
-
break;
|
|
112
|
-
case 'pollDataSource':
|
|
113
|
-
const newData = await fetchLatest();
|
|
114
|
-
if (newData.length > 0) {
|
|
115
|
-
this.setState({ ...this.state, lastPoll: Date.now(), data: newData });
|
|
116
|
-
}
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
**Step 5 — Human-in-the-loop patterns**
|
|
123
|
-
For agents that need approval before taking high-impact actions:
|
|
124
|
-
|
|
125
|
-
```typescript
|
|
126
|
-
// Approval flow — agent pauses, human approves, agent resumes
|
|
127
|
-
interface PendingApproval {
|
|
128
|
-
id: string;
|
|
129
|
-
action: string;
|
|
130
|
-
params: Record<string, unknown>;
|
|
131
|
-
requestedAt: string;
|
|
132
|
-
status: 'pending' | 'approved' | 'rejected';
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
@callable()
|
|
136
|
-
async requestApproval(action: string, params: Record<string, unknown>): Promise<string> {
|
|
137
|
-
const approval: PendingApproval = {
|
|
138
|
-
id: crypto.randomUUID(),
|
|
139
|
-
action,
|
|
140
|
-
params,
|
|
141
|
-
requestedAt: new Date().toISOString(),
|
|
142
|
-
status: 'pending',
|
|
143
|
-
};
|
|
144
|
-
this.setState({
|
|
145
|
-
...this.state,
|
|
146
|
-
pendingApprovals: [...this.state.pendingApprovals, approval],
|
|
147
|
-
});
|
|
148
|
-
// Client receives state update via WebSocket → shows approval UI
|
|
149
|
-
return approval.id;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
@callable()
|
|
153
|
-
async resolveApproval(id: string, decision: 'approved' | 'rejected') {
|
|
154
|
-
const updated = this.state.pendingApprovals.map(a =>
|
|
155
|
-
a.id === id ? { ...a, status: decision } : a
|
|
156
|
-
);
|
|
157
|
-
this.setState({ ...this.state, pendingApprovals: updated });
|
|
158
|
-
if (decision === 'approved') {
|
|
159
|
-
const approval = updated.find(a => a.id === id)!;
|
|
160
|
-
await this.executeAction(approval.action, approval.params);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
#### Sharp Edges
|
|
166
|
-
|
|
167
|
-
| Failure Mode | Mitigation |
|
|
168
|
-
|---|---|
|
|
169
|
-
| State grows unbounded (conversation history, logs) | Implement max size limits with archival; prune old entries on state update |
|
|
170
|
-
| Concurrent state mutations from multiple clients | Use version counter in state; reject updates with stale version |
|
|
171
|
-
| Agent crashes mid-workflow, loses progress | Use durable workflows (Cloudflare Workflows, Temporal) for multi-step tasks — each step is persisted |
|
|
172
|
-
| Scheduled tasks pile up during agent hibernation | Deduplicate on wake-up; use idempotency keys for task handlers |
|
|
1
|
+
---
|
|
2
|
+
name: "ai-agents"
|
|
3
|
+
pack: "@rune/ai-ml"
|
|
4
|
+
description: "Stateful AI agent architecture — persistent state, callable RPC methods, scheduling, multi-agent coordination, MCP server integration, and real-time client communication via WebSocket."
|
|
5
|
+
model: sonnet
|
|
6
|
+
tools: [Read, Edit, Write, Grep, Glob, Bash]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# ai-agents
|
|
10
|
+
|
|
11
|
+
Stateful AI agent architecture — persistent state, callable RPC methods, scheduling, multi-agent coordination, MCP server integration, and real-time client communication via WebSocket. Covers agent lifecycle, state management patterns, tool registration, human-in-the-loop approval flows, and durable workflow orchestration for long-running agent tasks.
|
|
12
|
+
|
|
13
|
+
#### Workflow
|
|
14
|
+
|
|
15
|
+
**Step 1 — Classify agent type**
|
|
16
|
+
Identify what the agent needs to do and map to an architecture:
|
|
17
|
+
|
|
18
|
+
| Agent Type | Key Characteristics | Platform Options |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| Stateless tool-caller | Single request → tool calls → response. No memory between requests. | Any LLM API + function calling |
|
|
21
|
+
| Conversational with memory | Multi-turn dialogue. Needs chat history persistence. | Session store (Redis, KV) + LLM |
|
|
22
|
+
| Stateful autonomous | Persistent state, scheduled tasks, reacts to events. Long-lived. | Cloudflare Agents SDK, LangGraph, CrewAI |
|
|
23
|
+
| Multi-agent coordinator | Multiple specialized agents collaborating on a task. | LangGraph, AutoGen, custom orchestrator |
|
|
24
|
+
| MCP server | Exposes tools/resources to any MCP-compatible client. | Cloudflare McpAgent, custom MCP server |
|
|
25
|
+
|
|
26
|
+
**Step 2 — Design state management**
|
|
27
|
+
For stateful agents, define the state contract:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// State must be serializable (JSON-safe) — no functions, no circular refs
|
|
31
|
+
interface AgentState {
|
|
32
|
+
// Domain state
|
|
33
|
+
conversations: ConversationEntry[];
|
|
34
|
+
preferences: Record<string, string>;
|
|
35
|
+
taskQueue: ScheduledTask[];
|
|
36
|
+
|
|
37
|
+
// Metadata
|
|
38
|
+
createdAt: string;
|
|
39
|
+
lastActiveAt: string;
|
|
40
|
+
version: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// State validation — reject invalid transitions
|
|
44
|
+
function validateStateChange(current: AgentState, next: AgentState): void {
|
|
45
|
+
if (next.version < current.version) {
|
|
46
|
+
throw new Error('State version cannot decrease — concurrent modification detected');
|
|
47
|
+
}
|
|
48
|
+
if (next.conversations.length > 10_000) {
|
|
49
|
+
throw new Error('Conversation limit exceeded — archive old entries first');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Step 3 — Implement tool registration**
|
|
55
|
+
Define agent capabilities as typed, callable methods:
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
// Tools as typed RPC methods (Cloudflare Agents SDK pattern)
|
|
59
|
+
import { Agent, callable } from 'agents';
|
|
60
|
+
|
|
61
|
+
export class ResearchAgent extends Agent<Env, ResearchState> {
|
|
62
|
+
initialState: ResearchState = { findings: [], status: 'idle' };
|
|
63
|
+
|
|
64
|
+
@callable()
|
|
65
|
+
async search(query: string): Promise<SearchResult[]> {
|
|
66
|
+
this.setState({ ...this.state, status: 'searching' });
|
|
67
|
+
const results = await this.env.AI.run('@cf/meta/llama-3-8b-instruct', {
|
|
68
|
+
prompt: `Search for: ${query}`,
|
|
69
|
+
});
|
|
70
|
+
const findings = parseResults(results);
|
|
71
|
+
this.setState({
|
|
72
|
+
...this.state,
|
|
73
|
+
findings: [...this.state.findings, ...findings],
|
|
74
|
+
status: 'idle',
|
|
75
|
+
});
|
|
76
|
+
return findings;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@callable()
|
|
80
|
+
async summarize(): Promise<string> {
|
|
81
|
+
if (this.state.findings.length === 0) {
|
|
82
|
+
throw new Error('No findings to summarize — run search first');
|
|
83
|
+
}
|
|
84
|
+
return generateSummary(this.state.findings);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Step 4 — Add scheduling and durability**
|
|
90
|
+
For agents that need to perform work on a schedule or survive restarts:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// Scheduled tasks — one-time, recurring, and cron
|
|
94
|
+
@callable()
|
|
95
|
+
async scheduleDigest(userId: string) {
|
|
96
|
+
// Daily digest at 9 AM
|
|
97
|
+
await this.schedule('0 9 * * *', 'sendDigest', { userId });
|
|
98
|
+
|
|
99
|
+
// One-time reminder in 1 hour
|
|
100
|
+
await this.schedule(3600, 'sendReminder', { userId, message: 'Check results' });
|
|
101
|
+
|
|
102
|
+
// Recurring every 30 minutes
|
|
103
|
+
await this.scheduleEvery(1800, 'pollDataSource');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Handler runs when scheduled time arrives — even if agent was hibernated
|
|
107
|
+
async onScheduledTask(task: ScheduledTask) {
|
|
108
|
+
switch (task.type) {
|
|
109
|
+
case 'sendDigest':
|
|
110
|
+
await this.compileAndSendDigest(task.payload.userId);
|
|
111
|
+
break;
|
|
112
|
+
case 'pollDataSource':
|
|
113
|
+
const newData = await fetchLatest();
|
|
114
|
+
if (newData.length > 0) {
|
|
115
|
+
this.setState({ ...this.state, lastPoll: Date.now(), data: newData });
|
|
116
|
+
}
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Step 5 — Human-in-the-loop patterns**
|
|
123
|
+
For agents that need approval before taking high-impact actions:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// Approval flow — agent pauses, human approves, agent resumes
|
|
127
|
+
interface PendingApproval {
|
|
128
|
+
id: string;
|
|
129
|
+
action: string;
|
|
130
|
+
params: Record<string, unknown>;
|
|
131
|
+
requestedAt: string;
|
|
132
|
+
status: 'pending' | 'approved' | 'rejected';
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@callable()
|
|
136
|
+
async requestApproval(action: string, params: Record<string, unknown>): Promise<string> {
|
|
137
|
+
const approval: PendingApproval = {
|
|
138
|
+
id: crypto.randomUUID(),
|
|
139
|
+
action,
|
|
140
|
+
params,
|
|
141
|
+
requestedAt: new Date().toISOString(),
|
|
142
|
+
status: 'pending',
|
|
143
|
+
};
|
|
144
|
+
this.setState({
|
|
145
|
+
...this.state,
|
|
146
|
+
pendingApprovals: [...this.state.pendingApprovals, approval],
|
|
147
|
+
});
|
|
148
|
+
// Client receives state update via WebSocket → shows approval UI
|
|
149
|
+
return approval.id;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@callable()
|
|
153
|
+
async resolveApproval(id: string, decision: 'approved' | 'rejected') {
|
|
154
|
+
const updated = this.state.pendingApprovals.map(a =>
|
|
155
|
+
a.id === id ? { ...a, status: decision } : a
|
|
156
|
+
);
|
|
157
|
+
this.setState({ ...this.state, pendingApprovals: updated });
|
|
158
|
+
if (decision === 'approved') {
|
|
159
|
+
const approval = updated.find(a => a.id === id)!;
|
|
160
|
+
await this.executeAction(approval.action, approval.params);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
#### Sharp Edges
|
|
166
|
+
|
|
167
|
+
| Failure Mode | Mitigation |
|
|
168
|
+
|---|---|
|
|
169
|
+
| State grows unbounded (conversation history, logs) | Implement max size limits with archival; prune old entries on state update |
|
|
170
|
+
| Concurrent state mutations from multiple clients | Use version counter in state; reject updates with stale version |
|
|
171
|
+
| Agent crashes mid-workflow, loses progress | Use durable workflows (Cloudflare Workflows, Temporal) for multi-step tasks — each step is persisted |
|
|
172
|
+
| Scheduled tasks pile up during agent hibernation | Deduplicate on wake-up; use idempotency keys for task handlers |
|