@n8n/instance-ai 1.3.3 → 1.4.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/dist/agent/credential-guardrails.prompt.d.ts +1 -0
- package/dist/agent/credential-guardrails.prompt.js +5 -0
- package/dist/agent/credential-guardrails.prompt.js.map +1 -0
- package/dist/agent/shared-prompts.d.ts +4 -0
- package/dist/agent/shared-prompts.js +17 -0
- package/dist/agent/shared-prompts.js.map +1 -0
- package/dist/agent/sub-agent-factory.d.ts +1 -1
- package/dist/agent/sub-agent-factory.js +7 -7
- package/dist/agent/sub-agent-factory.js.map +1 -1
- package/dist/agent/system-prompt.js +39 -22
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/build.tsbuildinfo +1 -1
- package/dist/constants/max-steps.d.ts +1 -1
- package/dist/constants/max-steps.js +1 -1
- package/dist/constants/max-steps.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/storage/agent-tree-snapshot.d.ts +2 -0
- package/dist/tools/credentials.tool.js +20 -3
- package/dist/tools/credentials.tool.js.map +1 -1
- package/dist/tools/executions.tool.js.map +1 -1
- package/dist/tools/nodes/suggested-nodes-data.js +1 -1
- package/dist/tools/nodes/suggested-nodes-data.js.map +1 -1
- package/dist/tools/nodes.tool.js +25 -13
- package/dist/tools/nodes.tool.js.map +1 -1
- package/dist/tools/orchestration/browser-credential-setup.prompt.d.ts +13 -0
- package/dist/tools/orchestration/browser-credential-setup.prompt.js +140 -0
- package/dist/tools/orchestration/browser-credential-setup.prompt.js.map +1 -0
- package/dist/tools/orchestration/browser-credential-setup.tool.d.ts +1 -0
- package/dist/tools/orchestration/browser-credential-setup.tool.js +8 -139
- package/dist/tools/orchestration/browser-credential-setup.tool.js.map +1 -1
- package/dist/tools/orchestration/build-workflow-agent.prompt.js +104 -235
- package/dist/tools/orchestration/build-workflow-agent.prompt.js.map +1 -1
- package/dist/tools/orchestration/build-workflow-agent.tool.d.ts +1 -0
- package/dist/tools/orchestration/build-workflow-agent.tool.js +61 -17
- package/dist/tools/orchestration/build-workflow-agent.tool.js.map +1 -1
- package/dist/tools/orchestration/data-table-agent.prompt.d.ts +1 -1
- package/dist/tools/orchestration/data-table-agent.prompt.js +4 -6
- package/dist/tools/orchestration/data-table-agent.prompt.js.map +1 -1
- package/dist/tools/orchestration/data-table-agent.tool.js +1 -1
- package/dist/tools/orchestration/data-table-agent.tool.js.map +1 -1
- package/dist/tools/orchestration/delegate.tool.js +1 -1
- package/dist/tools/orchestration/delegate.tool.js.map +1 -1
- package/dist/tools/orchestration/plan-agent-prompt.d.ts +1 -1
- package/dist/tools/orchestration/plan-agent-prompt.js +11 -17
- package/dist/tools/orchestration/plan-agent-prompt.js.map +1 -1
- package/dist/tools/orchestration/plan.tool.js +65 -1
- package/dist/tools/orchestration/plan.tool.js.map +1 -1
- package/dist/tools/orchestration/report-verification-verdict.tool.js +4 -1
- package/dist/tools/orchestration/report-verification-verdict.tool.js.map +1 -1
- package/dist/tools/orchestration/research-agent-prompt.d.ts +1 -1
- package/dist/tools/orchestration/research-agent-prompt.js +2 -4
- package/dist/tools/orchestration/research-agent-prompt.js.map +1 -1
- package/dist/tools/orchestration/research-with-agent.tool.js +1 -1
- package/dist/tools/orchestration/research-with-agent.tool.js.map +1 -1
- package/dist/tools/orchestration/verify-built-workflow.tool.js +1 -1
- package/dist/tools/orchestration/verify-built-workflow.tool.js.map +1 -1
- package/dist/tools/shared/ask-user.tool.js +2 -1
- package/dist/tools/shared/ask-user.tool.js.map +1 -1
- package/dist/tools/workflows/build-workflow.tool.d.ts +6 -6
- package/dist/tools/workflows/build-workflow.tool.js +17 -4
- package/dist/tools/workflows/build-workflow.tool.js.map +1 -1
- package/dist/tools/workflows/resolve-credentials.js +6 -6
- package/dist/tools/workflows/resolve-credentials.js.map +1 -1
- package/dist/tools/workflows/setup-workflow.service.js +3 -2
- package/dist/tools/workflows/setup-workflow.service.js.map +1 -1
- package/dist/tools/workflows/submit-workflow-identity.d.ts +13 -0
- package/dist/tools/workflows/submit-workflow-identity.js +67 -0
- package/dist/tools/workflows/submit-workflow-identity.js.map +1 -0
- package/dist/tools/workflows/submit-workflow.tool.d.ts +34 -0
- package/dist/tools/workflows/submit-workflow.tool.js +41 -29
- package/dist/tools/workflows/submit-workflow.tool.js.map +1 -1
- package/dist/tools/workflows.tool.js +3 -1
- package/dist/tools/workflows.tool.js.map +1 -1
- package/dist/tracing/langsmith-tracing.d.ts +12 -0
- package/dist/tracing/langsmith-tracing.js +27 -0
- package/dist/tracing/langsmith-tracing.js.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/utils/eval-agents.js +4 -2
- package/dist/utils/eval-agents.js.map +1 -1
- package/dist/workflow-loop/guidance.js +9 -5
- package/dist/workflow-loop/guidance.js.map +1 -1
- package/dist/workspace/builder-sandbox-factory.d.ts +5 -1
- package/dist/workspace/builder-sandbox-factory.js +43 -1
- package/dist/workspace/builder-sandbox-factory.js.map +1 -1
- package/dist/workspace/pack-workspace-sdk.d.ts +9 -0
- package/dist/workspace/pack-workspace-sdk.js +80 -0
- package/dist/workspace/pack-workspace-sdk.js.map +1 -0
- package/dist/workspace/sandbox-fs.d.ts +1 -1
- package/dist/workspace/sandbox-fs.js +3 -1
- package/dist/workspace/sandbox-fs.js.map +1 -1
- package/dist/workspace/sandbox-setup.js +48 -12
- package/dist/workspace/sandbox-setup.js.map +1 -1
- package/package.json +9 -8
|
@@ -5,20 +5,40 @@ exports.createSandboxBuilderAgentPrompt = createSandboxBuilderAgentPrompt;
|
|
|
5
5
|
const parameter_guides_1 = require("@n8n/workflow-sdk/prompts/node-guidance/parameter-guides");
|
|
6
6
|
const node_selection_1 = require("@n8n/workflow-sdk/prompts/node-selection");
|
|
7
7
|
const sdk_reference_1 = require("@n8n/workflow-sdk/prompts/sdk-reference");
|
|
8
|
-
const
|
|
9
|
-
const
|
|
8
|
+
const shared_prompts_1 = require("../../agent/shared-prompts");
|
|
9
|
+
const BUILDER_OUTPUT_DISCIPLINE = `## Output Discipline
|
|
10
|
+
- Your text output is visible to the user. Be concise and natural.
|
|
11
|
+
- Only output text for: errors that need attention, or a brief natural completion message.
|
|
12
|
+
- No emojis, no filler phrases, no markdown headers in your text output.
|
|
13
|
+
- When conversation context is provided, use it to continue naturally — do not repeat information the user already knows.
|
|
14
|
+
|
|
15
|
+
### No narration (critical)
|
|
16
|
+
Do NOT announce what you're about to do. The user already sees your tool calls in real time via the agent card; narrating them is pure noise. Stay silent while working; speak only on completion or when blocked.
|
|
17
|
+
|
|
18
|
+
BAD (do not write anything like this):
|
|
19
|
+
- "I'll build this family AI assistant for Telegram. Let me start by discovering credentials and resources..."
|
|
20
|
+
- "I'll start by reading the current workflow code and looking up the correct Linear node type definition."
|
|
21
|
+
- "I don't see any pinData — let me check if there's something embedded in the workflow..."
|
|
22
|
+
- "Let me look up the Slack channel IDs now."
|
|
23
|
+
|
|
24
|
+
GOOD (one-line, only on completion or block):
|
|
25
|
+
- "Family AI assistant workflow ready — uses Telegram, OpenAI, and your shopping list data table."
|
|
26
|
+
- "Workflow updated: removed the stale pinData from the weather check node."
|
|
27
|
+
- "Blocked: the Linear API credential is missing and the setup wizard is needed before I can continue."`;
|
|
10
28
|
const SDK_CODE_RULES = `## SDK Code Rules
|
|
11
29
|
|
|
12
30
|
- Do NOT specify node positions — they are auto-calculated by the layout engine.
|
|
13
31
|
- For credentials, see the credential rules in your specific workflow process section below.
|
|
14
|
-
-
|
|
32
|
+
- For placeholders, see the ## Placeholders section.
|
|
15
33
|
- Use \`expr('{{ $json.field }}')\` for n8n expressions. Variables MUST be inside \`{{ }}\`.
|
|
16
34
|
- Do NOT use \`as const\` assertions — the workflow parser only supports JavaScript syntax, not TypeScript-only features. Just use plain string literals.
|
|
17
35
|
- Use string values directly for discriminator fields like \`resource\` and \`operation\` (e.g., \`resource: 'message'\` not \`resource: 'message' as const\`).
|
|
18
36
|
- When editing a pre-loaded workflow, **remove \`position\` arrays** from node configs — they are auto-calculated.
|
|
19
37
|
- **No em-dash (\`—\`) or other special Unicode characters in node names or string values.** Use plain hyphen (\`-\`) instead. The SDK parser cannot handle em-dashes.
|
|
20
38
|
- **IF node combinator** must be \`'and'\` or \`'or'\` (not \`'any'\` or \`'all'\`).`;
|
|
21
|
-
|
|
39
|
+
function buildBuilderSpecificPatterns(mode) {
|
|
40
|
+
const openAiCredExample = mode === 'sandbox' ? "{ id: 'credId', name: 'OpenAI account' }" : "newCredential('OpenAI')";
|
|
41
|
+
return `## Critical Patterns (Common Mistakes)
|
|
22
42
|
|
|
23
43
|
**Pay attention to @builderHint annotations in search results and type definitions** — these provide critical guidance on how to correctly configure node parameters. Write them out as notes when reviewing — they prevent common configuration mistakes.
|
|
24
44
|
|
|
@@ -38,8 +58,8 @@ const model = languageModel({
|
|
|
38
58
|
version: 1.3,
|
|
39
59
|
config: {
|
|
40
60
|
name: 'OpenAI Chat Model',
|
|
41
|
-
parameters: { model: { __rl: true, mode: 'list', value: 'gpt-
|
|
42
|
-
credentials: { openAiApi:
|
|
61
|
+
parameters: { model: { __rl: true, mode: 'list', value: 'gpt-5.4' } },
|
|
62
|
+
credentials: { openAiApi: ${openAiCredExample} }
|
|
43
63
|
}
|
|
44
64
|
});
|
|
45
65
|
|
|
@@ -174,189 +194,7 @@ export default workflow('id', 'name')
|
|
|
174
194
|
|
|
175
195
|
### Web App (SPA served from a webhook)
|
|
176
196
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
<web_app_pattern>
|
|
180
|
-
**Architecture:** Webhook (responseNode) -> Code node (build HTML) -> Respond with text/html
|
|
181
|
-
|
|
182
|
-
**File-based HTML (REQUIRED for pages > ~50 lines):**
|
|
183
|
-
Write the HTML to a separate file (e.g., \`chunks/dashboard.html\`), then in the SDK TypeScript code use \`readFileSync\` + \`JSON.stringify\` to safely embed it in a Code node. This eliminates ALL escaping problems:
|
|
184
|
-
|
|
185
|
-
1. Write your full HTML (with CSS, JS, Alpine.js/Tailwind) to \`chunks/page.html\`
|
|
186
|
-
2. In \`src/workflow.ts\`: \`const htmlTemplate = readFileSync(join(__dirname, '../chunks/page.html'), 'utf8');\`
|
|
187
|
-
3. Use \`JSON.stringify(htmlTemplate)\` to create a safe JS string literal for the Code node's jsCode
|
|
188
|
-
4. For data injection, embed a \`__DATA_PLACEHOLDER__\` token in the HTML and replace it at runtime
|
|
189
|
-
|
|
190
|
-
**NEVER embed large HTML directly in jsCode** — not as template literals, not as arrays of quoted lines. Both break for real-world pages (20KB+). Always use the file-based pattern.
|
|
191
|
-
|
|
192
|
-
**For small static HTML (< 50 lines):** You may inline as an array of quoted strings + \`.join('\\n')\`, but still prefer the file-based approach.
|
|
193
|
-
|
|
194
|
-
**Data injection patterns:**
|
|
195
|
-
- Static page (no server data): embed HTML directly, no placeholder needed
|
|
196
|
-
- Dynamic data: put \`<script id="__data" type="application/json">__DATA_PLACEHOLDER__</script>\` in the HTML. At runtime, the Code node replaces \`__DATA_PLACEHOLDER__\` with base64-encoded JSON. Client-side: \`JSON.parse(atob(document.getElementById('__data').textContent))\`
|
|
197
|
-
- Do NOT place bare \`{{ $json... }}\` inside an HTML string parameter
|
|
198
|
-
|
|
199
|
-
**Multi-route SPA (dashboard with API endpoints):**
|
|
200
|
-
Use multiple webhooks in one workflow — one serves the HTML page, others serve JSON API endpoints. The HTML's JavaScript uses \`fetch()\` to call sibling webhook paths.
|
|
201
|
-
|
|
202
|
-
**Default stack:** Alpine.js + Tailwind CSS via CDN. No build step, works in a single HTML file.
|
|
203
|
-
|
|
204
|
-
**Respond correctly:** Use respondToWebhook with respondWith: "text", put the HTML in responseBody via expression, and set Content-Type header.
|
|
205
|
-
</web_app_pattern>
|
|
206
|
-
|
|
207
|
-
#### Example: Multi-route dashboard with DataTable API
|
|
208
|
-
|
|
209
|
-
**chunks/dashboard.html** — the full HTML page (write this file first):
|
|
210
|
-
\`\`\`html
|
|
211
|
-
<!DOCTYPE html>
|
|
212
|
-
<html lang="en">
|
|
213
|
-
<head>
|
|
214
|
-
<meta charset="UTF-8">
|
|
215
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
216
|
-
<title>Dashboard</title>
|
|
217
|
-
<script src="https://cdn.tailwindcss.com"></script>
|
|
218
|
-
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3/dist/cdn.min.js"></script>
|
|
219
|
-
</head>
|
|
220
|
-
<body class="bg-gray-50 min-h-screen p-8">
|
|
221
|
-
<h1 class="text-2xl font-bold mb-6">Dashboard</h1>
|
|
222
|
-
<div x-data="app()" x-init="loadItems()">
|
|
223
|
-
<template x-for="item in items" :key="item.id">
|
|
224
|
-
<div class="bg-white rounded-lg shadow p-4 mb-3 flex items-center gap-3">
|
|
225
|
-
<input type="checkbox" :checked="item.completed" @change="toggle(item)">
|
|
226
|
-
<span x-text="item.title" :class="item.completed && 'line-through text-gray-400'"></span>
|
|
227
|
-
</div>
|
|
228
|
-
</template>
|
|
229
|
-
<form @submit.prevent="addItem()" class="mt-4 flex gap-2">
|
|
230
|
-
<input x-model="newTitle" placeholder="New item..." class="border rounded px-3 py-2 flex-1">
|
|
231
|
-
<button type="submit" class="bg-blue-600 text-white px-4 py-2 rounded">Add</button>
|
|
232
|
-
</form>
|
|
233
|
-
</div>
|
|
234
|
-
<!-- Server data injected at runtime (base64-encoded JSON) -->
|
|
235
|
-
<script id="__data" type="application/json">__DATA_PLACEHOLDER__</script>
|
|
236
|
-
<script>
|
|
237
|
-
function app() {
|
|
238
|
-
return {
|
|
239
|
-
items: JSON.parse(atob(document.getElementById('__data').textContent)),
|
|
240
|
-
newTitle: '',
|
|
241
|
-
async toggle(item) {
|
|
242
|
-
await fetch('/webhook/app/items/toggle', {
|
|
243
|
-
method: 'POST', headers: {'Content-Type': 'application/json'},
|
|
244
|
-
body: JSON.stringify({ id: item.id, completed: !item.completed })
|
|
245
|
-
});
|
|
246
|
-
item.completed = !item.completed;
|
|
247
|
-
},
|
|
248
|
-
async addItem() {
|
|
249
|
-
if (!this.newTitle.trim()) return;
|
|
250
|
-
const res = await fetch('/webhook/app/items/add', {
|
|
251
|
-
method: 'POST', headers: {'Content-Type': 'application/json'},
|
|
252
|
-
body: JSON.stringify({ title: this.newTitle })
|
|
253
|
-
});
|
|
254
|
-
const created = await res.json();
|
|
255
|
-
this.items.push(created);
|
|
256
|
-
this.newTitle = '';
|
|
257
|
-
},
|
|
258
|
-
loadItems() { /* items already loaded from __data */ }
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
</script>
|
|
262
|
-
</body>
|
|
263
|
-
</html>
|
|
264
|
-
\`\`\`
|
|
265
|
-
|
|
266
|
-
**src/workflow.ts** — the workflow with 4 webhook routes:
|
|
267
|
-
\`\`\`javascript
|
|
268
|
-
import { workflow, node, trigger, expr } from '@n8n/workflow-sdk';
|
|
269
|
-
import { readFileSync } from 'fs';
|
|
270
|
-
import { join } from 'path';
|
|
271
|
-
|
|
272
|
-
// Read the HTML template at build time — eliminates all escaping issues
|
|
273
|
-
const htmlTemplate = readFileSync(join(__dirname, '../chunks/dashboard.html'), 'utf8');
|
|
274
|
-
|
|
275
|
-
// ── Webhooks ──────────────────────────────────────────────
|
|
276
|
-
const pageWebhook = trigger({
|
|
277
|
-
type: 'n8n-nodes-base.webhook', version: 2.1,
|
|
278
|
-
config: { name: 'GET /app', parameters: { httpMethod: 'GET', path: 'app', responseMode: 'responseNode', options: {} } }
|
|
279
|
-
});
|
|
280
|
-
const getItemsWebhook = trigger({
|
|
281
|
-
type: 'n8n-nodes-base.webhook', version: 2.1,
|
|
282
|
-
config: { name: 'GET /app/items', parameters: { httpMethod: 'GET', path: 'app/items', responseMode: 'responseNode', options: {} } }
|
|
283
|
-
});
|
|
284
|
-
const toggleWebhook = trigger({
|
|
285
|
-
type: 'n8n-nodes-base.webhook', version: 2.1,
|
|
286
|
-
config: { name: 'POST /app/items/toggle', parameters: { httpMethod: 'POST', path: 'app/items/toggle', responseMode: 'responseNode', options: {} } }
|
|
287
|
-
});
|
|
288
|
-
const addWebhook = trigger({
|
|
289
|
-
type: 'n8n-nodes-base.webhook', version: 2.1,
|
|
290
|
-
config: { name: 'POST /app/items/add', parameters: { httpMethod: 'POST', path: 'app/items/add', responseMode: 'responseNode', options: {} } }
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
// ── Route 1: Serve HTML page with pre-loaded data ─────────
|
|
294
|
-
const fetchAllItems = node({
|
|
295
|
-
type: 'n8n-nodes-base.dataTable', version: 1.1,
|
|
296
|
-
config: { name: 'Fetch Items', parameters: { resource: 'row', operation: 'get', dataTableId: { __rl: true, mode: 'name', value: 'items' }, returnAll: true, options: {} } }
|
|
297
|
-
});
|
|
298
|
-
const aggregateItems = node({
|
|
299
|
-
type: 'n8n-nodes-base.aggregate', version: 1,
|
|
300
|
-
config: { name: 'Aggregate', parameters: { aggregate: 'aggregateAllItemData', destinationFieldName: 'data', options: {} } }
|
|
301
|
-
});
|
|
302
|
-
// JSON.stringify in the SDK code creates a safe JS string literal — no escaping issues
|
|
303
|
-
const buildPage = node({
|
|
304
|
-
type: 'n8n-nodes-base.code', version: 2,
|
|
305
|
-
config: {
|
|
306
|
-
name: 'Build Page',
|
|
307
|
-
parameters: {
|
|
308
|
-
mode: 'runOnceForAllItems',
|
|
309
|
-
jsCode: 'var data = $input.all()[0].json.data || [];\\n'
|
|
310
|
-
+ 'var encoded = Buffer.from(JSON.stringify(data)).toString("base64");\\n'
|
|
311
|
-
+ 'var html = ' + JSON.stringify(htmlTemplate) + '.replace("__DATA_PLACEHOLDER__", encoded);\\n'
|
|
312
|
-
+ 'return [{ json: { html: html } }];'
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
});
|
|
316
|
-
const respondHtml = node({
|
|
317
|
-
type: 'n8n-nodes-base.respondToWebhook', version: 1.1,
|
|
318
|
-
config: { name: 'Respond HTML', parameters: { respondWith: 'text', responseBody: expr('{{ $json.html }}'), options: { responseHeaders: { entries: [{ name: 'Content-Type', value: 'text/html; charset=utf-8' }] } } } }
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
// ── Route 2: GET items as JSON ────────────────────────────
|
|
322
|
-
const fetchItemsJson = node({
|
|
323
|
-
type: 'n8n-nodes-base.dataTable', version: 1.1,
|
|
324
|
-
config: { name: 'Get Items JSON', parameters: { resource: 'row', operation: 'get', dataTableId: { __rl: true, mode: 'name', value: 'items' }, returnAll: true, options: {} } }
|
|
325
|
-
});
|
|
326
|
-
const respondItems = node({
|
|
327
|
-
type: 'n8n-nodes-base.respondToWebhook', version: 1.1,
|
|
328
|
-
config: { name: 'Respond Items', parameters: { respondWith: 'allEntries', options: {} } }
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
// ── Route 3: Toggle item completion ───────────────────────
|
|
332
|
-
const updateItem = node({
|
|
333
|
-
type: 'n8n-nodes-base.dataTable', version: 1.1,
|
|
334
|
-
config: { name: 'Update Item', parameters: { resource: 'row', operation: 'update', dataTableId: { __rl: true, mode: 'name', value: 'items' }, matchingColumns: ['id'], columns: { mappingMode: 'defineBelow', value: { id: expr('{{ $json.body.id }}'), completed: expr('{{ $json.body.completed }}') }, schema: [{ id: 'id', displayName: 'id', required: false, defaultMatch: true, display: true, type: 'string', canBeUsedToMatch: true }, { id: 'completed', displayName: 'completed', required: false, defaultMatch: false, display: true, type: 'boolean', canBeUsedToMatch: false }] }, options: {} } }
|
|
335
|
-
});
|
|
336
|
-
const respondToggle = node({
|
|
337
|
-
type: 'n8n-nodes-base.respondToWebhook', version: 1.1,
|
|
338
|
-
config: { name: 'Respond Toggle', parameters: { respondWith: 'allEntries', options: {} } }
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
// ── Route 4: Add new item ─────────────────────────────────
|
|
342
|
-
const insertItem = node({
|
|
343
|
-
type: 'n8n-nodes-base.dataTable', version: 1.1,
|
|
344
|
-
config: { name: 'Insert Item', parameters: { resource: 'row', operation: 'insert', dataTableId: { __rl: true, mode: 'name', value: 'items' }, columns: { mappingMode: 'defineBelow', value: { title: expr('{{ $json.body.title }}'), completed: false }, schema: [{ id: 'title', displayName: 'title', required: false, defaultMatch: false, display: true, type: 'string', canBeUsedToMatch: true }, { id: 'completed', displayName: 'completed', required: false, defaultMatch: false, display: true, type: 'boolean', canBeUsedToMatch: false }] }, options: {} } }
|
|
345
|
-
});
|
|
346
|
-
const respondAdd = node({
|
|
347
|
-
type: 'n8n-nodes-base.respondToWebhook', version: 1.1,
|
|
348
|
-
config: { name: 'Respond Add', parameters: { respondWith: 'allEntries', options: {} } }
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
// ── Wire it all together ──────────────────────────────────
|
|
352
|
-
export default workflow('id', 'Item Dashboard')
|
|
353
|
-
.add(pageWebhook).to(fetchAllItems).to(aggregateItems).to(buildPage).to(respondHtml)
|
|
354
|
-
.add(getItemsWebhook).to(fetchItemsJson).to(respondItems)
|
|
355
|
-
.add(toggleWebhook).to(updateItem).to(respondToggle)
|
|
356
|
-
.add(addWebhook).to(insertItem).to(respondAdd);
|
|
357
|
-
\`\`\`
|
|
358
|
-
|
|
359
|
-
**Key takeaway:** \`JSON.stringify(htmlTemplate)\` at build time produces a perfectly escaped JS string. The Code node's jsCode is just 4 lines. No escaping problems, no matter how large the HTML.
|
|
197
|
+
When the workflow serves HTML from a webhook (dashboards, admin UIs, custom forms), call \`templates(action="best-practices", technique="web_app")\` for the full file-based HTML pattern, data-injection recipe, multi-route architecture, and a complete multi-route dashboard example. Embedding large HTML inline in Code nodes breaks at ~20KB — always use the file-based pattern from the guide.
|
|
360
198
|
|
|
361
199
|
### Google Sheets — documentId and sheetName (RLC fields)
|
|
362
200
|
|
|
@@ -385,65 +223,88 @@ ${node_selection_1.CONNECTION_CHANGING_PARAMETERS}
|
|
|
385
223
|
|
|
386
224
|
### Baseline Flow Control Nodes
|
|
387
225
|
${node_selection_1.BASELINE_FLOW_CONTROL}`;
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
226
|
+
}
|
|
227
|
+
const BUILDER_SPECIFIC_PATTERNS_TOOL = buildBuilderSpecificPatterns('tool');
|
|
228
|
+
const BUILDER_SPECIFIC_PATTERNS_SANDBOX = buildBuilderSpecificPatterns('sandbox');
|
|
229
|
+
const SANDBOX_WORKFLOW_RULES = `Follow these rules strictly when generating workflows:
|
|
230
|
+
|
|
231
|
+
1. **Always use raw credential objects from \`credentials(action="list")\`**
|
|
232
|
+
- Wire credentials as \`{ id, name }\` objects returned by \`credentials(action="list")\`
|
|
233
|
+
- NEVER use placeholder strings, fake API keys, or hardcoded auth values
|
|
234
|
+
- Example: \`credentials: { slackApi: { id: 'yXYBqho73obh58ZS', name: 'Slack Bot' } }\`
|
|
235
|
+
- The key (e.g. \`slackApi\`) is the credential **type** from the node type definition
|
|
236
|
+
|
|
237
|
+
2. **Handle empty outputs with \`alwaysOutputData: true\`**
|
|
238
|
+
- Nodes that query data (Data Table get, Google Sheets lookup, HTTP Request, etc.) may return 0 items
|
|
239
|
+
- When a node returns 0 items, all downstream nodes are SKIPPED — the workflow chain breaks silently
|
|
240
|
+
- Set \`alwaysOutputData: true\` on any node whose output feeds downstream nodes and might return empty results
|
|
241
|
+
- Common cases: fresh/empty Data Tables, filtered queries, conditional lookups, API searches with no matches
|
|
242
|
+
- Example: \`config: { ..., alwaysOutputData: true }\`
|
|
243
|
+
|
|
244
|
+
3. **Use \`executeOnce: true\` for single-execution nodes**
|
|
245
|
+
- When a node receives N items but should only execute once (not N times), set \`executeOnce: true\`
|
|
246
|
+
- Common cases: sending a summary notification, generating a report, calling an API that doesn't need per-item execution
|
|
247
|
+
- Example: \`config: { ..., executeOnce: true }\``;
|
|
248
|
+
function composeSdkRulesAndPatterns(mode) {
|
|
249
|
+
const sandboxOverride = mode === 'sandbox'
|
|
250
|
+
? "> **Sandbox credential override**: The SDK pattern examples below use `newCredential('X')`. " +
|
|
251
|
+
"In sandbox mode, replace every `newCredential('X')` with the raw `{ id, name }` object from " +
|
|
252
|
+
'`credentials(action="list")`. `newCredential()` serializes to `undefined` in sandbox and will ' +
|
|
253
|
+
'silently drop credentials from the saved workflow.'
|
|
254
|
+
: null;
|
|
255
|
+
return [
|
|
256
|
+
SDK_CODE_RULES,
|
|
257
|
+
mode === 'sandbox' ? SANDBOX_WORKFLOW_RULES : sdk_reference_1.WORKFLOW_RULES,
|
|
258
|
+
...(sandboxOverride ? [sandboxOverride] : []),
|
|
259
|
+
'## SDK Patterns Reference\n\n' + sdk_reference_1.WORKFLOW_SDK_PATTERNS,
|
|
260
|
+
'## Expression Reference\n\n' + sdk_reference_1.EXPRESSION_REFERENCE,
|
|
261
|
+
'## Additional Functions\n\n' + sdk_reference_1.ADDITIONAL_FUNCTIONS,
|
|
262
|
+
'## Node-Specific Configuration Guides',
|
|
263
|
+
parameter_guides_1.IF_NODE_GUIDE.content,
|
|
264
|
+
parameter_guides_1.SWITCH_NODE_GUIDE.content,
|
|
265
|
+
parameter_guides_1.SET_NODE_GUIDE.content,
|
|
266
|
+
parameter_guides_1.HTTP_REQUEST_GUIDE.content,
|
|
267
|
+
parameter_guides_1.TOOL_NODES_GUIDE.content,
|
|
268
|
+
parameter_guides_1.EMBEDDING_NODES_GUIDE.content,
|
|
269
|
+
parameter_guides_1.RESOURCE_LOCATOR_GUIDE.content,
|
|
270
|
+
mode === 'sandbox' ? BUILDER_SPECIFIC_PATTERNS_SANDBOX : BUILDER_SPECIFIC_PATTERNS_TOOL,
|
|
271
|
+
].join('\n\n');
|
|
272
|
+
}
|
|
273
|
+
const SDK_RULES_AND_PATTERNS_TOOL = composeSdkRulesAndPatterns('tool');
|
|
274
|
+
const SDK_RULES_AND_PATTERNS_SANDBOX = composeSdkRulesAndPatterns('sandbox');
|
|
404
275
|
exports.BUILDER_AGENT_PROMPT = `You are an expert n8n workflow builder. You generate complete, valid TypeScript code using the @n8n/workflow-sdk.
|
|
405
276
|
|
|
406
|
-
|
|
407
|
-
- Your text output is visible to the user. Be concise but natural.
|
|
408
|
-
- Do NOT narrate your process ("I'll build this step by step", "Let me start by"). Just do the work.
|
|
409
|
-
- No emojis, no filler phrases, no markdown headers in your text output.
|
|
410
|
-
- When conversation context is provided, use it to continue naturally — do not repeat information the user already knows.
|
|
411
|
-
- Only output text for: errors that need attention, or a brief natural completion message.
|
|
277
|
+
${BUILDER_OUTPUT_DISCIPLINE}
|
|
412
278
|
|
|
413
279
|
## Repair Strategy
|
|
414
280
|
When called with failure details for an existing workflow, start from the pre-loaded code — do not re-discover node types already present.
|
|
415
281
|
|
|
416
282
|
## Escalation
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
283
|
+
${shared_prompts_1.ASK_USER_FALLBACK}
|
|
284
|
+
|
|
285
|
+
${shared_prompts_1.PLACEHOLDERS_RULE}
|
|
420
286
|
|
|
421
287
|
## Mandatory Process
|
|
422
288
|
1. **Research**: If the workflow fits a known category (notification, chatbot, scheduling, data_transformation, etc.), call \`nodes(action="suggested")\` first for curated recommendations. Then use \`nodes(action="search")\` for service-specific nodes (use short service names: "Gmail", "Slack", not "send email SMTP"). The results include \`discriminators\` (available resources and operations) for nodes that need them. Then call \`nodes(action="type-definition")\` with the appropriate resource/operation to get the TypeScript schema with exact parameter names and types. **Pay attention to @builderHint annotations** in search results and type definitions — they prevent common configuration mistakes.
|
|
423
289
|
2. **Build**: Write TypeScript SDK code and call \`build-workflow\`. Follow the SDK patterns below exactly.
|
|
424
290
|
3. **Fix errors**: If \`build-workflow\` returns errors, use **patch mode**: call \`build-workflow\` with \`patches\` (array of \`{old_str, new_str}\` replacements). Patches apply to your last submitted code, or auto-fetch from the saved workflow if \`workflowId\` is given. Much faster than resending full code.
|
|
425
291
|
4. **Modify existing workflows**: When updating a workflow, call \`build-workflow\` with \`workflowId\` + \`patches\`. The tool fetches the current code and applies your patches. Use \`workflows(action="get-as-code")\` first to see the current code if you need to identify what to replace.
|
|
426
|
-
|
|
292
|
+
5. **Done**: When \`build-workflow\` succeeds, output a brief, natural completion message.
|
|
427
293
|
|
|
428
|
-
Do NOT produce visible output until step
|
|
294
|
+
Do NOT produce visible output until step 5. All reasoning happens internally.
|
|
429
295
|
|
|
430
|
-
## Credential Rules
|
|
296
|
+
## Credential Rules (tool mode)
|
|
431
297
|
- Always use \`newCredential('Credential Name')\` for credentials, never fake keys or placeholders.
|
|
432
|
-
- NEVER use raw credential objects like \`{ id: '...', name: '...' }
|
|
298
|
+
- NEVER use raw credential objects like \`{ id: '...', name: '...' }\` — that form is for sandbox mode only.
|
|
433
299
|
- When editing a pre-loaded workflow, the roundtripped code may have credentials as raw objects — replace them with \`newCredential()\` calls.
|
|
434
300
|
- Unresolved credentials (where the user chose mock data or no credential is available) will be automatically mocked via pinned data at submit time. Always declare \`output\` on nodes that use credentials so mock data is available. The workflow will be testable via manual/test runs but not production-ready until real credentials are added.
|
|
435
301
|
|
|
436
|
-
${
|
|
302
|
+
${SDK_RULES_AND_PATTERNS_TOOL}
|
|
437
303
|
`;
|
|
438
304
|
function createSandboxBuilderAgentPrompt(workspaceRoot) {
|
|
439
305
|
return `You are an expert n8n workflow builder working inside a sandbox with real TypeScript tooling. You write workflow code as files and use \`tsc\` for validation.
|
|
440
306
|
|
|
441
|
-
|
|
442
|
-
- Your text output is visible to the user. Be concise but natural.
|
|
443
|
-
- Do NOT narrate your process ("I'll build this step by step", "Let me start by"). Just do the work.
|
|
444
|
-
- No emojis, no filler phrases, no markdown headers in your text output.
|
|
445
|
-
- When conversation context is provided, use it to continue naturally — do not repeat information the user already knows.
|
|
446
|
-
- Only output text for: errors that need attention, or a brief natural completion message.
|
|
307
|
+
${BUILDER_OUTPUT_DISCIPLINE}
|
|
447
308
|
|
|
448
309
|
## Workspace Layout
|
|
449
310
|
|
|
@@ -598,9 +459,9 @@ Replace \`CHUNK_WORKFLOW_ID\` with the actual ID returned by \`submit-workflow\`
|
|
|
598
459
|
- **Complex workflows** (5+ nodes, multiple integrations): Decompose into chunks.
|
|
599
460
|
Build, test, and compose. Each chunk is reusable across workflows.
|
|
600
461
|
|
|
601
|
-
|
|
462
|
+
${shared_prompts_1.PLACEHOLDERS_RULE}
|
|
602
463
|
|
|
603
|
-
|
|
464
|
+
## Setup Workflows (Create Missing Resources)
|
|
604
465
|
|
|
605
466
|
When \`nodes(action="explore-resources")\` returns no results for a required resource:
|
|
606
467
|
|
|
@@ -615,9 +476,7 @@ When \`nodes(action="explore-resources")\` returns no results for a required res
|
|
|
615
476
|
When called with failure details for an existing workflow, start from the pre-loaded code — do not re-discover node types already present.
|
|
616
477
|
|
|
617
478
|
## Escalation
|
|
618
|
-
|
|
619
|
-
- Do NOT retry the same failing approach more than twice — ask the user instead.
|
|
620
|
-
- ${PLACEHOLDER_ESCALATION}
|
|
479
|
+
${shared_prompts_1.ASK_USER_FALLBACK}
|
|
621
480
|
|
|
622
481
|
## Sandbox Isolation
|
|
623
482
|
|
|
@@ -635,9 +494,9 @@ When called with failure details for an existing workflow, start from the pre-lo
|
|
|
635
494
|
- **For large HTML, use the file-based pattern.** Write HTML to \`chunks/page.html\`, then \`readFileSync\` + \`JSON.stringify\` in your SDK code. NEVER embed large HTML directly in jsCode — it will break. See the web_app_pattern section.
|
|
636
495
|
- **Em-dash and Unicode**: the sandbox executes real JS so these technically work, but prefer plain hyphens for consistency with the shared SDK rules.
|
|
637
496
|
|
|
638
|
-
## Credentials
|
|
497
|
+
## Credentials (sandbox mode)
|
|
639
498
|
|
|
640
|
-
Call \`credentials(action="list")\` early. Each credential has an \`id\`, \`name\`, and \`type\`. Wire them into nodes like this:
|
|
499
|
+
Sandbox mode uses **raw credential objects** (not \`newCredential()\`). Call \`credentials(action="list")\` early. Each credential has an \`id\`, \`name\`, and \`type\`. Wire them into nodes like this:
|
|
641
500
|
|
|
642
501
|
\`\`\`typescript
|
|
643
502
|
credentials: {
|
|
@@ -683,8 +542,10 @@ n8n normalizes column names to snake_case (e.g., \`dayName\` → \`day_name\`).
|
|
|
683
542
|
|
|
684
543
|
4. **Resolve real resource IDs**: Check the node schemas from step 3 for parameters with \`searchListMethod\` or \`loadOptionsMethod\`. For EACH one, call \`nodes(action="explore-resources")\` with the node type, method name, and the matching credential from step 1 to discover real resource IDs.
|
|
685
544
|
- **This is mandatory for: calendars, spreadsheets, channels, folders, models, databases, and any other list-based parameter.** Do NOT assume values like "primary", "default", or "General" — always look up the real ID.
|
|
545
|
+
- **LLM models in particular** (OpenAI, Anthropic, Groq, etc.): always call \`explore-resources\` with the node's \`@searchListMethod\` when a credential for that provider is attached. The live list reflects what the credential can actually access — free/cheap tiers are often limited (e.g. an OpenAI free-tier key may only return \`gpt-5-mini\`). Picking a model ID that the credential can't access produces a broken workflow. The list is sorted newest-first; use the \`@builderHint\` as selection guidance (e.g. "prefer the GPT-5.4 family") over the live results, not as a hard-coded pick.
|
|
686
546
|
- Example: Google Calendar's \`calendar\` parameter uses \`searchListMethod: getCalendars\`. Call \`nodes(action="explore-resources")\` with \`methodName: "getCalendars"\` to get the actual calendar ID (e.g., "user@example.com"), not "primary".
|
|
687
547
|
- **Never use \`placeholder()\` or fake IDs for discoverable resources.** Create them via a setup workflow instead (see "Setup Workflows" section). For user-provided values, follow the placeholder rules in "SDK Code Rules".
|
|
548
|
+
- **If \`explore-resources\` returns more than one match and the user did not name a specific one, use \`placeholder('Select <resource>')\` for that parameter** (e.g. \`placeholder('Select a calendar')\`, \`placeholder('Select a Slack channel')\`). Picking one silently is a guess; the setup wizard surfaces placeholders so the user can choose after the build. Only pick a single match without prompting.
|
|
688
549
|
- If the resource can't be created via n8n (e.g., Slack channels), explain clearly in your summary what the user needs to set up.
|
|
689
550
|
|
|
690
551
|
5. **Write workflow code** to \`${workspaceRoot}/src/workflow.ts\`.
|
|
@@ -722,13 +583,21 @@ Follow the **Compositional Workflow Pattern** above. The process becomes:
|
|
|
722
583
|
Do NOT produce visible output until the final step. All reasoning happens internally.
|
|
723
584
|
|
|
724
585
|
## Modifying Existing Workflows
|
|
725
|
-
When modifying an existing workflow, the current code is **already pre-loaded** into \`${workspaceRoot}/src/workflow.ts\` with SDK imports.
|
|
726
|
-
|
|
586
|
+
When modifying an existing workflow, the current code is **already pre-loaded** into \`${workspaceRoot}/src/workflow.ts\` with SDK imports.
|
|
587
|
+
|
|
588
|
+
**Pre-flight check before any edit**: If the change introduces a node type not already in the file, or touches parameter values you haven't just looked up (model IDs, RLC values, enum selections, credential types, versions, etc.), call \`nodes(action="type-definition")\` first. Read \`@builderHint\`, \`@default\`, \`@searchListMethod\`, and \`@loadOptionsMethod\` from the output.
|
|
589
|
+
|
|
590
|
+
**Live credential-backed lookups are the source of truth for RLC/list parameters.** When a node exposes \`@searchListMethod\` or \`@loadOptionsMethod\` and a credential for its type is attached, call \`nodes(action="explore-resources")\` to query what the credential can actually access — don't rely on \`@default\` or memory. Treat \`@builderHint\` as *selection guidance over the live list* ("prefer the GPT-5.4 family", "prefer the most recent Sonnet") rather than as the source of the value itself. When no credential is attached, fall back to \`@default\`. If the hint and \`@default\` disagree on the fallback, prefer the hint — it's curated more actively.
|
|
591
|
+
|
|
592
|
+
Do not guess method names for \`explore-resources\`, and do not fill parameter values in from memory, even when the node or parameter feels familiar. This applies to swaps (Anthropic → OpenAI), model changes, trigger changes, and any parameter whose allowed values are unclear.
|
|
593
|
+
|
|
594
|
+
Steps:
|
|
595
|
+
- Read the current code with \`read_file\`
|
|
727
596
|
- Edit using \`edit_file\` for targeted changes or \`write_file\` for full rewrites (always use absolute paths)
|
|
728
597
|
- Run tsc → submit-workflow with the \`workflowId\`
|
|
729
598
|
- Do NOT call \`workflows(action="get-as-code")\` — the file is already populated
|
|
730
599
|
|
|
731
|
-
${
|
|
600
|
+
${SDK_RULES_AND_PATTERNS_SANDBOX}
|
|
732
601
|
`;
|
|
733
602
|
}
|
|
734
603
|
//# sourceMappingURL=build-workflow-agent.prompt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-workflow-agent.prompt.js","sourceRoot":"","sources":["../../../src/tools/orchestration/build-workflow-agent.prompt.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"build-workflow-agent.prompt.js","sourceRoot":"","sources":["../../../src/tools/orchestration/build-workflow-agent.prompt.ts"],"names":[],"mappings":";;;AAqWA,0EA0SC;AAvoBD,+FAQkE;AAClE,6EAIkD;AAClD,2EAKiD;AAEjD,+DAAkF;AAIlF,MAAM,yBAAyB,GAAG;;;;;;;;;;;;;;;;;;0GAkBwE,CAAC;AAI3G,MAAM,cAAc,GAAG;;;;;;;;;;qFAU8D,CAAC;AAKtF,SAAS,4BAA4B,CAAC,IAAwB;IAC7D,MAAM,iBAAiB,GACtB,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,0CAA0C,CAAC,CAAC,CAAC,yBAAyB,CAAC;IAC7F,OAAO;;;;;;;;;;;;;;;;;;;;;gCAqBwB,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6J/C,iCAAgB;;;EAGhB,+CAA8B;;;EAG9B,sCAAqB,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,8BAA8B,GAAG,4BAA4B,CAAC,MAAM,CAAC,CAAC;AAC5E,MAAM,iCAAiC,GAAG,4BAA4B,CAAC,SAAS,CAAC,CAAC;AAOlF,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;qDAkBsB,CAAC;AAEtD,SAAS,0BAA0B,CAAC,IAAwB;IAM3D,MAAM,eAAe,GACpB,IAAI,KAAK,SAAS;QACjB,CAAC,CAAC,8FAA8F;YAC/F,8FAA8F;YAC9F,gGAAgG;YAChG,oDAAoD;QACrD,CAAC,CAAC,IAAI,CAAC;IACT,OAAO;QACN,cAAc;QACd,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,8BAAc;QAC5D,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,+BAA+B,GAAG,qCAAqB;QACvD,6BAA6B,GAAG,oCAAoB;QACpD,6BAA6B,GAAG,oCAAoB;QACpD,uCAAuC;QACvC,gCAAa,CAAC,OAAO;QACrB,oCAAiB,CAAC,OAAO;QACzB,iCAAc,CAAC,OAAO;QACtB,qCAAkB,CAAC,OAAO;QAC1B,mCAAgB,CAAC,OAAO;QACxB,wCAAqB,CAAC,OAAO;QAC7B,yCAAsB,CAAC,OAAO;QAC9B,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,8BAA8B;KACvF,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAChB,CAAC;AAED,MAAM,2BAA2B,GAAG,0BAA0B,CAAC,MAAM,CAAC,CAAC;AACvE,MAAM,8BAA8B,GAAG,0BAA0B,CAAC,SAAS,CAAC,CAAC;AAIhE,QAAA,oBAAoB,GAAG;;EAElC,yBAAyB;;;;;;EAMzB,kCAAiB;;EAEjB,kCAAiB;;;;;;;;;;;;;;;;;EAiBjB,2BAA2B;CAC5B,CAAC;AAIF,SAAgB,+BAA+B,CAAC,aAAqB;IACpE,OAAO;;EAEN,yBAAyB;;;;0BAID,aAAa,6DAA6D,aAAa;;;EAG/G,aAAa;;;;;;;;;;;;;;;;;;KAkBV,aAAa;;;;;;;;;;;;;;;KAeb,aAAa;;;;;;;;;;;;;;;;;;;;;KAqBb,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAsDb,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwChB,kCAAiB;;;;;;;;;;;;;;;;;EAiBjB,kCAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sCA0DmB,aAAa;;;;;;;;;;;;;;kCAcjB,aAAa;;;;;;;;;;;;;;;;;;;;;;;;6BAwBlB,aAAa;;;;sCAIJ,aAAa;;;;;;;yFAOsC,aAAa;;;;;;;;;;;;;;EAcpG,8BAA8B;CAC/B,CAAC;AACF,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { BackgroundTaskResult, OrchestrationContext } from '../../types';
|
|
3
3
|
import { type SubmitWorkflowAttempt } from '../workflows/submit-workflow.tool';
|
|
4
|
+
export declare function recordSuccessfulWorkflowBuilds(tool: unknown, onWorkflowId: (workflowId: string) => void): void;
|
|
4
5
|
export declare function resultFromPostStreamError(input: {
|
|
5
6
|
error: unknown;
|
|
6
7
|
submitAttempts: SubmitWorkflowAttempt[];
|