@hera-al/server 1.6.12 → 1.6.13
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/bundled/a2ui/SKILL.md +339 -0
- package/bundled/buongiorno/SKILL.md +151 -0
- package/bundled/council/SKILL.md +168 -0
- package/bundled/council/scripts/council.mjs +202 -0
- package/bundled/dreaming/SKILL.md +177 -0
- package/bundled/google-workspace/SKILL.md +229 -0
- package/bundled/google-workspace/scripts/auth.sh +87 -0
- package/bundled/google-workspace/scripts/calendar.sh +508 -0
- package/bundled/google-workspace/scripts/drive.sh +459 -0
- package/bundled/google-workspace/scripts/gmail.sh +452 -0
- package/bundled/humanizer/SKILL.md +488 -0
- package/bundled/librarian/SKILL.md +155 -0
- package/bundled/plasma/SKILL.md +1417 -0
- package/bundled/sera/SKILL.md +143 -0
- package/bundled/the-skill-guardian/SKILL.md +103 -0
- package/bundled/the-skill-guardian/scripts/scan.sh +314 -0
- package/bundled/unix-time/SKILL.md +58 -0
- package/bundled/wandering/SKILL.md +174 -0
- package/bundled/xai-search/SKILL.md +91 -0
- package/bundled/xai-search/scripts/search.sh +197 -0
- package/dist/a2ui/parser.d.ts +76 -0
- package/dist/a2ui/parser.js +1 -0
- package/dist/a2ui/types.d.ts +147 -0
- package/dist/a2ui/types.js +1 -0
- package/dist/a2ui/validator.d.ts +32 -0
- package/dist/a2ui/validator.js +1 -0
- package/dist/agent/agent-service.d.ts +17 -11
- package/dist/agent/agent-service.js +1 -1
- package/dist/agent/session-agent.d.ts +1 -1
- package/dist/agent/session-agent.js +1 -1
- package/dist/agent/session-error-handler.js +1 -1
- package/dist/commands/debuga2ui.d.ts +13 -0
- package/dist/commands/debuga2ui.js +1 -0
- package/dist/commands/debugdynamic.d.ts +13 -0
- package/dist/commands/debugdynamic.js +1 -0
- package/dist/commands/mcp.d.ts +6 -3
- package/dist/commands/mcp.js +1 -1
- package/dist/gateway/node-registry.d.ts +29 -1
- package/dist/gateway/node-registry.js +1 -1
- package/dist/installer/hera.js +1 -1
- package/dist/memory/concept-store.d.ts +109 -0
- package/dist/memory/concept-store.js +1 -0
- package/dist/nostromo/nostromo.js +1 -1
- package/dist/server.d.ts +3 -2
- package/dist/server.js +1 -1
- package/dist/tools/a2ui-tools.d.ts +23 -0
- package/dist/tools/a2ui-tools.js +1 -0
- package/dist/tools/concept-tools.d.ts +3 -0
- package/dist/tools/concept-tools.js +1 -0
- package/dist/tools/dynamic-ui-tools.d.ts +25 -0
- package/dist/tools/dynamic-ui-tools.js +1 -0
- package/dist/tools/node-tools.js +1 -1
- package/dist/tools/plasma-client-tools.d.ts +28 -0
- package/dist/tools/plasma-client-tools.js +1 -0
- package/installationPkg/AGENTS.md +168 -22
- package/installationPkg/SOUL.md +56 -0
- package/installationPkg/TOOLS.md +126 -0
- package/installationPkg/USER.md +54 -1
- package/installationPkg/config.example.yaml +145 -34
- package/installationPkg/default-jobs.json +77 -0
- package/package.json +3 -2
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: a2ui
|
|
3
|
+
description: Generate rich interactive user interfaces (forms, dashboards, cards) on connected nodes with A2UI rendering capability
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# A2UI Skill
|
|
8
|
+
|
|
9
|
+
Use this skill when the user requests interactive UI elements that are better served as native visual components rather than text-based responses.
|
|
10
|
+
|
|
11
|
+
## When to Use A2UI
|
|
12
|
+
|
|
13
|
+
**✅ Use A2UI for:**
|
|
14
|
+
- **Forms** — booking, registration, multi-field input, surveys
|
|
15
|
+
- **Dashboards** — KPIs, metrics, status cards, progress tracking
|
|
16
|
+
- **Interactive lists** — email inbox, file browser with action buttons
|
|
17
|
+
- **Configuration panels** — toggles, sliders, dropdowns, color pickers
|
|
18
|
+
- **Approval workflows** — cards with approve/reject/delegate buttons
|
|
19
|
+
- **Data visualization** — cards with structured data, image galleries
|
|
20
|
+
- **Rich media** — audio/video players with controls
|
|
21
|
+
- **Multi-step wizards** — onboarding, setup flows
|
|
22
|
+
|
|
23
|
+
**❌ Do NOT use A2UI for:**
|
|
24
|
+
- Simple Q&A conversations (use text)
|
|
25
|
+
- Single yes/no questions (use text)
|
|
26
|
+
- File downloads or uploads (use MEDIA:)
|
|
27
|
+
- Purely informational messages (use text)
|
|
28
|
+
- Error messages (use text)
|
|
29
|
+
|
|
30
|
+
## Workflow
|
|
31
|
+
|
|
32
|
+
### 1. Check A2UI-Capable Nodes
|
|
33
|
+
|
|
34
|
+
Always start by checking which nodes support A2UI:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
a2ui_list_nodes()
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
If no nodes are available, inform the user:
|
|
41
|
+
> "To use interactive forms, please connect ElectrNode or OSXNode."
|
|
42
|
+
|
|
43
|
+
If multiple nodes are available, ask the user which one to use.
|
|
44
|
+
|
|
45
|
+
### 2. Design the Surface
|
|
46
|
+
|
|
47
|
+
Think about the user's need and design an appropriate A2UI surface:
|
|
48
|
+
|
|
49
|
+
- **Forms:** Use TextField, DateTimeInput, CheckBox, Slider, MultipleChoice + Button
|
|
50
|
+
- **Dashboards:** Use Card, Text (h1/h2), Column/Row layout
|
|
51
|
+
- **Lists:** Use List component or Column of Cards
|
|
52
|
+
- **Actions:** Always include Button components with clear labels
|
|
53
|
+
|
|
54
|
+
### 3. Generate JSONL
|
|
55
|
+
|
|
56
|
+
Create A2UI v0.8 JSONL (one JSON object per line):
|
|
57
|
+
|
|
58
|
+
**Required messages:**
|
|
59
|
+
1. `surfaceUpdate` — defines all components
|
|
60
|
+
2. `dataModelUpdate` (optional) — sets initial data values
|
|
61
|
+
3. `beginRendering` — makes the surface visible (REQUIRED!)
|
|
62
|
+
|
|
63
|
+
### 4. Render Surface
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
a2ui_render(nodeId, jsonl)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Or omit `nodeId` to use the first available node.
|
|
70
|
+
|
|
71
|
+
**Automatic validation:** The tool automatically validates your JSONL against the official Google A2UI v0.8 JSON Schema before rendering.
|
|
72
|
+
|
|
73
|
+
**If validation fails:**
|
|
74
|
+
- You'll receive detailed error messages
|
|
75
|
+
- Read the errors carefully
|
|
76
|
+
- Fix your JSONL
|
|
77
|
+
- Call `a2ui_render()` again with the corrected JSONL
|
|
78
|
+
- The tool will validate again automatically
|
|
79
|
+
|
|
80
|
+
**Common validation errors:**
|
|
81
|
+
- Button missing `child` property
|
|
82
|
+
- TextField using `dataRef` instead of `text.path`
|
|
83
|
+
- Action missing `event` wrapper
|
|
84
|
+
- Paths not starting with `/`
|
|
85
|
+
|
|
86
|
+
**Optional: Pre-validate manually**
|
|
87
|
+
If you want to validate before rendering (e.g., to catch errors early), you can call:
|
|
88
|
+
```
|
|
89
|
+
a2ui_validate(jsonl)
|
|
90
|
+
```
|
|
91
|
+
But this is optional — `a2ui_render` will validate automatically.
|
|
92
|
+
|
|
93
|
+
### 5. Handle User Actions
|
|
94
|
+
|
|
95
|
+
When the user interacts with the UI (clicks button, submits form), you'll receive a message like:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
[A2UI Action] submit_booking on surface booking (component: submit) {"guests":"2","date":"2026-02-20"}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Parse the action name and context, then respond appropriately:
|
|
102
|
+
- Update the surface with `a2ui_update()`
|
|
103
|
+
- Send text confirmation
|
|
104
|
+
- Clear the surface with `a2ui_reset()`
|
|
105
|
+
|
|
106
|
+
## A2UI v0.8 JSONL Format
|
|
107
|
+
|
|
108
|
+
### Message Types
|
|
109
|
+
|
|
110
|
+
**surfaceUpdate** — Define/update components:
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"surfaceUpdate": {
|
|
114
|
+
"surfaceId": "booking",
|
|
115
|
+
"components": [
|
|
116
|
+
{"id": "root", "component": {"Column": {"children": {"explicitList": ["title", "form"]}}}},
|
|
117
|
+
{"id": "title", "component": {"Text": {"text": {"literalString": "Book a Table"}, "usageHint": "h2"}}}
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**dataModelUpdate** — Set data model values:
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"dataModelUpdate": {
|
|
127
|
+
"surfaceId": "booking",
|
|
128
|
+
"path": "/",
|
|
129
|
+
"value": {"guests": "2", "date": "2026-02-20"}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**beginRendering** — Display the surface (REQUIRED):
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"beginRendering": {
|
|
138
|
+
"surfaceId": "booking",
|
|
139
|
+
"root": "root"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**deleteSurface** — Remove a surface:
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"deleteSurface": {
|
|
148
|
+
"surfaceId": "booking"
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Component Types (PascalCase)
|
|
154
|
+
|
|
155
|
+
**Layout:**
|
|
156
|
+
- `Column` — vertical stack (use `children.explicitList`)
|
|
157
|
+
- `Row` — horizontal row (use `children.explicitList`)
|
|
158
|
+
- `Card` — elevated container (use `child` for single child)
|
|
159
|
+
- `Divider` — horizontal line (no props needed)
|
|
160
|
+
- `Tabs` — tabbed interface
|
|
161
|
+
- `Modal` — overlay dialog
|
|
162
|
+
- `List` — scrollable list
|
|
163
|
+
|
|
164
|
+
**Content:**
|
|
165
|
+
- `Text` — text with usageHint: "h1", "h2", "h3", "h4", "h5", "body", "caption"
|
|
166
|
+
- `Image` — display image (use `url.literalString`)
|
|
167
|
+
- `Icon` — icon display
|
|
168
|
+
- `AudioPlayer` — audio playback
|
|
169
|
+
- `Video` — video playback
|
|
170
|
+
|
|
171
|
+
**Input:**
|
|
172
|
+
- `Button` — clickable button **CRITICAL: Button has NO label property. Use `child` to reference a Text component ID, and `action.event` for the action**
|
|
173
|
+
- `TextField` — text input **CRITICAL: Use `text.path` (NOT `dataRef`) for data binding with JSON Pointer path like "/fieldname"**
|
|
174
|
+
- `CheckBox` — checkbox input
|
|
175
|
+
- `MultipleChoice` — radio buttons or dropdown
|
|
176
|
+
- `Slider` — numeric slider
|
|
177
|
+
- `DateTimeInput` — date/time picker
|
|
178
|
+
|
|
179
|
+
### COMMON MISTAKES TO AVOID
|
|
180
|
+
|
|
181
|
+
**❌ WRONG: Button with label property**
|
|
182
|
+
```json
|
|
183
|
+
{"Button": {"label": {"literalString": "Submit"}, "action": {"name": "submit"}}}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**✅ CORRECT: Button with child Text component**
|
|
187
|
+
```json
|
|
188
|
+
{"id": "btn", "component": {"Button": {"child": "btn_text", "action": {"event": {"name": "submit"}}}}},
|
|
189
|
+
{"id": "btn_text", "component": {"Text": {"text": {"literalString": "Submit"}}}}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**❌ WRONG: TextField with dataRef**
|
|
193
|
+
```json
|
|
194
|
+
{"TextField": {"label": {"literalString": "Name"}, "dataRef": "name"}}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**✅ CORRECT: TextField with text.path**
|
|
198
|
+
```json
|
|
199
|
+
{"TextField": {"label": {"literalString": "Name"}, "text": {"path": "/name"}}}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**❌ WRONG: Action without event wrapper**
|
|
203
|
+
```json
|
|
204
|
+
{"Button": {"child": "text", "action": {"name": "submit"}}}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**✅ CORRECT: Action with event wrapper**
|
|
208
|
+
```json
|
|
209
|
+
{"Button": {"child": "text", "action": {"event": {"name": "submit", "context": [...]}}}}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Data Binding
|
|
213
|
+
|
|
214
|
+
Use JSON Pointer paths for two-way binding:
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
{"id": "name_field", "component": {
|
|
218
|
+
"TextField": {
|
|
219
|
+
"label": {"literalString": "Your Name"},
|
|
220
|
+
"text": {"path": "/name"}
|
|
221
|
+
}
|
|
222
|
+
}}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Then set initial value:
|
|
226
|
+
```json
|
|
227
|
+
{"dataModelUpdate": {"surfaceId": "main", "path": "/name", "value": "John"}}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Actions
|
|
231
|
+
|
|
232
|
+
Buttons emit actions with context. The Button component structure is:
|
|
233
|
+
|
|
234
|
+
```json
|
|
235
|
+
{
|
|
236
|
+
"id": "submit_btn",
|
|
237
|
+
"component": {
|
|
238
|
+
"Button": {
|
|
239
|
+
"child": "submit_text",
|
|
240
|
+
"action": {
|
|
241
|
+
"event": {
|
|
242
|
+
"name": "submit_form",
|
|
243
|
+
"context": [
|
|
244
|
+
{"key": "name", "value": {"path": "/name"}},
|
|
245
|
+
{"key": "email", "value": {"path": "/email"}}
|
|
246
|
+
]
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
And you MUST also define the child Text component:
|
|
255
|
+
|
|
256
|
+
```json
|
|
257
|
+
{
|
|
258
|
+
"id": "submit_text",
|
|
259
|
+
"component": {
|
|
260
|
+
"Text": {
|
|
261
|
+
"text": {"literalString": "Submit"}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
When clicked, you receive:
|
|
268
|
+
```
|
|
269
|
+
[A2UI Action] submit_form on surface main (component: submit_btn) {"name":"John","email":"john@example.com"}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Complete Example: Booking Form
|
|
273
|
+
|
|
274
|
+
```jsonl
|
|
275
|
+
{"surfaceUpdate":{"surfaceId":"booking","components":[{"id":"root","component":{"Column":{"children":{"explicitList":["title","guests","date","time","submit"]}}}},{"id":"title","component":{"Text":{"text":{"literalString":"Restaurant Booking"},"usageHint":"h2"}}},{"id":"guests","component":{"TextField":{"label":{"literalString":"Number of Guests"},"text":{"path":"/guests"},"placeholder":{"literalString":"e.g. 2"}}}},{"id":"date","component":{"DateTimeInput":{"label":{"literalString":"Date"},"value":{"path":"/date"}}}},{"id":"time","component":{"MultipleChoice":{"label":{"literalString":"Preferred Time"},"options":{"explicitList":[{"id":"t1","label":{"literalString":"18:00"},"value":{"literalString":"18:00"}},{"id":"t2","label":{"literalString":"19:00"},"value":{"literalString":"19:00"}},{"id":"t3","label":{"literalString":"20:00"},"value":{"literalString":"20:00"}}]},"selection":{"path":"/time"}}}},{"id":"submit","component":{"Button":{"child":"submit_text","action":{"event":{"name":"submit_booking","context":[{"key":"guests","value":{"path":"/guests"}},{"key":"date","value":{"path":"/date"}},{"key":"time","value":{"path":"/time"}}]}}}}},{"id":"submit_text","component":{"Text":{"text":{"literalString":"Confirm Booking"}}}}]}}
|
|
276
|
+
{"dataModelUpdate":{"surfaceId":"booking","path":"/","value":{"guests":"2","date":"2026-02-20","time":"19:00"}}}
|
|
277
|
+
{"beginRendering":{"surfaceId":"booking","root":"root"}}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Tools Reference
|
|
281
|
+
|
|
282
|
+
**a2ui_list_nodes()** — List A2UI-capable nodes
|
|
283
|
+
|
|
284
|
+
**a2ui_render(nodeId?, jsonl)** — Render surface with automatic validation
|
|
285
|
+
- `nodeId` (optional): Target node ID
|
|
286
|
+
- `jsonl` (required): A2UI v0.8 JSONL string
|
|
287
|
+
- **Validates automatically** against official Google schema
|
|
288
|
+
- Returns detailed errors if invalid, success message if valid
|
|
289
|
+
|
|
290
|
+
**a2ui_update(nodeId?, jsonl)** — Update existing surface with automatic validation
|
|
291
|
+
- `jsonl` (required): A2UI v0.8 JSONL string
|
|
292
|
+
- **Validates automatically** against official Google schema
|
|
293
|
+
- Use for progressive updates (no `beginRendering` needed)
|
|
294
|
+
|
|
295
|
+
**a2ui_validate(jsonl)** — Optional: Pre-validate JSONL
|
|
296
|
+
- `jsonl` (required): A2UI v0.8 JSONL to validate
|
|
297
|
+
- Returns: Validation result with detailed errors if invalid
|
|
298
|
+
- Use this if you want to validate before rendering (optional, since render/update validate automatically)
|
|
299
|
+
|
|
300
|
+
**a2ui_reset(nodeId?, surfaceId?)** — Clear surface
|
|
301
|
+
- `surfaceId` (optional): Surface to delete (default: "main")
|
|
302
|
+
- Use "all" to clear all surfaces
|
|
303
|
+
|
|
304
|
+
**a2ui_text(nodeId?, text, surfaceId?)** — Quick text surface
|
|
305
|
+
- Simple helper for displaying text in a surface
|
|
306
|
+
|
|
307
|
+
## Best Practices
|
|
308
|
+
|
|
309
|
+
1. **Read validation errors carefully** — When `a2ui_render` fails, read the error messages and fix the exact issues mentioned
|
|
310
|
+
2. **Fix and retry iteratively** — Correct your JSONL based on errors, then call `a2ui_render` again
|
|
311
|
+
3. **Always include beginRendering** — Without it, the surface won't be visible
|
|
312
|
+
4. **Use descriptive component IDs** — Makes debugging easier
|
|
313
|
+
5. **Validate data** — Use TextField placeholder/hints to guide user input
|
|
314
|
+
6. **Provide feedback** — After user action, update the surface or send confirmation text
|
|
315
|
+
7. **Use Cards for grouping** — Makes complex UIs more readable
|
|
316
|
+
8. **Keep it simple** — Don't over-engineer. Forms with 3-5 fields work best.
|
|
317
|
+
9. **Test incrementally** — Start with a simple surface, then add complexity
|
|
318
|
+
10. **Optional pre-validation** — Use `a2ui_validate()` to check your JSONL early if you want faster feedback
|
|
319
|
+
|
|
320
|
+
## Troubleshooting
|
|
321
|
+
|
|
322
|
+
**Surface doesn't appear:**
|
|
323
|
+
- Check if `beginRendering` message is included
|
|
324
|
+
- Verify `surfaceId` matches across all messages
|
|
325
|
+
- Confirm node is A2UI-capable with `a2ui_list_nodes()`
|
|
326
|
+
|
|
327
|
+
**User action not received:**
|
|
328
|
+
- Ensure Button has `action.event.name`
|
|
329
|
+
- Check `context` paths are correct (e.g., "/guests" not "guests")
|
|
330
|
+
- Verify data model was initialized with `dataModelUpdate`
|
|
331
|
+
|
|
332
|
+
**Rendering errors:**
|
|
333
|
+
- Validate JSONL syntax (one JSON object per line)
|
|
334
|
+
- Check component type names (PascalCase: "TextField", not "textField")
|
|
335
|
+
- Ensure all referenced IDs exist in `components` array
|
|
336
|
+
|
|
337
|
+
## Remember
|
|
338
|
+
|
|
339
|
+
A2UI is for **structured, interactive experiences**. For simple conversations, stick to text. When in doubt, ask yourself: "Would a native UI make this significantly better than text?" If yes, use A2UI. If no, use text.
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: buongiorno
|
|
3
|
+
description: "Morning standup: delivery report from overnight work, service health, weather, calendar, priorities for the day. Daily at 07:00."
|
|
4
|
+
user-invocable: false
|
|
5
|
+
priority: 2
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Buongiorno — Morning Standup
|
|
9
|
+
|
|
10
|
+
Cron giornaliero alle 07:00. Sessione isolata. This is NOT just a weather report — it's a **standup meeting** between you and the user.
|
|
11
|
+
|
|
12
|
+
## Philosophy
|
|
13
|
+
|
|
14
|
+
Like Andi's OpenClaw: "The next morning, I get a message. My agent telling me what it did, what it's stuck on, and what it needs from me."
|
|
15
|
+
|
|
16
|
+
## Flusso
|
|
17
|
+
|
|
18
|
+
### 1. Overnight Delivery Report
|
|
19
|
+
|
|
20
|
+
**This is the MOST IMPORTANT section.** Check what happened while the user slept:
|
|
21
|
+
|
|
22
|
+
1. Read `HEARTBEAT.md` — any completed tasks?
|
|
23
|
+
2. Read `workspace/agent-thoughts/` — any overnight wandering results?
|
|
24
|
+
3. Read the latest dream journal in `memory/dreams/` — anything insightful?
|
|
25
|
+
4. Check `memory/YYYY-MM-DD.md` (yesterday) — any pending tasks from yesterday's conversations?
|
|
26
|
+
5. Check any work-in-progress files in workspace
|
|
27
|
+
|
|
28
|
+
**Report format:**
|
|
29
|
+
- Completed: [what you delivered overnight]
|
|
30
|
+
- In progress: [what you're working on]
|
|
31
|
+
- Blocked: [what you need from the user]
|
|
32
|
+
- Discovered: [side-findings worth mentioning]
|
|
33
|
+
|
|
34
|
+
If nothing happened overnight, say so honestly: "Quiet night, nothing pending."
|
|
35
|
+
|
|
36
|
+
### 2. Service Health
|
|
37
|
+
|
|
38
|
+
Quick health check — don't belabor this, just flags:
|
|
39
|
+
|
|
40
|
+
**Gmail**: Use the `google-workspace` skill (gmail.sh) to check:
|
|
41
|
+
```
|
|
42
|
+
gmail.sh search "newer_than:1d" --max 3
|
|
43
|
+
```
|
|
44
|
+
- If it works: OK (silent)
|
|
45
|
+
- If error: Gmail KO — HIGHLIGHT
|
|
46
|
+
|
|
47
|
+
**Drive**: List recent files:
|
|
48
|
+
```
|
|
49
|
+
drive.sh list --max 3
|
|
50
|
+
```
|
|
51
|
+
- If it works: OK (silent)
|
|
52
|
+
- If error: Drive KO — HIGHLIGHT
|
|
53
|
+
|
|
54
|
+
**IMPORTANT**: Google scripts run LOCALLY (on the server), NOT on the connected Mac node.
|
|
55
|
+
|
|
56
|
+
Path: `workspace/.claude/skills/google-workspace/scripts/`
|
|
57
|
+
|
|
58
|
+
**Mac Node**: Check if connected (list_nodes). If offline, report it.
|
|
59
|
+
|
|
60
|
+
**Rule: Only mention services if they're broken.** "Services OK" in one line if everything works. Don't list every green service.
|
|
61
|
+
|
|
62
|
+
### 3. Agenda
|
|
63
|
+
|
|
64
|
+
Check **all** these sources:
|
|
65
|
+
|
|
66
|
+
1. **Google Calendar** — today's and tomorrow morning's events
|
|
67
|
+
2. **Apple Reminders** — reminders due today (via Mac node if available)
|
|
68
|
+
3. **MEMORY.md** — Open TODOs section, mentioned deadlines
|
|
69
|
+
4. **Yesterday's conversations** — did the user mention commitments?
|
|
70
|
+
|
|
71
|
+
**Prioritize**: put time-sensitive items first (meetings, deadlines), then generic tasks.
|
|
72
|
+
|
|
73
|
+
### 4. Weather
|
|
74
|
+
|
|
75
|
+
Use the `weather` skill:
|
|
76
|
+
- **The user's city** — temperature, conditions, day trend
|
|
77
|
+
|
|
78
|
+
**Condensed**: "City 8C -> 12C, cloudy." One line.
|
|
79
|
+
|
|
80
|
+
### 5. Today's Priorities
|
|
81
|
+
|
|
82
|
+
Based on everything above, suggest 2-3 priorities for the day:
|
|
83
|
+
- What's most important/urgent?
|
|
84
|
+
- What can the assistant handle autonomously?
|
|
85
|
+
- What needs the user's input?
|
|
86
|
+
|
|
87
|
+
### 6. Send Message
|
|
88
|
+
|
|
89
|
+
**Channel**: `{{CHANNEL}}`
|
|
90
|
+
**ChatId**: `{{CHAT_ID}}`
|
|
91
|
+
|
|
92
|
+
**Format** (example):
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
Good morning!
|
|
96
|
+
|
|
97
|
+
Overnight: completed the research on X and prepared the draft in workspace/. The bazaar-intel needs your review on DB schema.
|
|
98
|
+
|
|
99
|
+
Services OK
|
|
100
|
+
|
|
101
|
+
Today:
|
|
102
|
+
- 10:00 Call with Y (Calendar)
|
|
103
|
+
- Deadline Z (from MEMORY.md)
|
|
104
|
+
|
|
105
|
+
Weather: City 8->12C, cloudy
|
|
106
|
+
|
|
107
|
+
Priorities:
|
|
108
|
+
1. Review bazaar-intel DB schema (needs your input)
|
|
109
|
+
2. Finalize PR (I can do this)
|
|
110
|
+
3. Reply to email from X (do you need this?)
|
|
111
|
+
|
|
112
|
+
Have a good day!
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Message rules**:
|
|
116
|
+
- **Delivery report FIRST** — it's the most important section
|
|
117
|
+
- Brief and scannable — the user reads it right after waking up
|
|
118
|
+
- If a service is KO, highlight it
|
|
119
|
+
- Vary the greeting
|
|
120
|
+
- Tone: like a colleague giving you the morning briefing
|
|
121
|
+
- Priorities must be ACTIONABLE, not generic
|
|
122
|
+
|
|
123
|
+
### 7. HEARTBEAT.md Update
|
|
124
|
+
|
|
125
|
+
After sending the message, update `HEARTBEAT.md` with today's task checklist:
|
|
126
|
+
- Carried-over tasks from overnight
|
|
127
|
+
- New tasks from calendar/reminders
|
|
128
|
+
- Self-improvement items if any
|
|
129
|
+
|
|
130
|
+
This becomes the working checklist for today's heartbeats.
|
|
131
|
+
|
|
132
|
+
### 8. Log
|
|
133
|
+
|
|
134
|
+
Append to `workspace/agent-thoughts/buongiorno-log.md`:
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
## YYYY-MM-DD
|
|
138
|
+
- Overnight: [summary of overnight work]
|
|
139
|
+
- Services: OK/issues
|
|
140
|
+
- Calendar: N events
|
|
141
|
+
- Priorities set: [list]
|
|
142
|
+
- Message sent: yes
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Fallback
|
|
146
|
+
|
|
147
|
+
If the Mac node is unreachable:
|
|
148
|
+
- Skip Apple Reminders
|
|
149
|
+
- Report it in the message
|
|
150
|
+
- Everything else works (Google local, weather web, memory local)
|
|
151
|
+
- Send the standup anyway with available info
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: council
|
|
3
|
+
description: "Run a Karpathy-style LLM Council (multi-model parallel answers + peer review + chairman synthesis) using Pico subagents: Gemini Pro, Grok, GPT-5.2, and (if available) Opus."
|
|
4
|
+
user-invocable: true
|
|
5
|
+
priority: 4
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Council — LLM Council via Pico subagents
|
|
9
|
+
|
|
10
|
+
Obiettivo: replicare la logica di **karpathy/llm-council** in modalità “skill”, usando `pico_query` per interrogare più modelli in parallelo, poi fare peer-review/ranking, e infine una sintesi.
|
|
11
|
+
|
|
12
|
+
## Modelli (seats)
|
|
13
|
+
|
|
14
|
+
Questa istanza attualmente espone (vedi `pico_models`):
|
|
15
|
+
- `openrouter/google/gemini-3-pro-preview` ("Gemini Pro")
|
|
16
|
+
- `openrouter/x-ai/grok-4.1-fast` ("Grok")
|
|
17
|
+
- `openrouter/openai/gpt-5.2` ("GPT-5.2")
|
|
18
|
+
|
|
19
|
+
**Opus**:
|
|
20
|
+
- Se in `pico_models` compare un modello tipo `openrouter/anthropic/claude-3-opus` o simile, usalo.
|
|
21
|
+
- Se **non** è disponibile via Pico, il “seat Opus” viene coperto dal **modello corrente** (cioè tu, in questa sessione), generando/recensendo localmente invece che via `pico_query`.
|
|
22
|
+
|
|
23
|
+
> Nota: non inventare ref di modello. Prima fai sempre `pico_models` e scegli da lì.
|
|
24
|
+
|
|
25
|
+
> **IMPORTANTE — Formato nome modello per `pico_query`:**
|
|
26
|
+
> Il parametro `model` di `pico_query` accetta il **nome display** (es. `OpenRouter Grok`), **NON** il ref tecnico (es. `openrouter/x-ai/grok-4.1-fast`). Usare il ref causa errore "Model not found".
|
|
27
|
+
>
|
|
28
|
+
> Mapping attuale (feb 2026):
|
|
29
|
+
> | Nome display | Ref tecnico |
|
|
30
|
+
> |---|---|
|
|
31
|
+
> | `OpenRouter GPT` | `openai/gpt-5.2` |
|
|
32
|
+
> | `OpenRouter Flash` | `google/gemini-3-flash-preview` |
|
|
33
|
+
> | `OpenRouter RollingMem` | `openai/gpt-4.1-mini` |
|
|
34
|
+
> | `OpenRouter Grok` | `x-ai/grok-4.1-fast` |
|
|
35
|
+
> | `OpenRouter GeminiPro` | `google/gemini-3-pro-preview` |
|
|
36
|
+
> | `OpenRouter Opus1m` | `anthropic/claude-opus-4.6` |
|
|
37
|
+
|
|
38
|
+
## Interfaccia d’uso
|
|
39
|
+
|
|
40
|
+
When the user asks:
|
|
41
|
+
- “use council on this question ...”
|
|
42
|
+
- “run a council with gemini/grok/gpt/opus ...”
|
|
43
|
+
|
|
44
|
+
Esegui la pipeline qui sotto.
|
|
45
|
+
|
|
46
|
+
Se l’utente non specifica nulla:
|
|
47
|
+
- **Chairman**: GPT-5.2
|
|
48
|
+
- **Council**: Gemini Pro + Grok + GPT-5.2 + (Opus se disponibile, altrimenti seat locale)
|
|
49
|
+
|
|
50
|
+
## Pipeline (3 stadi)
|
|
51
|
+
|
|
52
|
+
### Stage 0 — Discovery & Setup
|
|
53
|
+
|
|
54
|
+
1) Chiama `pico_models`.
|
|
55
|
+
2) Costruisci la lista `COUNCIL_REFS` in questo ordine (se disponibili):
|
|
56
|
+
- `openrouter/google/gemini-3-pro-preview`
|
|
57
|
+
- `openrouter/x-ai/grok-4.1-fast`
|
|
58
|
+
- `openrouter/openai/gpt-5.2`
|
|
59
|
+
- (Opus ref se presente)
|
|
60
|
+
3) Scegli `CHAIR_REF`:
|
|
61
|
+
- preferenza: `openrouter/openai/gpt-5.2`
|
|
62
|
+
- fallback: un qualsiasi modello disponibile in `pico_models`
|
|
63
|
+
|
|
64
|
+
Se un modello non è disponibile, **saltalo** senza fallire l’intera esecuzione.
|
|
65
|
+
|
|
66
|
+
### Stage 1 — First opinions (parallelo)
|
|
67
|
+
|
|
68
|
+
Per ogni modello in `COUNCIL_REFS`, esegui `pico_query` in parallelo con:
|
|
69
|
+
|
|
70
|
+
**Prompt template**
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
You are one member of an LLM council.
|
|
74
|
+
|
|
75
|
+
User query:
|
|
76
|
+
{{USER_QUERY}}
|
|
77
|
+
|
|
78
|
+
Write your best answer.
|
|
79
|
+
- Be specific and actionable.
|
|
80
|
+
- If uncertain about facts, say so and propose verification steps.
|
|
81
|
+
- Prefer structure (headings/bullets) when helpful.
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Raccogli: `{modelRef, firstAnswer}`.
|
|
85
|
+
|
|
86
|
+
Se “Opus seat” è locale (non via Pico): genera anche tu una risposta indipendente *senza* guardare le altre.
|
|
87
|
+
|
|
88
|
+
### Stage 2 — Peer review + ranking (parallelo)
|
|
89
|
+
|
|
90
|
+
1) **Anonimizza** le risposte di Stage 1 assegnando ID `A, B, C, D...` e **non** includere il nome del modello nel testo inviato ai reviewer.
|
|
91
|
+
2) Per ogni reviewer (gli stessi modelli, più eventualmente te stesso se Opus seat locale), fai una `pico_query` con:
|
|
92
|
+
|
|
93
|
+
**Prompt template**
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
You are a critical reviewer in an LLM council.
|
|
97
|
+
|
|
98
|
+
User query:
|
|
99
|
+
{{USER_QUERY}}
|
|
100
|
+
|
|
101
|
+
Below are anonymized answers from different models:
|
|
102
|
+
|
|
103
|
+
Answer A:
|
|
104
|
+
...
|
|
105
|
+
|
|
106
|
+
Answer B:
|
|
107
|
+
...
|
|
108
|
+
|
|
109
|
+
Tasks:
|
|
110
|
+
1) Critique each answer briefly: strengths, weaknesses, missing pieces, hallucination risk.
|
|
111
|
+
2) Provide a ranking from best to worst (list the answer IDs).
|
|
112
|
+
3) Provide a short merge plan: what to combine into a final best answer.
|
|
113
|
+
|
|
114
|
+
Respond in JSON:
|
|
115
|
+
{
|
|
116
|
+
"critiques": [{"id":"A","notes":"..."}, ...],
|
|
117
|
+
"ranking": ["A","C","B"],
|
|
118
|
+
"merge_plan": "..."
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Se un reviewer non produce JSON valido:
|
|
123
|
+
- fai 1 retry chiedendo: “Return ONLY valid JSON.”
|
|
124
|
+
- se fallisce ancora, conserva comunque la parte testuale e marca `ranking: null`.
|
|
125
|
+
|
|
126
|
+
### Stage 3 — Chairman synthesis (1 chiamata)
|
|
127
|
+
|
|
128
|
+
Usa `CHAIR_REF` come chairman (di default GPT-5.2) e invia:
|
|
129
|
+
- user query
|
|
130
|
+
- tutte le risposte anonime
|
|
131
|
+
- tutte le review (critiques + ranking + merge plan)
|
|
132
|
+
|
|
133
|
+
**Prompt template**
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
You are the CHAIRMAN of an LLM council.
|
|
137
|
+
|
|
138
|
+
User query:
|
|
139
|
+
{{USER_QUERY}}
|
|
140
|
+
|
|
141
|
+
Anonymized answers:
|
|
142
|
+
{{ANSWERS_BLOCK}}
|
|
143
|
+
|
|
144
|
+
Peer reviews (critiques + ranking + merge plan):
|
|
145
|
+
{{REVIEWS_BLOCK}}
|
|
146
|
+
|
|
147
|
+
Rules:
|
|
148
|
+
- Produce ONE final answer to the user.
|
|
149
|
+
- Prefer correctness over confidence; call out uncertainty and suggest verification steps.
|
|
150
|
+
- When useful, include a short bullet list: "Key assumptions / decisions".
|
|
151
|
+
- Keep it concise but complete.
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Output
|
|
155
|
+
|
|
156
|
+
Rispondi all’utente con:
|
|
157
|
+
1) **Risposta finale** (chairman)
|
|
158
|
+
2) (Optional, if the user asks “debug” / “show me council”):
|
|
159
|
+
- elenco dei modelli usati
|
|
160
|
+
- mapping `A/B/C/D → modelRef`
|
|
161
|
+
- ranking aggregato (se possibile)
|
|
162
|
+
- note su modelli falliti
|
|
163
|
+
|
|
164
|
+
## Guardrail
|
|
165
|
+
|
|
166
|
+
- Non “aggiustare” le risposte inventando fatti: se il council è incerto, rendilo esplicito.
|
|
167
|
+
- Non rivelare informazioni private del workspace se non richieste.
|
|
168
|
+
- Se la domanda è ad alto rischio (finanza/medicina/legale), chiedi al chairman di includere disclaimer + passi di verifica.
|