@standardagents/skill 0.15.3 → 0.16.1-next.1e58032
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/package.json +1 -1
- package/skills/agentbuilder/SKILL.md +149 -9
package/package.json
CHANGED
|
@@ -33,7 +33,7 @@ For deeper reference material that this skill links to, see:
|
|
|
33
33
|
|
|
34
34
|
## Before you write any code
|
|
35
35
|
|
|
36
|
-
Most failed Standard Agent projects fail in the same
|
|
36
|
+
Most failed Standard Agent projects fail in the same seven ways. Read this section first and answer all seven questions explicitly before creating any code. Each links to the deeper section that explains *how*.
|
|
37
37
|
|
|
38
38
|
**1. Architect the agent graph before picking types.**
|
|
39
39
|
List the domains the system touches. Determine the tree (coordinator → domain agents → sub-domain agents). *Then* decide what each node is. Do not start by writing one agent and bolting tools onto it. → [Architecture & decomposition](#architecture--decomposition)
|
|
@@ -53,6 +53,9 @@ Fetch the official current docs. Confirm auth, base URL, endpoint paths, payload
|
|
|
53
53
|
**6. Check `ThreadState` before adding any dependency.**
|
|
54
54
|
Before reaching for S3, Redis, an external cron, a queue service, or even `node:fs`, confirm the framework does not already provide the capability via `ThreadState`. It almost always does. → [ThreadState first](#threadstate-first)
|
|
55
55
|
|
|
56
|
+
**7. Ship complete, polished definitions — not skeletons.**
|
|
57
|
+
A new agent is not done when it typechecks. It is done when it has a specific name, a `description`, an `icon`, human side labels, session tools wired in all three required places, and a prompt that handles the realistic edge cases of its domain. → [Creating a new agent: the completeness bar](#creating-a-new-agent-the-completeness-bar)
|
|
58
|
+
|
|
56
59
|
---
|
|
57
60
|
|
|
58
61
|
## What is a Standard Agent?
|
|
@@ -253,6 +256,140 @@ A `dual_ai` agent with no `sessionStop`, no `sessionFail`, and no `maxSessionTur
|
|
|
253
256
|
|
|
254
257
|
---
|
|
255
258
|
|
|
259
|
+
## Creating a new agent: the completeness bar
|
|
260
|
+
|
|
261
|
+
The most common quality failure when a coding agent creates a Standard Agent is **shipping a skeleton**: a bare `name`, no icon, sides called "Side A" and "Side B", a two-sentence prompt, and session tools that are bound on the agent but missing from the prompt's tool list. The agent typechecks, runs once, and then behaves badly in every way that matters. Hold every new agent to the bar in this section before calling it done.
|
|
262
|
+
|
|
263
|
+
### Identity & presentation (required, not optional)
|
|
264
|
+
|
|
265
|
+
| Field | Bar | Bad | Good |
|
|
266
|
+
|---|---|---|---|
|
|
267
|
+
| `name` | snake_case, domain + role. Suffix coordinators `_coordinator`, reviewers `_reviewer`, leaf agents `_agent`. | `assistant`, `my_agent`, `helper` | `gmail_agent`, `invoice_audit_reviewer`, `marketing_comms_coordinator` |
|
|
268
|
+
| `description` | One concrete sentence: what it does, for whom, with what. Shown in UIs. | "An agent that helps with email." | "Triages the support inbox, drafts replies for known issues, and escalates unknowns to a human queue." |
|
|
269
|
+
| `toolDescription` | Written for the **calling model**, not a human: when to choose this tool, what the key arguments are, what comes back. Required when `exposeAsTool: true`. | "Research agent." | "Research a topic with web search and source-backed URLs; returns a cited answer after an internal sufficiency review. Use for questions that need current or verifiable facts." |
|
|
270
|
+
| `icon` | Always set one. See below. | omitted | inline SVG data URI or hosted URL |
|
|
271
|
+
| `sideA.label` / `sideB.label` | Always set both on `dual_ai`. Name the **roles in the conversation** — they appear in the UI and logs. | "Side A" / "Side B", "AI 1" / "AI 2" | "Researcher" / "Reviewer", "Pilot" / "ATC", "Drafter" / "Editor", "Support" / "Customer" |
|
|
272
|
+
|
|
273
|
+
Side labels are also a design check: if you can't name the two roles, side_b probably doesn't have a real job yet — go back to [Session boundary discipline](#session-boundary-discipline).
|
|
274
|
+
|
|
275
|
+
### Icons
|
|
276
|
+
|
|
277
|
+
Every agent gets an `icon`. Don't skip it because no asset exists — author one. The value is any image URL, and an inline SVG data URI is self-contained and needs no hosting:
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
// agents/agents/invoice_audit_agent.ts
|
|
281
|
+
const icon = `data:image/svg+xml;utf8,${encodeURIComponent(
|
|
282
|
+
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
|
283
|
+
<rect width="32" height="32" rx="7" fill="#0f766e"/>
|
|
284
|
+
<path d="M10 9h12v14l-3-2-3 2-3-2-3 2z" fill="none" stroke="#ffffff" stroke-width="2" stroke-linejoin="round"/>
|
|
285
|
+
<path d="M13 14h6M13 18h4" stroke="#5eead4" stroke-width="2" stroke-linecap="round"/>
|
|
286
|
+
</svg>`,
|
|
287
|
+
)}`;
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Design rules for generated icons: one recognizable glyph for the domain (envelope for email, magnifier for research, calendar for scheduling), a filled rounded-square background in a single saturated color, two or three colors total, no text, no gradients, legible at 20×20. Give sibling agents in one project different background colors so they're distinguishable in the sidebar.
|
|
291
|
+
|
|
292
|
+
### Session tools must exist in three places
|
|
293
|
+
|
|
294
|
+
A session-ending tool is not "configured" until it appears in **all three** of these places. Missing any one produces a broken agent that still typechecks:
|
|
295
|
+
|
|
296
|
+
1. **`agents/tools/<name>.ts`** — a real `defineTool` whose args schema carries the payload fields (e.g. `final_answer`, `failure_summary`). The tool body can be a simple formatter; its job is to be callable and carry structured args.
|
|
297
|
+
2. **The side's prompt `tools` array** — the model can only call tools listed at the active step. A `sessionStop` binding to a tool the prompt never offers means the session *can never end on purpose*; it burns `maxSessionTurns` and fails opaquely.
|
|
298
|
+
3. **The `SideConfig` binding** — `sessionStop: { name: 'complete_research', messageProperty: 'final_answer' }`. Prefer the object form: `messageProperty` (and `attachmentsProperty` when files are returned) define the canonical payload the parent receives from a subagent. A bare string binding with no mapped property returns a vague payload upstream.
|
|
299
|
+
|
|
300
|
+
And a fourth, softer place: **the prompt text must tell the model when to call it** ("When the renders pass review, call `submit_video_assets` with ..."). Models do not infer termination protocol from tool names.
|
|
301
|
+
|
|
302
|
+
Quick failure-mode table:
|
|
303
|
+
|
|
304
|
+
| Symptom | Likely miss |
|
|
305
|
+
|---|---|
|
|
306
|
+
| Session always runs to `maxSessionTurns` | Session tool missing from the prompt's `tools` array, or prompt never says when to call it |
|
|
307
|
+
| Runtime error: unknown tool in session binding | Binding `name` typo, or tool file never created |
|
|
308
|
+
| Parent receives an empty / useless completion payload | `messageProperty` missing or doesn't match an arg field in the tool schema |
|
|
309
|
+
| Child fails but parent sees a "success" with garbage | No `sessionFail` bound — the model abused `sessionStop` to bail out |
|
|
310
|
+
|
|
311
|
+
### Prompt quality rubric
|
|
312
|
+
|
|
313
|
+
A two-sentence system prompt is a skeleton, not a prompt. Every side's prompt should cover, roughly in this order:
|
|
314
|
+
|
|
315
|
+
1. **Role and counterpart.** Who this side is *and who it is talking to*: "You are the researcher. The other participant is the user who needs the question answered." In `dual_ai`, each side must understand the other side's role or the conversation degrades into two assistants being polite to each other.
|
|
316
|
+
2. **Objective and definition of done.** One sentence the model can test against: "Done means every factual claim has a source URL and the reviewer has approved."
|
|
317
|
+
3. **Tool guidance.** When to use which tool — including the session tools: name them, say exactly what triggers calling them, and what belongs in each argument. For resumable subagents, distinguish `subagent_create` (new topic/instance) from `subagent_message` (follow-up to an existing instance).
|
|
318
|
+
4. **Edge cases.** This is what separates a thoughtful prompt from a placeholder. Walk the domain and enumerate what realistically goes wrong, with an instruction for each. The recurring ones:
|
|
319
|
+
- *Empty or low-quality results* — retry differently, broaden, or report honestly? How many attempts before giving up?
|
|
320
|
+
- *Auth / permission / quota errors from tools* — never retry blindly; call `sessionFail` with what the operator must fix.
|
|
321
|
+
- *Ambiguous request* — ask the counterpart side, or make a stated assumption? Pick one and say so.
|
|
322
|
+
- *Partial success* — deliver the partial result with gaps called out, or fail? Define the threshold.
|
|
323
|
+
- *Out-of-scope or unsafe asks* — refuse and route where?
|
|
324
|
+
- *Conflicting instructions between turns* — which takes precedence?
|
|
325
|
+
5. **Output format and quality bar.** Terse vs. comprehensive, citation requirements, structure of the final payload.
|
|
326
|
+
6. **Negative space.** What the model must NOT do: don't echo secrets, don't call `complete_*` before review, don't invent IDs, don't message the parent for FYI-only info.
|
|
327
|
+
|
|
328
|
+
High-leverage extra: include one **worked contrast example** inside the prompt — "this answer is insufficient, this one is sufficient, here's why" — like the incomplete-news-list example in the repo's `web_research_reviewer` prompt. One concrete contrast outperforms three paragraphs of abstract criteria.
|
|
329
|
+
|
|
330
|
+
Anti-patterns: a prompt that just restates the tool list ("You have tools to search and finish"); termination instructions buried mid-paragraph; criteria written for a human reader instead of as decisions the model must make; the same prompt pasted on both sides with the labels swapped.
|
|
331
|
+
|
|
332
|
+
### Subagent connection checklist
|
|
333
|
+
|
|
334
|
+
When the new agent is a child in a graph, creating the agent file is half the job. Verify the full wiring:
|
|
335
|
+
|
|
336
|
+
- [ ] Child is `dual_ai` with `exposeAsTool: true` and a calling-model-grade `toolDescription`
|
|
337
|
+
- [ ] Child has finite `maxSessionTurns`, and `sessionStop` + `sessionFail` bound on the side(s) that own those decisions
|
|
338
|
+
- [ ] The session tools pass the [three-places check](#session-tools-must-exist-in-three-places)
|
|
339
|
+
- [ ] The **parent prompt's `tools` array** has the subagent entry — an agent nobody references is unreachable. Choose `blocking` / `resumable` deliberately ([the four combinations](#subprompts-vs-subagents-vs-handoffs)), and map `initUserMessageProperty` (and `initAttachmentsProperty` for files) so the child starts with real context instead of an empty first turn
|
|
340
|
+
- [ ] The **parent prompt text** says when to delegate to this child and, if resumable, explains `subagent_create` vs `subagent_message`
|
|
341
|
+
- [ ] Side_b reviewers use a model from a *different provider* than side_a ([why](#session-boundary-discipline))
|
|
342
|
+
- [ ] Run the dev server and check the composition view: the parent→child edge should be visible, and creating a test thread should show the child spawn and the completion payload arrive back
|
|
343
|
+
|
|
344
|
+
### Worked example: a complete minimal agent
|
|
345
|
+
|
|
346
|
+
This is the shape every new `dual_ai` agent should have on day one — identity, icon, labels, both session tools, wired prompts. (Compressed for space; real prompts should be longer per the rubric above.)
|
|
347
|
+
|
|
348
|
+
```ts
|
|
349
|
+
// agents/tools/complete_audit.ts
|
|
350
|
+
export default defineTool({
|
|
351
|
+
description: 'Finish the audit session and return the findings to the requester.',
|
|
352
|
+
args: z.object({
|
|
353
|
+
findings: z.string().describe('Complete audit findings, ready for the requester.'),
|
|
354
|
+
discrepancy_count: z.number().describe('Number of discrepancies found.'),
|
|
355
|
+
}).strict(),
|
|
356
|
+
execute: async (_state, args) => ({ status: 'success' as const, result: args.findings }),
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// agents/tools/fail_audit.ts — same shape, args: { failure_summary: z.string() }
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
```ts
|
|
363
|
+
// agents/agents/invoice_audit_agent.ts
|
|
364
|
+
export default defineAgent({
|
|
365
|
+
name: 'invoice_audit_agent',
|
|
366
|
+
type: 'dual_ai',
|
|
367
|
+
description: 'Audits uploaded invoices against purchase orders and reports discrepancies.',
|
|
368
|
+
icon: invoiceAuditIcon, // inline SVG data URI, see Icons above
|
|
369
|
+
maxSessionTurns: 16,
|
|
370
|
+
sideA: {
|
|
371
|
+
label: 'Auditor',
|
|
372
|
+
prompt: 'invoice_audit_worker',
|
|
373
|
+
sessionFail: { name: 'fail_audit', messageProperty: 'failure_summary' },
|
|
374
|
+
maxSteps: 8,
|
|
375
|
+
},
|
|
376
|
+
sideB: {
|
|
377
|
+
label: 'Controller',
|
|
378
|
+
prompt: 'invoice_audit_reviewer',
|
|
379
|
+
sessionStop: { name: 'complete_audit', messageProperty: 'findings' },
|
|
380
|
+
sessionFail: { name: 'fail_audit', messageProperty: 'failure_summary' },
|
|
381
|
+
maxSteps: 4,
|
|
382
|
+
},
|
|
383
|
+
exposeAsTool: true,
|
|
384
|
+
toolDescription:
|
|
385
|
+
'Audit one or more invoices against purchase orders; returns findings with a discrepancy count after an internal controller review. Pass invoice file paths in attachments.',
|
|
386
|
+
});
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
Both prompts list their session tools in `tools` and the reviewer prompt instructs: *"Approve by calling `complete_audit` with the full findings in `findings` only after every line item has been checked; if documents are unreadable or POs are missing after one clarification round, call `fail_audit` and name exactly what the requester must provide."* The parent prompt adds `{ name: 'invoice_audit_agent', initUserMessageProperty: 'request', initAttachmentsProperty: 'invoice_files' }` to its `tools` and explains when to delegate.
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
256
393
|
## Model selection
|
|
257
394
|
|
|
258
395
|
**Rule: never write a model string the user did not request and `current-models` did not produce.**
|
|
@@ -552,20 +689,23 @@ AgentDefinition
|
|
|
552
689
|
sideA SideConfig AI side (or first AI in dual_ai)
|
|
553
690
|
sideB SideConfig second AI side; required for dual_ai
|
|
554
691
|
exposeAsTool boolean (default false) enables this agent to be called as a tool by other prompts
|
|
555
|
-
toolDescription string required if exposeAsTool: true
|
|
556
|
-
description string brief human description for UIs
|
|
557
|
-
icon string URL or
|
|
692
|
+
toolDescription string required if exposeAsTool: true — write it for the calling model
|
|
693
|
+
description string brief human description for UIs — always set on new agents
|
|
694
|
+
icon string URL or inline SVG data URI — always set on new agents
|
|
558
695
|
env Record<string, string> agent-level env values
|
|
559
696
|
hooks HookId[] agent-scoped hooks (when prompts don't specify their own)
|
|
560
697
|
```
|
|
561
698
|
|
|
562
|
-
`SideConfig` is where you
|
|
699
|
+
`SideConfig` is where you set the side's `label` and `prompt` and bind the **session lifecycle tools**:
|
|
563
700
|
|
|
564
|
-
- `
|
|
565
|
-
- `
|
|
566
|
-
- `
|
|
701
|
+
- `label` — the role name shown in the UI and logs ("Researcher", "Reviewer") — always set on `dual_ai` sides
|
|
702
|
+
- `prompt` — the prompt this side runs (references `agents/prompts/<name>`)
|
|
703
|
+
- `sessionStop` — tool whose call ends the session with a result; prefer `{ name, messageProperty }` so the payload is explicit
|
|
704
|
+
- `sessionFail` — tool whose call ends the session with a failure; same object form
|
|
705
|
+
- `sessionStatus` — optional, a tool used to publish status updates mid-run without ending the session
|
|
706
|
+
- `maxSteps` — per-side step cap within one turn
|
|
567
707
|
|
|
568
|
-
These are the bindings the [Session boundary discipline](#session-boundary-discipline) section refers to. Every `dual_ai` agent must set them.
|
|
708
|
+
These are the bindings the [Session boundary discipline](#session-boundary-discipline) section refers to. Every `dual_ai` agent must set them, and every session tool must pass the [three-places check](#session-tools-must-exist-in-three-places).
|
|
569
709
|
|
|
570
710
|
Packaging fields (`packageName`, `version`, `author`, `license`) exist for the agent packing system; ignore them unless you're publishing.
|
|
571
711
|
|