ag-cortex 0.1.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/.agent/commands/test-browser.md +339 -0
- package/.agent/rules/00-constitution.md +46 -0
- package/.agent/rules/project-rules.md +49 -0
- package/.agent/skills/agent-browser/SKILL.md +223 -0
- package/.agent/skills/agent-native-architecture/SKILL.md +435 -0
- package/.agent/skills/agent-native-architecture/references/action-parity-discipline.md +409 -0
- package/.agent/skills/agent-native-architecture/references/agent-execution-patterns.md +467 -0
- package/.agent/skills/agent-native-architecture/references/agent-native-testing.md +582 -0
- package/.agent/skills/agent-native-architecture/references/architecture-patterns.md +478 -0
- package/.agent/skills/agent-native-architecture/references/dynamic-context-injection.md +338 -0
- package/.agent/skills/agent-native-architecture/references/files-universal-interface.md +301 -0
- package/.agent/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +359 -0
- package/.agent/skills/agent-native-architecture/references/mcp-tool-design.md +506 -0
- package/.agent/skills/agent-native-architecture/references/mobile-patterns.md +871 -0
- package/.agent/skills/agent-native-architecture/references/product-implications.md +443 -0
- package/.agent/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +317 -0
- package/.agent/skills/agent-native-architecture/references/self-modification.md +269 -0
- package/.agent/skills/agent-native-architecture/references/shared-workspace-architecture.md +680 -0
- package/.agent/skills/agent-native-architecture/references/system-prompt-design.md +250 -0
- package/.agent/skills/agent-native-reviewer/SKILL.md +246 -0
- package/.agent/skills/andrew-kane-gem-writer/SKILL.md +184 -0
- package/.agent/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
- package/.agent/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
- package/.agent/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
- package/.agent/skills/andrew-kane-gem-writer/references/resources.md +119 -0
- package/.agent/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
- package/.agent/skills/ankane-readme-writer/SKILL.md +50 -0
- package/.agent/skills/architecture-strategist/SKILL.md +52 -0
- package/.agent/skills/best-practices-researcher/SKILL.md +100 -0
- package/.agent/skills/bug-reproduction-validator/SKILL.md +67 -0
- package/.agent/skills/code-simplicity-reviewer/SKILL.md +85 -0
- package/.agent/skills/coding-tutor/.claude-plugin/plugin.json +9 -0
- package/.agent/skills/coding-tutor/README.md +37 -0
- package/.agent/skills/coding-tutor/commands/quiz-me.md +1 -0
- package/.agent/skills/coding-tutor/commands/sync-tutorials.md +25 -0
- package/.agent/skills/coding-tutor/commands/teach-me.md +1 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/SKILL.md +214 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/create_tutorial.py +202 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py +203 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/quiz_priority.py +190 -0
- package/.agent/skills/coding-tutor/skills/coding-tutor/scripts/setup_tutorials.py +132 -0
- package/.agent/skills/compound-docs/SKILL.md +510 -0
- package/.agent/skills/compound-docs/assets/critical-pattern-template.md +34 -0
- package/.agent/skills/compound-docs/assets/resolution-template.md +93 -0
- package/.agent/skills/compound-docs/references/yaml-schema.md +65 -0
- package/.agent/skills/compound-docs/schema.yaml +176 -0
- package/.agent/skills/create-agent-skills/SKILL.md +299 -0
- package/.agent/skills/create-agent-skills/references/api-security.md +226 -0
- package/.agent/skills/create-agent-skills/references/be-clear-and-direct.md +531 -0
- package/.agent/skills/create-agent-skills/references/best-practices.md +404 -0
- package/.agent/skills/create-agent-skills/references/common-patterns.md +595 -0
- package/.agent/skills/create-agent-skills/references/core-principles.md +437 -0
- package/.agent/skills/create-agent-skills/references/executable-code.md +175 -0
- package/.agent/skills/create-agent-skills/references/iteration-and-testing.md +474 -0
- package/.agent/skills/create-agent-skills/references/official-spec.md +185 -0
- package/.agent/skills/create-agent-skills/references/recommended-structure.md +168 -0
- package/.agent/skills/create-agent-skills/references/skill-structure.md +372 -0
- package/.agent/skills/create-agent-skills/references/using-scripts.md +113 -0
- package/.agent/skills/create-agent-skills/references/using-templates.md +112 -0
- package/.agent/skills/create-agent-skills/references/workflows-and-validation.md +510 -0
- package/.agent/skills/create-agent-skills/templates/router-skill.md +73 -0
- package/.agent/skills/create-agent-skills/templates/simple-skill.md +33 -0
- package/.agent/skills/create-agent-skills/workflows/add-reference.md +96 -0
- package/.agent/skills/create-agent-skills/workflows/add-script.md +93 -0
- package/.agent/skills/create-agent-skills/workflows/add-template.md +74 -0
- package/.agent/skills/create-agent-skills/workflows/add-workflow.md +120 -0
- package/.agent/skills/create-agent-skills/workflows/audit-skill.md +138 -0
- package/.agent/skills/create-agent-skills/workflows/create-domain-expertise-skill.md +605 -0
- package/.agent/skills/create-agent-skills/workflows/create-new-skill.md +191 -0
- package/.agent/skills/create-agent-skills/workflows/get-guidance.md +121 -0
- package/.agent/skills/create-agent-skills/workflows/upgrade-to-router.md +161 -0
- package/.agent/skills/create-agent-skills/workflows/verify-skill.md +204 -0
- package/.agent/skills/data-integrity-guardian/SKILL.md +70 -0
- package/.agent/skills/data-migration-expert/SKILL.md +97 -0
- package/.agent/skills/deployment-verification-agent/SKILL.md +159 -0
- package/.agent/skills/design-implementation-reviewer/SKILL.md +85 -0
- package/.agent/skills/design-iterator/SKILL.md +197 -0
- package/.agent/skills/dhh-rails-reviewer/SKILL.md +45 -0
- package/.agent/skills/dhh-rails-style/SKILL.md +184 -0
- package/.agent/skills/dhh-rails-style/references/architecture.md +653 -0
- package/.agent/skills/dhh-rails-style/references/controllers.md +303 -0
- package/.agent/skills/dhh-rails-style/references/frontend.md +510 -0
- package/.agent/skills/dhh-rails-style/references/gems.md +266 -0
- package/.agent/skills/dhh-rails-style/references/models.md +359 -0
- package/.agent/skills/dhh-rails-style/references/testing.md +338 -0
- package/.agent/skills/dspy-ruby/SKILL.md +594 -0
- package/.agent/skills/dspy-ruby/assets/config-template.rb +359 -0
- package/.agent/skills/dspy-ruby/assets/module-template.rb +326 -0
- package/.agent/skills/dspy-ruby/assets/signature-template.rb +143 -0
- package/.agent/skills/dspy-ruby/references/core-concepts.md +265 -0
- package/.agent/skills/dspy-ruby/references/optimization.md +623 -0
- package/.agent/skills/dspy-ruby/references/providers.md +305 -0
- package/.agent/skills/every-style-editor/SKILL.md +134 -0
- package/.agent/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
- package/.agent/skills/figma-design-sync/SKILL.md +166 -0
- package/.agent/skills/file-todos/SKILL.md +251 -0
- package/.agent/skills/file-todos/assets/todo-template.md +155 -0
- package/.agent/skills/framework-docs-researcher/SKILL.md +83 -0
- package/.agent/skills/frontend-design/SKILL.md +42 -0
- package/.agent/skills/gemini-imagegen/SKILL.md +237 -0
- package/.agent/skills/gemini-imagegen/requirements.txt +2 -0
- package/.agent/skills/gemini-imagegen/scripts/compose_images.py +168 -0
- package/.agent/skills/gemini-imagegen/scripts/edit_image.py +157 -0
- package/.agent/skills/gemini-imagegen/scripts/gemini_images.py +265 -0
- package/.agent/skills/gemini-imagegen/scripts/generate_image.py +147 -0
- package/.agent/skills/gemini-imagegen/scripts/multi_turn_chat.py +215 -0
- package/.agent/skills/git-history-analyzer/SKILL.md +42 -0
- package/.agent/skills/git-worktree/SKILL.md +302 -0
- package/.agent/skills/git-worktree/scripts/worktree-manager.sh +345 -0
- package/.agent/skills/julik-frontend-races-reviewer/SKILL.md +222 -0
- package/.agent/skills/kieran-python-reviewer/SKILL.md +104 -0
- package/.agent/skills/kieran-rails-reviewer/SKILL.md +86 -0
- package/.agent/skills/kieran-typescript-reviewer/SKILL.md +95 -0
- package/.agent/skills/lint/SKILL.md +16 -0
- package/.agent/skills/pattern-recognition-specialist/SKILL.md +57 -0
- package/.agent/skills/performance-oracle/SKILL.md +110 -0
- package/.agent/skills/pr-comment-resolver/SKILL.md +69 -0
- package/.agent/skills/rclone/SKILL.md +150 -0
- package/.agent/skills/rclone/scripts/check_setup.sh +60 -0
- package/.agent/skills/repo-research-analyst/SKILL.md +113 -0
- package/.agent/skills/security-sentinel/SKILL.md +93 -0
- package/.agent/skills/skill-creator/SKILL.md +209 -0
- package/.agent/skills/skill-creator/scripts/init_skill.py +304 -0
- package/.agent/skills/skill-creator/scripts/package_skill.py +112 -0
- package/.agent/skills/skill-creator/scripts/quick_validate.py +72 -0
- package/.agent/skills/spec-flow-analyzer/SKILL.md +113 -0
- package/.agent/skills/test-agent/SKILL.md +4 -0
- package/.agent/workflows/agent-native-audit.md +277 -0
- package/.agent/workflows/ask-user-question.md +21 -0
- package/.agent/workflows/changelog.md +137 -0
- package/.agent/workflows/compound.md +202 -0
- package/.agent/workflows/create-agent-skill.md +8 -0
- package/.agent/workflows/deepen-plan-research.md +334 -0
- package/.agent/workflows/deepen-plan-synthesis.md +182 -0
- package/.agent/workflows/deepen-plan.md +79 -0
- package/.agent/workflows/feature-video.md +342 -0
- package/.agent/workflows/generate-command.md +162 -0
- package/.agent/workflows/heal-skill.md +142 -0
- package/.agent/workflows/lfg.md +20 -0
- package/.agent/workflows/plan-analysis.md +67 -0
- package/.agent/workflows/plan-next-steps.md +63 -0
- package/.agent/workflows/plan-review.md +33 -0
- package/.agent/workflows/plan-synthesis.md +106 -0
- package/.agent/workflows/plan.md +49 -0
- package/.agent/workflows/report-bug.md +150 -0
- package/.agent/workflows/reproduce-bug.md +99 -0
- package/.agent/workflows/resolve-parallel.md +34 -0
- package/.agent/workflows/resolve-pr-parallel.md +49 -0
- package/.agent/workflows/resolve-todo-parallel.md +35 -0
- package/.agent/workflows/review-analysis.md +145 -0
- package/.agent/workflows/review-synthesis.md +262 -0
- package/.agent/workflows/review.md +64 -0
- package/.agent/workflows/ship.md +90 -0
- package/.agent/workflows/test-command.md +3 -0
- package/.agent/workflows/triage.md +310 -0
- package/.agent/workflows/work.md +157 -0
- package/.agent/workflows/xcode-test.md +332 -0
- package/LICENSE +22 -0
- package/README.md +49 -0
- package/bin/ag-cortex.js +54 -0
- package/lib/core.js +165 -0
- package/package.json +31 -0
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
<overview>
|
|
2
|
+
Architectural patterns for building agent-native systems. These patterns emerge from the five core principles: Parity, Granularity, Composability, Emergent Capability, and Improvement Over Time.
|
|
3
|
+
|
|
4
|
+
Features are outcomes achieved by agents operating in a loop, not functions you write. Tools are atomic primitives. The agent applies judgment; the prompt defines the outcome.
|
|
5
|
+
|
|
6
|
+
See also:
|
|
7
|
+
- [files-universal-interface.md](./files-universal-interface.md) for file organization and context.md patterns
|
|
8
|
+
- [agent-execution-patterns.md](./agent-execution-patterns.md) for completion signals and partial completion
|
|
9
|
+
- [product-implications.md](./product-implications.md) for progressive disclosure and approval patterns
|
|
10
|
+
</overview>
|
|
11
|
+
|
|
12
|
+
<pattern name="event-driven-agent">
|
|
13
|
+
## Event-Driven Agent Architecture
|
|
14
|
+
|
|
15
|
+
The agent runs as a long-lived process that responds to events. Events become prompts.
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
19
|
+
│ Agent Loop │
|
|
20
|
+
├─────────────────────────────────────────────────────────────┤
|
|
21
|
+
│ Event Source → Agent (Antigravity) → Tool Calls → Response │
|
|
22
|
+
└─────────────────────────────────────────────────────────────┘
|
|
23
|
+
│
|
|
24
|
+
┌───────────────┼───────────────┐
|
|
25
|
+
▼ ▼ ▼
|
|
26
|
+
┌─────────┐ ┌──────────┐ ┌───────────┐
|
|
27
|
+
│ Content │ │ Self │ │ Data │
|
|
28
|
+
│ Tools │ │ Tools │ │ Tools │
|
|
29
|
+
└─────────┘ └──────────┘ └───────────┘
|
|
30
|
+
(write_file) (read_source) (store_item)
|
|
31
|
+
(restart) (list_items)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Key characteristics:**
|
|
35
|
+
- Events (messages, webhooks, timers) trigger agent turns
|
|
36
|
+
- Agent decides how to respond based on system prompt
|
|
37
|
+
- Tools are primitives for IO, not business logic
|
|
38
|
+
- State persists between events via data tools
|
|
39
|
+
|
|
40
|
+
**Example: Discord feedback bot**
|
|
41
|
+
```typescript
|
|
42
|
+
// Event source
|
|
43
|
+
client.on("messageCreate", (message) => {
|
|
44
|
+
if (!message.author.bot) {
|
|
45
|
+
runAgent({
|
|
46
|
+
userMessage: `New message from ${message.author}: "${message.content}"`,
|
|
47
|
+
channelId: message.channelId,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// System prompt defines behavior
|
|
53
|
+
const systemPrompt = `
|
|
54
|
+
When someone shares feedback:
|
|
55
|
+
1. Acknowledge their feedback warmly
|
|
56
|
+
2. Ask clarifying questions if needed
|
|
57
|
+
3. Store it using the feedback tools
|
|
58
|
+
4. Update the feedback site
|
|
59
|
+
|
|
60
|
+
Use your judgment about importance and categorization.
|
|
61
|
+
`;
|
|
62
|
+
```
|
|
63
|
+
</pattern>
|
|
64
|
+
|
|
65
|
+
<pattern name="two-layer-git">
|
|
66
|
+
## Two-Layer Git Architecture
|
|
67
|
+
|
|
68
|
+
For self-modifying agents, separate code (shared) from data (instance-specific).
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
72
|
+
│ GitHub (shared repo) │
|
|
73
|
+
│ - src/ (agent code) │
|
|
74
|
+
│ - site/ (web interface) │
|
|
75
|
+
│ - package.json (dependencies) │
|
|
76
|
+
│ - .gitignore (excludes data/, logs/) │
|
|
77
|
+
└─────────────────────────────────────────────────────────────┘
|
|
78
|
+
│
|
|
79
|
+
git clone
|
|
80
|
+
│
|
|
81
|
+
▼
|
|
82
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
83
|
+
│ Instance (Server) │
|
|
84
|
+
│ │
|
|
85
|
+
│ FROM GITHUB (tracked): │
|
|
86
|
+
│ - src/ → pushed back on code changes │
|
|
87
|
+
│ - site/ → pushed, triggers deployment │
|
|
88
|
+
│ │
|
|
89
|
+
│ LOCAL ONLY (untracked): │
|
|
90
|
+
│ - data/ → instance-specific storage │
|
|
91
|
+
│ - logs/ → runtime logs │
|
|
92
|
+
│ - .env → secrets │
|
|
93
|
+
└─────────────────────────────────────────────────────────────┘
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Why this works:**
|
|
97
|
+
- Code and site are version controlled (GitHub)
|
|
98
|
+
- Raw data stays local (instance-specific)
|
|
99
|
+
- Site is generated from data, so reproducible
|
|
100
|
+
- Automatic rollback via git history
|
|
101
|
+
</pattern>
|
|
102
|
+
|
|
103
|
+
<pattern name="multi-instance">
|
|
104
|
+
## Multi-Instance Branching
|
|
105
|
+
|
|
106
|
+
Each agent instance gets its own branch while sharing core code.
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
main # Shared features, bug fixes
|
|
110
|
+
├── instance/feedback-bot # Every Reader feedback bot
|
|
111
|
+
├── instance/support-bot # Customer support bot
|
|
112
|
+
└── instance/research-bot # Research assistant
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Change flow:**
|
|
116
|
+
| Change Type | Work On | Then |
|
|
117
|
+
|-------------|---------|------|
|
|
118
|
+
| Core features | main | Merge to instance branches |
|
|
119
|
+
| Bug fixes | main | Merge to instance branches |
|
|
120
|
+
| Instance config | instance branch | Done |
|
|
121
|
+
| Instance data | instance branch | Done |
|
|
122
|
+
|
|
123
|
+
**Sync tools:**
|
|
124
|
+
```typescript
|
|
125
|
+
tool("self_deploy", "Pull latest from main, rebuild, restart", ...)
|
|
126
|
+
tool("sync_from_instance", "Merge from another instance", ...)
|
|
127
|
+
tool("propose_to_main", "Create PR to share improvements", ...)
|
|
128
|
+
```
|
|
129
|
+
</pattern>
|
|
130
|
+
|
|
131
|
+
<pattern name="site-as-output">
|
|
132
|
+
## Site as Agent Output
|
|
133
|
+
|
|
134
|
+
The agent generates and maintains a website as a natural output, not through specialized site tools.
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
Discord Message
|
|
138
|
+
↓
|
|
139
|
+
Agent processes it, extracts insights
|
|
140
|
+
↓
|
|
141
|
+
Agent decides what site updates are needed
|
|
142
|
+
↓
|
|
143
|
+
Agent writes files using write_file primitive
|
|
144
|
+
↓
|
|
145
|
+
Git commit + push triggers deployment
|
|
146
|
+
↓
|
|
147
|
+
Site updates automatically
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Key insight:** Don't build site generation tools. Give the agent file tools and teach it in the prompt how to create good sites.
|
|
151
|
+
|
|
152
|
+
```markdown
|
|
153
|
+
## Site Management
|
|
154
|
+
|
|
155
|
+
You maintain a public feedback site. When feedback comes in:
|
|
156
|
+
1. Use write_file to update site/public/content/feedback.json
|
|
157
|
+
2. If the site's React components need improvement, modify them
|
|
158
|
+
3. Commit changes and push to trigger Vercel deploy
|
|
159
|
+
|
|
160
|
+
The site should be:
|
|
161
|
+
- Clean, modern dashboard aesthetic
|
|
162
|
+
- Clear visual hierarchy
|
|
163
|
+
- Status organization (Inbox, Active, Done)
|
|
164
|
+
|
|
165
|
+
You decide the structure. Make it good.
|
|
166
|
+
```
|
|
167
|
+
</pattern>
|
|
168
|
+
|
|
169
|
+
<pattern name="approval-gates">
|
|
170
|
+
## Approval Gates Pattern
|
|
171
|
+
|
|
172
|
+
Separate "propose" from "apply" for dangerous operations.
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
// Pending changes stored separately
|
|
176
|
+
const pendingChanges = new Map<string, string>();
|
|
177
|
+
|
|
178
|
+
tool("write_file", async ({ path, content }) => {
|
|
179
|
+
if (requiresApproval(path)) {
|
|
180
|
+
// Store for approval
|
|
181
|
+
pendingChanges.set(path, content);
|
|
182
|
+
const diff = generateDiff(path, content);
|
|
183
|
+
return {
|
|
184
|
+
text: `Change requires approval.\n\n${diff}\n\nReply "yes" to apply.`
|
|
185
|
+
};
|
|
186
|
+
} else {
|
|
187
|
+
// Apply immediately
|
|
188
|
+
writeFileSync(path, content);
|
|
189
|
+
return { text: `Wrote ${path}` };
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
tool("apply_pending", async () => {
|
|
194
|
+
for (const [path, content] of pendingChanges) {
|
|
195
|
+
writeFileSync(path, content);
|
|
196
|
+
}
|
|
197
|
+
pendingChanges.clear();
|
|
198
|
+
return { text: "Applied all pending changes" };
|
|
199
|
+
});
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**What requires approval:**
|
|
203
|
+
- src/*.ts (agent code)
|
|
204
|
+
- package.json (dependencies)
|
|
205
|
+
- system prompt changes
|
|
206
|
+
|
|
207
|
+
**What doesn't:**
|
|
208
|
+
- data/* (instance data)
|
|
209
|
+
- site/* (generated content)
|
|
210
|
+
- docs/* (documentation)
|
|
211
|
+
</pattern>
|
|
212
|
+
|
|
213
|
+
<pattern name="unified-agent-architecture">
|
|
214
|
+
## Unified Agent Architecture
|
|
215
|
+
|
|
216
|
+
One execution engine, many agent types. All agents use the same orchestrator but with different configurations.
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
220
|
+
│ AgentOrchestrator │
|
|
221
|
+
├─────────────────────────────────────────────────────────────┤
|
|
222
|
+
│ - Lifecycle management (start, pause, resume, stop) │
|
|
223
|
+
│ - Checkpoint/restore (for background execution) │
|
|
224
|
+
│ - Tool execution │
|
|
225
|
+
│ - Chat integration │
|
|
226
|
+
└─────────────────────────────────────────────────────────────┘
|
|
227
|
+
│ │ │
|
|
228
|
+
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
|
|
229
|
+
│ Research │ │ Chat │ │ Profile │
|
|
230
|
+
│ Agent │ │ Agent │ │ Agent │
|
|
231
|
+
└───────────┘ └───────────┘ └───────────┘
|
|
232
|
+
- web_search - read_library - read_photos
|
|
233
|
+
- write_file - publish_to_feed - write_file
|
|
234
|
+
- read_file - web_search - analyze_image
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Implementation:**
|
|
238
|
+
|
|
239
|
+
```swift
|
|
240
|
+
// All agents use the same orchestrator
|
|
241
|
+
let session = try await AgentOrchestrator.shared.startAgent(
|
|
242
|
+
config: ResearchAgent.create(book: book), // Config varies
|
|
243
|
+
tools: ResearchAgent.tools, // Tools vary
|
|
244
|
+
context: ResearchAgent.context(for: book) // Context varies
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
// Agent types define their own configuration
|
|
248
|
+
struct ResearchAgent {
|
|
249
|
+
static var tools: [AgentTool] {
|
|
250
|
+
[
|
|
251
|
+
FileTools.readFile(),
|
|
252
|
+
FileTools.writeFile(),
|
|
253
|
+
WebTools.webSearch(),
|
|
254
|
+
WebTools.webFetch(),
|
|
255
|
+
]
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
static func context(for book: Book) -> String {
|
|
259
|
+
"""
|
|
260
|
+
You are researching "\(book.title)" by \(book.author).
|
|
261
|
+
Save findings to Documents/Research/\(book.id)/
|
|
262
|
+
"""
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
struct ChatAgent {
|
|
267
|
+
static var tools: [AgentTool] {
|
|
268
|
+
[
|
|
269
|
+
FileTools.readFile(),
|
|
270
|
+
FileTools.writeFile(),
|
|
271
|
+
BookTools.readLibrary(),
|
|
272
|
+
BookTools.publishToFeed(), // Chat can publish directly
|
|
273
|
+
WebTools.webSearch(),
|
|
274
|
+
]
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
static func context(library: [Book]) -> String {
|
|
278
|
+
"""
|
|
279
|
+
You help the user with their reading.
|
|
280
|
+
Available books: \(library.map { $0.title }.joined(separator: ", "))
|
|
281
|
+
"""
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Benefits:**
|
|
287
|
+
- Consistent lifecycle management across all agent types
|
|
288
|
+
- Automatic checkpoint/resume (critical for mobile)
|
|
289
|
+
- Shared tool protocol
|
|
290
|
+
- Easy to add new agent types
|
|
291
|
+
- Centralized error handling and logging
|
|
292
|
+
</pattern>
|
|
293
|
+
|
|
294
|
+
<pattern name="agent-to-ui-communication">
|
|
295
|
+
## Agent-to-UI Communication
|
|
296
|
+
|
|
297
|
+
When agents take actions, the UI should reflect them immediately. The user should see what the agent did.
|
|
298
|
+
|
|
299
|
+
**Pattern 1: Shared Data Store (Recommended)**
|
|
300
|
+
|
|
301
|
+
Agent writes through the same service the UI observes:
|
|
302
|
+
|
|
303
|
+
```swift
|
|
304
|
+
// Shared service
|
|
305
|
+
class BookLibraryService: ObservableObject {
|
|
306
|
+
static let shared = BookLibraryService()
|
|
307
|
+
@Published var books: [Book] = []
|
|
308
|
+
@Published var feedItems: [FeedItem] = []
|
|
309
|
+
|
|
310
|
+
func addFeedItem(_ item: FeedItem) {
|
|
311
|
+
feedItems.append(item)
|
|
312
|
+
persist()
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Agent tool writes through shared service
|
|
317
|
+
tool("publish_to_feed", async ({ bookId, content, headline }) => {
|
|
318
|
+
let item = FeedItem(bookId: bookId, content: content, headline: headline)
|
|
319
|
+
BookLibraryService.shared.addFeedItem(item) // Same service UI uses
|
|
320
|
+
return { text: "Published to feed" }
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
// UI observes the same service
|
|
324
|
+
struct FeedView: View {
|
|
325
|
+
@StateObject var library = BookLibraryService.shared
|
|
326
|
+
|
|
327
|
+
var body: some View {
|
|
328
|
+
List(library.feedItems) { item in
|
|
329
|
+
FeedItemRow(item: item)
|
|
330
|
+
// Automatically updates when agent adds items
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**Pattern 2: File System Observation**
|
|
337
|
+
|
|
338
|
+
For file-based data, watch the file system:
|
|
339
|
+
|
|
340
|
+
```swift
|
|
341
|
+
class ResearchWatcher: ObservableObject {
|
|
342
|
+
@Published var files: [URL] = []
|
|
343
|
+
private var watcher: DirectoryWatcher?
|
|
344
|
+
|
|
345
|
+
func watch(bookId: String) {
|
|
346
|
+
let path = documentsURL.appendingPathComponent("Research/\(bookId)")
|
|
347
|
+
|
|
348
|
+
watcher = DirectoryWatcher(path: path) { [weak self] in
|
|
349
|
+
self?.reload(from: path)
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
reload(from: path)
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Agent writes files
|
|
357
|
+
tool("write_file", { path, content }) -> {
|
|
358
|
+
writeFile(documentsURL.appendingPathComponent(path), content)
|
|
359
|
+
// DirectoryWatcher triggers UI update automatically
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
**Pattern 3: Event Bus (Cross-Component)**
|
|
364
|
+
|
|
365
|
+
For complex apps with multiple independent components:
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
// Shared event bus
|
|
369
|
+
const agentEvents = new EventEmitter();
|
|
370
|
+
|
|
371
|
+
// Agent tool emits events
|
|
372
|
+
tool("publish_to_feed", async ({ content }) => {
|
|
373
|
+
const item = await feedService.add(content);
|
|
374
|
+
agentEvents.emit('feed:new-item', item);
|
|
375
|
+
return { text: "Published" };
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// UI components subscribe
|
|
379
|
+
function FeedView() {
|
|
380
|
+
const [items, setItems] = useState([]);
|
|
381
|
+
|
|
382
|
+
useEffect(() => {
|
|
383
|
+
const handler = (item) => setItems(prev => [...prev, item]);
|
|
384
|
+
agentEvents.on('feed:new-item', handler);
|
|
385
|
+
return () => agentEvents.off('feed:new-item', handler);
|
|
386
|
+
}, []);
|
|
387
|
+
|
|
388
|
+
return <FeedList items={items} />;
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
**What to avoid:**
|
|
393
|
+
|
|
394
|
+
```swift
|
|
395
|
+
// BAD: UI doesn't observe agent changes
|
|
396
|
+
// Agent writes to database directly
|
|
397
|
+
tool("publish_to_feed", { content }) {
|
|
398
|
+
database.insert("feed", content) // UI doesn't see this
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// UI loads once at startup, never refreshes
|
|
402
|
+
struct FeedView: View {
|
|
403
|
+
let items = database.query("feed") // Stale!
|
|
404
|
+
}
|
|
405
|
+
```
|
|
406
|
+
</pattern>
|
|
407
|
+
|
|
408
|
+
<pattern name="model-tier-selection">
|
|
409
|
+
## Model Tier Selection
|
|
410
|
+
|
|
411
|
+
Different agents need different intelligence levels. Use the cheapest model that achieves the outcome.
|
|
412
|
+
|
|
413
|
+
| Agent Type | Recommended Tier | Reasoning |
|
|
414
|
+
|------------|-----------------|-----------|
|
|
415
|
+
| Chat/Conversation | Balanced | Fast responses, good reasoning |
|
|
416
|
+
| Research | Balanced | Tool loops, not ultra-complex synthesis |
|
|
417
|
+
| Content Generation | Balanced | Creative but not synthesis-heavy |
|
|
418
|
+
| Complex Analysis | Powerful | Multi-document synthesis, nuanced judgment |
|
|
419
|
+
| Profile/Onboarding | Powerful | Photo analysis, complex pattern recognition |
|
|
420
|
+
| Simple Queries | Fast/Haiku | Quick lookups, simple transformations |
|
|
421
|
+
|
|
422
|
+
**Implementation:**
|
|
423
|
+
|
|
424
|
+
```swift
|
|
425
|
+
enum ModelTier {
|
|
426
|
+
case fast // gemini-flash: Quick, cheap, simple tasks
|
|
427
|
+
case balanced // gemini-pro: Good balance for most tasks
|
|
428
|
+
case powerful // gemini-ultra: Complex reasoning, synthesis
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
struct AgentConfig {
|
|
432
|
+
let modelTier: ModelTier
|
|
433
|
+
let tools: [AgentTool]
|
|
434
|
+
let systemPrompt: String
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Research agent: balanced tier
|
|
438
|
+
let researchConfig = AgentConfig(
|
|
439
|
+
modelTier: .balanced,
|
|
440
|
+
tools: researchTools,
|
|
441
|
+
systemPrompt: researchPrompt
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
// Profile analysis: powerful tier (complex photo interpretation)
|
|
445
|
+
let profileConfig = AgentConfig(
|
|
446
|
+
modelTier: .powerful,
|
|
447
|
+
tools: profileTools,
|
|
448
|
+
systemPrompt: profilePrompt
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
// Quick lookup: fast tier
|
|
452
|
+
let lookupConfig = AgentConfig(
|
|
453
|
+
modelTier: .fast,
|
|
454
|
+
tools: [readLibrary],
|
|
455
|
+
systemPrompt: "Answer quick questions about the user's library."
|
|
456
|
+
)
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
**Cost optimization strategies:**
|
|
460
|
+
- Start with balanced tier, only upgrade if quality insufficient
|
|
461
|
+
- Use fast tier for tool-heavy loops where each turn is simple
|
|
462
|
+
- Reserve powerful tier for synthesis tasks (comparing multiple sources)
|
|
463
|
+
- Consider token limits per turn to control costs
|
|
464
|
+
</pattern>
|
|
465
|
+
|
|
466
|
+
<design_questions>
|
|
467
|
+
## Questions to Ask When Designing
|
|
468
|
+
|
|
469
|
+
1. **What events trigger agent turns?** (messages, webhooks, timers, user requests)
|
|
470
|
+
2. **What primitives does the agent need?** (read, write, call API, restart)
|
|
471
|
+
3. **What decisions should the agent make?** (format, structure, priority, action)
|
|
472
|
+
4. **What decisions should be hardcoded?** (security boundaries, approval requirements)
|
|
473
|
+
5. **How does the agent verify its work?** (health checks, build verification)
|
|
474
|
+
6. **How does the agent recover from mistakes?** (git rollback, approval gates)
|
|
475
|
+
7. **How does the UI know when agent changes state?** (shared store, file watching, events)
|
|
476
|
+
8. **What model tier does each agent type need?** (fast, balanced, powerful)
|
|
477
|
+
9. **How do agents share infrastructure?** (unified orchestrator, shared tools)
|
|
478
|
+
</design_questions>
|