@codemation/agent-skills 0.3.0 → 0.5.1
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/CHANGELOG.md +182 -0
- package/dist/metadata.json +383 -36
- package/package.json +3 -1
- package/skills/builder/ai-agent/SKILL.md +314 -0
- package/skills/builder/ai-agent/references/anti-patterns.md +24 -0
- package/skills/{codemation-cli → builder/cli}/SKILL.md +1 -8
- package/skills/builder/connect-external-systems/SKILL.md +191 -0
- package/skills/builder/credential-development/SKILL.md +86 -0
- package/skills/{codemation-credential-development → builder/credential-development}/references/credential-patterns.md +3 -3
- package/skills/builder/custom-node-development/SKILL.md +61 -0
- package/skills/builder/custom-node-development/references/credential-aware-nodes.md +52 -0
- package/skills/builder/custom-node-development/references/define-batch-node.md +54 -0
- package/skills/{codemation-custom-node-development → builder/custom-node-development}/references/define-node-per-item.md +14 -14
- package/skills/{codemation-custom-node-development → builder/custom-node-development}/references/node-patterns.md +33 -49
- package/skills/builder/document-ai/SKILL.md +167 -0
- package/skills/builder/execution-context/SKILL.md +436 -0
- package/skills/{codemation-framework-concepts → builder/framework-concepts}/SKILL.md +10 -18
- package/skills/builder/gmail/SKILL.md +327 -0
- package/skills/builder/human-in-the-loop/SKILL.md +82 -0
- package/skills/{codemation-mcp-capabilities → builder/mcp-capabilities}/SKILL.md +4 -11
- package/skills/{codemation-mcp-capabilities → builder/mcp-capabilities}/references/agent-with-mcp.ts +1 -1
- package/skills/builder/msgraph/SKILL.md +338 -0
- package/skills/builder/odoo/SKILL.md +498 -0
- package/skills/{codemation-plugin-development → builder/plugin-development}/SKILL.md +4 -7
- package/skills/{codemation-plugin-development → builder/plugin-development}/references/plugin-anatomy.md +36 -15
- package/skills/{codemation-plugin-development → builder/plugin-development}/references/plugin-structure.md +2 -2
- package/skills/builder/rest-node/SKILL.md +148 -0
- package/skills/builder/testing/SKILL.md +142 -0
- package/skills/builder/workflow-dsl/SKILL.md +493 -0
- package/skills/builder/workspace-files/SKILL.md +191 -0
- package/skills/concierge/credentials/SKILL.md +91 -0
- package/skills/concierge/intake-automation-playbook/SKILL.md +78 -0
- package/skills/concierge/scenario-invoice-to-accounting/SKILL.md +48 -0
- package/skills/concierge/scenario-procurement-intake/SKILL.md +58 -0
- package/skills/codemation-ai-agent-node/SKILL.md +0 -66
- package/skills/codemation-ai-agent-node/references/anti-patterns.md +0 -11
- package/skills/codemation-credential-development/SKILL.md +0 -57
- package/skills/codemation-custom-node-development/SKILL.md +0 -61
- package/skills/codemation-custom-node-development/references/credential-aware-nodes.md +0 -38
- package/skills/codemation-custom-node-development/references/define-batch-node.md +0 -38
- package/skills/codemation-workflow-dsl/SKILL.md +0 -78
- package/skills/codemation-workflow-dsl/references/builder-patterns.md +0 -120
- package/skills/codemation-workflow-dsl/references/complete-example.md +0 -263
- package/skills/codemation-workflow-dsl/references/workflow-testing.md +0 -194
- /package/skills/{codemation-cli → builder/cli}/references/command-map.md +0 -0
- /package/skills/{codemation-framework-concepts → builder/framework-concepts}/references/architecture-map.md +0 -0
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
# Workflow Testing
|
|
2
|
-
|
|
3
|
-
## Use this reference when
|
|
4
|
-
|
|
5
|
-
You are authoring or reviewing a workflow that needs **end-to-end tests**: validate agent behavior, regression-test branching, score LLM outputs over time, or assert that a workflow produces the expected output for a known set of inputs.
|
|
6
|
-
|
|
7
|
-
This is **not** for unit-testing individual nodes — use `WorkflowTestKit` from `@codemation/core/testing` for that.
|
|
8
|
-
|
|
9
|
-
## Three building blocks
|
|
10
|
-
|
|
11
|
-
1. **`TestTrigger`** — drops on the canvas alongside live triggers (Webhook / Cron / Gmail / etc.). Authored callback yields one item per test case.
|
|
12
|
-
2. **`IsTestRun`** — per-item router with `true` / `false` ports. Branches based on whether the run was started by the test orchestrator.
|
|
13
|
-
3. **`Assertion`** — generic per-item assertion node; returns one or more `AssertionResult`s per input item, one persisted `TestAssertion` row per result.
|
|
14
|
-
|
|
15
|
-
## Typical workflow shape
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
[GmailTrigger: new email] ──┐
|
|
19
|
-
│
|
|
20
|
-
[TestTrigger: 10 fixtures]──┴─→ [ClassifyAgent]
|
|
21
|
-
│
|
|
22
|
-
[IsTestRun?]
|
|
23
|
-
│ │
|
|
24
|
-
true│ │false
|
|
25
|
-
↓ ↓
|
|
26
|
-
[Assertion] [SendReply] (real side effect — skipped in tests)
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Authoring a TestTrigger
|
|
30
|
-
|
|
31
|
-
```ts
|
|
32
|
-
import { TestTrigger } from "@codemation/core-nodes";
|
|
33
|
-
import { gmailCredentialType, type GmailSession } from "@codemation/core-nodes-gmail";
|
|
34
|
-
|
|
35
|
-
export const fixtureMailsTrigger = new TestTrigger<{ subject: string; body: string }>({
|
|
36
|
-
name: "Email fixtures",
|
|
37
|
-
credentialRequirements: [
|
|
38
|
-
{ slotKey: "gmail", label: "Gmail", acceptedTypes: [gmailCredentialType.definition.typeId] },
|
|
39
|
-
],
|
|
40
|
-
async *generateItems(ctx) {
|
|
41
|
-
const gmail = await ctx.getCredential<GmailSession>("gmail");
|
|
42
|
-
const messages = await gmail.listMessages({ labelIds: ["Label_test_mails"] });
|
|
43
|
-
for (const message of messages) {
|
|
44
|
-
if (ctx.signal.aborted) break;
|
|
45
|
-
yield { json: { subject: message.subject, body: message.body } };
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
concurrency: 8, // optional; default 4
|
|
49
|
-
caseLabel: (item) => item.json.subject, // optional; rows fall back to runId
|
|
50
|
-
});
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Notes:
|
|
54
|
-
|
|
55
|
-
- `triggerKind: "test"` is set automatically — `TriggerRuntimeService` skips it during live activation.
|
|
56
|
-
- `ctx.signal` is an `AbortSignal` raised when the suite is cancelled; long pulls should bail out.
|
|
57
|
-
- For hardcoded fixtures, just `yield { json: { ... } }` — no need to use credentials.
|
|
58
|
-
- Set `caseLabel` so the Tests-tab tree-table shows something readable instead of opaque runIds.
|
|
59
|
-
|
|
60
|
-
## Branching in the workflow
|
|
61
|
-
|
|
62
|
-
```ts
|
|
63
|
-
import { IsTestRun } from "@codemation/core-nodes";
|
|
64
|
-
|
|
65
|
-
const isTestRun = new IsTestRun("Skip side effects in tests");
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Or read `ctx.testContext` directly from a custom node:
|
|
69
|
-
|
|
70
|
-
```ts
|
|
71
|
-
async execute({ item, ctx }) {
|
|
72
|
-
if (ctx.testContext) {
|
|
73
|
-
return { json: { result: "synthetic-test-output" } };
|
|
74
|
-
}
|
|
75
|
-
return { json: await this.realApi.send(item.json) };
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## Authoring assertions
|
|
80
|
-
|
|
81
|
-
```ts
|
|
82
|
-
import { Assertion } from "@codemation/core-nodes";
|
|
83
|
-
|
|
84
|
-
const checkClassification = new Assertion<{ label: string; confidence: number }>({
|
|
85
|
-
name: "Classification checks",
|
|
86
|
-
assertions: (item) => [
|
|
87
|
-
{
|
|
88
|
-
// Boolean-style: 1 = pass, 0 = fail. Default threshold (0.5) handles this.
|
|
89
|
-
name: "label is spam",
|
|
90
|
-
score: item.json.label === "spam" ? 1 : 0,
|
|
91
|
-
expected: "spam",
|
|
92
|
-
actual: item.json.label,
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
// Continuous-score: declare the threshold explicitly.
|
|
96
|
-
name: "confidence ≥ 0.8",
|
|
97
|
-
score: item.json.confidence,
|
|
98
|
-
passThreshold: 0.8,
|
|
99
|
-
expected: "≥ 0.8",
|
|
100
|
-
actual: item.json.confidence,
|
|
101
|
-
},
|
|
102
|
-
],
|
|
103
|
-
});
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
The `AssertionResult` shape (stable; persister + chart UIs key off these fields):
|
|
107
|
-
|
|
108
|
-
```ts
|
|
109
|
-
interface AssertionResult {
|
|
110
|
-
readonly name: string;
|
|
111
|
-
/** 0..1 score. Source of truth for pass/fail (compared against `passThreshold`). */
|
|
112
|
-
readonly score: number;
|
|
113
|
-
/** 0..1 threshold for "passed". When omitted, consumers default to 0.5. */
|
|
114
|
-
readonly passThreshold?: number;
|
|
115
|
-
/** True when evaluating the assertion threw — treated as fail regardless of `score`. */
|
|
116
|
-
readonly errored?: true;
|
|
117
|
-
readonly expected?: JsonValue;
|
|
118
|
-
readonly actual?: JsonValue;
|
|
119
|
-
readonly message?: string;
|
|
120
|
-
readonly details?: Readonly<Record<string, JsonValue>>;
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
Pass/fail derivation (canonical, in `@codemation/core`):
|
|
125
|
-
|
|
126
|
-
```ts
|
|
127
|
-
import { deriveAssertionPassed } from "@codemation/core";
|
|
128
|
-
// errored ? false : score >= (passThreshold ?? 0.5)
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
`errored: true` is for the assertion code itself crashing (judge agent crashed, JSON parse failed) — use it to separate "broken evaluator" from "wrong workflow output" in dashboards:
|
|
132
|
-
|
|
133
|
-
```ts
|
|
134
|
-
assertions: async (item, ctx) => {
|
|
135
|
-
try {
|
|
136
|
-
const j = await runJudge(item, ctx);
|
|
137
|
-
return [{ name: "polite reply", score: j.score, passThreshold: 0.7, message: j.reason }];
|
|
138
|
-
} catch (err) {
|
|
139
|
-
return [{ name: "polite reply", score: 0, errored: true, message: String(err) }];
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
## Judge-by-Agent
|
|
145
|
-
|
|
146
|
-
A judge-by-agent is just an AI agent step feeding into an Assertion callback. Run an agent that returns a structured judgment, then map its output to an `AssertionResult` (`score: 0..1`, set `passThreshold`).
|
|
147
|
-
|
|
148
|
-
## Running tests
|
|
149
|
-
|
|
150
|
-
- **From the UI**: open the workflow → **Tests** tab. Pick a TestTrigger from the dropdown (the picker lists every `triggerKind === "test"` node), click **Run tests**. Use the metric selector on the trend chart to plot pass-rate, per-assertion average scores, or case counts. Click two historical runs to compare them side-by-side.
|
|
151
|
-
- **From code**: instantiate `TestSuiteOrchestrator` from `@codemation/core/bootstrap`, call `runSuite({ workflow, triggerNodeId })`.
|
|
152
|
-
- **From HTTP**: `POST /api/workflows/:workflowId/test-suite-runs` with `{ triggerNodeId, concurrency? }`.
|
|
153
|
-
|
|
154
|
-
## Status
|
|
155
|
-
|
|
156
|
-
### Per case (`Run.testCaseStatus`)
|
|
157
|
-
|
|
158
|
-
| Status | Meaning |
|
|
159
|
-
| ----------- | ------------------------------------------------------------------------------------- |
|
|
160
|
-
| `running` | Workflow run dispatched, not yet finished. |
|
|
161
|
-
| `succeeded` | Workflow completed AND every assertion passed. |
|
|
162
|
-
| `failed` | Assertion-rollup downgrade OR the workflow itself reported failure. |
|
|
163
|
-
| `errored` | Workflow run threw before reaching a terminal state (engine error, not an assertion). |
|
|
164
|
-
| `cancelled` | Suite's `AbortSignal` fired before this case completed. |
|
|
165
|
-
|
|
166
|
-
### Suite
|
|
167
|
-
|
|
168
|
-
| Status | Meaning |
|
|
169
|
-
| ----------- | ------------------------------------------------------------------- |
|
|
170
|
-
| `succeeded` | All cases passed (or zero cases yielded). |
|
|
171
|
-
| `failed` | Every case failed. |
|
|
172
|
-
| `partial` | Some passed, some failed — **the normal "1 of 10 failed" outcome**. |
|
|
173
|
-
| `cancelled` | Suite was aborted before all cases finished. |
|
|
174
|
-
| `errored` | The `generateItems` callback itself threw. |
|
|
175
|
-
|
|
176
|
-
The suite counters and status are re-derived from the final per-case statuses, so an "all workflows completed cleanly but assertions caught regressions" suite reports `partial` rather than `succeeded`.
|
|
177
|
-
|
|
178
|
-
## Best practices
|
|
179
|
-
|
|
180
|
-
- **Don't `throw` from `execute` to fail a case.** Throwing skips downstream nodes — including the Assertion node — so you lose all assertion data and only get a run-level error. Instead, let the workflow complete and assert on the (wrong) output. The assertion-rollup downgrades the case to `failed`.
|
|
181
|
-
- Use `score: 1`/`score: 0` for boolean checks (equality, contains, regex). The default `passThreshold = 0.5` handles them.
|
|
182
|
-
- Use `passThreshold` for continuous metrics (confidence, judge ratings, similarity).
|
|
183
|
-
- Reserve `errored: true` for assertion-code crashes, not low scores.
|
|
184
|
-
- Keep TestTriggers as source-controlled fixtures so historical chart comparisons are apples-to-apples.
|
|
185
|
-
|
|
186
|
-
## What's deferred (Phase 2)
|
|
187
|
-
|
|
188
|
-
- **Test-input snapshots** — Phase 1 fetches inputs live every run (rolling-input). Snapshotting will land in Phase 2 for stable judge-score charts.
|
|
189
|
-
- **Declarative assertion shorthands** — `StringEqualsAssertion`, `JudgeByAgentAssertion`, etc. compose on top of the generic `Assertion` shipping today.
|
|
190
|
-
- **CLI / cron / GitHub PR integration** — currently triggered manually via UI or HTTP only.
|
|
191
|
-
|
|
192
|
-
## Read more
|
|
193
|
-
|
|
194
|
-
- Top-level walkthrough: [`docs/workflow-testing.md`](../../../../docs/workflow-testing.md)
|
|
File without changes
|
|
File without changes
|