diff --git a/packages/@n8n/instance-ai/docs/tools.md b/packages/@n8n/instance-ai/docs/tools.md index 8a286db1e5f..9cb5e9d3c2e 100644 --- a/packages/@n8n/instance-ai/docs/tools.md +++ b/packages/@n8n/instance-ai/docs/tools.md @@ -151,8 +151,22 @@ Run a built workflow with sidecar pin data for verification (never persisted). | Field | Type | Required | Description | |-------|------|----------|-------------| | `workItemId` | string | yes | Work item ID from build outcome | +| `workflowId` | string | yes | Workflow ID to execute | +| `inputData` | object | no | Trigger payload — **shape depends on trigger type**, see below | +| `timeout` | number | no | Max wait in ms (default 300000) | -**Returns**: `{ executionId, success, status, data?, error? }` +**`inputData` shape by trigger type** (the adapter's `getPinDataForTrigger` spreads or wraps based on type — passing the wrong shape produces null downstream values that look like an expression bug): + +| Trigger | Pass | Adapter emits on `$json` | +|---|---|---| +| Form Trigger | flat field map, e.g. `{name: "Alice", email: "a@b.c"}` | `{ submittedAt, formMode: "instanceAi", name, email, ... }` — matches production. Do NOT wrap in `formFields`. | +| Webhook | body payload, e.g. `{event: "signup", userId: "..."}` | `{ headers, query, body: { event, userId, ... } }` | +| Chat Trigger | `{chatInput: "..."}` | `{ sessionId, action, chatInput }` | +| Schedule | omit | synthetic timestamp fields | + +**Writes on success/failure**: the tool persists a structured `verification` record (`{ attempted, success, executionId, status, evidence, verifiedAt }`) onto the build outcome so subsequent checkpoint turns can reuse it without re-running verify. + +**Returns**: `{ executionId?, success, status?, data?, error? }` ### `report-verification-verdict` *(conditional)* diff --git a/packages/@n8n/instance-ai/src/agent/__tests__/instance-agent.test.ts b/packages/@n8n/instance-ai/src/agent/__tests__/instance-agent.test.ts index 5929e8c0e35..d6396277153 100644 --- a/packages/@n8n/instance-ai/src/agent/__tests__/instance-agent.test.ts +++ b/packages/@n8n/instance-ai/src/agent/__tests__/instance-agent.test.ts @@ -69,6 +69,9 @@ const { ToolSearchProcessor } = require('@mastra/core/processors') as { ToolSearchProcessor: jest.Mock; }; +const { Agent } = + // eslint-disable-next-line @typescript-eslint/no-require-imports + require('@mastra/core/agent') as { Agent: jest.Mock }; describe('createInstanceAgent', () => { it('creates a fresh deferred tool processor for each run-scoped toolset', async () => { @@ -106,4 +109,34 @@ describe('createInstanceAgent', () => { 'build-workflow-with-agent': { id: 'build-run-2' }, }); }); + + it('does not attach a workspace to the orchestrator Agent', async () => { + Agent.mockClear(); + const memoryConfig = { storage: { id: 'memory-store' } } as never; + const fakeWorkspace = { id: 'should-be-ignored' } as never; + + await createInstanceAgent({ + modelId: 'test-model', + context: { + runLabel: 'ws-test', + localGatewayStatus: undefined, + licenseHints: undefined, + localMcpServer: undefined, + }, + orchestrationContext: { + runId: 'ws-test', + browserMcpConfig: undefined, + workspace: fakeWorkspace, + }, + memoryConfig, + // Exercise the deprecated field to confirm it is ignored. + workspace: fakeWorkspace, + } as never); + + expect(Agent).toHaveBeenCalledTimes(1); + const calls = Agent.mock.calls as Array<[Record]>; + const firstCall = calls[0]; + expect(firstCall).toBeDefined(); + expect(firstCall[0]).not.toHaveProperty('workspace'); + }); }); diff --git a/packages/@n8n/instance-ai/src/agent/__tests__/system-prompt.test.ts b/packages/@n8n/instance-ai/src/agent/__tests__/system-prompt.test.ts index 7e19ac3a9ad..cdbd279566a 100644 --- a/packages/@n8n/instance-ai/src/agent/__tests__/system-prompt.test.ts +++ b/packages/@n8n/instance-ai/src/agent/__tests__/system-prompt.test.ts @@ -71,6 +71,115 @@ describe('getSystemPrompt', () => { }); }); + describe('replan branch — must take action', () => { + it('requires the orchestrator to take action rather than just acknowledge', () => { + const prompt = getSystemPrompt({}); + + expect(prompt).toMatch(/You MUST take action in this same turn/); + expect(prompt).toContain('awaiting_replan'); + expect(prompt).toMatch(/Do NOT reply with an acknowledgement or status update alone/); + expect(prompt).toContain('the thread will silently stall'); + }); + + it('lists both single-task (direct tool) and multi-task (create-tasks) routes', () => { + const prompt = getSystemPrompt({}); + + expect(prompt).toMatch(/handle a single simple task directly/); + expect(prompt).toMatch(/call `create-tasks` for multiple dependent tasks/); + }); + }); + + describe('When to Plan — what-am-I-touching axis', () => { + it('routes new/multi-workflow/data-table work through plan', () => { + const prompt = getSystemPrompt({}); + + expect(prompt).toContain('## When to Plan'); + expect(prompt).toMatch(/New workflow \(no `workflowId`\), multi-workflow build/); + expect(prompt).toMatch(/data tables created or schemas changed/); + }); + + it('routes existing-workflow edits through bypassPlan', () => { + const prompt = getSystemPrompt({}); + + expect(prompt).toMatch(/Any edit to an existing workflow that runs the builder/); + expect(prompt).toContain('`bypassPlan: true`'); + expect(prompt).toContain('existing `workflowId`'); + }); + + it('routes non-build ops through direct tools', () => { + const prompt = getSystemPrompt({}); + + expect(prompt).toMatch(/Non-build ops on an existing workflow/); + expect(prompt).toContain('The builder does not run.'); + }); + + it('routes replan follow-ups as routing, not re-planning', () => { + const prompt = getSystemPrompt({}); + + expect(prompt).toMatch(/Replan follow-up/); + expect(prompt).toMatch(/route, don't re-plan/); + }); + }); + + describe('post-build verify for bypassPlan', () => { + it('instructs the orchestrator to call verify-built-workflow on mockable triggers', () => { + const prompt = getSystemPrompt({}); + + expect(prompt).toContain('Post-build flow'); + expect(prompt).toContain('verify-built-workflow'); + expect(prompt).toContain('outcome.triggerNodes'); + expect(prompt).toContain('n8n-nodes-base.scheduleTrigger'); + expect(prompt).toContain('n8n-nodes-base.webhook'); + expect(prompt).toContain('@n8n/n8n-nodes-langchain.chatTrigger'); + expect(prompt).toContain('n8n-nodes-base.formTrigger'); + }); + + it('reads workflowId/workItemId from the outcome field, not result', () => { + const prompt = getSystemPrompt({}); + + expect(prompt).toContain('outcome.workflowId'); + expect(prompt).toContain('outcome.workItemId'); + expect(prompt).toMatch(/result.*only a short text summary/); + }); + + it('runs verify even when mocked credentials are present', () => { + const prompt = getSystemPrompt({}); + + expect(prompt).toMatch( + /Run verify even when `outcome\.mockedCredentialsByNode` is non-empty/, + ); + }); + }); + + describe('checkpoint branch — in-turn patch rule + retry carve-out', () => { + it('tells the orchestrator it may patch during a checkpoint and will re-enter the same checkpoint', () => { + const prompt = getSystemPrompt({}); + + expect(prompt).toContain('patch in place'); + expect(prompt).toMatch( + /you will receive another `` for the SAME checkpoint/, + ); + expect(prompt).toContain('re-verify'); + expect(prompt).toContain('complete-checkpoint'); + }); + + it('allows one more in-checkpoint patch if the first surfaced a new narrow bug', () => { + const prompt = getSystemPrompt({}); + + expect(prompt).toMatch(/call `complete-checkpoint`.*OR spawn one more in-checkpoint patch/); + expect(prompt).toMatch(/Keep the patch count small/); + expect(prompt).toMatch(/within two rounds/); + }); + + it('still warns not to end a checkpoint turn with an unsettled in-turn patch', () => { + const prompt = getSystemPrompt({}); + + expect(prompt).toMatch( + /Do NOT end a checkpoint turn that had an in-turn patch spawned without either calling `complete-checkpoint` on the next re-entry or spawning another bounded patch/, + ); + }); + }); + describe('multi-credential disambiguation guidance', () => { it('instructs the orchestrator to ask once when a service has more than one credential of the same type', () => { const prompt = getSystemPrompt({}); diff --git a/packages/@n8n/instance-ai/src/agent/instance-agent.ts b/packages/@n8n/instance-ai/src/agent/instance-agent.ts index fdfd64dfd95..5a58272e9a8 100644 --- a/packages/@n8n/instance-ai/src/agent/instance-agent.ts +++ b/packages/@n8n/instance-ai/src/agent/instance-agent.ts @@ -217,6 +217,18 @@ export async function createInstanceAgent(options: CreateInstanceAgentOptions): branchReadOnly: context.branchReadOnly, }); + // NOTE: we intentionally do NOT pass `workspace` to the orchestrator Agent. + // Mastra auto-registers `mastra_workspace_*` tools (execute_command, write_file, + // get_process_output, etc.) whenever a workspace is provided. The orchestrator + // has no legitimate need for them — it does not run commands or write files — + // and the LLM has been observed abusing `execute_command` as a `sleep` primitive + // and calling `get_process_output` with `build-*` task IDs that live in a + // different namespace than Mastra process PIDs. The workflow-builder subagent + // creates its own per-task sandbox via `builderSandboxFactory`; the + // `orchestrationContext.workspace` referenced by that factory is untouched. + // `options.workspace` is kept on the type as @deprecated for one release so + // external callers get a compile-time warning; it is otherwise ignored here. + const agent = new Agent({ id: 'n8n-instance-agent', name: 'n8n Instance Agent', @@ -231,7 +243,6 @@ export async function createInstanceAgent(options: CreateInstanceAgentOptions): tools: hasDeferrableTools ? coreTools : tracedOrchestratorTools, inputProcessors: toolSearchProcessor ? [toolSearchProcessor] : undefined, memory, - workspace: options.workspace, }); mergeTraceRunInputs( diff --git a/packages/@n8n/instance-ai/src/agent/system-prompt.ts b/packages/@n8n/instance-ai/src/agent/system-prompt.ts index d7b5cb91416..241e88dc886 100644 --- a/packages/@n8n/instance-ai/src/agent/system-prompt.ts +++ b/packages/@n8n/instance-ai/src/agent/system-prompt.ts @@ -189,11 +189,15 @@ You have access to workflow, execution, and credential tools plus a specialized ## When to Plan -1. **Single workflow** (build, fix, or modify one workflow): call \`build-workflow-with-agent\` directly — no plan needed. +Route by **what you are touching**, not by how risky the change feels: -2. **Multi-step work** (2+ tasks with dependencies — e.g. data table setup + multiple workflows, or parallel builds + consolidation): call \`plan\` immediately — do NOT ask the user questions first. The planner sub-agent discovers credentials, data tables, and best practices, and will ask the user targeted questions itself if needed — it has far better context about what to ask than you do. Only pass \`guidance\` when the conversation is ambiguous about which approach to take — one sentence, not a rewrite. When \`plan\` returns, tasks are already dispatched. +1. **New workflow (no \`workflowId\`), multi-workflow build, or any request that needs data tables created or schemas changed** → call \`plan\`. The planner sub-agent discovers credentials, data tables, and best practices; the orchestrator-run checkpoint independently proves every deliverable works. Do NOT ask the user questions first — the planner asks targeted questions itself if needed. Only pass \`guidance\` when the conversation is ambiguous. When \`plan\` returns, tasks are already dispatched. -3. **Replanning after failure** (\`\` arrived): inspect the failure details and remaining work. If only one simple task remains (e.g. a single data table operation or credential setup), handle it directly with the appropriate tool (\`manage-data-tables-with-agent\`, \`delegate\`, \`build-workflow-with-agent\`). Use \`create-tasks\` only when multiple dependent tasks still need scheduling — a runtime guard rejects \`create-tasks\` outside a replan context. If replanning is not appropriate, explain the blocker to the user. +2. **Any edit to an existing workflow that runs the builder** (add/remove/rewire a node, change an expression, swap a credential, change a schedule, fix a Code node) → call \`build-workflow-with-agent\` directly with \`bypassPlan: true\`, the existing \`workflowId\`, and a one-sentence \`reason\`. A plan-for-every-edit is too slow; the orchestrator runs a lightweight verify afterwards (see **Post-build flow**). + +3. **Non-build ops on an existing workflow** (rename, toggle active, duplicate, move to folder, describe, read executions, publish, delete) → use the specific direct tool (\`workflows\`, \`executions\`, etc.). The builder does not run. + +4. **Replan follow-up** (\`\`) → route, don't re-plan. If one simple task remains (e.g. a single data-table op, credential setup, or single-workflow patch), handle it directly with the matching tool. If multiple dependent tasks still need scheduling, call \`create-tasks\` (a runtime guard rejects \`create-tasks\` outside a replan context). If nothing sensible remains, explain the blocker to the user. **Never end a replan turn with only an acknowledgement** — the scheduler will not fire another follow-up until you act, and the thread will silently stall. Use \`task-control(action="update-checklist")\` only for lightweight visible checklists that do not need scheduler-driven execution. @@ -207,7 +211,7 @@ When \`credentials(action="setup")\` returns \`needsBrowserSetup=true\`, call \` Never use \`delegate\` to build, patch, fix, or update workflows — delegate does not have access to the builder sandbox, verification, or submit tools. -To fix or modify an existing workflow, use a \`build-workflow\` task (via \`plan\` if multi-step, or \`build-workflow-with-agent\` directly if single) with the existing workflow ID and a spec describing what to change. +To edit an existing workflow, call \`build-workflow-with-agent\` directly with \`bypassPlan: true\`, the existing \`workflowId\`, a one-sentence \`reason\`, and a \`task\` spec describing what to change. The orchestrator verifies the result afterwards via \`verify-built-workflow\` when the trigger is mockable (see **Post-build flow**). Use \`plan\` only when the change spans multiple workflows, creates new workflows, or needs new or changed data-table schemas — then the orchestrator-run checkpoint drives verification. The detached builder handles node discovery, schema lookups, resource discovery, code generation, validation, and saving. Describe **what** to build (or fix), not **how**: user goal, integrations, credential names, data flow, data table schemas. Don't specify node types or parameter configurations. Mention integrations by service name (Slack, Google Calendar) but don't specify which channels, calendars, spreadsheets, folders, or other resources to use — the builder resolves real resource IDs at build time. @@ -225,11 +229,13 @@ Always pass \`conversationContext\` when spawning background agents (\`build-wor ${SECRET_ASK_GUARDRAIL} -**Post-build flow** (for direct builds via \`build-workflow-with-agent\`): -1. Builder finishes → check if the workflow has mocked credentials, missing parameters, unresolved placeholders, or unconfigured triggers. -2. If yes → call \`workflows(action="setup")\` with the workflowId so the user can configure them through the setup UI. +**Post-build flow** (for direct \`build-workflow-with-agent\` calls with \`bypassPlan: true\` — plan-driven builds handle their own setup/verify flow via the checkpoint): +1. Builder finishes → read \`outcome.workflowId\`, \`outcome.workItemId\`, and \`outcome.triggerNodes\` from the \`\` payload's \`outcome\` field (the \`result\` field is only a short text summary). If \`outcome\` is missing, the build did not submit — skip to step 2. + - If any \`outcome.triggerNodes[*].nodeType\` matches \`n8n-nodes-base.scheduleTrigger\`, \`n8n-nodes-base.webhook\`, \`@n8n/n8n-nodes-langchain.chatTrigger\`, or \`n8n-nodes-base.formTrigger\`, call \`verify-built-workflow\` with the \`workItemId\` / \`workflowId\` and the trigger-appropriate \`inputData\` shape (see **Per-trigger \`inputData\` shape** below). The verify tool runs the workflow with sidecar pin-data — including the builder's mocked-credential pin data — and cleans up data-table rows it inserted, so it is safe to run without user approval. Run verify even when \`outcome.mockedCredentialsByNode\` is non-empty — the mocked pin data is precisely what it is designed to use. + - Skip verify only when: \`outcome.workflowId\` or \`outcome.workItemId\` is missing; \`outcome.hasUnresolvedPlaceholders === true\`; no trigger in \`triggerNodes\` matches a mockable type (polling triggers, OAuth-bound triggers); or the test path requires mocked credentials AND no \`outcome.verificationPinData\` is available (real-credential workflows with no mocked nodes do NOT require pin data — \`verify-built-workflow\` accepts missing pin data). +2. If the workflow has mocked credentials, missing parameters, unresolved placeholders, or unconfigured triggers → call \`workflows(action="setup")\` with the workflowId so the user can configure them through the setup UI. 3. When \`workflows(action="setup")\` returns \`deferred: true\`, respect the user's decision — do not retry with \`credentials(action="setup")\` or any other setup tool. The user chose to set things up later. -4. Ask the user if they want to test the workflow. +4. Ask the user if they want to test the workflow (skip this if \`verify-built-workflow\` already proved it works end-to-end). 5. Only call \`workflows(action="publish")\` when the user explicitly asks to publish. Never publish automatically. ## Tool Usage @@ -303,17 +309,29 @@ Working memory persists across all your conversations with this user. Keep it fo When \`plan\` or \`create-tasks\` returns, tasks are already running. Write one short sentence acknowledging the work, then end your turn. Do not summarize — the user already approved the plan. Wait for \`\` to arrive; do not invent synthetic follow-up turns. +**Never poll and never sleep.** Background tasks (\`build-workflow-with-agent\`, \`manage-data-tables-with-agent\`, \`research-with-agent\`, \`delegate\`) settle via \`\` turns that arrive automatically when work finishes. After you spawn or acknowledge one, end your turn. Do not call \`workflows(action="list")\`, \`executions(action="list")\`, or any shell command to check progress — you will receive a follow-up turn the moment the task settles. If a task appears stuck, tell the user and stop; do not try to detect completion yourself. Do not re-dispatch a build whose task ID is already visible in \`\` — a duplicate call is rejected with a \`Build already in progress\` message. + When \`\` context is present, use it only to reference active task IDs for cancellation or corrections. -When \`\` is present, all planned tasks completed successfully. Read the task outcomes and write the final user-facing completion message. Do not create another plan. +When \`\` is present, all planned tasks completed successfully. Treat verified workflow drafts as finished deliverables — they are ready to use. Write a concise completion message that names each delivered artifact (data tables, workflows) and summarizes what it does, using the user's time zone for any scheduled timings. Do not hedge with phrases like "ready to go live" or "let me know when you're ready" — the work is done. If any workflow is unpublished, state that plainly as a one-line next-step note ("Publish when you want it live — you can do that from the workflow editor."), not as a gating condition. Do not create another plan. -When \`\` is present, a planned task failed — apply the replanning branch from \`## When to Plan\` above. +When \`\` is present, a planned task failed and the graph is in \`awaiting_replan\`. You MUST take action in this same turn — handle a single simple task directly (matching tool: \`build-workflow-with-agent\`, \`manage-data-tables-with-agent\`, \`delegate\`, etc.), call \`create-tasks\` for multiple dependent tasks, or explain the blocker to the user if nothing sensible remains. Do NOT reply with an acknowledgement or status update alone — the scheduler will not fire another follow-up until you act, and the thread will silently stall. Apply the replan branch from \`## When to Plan\` above. + +When \`\` is present, the block contains exactly one checkpoint task (\`checkpoint.id\`, \`checkpoint.title\`, \`checkpoint.instructions\`, and \`checkpoint.dependsOn\` — the outcomes of prior tasks, including workflow build outcomes with their \`outcome.workItemId\` / \`outcome.workflowId\`). **Always run your own verification — never trust the builder's self-report.** The builder's \`outcome.verification\` is observability metadata, not checkpoint evidence. The checkpoint exists precisely because the builder is a sub-agent whose claims (especially "I verified it works") must be independently proven. Execute \`checkpoint.instructions\` using your tools — typically \`verify-built-workflow\` with the work item ID from the dependency outcome, or \`executions(action="run")\` for a built workflow with real credentials and a testable trigger. Then call \`complete-checkpoint(taskId, status, result)\` **exactly once** to report the outcome (\`status: "succeeded"\` on pass, \`"failed"\` on a verification failure). Do not create a new plan, do not write a user-facing message — the checkpoint card in the plan checklist is the user-visible surface. End your turn as soon as \`complete-checkpoint\` returns. When \`\` is present, a detached background task (builder, research, data-tables agent) finished. The \`result\` field holds the sub-agent's authoritative summary of what was actually done. **When you write the user-facing recap, take factual details — model IDs, node names, resource IDs, parameter values — directly from this \`result\` text.** Do not substitute values from conversation history or training priors: if the \`result\` says \`gpt-5.4-mini\`, write \`gpt-5.4-mini\`, not "GPT-4o mini" or any other name you associate with the provider. The task spec describes intent; the \`result\` describes what actually happened. -If the user sends a correction while a build is running, call \`task-control(action="correct-task")\` with the task ID and correction. +**If your verification surfaced a bug you can patch in place** (e.g., a Code-node shape issue), you MAY call \`build-workflow-with-agent\` directly during this checkpoint turn to apply the fix. When the patch builder settles, you will receive another \`\` for the SAME checkpoint — re-verify, then on the next re-entry either call \`complete-checkpoint\` (succeeded / failed) OR spawn one more in-checkpoint patch when the first surfaced a new narrow bug. Do NOT end a checkpoint turn that had an in-turn patch spawned without either calling \`complete-checkpoint\` on the next re-entry or spawning another bounded patch. Keep the patch count small: if the issue cannot be narrowed within two rounds, call \`complete-checkpoint(status="failed", error=...)\` with a summary of what remains and let replan take over. -## Sandbox (Code Execution) +### Per-trigger \`inputData\` shape -When available, \`mastra_workspace_execute_command\` runs shell commands in a persistent isolated sandbox. Use it for code execution, package installation, file processing. The sandbox cannot access the n8n host filesystem — use tool calls for n8n data.`; +Used by both the checkpoint verification path and the bypassPlan post-build verify step. The pin-data adapter spreads / wraps based on trigger type — passing the wrong shape gives null downstream values that look like an expression bug: +- **Form Trigger** (\`n8n-nodes-base.formTrigger\`) — flat field map, e.g. \`{name: "Alice", email: "a@b.c"}\`. The production Form Trigger emits each field directly on \`$json\`, so the builder's \`$json.\` expressions are correct. **Do NOT wrap in \`formFields\`** — the adapter will reject the call. +- **Webhook** (\`n8n-nodes-base.webhook\`) — the body payload, e.g. \`{event: "signup", userId: "..."}\`. The adapter wraps it under \`body\`, so downstream nodes reference \`$json.body.\`. +- **Chat Trigger** (\`@n8n/n8n-nodes-langchain.chatTrigger\`) — \`{chatInput: "user message"}\`. +- **Schedule Trigger** (\`n8n-nodes-base.scheduleTrigger\`) — omit \`inputData\`; the adapter emits synthetic timestamp fields. + +**Do not patch a workflow first when verify returns null downstream values.** Re-run verify with the corrected \`inputData\` shape. Only patch the workflow if the expression is wrong against the *production* trigger output shape (consult node descriptions), not the \`instanceAi\` pin data path. + +If the user sends a correction while a build is running, call \`task-control(action="correct-task")\` with the task ID and correction.`; } diff --git a/packages/@n8n/instance-ai/src/constants/model-settings.ts b/packages/@n8n/instance-ai/src/constants/model-settings.ts new file mode 100644 index 00000000000..e644d05fd1a --- /dev/null +++ b/packages/@n8n/instance-ai/src/constants/model-settings.ts @@ -0,0 +1,11 @@ +/** + * Per-agent sampling temperature. + * + * Lower values make the model more deterministic. Agents that emit + * structured output (e.g. workflow SDK code) run colder so "creative" + * token choices don't translate into broken artifacts. + */ +export const TEMPERATURE = { + /** Workflow builder — emits strict workflow SDK TypeScript. */ + BUILDER: 0.2, +} as const; diff --git a/packages/@n8n/instance-ai/src/index.ts b/packages/@n8n/instance-ai/src/index.ts index 6477a06a4cc..771fd52d8fd 100644 --- a/packages/@n8n/instance-ai/src/index.ts +++ b/packages/@n8n/instance-ai/src/index.ts @@ -125,7 +125,10 @@ export type { } from './workflow-loop'; export { WorkflowLoopRuntime } from './workflow-loop/runtime'; export { PlannedTaskCoordinator } from './planned-tasks/planned-task-service'; -export { applyPlannedTaskPermissions } from './planned-tasks/planned-task-permissions'; +export { + applyPlannedTaskPermissions, + PLANNED_TASK_PERMISSION_OVERRIDES, +} from './planned-tasks/planned-task-permissions'; export type { InstanceAiContext, InstanceAiWorkflowService, @@ -152,6 +155,7 @@ export type { PlannedTaskService, OrchestrationContext, SpawnBackgroundTaskOptions, + SpawnBackgroundTaskResult, BackgroundTaskResult, InstanceAiToolTraceOptions, InstanceAiTraceContext, diff --git a/packages/@n8n/instance-ai/src/planned-tasks/__tests__/planned-task-service.test.ts b/packages/@n8n/instance-ai/src/planned-tasks/__tests__/planned-task-service.test.ts index 7c6899c6d65..e9efc0de72b 100644 --- a/packages/@n8n/instance-ai/src/planned-tasks/__tests__/planned-task-service.test.ts +++ b/packages/@n8n/instance-ai/src/planned-tasks/__tests__/planned-task-service.test.ts @@ -54,7 +54,7 @@ describe('PlannedTaskCoordinator', () => { }); describe('createPlan', () => { - it('saves a valid plan and returns graph', async () => { + it('saves a valid plan in awaiting_approval status and returns graph', async () => { const tasks = [makeTask({ id: 'a' }), makeTask({ id: 'b', deps: ['a'] })]; const result = await coordinator.createPlan('thread-1', tasks, { planRunId: 'run-1' }); @@ -63,7 +63,7 @@ describe('PlannedTaskCoordinator', () => { 'thread-1', expect.objectContaining({ planRunId: 'run-1', - status: 'active', + status: 'awaiting_approval', // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment tasks: expect.arrayContaining([ expect.objectContaining({ id: 'a', status: 'planned' }), @@ -71,7 +71,7 @@ describe('PlannedTaskCoordinator', () => { ]), }), ); - expect(result.status).toBe('active'); + expect(result.status).toBe('awaiting_approval'); expect(result.tasks).toHaveLength(2); }); @@ -106,6 +106,36 @@ describe('PlannedTaskCoordinator', () => { coordinator.createPlan('thread-1', tasks, { planRunId: 'run-1' }), ).rejects.toThrow('must include at least one tool'); }); + + it('accepts a checkpoint task that depends on a build-workflow task', async () => { + const tasks = [ + makeTask({ id: 'wf-1' }), + makeTask({ id: 'verify-1', kind: 'checkpoint', deps: ['wf-1'] }), + ]; + + const result = await coordinator.createPlan('thread-1', tasks, { planRunId: 'run-1' }); + + expect(result.tasks).toHaveLength(2); + }); + + it('throws when a checkpoint task has no deps', async () => { + const tasks = [makeTask({ id: 'verify-1', kind: 'checkpoint', deps: [] })]; + + await expect( + coordinator.createPlan('thread-1', tasks, { planRunId: 'run-1' }), + ).rejects.toThrow('must depend on at least one build-workflow task'); + }); + + it('throws when a checkpoint task depends only on non-build-workflow tasks', async () => { + const tasks = [ + makeTask({ id: 'dt-1', kind: 'manage-data-tables' }), + makeTask({ id: 'verify-1', kind: 'checkpoint', deps: ['dt-1'] }), + ]; + + await expect( + coordinator.createPlan('thread-1', tasks, { planRunId: 'run-1' }), + ).rejects.toThrow('must depend on at least one build-workflow task'); + }); }); describe('getGraph', () => { @@ -348,6 +378,239 @@ describe('PlannedTaskCoordinator', () => { }); }); + describe('markCheckpointSucceeded', () => { + it('transitions a running checkpoint to succeeded', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + tasks: [makeTaskRecord({ id: 'verify-1', kind: 'checkpoint', status: 'running' })], + }); + return await Promise.resolve(updater(graph)); + }); + + const res = await coordinator.markCheckpointSucceeded('thread-1', 'verify-1', { + result: 'Verified', + }); + + expect(res.ok).toBe(true); + if (res.ok) { + expect(res.graph.tasks[0].status).toBe('succeeded'); + expect(res.graph.tasks[0].result).toBe('Verified'); + } + }); + + it('rejects when the target task is not found', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ tasks: [] }); + return await Promise.resolve(updater(graph)); + }); + + const res = await coordinator.markCheckpointSucceeded('thread-1', 'missing', {}); + + expect(res).toEqual({ ok: false, reason: 'not-found' }); + }); + + it('rejects when the target task is not a checkpoint', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + tasks: [makeTaskRecord({ id: 'task-1', kind: 'build-workflow', status: 'running' })], + }); + return await Promise.resolve(updater(graph)); + }); + + const res = await coordinator.markCheckpointSucceeded('thread-1', 'task-1', {}); + + expect(res).toEqual({ + ok: false, + reason: 'wrong-kind', + actual: { kind: 'build-workflow' }, + }); + }); + + it('rejects when the checkpoint is not in running state', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + tasks: [makeTaskRecord({ id: 'verify-1', kind: 'checkpoint', status: 'planned' })], + }); + return await Promise.resolve(updater(graph)); + }); + + const res = await coordinator.markCheckpointSucceeded('thread-1', 'verify-1', {}); + + expect(res).toEqual({ + ok: false, + reason: 'wrong-status', + actual: { status: 'planned' }, + }); + }); + }); + + describe('markCheckpointFailed', () => { + it('transitions a running checkpoint to failed with error', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + tasks: [makeTaskRecord({ id: 'verify-1', kind: 'checkpoint', status: 'running' })], + }); + return await Promise.resolve(updater(graph)); + }); + + const res = await coordinator.markCheckpointFailed('thread-1', 'verify-1', { + error: 'Workflow errored', + }); + + expect(res.ok).toBe(true); + if (res.ok) { + expect(res.graph.tasks[0].status).toBe('failed'); + expect(res.graph.tasks[0].error).toBe('Workflow errored'); + } + }); + + it('cancels dependent tasks on failure', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + tasks: [ + makeTaskRecord({ id: 'verify-1', kind: 'checkpoint', status: 'running' }), + makeTaskRecord({ + id: 'wf-2', + kind: 'build-workflow', + status: 'planned', + deps: ['verify-1'], + }), + ], + }); + return await Promise.resolve(updater(graph)); + }); + + const res = await coordinator.markCheckpointFailed('thread-1', 'verify-1', { + error: 'boom', + }); + + expect(res.ok).toBe(true); + if (res.ok) { + const wf2 = res.graph.tasks.find((t) => t.id === 'wf-2'); + expect(wf2?.status).toBe('cancelled'); + } + }); + + it('rejects when the target task is not a checkpoint', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + tasks: [makeTaskRecord({ id: 'task-1', kind: 'build-workflow', status: 'running' })], + }); + return await Promise.resolve(updater(graph)); + }); + + const res = await coordinator.markCheckpointFailed('thread-1', 'task-1', {}); + + expect(res).toEqual({ + ok: false, + reason: 'wrong-kind', + actual: { kind: 'build-workflow' }, + }); + }); + + it('persists the structured outcome on the failed checkpoint so replans keep execution context', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + tasks: [makeTaskRecord({ id: 'verify-1', kind: 'checkpoint', status: 'running' })], + }); + return await Promise.resolve(updater(graph)); + }); + + const res = await coordinator.markCheckpointFailed('thread-1', 'verify-1', { + error: 'Node crashed', + outcome: { + executionId: 'exec-42', + failureNode: 'Insert Row', + errorMessage: 'constraint violation', + }, + }); + + expect(res.ok).toBe(true); + if (res.ok) { + const failed = res.graph.tasks.find((t) => t.id === 'verify-1'); + expect(failed?.status).toBe('failed'); + expect(failed?.outcome).toEqual({ + executionId: 'exec-42', + failureNode: 'Insert Row', + errorMessage: 'constraint violation', + }); + } + }); + }); + + describe('revertCheckpointToPlanned', () => { + it('rewinds a running checkpoint to planned without touching dependents', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + tasks: [ + makeTaskRecord({ + id: 'verify-1', + kind: 'checkpoint', + status: 'running', + agentId: 'agent-race', + startedAt: 123, + }), + makeTaskRecord({ + id: 'wf-2', + kind: 'build-workflow', + status: 'planned', + deps: ['verify-1'], + }), + ], + }); + return await Promise.resolve(updater(graph)); + }); + + const res = await coordinator.revertCheckpointToPlanned('thread-1', 'verify-1'); + + expect(res.ok).toBe(true); + if (res.ok) { + const verify = res.graph.tasks.find((t) => t.id === 'verify-1'); + expect(verify?.status).toBe('planned'); + expect(verify?.agentId).toBeUndefined(); + expect(verify?.startedAt).toBeUndefined(); + // Dependents must remain untouched — scheduling race is not a failure. + const wf2 = res.graph.tasks.find((t) => t.id === 'wf-2'); + expect(wf2?.status).toBe('planned'); + expect(wf2?.error).toBeUndefined(); + } + }); + + it('rejects when the target task is not a checkpoint', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + tasks: [makeTaskRecord({ id: 'task-1', kind: 'build-workflow', status: 'running' })], + }); + return await Promise.resolve(updater(graph)); + }); + + const res = await coordinator.revertCheckpointToPlanned('thread-1', 'task-1'); + + expect(res).toEqual({ + ok: false, + reason: 'wrong-kind', + actual: { kind: 'build-workflow' }, + }); + }); + + it('rejects when the checkpoint is not running', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + tasks: [makeTaskRecord({ id: 'verify-1', kind: 'checkpoint', status: 'planned' })], + }); + return await Promise.resolve(updater(graph)); + }); + + const res = await coordinator.revertCheckpointToPlanned('thread-1', 'verify-1'); + + expect(res).toEqual({ + ok: false, + reason: 'wrong-status', + actual: { status: 'planned' }, + }); + }); + }); + describe('tick', () => { it('dispatches ready tasks with all deps satisfied', async () => { storage.update.mockImplementation(async (_threadId, updater) => { @@ -385,6 +648,92 @@ describe('PlannedTaskCoordinator', () => { expect(action.type).toBe('none'); }); + it('returns orchestrate-checkpoint when a checkpoint is ready', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + tasks: [ + makeTaskRecord({ id: 'wf-1', kind: 'build-workflow', status: 'succeeded' }), + makeTaskRecord({ + id: 'verify-1', + kind: 'checkpoint', + deps: ['wf-1'], + status: 'planned', + }), + ], + }); + return await Promise.resolve(updater(graph)); + }); + + const action = await coordinator.tick('thread-1'); + + expect(action.type).toBe('orchestrate-checkpoint'); + if (action.type === 'orchestrate-checkpoint') { + expect(action.tasks).toHaveLength(1); + expect(action.tasks[0].id).toBe('verify-1'); + } + }); + + it('emits a single checkpoint even when multiple are ready', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + tasks: [ + makeTaskRecord({ id: 'wf-1', kind: 'build-workflow', status: 'succeeded' }), + makeTaskRecord({ id: 'wf-2', kind: 'build-workflow', status: 'succeeded' }), + makeTaskRecord({ + id: 'verify-1', + kind: 'checkpoint', + deps: ['wf-1'], + status: 'planned', + }), + makeTaskRecord({ + id: 'verify-2', + kind: 'checkpoint', + deps: ['wf-2'], + status: 'planned', + }), + ], + }); + return await Promise.resolve(updater(graph)); + }); + + const action = await coordinator.tick('thread-1'); + + expect(action.type).toBe('orchestrate-checkpoint'); + if (action.type === 'orchestrate-checkpoint') { + expect(action.tasks).toHaveLength(1); + } + }); + + it('prefers an orchestrate-checkpoint over a background dispatch', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + tasks: [ + makeTaskRecord({ id: 'wf-1', kind: 'build-workflow', status: 'succeeded' }), + makeTaskRecord({ + id: 'verify-1', + kind: 'checkpoint', + deps: ['wf-1'], + status: 'planned', + }), + makeTaskRecord({ + id: 'wf-2', + kind: 'build-workflow', + deps: [], + status: 'planned', + }), + ], + }); + return await Promise.resolve(updater(graph)); + }); + + const action = await coordinator.tick('thread-1'); + + expect(action.type).toBe('orchestrate-checkpoint'); + if (action.type === 'orchestrate-checkpoint') { + expect(action.tasks[0].id).toBe('verify-1'); + } + }); + it('triggers replan when a task has failed', async () => { storage.update.mockImplementation(async (_threadId, updater) => { const graph = makeGraph({ @@ -466,4 +815,107 @@ describe('PlannedTaskCoordinator', () => { expect(storage.clear).toHaveBeenCalledWith('thread-1'); }); }); + + describe('approvePlan', () => { + it('transitions awaiting_approval → active', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ status: 'awaiting_approval' }); + return await Promise.resolve(updater(graph)); + }); + + const result = await coordinator.approvePlan('thread-1'); + + expect(result?.status).toBe('active'); + }); + + it('leaves an active graph untouched', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ status: 'active' }); + return await Promise.resolve(updater(graph)); + }); + + const result = await coordinator.approvePlan('thread-1'); + + expect(result?.status).toBe('active'); + }); + + it('does not resurrect a cancelled graph', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ status: 'cancelled' }); + return await Promise.resolve(updater(graph)); + }); + + const result = await coordinator.approvePlan('thread-1'); + + expect(result?.status).toBe('cancelled'); + }); + }); + + describe('tick on awaiting_approval graphs', () => { + it('returns none (never dispatches) when graph is awaiting_approval', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + status: 'awaiting_approval', + tasks: [makeTaskRecord({ id: 'a', status: 'planned' })], + }); + return await Promise.resolve(updater(graph)); + }); + + const action = await coordinator.tick('thread-1'); + + expect(action.type).toBe('none'); + }); + }); + + describe('revertToActive', () => { + it('flips an awaiting_replan graph back to active', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + status: 'awaiting_replan', + tasks: [makeTaskRecord({ id: 'a', status: 'failed', error: 'boom' })], + }); + return await Promise.resolve(updater(graph)); + }); + + const result = await coordinator.revertToActive('thread-1'); + + expect(result?.status).toBe('active'); + }); + + it('flips a completed graph back to active', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ + status: 'completed', + tasks: [makeTaskRecord({ id: 'a', status: 'succeeded' })], + }); + return await Promise.resolve(updater(graph)); + }); + + const result = await coordinator.revertToActive('thread-1'); + + expect(result?.status).toBe('active'); + }); + + it('leaves a cancelled graph untouched', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ status: 'cancelled' }); + return await Promise.resolve(updater(graph)); + }); + + const result = await coordinator.revertToActive('thread-1'); + + expect(result?.status).toBe('cancelled'); + }); + + it('leaves an active graph untouched', async () => { + storage.update.mockImplementation(async (_threadId, updater) => { + const graph = makeGraph({ status: 'active' }); + return await Promise.resolve(updater(graph)); + }); + + const result = await coordinator.revertToActive('thread-1'); + + expect(result?.status).toBe('active'); + }); + }); }); diff --git a/packages/@n8n/instance-ai/src/planned-tasks/planned-task-permissions.ts b/packages/@n8n/instance-ai/src/planned-tasks/planned-task-permissions.ts index 246aaedf221..e8cb2f25aa4 100644 --- a/packages/@n8n/instance-ai/src/planned-tasks/planned-task-permissions.ts +++ b/packages/@n8n/instance-ai/src/planned-tasks/planned-task-permissions.ts @@ -11,7 +11,7 @@ import type { InstanceAiContext, PlannedTaskKind } from '../types'; * Destructive actions (delete-data-table), open-ended actions (fetch-url, read-file), * and credential deletion are intentionally excluded — they always require explicit approval. */ -const PLANNED_TASK_PERMISSION_OVERRIDES: Partial< +export const PLANNED_TASK_PERMISSION_OVERRIDES: Partial< Record> > = { 'manage-data-tables': { @@ -23,6 +23,12 @@ const PLANNED_TASK_PERMISSION_OVERRIDES: Partial< runWorkflow: 'always_allow', publishWorkflow: 'always_allow', }, + // Checkpoint tasks run inside an orchestrator follow-up run. Plan approval + // authorizes the verification step, so the orchestrator can call + // verify-built-workflow / executions(action="run") without a second prompt. + checkpoint: { + runWorkflow: 'always_allow', + }, }; /** diff --git a/packages/@n8n/instance-ai/src/planned-tasks/planned-task-service.ts b/packages/@n8n/instance-ai/src/planned-tasks/planned-task-service.ts index 3780b52f6bc..dce1c597a13 100644 --- a/packages/@n8n/instance-ai/src/planned-tasks/planned-task-service.ts +++ b/packages/@n8n/instance-ai/src/planned-tasks/planned-task-service.ts @@ -1,5 +1,6 @@ import type { PlannedTaskStorage } from '../storage/planned-task-storage'; import type { + CheckpointSettleResult, PlannedTask, PlannedTaskGraph, PlannedTaskRecord, @@ -17,6 +18,7 @@ function validateDependencies(tasks: PlannedTask[]): void { } const knownIds = new Set(tasks.map((task) => task.id)); + const byId = new Map(tasks.map((task) => [task.id, task])); for (const task of tasks) { for (const depId of task.deps) { if (!knownIds.has(depId)) { @@ -26,11 +28,25 @@ function validateDependencies(tasks: PlannedTask[]): void { if (task.kind === 'delegate' && (!task.tools || task.tools.length === 0)) { throw new Error(`Delegate task "${task.id}" must include at least one tool`); } + if (task.kind === 'checkpoint') { + if (task.deps.length === 0) { + throw new Error( + `Checkpoint task "${task.id}" must depend on at least one build-workflow task`, + ); + } + const dependsOnBuildWorkflow = task.deps.some( + (depId) => byId.get(depId)?.kind === 'build-workflow', + ); + if (!dependsOnBuildWorkflow) { + throw new Error( + `Checkpoint task "${task.id}" must depend on at least one build-workflow task`, + ); + } + } } const visiting = new Set(); const visited = new Set(); - const byId = new Map(tasks.map((task) => [task.id, task])); const visit = (taskId: string) => { if (visited.has(taskId)) return; @@ -96,10 +112,13 @@ export class PlannedTaskCoordinator implements PlannedTaskService { ): Promise { validateDependencies(tasks); + // New plans start in awaiting_approval so tick() (which only acts on + // status==='active') cannot dispatch them before the user approves. + // Callers flip to 'active' via approvePlan() once approval is confirmed. const graph: PlannedTaskGraph = { planRunId: metadata.planRunId, messageGroupId: metadata.messageGroupId, - status: 'active', + status: 'awaiting_approval', tasks: tasks.map((task) => ({ ...task, status: 'planned', @@ -110,6 +129,22 @@ export class PlannedTaskCoordinator implements PlannedTaskService { return graph; } + /** + * Transition a graph from `awaiting_approval` → `active` after the user + * approves the plan. Callers (create-tasks, submit-plan) must invoke this + * before schedulePlannedTasks() so tick() can begin dispatching. No-op on + * any other status (a cancelled plan stays cancelled, an already-active + * plan doesn't regress). + */ + async approvePlan(threadId: string): Promise { + return await this.storage.update(threadId, (graph) => { + if (graph.status === 'awaiting_approval') { + return { ...graph, status: 'active' }; + } + return graph; + }); + } + async getGraph(threadId: string): Promise { return await this.storage.get(threadId); } @@ -185,6 +220,157 @@ export class PlannedTaskCoordinator implements PlannedTaskService { }); } + /** + * Guarded terminal transition for checkpoint tasks only. + * Rejects when the target is missing, not a checkpoint, or not running. + * Prevents accidental corruption of the graph via a wrong `taskId`. + */ + async markCheckpointSucceeded( + threadId: string, + taskId: string, + update: { result?: string; outcome?: Record; finishedAt?: number }, + ): Promise { + let result: CheckpointSettleResult = { ok: false, reason: 'not-found' }; + + await this.storage.update(threadId, (graph) => { + const task = graph.tasks.find((t) => t.id === taskId); + if (!task) { + result = { ok: false, reason: 'not-found' }; + return graph; + } + if (task.kind !== 'checkpoint') { + result = { ok: false, reason: 'wrong-kind', actual: { kind: task.kind } }; + return graph; + } + if (task.status !== 'running') { + result = { ok: false, reason: 'wrong-status', actual: { status: task.status } }; + return graph; + } + + const next = updateTaskRecord(graph, taskId, (t) => ({ + ...t, + status: 'succeeded', + result: update.result ?? t.result, + outcome: update.outcome ?? t.outcome, + finishedAt: update.finishedAt ?? Date.now(), + error: undefined, + })); + if (!next) { + result = { ok: false, reason: 'not-found' }; + return graph; + } + result = { ok: true, graph: next }; + return next; + }); + + return result; + } + + /** + * Rewind a running checkpoint back to `planned` so the next scheduler tick + * re-emits the same `orchestrate-checkpoint` action. Used by the service when + * `startInternalFollowUpRun` no-ops due to a scheduling race (another run + * became active between `markRunning` and the follow-up dispatch). Unlike + * `markCheckpointFailed` this does NOT cascade cancel to dependents — the + * checkpoint hasn't actually failed, it just lost a schedule slot and will + * run on the next tick. + */ + async revertCheckpointToPlanned( + threadId: string, + taskId: string, + ): Promise { + let result: CheckpointSettleResult = { ok: false, reason: 'not-found' }; + + await this.storage.update(threadId, (graph) => { + const task = graph.tasks.find((t) => t.id === taskId); + if (!task) { + result = { ok: false, reason: 'not-found' }; + return graph; + } + if (task.kind !== 'checkpoint') { + result = { ok: false, reason: 'wrong-kind', actual: { kind: task.kind } }; + return graph; + } + if (task.status !== 'running') { + result = { ok: false, reason: 'wrong-status', actual: { status: task.status } }; + return graph; + } + + const tasks = graph.tasks.map((t) => { + if (t.id !== taskId) return t; + const { agentId: _agentId, startedAt: _startedAt, ...rest } = t; + return { ...rest, status: 'planned' }; + }); + + const next: PlannedTaskGraph = { ...graph, tasks }; + result = { ok: true, graph: next }; + return next; + }); + + return result; + } + + async markCheckpointFailed( + threadId: string, + taskId: string, + update: { + error?: string; + /** Structured outcome (executionId, failureNode, etc.). Preserved on the + * failed task so replans have execution context, not just an error string. */ + outcome?: Record; + finishedAt?: number; + }, + ): Promise { + let result: CheckpointSettleResult = { ok: false, reason: 'not-found' }; + + await this.storage.update(threadId, (graph) => { + const task = graph.tasks.find((t) => t.id === taskId); + if (!task) { + result = { ok: false, reason: 'not-found' }; + return graph; + } + if (task.kind !== 'checkpoint') { + result = { ok: false, reason: 'wrong-kind', actual: { kind: task.kind } }; + return graph; + } + if (task.status !== 'running') { + result = { ok: false, reason: 'wrong-status', actual: { status: task.status } }; + return graph; + } + + const dependents = collectDependents(graph, taskId); + const finishedAt = update.finishedAt ?? Date.now(); + const failureError = update.error ?? task.error ?? 'Checkpoint failed'; + + const tasks = graph.tasks.map((t) => { + if (t.id === taskId) { + return { + ...t, + status: 'failed', + error: failureError, + outcome: update.outcome ?? t.outcome, + finishedAt, + }; + } + if (dependents.has(t.id) && (t.status === 'planned' || t.status === 'running')) { + return { + ...t, + status: 'cancelled', + error: `Cancelled: dependency "${taskId}" failed`, + finishedAt, + }; + } + return t; + }); + + const next: PlannedTaskGraph = { ...graph, tasks }; + result = { ok: true, graph: next }; + return next; + }); + + return result; + } + async markCancelled( threadId: string, taskId: string, @@ -254,6 +440,14 @@ export class PlannedTaskCoordinator implements PlannedTaskService { return graph; } + // Checkpoints run inline in the orchestrator (sequential, one per follow-up run). + // Give them priority over background dispatch to keep sequencing clean. + const readyCheckpoint = readyTasks.find((t) => t.kind === 'checkpoint'); + if (readyCheckpoint) { + action = { type: 'orchestrate-checkpoint', graph, tasks: [readyCheckpoint] }; + return graph; + } + action = { type: 'dispatch', graph, tasks: readyTasks.slice(0, availableSlots) }; return graph; }); @@ -265,4 +459,24 @@ export class PlannedTaskCoordinator implements PlannedTaskService { async clear(threadId: string): Promise { await this.storage.clear(threadId); } + + /** + * Revert the graph's status back to `active` when a pending follow-up action + * (replan or synthesize) couldn't be dispatched — typically because a user + * chat run was live at the moment the scheduler tried to start the internal + * follow-up. Without this, tick() returns `none` for non-active graphs and + * the follow-up is silently lost. The next tick sees the graph active again + * and re-emits the same action. + * + * Only transitions from `awaiting_replan` or `completed` — never from + * `cancelled` (a user-cancelled plan must stay cancelled). + */ + async revertToActive(threadId: string): Promise { + return await this.storage.update(threadId, (graph) => { + if (graph.status === 'awaiting_replan' || graph.status === 'completed') { + return { ...graph, status: 'active' }; + } + return graph; + }); + } } diff --git a/packages/@n8n/instance-ai/src/runtime/__tests__/background-task-manager.test.ts b/packages/@n8n/instance-ai/src/runtime/__tests__/background-task-manager.test.ts index 469dd278510..7e9470cc6e5 100644 --- a/packages/@n8n/instance-ai/src/runtime/__tests__/background-task-manager.test.ts +++ b/packages/@n8n/instance-ai/src/runtime/__tests__/background-task-manager.test.ts @@ -30,7 +30,7 @@ describe('BackgroundTaskManager', () => { it('spawns a task and tracks it as running', () => { const result = manager.spawn(makeSpawnOptions()); - expect(result).toBe(true); + expect(result.status).toBe('started'); expect(manager.getRunningTasks('thread-1')).toHaveLength(1); expect(manager.getRunningTasks('thread-1')[0].taskId).toBe('task-1'); }); @@ -50,7 +50,7 @@ describe('BackgroundTaskManager', () => { const result = manager.spawn(makeSpawnOptions({ taskId: 't4', onLimitReached })); - expect(result).toBe(false); + expect(result.status).toBe('limit-reached'); expect(onLimitReached).toHaveBeenCalledWith(expect.stringContaining('limit of 3')); }); @@ -170,6 +170,177 @@ describe('BackgroundTaskManager', () => { }); }); + describe('single-flight dedupe', () => { + it('returns duplicate when plannedTaskId matches a running task', () => { + const first = manager.spawn( + makeSpawnOptions({ + taskId: 'first', + run: async () => await new Promise(() => {}), + dedupeKey: { role: 'workflow-builder', plannedTaskId: 'planned-1' }, + }), + ); + expect(first.status).toBe('started'); + + const run = jest.fn(async (): Promise => await new Promise(() => {})); + const second = manager.spawn( + makeSpawnOptions({ + taskId: 'second', + run, + dedupeKey: { role: 'workflow-builder', plannedTaskId: 'planned-1' }, + }), + ); + + expect(second.status).toBe('duplicate'); + if (second.status === 'duplicate') { + expect(second.existing.taskId).toBe('first'); + } + expect(run).not.toHaveBeenCalled(); + expect(manager.getRunningTasks('thread-1')).toHaveLength(1); + }); + + it('allows a new spawn once the first planned-task settles', async () => { + const { promise, resolve } = createDeferred(); + manager.spawn( + makeSpawnOptions({ + taskId: 'first', + run: async () => await promise, + dedupeKey: { role: 'workflow-builder', plannedTaskId: 'planned-2' }, + }), + ); + + resolve('done'); + await flushPromises(); + + const second = manager.spawn( + makeSpawnOptions({ + taskId: 'second', + run: async () => await new Promise(() => {}), + dedupeKey: { role: 'workflow-builder', plannedTaskId: 'planned-2' }, + }), + ); + expect(second.status).toBe('started'); + }); + + it('returns duplicate when workflowId + role matches a running task without plannedTaskId', () => { + manager.spawn( + makeSpawnOptions({ + taskId: 'first', + run: async () => await new Promise(() => {}), + dedupeKey: { role: 'workflow-builder', workflowId: 'wf-1' }, + }), + ); + + const run = jest.fn(async (): Promise => await new Promise(() => {})); + const second = manager.spawn( + makeSpawnOptions({ + taskId: 'second', + run, + dedupeKey: { role: 'workflow-builder', workflowId: 'wf-1' }, + }), + ); + + expect(second.status).toBe('duplicate'); + expect(run).not.toHaveBeenCalled(); + }); + + it('does not collapse two distinct plannedTaskIds that target the same workflowId', () => { + // A planner may emit two work items for the same workflow — e.g., initial + // build (planned-A) followed by a patch (planned-B). They are distinct + // planned tasks and must both run; collapsing them on workflowId would + // skip work the user approved. + const first = manager.spawn( + makeSpawnOptions({ + taskId: 'task-A', + run: async () => await new Promise(() => {}), + dedupeKey: { + role: 'workflow-builder', + plannedTaskId: 'planned-A', + workflowId: 'wf-shared', + }, + }), + ); + expect(first.status).toBe('started'); + + const run = jest.fn(async (): Promise => await new Promise(() => {})); + const second = manager.spawn( + makeSpawnOptions({ + taskId: 'task-B', + run, + dedupeKey: { + role: 'workflow-builder', + plannedTaskId: 'planned-B', + workflowId: 'wf-shared', + }, + }), + ); + + expect(second.status).toBe('started'); + expect(run).toHaveBeenCalledTimes(1); + expect(manager.getRunningTasks('thread-1')).toHaveLength(2); + }); + + it('does not dedupe across roles for the same workflowId', () => { + manager.spawn( + makeSpawnOptions({ + taskId: 'builder', + role: 'workflow-builder', + run: async () => await new Promise(() => {}), + dedupeKey: { role: 'workflow-builder', workflowId: 'wf-1' }, + }), + ); + + const other = manager.spawn( + makeSpawnOptions({ + taskId: 'researcher', + role: 'web-researcher', + run: async () => await new Promise(() => {}), + dedupeKey: { role: 'web-researcher', workflowId: 'wf-1' }, + }), + ); + + expect(other.status).toBe('started'); + expect(manager.getRunningTasks('thread-1')).toHaveLength(2); + }); + + it('limit-reached still fires even when dedupe would have passed', () => { + const filler = makeSpawnOptions({ run: async () => await new Promise(() => {}) }); + manager.spawn({ ...filler, taskId: 't1' }); + manager.spawn({ ...filler, taskId: 't2' }); + manager.spawn({ ...filler, taskId: 't3' }); + + const onLimitReached = jest.fn(); + const result = manager.spawn( + makeSpawnOptions({ + taskId: 't4', + onLimitReached, + dedupeKey: { role: 'workflow-builder', plannedTaskId: 'planned-fresh' }, + }), + ); + expect(result.status).toBe('limit-reached'); + expect(onLimitReached).toHaveBeenCalled(); + }); + + it('cancelTask releases dedupe indices so a fresh spawn is allowed', () => { + manager.spawn( + makeSpawnOptions({ + taskId: 'first', + run: async () => await new Promise(() => {}), + dedupeKey: { role: 'workflow-builder', plannedTaskId: 'planned-3' }, + }), + ); + manager.cancelTask('thread-1', 'first'); + + const second = manager.spawn( + makeSpawnOptions({ + taskId: 'second', + run: async () => await new Promise(() => {}), + dedupeKey: { role: 'workflow-builder', plannedTaskId: 'planned-3' }, + }), + ); + expect(second.status).toBe('started'); + }); + }); + describe('queueCorrection', () => { it('queues correction for running task', () => { manager.spawn(makeSpawnOptions({ run: async () => await new Promise(() => {}) })); @@ -374,6 +545,70 @@ describe('BackgroundTaskManager', () => { expect(manager.getRunningTasks('thread-1')).toHaveLength(0); }); }); + + describe('getRunningTasksByParentCheckpoint', () => { + it('returns running tasks tagged with the given checkpoint id', () => { + manager.spawn( + makeSpawnOptions({ + taskId: 'child-1', + run: async () => await new Promise(() => {}), + parentCheckpointId: 'cp-verify-1', + }), + ); + manager.spawn( + makeSpawnOptions({ + taskId: 'child-2', + run: async () => await new Promise(() => {}), + parentCheckpointId: 'cp-verify-1', + }), + ); + manager.spawn( + makeSpawnOptions({ + taskId: 'unrelated', + run: async () => await new Promise(() => {}), + }), + ); + + const children = manager.getRunningTasksByParentCheckpoint('thread-1', 'cp-verify-1'); + expect(children.map((c) => c.taskId).sort()).toEqual(['child-1', 'child-2']); + }); + + it('excludes tasks tagged under a different checkpoint', () => { + manager.spawn( + makeSpawnOptions({ + taskId: 'child-a', + run: async () => await new Promise(() => {}), + parentCheckpointId: 'cp-A', + }), + ); + manager.spawn( + makeSpawnOptions({ + taskId: 'child-b', + run: async () => await new Promise(() => {}), + parentCheckpointId: 'cp-B', + }), + ); + + const childrenA = manager.getRunningTasksByParentCheckpoint('thread-1', 'cp-A'); + expect(childrenA.map((c) => c.taskId)).toEqual(['child-a']); + }); + + it('excludes tasks that have already settled', async () => { + const { promise, resolve } = createDeferred(); + manager.spawn( + makeSpawnOptions({ + taskId: 'child-done', + parentCheckpointId: 'cp-verify-1', + run: async () => await promise, + }), + ); + + resolve('done'); + await flushPromises(); + + expect(manager.getRunningTasksByParentCheckpoint('thread-1', 'cp-verify-1')).toHaveLength(0); + }); + }); }); describe('enrichMessageWithRunningTasks', () => { diff --git a/packages/@n8n/instance-ai/src/runtime/background-task-manager.ts b/packages/@n8n/instance-ai/src/runtime/background-task-manager.ts index edebd2ccd32..c8f22f6bd77 100644 --- a/packages/@n8n/instance-ai/src/runtime/background-task-manager.ts +++ b/packages/@n8n/instance-ai/src/runtime/background-task-manager.ts @@ -21,6 +21,25 @@ export interface ManagedBackgroundTask { plannedTaskId?: string; workItemId?: string; traceContext?: InstanceAiTraceContext; + /** Identity used for single-flight dedupe lookups; copied from the spawn options. */ + dedupeKey?: BackgroundTaskDedupeKey; + /** + * The checkpoint task id this background task was spawned under, when the + * orchestrator called a detached sub-agent tool inside a + * `` turn. The checkpoint safety + * net uses this to tell "orchestrator exited silently" apart from + * "orchestrator handed off to an in-flight patch builder". + */ + parentCheckpointId?: string; +} + +export interface BackgroundTaskDedupeKey { + /** Planned-task graph ID this background task is dispatched for. Primary dedupe key. */ + plannedTaskId?: string; + /** Target workflow ID for this background task. Fallback dedupe key when there is no planned task. */ + workflowId?: string; + /** Agent role (e.g. 'workflow-builder'). Scopes the workflowId fallback so different roles against the same workflow don't collide. */ + role: string; } export interface SpawnManagedBackgroundTaskOptions { @@ -33,6 +52,22 @@ export interface SpawnManagedBackgroundTaskOptions { plannedTaskId?: string; workItemId?: string; traceContext?: InstanceAiTraceContext; + /** + * Identity for single-flight dedupe. When supplied, a spawn with the same `plannedTaskId` + * (primary) or `role + workflowId` (fallback) as a currently-running task returns + * `{ status: 'duplicate', existing }` instead of launching a second task. + */ + dedupeKey?: BackgroundTaskDedupeKey; + /** + * Link this background task to a running checkpoint in the planned-task + * graph. Set when the orchestrator spawns a detached sub-agent (builder, + * research, data-table, delegate) from inside a + * `` turn. The post-run safety + * net defers failing the checkpoint while any child with this id is still + * running, and the settlement path re-emits the checkpoint follow-up when + * the last child settles. + */ + parentCheckpointId?: string; run: ( signal: AbortSignal, drainCorrections: () => string[], @@ -44,6 +79,11 @@ export interface SpawnManagedBackgroundTaskOptions { onSettled?: (task: ManagedBackgroundTask) => void | Promise; } +export type SpawnManagedBackgroundTaskResult = + | { status: 'started'; task: ManagedBackgroundTask } + | { status: 'limit-reached' } + | { status: 'duplicate'; existing: ManagedBackgroundTask }; + export interface BackgroundTaskMessageOptions< TTask extends ManagedBackgroundTask = ManagedBackgroundTask, > { @@ -52,9 +92,51 @@ export interface BackgroundTaskMessageOptions< export class BackgroundTaskManager { private readonly tasks = new Map(); + /** plannedTaskId → taskId for the currently-running task. Populated only when the caller provides a dedupeKey with plannedTaskId. */ + private readonly byPlannedTaskId = new Map(); + /** + * `${role}:${workflowId}` → taskId for the currently-running task. Only + * populated (and only consulted) when the caller provides a dedupeKey + * WITHOUT a plannedTaskId. When both keys are present we treat + * plannedTaskId as the canonical identity — two distinct planned tasks may + * legitimately target the same workflow (e.g., build + later patch) and + * must not collapse into each other. + */ + private readonly byRoleAndWorkflowId = new Map(); constructor(private readonly maxConcurrentPerThread = 5) {} + private workflowKey(role: string, workflowId: string): string { + return `${role}:${workflowId}`; + } + + private findDuplicate( + dedupeKey: BackgroundTaskDedupeKey | undefined, + ): ManagedBackgroundTask | undefined { + if (!dedupeKey) return undefined; + if (dedupeKey.plannedTaskId) { + // plannedTaskId is the canonical identity when present — we must NOT + // fall back to the workflowId index, otherwise distinct planned tasks + // targeting the same (role, workflowId) would falsely collapse. + const existingId = this.byPlannedTaskId.get(dedupeKey.plannedTaskId); + if (existingId) { + const existing = this.tasks.get(existingId); + if (existing && existing.status === 'running') return existing; + } + return undefined; + } + if (dedupeKey.workflowId) { + const existingId = this.byRoleAndWorkflowId.get( + this.workflowKey(dedupeKey.role, dedupeKey.workflowId), + ); + if (existingId) { + const existing = this.tasks.get(existingId); + if (existing && existing.status === 'running') return existing; + } + } + return undefined; + } + getTaskSnapshots(threadId: string): ManagedBackgroundTask[] { return [...this.tasks.values()].filter((task) => task.threadId === threadId); } @@ -65,6 +147,24 @@ export class BackgroundTaskManager { ); } + /** + * Return all running background tasks on this thread that were spawned + * under the given checkpoint task id. Used by the checkpoint safety net to + * defer failing a checkpoint while a detached patch/research/data-table + * sub-agent it just launched is still in-flight. + */ + getRunningTasksByParentCheckpoint( + threadId: string, + checkpointTaskId: string, + ): ManagedBackgroundTask[] { + return [...this.tasks.values()].filter( + (task) => + task.threadId === threadId && + task.status === 'running' && + task.parentCheckpointId === checkpointTaskId, + ); + } + queueCorrection( threadId: string, taskId: string, @@ -89,6 +189,7 @@ export class BackgroundTaskManager { task.abortController.abort(); task.status = 'cancelled'; this.tasks.delete(taskId); + this.releaseDedupeIndices(task); return task; } @@ -100,6 +201,7 @@ export class BackgroundTaskManager { task.status = 'cancelled'; cancelled.push(task); this.tasks.delete(taskId); + this.releaseDedupeIndices(task); } return cancelled; } @@ -110,17 +212,21 @@ export class BackgroundTaskManager { task.abortController.abort(); cancelled.push(task); this.tasks.delete(taskId); + this.releaseDedupeIndices(task); } return cancelled; } - spawn(options: SpawnManagedBackgroundTaskOptions): boolean { + spawn(options: SpawnManagedBackgroundTaskOptions): SpawnManagedBackgroundTaskResult { + const duplicate = this.findDuplicate(options.dedupeKey); + if (duplicate) return { status: 'duplicate', existing: duplicate }; + const runningCount = this.getRunningTasks(options.threadId).length; if (runningCount >= this.maxConcurrentPerThread) { options.onLimitReached?.( `Cannot start background task: limit of ${this.maxConcurrentPerThread} concurrent tasks reached. Wait for existing tasks to complete.`, ); - return false; + return { status: 'limit-reached' }; } const task: ManagedBackgroundTask = { @@ -137,11 +243,41 @@ export class BackgroundTaskManager { plannedTaskId: options.plannedTaskId, workItemId: options.workItemId, traceContext: options.traceContext, + dedupeKey: options.dedupeKey, + parentCheckpointId: options.parentCheckpointId, }; this.tasks.set(options.taskId, task); + if (options.dedupeKey?.plannedTaskId) { + this.byPlannedTaskId.set(options.dedupeKey.plannedTaskId, options.taskId); + } else if (options.dedupeKey?.workflowId) { + // Only index by (role, workflowId) when there is no plannedTaskId. + // Otherwise a later spawn for a different planned task targeting the + // same workflow would be wrongly matched against this one. + this.byRoleAndWorkflowId.set( + this.workflowKey(options.dedupeKey.role, options.dedupeKey.workflowId), + options.taskId, + ); + } void this.executeTask(task, options); - return true; + return { status: 'started', task }; + } + + private releaseDedupeIndices(task: ManagedBackgroundTask): void { + const key = task.dedupeKey; + if (!key) return; + if (key.plannedTaskId) { + if (this.byPlannedTaskId.get(key.plannedTaskId) === task.taskId) { + this.byPlannedTaskId.delete(key.plannedTaskId); + } + return; + } + if (key.workflowId) { + const wfKey = this.workflowKey(key.role, key.workflowId); + if (this.byRoleAndWorkflowId.get(wfKey) === task.taskId) { + this.byRoleAndWorkflowId.delete(wfKey); + } + } } private async executeTask( @@ -185,6 +321,7 @@ export class BackgroundTaskManager { } } finally { this.tasks.delete(task.taskId); + this.releaseDedupeIndices(task); } } } diff --git a/packages/@n8n/instance-ai/src/runtime/run-state-registry.ts b/packages/@n8n/instance-ai/src/runtime/run-state-registry.ts index 6bc26b97318..19b5a4cb02b 100644 --- a/packages/@n8n/instance-ai/src/runtime/run-state-registry.ts +++ b/packages/@n8n/instance-ai/src/runtime/run-state-registry.ts @@ -18,6 +18,10 @@ export interface SuspendedRunState extends ActiveRunState { toolCallId: string; requestId: string; createdAt: number; + /** Set when the suspended run was a planned-task checkpoint follow-up. + * Preserved across suspend/resume so the resumed run's finalizer can + * run the deadlock fallback and reschedule. */ + checkpoint?: { isCheckpointFollowUp: true; checkpointTaskId: string }; } export interface ConfirmationData { @@ -85,6 +89,9 @@ export class RunStateRegistry { private readonly runIdsByMessageGroup = new Map(); + /** IANA time zone captured at initial-run entry and reused by follow-up runs. */ + private readonly threadTimeZones = new Map(); + startRun(options: StartRunOptions): StartedRunState { const runId = `run_${nanoid()}`; const abortController = new AbortController(); @@ -270,6 +277,14 @@ export class RunStateRegistry { return this.threadResearchMode.get(threadId); } + setTimeZone(threadId: string, timeZone: string): void { + this.threadTimeZones.set(threadId, timeZone); + } + + getTimeZone(threadId: string): string | undefined { + return this.threadTimeZones.get(threadId); + } + /** * Find suspended runs and pending confirmations older than `maxAgeMs`. * Returns thread IDs and request IDs that should be cancelled/rejected. @@ -330,6 +345,7 @@ export class RunStateRegistry { this.threadUsers.delete(threadId); this.threadResearchMode.delete(threadId); + this.threadTimeZones.delete(threadId); const groupId = this.threadMessageGroupId.get(threadId); if (groupId) this.runIdsByMessageGroup.delete(groupId); @@ -354,6 +370,7 @@ export class RunStateRegistry { this.pendingConfirmations.clear(); this.threadUsers.clear(); this.threadResearchMode.clear(); + this.threadTimeZones.clear(); this.threadMessageGroupId.clear(); this.runIdsByMessageGroup.clear(); diff --git a/packages/@n8n/instance-ai/src/storage/__tests__/planned-task-storage.test.ts b/packages/@n8n/instance-ai/src/storage/__tests__/planned-task-storage.test.ts index 126ce609451..31eed2bd21b 100644 --- a/packages/@n8n/instance-ai/src/storage/__tests__/planned-task-storage.test.ts +++ b/packages/@n8n/instance-ai/src/storage/__tests__/planned-task-storage.test.ts @@ -1,70 +1,117 @@ import type { Memory } from '@mastra/memory'; +jest.mock('../thread-patch', () => ({ + patchThread: jest.fn(), +})); + import type { PlannedTaskGraph } from '../../types'; import { PlannedTaskStorage } from '../planned-task-storage'; +import { patchThread } from '../thread-patch'; -jest.mock('../thread-patch', () => ({ - patchThread: jest.fn( - ( - _memory: Memory, - opts: { - threadId: string; - update: (thread: { metadata?: Record }) => { - metadata: Record; - }; - }, - ) => { - const currentMetadata = metadataByThread.get(opts.threadId) ?? {}; - const next = opts.update({ metadata: currentMetadata }); - metadataByThread.set(opts.threadId, next.metadata); - }, - ), -})); - -const metadataByThread = new Map>(); +const mockedPatchThread = jest.mocked(patchThread); function makeMemory(): Memory { return { - getThreadById: jest.fn(({ threadId }: { threadId: string }) => ({ - id: threadId, - title: 'Test', - metadata: metadataByThread.get(threadId), - resourceId: 'res-1', - createdAt: new Date(), - updatedAt: new Date(), - })), + getThreadById: jest.fn(), } as unknown as Memory; } -function baseGraph(): PlannedTaskGraph { +function makeGraph(overrides: Partial = {}): PlannedTaskGraph { return { planRunId: 'run-1', status: 'active', tasks: [ { - id: 'task-1', - title: 'Build', + id: 'build-1', + title: 'Build workflow', kind: 'build-workflow', - spec: 'spec', + spec: 'Build it', deps: [], - status: 'running', + status: 'planned', + }, + { + id: 'verify-1', + title: "Verify 'build-1' workflow runs successfully", + kind: 'checkpoint', + spec: 'Call verify-built-workflow with the build outcome.', + deps: ['build-1'], + status: 'planned', }, ], + ...overrides, }; } describe('PlannedTaskStorage', () => { + let memory: Memory; + let storage: PlannedTaskStorage; + beforeEach(() => { - metadataByThread.clear(); + jest.clearAllMocks(); + memory = makeMemory(); + storage = new PlannedTaskStorage(memory); }); - it('round-trips a graph through save -> get', async () => { - const storage = new PlannedTaskStorage(makeMemory()); - const graph = baseGraph(); + describe('get() kind parsing', () => { + it('round-trips a graph containing a checkpoint task', async () => { + const graph = makeGraph(); + (memory.getThreadById as jest.Mock).mockResolvedValue({ + metadata: { instanceAiPlannedTasks: graph }, + }); - await storage.save('thread-1', graph); - const loaded = await storage.get('thread-1'); + const loaded = await storage.get('thread-1'); - expect(loaded?.tasks[0].id).toBe('task-1'); + expect(loaded).not.toBeNull(); + expect(loaded?.tasks.map((t) => t.kind)).toEqual(['build-workflow', 'checkpoint']); + const checkpoint = loaded?.tasks.find((t) => t.id === 'verify-1'); + expect(checkpoint?.kind).toBe('checkpoint'); + expect(checkpoint?.deps).toEqual(['build-1']); + }); + + it('returns null when the stored graph has an unknown kind', async () => { + (memory.getThreadById as jest.Mock).mockResolvedValue({ + metadata: { + instanceAiPlannedTasks: { + ...makeGraph(), + tasks: [ + { + id: 'x', + title: 'x', + kind: 'not-a-kind', + spec: '', + deps: [], + status: 'planned', + }, + ], + }, + }, + }); + + const loaded = await storage.get('thread-1'); + expect(loaded).toBeNull(); + }); + }); + + describe('update() kind parsing', () => { + it('persists updates that include checkpoint kind', async () => { + const graph = makeGraph(); + mockedPatchThread.mockImplementation(async (_mem, opts) => { + await Promise.resolve(); + opts.update({ + metadata: { instanceAiPlannedTasks: graph }, + } as unknown as Parameters[0]); + return null; + }); + + const result = await storage.update('thread-1', (g) => ({ + ...g, + tasks: g.tasks.map((t) => (t.id === 'verify-1' ? { ...t, status: 'running' as const } : t)), + })); + + expect(result).not.toBeNull(); + const checkpoint = result?.tasks.find((t) => t.id === 'verify-1'); + expect(checkpoint?.status).toBe('running'); + expect(checkpoint?.kind).toBe('checkpoint'); + }); }); }); diff --git a/packages/@n8n/instance-ai/src/storage/planned-task-storage.ts b/packages/@n8n/instance-ai/src/storage/planned-task-storage.ts index bc80efdb10d..2eccaf2baed 100644 --- a/packages/@n8n/instance-ai/src/storage/planned-task-storage.ts +++ b/packages/@n8n/instance-ai/src/storage/planned-task-storage.ts @@ -11,6 +11,7 @@ const plannedTaskKindSchema = z.enum([ 'build-workflow', 'manage-data-tables', 'research', + 'checkpoint', ]); const plannedTaskStatusSchema = z.enum(['planned', 'running', 'succeeded', 'failed', 'cancelled']); @@ -36,7 +37,7 @@ const plannedTaskRecordSchema = z.object({ const plannedTaskGraphSchema = z.object({ planRunId: z.string(), messageGroupId: z.string().optional(), - status: z.enum(['active', 'awaiting_replan', 'completed', 'cancelled']), + status: z.enum(['awaiting_approval', 'active', 'awaiting_replan', 'completed', 'cancelled']), tasks: z.array(plannedTaskRecordSchema), }); diff --git a/packages/@n8n/instance-ai/src/tools/__tests__/data-tables.tool.test.ts b/packages/@n8n/instance-ai/src/tools/__tests__/data-tables.tool.test.ts index ed23342d72d..9eb3469e83b 100644 --- a/packages/@n8n/instance-ai/src/tools/__tests__/data-tables.tool.test.ts +++ b/packages/@n8n/instance-ai/src/tools/__tests__/data-tables.tool.test.ts @@ -140,7 +140,9 @@ describe('data-tables tool', () => { noSuspendCtx(), ); - expect(context.dataTableService.getSchema).toHaveBeenCalledWith('dt-1'); + expect(context.dataTableService.getSchema).toHaveBeenCalledWith('dt-1', { + projectId: undefined, + }); expect(result).toEqual({ columns }); }); }); @@ -168,6 +170,7 @@ describe('data-tables tool', () => { filter, limit: 10, offset: 0, + projectId: undefined, }); expect(result).toEqual(queryResult); }); @@ -399,7 +402,9 @@ describe('data-tables tool', () => { const tool = createDataTablesTool(context); const result = await tool.execute!(deleteInput as never, noSuspendCtx()); - expect(context.dataTableService.delete).toHaveBeenCalledWith('dt-1'); + expect(context.dataTableService.delete).toHaveBeenCalledWith('dt-1', { + projectId: undefined, + }); expect(result).toEqual({ success: true }); }); @@ -409,7 +414,9 @@ describe('data-tables tool', () => { const tool = createDataTablesTool(context); const result = await tool.execute!(deleteInput as never, resumeCtx(true)); - expect(context.dataTableService.delete).toHaveBeenCalledWith('dt-1'); + expect(context.dataTableService.delete).toHaveBeenCalledWith('dt-1', { + projectId: undefined, + }); expect(result).toEqual({ success: true }); }); @@ -469,10 +476,11 @@ describe('data-tables tool', () => { const tool = createDataTablesTool(context); const result = await tool.execute!(addColumnInput as never, noSuspendCtx()); - expect(context.dataTableService.addColumn).toHaveBeenCalledWith('dt-1', { - name: 'age', - type: 'number', - }); + expect(context.dataTableService.addColumn).toHaveBeenCalledWith( + 'dt-1', + { name: 'age', type: 'number' }, + { projectId: undefined }, + ); expect(result).toEqual({ column }); }); @@ -542,7 +550,9 @@ describe('data-tables tool', () => { const tool = createDataTablesTool(context); const result = await tool.execute!(deleteColumnInput as never, noSuspendCtx()); - expect(context.dataTableService.deleteColumn).toHaveBeenCalledWith('dt-1', 'col-1'); + expect(context.dataTableService.deleteColumn).toHaveBeenCalledWith('dt-1', 'col-1', { + projectId: undefined, + }); expect(result).toEqual({ success: true }); }); @@ -552,7 +562,9 @@ describe('data-tables tool', () => { const tool = createDataTablesTool(context); const result = await tool.execute!(deleteColumnInput as never, resumeCtx(true)); - expect(context.dataTableService.deleteColumn).toHaveBeenCalledWith('dt-1', 'col-1'); + expect(context.dataTableService.deleteColumn).toHaveBeenCalledWith('dt-1', 'col-1', { + projectId: undefined, + }); expect(result).toEqual({ success: true }); }); @@ -614,6 +626,7 @@ describe('data-tables tool', () => { 'dt-1', 'col-1', 'full_name', + { projectId: undefined }, ); expect(result).toEqual({ success: true }); }); @@ -628,6 +641,7 @@ describe('data-tables tool', () => { 'dt-1', 'col-1', 'full_name', + { projectId: undefined }, ); expect(result).toEqual({ success: true }); }); @@ -689,6 +703,7 @@ describe('data-tables tool', () => { expect(context.dataTableService.insertRows).toHaveBeenCalledWith( 'dt-1', insertRowsInput.rows, + { projectId: undefined }, ); expect(result).toEqual({ insertedCount: 2 }); }); @@ -703,6 +718,7 @@ describe('data-tables tool', () => { expect(context.dataTableService.insertRows).toHaveBeenCalledWith( 'dt-1', insertRowsInput.rows, + { projectId: undefined }, ); expect(result).toEqual({ insertedCount: 2 }); }); @@ -789,6 +805,7 @@ describe('data-tables tool', () => { 'dt-1', updateRowsInput.filter, updateRowsInput.data, + { projectId: undefined }, ); expect(result).toEqual({ updatedCount: 5 }); }); @@ -804,6 +821,7 @@ describe('data-tables tool', () => { 'dt-1', updateRowsInput.filter, updateRowsInput.data, + { projectId: undefined }, ); expect(result).toEqual({ updatedCount: 3 }); }); @@ -900,6 +918,7 @@ describe('data-tables tool', () => { expect(context.dataTableService.deleteRows).toHaveBeenCalledWith( 'dt-1', deleteRowsInput.filter, + { projectId: undefined }, ); expect(result).toEqual({ success: true, @@ -925,6 +944,7 @@ describe('data-tables tool', () => { expect(context.dataTableService.deleteRows).toHaveBeenCalledWith( 'dt-1', deleteRowsInput.filter, + { projectId: undefined }, ); expect(result).toEqual({ success: true, diff --git a/packages/@n8n/instance-ai/src/tools/__tests__/executions.tool.test.ts b/packages/@n8n/instance-ai/src/tools/__tests__/executions.tool.test.ts index fd7ef278d96..953fcf3a3e4 100644 --- a/packages/@n8n/instance-ai/src/tools/__tests__/executions.tool.test.ts +++ b/packages/@n8n/instance-ai/src/tools/__tests__/executions.tool.test.ts @@ -279,6 +279,50 @@ describe('executions tool', () => { timeout: undefined, }); }); + + describe('allowedRunWorkflowIds scope', () => { + it('runs without HITL when always_allow + workflow id is in the allow-list', async () => { + const context = createMockContext({ + permissions: { runWorkflow: 'always_allow' }, + allowedRunWorkflowIds: new Set(['wf-1']), + }); + (context.executionService.run as jest.Mock).mockResolvedValue({ + executionId: 'exec-1', + status: 'success', + }); + const suspendFn = jest.fn(); + + const tool = createExecutionsTool(context); + await tool.execute!( + { action: 'run' as const, workflowId: 'wf-1' }, + createAgentCtx({ suspend: suspendFn }) as never, + ); + + expect(suspendFn).not.toHaveBeenCalled(); + expect(context.executionService.run).toHaveBeenCalledWith('wf-1', undefined, { + timeout: undefined, + }); + }); + + it('still requires HITL approval when always_allow is set but workflow id is NOT in the allow-list', async () => { + const context = createMockContext({ + permissions: { runWorkflow: 'always_allow' }, + allowedRunWorkflowIds: new Set(['wf-other']), + }); + (context.workflowService.get as jest.Mock).mockResolvedValue({ name: 'Off-scope WF' }); + const suspendFn = jest.fn(); + + const tool = createExecutionsTool(context); + const result = await tool.execute!( + { action: 'run' as const, workflowId: 'wf-1' }, + createAgentCtx({ suspend: suspendFn }) as never, + ); + + expect(suspendFn).toHaveBeenCalled(); + expect(context.executionService.run).not.toHaveBeenCalled(); + expect(result).toMatchObject({ denied: true, reason: 'Awaiting confirmation' }); + }); + }); }); // ── debug ─────────────────────────────────────────────────────────────── diff --git a/packages/@n8n/instance-ai/src/tools/data-tables.tool.ts b/packages/@n8n/instance-ai/src/tools/data-tables.tool.ts index 606ec024b6a..cdad5fb2ea6 100644 --- a/packages/@n8n/instance-ai/src/tools/data-tables.tool.ts +++ b/packages/@n8n/instance-ai/src/tools/data-tables.tool.ts @@ -66,19 +66,32 @@ function isNameConflictError(error: unknown): boolean { // ── Action schemas ───────────────────────────────────────────────────────── +const projectIdDescribe = + 'Project ID. For list/create, scopes the operation to this project (defaults to personal). For id-based actions (schema, query, delete, add-column, delete-column, rename-column, insert/update/delete-rows), disambiguates when `dataTableId` is a name that exists in multiple accessible projects. Ignored when `dataTableId` is a UUID; rejected when the UUID belongs to a different project.'; + const listAction = z.object({ action: z.literal('list').describe('List data tables in a project'), - projectId: z.string().optional().describe('Project ID. Defaults to personal project.'), + projectId: z.string().optional().describe(projectIdDescribe), }); const schemaAction = z.object({ action: z.literal('schema').describe('Get column definitions for a data table'), - dataTableId: z.string().describe('ID of the data table'), + dataTableId: z + .string() + .describe( + 'ID (UUID) of the data table. A name also works as a fallback, but pass an id when possible.', + ), + projectId: z.string().optional().describe(projectIdDescribe), }); const queryAction = z.object({ action: z.literal('query').describe('Query rows from a data table with optional filtering'), - dataTableId: z.string().describe('ID of the data table'), + dataTableId: z + .string() + .describe( + 'ID (UUID) of the data table. A name also works as a fallback, but pass an id when possible.', + ), + projectId: z.string().optional().describe(projectIdDescribe), filter: filterSchema.optional().describe('Row filter conditions'), limit: z .number() @@ -93,7 +106,7 @@ const queryAction = z.object({ const createAction = z.object({ action: z.literal('create').describe('Create a new data table with typed columns'), name: z.string().min(1).max(128).describe('Table name'), - projectId: z.string().optional().describe('Project ID. Defaults to personal project.'), + projectId: z.string().optional().describe(projectIdDescribe), columns: z .array( z.object({ @@ -107,32 +120,57 @@ const createAction = z.object({ const deleteAction = z.object({ action: z.literal('delete').describe('Permanently delete a data table and all its rows'), - dataTableId: z.string().describe('ID of the data table'), + dataTableId: z + .string() + .describe( + 'ID (UUID) of the data table. A name also works as a fallback, but pass an id when possible.', + ), + projectId: z.string().optional().describe(projectIdDescribe), }); const addColumnAction = z.object({ action: z.literal('add-column').describe('Add a new column to an existing data table'), - dataTableId: z.string().describe('ID of the data table'), + dataTableId: z + .string() + .describe( + 'ID (UUID) of the data table. A name also works as a fallback, but pass an id when possible.', + ), + projectId: z.string().optional().describe(projectIdDescribe), columnName: z.string().describe('Column name (alphanumeric + underscores)'), type: columnTypeSchema.describe('Column data type'), }); const deleteColumnAction = z.object({ action: z.literal('delete-column').describe('Remove a column from a data table'), - dataTableId: z.string().describe('ID of the data table'), + dataTableId: z + .string() + .describe( + 'ID (UUID) of the data table. A name also works as a fallback, but pass an id when possible.', + ), + projectId: z.string().optional().describe(projectIdDescribe), columnId: z.string().describe('ID of the column'), }); const renameColumnAction = z.object({ action: z.literal('rename-column').describe('Rename a column in a data table'), - dataTableId: z.string().describe('ID of the data table'), + dataTableId: z + .string() + .describe( + 'ID (UUID) of the data table. A name also works as a fallback, but pass an id when possible.', + ), + projectId: z.string().optional().describe(projectIdDescribe), columnId: z.string().describe('ID of the column'), newName: z.string().describe('New column name'), }); const insertRowsAction = z.object({ action: z.literal('insert-rows').describe('Insert rows into a data table'), - dataTableId: z.string().describe('ID of the data table'), + dataTableId: z + .string() + .describe( + 'ID (UUID) of the data table. A name also works as a fallback, but pass an id when possible.', + ), + projectId: z.string().optional().describe(projectIdDescribe), rows: z .array(z.record(z.unknown())) .min(1) @@ -142,7 +180,12 @@ const insertRowsAction = z.object({ const updateRowsAction = z.object({ action: z.literal('update-rows').describe('Update rows matching a filter in a data table'), - dataTableId: z.string().describe('ID of the data table'), + dataTableId: z + .string() + .describe( + 'ID (UUID) of the data table. A name also works as a fallback, but pass an id when possible.', + ), + projectId: z.string().optional().describe(projectIdDescribe), filter: filterSchema.describe('Row filter conditions'), data: z.record(z.unknown()).describe('Column values to set on matching rows'), }); @@ -153,7 +196,12 @@ const deleteRowsAction = z.object({ .describe( 'Delete rows matching a filter from a data table. At least one filter condition is required.', ), - dataTableId: z.string().describe('ID of the data table'), + dataTableId: z + .string() + .describe( + 'ID (UUID) of the data table. A name also works as a fallback, but pass an id when possible.', + ), + projectId: z.string().optional().describe(projectIdDescribe), filter: filterSchemaWithMinOne.describe('Row filter conditions'), }); @@ -190,7 +238,9 @@ async function handleSchema( context: InstanceAiContext, input: Extract, ) { - const columns = await context.dataTableService.getSchema(input.dataTableId); + const columns = await context.dataTableService.getSchema(input.dataTableId, { + projectId: input.projectId, + }); return { columns }; } @@ -202,6 +252,7 @@ async function handleQuery( filter: input.filter, limit: input.limit, offset: input.offset, + projectId: input.projectId, }); const returnedRows = result.data.length; @@ -301,7 +352,7 @@ async function handleDelete( } // State 3: Approved or always_allow — execute - await context.dataTableService.delete(input.dataTableId); + await context.dataTableService.delete(input.dataTableId, { projectId: input.projectId }); return { success: true }; } @@ -335,10 +386,11 @@ async function handleAddColumn( } // State 3: Approved or always_allow — execute - const column = await context.dataTableService.addColumn(input.dataTableId, { - name: input.columnName, - type: input.type, - }); + const column = await context.dataTableService.addColumn( + input.dataTableId, + { name: input.columnName, type: input.type }, + { projectId: input.projectId }, + ); return { column }; } @@ -372,7 +424,9 @@ async function handleDeleteColumn( } // State 3: Approved or always_allow — execute - await context.dataTableService.deleteColumn(input.dataTableId, input.columnId); + await context.dataTableService.deleteColumn(input.dataTableId, input.columnId, { + projectId: input.projectId, + }); return { success: true }; } @@ -406,7 +460,9 @@ async function handleRenameColumn( } // State 3: Approved or always_allow — execute - await context.dataTableService.renameColumn(input.dataTableId, input.columnId, input.newName); + await context.dataTableService.renameColumn(input.dataTableId, input.columnId, input.newName, { + projectId: input.projectId, + }); return { success: true }; } @@ -440,7 +496,9 @@ async function handleInsertRows( } // State 3: Approved or always_allow — execute - return await context.dataTableService.insertRows(input.dataTableId, input.rows); + return await context.dataTableService.insertRows(input.dataTableId, input.rows, { + projectId: input.projectId, + }); } async function handleUpdateRows( @@ -473,7 +531,9 @@ async function handleUpdateRows( } // State 3: Approved or always_allow — execute - return await context.dataTableService.updateRows(input.dataTableId, input.filter, input.data); + return await context.dataTableService.updateRows(input.dataTableId, input.filter, input.data, { + projectId: input.projectId, + }); } async function handleDeleteRows( @@ -515,7 +575,9 @@ async function handleDeleteRows( } // State 3: Approved or always_allow — execute - const result = await context.dataTableService.deleteRows(input.dataTableId, input.filter); + const result = await context.dataTableService.deleteRows(input.dataTableId, input.filter, { + projectId: input.projectId, + }); return { success: true, deletedCount: result.deletedCount, diff --git a/packages/@n8n/instance-ai/src/tools/executions.tool.ts b/packages/@n8n/instance-ai/src/tools/executions.tool.ts index 74e55d3d60a..e401579125b 100644 --- a/packages/@n8n/instance-ai/src/tools/executions.tool.ts +++ b/packages/@n8n/instance-ai/src/tools/executions.tool.ts @@ -139,7 +139,15 @@ async function handleRun( }; } - const needsApproval = context.permissions?.runWorkflow !== 'always_allow'; + // `always_allow` is only honored for the workflow IDs the caller pre-authorized + // (e.g. checkpoint follow-ups scope the override to the workflows the checkpoint + // is verifying). When the allow-list is unset, `always_allow` applies broadly, + // matching the legacy behavior. + const allowList = context.allowedRunWorkflowIds; + const allowedByScope = + context.permissions?.runWorkflow === 'always_allow' && + (allowList === undefined || allowList.has(input.workflowId)); + const needsApproval = !allowedByScope; // If approval is required and this is the first call, suspend for confirmation if (needsApproval && (resumeData === undefined || resumeData === null)) { diff --git a/packages/@n8n/instance-ai/src/tools/index.ts b/packages/@n8n/instance-ai/src/tools/index.ts index 483de77f1cc..167b83444ed 100644 --- a/packages/@n8n/instance-ai/src/tools/index.ts +++ b/packages/@n8n/instance-ai/src/tools/index.ts @@ -8,6 +8,7 @@ import { createToolsFromLocalMcpServer } from './filesystem/create-tools-from-mc import { createNodesTool } from './nodes.tool'; import { createBrowserCredentialSetupTool } from './orchestration/browser-credential-setup.tool'; import { createBuildWorkflowAgentTool } from './orchestration/build-workflow-agent.tool'; +import { createCompleteCheckpointTool } from './orchestration/complete-checkpoint.tool'; import { createDelegateTool } from './orchestration/delegate.tool'; import { createPlanWithAgentTool } from './orchestration/plan-with-agent.tool'; import { createPlanTool } from './orchestration/plan.tool'; @@ -75,6 +76,7 @@ export function createOrchestrationTools(context: OrchestrationContext) { 'task-control': createTaskControlTool(context), delegate: createDelegateTool(context), 'build-workflow-with-agent': createBuildWorkflowAgentTool(context), + 'complete-checkpoint': createCompleteCheckpointTool(context), ...(context.browserMcpConfig || hasGatewayBrowserTools(context) ? { 'browser-credential-setup': createBrowserCredentialSetupTool(context), diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/blueprint-accumulator.test.ts b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/blueprint-accumulator.test.ts new file mode 100644 index 00000000000..277ecaa9b4f --- /dev/null +++ b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/blueprint-accumulator.test.ts @@ -0,0 +1,144 @@ +import { BlueprintAccumulator } from '../blueprint-accumulator'; + +describe('BlueprintAccumulator', () => { + let accumulator: BlueprintAccumulator; + + beforeEach(() => { + accumulator = new BlueprintAccumulator(); + }); + + describe('addItem with kind=checkpoint', () => { + it('produces a PlannedTaskInput with kind=checkpoint', () => { + accumulator.addItem({ + kind: 'workflow', + id: 'wf-1', + name: 'Daily Email', + purpose: 'Send a daily summary email', + integrations: [], + dependsOn: [], + }); + + const task = accumulator.addItem({ + kind: 'checkpoint', + id: 'verify-1', + title: "Verify 'Daily Email' workflow runs without errors", + instructions: + 'Call verify-built-workflow with the workItemId from wf-1. Assert success===true.', + dependsOn: ['wf-1'], + }); + + expect(task).toEqual({ + id: 'verify-1', + title: "Verify 'Daily Email' workflow runs without errors", + kind: 'checkpoint', + spec: 'Call verify-built-workflow with the workItemId from wf-1. Assert success===true.', + deps: ['wf-1'], + }); + }); + + it('includes the checkpoint in getTaskList and getTaskItemsForEvent', () => { + accumulator.addItem({ + kind: 'workflow', + id: 'wf-1', + name: 'WF', + purpose: 'p', + integrations: [], + dependsOn: [], + }); + accumulator.addItem({ + kind: 'checkpoint', + id: 'verify-1', + title: 'Verify WF', + instructions: 'Verify it', + dependsOn: ['wf-1'], + }); + + const list = accumulator.getTaskList(); + const items = accumulator.getTaskItemsForEvent(); + + expect(list.map((t) => t.kind)).toEqual(['build-workflow', 'checkpoint']); + expect(items.map((t) => t.id)).toEqual(['wf-1', 'verify-1']); + }); + + it('removeItem drops the checkpoint and dangling dep references', () => { + accumulator.addItem({ + kind: 'workflow', + id: 'wf-1', + name: 'WF', + purpose: 'p', + integrations: [], + dependsOn: [], + }); + accumulator.addItem({ + kind: 'checkpoint', + id: 'verify-1', + title: 'Verify WF', + instructions: 'Verify it', + dependsOn: ['wf-1'], + }); + + expect(accumulator.removeItem('verify-1')).toBe(true); + expect(accumulator.getTaskList().map((t) => t.id)).toEqual(['wf-1']); + }); + + it('cascade-removes a checkpoint when its only build-workflow dep is removed', () => { + accumulator.addItem({ + kind: 'workflow', + id: 'wf-1', + name: 'WF', + purpose: 'p', + integrations: [], + dependsOn: [], + }); + accumulator.addItem({ + kind: 'checkpoint', + id: 'verify-1', + title: 'Verify WF', + instructions: 'Verify it', + dependsOn: ['wf-1'], + }); + + accumulator.removeItem('wf-1'); + + // Checkpoint must not survive as an orphan — createPlan would reject + // it at submit-plan time because checkpoint deps must reference a + // build-workflow task. + const list = accumulator.getTaskList(); + expect(list.find((t) => t.id === 'verify-1')).toBeUndefined(); + expect(list.find((t) => t.id === 'wf-1')).toBeUndefined(); + expect(list).toHaveLength(0); + }); + + it('keeps a checkpoint that still depends on at least one remaining workflow', () => { + accumulator.addItem({ + kind: 'workflow', + id: 'wf-1', + name: 'WF1', + purpose: 'p', + integrations: [], + dependsOn: [], + }); + accumulator.addItem({ + kind: 'workflow', + id: 'wf-2', + name: 'WF2', + purpose: 'p', + integrations: [], + dependsOn: [], + }); + accumulator.addItem({ + kind: 'checkpoint', + id: 'verify-both', + title: 'Verify both', + instructions: 'Verify both', + dependsOn: ['wf-1', 'wf-2'], + }); + + accumulator.removeItem('wf-1'); + + const checkpoint = accumulator.getTaskList().find((t) => t.id === 'verify-both'); + expect(checkpoint).toBeDefined(); + expect(checkpoint?.deps).toEqual(['wf-2']); + }); + }); +}); diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/blueprint.schema.test.ts b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/blueprint.schema.test.ts new file mode 100644 index 00000000000..475f479ed18 --- /dev/null +++ b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/blueprint.schema.test.ts @@ -0,0 +1,32 @@ +import { blueprintCheckpointItemSchema } from '../blueprint.schema'; + +describe('blueprintCheckpointItemSchema', () => { + it('rejects a checkpoint with an empty dependsOn array', () => { + const result = blueprintCheckpointItemSchema.safeParse({ + id: 'verify-1', + title: 'Verify something', + instructions: 'Call verify-built-workflow', + dependsOn: [], + }); + expect(result.success).toBe(false); + }); + + it('rejects a checkpoint that omits dependsOn entirely', () => { + const result = blueprintCheckpointItemSchema.safeParse({ + id: 'verify-1', + title: 'Verify something', + instructions: 'Call verify-built-workflow', + }); + expect(result.success).toBe(false); + }); + + it('accepts a checkpoint that depends on at least one workflow item', () => { + const result = blueprintCheckpointItemSchema.safeParse({ + id: 'verify-1', + title: 'Verify Daily Email workflow runs without errors', + instructions: 'Call verify-built-workflow with the workItemId from wf-1.', + dependsOn: ['wf-1'], + }); + expect(result.success).toBe(true); + }); +}); diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/build-workflow-agent.tool.test.ts b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/build-workflow-agent.tool.test.ts index 46b2ae4c75b..fdb5cd10f51 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/build-workflow-agent.tool.test.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/build-workflow-agent.tool.test.ts @@ -5,13 +5,45 @@ jest.mock('@mastra/core/agent', () => ({ jest.mock('@mastra/core/mastra', () => ({ Mastra: jest.fn(), })); +jest.mock('@mastra/core/tools', () => ({ + createTool: jest.fn((config: Record) => config), +})); +import type { OrchestrationContext } from '../../../types'; import type { SubmitWorkflowAttempt } from '../../workflows/submit-workflow.tool'; -const { recordSuccessfulWorkflowBuilds, resultFromPostStreamError } = +const { resultFromPostStreamError, createBuildWorkflowAgentTool, recordSuccessfulWorkflowBuilds } = // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/consistent-type-imports require('../build-workflow-agent.tool') as typeof import('../build-workflow-agent.tool'); +type BuildExecutable = { + execute: (input: Record) => Promise<{ result: string; taskId: string }>; +}; + +function createMockContext(overrides: Partial = {}): OrchestrationContext { + return { + threadId: 'test-thread', + runId: 'test-run', + userId: 'test-user', + orchestratorAgentId: 'test-agent', + modelId: 'test-model' as OrchestrationContext['modelId'], + storage: { id: 'test-storage' } as OrchestrationContext['storage'], + subAgentMaxSteps: 5, + eventBus: { + publish: jest.fn(), + subscribe: jest.fn(), + getEventsAfter: jest.fn(), + getNextEventId: jest.fn(), + getEventsForRun: jest.fn().mockReturnValue([]), + getEventsForRuns: jest.fn().mockReturnValue([]), + }, + logger: { info: jest.fn(), warn: jest.fn(), error: jest.fn(), debug: jest.fn() }, + domainTools: {}, + abortSignal: new AbortController().signal, + ...overrides, + } as OrchestrationContext; +} + const MAIN_PATH = '/home/daytona/workspace/src/workflow.ts'; describe('resultFromPostStreamError', () => { @@ -129,6 +161,115 @@ describe('resultFromPostStreamError', () => { }); }); +describe('createBuildWorkflowAgentTool — plan-enforcement guard', () => { + const ORIGINAL_ENV = process.env.N8N_INSTANCE_AI_ENFORCE_BUILD_VIA_PLAN; + + afterEach(() => { + if (ORIGINAL_ENV === undefined) { + delete process.env.N8N_INSTANCE_AI_ENFORCE_BUILD_VIA_PLAN; + } else { + process.env.N8N_INSTANCE_AI_ENFORCE_BUILD_VIA_PLAN = ORIGINAL_ENV; + } + }); + + it('rejects direct calls outside a replan/checkpoint follow-up', async () => { + const context = createMockContext(); + const tool = createBuildWorkflowAgentTool(context) as unknown as BuildExecutable; + + const out = await tool.execute({ task: 'Build a Slack notifier' }); + + expect(out.taskId).toBe(''); + expect(out.result).toContain('bypassPlan'); + expect(out.result).toMatch( + /For new workflows, multi-workflow builds, or data-table schema changes/, + ); + expect(out.result).toContain('`plan`'); + expect(context.logger.warn).toHaveBeenCalledWith( + 'build-workflow-with-agent called outside plan/replan context — rejecting', + expect.objectContaining({ threadId: 'test-thread' }), + ); + }); + + it('rejects bypassPlan=true without a workflowId (new builds must go through plan)', async () => { + const context = createMockContext(); + const tool = createBuildWorkflowAgentTool(context) as unknown as BuildExecutable; + + const out = await tool.execute({ + task: 'build something shiny', + bypassPlan: true, + reason: 'I feel like skipping the plan today', + }); + + expect(out.taskId).toBe(''); + expect(out.result).toMatch(/edits to an EXISTING workflow and requires a `workflowId`/); + }); + + it('rejects bypassPlan=true without a reason', async () => { + const context = createMockContext(); + const tool = createBuildWorkflowAgentTool(context) as unknown as BuildExecutable; + + const out = await tool.execute({ + task: 'patch one expression', + workflowId: 'WF_EXISTING', + bypassPlan: true, + }); + + expect(out.taskId).toBe(''); + expect(out.result).toContain('requires a one-sentence `reason`'); + }); + + it('allows the call when bypassPlan=true with a reason is provided', async () => { + const context = createMockContext(); + const tool = createBuildWorkflowAgentTool(context) as unknown as BuildExecutable; + + const out = await tool.execute({ + task: 'patch one expression', + workflowId: 'WF_EXISTING', + bypassPlan: true, + reason: 'Swap Slack channel on this notifier.', + }); + + // Guard passes → reaches startBuildWorkflowAgentTask, which short-circuits on + // missing spawnBackgroundTask. The point is we got past the guard, not what + // the downstream does. + expect(out.result).not.toMatch(/`bypassPlan: true` is for edits/); + const warnMock = context.logger.warn as jest.Mock?]>; + expect(warnMock.mock.calls.some((c) => c[0].includes('bypassing plan'))).toBe(true); + }); + + it('allows direct calls in a replan follow-up', async () => { + const context = createMockContext({ isReplanFollowUp: true }); + const tool = createBuildWorkflowAgentTool(context) as unknown as BuildExecutable; + + const out = await tool.execute({ task: 'retry after failure' }); + + expect(out.result).not.toContain('direct builder calls require'); + expect(context.logger.warn).not.toHaveBeenCalledWith( + 'build-workflow-with-agent called outside plan/replan context — rejecting', + expect.anything(), + ); + }); + + it('allows direct calls in a checkpoint follow-up', async () => { + const context = createMockContext({ isCheckpointFollowUp: true }); + const tool = createBuildWorkflowAgentTool(context) as unknown as BuildExecutable; + + const out = await tool.execute({ task: 'checkpoint branch' }); + + expect(out.result).not.toContain('direct builder calls require'); + }); + + it('skips the guard when the env flag is disabled', async () => { + process.env.N8N_INSTANCE_AI_ENFORCE_BUILD_VIA_PLAN = 'false'; + const context = createMockContext(); + const tool = createBuildWorkflowAgentTool(context) as unknown as BuildExecutable; + + const out = await tool.execute({ task: 'build directly' }); + + expect(out.result).not.toContain('direct builder calls require'); + }); +}); + describe('recordSuccessfulWorkflowBuilds', () => { it('records workflow IDs returned from successful build-workflow executions', async () => { const onWorkflowId = jest.fn(); diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/complete-checkpoint.tool.test.ts b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/complete-checkpoint.tool.test.ts new file mode 100644 index 00000000000..06e9fb77305 --- /dev/null +++ b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/complete-checkpoint.tool.test.ts @@ -0,0 +1,207 @@ +import type { + CheckpointSettleResult, + OrchestrationContext, + PlannedTaskService, +} from '../../../types'; + +// Mock heavy Mastra dependencies to avoid ESM issues in Jest +jest.mock('@mastra/core/tools', () => ({ + createTool: jest.fn((config: Record) => config), +})); + +const { createCompleteCheckpointTool } = + // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/consistent-type-imports + require('../complete-checkpoint.tool') as typeof import('../complete-checkpoint.tool'); + +type Executable = { + execute: (input: unknown) => Promise<{ ok: boolean; result: string }>; +}; + +function makeService(overrides: Partial = {}): PlannedTaskService { + return { + markCheckpointSucceeded: jest.fn(), + markCheckpointFailed: jest.fn(), + ...overrides, + } as unknown as PlannedTaskService; +} + +function makeContext(service: PlannedTaskService): OrchestrationContext { + return { + threadId: 'thread-1', + runId: 'run-1', + userId: 'user-1', + orchestratorAgentId: 'orc', + modelId: 'model' as OrchestrationContext['modelId'], + storage: {} as OrchestrationContext['storage'], + subAgentMaxSteps: 5, + eventBus: { + publish: jest.fn(), + subscribe: jest.fn(), + getEventsAfter: jest.fn(), + getNextEventId: jest.fn(), + getEventsForRun: jest.fn().mockReturnValue([]), + getEventsForRuns: jest.fn().mockReturnValue([]), + }, + logger: { info: jest.fn(), warn: jest.fn(), error: jest.fn(), debug: jest.fn() }, + domainTools: {}, + abortSignal: new AbortController().signal, + taskStorage: { get: jest.fn(), save: jest.fn() }, + plannedTaskService: service, + }; +} + +describe('createCompleteCheckpointTool', () => { + it('marks a checkpoint succeeded via markCheckpointSucceeded', async () => { + const service = makeService({ + markCheckpointSucceeded: jest + .fn() + .mockResolvedValue({ ok: true, graph: { tasks: [], planRunId: 'r', status: 'active' } }), + }); + const tool = createCompleteCheckpointTool(makeContext(service)) as unknown as Executable; + + const res = await tool.execute({ + taskId: 'verify-1', + status: 'succeeded', + result: 'Verified', + }); + + expect(res.ok).toBe(true); + expect(res.result).toContain('succeeded'); + expect(service.markCheckpointSucceeded).toHaveBeenCalledWith('thread-1', 'verify-1', { + result: 'Verified', + outcome: undefined, + }); + expect(service.markCheckpointFailed).not.toHaveBeenCalled(); + }); + + it('marks a checkpoint failed via markCheckpointFailed', async () => { + const service = makeService({ + markCheckpointFailed: jest + .fn() + .mockResolvedValue({ ok: true, graph: { tasks: [], planRunId: 'r', status: 'active' } }), + }); + const tool = createCompleteCheckpointTool(makeContext(service)) as unknown as Executable; + + const res = await tool.execute({ + taskId: 'verify-1', + status: 'failed', + error: 'Workflow errored', + }); + + expect(res.ok).toBe(true); + expect(service.markCheckpointFailed).toHaveBeenCalledWith('thread-1', 'verify-1', { + error: 'Workflow errored', + outcome: undefined, + }); + }); + + it('forwards structured outcome to markCheckpointFailed so replans keep execution context', async () => { + const service = makeService({ + markCheckpointFailed: jest + .fn() + .mockResolvedValue({ ok: true, graph: { tasks: [], planRunId: 'r', status: 'active' } }), + }); + const tool = createCompleteCheckpointTool(makeContext(service)) as unknown as Executable; + + await tool.execute({ + taskId: 'verify-1', + status: 'failed', + error: 'Node crashed', + outcome: { + executionId: 'exec-42', + failureNode: 'Insert Row', + errorMessage: 'constraint violation', + }, + }); + + expect(service.markCheckpointFailed).toHaveBeenCalledWith('thread-1', 'verify-1', { + error: 'Node crashed', + outcome: { + executionId: 'exec-42', + failureNode: 'Insert Row', + errorMessage: 'constraint violation', + }, + }); + }); + + it('returns error string (not throw) on not-found', async () => { + const not: CheckpointSettleResult = { ok: false, reason: 'not-found' }; + const service = makeService({ + markCheckpointSucceeded: jest.fn().mockResolvedValue(not), + }); + const tool = createCompleteCheckpointTool(makeContext(service)) as unknown as Executable; + + const res = await tool.execute({ taskId: 'missing', status: 'succeeded' }); + + expect(res.ok).toBe(false); + expect(res.result).toContain('no task with id'); + }); + + it('returns error string on wrong-kind', async () => { + const wk: CheckpointSettleResult = { + ok: false, + reason: 'wrong-kind', + actual: { kind: 'build-workflow' }, + }; + const service = makeService({ + markCheckpointSucceeded: jest.fn().mockResolvedValue(wk), + }); + const tool = createCompleteCheckpointTool(makeContext(service)) as unknown as Executable; + + const res = await tool.execute({ taskId: 'wf-1', status: 'succeeded' }); + + expect(res.ok).toBe(false); + expect(res.result).toContain('not a checkpoint'); + expect(res.result).toContain('build-workflow'); + }); + + it('returns error string on wrong-status', async () => { + const ws: CheckpointSettleResult = { + ok: false, + reason: 'wrong-status', + actual: { status: 'planned' }, + }; + const service = makeService({ + markCheckpointSucceeded: jest.fn().mockResolvedValue(ws), + }); + const tool = createCompleteCheckpointTool(makeContext(service)) as unknown as Executable; + + const res = await tool.execute({ taskId: 'verify-1', status: 'succeeded' }); + + expect(res.ok).toBe(false); + expect(res.result).toContain('not in running state'); + expect(res.result).toContain('planned'); + }); + + it('returns an error when planned task service is absent', async () => { + const tool = createCompleteCheckpointTool({ + ...makeContext(makeService()), + plannedTaskService: undefined, + } as OrchestrationContext) as unknown as Executable; + + const res = await tool.execute({ taskId: 'verify-1', status: 'succeeded' }); + + expect(res.ok).toBe(false); + expect(res.result).toContain('not available'); + }); + + it('defaults failed-error to result or a sensible default', async () => { + const service = makeService({ + markCheckpointFailed: jest + .fn() + .mockResolvedValue({ ok: true, graph: { tasks: [], planRunId: 'r', status: 'active' } }), + }); + const tool = createCompleteCheckpointTool(makeContext(service)) as unknown as Executable; + + await tool.execute({ + taskId: 'verify-1', + status: 'failed', + result: 'Workflow hit 429 during verify', + }); + + expect(service.markCheckpointFailed).toHaveBeenCalledWith('thread-1', 'verify-1', { + error: 'Workflow hit 429 during verify', + outcome: undefined, + }); + }); +}); diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/plan-with-agent.tool.test.ts b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/plan-with-agent.tool.test.ts new file mode 100644 index 00000000000..cb0dbbe3240 --- /dev/null +++ b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/plan-with-agent.tool.test.ts @@ -0,0 +1,133 @@ +// Mock heavy Mastra dependencies to avoid ESM issues in Jest +jest.mock('@mastra/core/agent', () => ({ + Agent: jest.fn(), +})); +jest.mock('@mastra/core/mastra', () => ({ + Mastra: jest.fn(), +})); +jest.mock('@mastra/core/tools', () => ({ + createTool: jest.fn((config: Record) => config), +})); + +import type { OrchestrationContext, PlannedTaskGraph, PlannedTaskService } from '../../../types'; + +const { __testClearPlannedTaskGraph, __testFormatMessagesForBriefing } = + // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/consistent-type-imports + require('../plan-with-agent.tool') as typeof import('../plan-with-agent.tool'); + +function makeContext(overrides: { + graph: PlannedTaskGraph | null; + runId?: string; +}): { + context: OrchestrationContext; + clear: jest.Mock; + getGraph: jest.Mock; +} { + const clear = jest.fn(async () => { + await Promise.resolve(); + }); + const getGraph = jest.fn(async () => { + await Promise.resolve(); + return overrides.graph; + }); + const plannedTaskService: Partial = { + getGraph, + clear, + }; + const context = { + threadId: 't-1', + runId: overrides.runId ?? 'run-current', + plannedTaskService: plannedTaskService as PlannedTaskService, + } as unknown as OrchestrationContext; + return { context, clear, getGraph }; +} + +describe('clearPlannedTaskGraph', () => { + it('clears the graph when it belongs to this run and is awaiting approval', async () => { + const { context, clear } = makeContext({ + graph: { + planRunId: 'run-current', + status: 'awaiting_approval', + tasks: [], + }, + }); + + await __testClearPlannedTaskGraph(context); + + expect(clear).toHaveBeenCalledWith('t-1'); + }); + + it('does not clear an active graph from a prior approved plan', async () => { + // A previous `/plan` call already succeeded; its graph is `active` with + // pending checkpoints. A new planner error must not wipe it. + const { context, clear } = makeContext({ + graph: { + planRunId: 'run-previous', + status: 'active', + tasks: [], + }, + }); + + await __testClearPlannedTaskGraph(context); + + expect(clear).not.toHaveBeenCalled(); + }); + + it('does not clear an awaiting-approval graph that was created by a different planner run', async () => { + // Defensive: a concurrent plan for a different run should not have its + // unapproved graph wiped by this run's error-path cleanup. + const { context, clear } = makeContext({ + graph: { + planRunId: 'run-other', + status: 'awaiting_approval', + tasks: [], + }, + }); + + await __testClearPlannedTaskGraph(context); + + expect(clear).not.toHaveBeenCalled(); + }); + + it('is a no-op when no graph exists', async () => { + const { context, clear, getGraph } = makeContext({ graph: null }); + + await __testClearPlannedTaskGraph(context); + + expect(getGraph).toHaveBeenCalled(); + expect(clear).not.toHaveBeenCalled(); + }); + + it('swallows getGraph errors so the caller can return its own error', async () => { + const { context, getGraph } = makeContext({ + graph: { planRunId: 'run-current', status: 'awaiting_approval', tasks: [] }, + }); + getGraph.mockRejectedValueOnce(new Error('db down')); + + await expect(__testClearPlannedTaskGraph(context)).resolves.toBeUndefined(); + }); +}); + +describe('formatMessagesForBriefing', () => { + // The planner system prompt (plan-agent-prompt.ts) treats + // and as a paired contract — schedule/cron decisions read + // both. Emitting only one drops half the contract. + + it('emits alongside when a zone is provided', () => { + const briefing = __testFormatMessagesForBriefing( + [{ role: 'user', content: 'schedule me a daily digest' }], + undefined, + 'America/New_York', + ); + + expect(briefing).toMatch(/[^<]+<\/current-datetime>/); + expect(briefing).toContain('America/New_York'); + }); + + it('still emits when no zone is provided', () => { + const briefing = __testFormatMessagesForBriefing([], undefined, undefined); + + expect(briefing).toMatch(/[^<]+<\/current-datetime>/); + expect(briefing).not.toContain(''); + }); +}); diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/plan.tool.test.ts b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/plan.tool.test.ts index 1a277d34161..fcb1c51ecc7 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/plan.tool.test.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/plan.tool.test.ts @@ -20,6 +20,8 @@ function makePlannedTaskService(overrides: Partial = {}): Pl return { createPlan: jest.fn().mockResolvedValue(undefined), getGraph: jest.fn().mockResolvedValue(null), + approvePlan: jest.fn().mockResolvedValue(undefined), + clear: jest.fn().mockResolvedValue(undefined), ...overrides, } as unknown as PlannedTaskService; } @@ -230,4 +232,120 @@ describe('createPlanTool — replan-only guard', () => { expect(out.result).toContain('Plan approved'); expect(context.schedulePlannedTasks).toHaveBeenCalled(); }); + + it('flips graph to active via approvePlan before scheduling on approval', async () => { + const context = createMockContext({ currentUserMessage: 'ordinary message' }); + const tool = createPlanTool(context) as unknown as Executable; + + await tool.execute({ tasks: validTasks() }, { agent: { resumeData: { approved: true } } }); + + expect(context.plannedTaskService!.approvePlan).toHaveBeenCalledWith('test-thread'); + expect(context.schedulePlannedTasks).toHaveBeenCalled(); + }); + + it('returns the rejection result even when taskStorage.save fails so the revision flow can proceed', async () => { + // The persisted graph stays in awaiting_approval regardless of UI cleanup + // — the next createPlan overwrites it. A storage flake here must not abort + // the rejection path or strand the user without a "User requested changes" + // message and a chance to revise. + const context = createMockContext({ + currentUserMessage: 'ordinary message', + taskStorage: { + get: jest.fn(), + save: jest.fn().mockRejectedValue(new Error('storage flake')), + } as TaskStorage, + }); + const tool = createPlanTool(context) as unknown as Executable; + + const out = await tool.execute( + { tasks: validTasks() }, + { agent: { resumeData: { approved: false, userInput: 'try again' } } }, + ); + + expect(out.taskCount).toBe(0); + expect(out.result).toContain('User requested changes'); + expect(context.logger.warn).toHaveBeenCalledWith( + 'Failed to clear rejected plan checklist', + expect.objectContaining({ error: expect.anything() as unknown }), + ); + }); + + it('keeps the awaiting_approval graph on rejection so a same-turn revision can pass the guard', async () => { + // The rejected plan stays in `awaiting_approval` (scoped to runId) so the + // LLM's next create-tasks call — which the tool result tells it to make — + // is treated as a revision and bypasses planner-discovery guard. The + // scheduler ignores `awaiting_approval`, so leaving it in place can't + // dispatch a rejected plan. + const context = createMockContext({ currentUserMessage: 'ordinary message' }); + const tool = createPlanTool(context) as unknown as Executable; + + const out = await tool.execute( + { tasks: validTasks() }, + { agent: { resumeData: { approved: false, userInput: 'not what I wanted' } } }, + ); + + expect(out.taskCount).toBe(0); + expect(out.result).toContain('User requested changes'); + expect(context.plannedTaskService!.clear).not.toHaveBeenCalled(); + expect(context.schedulePlannedTasks).not.toHaveBeenCalled(); + expect(context.plannedTaskService!.approvePlan).not.toHaveBeenCalled(); + // UI checklist still resets so the rejected todos don't linger on screen + expect(context.taskStorage.save).toHaveBeenCalledWith('test-thread', { tasks: [] }); + expect(context.eventBus.publish).toHaveBeenCalledWith( + 'test-thread', + expect.objectContaining({ + type: 'tasks-update', + payload: { tasks: { tasks: [] }, planItems: [] }, + }), + ); + }); + + it('allows a same-turn revision after rejection (awaiting_approval with same runId)', async () => { + // After rejection, the graph stays in awaiting_approval with planRunId === + // context.runId. The next create-tasks call must pass threadHasExistingPlan + // so the revision flow advertised by the tool result works. + const context = createMockContext({ + currentUserMessage: 'revise the plan', + runId: 'run-1', + plannedTaskService: makePlannedTaskService({ + getGraph: jest.fn().mockResolvedValue({ + threadId: 'test-thread', + status: 'awaiting_approval', + planRunId: 'run-1', + tasks: [], + } as unknown as Awaited>), + }), + }); + const tool = createPlanTool(context) as unknown as Executable; + const suspend = jest.fn().mockResolvedValue(undefined); + + const out = await tool.execute({ tasks: validTasks() }, { agent: { suspend } }); + + expect(out.result).toBe('Awaiting approval'); + expect(context.plannedTaskService!.createPlan).toHaveBeenCalled(); + }); + + it('rejects a fresh request when an orphan awaiting_approval graph exists from a previous run', async () => { + // LLM rejected a prior plan and never revised; the graph orphans in + // awaiting_approval with a stale planRunId. A new turn must still go + // through planner discovery, not silently bypass the guard. + const context = createMockContext({ + currentUserMessage: 'unrelated new request', + runId: 'run-2', + plannedTaskService: makePlannedTaskService({ + getGraph: jest.fn().mockResolvedValue({ + threadId: 'test-thread', + status: 'awaiting_approval', + planRunId: 'run-1', + tasks: [], + } as unknown as Awaited>), + }), + }); + const tool = createPlanTool(context) as unknown as Executable; + + const out = await tool.execute({ tasks: validTasks() }, { agent: { suspend: jest.fn() } }); + + expect(out.result).toMatch(/^Error: `create-tasks` is for replanning only/); + expect(context.plannedTaskService!.createPlan).not.toHaveBeenCalled(); + }); }); diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/research-with-agent.tool.test.ts b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/research-with-agent.tool.test.ts index 5d4f39a3cdc..68d5375674c 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/research-with-agent.tool.test.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/research-with-agent.tool.test.ts @@ -52,7 +52,11 @@ function createMockContext(overrides?: Partial): Orchestra domainTools, abortSignal: new AbortController().signal, taskStorage: {} as TaskStorage, - spawnBackgroundTask: jest.fn(), + spawnBackgroundTask: jest.fn(() => ({ + status: 'started' as const, + taskId: 'spawn-task-id', + agentId: 'spawn-agent-id', + })), cancelBackgroundTask: jest.fn(), ...overrides, }; @@ -144,5 +148,46 @@ describe('research-with-agent tool', () => { expect(result.result).toBe('Error: background task support not available.'); }); + + it('does not publish agent-spawned when spawn returns duplicate', async () => { + // The single-flight dedupe path used to emit a phantom `agent-spawned` + // before checking the spawn outcome — leaving an orphan card in the UI. + const context = createMockContext({ + spawnBackgroundTask: jest.fn(() => ({ + status: 'duplicate' as const, + existing: { + taskId: 'task-existing', + agentId: 'agent-existing', + role: 'web-researcher', + }, + })), + }); + const tool = createResearchWithAgentTool(context); + + const result = (await tool.execute!({ goal: 'test' }, {} as never)) as { + result: string; + taskId: string; + }; + + expect(result.result).toContain('Research already in progress'); + expect(result.taskId).toBe('task-existing'); + expect(context.eventBus.publish).not.toHaveBeenCalled(); + }); + + it('does not publish agent-spawned when spawn returns limit-reached', async () => { + const context = createMockContext({ + spawnBackgroundTask: jest.fn(() => ({ status: 'limit-reached' as const })), + }); + const tool = createResearchWithAgentTool(context); + + const result = (await tool.execute!({ goal: 'test' }, {} as never)) as { + result: string; + taskId: string; + }; + + expect(result.result).toContain('limit reached'); + expect(result.taskId).toBe(''); + expect(context.eventBus.publish).not.toHaveBeenCalled(); + }); }); }); diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/verify-built-workflow.tool.test.ts b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/verify-built-workflow.tool.test.ts new file mode 100644 index 00000000000..6d751676dde --- /dev/null +++ b/packages/@n8n/instance-ai/src/tools/orchestration/__tests__/verify-built-workflow.tool.test.ts @@ -0,0 +1,509 @@ +import type { + InstanceAiDataTableService, + InstanceAiWorkflowService, + OrchestrationContext, + WorkflowTaskService, +} from '../../../types'; +import type { WorkflowBuildOutcome } from '../../../workflow-loop/workflow-loop-state'; +import { createVerifyBuiltWorkflowTool } from '../verify-built-workflow.tool'; + +type ExecutionRunResult = { + executionId?: string | null; + status: 'success' | 'error' | 'waiting' | 'running' | 'unknown'; + data?: Record; + error?: string; +}; + +interface VerifyToolContext { + workflowTaskService: WorkflowTaskService; + domainContext: { + executionService: { + run: jest.Mock< + Promise, + [string, Record | undefined, { timeout?: number; pinData?: unknown }] + >; + }; + workflowService?: InstanceAiWorkflowService; + dataTableService?: InstanceAiDataTableService; + }; + logger: { debug: jest.Mock; info: jest.Mock; warn: jest.Mock; error: jest.Mock }; +} + +function makeBuildOutcome(overrides: Partial = {}): WorkflowBuildOutcome { + return { + workItemId: 'wi-1', + taskId: 'task-1', + workflowId: 'wf-1', + submitted: true, + triggerType: 'manual_or_testable', + needsUserInput: false, + summary: 'built ok', + ...overrides, + }; +} + +function makeContext( + outcome: WorkflowBuildOutcome | undefined, + runResult: ExecutionRunResult, + overrides: { + workflowNodes?: Array<{ name?: string; type: string; parameters?: Record }>; + tableRows?: Record>>; + queriesAfterRun?: Record>>; + /** Throw `snapshotError` on the first queryRows call for the given table id. */ + snapshotErrors?: Record; + } = {}, +) { + const updateBuildOutcome = jest.fn( + async (_workItemId: string, _update: Partial) => { + await Promise.resolve(); + }, + ); + const run = jest.fn( + async ( + _workflowId: string, + _inputData: Record | undefined, + _options: { timeout?: number; pinData?: unknown }, + ): Promise => { + await Promise.resolve(); + return runResult; + }, + ); + + type QueryRowsResult = { count: number; data: Array> }; + /** + * Track which dataTableIds we've already "seen a last page for" — any call + * after the snapshot phase for a given table switches to `queriesAfterRun`. + */ + const snapshotDone = new Set(); + const queryRows = jest.fn( + async ( + dataTableId: string, + opts?: { limit?: number; offset?: number }, + ): Promise => { + const snapshotError = overrides.snapshotErrors?.[dataTableId]; + if (snapshotError && !snapshotDone.has(dataTableId)) { + // Mark done so post-run phase doesn't keep throwing if that matters. + snapshotDone.add(dataTableId); + throw snapshotError; + } + const limit = opts?.limit ?? Number.MAX_SAFE_INTEGER; + const offset = opts?.offset ?? 0; + const baseRows: Array> = snapshotDone.has(dataTableId) + ? (overrides.queriesAfterRun?.[dataTableId] ?? overrides.tableRows?.[dataTableId] ?? []) + : (overrides.tableRows?.[dataTableId] ?? []); + const page = baseRows.slice(offset, offset + limit); + // If this page is the last one of the snapshot (fewer than `limit` rows), + // any subsequent calls for this table should fall through to post-run data. + if (!snapshotDone.has(dataTableId) && page.length < limit) { + snapshotDone.add(dataTableId); + } + await Promise.resolve(); + return { count: baseRows.length, data: page }; + }, + ); + type DeleteRowsFilter = { + type: 'and' | 'or'; + filters: Array<{ + columnName: string; + condition: 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like'; + value: string | number | boolean | null; + }>; + }; + const deleteRows = jest.fn(async (_dataTableId: string, _filter: DeleteRowsFilter) => { + await Promise.resolve(); + return { deletedCount: 0, dataTableId: '', tableName: '', projectId: '' }; + }); + + const workflowService = { + getAsWorkflowJSON: jest.fn(async () => { + await Promise.resolve(); + return { nodes: overrides.workflowNodes ?? [] }; + }), + } as unknown as InstanceAiWorkflowService; + + const dataTableService = { + queryRows, + deleteRows, + } as unknown as InstanceAiDataTableService; + + const logger = { + debug: jest.fn(), + info: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + }; + + const ctx: VerifyToolContext = { + workflowTaskService: { + reportBuildOutcome: jest.fn(), + reportVerificationVerdict: jest.fn(), + getBuildOutcome: jest.fn(async () => { + await Promise.resolve(); + return outcome; + }), + updateBuildOutcome, + } as unknown as WorkflowTaskService, + domainContext: { + executionService: { run }, + workflowService, + dataTableService, + }, + logger, + }; + return { ctx, updateBuildOutcome, queryRows, deleteRows }; +} + +async function runTool( + ctx: VerifyToolContext, + input: { workItemId: string; workflowId: string; inputData?: Record }, +) { + const tool = createVerifyBuiltWorkflowTool(ctx as unknown as OrchestrationContext); + // createTool's execute signature wraps the user function; invoke directly via internal handler + const handler = ( + tool as unknown as { + execute: (input: { + workItemId: string; + workflowId: string; + inputData?: Record; + }) => Promise<{ + success: boolean; + error?: string; + executionId?: string; + status?: string; + data?: Record; + }>; + } + ).execute; + return await handler(input); +} + +describe('verify-built-workflow tool', () => { + it('persists a success verification record onto the build outcome', async () => { + const { ctx, updateBuildOutcome } = makeContext(makeBuildOutcome(), { + executionId: 'exec-1', + status: 'success', + data: { 'Form Trigger': {}, 'Insert Row': {} }, + }); + + const result = await runTool(ctx, { + workItemId: 'wi-1', + workflowId: 'wf-1', + inputData: { name: 'Alice' }, + }); + + expect(result.success).toBe(true); + expect(updateBuildOutcome).toHaveBeenCalledTimes(1); + const call = updateBuildOutcome.mock.calls[0]; + expect(call).toBeDefined(); + const update = call[1]; + expect(update.verification).toMatchObject({ + attempted: true, + success: true, + executionId: 'exec-1', + status: 'success', + }); + expect(update.verification?.evidence?.nodesExecuted).toEqual(['Form Trigger', 'Insert Row']); + expect(typeof update.verification?.verifiedAt).toBe('string'); + }); + + it('persists a failure verification record with failureSignature', async () => { + const { ctx, updateBuildOutcome } = makeContext(makeBuildOutcome(), { + executionId: 'exec-2', + status: 'error', + error: 'Node "Insert Row" crashed', + }); + + const result = await runTool(ctx, { workItemId: 'wi-1', workflowId: 'wf-1' }); + + expect(result.success).toBe(false); + expect(updateBuildOutcome).toHaveBeenCalledTimes(1); + const call = updateBuildOutcome.mock.calls[0]; + expect(call).toBeDefined(); + const update = call[1]; + expect(update.verification).toMatchObject({ + attempted: true, + success: false, + status: 'error', + failureSignature: 'Node "Insert Row" crashed', + evidence: { errorMessage: 'Node "Insert Row" crashed' }, + }); + }); + + it('returns an error result when no build outcome exists', async () => { + const { ctx, updateBuildOutcome } = makeContext(undefined, { + status: 'success', + }); + + const result = await runTool(ctx, { workItemId: 'wi-missing', workflowId: 'wf-1' }); + + expect(result.success).toBe(false); + expect(result.error).toMatch(/No build outcome found/); + expect(updateBuildOutcome).not.toHaveBeenCalled(); + }); + + it('swallows storage errors when persisting verification', async () => { + const { ctx, updateBuildOutcome } = makeContext(makeBuildOutcome(), { + executionId: 'exec-3', + status: 'success', + }); + updateBuildOutcome.mockRejectedValueOnce(new Error('storage unavailable')); + + const result = await runTool(ctx, { workItemId: 'wi-1', workflowId: 'wf-1' }); + + expect(result.success).toBe(true); + expect(result.executionId).toBe('exec-3'); + }); + + it('cleans up rows inserted by the verification run, reading row IDs from the node output', async () => { + const { ctx, deleteRows } = makeContext( + makeBuildOutcome(), + { + executionId: 'exec-4', + status: 'success', + // The insert node's output is what drives the delete set — a concurrent + // writer's row would never appear here, so it's safe from cleanup. + data: { + 'Lead Form': [{ name: 'Test' }], + 'Insert Lead': [{ id: 3, name: 'Test', email: 'test@example.com' }], + }, + }, + { + workflowNodes: [ + { + name: 'Insert Lead', + type: 'n8n-nodes-base.dataTable', + parameters: { operation: 'insert', dataTableId: 'tbl-leads' }, + }, + ], + tableRows: { 'tbl-leads': [{ id: 1 }, { id: 2 }] }, + }, + ); + + const result = await runTool(ctx, { + workItemId: 'wi-1', + workflowId: 'wf-1', + inputData: { name: 'Test' }, + }); + + expect(result.success).toBe(true); + expect(deleteRows).toHaveBeenCalledTimes(1); + const call = deleteRows.mock.calls[0]; + expect(call).toBeDefined(); + expect(call[0]).toBe('tbl-leads'); + expect(call[1]).toEqual({ + type: 'or', + filters: [{ columnName: 'id', condition: 'eq', value: 3 }], + }); + }); + + it('never deletes rows produced by an upsert node, even when the ID looks new', async () => { + // Upsert outputs cannot distinguish a freshly-created row from a match on + // an existing row. A concurrent writer inserting between snapshot and + // upsert would yield an ID that looks "new" to ID-diff but actually + // belongs to that writer — deleting it would destroy production data. + // We therefore skip cleanup for upsert nodes entirely. + const { ctx, deleteRows } = makeContext( + makeBuildOutcome(), + { + executionId: 'exec-upsert', + status: 'success', + data: { + // id=99 is not in the pre-verify snapshot — under the old + // ID-diff logic this would be deleted. The new contract leaves + // it alone because we cannot prove it was created by verify. + 'Upsert Lead': [{ id: 99, name: 'Could be a concurrent writer' }], + }, + }, + { + workflowNodes: [ + { + name: 'Upsert Lead', + type: 'n8n-nodes-base.dataTable', + parameters: { operation: 'upsert', dataTableId: 'tbl-leads' }, + }, + ], + tableRows: { 'tbl-leads': [{ id: 1 }, { id: 2 }] }, + }, + ); + + const result = await runTool(ctx, { workItemId: 'wi-1', workflowId: 'wf-1' }); + + expect(result.success).toBe(true); + expect(deleteRows).not.toHaveBeenCalled(); + }); + + it('does not delete rows from concurrent writers that never appeared in the node output', async () => { + const { ctx, deleteRows } = makeContext( + makeBuildOutcome(), + { + executionId: 'exec-concurrent', + status: 'success', + // The verify's insert node only emitted id=3; a concurrent writer that + // added id=4 after the snapshot would be invisible to us and must NOT + // be deleted. This test asserts the delete set is driven purely by + // node output, not by a post-verify table-wide diff. + data: { + 'Insert Lead': [{ id: 3, name: 'VerifyRow' }], + }, + }, + { + workflowNodes: [ + { + name: 'Insert Lead', + type: 'n8n-nodes-base.dataTable', + parameters: { operation: 'insert', dataTableId: 'tbl-leads' }, + }, + ], + tableRows: { 'tbl-leads': [{ id: 1 }, { id: 2 }] }, + }, + ); + + const result = await runTool(ctx, { workItemId: 'wi-1', workflowId: 'wf-1' }); + + expect(result.success).toBe(true); + expect(deleteRows).toHaveBeenCalledTimes(1); + // Only id=3 (the row our insert node emitted), not id=4 from the concurrent writer. + expect(deleteRows.mock.calls[0][1]).toEqual({ + type: 'or', + filters: [{ columnName: 'id', condition: 'eq', value: 3 }], + }); + }); + + it('treats a waiting status with output as a successful run (e.g. Form Trigger response page)', async () => { + const { ctx, updateBuildOutcome } = makeContext(makeBuildOutcome(), { + executionId: 'exec-form-1', + status: 'waiting', + data: { + 'Lead Form': {}, + 'Insert Lead': {}, + 'Confirmation Page': {}, + }, + }); + + const result = await runTool(ctx, { + workItemId: 'wi-1', + workflowId: 'wf-1', + inputData: { name: 'Alice', email: 'a@b.c' }, + }); + + expect(result.success).toBe(true); + expect(result.status).toBe('waiting'); + expect(updateBuildOutcome).toHaveBeenCalledTimes(1); + const update = updateBuildOutcome.mock.calls[0][1]; + expect(update.verification).toMatchObject({ + attempted: true, + success: true, + status: 'waiting', + }); + }); + + it('treats a waiting status with no output as failure', async () => { + const { ctx } = makeContext(makeBuildOutcome(), { + executionId: 'exec-form-2', + status: 'waiting', + data: {}, + }); + + const result = await runTool(ctx, { workItemId: 'wi-1', workflowId: 'wf-1' }); + + expect(result.success).toBe(false); + }); + + it('paginates the pre-verify snapshot so a pathological insert output cannot delete a pre-existing row past the first page', async () => { + // Build a table with 1500 rows — past the snapshot page size. + // The insert node's output is `id=1234` (a row that already existed). If + // pagination is broken the snapshot only contains ids 1..1000, and the + // snapshot's defensive filter wouldn't protect id=1234 — the cleanup + // would delete a pre-existing row. + const bigTable: Array> = Array.from({ length: 1500 }, (_v, i) => ({ + id: i + 1, + })); + const { ctx, deleteRows, queryRows } = makeContext( + makeBuildOutcome(), + { + executionId: 'exec-insert-past-page', + status: 'success', + data: { + // Insert node's output references id=1234 — beyond the single-page cap. + 'Insert Lead': [{ id: 1234, name: 'Existing', stage: 'qualified' }], + }, + }, + { + workflowNodes: [ + { + name: 'Insert Lead', + type: 'n8n-nodes-base.dataTable', + parameters: { operation: 'insert', dataTableId: 'tbl-leads' }, + }, + ], + tableRows: { 'tbl-leads': bigTable }, + }, + ); + + const result = await runTool(ctx, { workItemId: 'wi-1', workflowId: 'wf-1' }); + + expect(result.success).toBe(true); + // Must have made more than one snapshot query to cover a 1500-row table. + const snapshotCalls = queryRows.mock.calls.filter( + (c) => c[0] === 'tbl-leads' && typeof (c[1] as { offset?: number })?.offset === 'number', + ); + expect(snapshotCalls.length).toBeGreaterThan(1); + // And the pre-existing row must not have been deleted. + expect(deleteRows).not.toHaveBeenCalled(); + }); + + it('skips insert cleanup for a table when the pre-verify snapshot read fails', async () => { + const { ctx, deleteRows } = makeContext( + makeBuildOutcome(), + { + executionId: 'exec-snapshot-fail', + status: 'success', + data: { + 'Insert Lead': [{ id: 42, name: 'Existing', stage: 'qualified' }], + }, + }, + { + workflowNodes: [ + { + name: 'Insert Lead', + type: 'n8n-nodes-base.dataTable', + parameters: { operation: 'insert', dataTableId: 'tbl-leads' }, + }, + ], + tableRows: { 'tbl-leads': [{ id: 42 }] }, + snapshotErrors: { 'tbl-leads': new Error('DB unavailable') }, + }, + ); + + const result = await runTool(ctx, { workItemId: 'wi-1', workflowId: 'wf-1' }); + + expect(result.success).toBe(true); + expect(deleteRows).not.toHaveBeenCalled(); + }); + + it('does not delete rows for dataTable nodes that only read', async () => { + const { ctx, deleteRows } = makeContext( + makeBuildOutcome(), + { + executionId: 'exec-5', + status: 'success', + data: { 'Lookup Lead': [{ id: 1, name: 'Existing' }] }, + }, + { + workflowNodes: [ + { + name: 'Lookup Lead', + type: 'n8n-nodes-base.dataTable', + parameters: { operation: 'get', dataTableId: 'tbl-leads' }, + }, + ], + tableRows: { 'tbl-leads': [{ id: 1 }] }, + }, + ); + + const result = await runTool(ctx, { workItemId: 'wi-1', workflowId: 'wf-1' }); + + expect(result.success).toBe(true); + expect(deleteRows).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/add-plan-item.tool.ts b/packages/@n8n/instance-ai/src/tools/orchestration/add-plan-item.tool.ts index c82986ca07d..38f3541f709 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/add-plan-item.tool.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/add-plan-item.tool.ts @@ -11,6 +11,7 @@ import { z } from 'zod'; import type { BlueprintAccumulator } from './blueprint-accumulator'; import { + blueprintCheckpointItemSchema, blueprintDataTableItemSchema, blueprintDelegateItemSchema, blueprintResearchItemSchema, @@ -52,6 +53,7 @@ const addPlanItemInputSchema = z.object({ blueprintDataTableItemSchema.extend({ kind: z.literal('data-table') }), blueprintResearchItemSchema.extend({ kind: z.literal('research') }), blueprintDelegateItemSchema.extend({ kind: z.literal('delegate') }), + blueprintCheckpointItemSchema.extend({ kind: z.literal('checkpoint') }), ]), }); @@ -62,9 +64,10 @@ export function createAddPlanItemTool( return createTool({ id: 'add-plan-item', description: - 'Add a single plan item (data table, workflow, research, or delegate task). ' + + 'Add a single plan item (data table, workflow, research, delegate, or checkpoint task). ' + 'Call once per item as you design it — each call makes the item visible to the user immediately. ' + 'Emit data tables FIRST. Add workflow items only if the request requires automation. ' + + 'Add a checkpoint item AFTER its target workflow(s) so the orchestrator can verify the result end-to-end. ' + 'Set summary and assumptions on your first call.', inputSchema: addPlanItemInputSchema, outputSchema: z.object({ result: z.string() }), diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/blueprint-accumulator.ts b/packages/@n8n/instance-ai/src/tools/orchestration/blueprint-accumulator.ts index 517d36b1b28..33baaa36f9c 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/blueprint-accumulator.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/blueprint-accumulator.ts @@ -9,6 +9,7 @@ */ import type { + BlueprintCheckpointItem, BlueprintDataTableItem, BlueprintDelegateItem, BlueprintResearchItem, @@ -37,7 +38,8 @@ type BlueprintItem = | (BlueprintWorkflowItem & { kind: 'workflow' }) | (BlueprintDataTableItem & { kind: 'data-table' }) | (BlueprintResearchItem & { kind: 'research' }) - | (BlueprintDelegateItem & { kind: 'delegate' }); + | (BlueprintDelegateItem & { kind: 'delegate' }) + | (BlueprintCheckpointItem & { kind: 'checkpoint' }); // --------------------------------------------------------------------------- // Per-item conversion helpers @@ -147,6 +149,16 @@ function delegateItemToTask(di: BlueprintDelegateItem): PlannedTaskInput { }; } +function checkpointItemToTask(c: BlueprintCheckpointItem): PlannedTaskInput { + return { + id: c.id, + title: c.title, + kind: 'checkpoint', + spec: c.instructions, + deps: c.dependsOn, + }; +} + // --------------------------------------------------------------------------- // BlueprintAccumulator // --------------------------------------------------------------------------- @@ -160,6 +172,8 @@ export class BlueprintAccumulator { private delegateItems: BlueprintDelegateItem[] = []; + private checkpoints: BlueprintCheckpointItem[] = []; + private tasks: PlannedTaskInput[] = []; private summary = ''; @@ -197,6 +211,12 @@ export class BlueprintAccumulator { task = delegateItemToTask(di); break; } + case 'checkpoint': { + const { kind: _, ...c } = item; + this.upsertArray(this.checkpoints, c); + task = checkpointItemToTask(c); + break; + } } this.upsertTask(task); @@ -235,7 +255,10 @@ export class BlueprintAccumulator { } } - /** Remove an item by ID. Returns true if found and removed. */ + /** Remove an item by ID. Returns true if found and removed. + * Cascade-removes any checkpoint that loses its last build-workflow dep as + * a result — otherwise submit-plan would later fail validation because + * checkpoints must depend on at least one build-workflow task. */ removeItem(id: string): boolean { const taskIdx = this.tasks.findIndex((t) => t.id === id); if (taskIdx < 0) return false; @@ -245,10 +268,26 @@ export class BlueprintAccumulator { this.removeFromArray(this.workflows, id); this.removeFromArray(this.researchItems, id); this.removeFromArray(this.delegateItems, id); + this.removeFromArray(this.checkpoints, id); // Clean up dangling dep references in remaining tasks for (const task of this.tasks) { task.deps = task.deps.filter((dep) => dep !== id); } + + // Cascade-remove orphaned checkpoints: any checkpoint whose deps no + // longer reference a build-workflow task is invalid and must go too. + const workflowIds = new Set(this.workflows.map((w) => w.id)); + const orphanedCheckpointIds: string[] = []; + for (const cp of this.checkpoints) { + const stillHasWorkflowDep = cp.dependsOn.some((depId) => workflowIds.has(depId)); + if (!stillHasWorkflowDep) { + orphanedCheckpointIds.push(cp.id); + } + } + for (const orphanId of orphanedCheckpointIds) { + this.removeItem(orphanId); + } + return true; } diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/blueprint.schema.ts b/packages/@n8n/instance-ai/src/tools/orchestration/blueprint.schema.ts index 70905d2026e..81a380b96ec 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/blueprint.schema.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/blueprint.schema.ts @@ -54,6 +54,24 @@ export const blueprintDelegateItemSchema = z.object({ dependsOn: z.array(z.string()).default([]), }); +export const blueprintCheckpointItemSchema = z.object({ + id: z.string().describe('Stable ID — preserved as task ID'), + title: z + .string() + .describe( + 'User-readable verification goal (e.g., "Verify Daily Email workflow runs without errors")', + ), + instructions: z + .string() + .describe( + 'Detailed verification steps the orchestrator must execute — which tools to call, the expected pass condition. The orchestrator runs this itself (no sub-agent).', + ), + dependsOn: z + .array(z.string()) + .min(1) + .describe('IDs of items this checkpoint verifies. Must include at least one workflow item ID.'), +}); + // --------------------------------------------------------------------------- // Top-level blueprint schema // --------------------------------------------------------------------------- @@ -64,6 +82,7 @@ export const planningBlueprintSchema = z.object({ dataTables: z.array(blueprintDataTableItemSchema).default([]), researchItems: z.array(blueprintResearchItemSchema).default([]), delegateItems: z.array(blueprintDelegateItemSchema).default([]), + checkpointItems: z.array(blueprintCheckpointItemSchema).default([]), assumptions: z.array(z.string()).default([]).describe('Assumptions the plan relies on'), openQuestions: z .array(z.string()) @@ -76,3 +95,4 @@ export type BlueprintWorkflowItem = z.infer; export type BlueprintDataTableItem = z.infer; export type BlueprintResearchItem = z.infer; export type BlueprintDelegateItem = z.infer; +export type BlueprintCheckpointItem = z.infer; diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/build-workflow-agent.prompt.ts b/packages/@n8n/instance-ai/src/tools/orchestration/build-workflow-agent.prompt.ts index b60cd81268c..8dfbaf53701 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/build-workflow-agent.prompt.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/build-workflow-agent.prompt.ts @@ -274,17 +274,24 @@ const SANDBOX_WORKFLOW_RULES = `Follow these rules strictly when generating work - Example: \`credentials: { slackApi: { id: 'yXYBqho73obh58ZS', name: 'Slack Bot' } }\` - The key (e.g. \`slackApi\`) is the credential **type** from the node type definition -2. **Handle empty outputs with \`alwaysOutputData: true\`** - - Nodes that query data (Data Table get, Google Sheets lookup, HTTP Request, etc.) may return 0 items - - When a node returns 0 items, all downstream nodes are SKIPPED — the workflow chain breaks silently - - Set \`alwaysOutputData: true\` on any node whose output feeds downstream nodes and might return empty results - - Common cases: fresh/empty Data Tables, filtered queries, conditional lookups, API searches with no matches - - Example: \`config: { ..., alwaysOutputData: true }\` +2. **Trust empty item lists — don't synthesize fake items** + - When a query returns 0 items, downstream nodes simply don't run for that execution. For scheduled or polling triggers this is the correct "nothing to do this round" signal — the next run will execute normally when data appears. + - DO NOT add \`alwaysOutputData: true\` just to "keep the chain alive." Forcing an empty \`{}\` item downstream is what causes \`undefined\` reads, failed HTTP calls to \`GET undefined\`, and Code-node crashes on missing fields. + - DO NOT add an IF gate before a loop to check "has items?" — loops (\`splitInBatches\`, per-item nodes, \`filter\`) already no-op on empty input. The gate is redundant and adds a failure surface. + - \`alwaysOutputData: true\` is only correct when you specifically need a downstream branch to run on the "empty" case — e.g. a dedicated "no matches found" notification path. In that case, pair it with an \`IF\` that explicitly checks for the empty case and routes accordingly. Never use it as a default. + - To drop invalid items mid-pipeline, use a \`filter\` node. A \`filter\` that rejects everything emits 0 items and the chain correctly stops — no \`IF\` + \`splitInBatches\` composition needed. 3. **Use \`executeOnce: true\` for single-execution nodes** - When a node receives N items but should only execute once (not N times), set \`executeOnce: true\` - Common cases: sending a summary notification, generating a report, calling an API that doesn't need per-item execution - - Example: \`config: { ..., executeOnce: true }\``; + - Example: \`config: { ..., executeOnce: true }\` + +4. **Pick the right control-flow primitive** + - **Per-item loop with side effects (fetch, embed, write)** → \`splitInBatches\` with \`batchSize: 1\` feeding the per-item work, loop back via \`nextBatch\`. No \`IF\` gate before it. + - **Drop items that don't match a predicate** → \`filter\`. It emits 0 items when nothing matches, and the chain stops cleanly. + - **Two mutually exclusive paths that both do real work** → \`IF\` (\`onTrue\` / \`onFalse\`). + - **Many mutually exclusive paths keyed off a value** → \`switch\` (\`onCase\`). + - Nested control flow is supported: \`ifNode.onTrue(loopBuilder)\`, \`switchNode.onCase(0, loopBuilder)\`, and \`splitInBatches(sib).onEachBatch(ifElseBuilder)\` all compile and wire correctly. Use them when the semantics genuinely call for it, not as a workaround for empty-list handling.`; function composeSdkRulesAndPatterns(mode: 'tool' | 'sandbox'): string { // Shared WORKFLOW_SDK_PATTERNS uses `newCredential('X')` throughout. That diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/build-workflow-agent.tool.ts b/packages/@n8n/instance-ai/src/tools/orchestration/build-workflow-agent.tool.ts index a2979ba03f0..21244aab1a1 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/build-workflow-agent.tool.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/build-workflow-agent.tool.ts @@ -29,6 +29,7 @@ import { createVerifyBuiltWorkflowTool } from './verify-built-workflow.tool'; import { registerWithMastra } from '../../agent/register-with-mastra'; import { buildSubAgentBriefing } from '../../agent/sub-agent-briefing'; import { MAX_STEPS } from '../../constants/max-steps'; +import { TEMPERATURE } from '../../constants/model-settings'; import type { Logger } from '../../logger'; import { createLlmStepTraceHooks } from '../../runtime/resumable-stream-executor'; import { consumeStreamWithHitl } from '../../stream/consume-with-hitl'; @@ -48,20 +49,6 @@ import { buildCredentialMap, type CredentialMap } from '../workflows/resolve-cre import { createIdentityEnforcedSubmitWorkflowTool } from '../workflows/submit-workflow-identity'; import { type SubmitWorkflowAttempt } from '../workflows/submit-workflow.tool'; -/** Trigger types that cannot be test-fired programmatically (need an external request). */ -const UNTESTABLE_TRIGGERS = new Set([ - 'n8n-nodes-base.webhook', - 'n8n-nodes-base.formTrigger', - '@n8n/n8n-nodes-langchain.mcpTrigger', - '@n8n/n8n-nodes-langchain.chatTrigger', -]); - -/** Human-readable label derived from a node type string, e.g. "n8n-nodes-base.formTrigger" → "form" */ -function triggerLabel(nodeType: string): string { - const short = nodeType.split('.').pop() ?? nodeType; - return short.replace(/Trigger$/i, '').toLowerCase() || short.toLowerCase(); -} - /** * Clear the AI-builder temporary marker from the build's main workflow so the * run-finish reap leaves it alone. Best-effort: a failure here means the @@ -113,14 +100,13 @@ export function recordSuccessfulWorkflowBuilds( }; } -const UNTESTABLE_TRIGGER_LABELS = [...UNTESTABLE_TRIGGERS].map(triggerLabel).join(', '); - -function detectTriggerType(attempt: SubmitWorkflowAttempt | undefined): TriggerType { - if (!attempt?.triggerNodeTypes || attempt.triggerNodeTypes.length === 0) { - return 'manual_or_testable'; - } - const allUntestable = attempt.triggerNodeTypes.every((t) => UNTESTABLE_TRIGGERS.has(t)); - return allUntestable ? 'trigger_only' : 'manual_or_testable'; +function detectTriggerType(_attempt: SubmitWorkflowAttempt | undefined): TriggerType { + // Every trigger type the builder can produce is testable — manual/schedule via + // `executions(action="run")`, event-based via `verify-built-workflow` with inputData. + // `trigger_only` is reserved for workflows the builder could not fully wire + // (e.g. unresolved placeholders), which is detected separately via + // `hasUnresolvedPlaceholders` in buildOutcome(). + return 'manual_or_testable'; } function buildOutcome( @@ -164,9 +150,13 @@ You are running as a detached background task. Do not stop after a successful su Your job is done when ONE of these is true: - the workflow is verified (ran successfully) -- the workflow uses only event triggers (${UNTESTABLE_TRIGGER_LABELS}) and cannot be runtime-tested — stop after a successful submit. Do NOT publish it; the orchestrator will handle setup and publishing. - you are blocked after one repair attempt per unique failure +Do NOT stop after a successful submit without verifying. Every trigger type is testable: +manual / schedule via \`executions(action="run")\`; event-based triggers (form, webhook, +chat, mcp, linear, github, slack, etc.) via \`verify-built-workflow\` with an \`inputData\` +payload. The pin-data adapter injects it as the trigger node's output. + ### Submit discipline **Every file edit MUST be followed by submit-workflow before you do anything else.** @@ -174,8 +164,13 @@ The system tracks file hashes. If you edit the code and then call \`executions(a ### Verification -- If submit-workflow returned mocked credentials, call verify-built-workflow with the workItemId -- Otherwise call \`executions(action="run")\` to test (skip for trigger-only workflows). For event-based triggers (Linear, GitHub, Slack, etc.), pass \`inputData\` with sample data matching the trigger's expected output shape — the system injects it as the trigger node's output. +- If submit-workflow returned mocked credentials, call \`verify-built-workflow\` with the workItemId. +- Otherwise pick based on trigger type: + - **Manual / Schedule** — \`executions(action="run")\`. + - **Form Trigger** — \`verify-built-workflow\` with \`inputData\` as a flat field map, e.g. \`{name: "Alice", email: "a@b.c"}\`. Do NOT wrap in \`formFields\` — production Form Trigger emits fields directly on \`$json\`, and the adapter rejects wrapped payloads. + - **Webhook** — \`verify-built-workflow\` with \`inputData\` as the body payload, e.g. \`{event: "signup", userId: "..."}\`. Adapter wraps it under \`body\`; downstream expressions use \`$json.body.\`. + - **Chat Trigger** — \`verify-built-workflow\` with \`{chatInput: "user message"}\`. + - **Other event triggers (Linear, GitHub, Slack, MCP, etc.)** — \`verify-built-workflow\` with \`inputData\` matching the trigger's expected payload shape. - If verification fails, call \`executions(action="debug")\`, fix the code, re-submit, and retry once - If the same failure signature repeats, stop and explain the block @@ -314,25 +309,6 @@ export async function startBuildWorkflowAgentTask( const taskId = input.taskId ?? `build-${nanoid(8)}`; const workItemId = `wi_${nanoid(8)}`; - context.eventBus.publish(context.threadId, { - type: 'agent-spawned', - runId: context.runId, - agentId: subAgentId, - payload: { - parentId: context.orchestratorAgentId, - role: 'workflow-builder', - tools: Object.keys(builderTools), - taskId, - kind: 'builder', - title: 'Building workflow', - subtitle: truncateLabel(input.task), - goal: input.task, - targetResource: input.workflowId - ? { type: 'workflow' as const, id: input.workflowId } - : { type: 'workflow' as const }, - }, - }); - const { workflowId } = input; // Build additional context based on sandbox mode and existing workflow @@ -373,7 +349,7 @@ export async function startBuildWorkflowAgentTask( }, }); - context.spawnBackgroundTask({ + const spawnOutcome = context.spawnBackgroundTask({ taskId, threadId: context.threadId, agentId: subAgentId, @@ -381,6 +357,18 @@ export async function startBuildWorkflowAgentTask( traceContext, plannedTaskId: input.plannedTaskId, workItemId, + dedupeKey: { + role: 'workflow-builder', + plannedTaskId: input.plannedTaskId, + workflowId: input.workflowId, + }, + // When the orchestrator spawns a builder inside a checkpoint follow-up + // (e.g. to patch a runtime bug the verify exposed), tag the task so the + // safety net doesn't pre-emptively fail the checkpoint and the + // settlement path can re-enter the checkpoint context instead of a + // bare background-task-completed shell. + parentCheckpointId: + context.isCheckpointFollowUp === true ? context.checkpointTaskId : undefined, run: async (signal, drainCorrections, waitForCorrection): Promise => await withTraceContextActor(traceContext, async () => { let builderWs: BuilderWorkspace | undefined; @@ -483,6 +471,7 @@ export async function startBuildWorkflowAgentTask( const stream = await subAgent.stream(briefing, { maxSteps: MAX_STEPS.BUILDER, abortSignal: signal, + modelSettings: { temperature: TEMPERATURE.BUILDER }, providerOptions: { anthropic: { cacheControl: { type: 'ephemeral' } }, }, @@ -632,6 +621,7 @@ export async function startBuildWorkflowAgentTask( const stream = await subAgent.stream(briefing, { maxSteps: MAX_STEPS.BUILDER, abortSignal: signal, + modelSettings: { temperature: TEMPERATURE.BUILDER }, providerOptions: { anthropic: { cacheControl: { type: 'ephemeral' } }, }, @@ -667,6 +657,43 @@ export async function startBuildWorkflowAgentTask( }), }); + if (spawnOutcome.status === 'duplicate') { + return { + result: `Workflow build already in progress (task: ${spawnOutcome.existing.taskId}). Acknowledge and wait for the planned-task-follow-up — do not dispatch again.`, + taskId: spawnOutcome.existing.taskId, + agentId: spawnOutcome.existing.agentId, + }; + } + if (spawnOutcome.status === 'limit-reached') { + return { + result: + 'Could not start build: concurrent background-task limit reached. Wait for an existing task to finish and try again.', + taskId: '', + agentId: '', + }; + } + + // Spawn confirmed — publish the UI event now so duplicate/limit-reached + // rejections above don't leave a phantom builder card on the chat surface. + context.eventBus.publish(context.threadId, { + type: 'agent-spawned', + runId: context.runId, + agentId: subAgentId, + payload: { + parentId: context.orchestratorAgentId, + role: 'workflow-builder', + tools: Object.keys(builderTools), + taskId, + kind: 'builder', + title: 'Building workflow', + subtitle: truncateLabel(input.task), + goal: input.task, + targetResource: input.workflowId + ? { type: 'workflow' as const, id: input.workflowId } + : { type: 'workflow' as const }, + }, + }); + return { result: `Workflow build started (task: ${taskId}). Reply with one short sentence — e.g. name what's being built. Do NOT summarize the plan or list details.`, taskId, @@ -692,21 +719,95 @@ export const buildWorkflowAgentInputSchema = z.object({ .describe( 'Brief summary of the conversation so far — what was discussed, decisions made, and information gathered (e.g., which credentials are available). The builder uses this to avoid repeating information the user already knows.', ), + bypassPlan: z + .boolean() + .optional() + .describe( + 'Set to true for any edit to an existing workflow — adding/removing/rewiring a node, changing an expression, swapping a credential, changing a schedule, fixing a Code node. Requires an existing `workflowId` and a one-sentence `reason`. The orchestrator verifies the result afterwards via `verify-built-workflow` when the trigger is mockable. ' + + 'A runtime guard rejects direct calls without `bypassPlan: true` outside replan/checkpoint follow-ups: new workflow builds, multi-workflow work, and data-table schema changes must go through `plan` so the build gets its orchestrator-run checkpoint.', + ), + reason: z + .string() + .optional() + .describe( + 'One sentence explaining why the planner is being bypassed (e.g. "swap Slack channel on workflow X", "fix Code node shape issue"). Required when bypassPlan is true.', + ), }); +/** + * Replan / checkpoint follow-ups have already paid the planner's discovery cost + * and carry the checkpoint task graph from the original plan — direct builder + * calls in those contexts are legitimate (e.g. retry the one failing task). + */ +function isPostPlanFollowUp(context: OrchestrationContext): boolean { + return context.isReplanFollowUp === true || context.isCheckpointFollowUp === true; +} + +function isBuildViaPlanGuardEnabled(): boolean { + const raw = process.env.N8N_INSTANCE_AI_ENFORCE_BUILD_VIA_PLAN; + if (raw === undefined) return true; + return raw.toLowerCase() !== 'false' && raw !== '0'; +} + export function createBuildWorkflowAgentTool(context: OrchestrationContext) { return createTool({ id: 'build-workflow-with-agent', description: 'Build or modify an n8n workflow using a specialized builder agent. ' + - 'The agent handles node discovery, schema lookups, code generation, ' + - 'and validation internally.', + 'The agent handles node discovery, schema lookups, code generation, and validation internally. ' + + 'For edits to an existing workflow, call directly with `bypassPlan: true`, the existing `workflowId`, and a one-sentence `reason` — the orchestrator runs a lightweight verify afterwards. ' + + 'For new workflows, multi-workflow builds, or data-table schema changes, go through `plan` — ' + + 'a runtime guard rejects direct calls without `bypassPlan: true` outside replan/checkpoint follow-ups, because those paths need the orchestrator-run checkpoint for end-to-end verification.', inputSchema: buildWorkflowAgentInputSchema, outputSchema: z.object({ result: z.string(), taskId: z.string(), }), execute: async (input: z.infer) => { + if (isBuildViaPlanGuardEnabled() && !isPostPlanFollowUp(context)) { + if (!input.bypassPlan) { + context.logger.warn( + 'build-workflow-with-agent called outside plan/replan context — rejecting', + { + threadId: context.threadId, + hasWorkflowId: Boolean(input.workflowId), + }, + ); + return { + result: + 'Error: direct builder calls require `bypassPlan: true` + an existing ' + + '`workflowId` + a one-sentence `reason`. Use that combination for any edit to ' + + 'an existing workflow. For new workflows, multi-workflow builds, or data-table ' + + 'schema changes, call `plan` with a `build-workflow` task instead — the planner ' + + 'discovers credentials, data tables, and best practices, and schedules an ' + + 'orchestrator-run verification checkpoint.', + taskId: '', + }; + } + if (!input.workflowId) { + return { + result: + 'Error: `bypassPlan: true` is for edits to an EXISTING workflow and requires a ' + + '`workflowId`. New workflow builds must go through `plan` so an orchestrator-run ' + + 'verification checkpoint is scheduled. Call `plan` with a `build-workflow` task ' + + 'instead.', + taskId: '', + }; + } + if (!input.reason || input.reason.trim().length === 0) { + return { + result: + 'Error: `bypassPlan: true` requires a one-sentence `reason` describing the edit ' + + '(e.g. "swap Slack channel", "fix Code node shape issue").', + taskId: '', + }; + } + context.logger.warn('build-workflow-with-agent bypassing plan with bypassPlan=true', { + threadId: context.threadId, + workflowId: input.workflowId, + reason: input.reason, + }); + } const result = await startBuildWorkflowAgentTask(context, input); return { result: result.result, taskId: result.taskId }; }, diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/complete-checkpoint.tool.ts b/packages/@n8n/instance-ai/src/tools/orchestration/complete-checkpoint.tool.ts new file mode 100644 index 00000000000..a46049617a4 --- /dev/null +++ b/packages/@n8n/instance-ai/src/tools/orchestration/complete-checkpoint.tool.ts @@ -0,0 +1,102 @@ +/** + * complete-checkpoint tool — called by the orchestrator to settle a planned-task + * checkpoint. + * + * The service enqueues an internal follow-up run carrying a checkpoint's spec. + * The orchestrator executes the spec using its normal tools (verify-built-workflow, + * executions(action="run"), etc.) and then MUST call this tool exactly once to + * report the outcome. The service's post-run deadlock fallback guarantees + * progress even if the orchestrator forgets. + */ + +import { createTool } from '@mastra/core/tools'; +import { z } from 'zod'; + +import type { OrchestrationContext } from '../../types'; + +const inputSchema = z.object({ + taskId: z.string().describe('The checkpoint task ID from the payload'), + status: z + .enum(['succeeded', 'failed']) + .describe('Whether the verification passed (succeeded) or failed (failed)'), + result: z + .string() + .optional() + .describe('Short user-visible note describing the verification outcome'), + error: z.string().optional().describe('Error message when status=failed'), + outcome: z + .record(z.unknown()) + .optional() + .describe('Structured outcome payload (e.g., executionId, failureNode, data excerpt)'), +}); + +const outputSchema = z.object({ + result: z.string(), + ok: z.boolean(), +}); + +export function createCompleteCheckpointTool(context: OrchestrationContext) { + return createTool({ + id: 'complete-checkpoint', + description: + 'Report the outcome of a planned-task checkpoint you just executed. ' + + 'Call this exactly once per block. ' + + 'Only valid for tasks of kind "checkpoint" that are currently running; ' + + 'calling with any other taskId returns an error and does not modify the graph.', + inputSchema, + outputSchema, + execute: async (input: z.infer) => { + if (!context.plannedTaskService) { + return { ok: false, result: 'Error: planned task service not available.' }; + } + + const settleResult = + input.status === 'succeeded' + ? await context.plannedTaskService.markCheckpointSucceeded( + context.threadId, + input.taskId, + { + result: input.result, + outcome: input.outcome, + }, + ) + : await context.plannedTaskService.markCheckpointFailed(context.threadId, input.taskId, { + error: input.error ?? input.result ?? 'Checkpoint verification failed', + // Preserve structured outcome (executionId, failureNode, data excerpt). + // Without this, replans only see a flat error string and lose execution + // context that would otherwise seed a targeted retry. + outcome: input.outcome, + }); + + if (settleResult.ok) { + return { + ok: true, + result: `Checkpoint ${input.taskId} marked ${input.status}.`, + }; + } + + const reason = settleResult.reason; + if (reason === 'not-found') { + return { + ok: false, + result: `Error: no task with id "${input.taskId}" exists in the current plan.`, + }; + } + if (reason === 'wrong-kind') { + return { + ok: false, + result: + `Error: task "${input.taskId}" is not a checkpoint ` + + `(actual kind: ${settleResult.actual?.kind ?? 'unknown'}). ` + + 'complete-checkpoint can only settle checkpoint tasks.', + }; + } + return { + ok: false, + result: + `Error: checkpoint "${input.taskId}" is not in running state ` + + `(actual status: ${settleResult.actual?.status ?? 'unknown'}).`, + }; + }, + }); +} diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/data-table-agent.tool.ts b/packages/@n8n/instance-ai/src/tools/orchestration/data-table-agent.tool.ts index 7a26417e69b..6eb8c57e66f 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/data-table-agent.tool.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/data-table-agent.tool.ts @@ -72,22 +72,6 @@ export async function startDataTableAgentTask( const subAgentId = input.agentId ?? `agent-datatable-${nanoid(6)}`; const taskId = input.taskId ?? `datatable-${nanoid(8)}`; - context.eventBus.publish(context.threadId, { - type: 'agent-spawned', - runId: context.runId, - agentId: subAgentId, - payload: { - parentId: context.orchestratorAgentId, - role: 'data-table-manager', - tools: Object.keys(dataTableTools), - taskId, - kind: 'data-table', - title: 'Managing data table', - subtitle: truncateLabel(input.task), - goal: input.task, - targetResource: { type: 'data-table' as const }, - }, - }); const traceContext = await createDetachedSubAgentTracing(context, { agentId: subAgentId, role: 'data-table-manager', @@ -101,13 +85,16 @@ export async function startDataTableAgentTask( }); const tracedDataTableTools = traceSubAgentTools(context, dataTableTools, 'data-table-manager'); - context.spawnBackgroundTask({ + const spawnOutcome = context.spawnBackgroundTask({ taskId, threadId: context.threadId, agentId: subAgentId, role: 'data-table-manager', traceContext, plannedTaskId: input.plannedTaskId, + dedupeKey: { role: 'data-table-manager', plannedTaskId: input.plannedTaskId }, + parentCheckpointId: + context.isCheckpointFollowUp === true ? context.checkpointTaskId : undefined, run: async (signal, _drainCorrections, _waitForCorrection) => { return await withTraceContextActor(traceContext, async () => { const subAgent = new Agent({ @@ -175,6 +162,41 @@ export async function startDataTableAgentTask( }, }); + if (spawnOutcome.status === 'duplicate') { + return { + result: `Data table operation already in progress (task: ${spawnOutcome.existing.taskId}). Wait for the planned-task-follow-up — do not dispatch again.`, + taskId: spawnOutcome.existing.taskId, + agentId: spawnOutcome.existing.agentId, + }; + } + if (spawnOutcome.status === 'limit-reached') { + return { + result: + 'Could not start data table operation: concurrent background-task limit reached. Wait for an existing task to finish and try again.', + taskId: '', + agentId: '', + }; + } + + // Spawn confirmed — publish the UI event now so duplicate/limit-reached + // rejections above don't leave a phantom card on the chat surface. + context.eventBus.publish(context.threadId, { + type: 'agent-spawned', + runId: context.runId, + agentId: subAgentId, + payload: { + parentId: context.orchestratorAgentId, + role: 'data-table-manager', + tools: Object.keys(dataTableTools), + taskId, + kind: 'data-table', + title: 'Managing data table', + subtitle: truncateLabel(input.task), + goal: input.task, + targetResource: { type: 'data-table' as const }, + }, + }); + return { result: `Data table operation started (task: ${taskId}). Do NOT summarize the plan or list details.`, taskId, diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/delegate.tool.ts b/packages/@n8n/instance-ai/src/tools/orchestration/delegate.tool.ts index 107ca499ce1..59e4b879eed 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/delegate.tool.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/delegate.tool.ts @@ -129,22 +129,6 @@ export async function startDetachedDelegateTask( const subAgentId = input.agentId ?? `agent-delegate-${nanoid(6)}`; const taskId = input.taskId ?? `delegate-${nanoid(8)}`; - context.eventBus.publish(context.threadId, { - type: 'agent-spawned', - runId: context.runId, - agentId: subAgentId, - payload: { - parentId: context.orchestratorAgentId, - role, - tools: input.tools, - taskId, - kind: 'delegate', - title: input.title, - subtitle: truncateLabel(input.spec), - goal: input.spec, - }, - }); - const briefingMessage = await buildDelegateBriefing( context, role, @@ -167,13 +151,16 @@ export async function startDetachedDelegateTask( }); const tracedTools = traceSubAgentTools(context, validTools, role); - context.spawnBackgroundTask({ + const spawnOutcome = context.spawnBackgroundTask({ taskId, threadId: context.threadId, agentId: subAgentId, role, traceContext, plannedTaskId: input.plannedTaskId, + dedupeKey: { role, plannedTaskId: input.plannedTaskId }, + parentCheckpointId: + context.isCheckpointFollowUp === true ? context.checkpointTaskId : undefined, run: async (signal, drainCorrections, waitForCorrection) => { return await withTraceContextActor(traceContext, async () => { const subAgent = createSubAgent({ @@ -226,6 +213,40 @@ export async function startDetachedDelegateTask( }, }); + if (spawnOutcome.status === 'duplicate') { + return { + result: `Delegation already in progress (task: ${spawnOutcome.existing.taskId}). Wait for the planned-task-follow-up — do not dispatch again.`, + taskId: spawnOutcome.existing.taskId, + agentId: spawnOutcome.existing.agentId, + }; + } + if (spawnOutcome.status === 'limit-reached') { + return { + result: + 'Could not start delegation: concurrent background-task limit reached. Wait for an existing task to finish and try again.', + taskId: '', + agentId: '', + }; + } + + // Spawn confirmed — publish the UI event now so duplicate/limit-reached + // rejections above don't leave a phantom card on the chat surface. + context.eventBus.publish(context.threadId, { + type: 'agent-spawned', + runId: context.runId, + agentId: subAgentId, + payload: { + parentId: context.orchestratorAgentId, + role, + tools: input.tools, + taskId, + kind: 'delegate', + title: input.title, + subtitle: truncateLabel(input.spec), + goal: input.spec, + }, + }); + return { result: `Delegation started (task: ${taskId}). Do NOT summarize the plan or list details.`, taskId, diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/plan-agent-prompt.ts b/packages/@n8n/instance-ai/src/tools/orchestration/plan-agent-prompt.ts index ee87116a3cc..be0cb5f1626 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/plan-agent-prompt.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/plan-agent-prompt.ts @@ -66,8 +66,14 @@ ${NATIVE_NODE_PREFERENCE} ## Critical Rules +- **User time zone is in context as \`\` / \`\`.** Schedule times, cron expressions, and digest times must be stated in the user's time zone. Never write "instance default timezone" or leave the zone ambiguous — spell it out (e.g. "daily at 08:00 America/New_York"). - **Dependencies are mandatory.** Every workflow must list the data table IDs it reads from or writes to in \`dependsOn\`. If workflow C needs data from A and B, it must depend on both. - **No duplicate items.** Each piece of work appears exactly once. Use \`workflow\` kind for workflows, \`data-table\` kind for all data table operations (create, delete, modify, seed), \`research\` kind for web research. Use \`delegate\` only for tasks that don't fit the other kinds — never for data table operations. - **Data-table-only plans are valid.** When the request is purely about data tables (no triggers, schedules, or integrations), use only \`data-table\` items — don't wrap them in \`workflow\` or \`delegate\`. For creation, include \`columns\`; for other operations, omit \`columns\` and describe the operation in \`purpose\`. Include seed rows in \`purpose\` when the user wants sample data. - **Each item's \`purpose\` describes only that item.** Do not reference work handled by other plan items — each agent only sees its own spec, and cross-task context causes scope creep. +- **Workflow verification is mandatory.** For **every** \`workflow\` item you add, also add a \`checkpoint\` item whose \`dependsOn\` includes that workflow's ID. Checkpoints are orchestrator-executed — the orchestrator runs them itself using its own tools, they are not delegated. + - \`title\`: a user-readable verification goal, e.g. \`"Verify 'Daily API Email' workflow runs successfully"\`. + - \`instructions\`: detailed steps the orchestrator must execute. Prefer \`verify-built-workflow\` with the work item ID from the build outcome — it uses pin data captured at build time, so it works even for event-triggered workflows (webhook, form, chat, mcp). For workflows with real credentials and a testable trigger (manual, schedule), \`executions(action="run")\` is acceptable. State the pass condition in plain terms (e.g. "run completes without errors and produces at least one output row"). + - Do NOT list \`tools\` on a checkpoint — it is not a delegate task. + - Do NOT emit a checkpoint for a \`data-table\`, \`research\`, or \`delegate\` item. Checkpoints are for workflows only. - **Always call \`submit-plan\` after the last \`add-plan-item\`.** On rejection, be surgical — change only what the user asked for. Never fabricate node names; search first if unsure.`; diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/plan-with-agent.tool.ts b/packages/@n8n/instance-ai/src/tools/orchestration/plan-with-agent.tool.ts index 5d783064194..d4ac40813d3 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/plan-with-agent.tool.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/plan-with-agent.tool.ts @@ -15,6 +15,7 @@ import { Agent } from '@mastra/core/agent'; import type { ToolsInput } from '@mastra/core/agent'; import { createTool } from '@mastra/core/tools'; +import { DateTime } from 'luxon'; import { nanoid } from 'nanoid'; import { z } from 'zod'; @@ -132,9 +133,20 @@ async function getRecentMessages( return messages; } -function formatMessagesForBriefing(messages: FormattedMessage[], guidance?: string): string { +function formatMessagesForBriefing( + messages: FormattedMessage[], + guidance?: string, + timeZone?: string, +): string { const parts: string[] = []; + const now = timeZone ? DateTime.now().setZone(timeZone) : DateTime.now(); + const isoNow = now.toISO({ includeOffset: true }) ?? new Date().toISOString(); + parts.push(`${isoNow}`); + if (timeZone) { + parts.push(`${timeZone}`); + } + if (messages.length > 0) { parts.push('## Recent conversation'); for (const m of messages) { @@ -154,6 +166,8 @@ function formatMessagesForBriefing(messages: FormattedMessage[], guidance?: stri return parts.join('\n\n'); } +export const __testFormatMessagesForBriefing = formatMessagesForBriefing; + // --------------------------------------------------------------------------- // Helper: clear draft checklist from taskStorage // --------------------------------------------------------------------------- @@ -176,6 +190,36 @@ async function clearDraftChecklist(context: OrchestrationContext): Promise } } +/** + * Remove any persisted planned-task graph for this thread *if and only if* it + * belongs to this planner run's unapproved plan. Called on planner give-up / + * error paths to prevent a later schedulePlannedTasks() tick from dispatching + * a plan the user never approved. + * + * Guarded because the thread may already carry an unrelated active graph (a + * prior approved plan with pending checkpoints / in-flight tasks); an + * unconditional `clear()` here would strand that work. We only touch the graph + * when its `planRunId` matches this run AND its `status` is `awaiting_approval` + * — the single window where submit-plan has persisted but approval hasn't + * happened yet. + */ +export async function __testClearPlannedTaskGraph(context: OrchestrationContext): Promise { + return await clearPlannedTaskGraph(context); +} + +async function clearPlannedTaskGraph(context: OrchestrationContext): Promise { + if (!context.plannedTaskService) return; + try { + const graph = await context.plannedTaskService.getGraph(context.threadId); + if (!graph) return; + if (graph.planRunId !== context.runId) return; + if (graph.status !== 'awaiting_approval') return; + await context.plannedTaskService.clear(context.threadId); + } catch { + // Best-effort — don't let cleanup failures block the return path + } +} + // --------------------------------------------------------------------------- // Tool factory // --------------------------------------------------------------------------- @@ -227,7 +271,7 @@ export function createPlanWithAgentTool(context: OrchestrationContext) { // ── Retrieve conversation history ───────────────────────────── const messages = await getRecentMessages(context, MESSAGE_HISTORY_COUNT); - const briefing = formatMessagesForBriefing(messages, input.guidance); + const briefing = formatMessagesForBriefing(messages, input.guidance, context.timeZone); // ── IDs & events ────────────────────────────────────────────── const subAgentId = `agent-planner-${nanoid(6)}`; @@ -337,7 +381,12 @@ export function createPlanWithAgentTool(context: OrchestrationContext) { // ── Schedule tasks after planner-driven approval ────────── // Only dispatch if submit-plan was called AND the user approved. + // createPlan persists the graph as `awaiting_approval`; flip it + // to `active` before scheduling so tick() can dispatch. if (accumulator.isApproved()) { + if (context.plannedTaskService) { + await context.plannedTaskService.approvePlan(context.threadId); + } if (context.schedulePlannedTasks) { await context.schedulePlannedTasks(); } @@ -350,6 +399,11 @@ export function createPlanWithAgentTool(context: OrchestrationContext) { // Planner finished without approval (no submit-plan or user didn't approve) publishClearingEvent(context); await clearDraftChecklist(context); + // Clear the persisted planned-task graph too. submit-plan persists + // it BEFORE user approval (so HITL can display the checklist), so + // leaving it intact on planner give-up would let a later + // schedulePlannedTasks() tick pick up and dispatch a rejected plan. + await clearPlannedTaskGraph(context); if (!accumulator.isEmpty()) { return { result: `Planner added ${accumulator.getTaskList().length} items but did not submit the plan for approval. The plan was not executed.`, @@ -376,9 +430,17 @@ export function createPlanWithAgentTool(context: OrchestrationContext) { }, }); - // Clear draft checklist on error - publishClearingEvent(context); - await clearDraftChecklist(context); + // Clear draft checklist and persisted graph on error — same reason + // as the non-approval path: an error-aborted plan must not later be + // auto-dispatched by the post-run reschedule. Skip both when the user + // already approved this plan: the failure is downstream of approval + // (e.g. approvePlan/schedulePlannedTasks threw), and clearing would + // drop a plan the user explicitly accepted. + if (!accumulator.isApproved()) { + publishClearingEvent(context); + await clearDraftChecklist(context); + await clearPlannedTaskGraph(context); + } return { result: `Planner error: ${errorMessage}` }; } diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/plan.tool.ts b/packages/@n8n/instance-ai/src/tools/orchestration/plan.tool.ts index b1073a5d452..a2337d0e6d4 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/plan.tool.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/plan.tool.ts @@ -8,7 +8,7 @@ import type { OrchestrationContext, PlannedTask } from '../../types'; const plannedTaskSchema = z.object({ id: z.string().describe('Stable task identifier used by dependency edges'), title: z.string().describe('Short user-facing task title'), - kind: z.enum(['delegate', 'build-workflow', 'manage-data-tables', 'research']), + kind: z.enum(['delegate', 'build-workflow', 'manage-data-tables', 'research', 'checkpoint']), spec: z.string().describe('Detailed executor briefing for this task'), deps: z .array(z.string()) @@ -54,12 +54,21 @@ function isReplanContext(context: OrchestrationContext): boolean { * `cancelled`) must not bypass the guard — a fresh user request on a long- * lived thread needs to go through `plan` for discovery, same as any first * request. + * + * `awaiting_approval` is treated as "existing" only within the run that + * created it. The rejection path leaves the graph in `awaiting_approval` so a + * same-turn revision can call `create-tasks` again, but an orphaned + * `awaiting_approval` graph from a previous turn (the LLM never revised after + * a rejection) must not bypass planner discovery for a fresh user request. */ async function threadHasExistingPlan(context: OrchestrationContext): Promise { if (!context.plannedTaskService) return false; try { const graph = await context.plannedTaskService.getGraph(context.threadId); if (!graph) return false; + if (graph.status === 'awaiting_approval') { + return graph.planRunId === context.runId; + } return graph.status === 'active' || graph.status === 'awaiting_replan'; } catch { return false; @@ -189,8 +198,10 @@ export function createPlanTool(context: OrchestrationContext) { return { result: 'Awaiting approval', taskCount: input.tasks.length }; } - // User approved — start execution + // User approved — flip graph status from awaiting_approval → active, + // then start execution. if (resumeData.approved) { + await context.plannedTaskService.approvePlan(context.threadId); await context.schedulePlannedTasks(); return { result: `Plan approved. Started ${input.tasks.length} task${input.tasks.length === 1 ? '' : 's'}.`, @@ -198,7 +209,26 @@ export function createPlanTool(context: OrchestrationContext) { }; } - // User rejected or requested changes — return feedback to LLM + // User rejected or requested changes. Reset the UI checklist so the + // rejected plan's "todo" items don't linger on screen, but keep the + // persisted graph in `awaiting_approval` so the LLM's next + // `create-tasks` revision passes the replan guard via + // `threadHasExistingPlan` (scoped to the current runId). The + // scheduler ignores `awaiting_approval` graphs, so leaving the graph + // in place can't dispatch the rejected plan; the next createPlan + // call overwrites it with the revised tasks. + // Best-effort: a storage failure here must not abort the revision flow. + try { + await context.taskStorage.save(context.threadId, { tasks: [] }); + } catch (error) { + context.logger.warn('Failed to clear rejected plan checklist', { error }); + } + context.eventBus.publish(context.threadId, { + type: 'tasks-update', + runId: context.runId, + agentId: context.orchestratorAgentId, + payload: { tasks: { tasks: [] }, planItems: [] }, + }); return { result: `User requested changes: ${resumeData.userInput ?? 'No feedback provided'}. Revise the tasks and call create-tasks again.`, taskCount: 0, diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/research-with-agent.tool.ts b/packages/@n8n/instance-ai/src/tools/orchestration/research-with-agent.tool.ts index 0519baea1ce..33cb148e53e 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/research-with-agent.tool.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/research-with-agent.tool.ts @@ -66,22 +66,6 @@ export async function startResearchAgentTask( const subAgentId = input.agentId ?? `agent-researcher-${nanoid(6)}`; const taskId = input.taskId ?? `research-${nanoid(8)}`; - context.eventBus.publish(context.threadId, { - type: 'agent-spawned', - runId: context.runId, - agentId: subAgentId, - payload: { - parentId: context.orchestratorAgentId, - role: 'web-researcher', - tools: Object.keys(researchTools), - taskId, - kind: 'researcher', - title: 'Researching', - subtitle: truncateLabel(input.goal), - goal: input.goal, - }, - }); - const briefing = await buildSubAgentBriefing({ task: input.goal, conversationContext: input.conversationContext, @@ -102,13 +86,16 @@ export async function startResearchAgentTask( }); const tracedResearchTools = traceSubAgentTools(context, researchTools, 'web-researcher'); - context.spawnBackgroundTask({ + const spawnOutcome = context.spawnBackgroundTask({ taskId, threadId: context.threadId, agentId: subAgentId, role: 'web-researcher', traceContext, plannedTaskId: input.plannedTaskId, + dedupeKey: { role: 'web-researcher', plannedTaskId: input.plannedTaskId }, + parentCheckpointId: + context.isCheckpointFollowUp === true ? context.checkpointTaskId : undefined, run: async (signal, drainCorrections, waitForCorrection) => { return await withTraceContextActor(traceContext, async () => { const subAgent = new Agent({ @@ -168,6 +155,40 @@ export async function startResearchAgentTask( }, }); + if (spawnOutcome.status === 'duplicate') { + return { + result: `Research already in progress (task: ${spawnOutcome.existing.taskId}). Wait for the planned-task-follow-up — do not dispatch again.`, + taskId: spawnOutcome.existing.taskId, + agentId: spawnOutcome.existing.agentId, + }; + } + if (spawnOutcome.status === 'limit-reached') { + return { + result: + 'Could not start research: concurrent background-task limit reached. Wait for an existing task to finish and try again.', + taskId: '', + agentId: '', + }; + } + + // Spawn confirmed — publish the UI event now so duplicate/limit-reached + // rejections above don't leave a phantom card on the chat surface. + context.eventBus.publish(context.threadId, { + type: 'agent-spawned', + runId: context.runId, + agentId: subAgentId, + payload: { + parentId: context.orchestratorAgentId, + role: 'web-researcher', + tools: Object.keys(researchTools), + taskId, + kind: 'researcher', + title: 'Researching', + subtitle: truncateLabel(input.goal), + goal: input.goal, + }, + }); + return { result: `Research started (task: ${taskId}). Do NOT summarize the plan or list details.`, taskId, diff --git a/packages/@n8n/instance-ai/src/tools/orchestration/verify-built-workflow.tool.ts b/packages/@n8n/instance-ai/src/tools/orchestration/verify-built-workflow.tool.ts index b21019528c8..1201aaa560f 100644 --- a/packages/@n8n/instance-ai/src/tools/orchestration/verify-built-workflow.tool.ts +++ b/packages/@n8n/instance-ai/src/tools/orchestration/verify-built-workflow.tool.ts @@ -9,12 +9,255 @@ import { createTool } from '@mastra/core/tools'; import { z } from 'zod'; -import type { OrchestrationContext } from '../../types'; +import type { Logger } from '../../logger'; +import type { + InstanceAiDataTableService, + InstanceAiWorkflowService, + OrchestrationContext, +} from '../../types'; + +interface DataTableWriteNode { + nodeName: string; + dataTableId: string; + /** + * Only `insert` is cleaned up post-verify. `upsert` is tracked but never + * cleaned up because its node output cannot distinguish a newly-created + * row from a match on an existing row (see cleanupInsertedRowsByNodeOutput). + * `update` never creates rows so cleanup is moot. + */ + operation: 'insert' | 'upsert' | 'update'; +} + +/** + * Extract the data-table write nodes a workflow contains, keyed by node name so + * we can look up each node's per-execution output and identify the exact row IDs + * it created. Returning node-level records (instead of just dataTable IDs) is + * what lets post-verify cleanup delete only rows *this* run inserted — rows from + * concurrent writers never appear in these nodes' outputs, so they are safe. + */ +async function extractDataTableWriteNodes( + workflowService: InstanceAiWorkflowService, + workflowId: string, +): Promise { + try { + const json = await workflowService.getAsWorkflowJSON(workflowId); + const out: DataTableWriteNode[] = []; + for (const node of json.nodes ?? []) { + if (node.type !== 'n8n-nodes-base.dataTable') continue; + const params = node.parameters as Record | undefined; + const operation = params?.operation; + if (operation !== 'insert' && operation !== 'upsert' && operation !== 'update') continue; + const ref = params?.dataTableId; + let dataTableId: string | undefined; + if (typeof ref === 'string' && ref.length > 0) { + dataTableId = ref; + } else if ( + ref && + typeof ref === 'object' && + 'value' in ref && + typeof (ref as { value: unknown }).value === 'string' + ) { + const value = (ref as { value: string }).value; + if (value.length > 0) dataTableId = value; + } + if (!dataTableId || !node.name) continue; + out.push({ nodeName: node.name, dataTableId, operation }); + } + return out; + } catch { + return []; + } +} + +/** + * Extract the numeric `id` values that a single node produced as output during + * the verify execution. Handles the common n8n shapes: an array of row objects, + * a `{ json: {...} }` wrapper, or a single row object. + */ +function extractRowIdsFromNodeOutput(nodeOutput: unknown): number[] { + const ids: number[] = []; + const visit = (value: unknown): void => { + if (!value) return; + if (Array.isArray(value)) { + for (const item of value) visit(item); + return; + } + if (typeof value !== 'object') return; + const row = value as Record; + if (row.json !== undefined) { + visit(row.json); + return; + } + const id = row.id; + if (typeof id === 'number' && Number.isFinite(id)) ids.push(id); + }; + visit(nodeOutput); + return ids; +} + +/** + * Per-table pre-verify snapshot. A `Set` is a complete list of row IDs that + * existed before the run. `null` means the snapshot could not be built (empty + * table, read error, or pagination cap hit) — cleanup skips any table with a + * null snapshot. The snapshot guards insert-node cleanup against pathological + * outputs (e.g. an insert node returning an existing row ID); upsert outputs + * are not eligible for cleanup at all. + */ +type PreIdsMap = Map | null>; + +/** Rows per page when snapshotting table contents. */ +const SNAPSHOT_PAGE_SIZE = 1000; +/** + * Hard cap on total rows we will snapshot per table. Snapshot is only a safety + * check (`is this ID pre-existing?`) so on tables above this size we disable + * cleanup rather than keep paging forever. + */ +const SNAPSHOT_MAX_ROWS = 100_000; + +/** + * Delete rows this verify execution inserted, identified by the node outputs of + * the dataTable insert nodes the workflow contains. Rows inserted by concurrent + * writers never appear in an insert node's output and are therefore safe. + * + * Upsert nodes are deliberately skipped: their node output cannot distinguish + * a newly-created row from a match on an existing one. A concurrent writer + * inserting a row between the snapshot and the upsert call could yield an ID + * that looks "new" to the ID-diff check while actually belonging to the + * concurrent writer — deleting it would destroy production data. Until the + * upsert path exposes a `wasCreated` flag in the row return, we trade leaking + * a few verify-created rows for guaranteed safety. + * + * When `preIdsByTable.get(dataTableId)` is `null` the snapshot could not be + * built and cleanup is skipped for that table; without a reliable pre-existing + * set we cannot distinguish a new insert from a row that pre-existed. + */ +async function cleanupInsertedRowsByNodeOutput( + dataTableService: InstanceAiDataTableService, + writeNodes: DataTableWriteNode[], + resultData: Record | undefined, + preIdsByTable: PreIdsMap, + logger: Logger, +): Promise { + if (!resultData) return 0; + /** per-table set of row IDs the workflow's own insert nodes produced */ + const createdIdsByTable = new Map>(); + for (const { nodeName, dataTableId, operation } of writeNodes) { + if (operation !== 'insert') continue; + const output = resultData[nodeName]; + if (!output) continue; + const ids = extractRowIdsFromNodeOutput(output); + if (ids.length === 0) continue; + let bucket = createdIdsByTable.get(dataTableId); + if (!bucket) { + bucket = new Set(); + createdIdsByTable.set(dataTableId, bucket); + } + for (const id of ids) bucket.add(id); + } + let total = 0; + for (const [dataTableId, ids] of createdIdsByTable) { + const preIds = preIdsByTable.get(dataTableId); + if (preIds === undefined || preIds === null) { + logger.warn( + 'Skipping data-table cleanup: pre-verify snapshot unavailable. Rows left in place to avoid deleting existing data.', + { dataTableId, candidateIds: ids.size }, + ); + continue; + } + // Only delete IDs that did not exist before the run — upsert-matched rows stay. + const toDelete = [...ids].filter((id) => !preIds.has(id)); + if (toDelete.length === 0) continue; + try { + await dataTableService.deleteRows(dataTableId, { + type: 'or', + filters: toDelete.map((id) => ({ + columnName: 'id', + condition: 'eq' as const, + value: id, + })), + }); + total += toDelete.length; + } catch { + // best-effort: failure on one table does not block others + } + } + return total; +} + +/** + * Pre-verify snapshot of current row IDs per tracked table. Used as a defensive + * filter for insert-node cleanup — any output ID present in the pre-snapshot + * is left alone, never deleted. The delete set is still driven by node output, + * not by a post-verify table-wide diff, so concurrent writers stay safe. + * + * The snapshot pages through the full table because the cap on `queryRows` + * would otherwise leave existing rows past the first page unprotected. If + * pagination fails mid-way or the table is bigger than `SNAPSHOT_MAX_ROWS`, + * the entry is set to `null` so `cleanupInsertedRowsByNodeOutput` skips that + * table rather than guess. + */ +async function snapshotRowIdsPerTable( + dataTableService: InstanceAiDataTableService, + dataTableIds: Iterable, + logger: Logger, +): Promise { + const out: PreIdsMap = new Map(); + for (const id of dataTableIds) { + try { + const bucket = new Set(); + let offset = 0; + let truncated = false; + for (;;) { + const { data } = await dataTableService.queryRows(id, { + limit: SNAPSHOT_PAGE_SIZE, + offset, + }); + for (const row of data) { + const rid = row.id; + if (typeof rid === 'number') bucket.add(rid); + } + if (data.length < SNAPSHOT_PAGE_SIZE) break; + offset += SNAPSHOT_PAGE_SIZE; + if (offset >= SNAPSHOT_MAX_ROWS) { + truncated = true; + break; + } + } + if (truncated) { + logger.warn( + 'Data-table pre-verify snapshot exceeded row cap — cleanup disabled for this table', + { dataTableId: id, cap: SNAPSHOT_MAX_ROWS }, + ); + out.set(id, null); + } else { + out.set(id, bucket); + } + } catch (error) { + logger.warn('Data-table pre-verify snapshot failed — cleanup disabled for this table', { + dataTableId: id, + error: error instanceof Error ? error.message : String(error), + }); + out.set(id, null); + } + } + return out; +} export const verifyBuiltWorkflowInputSchema = z.object({ workItemId: z.string().describe('The work item ID from the build (wi_XXXXXXXX)'), workflowId: z.string().describe('The workflow ID to verify'), - inputData: z.record(z.unknown()).optional().describe('Input data passed to the workflow trigger'), + inputData: z + .record(z.unknown()) + .optional() + .describe( + "Input data for the workflow trigger. Shape MUST match the trigger's real-world output: " + + 'Form Trigger → flat field map like {name: "Alice", email: "a@b.c"} (do NOT wrap in formFields); ' + + 'Webhook → the body payload like {event: "signup", userId: "..."} (adapter wraps it under body); ' + + 'Chat Trigger → {chatInput: "user message"}; ' + + 'Schedule Trigger → omit inputData. ' + + "If you wrap a form payload in {formFields: {...}} the adapter will reject the call — the builder's " + + 'downstream expressions reference $json., matching the flat production shape.', + ), timeout: z .number() .int() @@ -29,7 +272,10 @@ export function createVerifyBuiltWorkflowTool(context: OrchestrationContext) { id: 'verify-built-workflow', description: 'Run a built workflow that has mocked credentials, using sidecar verification pin data ' + - 'from the build outcome. Use this instead of `executions(action="run")` when the build had mocked credentials.', + 'from the build outcome. Use this instead of `executions(action="run")` when the build had mocked credentials. ' + + 'CRITICAL: `inputData` shape depends on the trigger type — see the per-trigger guidance on the inputData field. ' + + 'Passing the wrong shape (e.g. wrapping form fields under `formFields`) produces null downstream values that ' + + 'look like an expression bug but are not — do not patch the workflow, re-run verify with the correct shape.', inputSchema: verifyBuiltWorkflowInputSchema, outputSchema: z.object({ executionId: z.string().optional(), @@ -51,6 +297,23 @@ export function createVerifyBuiltWorkflowTool(context: OrchestrationContext) { }; } + // Pre-verify: enumerate the dataTable write nodes in the workflow and + // snapshot current row IDs for each insert-touched table. The delete + // set comes from each insert node's own output after verify (so + // concurrent writers stay invisible to cleanup); the snapshot is a + // defensive filter so any ID that pre-existed cannot be deleted. + // Upsert outputs are deliberately never cleaned — see + // `cleanupInsertedRowsByNodeOutput` for the rationale. + const writeNodes = await extractDataTableWriteNodes( + context.domainContext.workflowService, + input.workflowId, + ); + const preSnapshots = await snapshotRowIdsPerTable( + context.domainContext.dataTableService, + new Set(writeNodes.map((n) => n.dataTableId)), + context.logger, + ); + const result = await context.domainContext.executionService.run( input.workflowId, input.inputData, @@ -60,9 +323,62 @@ export function createVerifyBuiltWorkflowTool(context: OrchestrationContext) { }, ); + // Treat `waiting` as success when the workflow produced output and recorded + // no error. `waiting` is a terminal-ish state for several legitimate flows: + // Form Trigger workflows that end on a form-respond / completion page, Wait + // nodes, and HITL prompts. Considering it a failure caused builders to + // falsely retry verified form workflows and prevented checkpoints from + // reusing builder evidence. Only treat `waiting` with no output rows AND + // no error as indeterminate (falls through to failure). + const hasOutput = result.data ? Object.keys(result.data).length > 0 : false; + const success = + result.status === 'success' || (result.status === 'waiting' && !result.error && hasOutput); + + // Post-verify cleanup: delete only rows this run's own dataTable insert + // nodes emitted as output, and only those whose IDs were not present in + // the pre-verify snapshot (protects upsert-updated rows from deletion). + const cleanedRows = await cleanupInsertedRowsByNodeOutput( + context.domainContext.dataTableService, + writeNodes, + result.data, + preSnapshots, + context.logger, + ); + + // Persist a structured verification record onto the build outcome so the + // checkpoint follow-up turn can reuse it instead of re-running verify. + // Best-effort: swallow storage errors so they don't mask the verify result. + try { + const nodesExecuted = result.data ? Object.keys(result.data) : undefined; + await context.workflowTaskService.updateBuildOutcome(input.workItemId, { + verification: { + attempted: true, + success, + executionId: result.executionId || undefined, + status: result.status, + failureSignature: success ? undefined : result.error, + evidence: { + nodesExecuted: nodesExecuted && nodesExecuted.length > 0 ? nodesExecuted : undefined, + errorMessage: success ? undefined : result.error, + }, + verifiedAt: new Date().toISOString(), + }, + }); + } catch { + // intentional: verification record persistence is advisory + } + + if (cleanedRows > 0) { + context.logger.debug?.('verify-built-workflow: cleaned up inserted rows', { + workItemId: input.workItemId, + workflowId: input.workflowId, + cleanedRows, + }); + } + return { executionId: result.executionId || undefined, - success: result.status === 'success', + success, status: result.status, data: result.data, error: result.error, diff --git a/packages/@n8n/instance-ai/src/tools/workflows/__tests__/submit-workflow.tool.test.ts b/packages/@n8n/instance-ai/src/tools/workflows/__tests__/submit-workflow.tool.test.ts index cd2a5e7dcda..a305c0f6a84 100644 --- a/packages/@n8n/instance-ai/src/tools/workflows/__tests__/submit-workflow.tool.test.ts +++ b/packages/@n8n/instance-ai/src/tools/workflows/__tests__/submit-workflow.tool.test.ts @@ -1,7 +1,7 @@ import type { Workspace } from '@mastra/core/workspace'; import type { InstanceAiContext } from '../../../types'; -import type { SubmitWorkflowAttempt } from '../submit-workflow.tool'; +import { isTriggerNodeType, type SubmitWorkflowAttempt } from '../submit-workflow.tool'; jest.mock('@mastra/core/tools', () => ({ createTool: jest.fn((config: Record) => config), @@ -46,6 +46,33 @@ function makeWorkspace(): Workspace { } as unknown as Workspace; } +describe('isTriggerNodeType', () => { + it.each([ + 'n8n-nodes-base.webhook', + 'n8n-nodes-base.formTrigger', + 'n8n-nodes-base.scheduleTrigger', + '@n8n/n8n-nodes-langchain.chatTrigger', + ])('recognises known-mockable type %s', (type) => { + expect(isTriggerNodeType(type)).toBe(true); + }); + + it.each([ + 'n8n-nodes-base.emailReadImapTrigger', + '@n8n/n8n-nodes-langchain.mcpTrigger', + 'n8n-nodes-base.manualTrigger', + 'customNamespace.someCustomtrigger', + ])('recognises suffix-matched trigger type %s', (type) => { + expect(isTriggerNodeType(type)).toBe(true); + }); + + it.each(['n8n-nodes-base.slack', 'n8n-nodes-base.code', 'n8n-nodes-base.set', undefined, ''])( + 'returns false for non-trigger %s', + (type) => { + expect(isTriggerNodeType(type)).toBe(false); + }, + ); +}); + describe('createSubmitWorkflowTool — permission enforcement', () => { it('rejects create when createWorkflow is blocked and reports the attempt', async () => { const attempts: SubmitWorkflowAttempt[] = []; diff --git a/packages/@n8n/instance-ai/src/tools/workflows/submit-workflow.tool.ts b/packages/@n8n/instance-ai/src/tools/workflows/submit-workflow.tool.ts index 898fa5d8132..0b74bac803e 100644 --- a/packages/@n8n/instance-ai/src/tools/workflows/submit-workflow.tool.ts +++ b/packages/@n8n/instance-ai/src/tools/workflows/submit-workflow.tool.ts @@ -28,8 +28,13 @@ export interface SubmitWorkflowAttempt { success: boolean; /** Workflow ID assigned by n8n after a successful save. */ workflowId?: string; - /** Node types of all trigger nodes in the submitted workflow. */ - triggerNodeTypes?: string[]; + /** + * Trigger nodes in the submitted workflow, each carrying name + type. + * Populated by a conservative detector (known-mockable allow-list plus + * any node type ending in `Trigger`); surfaces to the build outcome so + * the orchestrator can choose a `verify-built-workflow` `inputData` shape. + */ + triggerNodes?: Array<{ nodeName: string; nodeType: string }>; /** Node names whose credentials were mocked. */ mockedNodeNames?: string[]; /** Credential types that were mocked (not resolved to real credentials). */ @@ -57,6 +62,32 @@ const WEBHOOK_NODE_TYPES = new Set([ '@n8n/n8n-nodes-langchain.chatTrigger', ]); +/** + * Node types the bypassPlan post-build verify flow can exercise without user + * approval (verify-built-workflow injects sidecar pin data matching each + * trigger's production output shape). Kept in sync with the per-trigger + * inputData shape block in the orchestrator system prompt. + */ +const KNOWN_MOCKABLE_TRIGGER_TYPES = new Set([ + 'n8n-nodes-base.webhook', + 'n8n-nodes-base.formTrigger', + 'n8n-nodes-base.scheduleTrigger', + '@n8n/n8n-nodes-langchain.chatTrigger', +]); + +/** + * Whether a node's type should be surfaced in `SubmitWorkflowAttempt.triggerNodes` + * so the orchestrator can decide if it can verify the build without user input. + * Known-mockable types feed the post-build verify step directly; other `*Trigger` + * suffix types are included for visibility but skipped by the verify step. + * Exported for direct unit coverage. + */ +export function isTriggerNodeType(nodeType: string | undefined): boolean { + if (!nodeType) return false; + if (KNOWN_MOCKABLE_TRIGGER_TYPES.has(nodeType)) return true; + return nodeType.endsWith('Trigger') || nodeType.endsWith('trigger'); +} + /** * Ensure webhook nodes have a webhookId so n8n registers clean URL paths. * Without it, getNodeWebhookPath() falls back to encoding the node name @@ -378,10 +409,13 @@ export function createSubmitWorkflowTool( }); } - const triggers = (json.nodes ?? []).filter( - (n) => n.type?.endsWith?.('Trigger') || n.type?.endsWith?.('trigger'), - ); - const triggerNodeTypes = triggers.map((t) => t.type).filter(Boolean); + const triggerNodes = (json.nodes ?? []) + .filter((n) => isTriggerNodeType(n.type)) + .map((n) => ({ nodeName: n.name, nodeType: n.type })) + .filter( + (t): t is { nodeName: string; nodeType: string } => + Boolean(t.nodeName) && Boolean(t.nodeType), + ); // Scan node parameters for unresolved placeholder values const hasPlaceholders = (json.nodes ?? []).some((n) => hasPlaceholderDeep(n.parameters)); @@ -389,7 +423,7 @@ export function createSubmitWorkflowTool( await reportAttempt({ success: true, workflowId: savedId, - triggerNodeTypes, + triggerNodes, mockedNodeNames: hasMockedCredentials ? mockResult.mockedNodeNames : undefined, mockedCredentialTypes: hasMockedCredentials ? mockResult.mockedCredentialTypes : undefined, mockedCredentialsByNode: hasMockedCredentials diff --git a/packages/@n8n/instance-ai/src/tracing/__tests__/trace-replay.test.ts b/packages/@n8n/instance-ai/src/tracing/__tests__/trace-replay.test.ts index 25a047c189f..d9626d68165 100644 --- a/packages/@n8n/instance-ai/src/tracing/__tests__/trace-replay.test.ts +++ b/packages/@n8n/instance-ai/src/tracing/__tests__/trace-replay.test.ts @@ -250,6 +250,29 @@ describe('TraceIndex', () => { ); }); + it('should scan forward for a matching tool when requested', () => { + const events: TraceEvent[] = [ + makeToolCall(1, 'orchestrator', 'credentials'), + makeToolCall(2, 'orchestrator', 'build-workflow-with-agent'), + makeToolCall(3, 'orchestrator', 'plan'), + ]; + + const index = new TraceIndex(events); + + expect(index.nextMatching('orchestrator', 'plan')?.stepId).toBe(3); + expect(index.nextMatching('orchestrator', 'credentials')).toBeNull(); + }); + + it('should return null from matching lookup when trace is exhausted or role is unknown', () => { + const events: TraceEvent[] = [makeToolCall(1, 'orchestrator', 'search-nodes')]; + + const index = new TraceIndex(events); + + expect(index.nextMatching('unknown-role', 'search-nodes')).toBeNull(); + expect(index.nextMatching('orchestrator', 'search-nodes')?.stepId).toBe(1); + expect(index.nextMatching('orchestrator', 'another-tool')).toBeNull(); + }); + it('should handle interleaved orchestrator and sub-agent calls', () => { const events: TraceEvent[] = [ makeToolCall(1, 'orchestrator', 'tool-a'), diff --git a/packages/@n8n/instance-ai/src/tracing/langsmith-tracing.ts b/packages/@n8n/instance-ai/src/tracing/langsmith-tracing.ts index 1680ad0a1bd..e6d0aaf2254 100644 --- a/packages/@n8n/instance-ai/src/tracing/langsmith-tracing.ts +++ b/packages/@n8n/instance-ai/src/tracing/langsmith-tracing.ts @@ -1012,10 +1012,12 @@ function replayWrapTool( resumeSchema: tool.resumeSchema, requestContextSchema: tool.requestContextSchema, execute: async (input, context) => { - const event = traceIndex.next(agentRole, tool.id); - const remappedInput = idRemapper.remapInput(input); + const event = traceIndex.nextMatching(agentRole, tool.id); + const remappedInput: unknown = event ? idRemapper.remapInput(input) : input; const realOutput = await tool.execute!(remappedInput, context); - idRemapper.learn(event.output, realOutput as Record); + if (event) { + idRemapper.learn(event.output, realOutput as Record); + } return realOutput; }, mastra: tool.mastra, @@ -1049,7 +1051,12 @@ function pureReplayWrapTool( resumeSchema: tool.resumeSchema, requestContextSchema: tool.requestContextSchema, execute: async (_input, _context) => { - const event = traceIndex.next(agentRole, tool.id); + const event = traceIndex.nextMatching(agentRole, tool.id); + if (!event) { + throw new Error( + `No recorded output for pure-replay tool "${tool.id}" in role "${agentRole}"`, + ); + } return await Promise.resolve(idRemapper.remapOutput(event.output)); }, mastra: tool.mastra, diff --git a/packages/@n8n/instance-ai/src/tracing/trace-replay.ts b/packages/@n8n/instance-ai/src/tracing/trace-replay.ts index 17cdfc2354d..4876d05d515 100644 --- a/packages/@n8n/instance-ai/src/tracing/trace-replay.ts +++ b/packages/@n8n/instance-ai/src/tracing/trace-replay.ts @@ -92,6 +92,30 @@ export class TraceIndex { this.cursors.set(agentRole, cursor + 1); return event; } + + nextMatching(agentRole: string, expectedToolName: string): ToolTraceEvent | null { + const events = this.byRole.get(agentRole); + const cursor = this.cursors.get(agentRole) ?? 0; + + if (!events || cursor >= events.length) { + return null; + } + + const event = events[cursor]; + if (event.toolName === expectedToolName) { + this.cursors.set(agentRole, cursor + 1); + return event; + } + + for (let i = cursor + 1; i < events.length; i++) { + if (events[i].toolName === expectedToolName) { + this.cursors.set(agentRole, i + 1); + return events[i]; + } + } + + return null; + } } // ── IdRemapper ────────────────────────────────────────────────────────────── diff --git a/packages/@n8n/instance-ai/src/types.ts b/packages/@n8n/instance-ai/src/types.ts index 89809cb988a..9191a75552b 100644 --- a/packages/@n8n/instance-ai/src/types.ts +++ b/packages/@n8n/instance-ai/src/types.ts @@ -370,6 +370,18 @@ export interface DataTableFilterInput { // ── Data table service ─────────────────────────────────────────────────────── +/** + * Optional disambiguator accepted by every id-based data-table service call. + * When the orchestrator passes a table NAME instead of a UUID, the adapter's + * resolver filters the name lookup to this project so collisions across + * projects don't require the orchestrator to guess the right UUID. When the + * orchestrator passes a UUID AND a mismatched `projectId`, the adapter rejects + * the call (the resolver never silently drops `projectId`). + */ +export interface DataTableIdOptions { + projectId?: string; +} + export interface InstanceAiDataTableService { list(options?: { projectId?: string }): Promise; create( @@ -377,30 +389,44 @@ export interface InstanceAiDataTableService { columns: Array<{ name: string; type: 'string' | 'number' | 'boolean' | 'date' }>, options?: { projectId?: string }, ): Promise; - delete(dataTableId: string): Promise; - getSchema(dataTableId: string): Promise; + delete(dataTableId: string, options?: DataTableIdOptions): Promise; + getSchema(dataTableId: string, options?: DataTableIdOptions): Promise; addColumn( dataTableId: string, column: { name: string; type: 'string' | 'number' | 'boolean' | 'date' }, + options?: DataTableIdOptions, ): Promise; - deleteColumn(dataTableId: string, columnId: string): Promise; - renameColumn(dataTableId: string, columnId: string, newName: string): Promise; + deleteColumn(dataTableId: string, columnId: string, options?: DataTableIdOptions): Promise; + renameColumn( + dataTableId: string, + columnId: string, + newName: string, + options?: DataTableIdOptions, + ): Promise; queryRows( dataTableId: string, - options?: { filter?: DataTableFilterInput; limit?: number; offset?: number }, + options?: { + filter?: DataTableFilterInput; + limit?: number; + offset?: number; + projectId?: string; + }, ): Promise<{ count: number; data: Array> }>; insertRows( dataTableId: string, rows: Array>, + options?: DataTableIdOptions, ): Promise<{ insertedCount: number; dataTableId: string; tableName: string; projectId: string }>; updateRows( dataTableId: string, filter: DataTableFilterInput, data: Record, + options?: DataTableIdOptions, ): Promise<{ updatedCount: number; dataTableId: string; tableName: string; projectId: string }>; deleteRows( dataTableId: string, filter: DataTableFilterInput, + options?: DataTableIdOptions, ): Promise<{ deletedCount: number; dataTableId: string; tableName: string; projectId: string }>; } @@ -538,6 +564,10 @@ export interface InstanceAiContext { localGatewayStatus?: LocalGatewayStatus; /** Per-action HITL permission overrides. When absent, tools default to requiring approval. */ permissions?: InstanceAiPermissions; + /** When set, `runWorkflow: 'always_allow'` only short-circuits HITL approval for these workflow IDs. + * Used by checkpoint follow-up runs to scope the override to the workflows the checkpoint is + * verifying — `executions(action="run")` on any other workflow still requires user approval. */ + allowedRunWorkflowIds?: ReadonlySet; /** When true, the instance is in read-only mode (source control branchReadOnly). */ branchReadOnly?: boolean; /** Human-readable hints about licensed features that are NOT available on this instance. @@ -576,7 +606,12 @@ export interface TaskStorage { // ── Planned task graphs ───────────────────────────────────────────────────── -export type PlannedTaskKind = 'delegate' | 'build-workflow' | 'manage-data-tables' | 'research'; +export type PlannedTaskKind = + | 'delegate' + | 'build-workflow' + | 'manage-data-tables' + | 'research' + | 'checkpoint'; export interface PlannedTask { id: string; @@ -602,7 +637,12 @@ export interface PlannedTaskRecord extends PlannedTask { finishedAt?: number; } -export type PlannedTaskGraphStatus = 'active' | 'awaiting_replan' | 'completed' | 'cancelled'; +export type PlannedTaskGraphStatus = + | 'awaiting_approval' + | 'active' + | 'awaiting_replan' + | 'completed' + | 'cancelled'; export interface PlannedTaskGraph { planRunId: string; @@ -614,6 +654,7 @@ export interface PlannedTaskGraph { export type PlannedTaskSchedulerAction = | { type: 'none'; graph: PlannedTaskGraph | null } | { type: 'dispatch'; graph: PlannedTaskGraph; tasks: PlannedTaskRecord[] } + | { type: 'orchestrate-checkpoint'; graph: PlannedTaskGraph; tasks: PlannedTaskRecord[] } | { type: 'replan'; graph: PlannedTaskGraph; failedTask: PlannedTaskRecord } | { type: 'synthesize'; graph: PlannedTaskGraph }; @@ -644,13 +685,52 @@ export interface PlannedTaskService { taskId: string, update?: { error?: string; finishedAt?: number }, ): Promise; + markCheckpointSucceeded( + threadId: string, + taskId: string, + update: { result?: string; outcome?: Record; finishedAt?: number }, + ): Promise; + markCheckpointFailed( + threadId: string, + taskId: string, + update: { + error?: string; + /** Structured verification outcome (executionId, failureNode, etc.) so + * replans have execution context, not just a flat error string. */ + outcome?: Record; + finishedAt?: number; + }, + ): Promise; + /** Rewind a running checkpoint back to `planned` after a scheduling race + * prevented its follow-up from starting. Non-destructive — dependents are + * untouched and the next tick re-emits `orchestrate-checkpoint`. */ + revertCheckpointToPlanned(threadId: string, taskId: string): Promise; tick( threadId: string, options?: { availableSlots?: number }, ): Promise; clear(threadId: string): Promise; + /** Transition an `awaiting_approval` graph → `active` after the user + * approves the plan. No-op on any other status. */ + approvePlan(threadId: string): Promise; + /** Revert an `awaiting_replan` or `completed` graph back to `active`. Used by + * the service when a replan or synthesize follow-up couldn't start. */ + revertToActive(threadId: string): Promise; } +/** + * Result of a guarded checkpoint settlement. The mutators only transition a task + * when its kind is `checkpoint` AND its status is `running`, so callers can read + * the `reason` to report a precise error back to the LLM. + */ +export type CheckpointSettleResult = + | { ok: true; graph: PlannedTaskGraph } + | { + ok: false; + reason: 'not-found' | 'wrong-kind' | 'wrong-status'; + actual?: { kind?: PlannedTaskKind; status?: PlannedTaskStatus }; + }; + // ── MCP ────────────────────────────────────────────────────────────────────── export interface McpServerConfig { @@ -796,6 +876,27 @@ export interface SpawnBackgroundTaskOptions { /** Unique work item ID for workflow loop tracking. When set, the service * uses the workflow loop controller to manage verify/repair transitions. */ workItemId?: string; + /** + * Identity used for single-flight dedupe. When present, a spawn with the same + * `plannedTaskId` (primary) or `role + workflowId` (fallback) as a currently-running + * task returns `{ status: 'duplicate', existing }` instead of starting a new task. + */ + dedupeKey?: { + plannedTaskId?: string; + workflowId?: string; + role: string; + }; + /** + * Link this background task to a running checkpoint in the planned-task + * graph. Set when the orchestrator spawns a detached sub-agent (builder, + * research, data-table, delegate) from inside a + * `` turn. The post-run safety + * net defers failing the checkpoint while a child with this id is still + * running, and settlement re-emits the checkpoint follow-up when the last + * child settles — so the orchestrator re-enters the checkpoint context + * instead of a bare `` shell. + */ + parentCheckpointId?: string; run: ( signal: AbortSignal, drainCorrections: () => string[], @@ -803,6 +904,22 @@ export interface SpawnBackgroundTaskOptions { ) => Promise; } +/** Result of a {@link SpawnBackgroundTaskOptions} spawn. */ +export type SpawnBackgroundTaskResult = + | { status: 'started'; taskId: string; agentId: string } + | { status: 'limit-reached' } + | { + status: 'duplicate'; + /** The live background task that matched on `dedupeKey`. */ + existing: { + taskId: string; + agentId: string; + role: string; + plannedTaskId?: string; + workItemId?: string; + }; + }; + export interface WorkflowTaskService { reportBuildOutcome(outcome: WorkflowBuildOutcome): Promise; reportVerificationVerdict(verdict: VerificationResult): Promise; @@ -854,7 +971,7 @@ export interface OrchestrationContext { /** Webhook base URL for the n8n instance (e.g. http://localhost:5678/webhook) — used to construct webhook URLs for created workflows */ webhookBaseUrl?: string; /** Spawn a detached background task that outlives the current orchestrator run */ - spawnBackgroundTask?: (opts: SpawnBackgroundTaskOptions) => void; + spawnBackgroundTask?: (opts: SpawnBackgroundTaskOptions) => SpawnBackgroundTaskResult; /** Cancel a running background task by its ID */ cancelBackgroundTask?: (taskId: string) => Promise; /** Persist and inspect dependency-aware planned tasks for this thread. */ @@ -876,6 +993,12 @@ export interface OrchestrationContext { * background task. Set by the host, not by user text — the create-tasks guard * reads this instead of substring-matching `currentUserMessage`. */ isReplanFollowUp?: boolean; + /** True when the current run was started to execute a planned-task checkpoint. + * The orchestrator should run the checkpoint's spec and call complete-checkpoint. */ + isCheckpointFollowUp?: boolean; + /** When isCheckpointFollowUp is true, the task ID of the checkpoint being executed. + * Used by the post-run deadlock fallback in the service. */ + checkpointTaskId?: string; /** The domain context — gives sub-agent tools access to n8n services */ domainContext?: InstanceAiContext; /** When true, research guidance may suggest planned research tasks and the builder gets web-search/fetch-url */ @@ -909,7 +1032,12 @@ export interface CreateInstanceAgentOptions { memoryConfig: InstanceAiMemoryConfig; /** Pre-built Memory instance. When provided, `memoryConfig` is ignored for memory creation. */ memory?: Memory; - /** Workspace with sandbox for code execution. When provided, the agent gets execute_command tool. */ + /** + * @deprecated Ignored by the orchestrator. Passing a workspace here used to auto-register + * `mastra_workspace_*` tools on the orchestrator, which the LLM abused as a `sleep` primitive + * and mis-routed for build-task polling. Sandbox access is now scoped to the workflow-builder + * subagent via `builderSandboxFactory`; `orchestrationContext.workspace` still flows to it. + */ workspace?: Workspace; /** When true, all tools are loaded eagerly (no ToolSearchProcessor). Workaround for Mastra bug where toModelOutput is not called for deferred tools. */ disableDeferredTools?: boolean; diff --git a/packages/@n8n/instance-ai/src/workflow-loop/workflow-loop-state.ts b/packages/@n8n/instance-ai/src/workflow-loop/workflow-loop-state.ts index 31d7d3deabf..92b0c629f67 100644 --- a/packages/@n8n/instance-ai/src/workflow-loop/workflow-loop-state.ts +++ b/packages/@n8n/instance-ai/src/workflow-loop/workflow-loop-state.ts @@ -65,12 +65,55 @@ export type AttemptRecord = z.infer; export const triggerTypeSchema = z.enum(['manual_or_testable', 'trigger_only']); +/** + * Structured verification evidence the builder captures when it runs + * `verify-built-workflow`. Downstream checkpoint runs read this and skip + * running verify again when `success === true`. + */ +export const workflowVerificationEvidenceSchema = z.object({ + attempted: z.boolean(), + success: z.boolean(), + executionId: z.string().optional(), + status: z.enum(['success', 'error', 'waiting', 'running', 'unknown']).optional(), + failureSignature: z.string().optional(), + evidence: z + .object({ + nodesExecuted: z.array(z.string()).optional(), + producedOutputRows: z.number().optional(), + errorNodeName: z.string().optional(), + errorMessage: z.string().optional(), + }) + .optional(), + verifiedAt: z.string().datetime().optional(), +}); + +export type WorkflowVerificationEvidence = z.infer; + +/** + * Structured trigger descriptor for each trigger node in the submitted workflow. + * The orchestrator uses `nodeType` to decide whether the bypassPlan post-build + * flow can invoke `verify-built-workflow` (mockable types) or must defer to a + * manual user test (polling / OAuth-bound triggers). + */ +export const triggerNodeDescriptorSchema = z.object({ + nodeName: z.string(), + nodeType: z.string(), +}); + +export type TriggerNodeDescriptor = z.infer; + export const workflowBuildOutcomeSchema = z.object({ workItemId: z.string(), taskId: z.string(), workflowId: z.string().optional(), submitted: z.boolean(), triggerType: triggerTypeSchema, + /** + * Trigger nodes in the submitted workflow. Populated on successful submits; + * absent on failed or pre-submit outcomes. The orchestrator reads `nodeType` + * to pick a `verify-built-workflow` `inputData` shape for bypassPlan builds. + */ + triggerNodes: z.array(triggerNodeDescriptorSchema).optional(), needsUserInput: z.boolean(), blockingReason: z.string().optional(), failureSignature: z.string().optional(), @@ -84,6 +127,13 @@ export const workflowBuildOutcomeSchema = z.object({ verificationPinData: z.record(z.array(z.record(z.unknown()))).optional(), /** Whether any node parameters contain unresolved placeholder values. */ hasUnresolvedPlaceholders: z.boolean().optional(), + /** + * Structured verification record from the most recent `verify-built-workflow` call + * that executed inside the builder. Observability metadata only: checkpoints must + * still run independent verification before completing — the builder's self-report + * is a claim, not proof. + */ + verification: workflowVerificationEvidenceSchema.optional(), summary: z.string(), }); diff --git a/packages/@n8n/instance-ai/src/workspace/__tests__/builder-sandbox-factory.test.ts b/packages/@n8n/instance-ai/src/workspace/__tests__/builder-sandbox-factory.test.ts new file mode 100644 index 00000000000..c4857924647 --- /dev/null +++ b/packages/@n8n/instance-ai/src/workspace/__tests__/builder-sandbox-factory.test.ts @@ -0,0 +1,147 @@ +// Tight mocks so we can drive `createN8nSandbox` end-to-end in Jest without +// touching real sandboxes, filesystems, or the Mastra runtime. +jest.mock('@mastra/core/workspace', () => { + class Workspace { + sandbox: unknown; + filesystem: unknown; + constructor(opts: { sandbox: unknown; filesystem: unknown }) { + this.sandbox = opts.sandbox; + this.filesystem = opts.filesystem; + } + async init(): Promise { + await Promise.resolve(); + } + } + class LocalSandbox {} + class LocalFilesystem {} + return { Workspace, LocalSandbox, LocalFilesystem }; +}); + +jest.mock('@mastra/daytona', () => ({ DaytonaSandbox: class {} })); +jest.mock('@daytonaio/sdk', () => ({ Daytona: class {} })); + +jest.mock('../daytona-filesystem', () => ({ + DaytonaFilesystem: class { + constructor(public sandbox: unknown) {} + }, +})); + +jest.mock('../n8n-sandbox-filesystem', () => ({ + N8nSandboxFilesystem: class { + constructor(public sandbox: unknown) {} + writeFile = jest.fn(async () => { + await Promise.resolve(); + }); + }, +})); + +jest.mock('../n8n-sandbox-image-manager', () => ({ + N8nSandboxImageManager: class { + getDockerfile() { + return 'FROM node:20'; + } + }, +})); + +type MockN8nSandbox = { destroy: jest.Mock }; +const capturedSandboxes: MockN8nSandbox[] = []; + +jest.mock('../n8n-sandbox-sandbox', () => ({ + N8nSandboxServiceSandbox: class { + destroy = jest.fn(async () => { + await Promise.resolve(); + }); + constructor(public opts: Record) { + capturedSandboxes.push(this as unknown as MockN8nSandbox); + } + }, +})); + +jest.mock('../sandbox-fs', () => ({ + runInSandbox: jest.fn(async () => await Promise.resolve({ exitCode: 0, stdout: '', stderr: '' })), + writeFileViaSandbox: jest.fn(async () => { + await Promise.resolve(); + }), +})); + +jest.mock('../sandbox-setup', () => ({ + getWorkspaceRoot: jest.fn(async () => await Promise.resolve('/workspace')), + formatNodeCatalogLine: jest.fn((x: { name?: string }) => x.name ?? ''), + setupSandboxWorkspace: jest.fn(async () => await Promise.resolve()), +})); + +import type { InstanceAiContext } from '../../types'; +import type { SandboxConfig } from '../create-workspace'; + +const { BuilderSandboxFactory } = + // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/consistent-type-imports + require('../builder-sandbox-factory') as typeof import('../builder-sandbox-factory'); + +function makeContext(): InstanceAiContext { + return { + nodeService: { + listSearchable: jest.fn(async () => await Promise.resolve([{ name: 'node-a' }])), + }, + } as unknown as InstanceAiContext; +} + +function makeConfig(): SandboxConfig { + return { + enabled: true, + provider: 'n8n-sandbox', + serviceUrl: 'https://sandbox.example.com', + apiKey: 'secret', + } as SandboxConfig; +} + +describe('BuilderSandboxFactory.createN8nSandbox cleanup on failure', () => { + beforeEach(() => { + capturedSandboxes.length = 0; + }); + + it('destroys the remote sandbox when a post-creation step throws', async () => { + // Force `getWorkspaceRoot` to throw so the post-creation workspace setup + // fails. Any step after `new N8nSandboxServiceSandbox(...)` that can throw + // (workspace.init, getWorkspaceRoot, catalog write, SDK link) should + // funnel through the same destroy path. + // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/consistent-type-imports + const sandboxSetup = require('../sandbox-setup') as typeof import('../sandbox-setup'); + (sandboxSetup.getWorkspaceRoot as jest.Mock).mockRejectedValueOnce(new Error('setup boom')); + + const factory = new BuilderSandboxFactory(makeConfig(), undefined); + + await expect(factory.create('b-1', makeContext())).rejects.toThrow('setup boom'); + + expect(capturedSandboxes).toHaveLength(1); + expect(capturedSandboxes[0].destroy).toHaveBeenCalledTimes(1); + }); + + it('swallows destroy errors so the original failure is surfaced, not the cleanup error', async () => { + // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/consistent-type-imports + const sandboxSetup = require('../sandbox-setup') as typeof import('../sandbox-setup'); + (sandboxSetup.getWorkspaceRoot as jest.Mock).mockRejectedValueOnce(new Error('setup boom')); + + const factory = new BuilderSandboxFactory(makeConfig(), undefined); + const createPromise = factory.create('b-2', makeContext()); + + // Arrange: when createN8nSandbox tries to destroy after the error, that + // call also throws. The user-facing error must still be the original. + await expect(createPromise).rejects.toThrow('setup boom'); + + expect(capturedSandboxes).toHaveLength(1); + // The next spawn should also destroy cleanly even after a prior destroy failed. + capturedSandboxes[0].destroy.mockRejectedValueOnce(new Error('destroy also failed')); + }); + + it('returns a cleanup handle that destroys the sandbox when create succeeds', async () => { + const factory = new BuilderSandboxFactory(makeConfig(), undefined); + const bw = await factory.create('b-3', makeContext()); + + expect(capturedSandboxes).toHaveLength(1); + expect(capturedSandboxes[0].destroy).not.toHaveBeenCalled(); + + await bw.cleanup(); + + expect(capturedSandboxes[0].destroy).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/@n8n/instance-ai/src/workspace/builder-sandbox-factory.ts b/packages/@n8n/instance-ai/src/workspace/builder-sandbox-factory.ts index 14ab7ae156e..1fe72197ec9 100644 --- a/packages/@n8n/instance-ai/src/workspace/builder-sandbox-factory.ts +++ b/packages/@n8n/instance-ai/src/workspace/builder-sandbox-factory.ts @@ -259,33 +259,44 @@ export class BuilderSandboxFactory { dockerfile, }); - const workspace = new Workspace({ - sandbox, - filesystem: new N8nSandboxFilesystem(sandbox), - }); - - await workspace.init(); - - const root = await getWorkspaceRoot(workspace); - if (workspace.filesystem) { - await workspace.filesystem.writeFile(`${root}/node-types/index.txt`, catalog); - } else { - await writeFileViaSandbox(workspace, `${root}/node-types/index.txt`, catalog); - } - - await this.linkWorkspaceSdkIfEnabled(workspace, root); - - return { - workspace, - cleanup: async () => { - await cleanupTrackedSandboxProcesses(workspace); - try { - await sandbox.destroy(); - } catch { - // Best-effort cleanup - } - }, + const destroySandbox = async (): Promise => { + try { + await sandbox.destroy(); + } catch { + // Best-effort cleanup + } }; + + try { + const workspace = new Workspace({ + sandbox, + filesystem: new N8nSandboxFilesystem(sandbox), + }); + + await workspace.init(); + + const root = await getWorkspaceRoot(workspace); + if (workspace.filesystem) { + await workspace.filesystem.writeFile(`${root}/node-types/index.txt`, catalog); + } else { + await writeFileViaSandbox(workspace, `${root}/node-types/index.txt`, catalog); + } + + await this.linkWorkspaceSdkIfEnabled(workspace, root); + + return { + workspace, + cleanup: async () => { + await cleanupTrackedSandboxProcesses(workspace); + await destroySandbox(); + }, + }; + } catch (error) { + // If any step after sandbox creation throws (workspace init, catalog + // write, SDK link), destroy the remote sandbox so it isn't orphaned. + await destroySandbox(); + throw error; + } } private assertIsDaytona(): Extract { diff --git a/packages/@n8n/workflow-sdk/src/index.ts b/packages/@n8n/workflow-sdk/src/index.ts index 0ccf6b2c55d..01a36555605 100644 --- a/packages/@n8n/workflow-sdk/src/index.ts +++ b/packages/@n8n/workflow-sdk/src/index.ts @@ -125,6 +125,7 @@ export type { SwitchCaseTarget } from './workflow-builder/control-flow-builders/ // Split in batches export { splitInBatches } from './workflow-builder/control-flow-builders/split-in-batches'; +export type { SplitInBatchesTarget } from './types/base'; // Note: fanOut() removed - use plain arrays for parallel connections // Note: fanIn() removed - use multiple .to(node.input(n)) calls instead diff --git a/packages/@n8n/workflow-sdk/src/prompts/sdk-reference/workflow-patterns.ts b/packages/@n8n/workflow-sdk/src/prompts/sdk-reference/workflow-patterns.ts index 583f9d0bf8f..a212da0d3be 100644 --- a/packages/@n8n/workflow-sdk/src/prompts/sdk-reference/workflow-patterns.ts +++ b/packages/@n8n/workflow-sdk/src/prompts/sdk-reference/workflow-patterns.ts @@ -96,49 +96,62 @@ export default workflow('id', 'name') -Nodes that fetch or filter data may return 0 items, which stops the entire downstream chain. -Use \`alwaysOutputData: true\` on data-fetching nodes to ensure the chain continues with an empty item \`{json: {}}\`. +When a node returns 0 items, downstream nodes are skipped for that execution. **This is usually the correct behavior** — the scheduler / trigger fires again later, and when there is data, the chain runs normally. Don't paper over an empty result with \`alwaysOutputData: true\` by default. +**\`alwaysOutputData: true\` forces a synthetic \`{json: {}}\` item downstream.** This is a footgun: downstream nodes will try to read fields that don't exist, HTTP requests will hit \`GET undefined\`, and loops will run once on a fake item. Use it *only* when the empty case has its own dedicated branch that you want to execute. + +**Correct pattern — no \`alwaysOutputData\`:** \`\`\`javascript -// Data Table might be empty (fresh table, no matching rows) -const getReflections = node({ - type: 'n8n-nodes-base.dataTable', - version: 1.1, +// Scheduler that processes pending work +workflow('ingest', 'Ingest Worker') + .add(scheduleTrigger) // fires every 5 min + .to(getPending) // returns 0..N rows; no alwaysOutputData + .to(splitInBatches({version: 3, config: {parameters: {batchSize: 1}}}) + .onEachBatch(fetchUrl.to(embed).to(saveChunk)) + ); +// On runs where getPending returns 0 items, the loop simply doesn't execute. +// On runs where it returns rows, the loop iterates. No gate, no filter needed. +\`\`\` + +**Correct pattern — empty case needs its own branch:** +\`\`\`javascript +// "No matches found" deserves a notification +const search = node({ + type: 'n8n-nodes-base.httpRequest', + version: 4.4, config: { - name: 'Get Reflections', - alwaysOutputData: true, // Chain continues even if table is empty - parameters: { resource: 'row', operation: 'get', returnAll: true } + name: 'Search', + alwaysOutputData: true, // empty-case branch below needs to execute + parameters: { /* ... */ } } }); - -// Downstream Code node handles the empty case -const processData = node({ - type: 'n8n-nodes-base.code', - version: 2, +const hasResults = ifElse({ + version: 2.2, config: { - name: 'Process Data', + name: 'Has Results?', parameters: { - mode: 'runOnceForAllItems', - jsCode: \\\` -const items = $input.all(); -// items will be [{json: {}}] if upstream had no data -const hasData = items.length > 0 && Object.keys(items[0].json).length > 0; -// ... handle both cases -\\\`.trim() + conditions: { + options: { caseSensitive: true, typeValidation: 'loose' }, + conditions: [{ leftValue: '={{ $json.results }}', operator: { type: 'array', operation: 'notEmpty' } }], + combinator: 'and' + } } } }); +workflow('search', 'Search').add(trigger).to(search).to( + hasResults.onTrue(processResults).onFalse(notifyNoMatches) +); \`\`\` -**When to use \`alwaysOutputData: true\`:** -- Data Table with \`operation: 'get'\` (table may be empty or freshly created) -- Any lookup/search/filter node whose result feeds into downstream processing -- HTTP Request that may return an empty array +**When to use \`alwaysOutputData: true\`:** only when you've paired it with an explicit empty-case branch, AND the downstream branch doesn't blindly read item fields. **When NOT to use it:** -- Trigger nodes (they always produce output) -- Code nodes (handle empty input in your code logic instead) -- Nodes at the end of the chain (no downstream to protect) +- Scheduled/polling triggers where the "no work" case should silently skip +- Before a \`splitInBatches\` loop — loops already no-op on empty input +- Before a \`filter\` — the filter already no-ops on empty input +- When all you'd do on the empty case is "nothing" + +**Don't gate loops with an \`IF\`.** \`ifElse.onTrue(splitInBatches)\` to check "are there items?" is redundant — the loop already does the right thing with 0 items. Drop the IF. diff --git a/packages/@n8n/workflow-sdk/src/prompts/sdk-reference/workflow-rules.ts b/packages/@n8n/workflow-sdk/src/prompts/sdk-reference/workflow-rules.ts index bde8acf6b98..87a2d2250fe 100644 --- a/packages/@n8n/workflow-sdk/src/prompts/sdk-reference/workflow-rules.ts +++ b/packages/@n8n/workflow-sdk/src/prompts/sdk-reference/workflow-rules.ts @@ -14,14 +14,21 @@ export const WORKFLOW_RULES = `Follow these rules strictly when generating workf - Example: \`credentials: { slackApi: newCredential('Slack Bot') }\` - The credential type must match what the node expects -2. **Handle empty outputs with \`alwaysOutputData: true\`** - - Nodes that query data (Data Table get, Google Sheets lookup, HTTP Request, etc.) may return 0 items - - When a node returns 0 items, all downstream nodes are SKIPPED — the workflow chain breaks silently - - Set \`alwaysOutputData: true\` on any node whose output feeds downstream nodes and might return empty results - - Common cases: fresh/empty Data Tables, filtered queries, conditional lookups, API searches with no matches - - Example: \`config: { ..., alwaysOutputData: true }\` +2. **Trust empty item lists — don't synthesize fake items** + - When a query returns 0 items, downstream nodes simply don't run for that execution. For scheduled or polling triggers this is the correct "nothing to do this round" signal — the next run will execute normally when data appears. + - DO NOT add \`alwaysOutputData: true\` just to "keep the chain alive." Forcing an empty \`{}\` item downstream is what causes \`undefined\` reads, failed HTTP calls to \`GET undefined\`, and Code-node crashes on missing fields. + - DO NOT add an IF gate before a loop to check "has items?" — loops (\`splitInBatches\`, per-item nodes, \`filter\`) already no-op on empty input. The gate is redundant and adds a failure surface. + - \`alwaysOutputData: true\` is only correct when you specifically need a downstream branch to run on the "empty" case — e.g. a dedicated "no matches found" notification path. In that case, pair it with an \`IF\` that explicitly checks for the empty case and routes accordingly. Never use it as a default. + - To drop invalid items mid-pipeline, use a \`filter\` node. A \`filter\` that rejects everything emits 0 items and the chain correctly stops — no \`IF\` + \`splitInBatches\` composition needed. 3. **Use \`executeOnce: true\` for single-execution nodes** - When a node receives N items but should only execute once (not N times), set \`executeOnce: true\` - Common cases: sending a summary notification, generating a report, calling an API that doesn't need per-item execution - - Example: \`config: { ..., executeOnce: true }\``; + - Example: \`config: { ..., executeOnce: true }\` + +4. **Pick the right control-flow primitive** + - **Per-item loop with side effects (fetch, embed, write)** → \`splitInBatches\` with \`batchSize: 1\` feeding the per-item work, loop back via \`nextBatch\`. No \`IF\` gate before it. + - **Drop items that don't match a predicate** → \`filter\`. It emits 0 items when nothing matches, and the chain stops cleanly. + - **Two mutually exclusive paths that both do real work** → \`IF\` (\`onTrue\` / \`onFalse\`). + - **Many mutually exclusive paths keyed off a value** → \`switch\` (\`onCase\`). + - Nested control flow is supported: \`ifNode.onTrue(loopBuilder)\`, \`switchNode.onCase(0, loopBuilder)\`, and \`splitInBatches(sib).onEachBatch(ifElseBuilder)\` all compile and wire correctly. Use them when the semantics genuinely call for it, not as a workaround for empty-list handling.`; diff --git a/packages/@n8n/workflow-sdk/src/types/base.ts b/packages/@n8n/workflow-sdk/src/types/base.ts index 2b6fee4afa8..9771ae4a8d1 100644 --- a/packages/@n8n/workflow-sdk/src/types/base.ts +++ b/packages/@n8n/workflow-sdk/src/types/base.ts @@ -791,7 +791,8 @@ export type IfElseTarget = | NodeChain, NodeInstance> > | IfElseBuilder - | SwitchCaseBuilder; + | SwitchCaseBuilder + | SplitInBatchesBuilder; /** * Target type for Switch case branches - can be a node, chain, null, plain array (fan-out), or nested builder @@ -805,7 +806,24 @@ export type SwitchCaseTarget = | NodeChain, NodeInstance> > | IfElseBuilder - | SwitchCaseBuilder; + | SwitchCaseBuilder + | SplitInBatchesBuilder; + +/** + * Target type for SplitInBatches `onEachBatch` / `onDone` branches - can be a node, + * chain, null, plain array (fan-out), or nested control-flow builder. + */ +export type SplitInBatchesTarget = + | null + | NodeInstance + | NodeChain, NodeInstance> + | Array< + | NodeInstance + | NodeChain, NodeInstance> + > + | IfElseBuilder + | SwitchCaseBuilder + | SplitInBatchesBuilder; /** * Fluent builder for IF nodes with onTrue/onFalse methods. @@ -848,10 +866,14 @@ export interface IfElseBuilder { onFalse(target: IfElseTarget): IfElseBuilder; /** - * Set the target for the error branch (output 2). - * Only applicable when the IF node has onError: 'continueErrorOutput'. + * Set the target for the IF node's own error output (output 2). * - * @param target - The node or chain to execute on error + * This wires the IF node's error branch — it is NOT a generic per-node + * "on-error" output. Only applicable when the IF node's config sets + * `onError: 'continueErrorOutput'`. For wiring a regular node's error + * output, use `node.onError(handler)` on the source node instead. + * + * @param target - The node or chain to execute when the IF condition errors */ onError(target: IfElseTarget): IfElseBuilder; @@ -938,16 +960,7 @@ export interface SplitInBatchesBuilder { * .onEachBatch(processNode.to(sibNode)) * .onDone(finalizeNode) */ - onEachBatch( - target: - | null - | NodeInstance - | NodeChain, NodeInstance> - | Array< - | NodeInstance - | NodeChain, NodeInstance> - >, - ): SplitInBatchesBuilder; + onEachBatch(target: SplitInBatchesTarget): SplitInBatchesBuilder; /** * Fluent API: Set the "done" branch target (output 0). @@ -959,16 +972,7 @@ export interface SplitInBatchesBuilder { * .onDone(finalizeNode) * .onEachBatch(processNode.to(sibNode)) */ - onDone( - target: - | null - | NodeInstance - | NodeChain, NodeInstance> - | Array< - | NodeInstance - | NodeChain, NodeInstance> - >, - ): SplitInBatchesBuilder; + onDone(target: SplitInBatchesTarget): SplitInBatchesBuilder; } // ============================================================================= diff --git a/packages/@n8n/workflow-sdk/src/workflow-builder.integration.test.ts b/packages/@n8n/workflow-sdk/src/workflow-builder.integration.test.ts index ad3921ad0e0..c468fdfc084 100644 --- a/packages/@n8n/workflow-sdk/src/workflow-builder.integration.test.ts +++ b/packages/@n8n/workflow-sdk/src/workflow-builder.integration.test.ts @@ -768,4 +768,121 @@ describe('New SDK API', () => { expect(json.connections['Handle Error'].main[0]![0].node).toBe('Notify'); }); }); + + describe('Nested control-flow targets', () => { + it('allows ifElse.onTrue(splitInBatchesBuilder)', () => { + const t = createTrigger('Start'); + const ifNode = createIfNode('HasItems?'); + const sibNode = createSplitInBatchesNode('Loop'); + const processNode = createNode('Process'); + const doneNode = createNode('Done'); + + const loop = splitInBatches(sibNode).onEachBatch(processNode).onDone(doneNode); + + const wf = workflow('test', 'Test').add(t).to(ifNode.onTrue!(loop).onFalse(null)); + + const json = wf.toJSON(); + + // IF true output wires to the SIB node (head of the nested builder) + expect(json.connections['HasItems?'].main[0]![0].node).toBe('Loop'); + // SIB branches are wired by the SIB handler + expect(json.connections['Loop'].main[0]![0].node).toBe('Done'); + expect(json.connections['Loop'].main[1]![0].node).toBe('Process'); + }); + + it('allows ifElse.onFalse(splitInBatchesBuilder)', () => { + const t = createTrigger('Start'); + const ifNode = createIfNode('Flag?'); + const sibNode = createSplitInBatchesNode('Loop'); + const processNode = createNode('Process'); + const successNode = createNode('Success'); + + const loop = splitInBatches(sibNode).onEachBatch(processNode); + + const wf = workflow('test', 'Test').add(t).to(ifNode.onTrue!(successNode).onFalse(loop)); + + const json = wf.toJSON(); + + expect(json.connections['Flag?'].main[0]![0].node).toBe('Success'); + expect(json.connections['Flag?'].main[1]![0].node).toBe('Loop'); + expect(json.connections['Loop'].main[1]![0].node).toBe('Process'); + }); + + it('allows ifElse.onError(splitInBatchesBuilder)', () => { + const t = createTrigger('Start'); + const ifNode = node({ + type: 'n8n-nodes-base.if', + version: 2.2, + config: { + name: 'Gate', + onError: 'continueErrorOutput', + parameters: { + conditions: { + conditions: [ + { + leftValue: '={{ $json.value }}', + operator: { type: 'boolean', operation: 'true' }, + }, + ], + }, + }, + }, + }) as NodeInstance<'n8n-nodes-base.if', string, unknown>; + const sibNode = createSplitInBatchesNode('ErrorLoop'); + const recover = createNode('Recover'); + const ok = createNode('OK'); + + const loop = splitInBatches(sibNode).onEachBatch(recover); + + const wf = workflow('test', 'Test').add(t).to(ifNode.onTrue!(ok).onFalse(null).onError(loop)); + + const json = wf.toJSON(); + + // IF with onError='continueErrorOutput' emits three main outputs: true/false/error. + // The error branch lands on output 2 and points at the SIB head. + expect(json.connections['Gate'].main[2]![0].node).toBe('ErrorLoop'); + }); + + it('allows switch.onCase(n, splitInBatchesBuilder)', () => { + const t = createTrigger('Start'); + const switchNode = createSwitchNode('Route'); + const sibNode = createSplitInBatchesNode('BatchA'); + const processA = createNode('ProcessA'); + const simple = createNode('Simple'); + + const loop = splitInBatches(sibNode).onEachBatch(processA); + + const wf = workflow('test', 'Test').add(t).to(switchNode.onCase!(0, loop).onCase(1, simple)); + + const json = wf.toJSON(); + + expect(json.connections['Route'].main[0]![0].node).toBe('BatchA'); + expect(json.connections['Route'].main[1]![0].node).toBe('Simple'); + }); + + it('allows splitInBatches.onEachBatch(ifElseBuilder)', () => { + const t = createTrigger('Start'); + const sibNode = createSplitInBatchesNode('Loop'); + const ifNode = createIfNode('PerItem'); + const hit = createNode('Hit'); + const miss = createNode('Miss'); + const finalize = createNode('Finalize'); + + const loop = splitInBatches(sibNode) + .onEachBatch(ifNode.onTrue!(hit).onFalse(miss)) + .onDone(finalize); + + const wf = workflow('test', 'Test').add(t).to(loop); + + const json = wf.toJSON(); + + // SIB each output (index 1) -> IF head + expect(json.connections['Loop'].main[1]![0].node).toBe('PerItem'); + // IF branches materialised + expect(json.connections['PerItem'].main[0]![0].node).toBe('Hit'); + expect(json.connections['PerItem'].main[1]![0].node).toBe('Miss'); + // Done output wired to finalize + expect(json.connections['Loop'].main[0]![0].node).toBe('Finalize'); + }); + }); }); diff --git a/packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/if-else.ts b/packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/if-else.ts index 456f4319a22..556af2e4ae0 100644 --- a/packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/if-else.ts +++ b/packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/if-else.ts @@ -1,15 +1 @@ -import type { NodeInstance, NodeChain, IfElseBuilder, SwitchCaseBuilder } from '../../types/base'; - -/** - * A branch target - can be a node, node chain, null, plain array (fan-out), or nested builder - */ -export type IfElseTarget = - | null - | NodeInstance - | NodeChain, NodeInstance> - | Array< - | NodeInstance - | NodeChain, NodeInstance> - > - | IfElseBuilder - | SwitchCaseBuilder; +export type { IfElseTarget } from '../../types/base'; diff --git a/packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/split-in-batches.ts b/packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/split-in-batches.ts index 032220aafb9..0d9ae1d2b9a 100644 --- a/packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/split-in-batches.ts +++ b/packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/split-in-batches.ts @@ -90,6 +90,7 @@ export type NodeBatch = * - NodeInstance: single target * - NodeChain: a chain of nodes * - Plain array: multiple parallel targets (fan-out) + * - Nested control-flow builder (IfElse / SwitchCase / SplitInBatches) */ export type BranchTarget = | null @@ -98,7 +99,10 @@ export type BranchTarget = | Array< | NodeInstance | NodeChain, NodeInstance> - >; + > + | IfElseBuilder + | SwitchCaseBuilder + | SplitInBatchesBuilder; /** * Named object syntax for splitInBatches branches. @@ -396,7 +400,7 @@ function extractNodesFromTarget( } // Handle IfElseBuilder (fluent API) if (isIfElseBuilder(target)) { - const builder = target as IfElseBuilder; + const builder = target; const nodes: Array> = [builder.ifNode]; nodes.push(...extractNodesFromTarget(builder.trueBranch as BranchTarget)); nodes.push(...extractNodesFromTarget(builder.falseBranch as BranchTarget)); @@ -404,15 +408,52 @@ function extractNodesFromTarget( } // Handle SwitchCaseBuilder (fluent API) if (isSwitchCaseBuilder(target)) { - const builder = target as SwitchCaseBuilder; + const builder = target; const nodes: Array> = [builder.switchNode]; for (const caseTarget of builder.caseMapping.values()) { nodes.push(...extractNodesFromTarget(caseTarget as BranchTarget)); } return nodes; } + // Handle nested SplitInBatchesBuilder (duck-type so it covers all three impl classes) + if (isSplitInBatchesBuilderShape(target)) { + const nodes: Array> = [target.sibNode]; + for (const doneBatch of target._doneBatches) { + nodes.push(...extractNodesFromTarget(doneBatch as BranchTarget)); + } + for (const eachBatch of target._eachBatches) { + nodes.push(...extractNodesFromTarget(eachBatch as BranchTarget)); + } + if (target._doneTarget !== undefined) { + nodes.push(...extractNodesFromTarget(target._doneTarget)); + } + if (target._eachTarget !== undefined) { + nodes.push(...extractNodesFromTarget(target._eachTarget)); + } + return nodes; + } // It's a single NodeInstance - return [target]; + return [target as NodeInstance]; +} + +/** + * Duck-type check for any SplitInBatchesBuilder implementation (Impl, WithExistingNode, + * NamedSyntax). Covers all three classes because they all expose the same shape. + */ +function isSplitInBatchesBuilderShape(value: unknown): value is { + sibNode: NodeInstance<'n8n-nodes-base.splitInBatches', string, unknown>; + _doneBatches: NodeBatch[]; + _eachBatches: NodeBatch[]; + _doneTarget?: BranchTarget; + _eachTarget?: BranchTarget; +} { + return ( + value !== null && + typeof value === 'object' && + 'sibNode' in value && + '_doneBatches' in value && + '_eachBatches' in value + ); } /** @@ -436,8 +477,12 @@ function getFirstNodes(target: BranchTarget): Array]; } /** diff --git a/packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/switch-case.ts b/packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/switch-case.ts index 2f3be102095..4c91efab7ab 100644 --- a/packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/switch-case.ts +++ b/packages/@n8n/workflow-sdk/src/workflow-builder/control-flow-builders/switch-case.ts @@ -1,13 +1 @@ -import type { NodeInstance, NodeChain } from '../../types/base'; - -/** - * A case target - can be a node, node chain, null, or plain array (fan-out) - */ -export type SwitchCaseTarget = - | null - | NodeInstance - | NodeChain, NodeInstance> - | Array< - | NodeInstance - | NodeChain, NodeInstance> - >; +export type { SwitchCaseTarget } from '../../types/base'; diff --git a/packages/@n8n/workflow-sdk/src/workflow-builder/node-builders/node-builder.ts b/packages/@n8n/workflow-sdk/src/workflow-builder/node-builders/node-builder.ts index 5b76f7a1436..b6caa8d4646 100644 --- a/packages/@n8n/workflow-sdk/src/workflow-builder/node-builders/node-builder.ts +++ b/packages/@n8n/workflow-sdk/src/workflow-builder/node-builders/node-builder.ts @@ -581,6 +581,27 @@ function extractNodesFromTarget(target: unknown): Array> = [builder.sibNode]; + for (const doneTarget of builder._doneBatches) { + nodes.push(...extractNodesFromTarget(doneTarget)); + } + for (const eachTarget of builder._eachBatches) { + nodes.push(...extractNodesFromTarget(eachTarget)); + } + if (builder._doneTarget !== undefined) { + nodes.push(...extractNodesFromTarget(builder._doneTarget)); + } + if (builder._eachTarget !== undefined) { + nodes.push(...extractNodesFromTarget(builder._eachTarget)); + } + return nodes; + } + // Check if it's a node-like object with type, version, config if ( target !== null && diff --git a/packages/cli/src/modules/instance-ai/__tests__/instance-ai.adapter.service.test.ts b/packages/cli/src/modules/instance-ai/__tests__/instance-ai.adapter.service.test.ts index 5dfdee59713..0fc03250c0c 100644 --- a/packages/cli/src/modules/instance-ai/__tests__/instance-ai.adapter.service.test.ts +++ b/packages/cli/src/modules/instance-ai/__tests__/instance-ai.adapter.service.test.ts @@ -15,6 +15,7 @@ import { extractExecutionResult, extractExecutionDebugInfo, extractNodeOutput, + resolveDataTableByIdOrName, truncateNodeOutput, truncateResultData, } from '../instance-ai.adapter.service'; @@ -826,7 +827,7 @@ function createDataTableAdapterForTests(overrides?: { }; const mockDataTableRepository = { - findOneByOrFail: jest + findOneBy: jest .fn() .mockResolvedValue({ id: 'dt-1', name: 'Orders', projectId: 'team-project-id' }), }; @@ -1546,3 +1547,125 @@ describe('createExecutionAdapter', () => { expect(query).not.toHaveProperty('accessibleWorkflowIds'); }); }); + +// --------------------------------------------------------------------------- +// resolveDataTableByIdOrName +// --------------------------------------------------------------------------- + +describe('resolveDataTableByIdOrName', () => { + type TableRecord = { id: string; name: string; projectId: string }; + + function makeRepo(tables: TableRecord[]) { + return { + findOneBy: jest.fn(async (where: { id: string }) => { + return tables.find((t) => t.id === where.id) ?? null; + }), + findBy: jest.fn(async (where: { name: string; projectId?: string }) => { + return tables.filter( + (t) => t.name === where.name && (!where.projectId || t.projectId === where.projectId), + ); + }), + }; + } + + function makeLogger() { + return { warn: jest.fn() }; + } + + const table = { id: 'dt_uuid_123', name: 'kb_sources', projectId: 'proj_1' }; + + it('returns hit on an id match without logging a warning', async () => { + const repo = makeRepo([table]); + const logger = makeLogger(); + + const result = await resolveDataTableByIdOrName(repo, logger, 'dt_uuid_123'); + + expect(result).toEqual({ kind: 'hit', table }); + expect(repo.findOneBy).toHaveBeenCalledWith({ id: 'dt_uuid_123' }); + expect(repo.findBy).not.toHaveBeenCalled(); + expect(logger.warn).not.toHaveBeenCalled(); + }); + + it('falls back to name lookup when the id lookup misses, and warns', async () => { + const repo = makeRepo([table]); + const logger = makeLogger(); + + const result = await resolveDataTableByIdOrName(repo, logger, 'kb_sources'); + + expect(result).toEqual({ kind: 'hit', table }); + expect(repo.findOneBy).toHaveBeenCalledWith({ id: 'kb_sources' }); + expect(repo.findBy).toHaveBeenCalledWith({ name: 'kb_sources' }); + expect(logger.warn).toHaveBeenCalledTimes(1); + expect(logger.warn.mock.calls[0][0]).toMatch(/called with table name instead of id/); + expect(logger.warn.mock.calls[0][1]).toEqual({ + passedValue: 'kb_sources', + resolvedId: 'dt_uuid_123', + projectId: 'proj_1', + }); + }); + + it('returns miss when neither id nor name matches', async () => { + const repo = makeRepo([table]); + const logger = makeLogger(); + + const result = await resolveDataTableByIdOrName(repo, logger, 'does_not_exist'); + + expect(result).toEqual({ kind: 'miss' }); + expect(logger.warn).not.toHaveBeenCalled(); + }); + + it('filters id hits that fail the access filter', async () => { + const repo = makeRepo([table]); + const logger = makeLogger(); + + const result = await resolveDataTableByIdOrName(repo, logger, 'dt_uuid_123', { + accessFilter: async () => false, + }); + + expect(result).toEqual({ kind: 'miss' }); + }); + + it('narrows the name lookup when projectIdFilter is provided', async () => { + const repo = makeRepo([table, { id: 'dt_uuid_456', name: 'kb_sources', projectId: 'proj_2' }]); + const logger = makeLogger(); + + const result = await resolveDataTableByIdOrName(repo, logger, 'kb_sources', { + projectIdFilter: 'proj_2', + }); + + expect(result.kind).toBe('hit'); + expect(repo.findBy).toHaveBeenCalledWith({ name: 'kb_sources', projectId: 'proj_2' }); + if (result.kind === 'hit') expect(result.table.id).toBe('dt_uuid_456'); + }); + + it('returns ambiguous when multiple accessible candidates share a name', async () => { + const twin = { id: 'dt_uuid_456', name: 'kb_sources', projectId: 'proj_2' }; + const repo = makeRepo([table, twin]); + const logger = makeLogger(); + + const result = await resolveDataTableByIdOrName(repo, logger, 'kb_sources', { + accessFilter: async () => true, + }); + + expect(result.kind).toBe('ambiguous'); + if (result.kind === 'ambiguous') { + expect(result.candidates).toHaveLength(2); + expect(result.candidates.map((c) => c.projectId).sort()).toEqual(['proj_1', 'proj_2']); + } + expect(logger.warn).not.toHaveBeenCalled(); + }); + + it('picks the single accessible candidate when ambiguity is resolved by access filter', async () => { + const twin = { id: 'dt_uuid_456', name: 'kb_sources', projectId: 'proj_2' }; + const repo = makeRepo([table, twin]); + const logger = makeLogger(); + + const result = await resolveDataTableByIdOrName(repo, logger, 'kb_sources', { + accessFilter: async (id) => id === 'dt_uuid_123', + }); + + expect(result.kind).toBe('hit'); + if (result.kind === 'hit') expect(result.table.id).toBe('dt_uuid_123'); + expect(logger.warn).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/cli/src/modules/instance-ai/__tests__/instance-ai.service.test.ts b/packages/cli/src/modules/instance-ai/__tests__/instance-ai.service.test.ts new file mode 100644 index 00000000000..6ac1c902024 --- /dev/null +++ b/packages/cli/src/modules/instance-ai/__tests__/instance-ai.service.test.ts @@ -0,0 +1,185 @@ +import type { z as zType } from 'zod'; + +// Manual mocks — must be declared before any imports that touch the mocked modules. +jest.mock('@n8n/instance-ai', () => { + const { z } = jest.requireActual<{ z: typeof zType }>('zod'); + return { + McpClientManager: class { + disconnect = jest.fn(); + }, + createDomainAccessTracker: jest.fn(), + BuilderSandboxFactory: class {}, + SnapshotManager: class {}, + createSandbox: jest.fn(), + createWorkspace: jest.fn(), + workflowBuildOutcomeSchema: z.object({}), + handleBuildOutcome: jest.fn(), + handleVerificationVerdict: jest.fn(), + createInstanceAgent: jest.fn(), + createAllTools: jest.fn(), + createMemory: jest.fn(), + mapMastraChunkToEvent: jest.fn(), + }; +}); +jest.mock('@mastra/core/agent', () => ({})); +jest.mock('@mastra/core/storage', () => ({ + MemoryStorage: class {}, + MastraCompositeStore: class {}, + WorkflowsStorage: class {}, +})); +jest.mock('@mastra/memory', () => ({ + Memory: class {}, +})); +jest.mock('@mastra/core/workflows', () => ({})); + +import type { User } from '@n8n/db'; + +import { InstanceAiService } from '../instance-ai.service'; + +type ServiceInternals = { + pendingCheckpointReentries: Map>; + queuePendingCheckpointReentry: (threadId: string, checkpointTaskId: string) => void; + drainPendingCheckpointReentries: (user: User, threadId: string) => Promise; + reenterCheckpointById: jest.Mock, [User, string, string, string?]>; + backgroundTasks: { + getRunningTasksByParentCheckpoint: jest.Mock; + }; + runState: { + getActiveRunId: jest.Mock; + hasSuspendedRun: jest.Mock; + }; + logger: { debug: jest.Mock; warn: jest.Mock; error: jest.Mock }; +}; + +function createCheckpointService(): ServiceInternals { + // Bypass the constructor — we only exercise the three pending-reentry helpers + // and their direct dependencies. Everything else (scheduler, event bus, etc.) + // is out of scope for this unit. + const service = Object.create(InstanceAiService.prototype) as unknown as ServiceInternals; + + service.pendingCheckpointReentries = new Map(); + service.reenterCheckpointById = jest.fn( + async (_user: User, _threadId: string, _checkpointTaskId: string, _mgid?: string) => true, + ); + service.backgroundTasks = { + getRunningTasksByParentCheckpoint: jest.fn(() => []), + }; + service.runState = { + getActiveRunId: jest.fn(() => undefined), + hasSuspendedRun: jest.fn(() => false), + }; + service.logger = { + debug: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + }; + + return service; +} + +const fakeUser = { id: 'user-1' } as User; + +describe('InstanceAiService — pending checkpoint re-entry', () => { + describe('queuePendingCheckpointReentry', () => { + it('records a marker keyed by threadId + checkpointTaskId', () => { + const service = createCheckpointService(); + + service.queuePendingCheckpointReentry('thread-a', 'cp-1'); + + expect(service.pendingCheckpointReentries.get('thread-a')).toEqual(new Set(['cp-1'])); + }); + + it('deduplicates markers for the same (thread, checkpoint) pair', () => { + const service = createCheckpointService(); + + service.queuePendingCheckpointReentry('thread-a', 'cp-1'); + service.queuePendingCheckpointReentry('thread-a', 'cp-1'); + + expect(service.pendingCheckpointReentries.get('thread-a')?.size).toBe(1); + }); + + it('keeps markers for different threads separate', () => { + const service = createCheckpointService(); + + service.queuePendingCheckpointReentry('thread-a', 'cp-1'); + service.queuePendingCheckpointReentry('thread-b', 'cp-1'); + + expect(service.pendingCheckpointReentries.get('thread-a')).toEqual(new Set(['cp-1'])); + expect(service.pendingCheckpointReentries.get('thread-b')).toEqual(new Set(['cp-1'])); + }); + }); + + describe('drainPendingCheckpointReentries', () => { + it('fires re-entry for each queued marker when the thread is idle', async () => { + const service = createCheckpointService(); + service.queuePendingCheckpointReentry('thread-a', 'cp-1'); + service.queuePendingCheckpointReentry('thread-a', 'cp-2'); + + await service.drainPendingCheckpointReentries(fakeUser, 'thread-a'); + + expect(service.reenterCheckpointById).toHaveBeenCalledTimes(2); + expect(service.reenterCheckpointById).toHaveBeenCalledWith(fakeUser, 'thread-a', 'cp-1'); + expect(service.reenterCheckpointById).toHaveBeenCalledWith(fakeUser, 'thread-a', 'cp-2'); + expect(service.pendingCheckpointReentries.get('thread-a')).toBeUndefined(); + }); + + it('stops draining if a new run starts mid-drain', async () => { + const service = createCheckpointService(); + service.queuePendingCheckpointReentry('thread-a', 'cp-1'); + service.queuePendingCheckpointReentry('thread-a', 'cp-2'); + + // After the first re-entry fires, simulate a new active run. + let calls = 0; + service.reenterCheckpointById.mockImplementation(async () => { + calls += 1; + if (calls === 1) { + service.runState.getActiveRunId.mockReturnValue('run-new'); + } + return true; + }); + + await service.drainPendingCheckpointReentries(fakeUser, 'thread-a'); + + // First marker drained; second should remain queued for the next run's cleanup. + expect(service.reenterCheckpointById).toHaveBeenCalledTimes(1); + expect(service.pendingCheckpointReentries.get('thread-a')).toEqual(new Set(['cp-2'])); + }); + + it('skips a marker whose parent-tagged siblings are still running', async () => { + const service = createCheckpointService(); + service.queuePendingCheckpointReentry('thread-a', 'cp-1'); + service.queuePendingCheckpointReentry('thread-a', 'cp-2'); + + // cp-1 has a sibling still in flight, cp-2 is clear. + service.backgroundTasks.getRunningTasksByParentCheckpoint.mockImplementation( + (_threadId: string, cp: string) => (cp === 'cp-1' ? [{ taskId: 'sibling-running' }] : []), + ); + + await service.drainPendingCheckpointReentries(fakeUser, 'thread-a'); + + expect(service.reenterCheckpointById).toHaveBeenCalledTimes(1); + expect(service.reenterCheckpointById).toHaveBeenCalledWith(fakeUser, 'thread-a', 'cp-2'); + // cp-1 stays queued — the sibling's own settlement will drive the next drain. + expect(service.pendingCheckpointReentries.get('thread-a')).toEqual(new Set(['cp-1'])); + }); + + it('returns early when a suspended run is present', async () => { + const service = createCheckpointService(); + service.queuePendingCheckpointReentry('thread-a', 'cp-1'); + service.runState.hasSuspendedRun.mockReturnValue(true); + + await service.drainPendingCheckpointReentries(fakeUser, 'thread-a'); + + expect(service.reenterCheckpointById).not.toHaveBeenCalled(); + expect(service.pendingCheckpointReentries.get('thread-a')).toEqual(new Set(['cp-1'])); + }); + + it('is a no-op when no markers are queued', async () => { + const service = createCheckpointService(); + + await service.drainPendingCheckpointReentries(fakeUser, 'thread-nonexistent'); + + expect(service.reenterCheckpointById).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/packages/cli/src/modules/instance-ai/instance-ai.adapter.service.ts b/packages/cli/src/modules/instance-ai/instance-ai.adapter.service.ts index 055f68c4c4b..d9e3d8fc0f7 100644 --- a/packages/cli/src/modules/instance-ai/instance-ai.adapter.service.ts +++ b/packages/cli/src/modules/instance-ai/instance-ai.adapter.service.ts @@ -1177,24 +1177,65 @@ export class InstanceAiAdapterService { const { resolveProjectId } = this.createProjectScopeHelpers(user); - // Check scope for a data table and return its projectId for downstream service calls - const resolveProjectIdForTable = async (scopes: Scope[], dataTableId: string) => { - const allowed = await userHasScopes(user, scopes, false, { dataTableId }); - if (!allowed) { + const logger = this.logger; + + /** + * Resolve a data-table identifier (UUID or name) to a concrete row the + * caller can access. Returns the resolved `id`, `name`, and `projectId`. + * Throws on not-found, ambiguous-name (when multiple accessible projects + * share the name and no `projectId` disambiguator was given), or + * UUID+projectId mismatch (when both are provided but the UUID's actual + * project differs from the one passed). + */ + const resolveAccessibleTable = async ( + scopes: Scope[], + dataTableId: string, + disambiguator?: { projectId?: string }, + ): Promise => { + const projectIdFilter = disambiguator?.projectId; + const result = await resolveDataTableByIdOrName(dataTableRepository, logger, dataTableId, { + projectIdFilter, + accessFilter: async (id) => await userHasScopes(user, scopes, false, { dataTableId: id }), + }); + if (result.kind === 'miss') { throw new Error(`Data table "${dataTableId}" not found`); } - const table = await dataTableRepository.findOneByOrFail({ id: dataTableId }); - return table.projectId; + if (result.kind === 'ambiguous') { + const projectIds = result.candidates.map((c) => c.projectId).join(', '); + throw new Error( + `Data table name "${dataTableId}" is ambiguous across accessible projects ` + + `(${projectIds}); pass the UUID or include a \`projectId\` to disambiguate.`, + ); + } + // UUID + projectId mismatch: the id hit resolved, but the caller's + // disambiguator points at a different project. Never silently drop + // the projectId — return mismatch so the caller fixes the call. + if (projectIdFilter && result.table.projectId !== projectIdFilter) { + throw new Error( + `Data table "${dataTableId}" does not belong to project "${projectIdFilter}".`, + ); + } + return result.table; }; - // Like resolveProjectIdForTable but also returns the table name for artifact display - const resolveTableMeta = async (scopes: Scope[], dataTableId: string) => { - const allowed = await userHasScopes(user, scopes, false, { dataTableId }); - if (!allowed) { - throw new Error(`Data table "${dataTableId}" not found`); - } - const table = await dataTableRepository.findOneByOrFail({ id: dataTableId }); - return { projectId: table.projectId, tableName: table.name }; + // Check scope and return projectId + resolved UUID for downstream service calls + const resolveProjectIdForTable = async ( + scopes: Scope[], + dataTableId: string, + disambiguator?: { projectId?: string }, + ) => { + const table = await resolveAccessibleTable(scopes, dataTableId, disambiguator); + return { projectId: table.projectId, resolvedId: table.id }; + }; + + // Like resolveProjectIdForTable but also returns the table name + const resolveTableMeta = async ( + scopes: Scope[], + dataTableId: string, + disambiguator?: { projectId?: string }, + ) => { + const table = await resolveAccessibleTable(scopes, dataTableId, disambiguator); + return { projectId: table.projectId, tableName: table.name, resolvedId: table.id }; }; return { @@ -1231,15 +1272,23 @@ export class InstanceAiAdapterService { }; }, - async delete(dataTableId) { + async delete(dataTableId, options) { assertNotReadOnly(); - const projectId = await resolveProjectIdForTable(['dataTable:delete'], dataTableId); - await dataTableService.deleteDataTable(dataTableId, projectId); + const { projectId, resolvedId } = await resolveProjectIdForTable( + ['dataTable:delete'], + dataTableId, + options, + ); + await dataTableService.deleteDataTable(resolvedId, projectId); }, - async getSchema(dataTableId) { - const projectId = await resolveProjectIdForTable(['dataTable:read'], dataTableId); - const columns = await dataTableService.getColumns(dataTableId, projectId); + async getSchema(dataTableId, options) { + const { projectId, resolvedId } = await resolveProjectIdForTable( + ['dataTable:read'], + dataTableId, + options, + ); + const columns = await dataTableService.getColumns(resolvedId, projectId); return columns.map( (c, index): DataTableColumnInfo => ({ id: c.id, @@ -1250,10 +1299,14 @@ export class InstanceAiAdapterService { ); }, - async addColumn(dataTableId, column) { + async addColumn(dataTableId, column, options) { assertNotReadOnly(); - const projectId = await resolveProjectIdForTable(['dataTable:update'], dataTableId); - const result = await dataTableService.addColumn(dataTableId, projectId, column); + const { projectId, resolvedId } = await resolveProjectIdForTable( + ['dataTable:update'], + dataTableId, + options, + ); + const result = await dataTableService.addColumn(resolvedId, projectId, column); return { id: result.id, name: result.name, @@ -1262,84 +1315,99 @@ export class InstanceAiAdapterService { }; }, - async deleteColumn(dataTableId, columnId) { + async deleteColumn(dataTableId, columnId, options) { assertNotReadOnly(); - const projectId = await resolveProjectIdForTable(['dataTable:update'], dataTableId); - await dataTableService.deleteColumn(dataTableId, projectId, columnId); + const { projectId, resolvedId } = await resolveProjectIdForTable( + ['dataTable:update'], + dataTableId, + options, + ); + await dataTableService.deleteColumn(resolvedId, projectId, columnId); }, - async renameColumn(dataTableId, columnId, newName) { + async renameColumn(dataTableId, columnId, newName, options) { assertNotReadOnly(); - const projectId = await resolveProjectIdForTable(['dataTable:update'], dataTableId); - await dataTableService.renameColumn(dataTableId, projectId, columnId, { + const { projectId, resolvedId } = await resolveProjectIdForTable( + ['dataTable:update'], + dataTableId, + options, + ); + await dataTableService.renameColumn(resolvedId, projectId, columnId, { name: newName, }); }, async queryRows(dataTableId, options) { - const projectId = await resolveProjectIdForTable(['dataTable:readRow'], dataTableId); - return await dataTableService.getManyRowsAndCount(dataTableId, projectId, { + const { projectId, resolvedId } = await resolveProjectIdForTable( + ['dataTable:readRow'], + dataTableId, + options, + ); + return await dataTableService.getManyRowsAndCount(resolvedId, projectId, { take: options?.limit ?? 50, skip: options?.offset ?? 0, filter: options?.filter as DataTableFilter | undefined, }); }, - async insertRows(dataTableId, rows) { + async insertRows(dataTableId, rows, options) { assertNotReadOnly(); - const { projectId, tableName } = await resolveTableMeta( + const { projectId, tableName, resolvedId } = await resolveTableMeta( ['dataTable:writeRow'], dataTableId, + options, ); const result = await dataTableService.insertRows( - dataTableId, + resolvedId, projectId, rows as DataTableRows, 'count', ); return { insertedCount: typeof result === 'number' ? result : rows.length, - dataTableId, + dataTableId: resolvedId, tableName, projectId, }; }, - async updateRows(dataTableId, filter, data) { + async updateRows(dataTableId, filter, data, options) { assertNotReadOnly(); - const { projectId, tableName } = await resolveTableMeta( + const { projectId, tableName, resolvedId } = await resolveTableMeta( ['dataTable:writeRow'], dataTableId, + options, ); const result = await dataTableService.updateRows( - dataTableId, + resolvedId, projectId, { filter: filter as DataTableFilter, data: data as DataTableRow }, true, ); return { updatedCount: Array.isArray(result) ? result.length : 0, - dataTableId, + dataTableId: resolvedId, tableName, projectId, }; }, - async deleteRows(dataTableId, filter) { + async deleteRows(dataTableId, filter, options) { assertNotReadOnly(); - const { projectId, tableName } = await resolveTableMeta( + const { projectId, tableName, resolvedId } = await resolveTableMeta( ['dataTable:writeRow'], dataTableId, + options, ); const result = await dataTableService.deleteRows( - dataTableId, + resolvedId, projectId, { filter: filter as DataTableFilter }, true, ); return { deletedCount: Array.isArray(result) ? result.length : 0, - dataTableId, + dataTableId: resolvedId, tableName, projectId, }; @@ -2158,6 +2226,83 @@ const MAX_RESULT_CHARS = 20_000; /** Maximum characters for a single node's output preview when truncating. */ const MAX_NODE_OUTPUT_CHARS = 1_000; +/** + * Minimal DataTable shape the resolver needs. Kept narrow so tests can mock + * the repository without depending on the full TypeORM entity. + */ +interface DataTableRecord { + id: string; + name: string; + projectId: string; +} + +interface DataTableIdOrNameRepository { + findOneBy: (where: { id: string }) => Promise; + findBy: (where: { name: string; projectId?: string }) => Promise; +} + +interface DataTableResolverLogger { + warn: (message: string, meta?: Record) => void; +} + +export type ResolveDataTableResult = + | { kind: 'hit'; table: DataTableRecord } + | { kind: 'miss' } + | { kind: 'ambiguous'; candidates: DataTableRecord[] }; + +/** + * Look up a data table by the orchestrator-supplied identifier. Tries `id` + * first; if that misses, tries `name`. The name fallback exists because the + * orchestrator occasionally passes the human-readable table name it saw in a + * `data-tables list` response instead of the numeric id. + * + * When the caller provides an `accessFilter`, candidates the user cannot + * access are filtered out BEFORE the ambiguity check — so a collision across + * projects the caller can't see still resolves cleanly to the one they can. + * `projectIdFilter` narrows the name lookup at the database level when the + * caller already knows the target project (table names are unique per + * project). + */ +export async function resolveDataTableByIdOrName( + repository: DataTableIdOrNameRepository, + logger: DataTableResolverLogger, + idOrName: string, + options?: { + projectIdFilter?: string; + accessFilter?: (id: string) => Promise; + }, +): Promise { + const byId = await repository.findOneBy({ id: idOrName }); + if (byId) { + if (options?.accessFilter && !(await options.accessFilter(byId.id))) { + return { kind: 'miss' }; + } + return { kind: 'hit', table: byId }; + } + + const candidates = await repository.findBy({ + name: idOrName, + ...(options?.projectIdFilter ? { projectId: options.projectIdFilter } : {}), + }); + let filtered = candidates; + if (options?.accessFilter) { + filtered = []; + for (const c of candidates) { + if (await options.accessFilter(c.id)) filtered.push(c); + } + } + if (filtered.length === 0) return { kind: 'miss' }; + if (filtered.length > 1) return { kind: 'ambiguous', candidates: filtered }; + + const hit = filtered[0]; + logger.warn('data-tables tool called with table name instead of id — resolved by name fallback', { + passedValue: idOrName, + resolvedId: hit.id, + projectId: hit.projectId, + }); + return { kind: 'hit', table: hit }; +} + /** * Find the `builderHint.message` of the property that references a given * method name via `@searchListMethod` (RLC list modes) or `@loadOptionsMethod`. @@ -2463,8 +2608,39 @@ function getExecutionModeForTrigger(node: INode): WorkflowExecuteMode { } } +/** + * Validate that `inputData` matches the shape the caller of `verify-built-workflow` + * is expected to pass for this trigger. Throws a descriptive error when the shape + * is wrong — this is surfaced to the orchestrator via the execution result and + * prevents the common "null downstream values" misdiagnosis where the orchestrator + * would otherwise patch the workflow's expressions (breaking it in production). + */ +function validateInputDataShape(node: INode, inputData: Record): void { + if (node.type === FORM_TRIGGER_NODE_TYPE) { + // Production Form Trigger emits field values FLAT on `json` alongside + // `submittedAt` and `formMode`. Callers that place fields under `formFields` + // (whether pure-wrap `{formFields: {...}}` or mixed-key `{formFields: {...}, + // other: ...}`) produce pin data where `$json.` resolves to null and + // downstream expressions look broken. Any top-level `formFields` object is + // treated as a mistake — real Form Trigger fields are scalars and would not + // surface as a nested object here. + const formFieldsValue = inputData.formFields; + const looksWrapped = typeof formFieldsValue === 'object' && formFieldsValue !== null; + if (looksWrapped) { + throw new Error( + 'verify-built-workflow: inputData for a Form Trigger must be a flat field map ' + + '(e.g. {name: "Alice", email: "a@b.c"}), NOT wrapped in `formFields`. ' + + 'The production Form Trigger emits fields directly on $json, so downstream ' + + 'expressions like $json.name are correct. Re-run with the flat shape.', + ); + } + } +} + /** Construct proper pin data per trigger type. */ function getPinDataForTrigger(node: INode, inputData: Record): IPinData { + validateInputDataShape(node, inputData); + switch (node.type) { case CHAT_TRIGGER_NODE_TYPE: return { @@ -2495,18 +2671,39 @@ function getPinDataForTrigger(node: INode, inputData: Record): ], }; - case WEBHOOK_NODE_TYPE: + case WEBHOOK_NODE_TYPE: { + // Allow callers that already wrap the payload as an envelope + // (`{body, headers?, query?}`) — unwrap once so the adapter's outer + // `body: inputData` wrapper doesn't create double nesting. But only + // treat `inputData` as an envelope when ALL top-level keys look like + // envelope fields; otherwise a flat payload that happens to contain a + // `body` field (e.g. `{event: 'signup', body: {...}}`) would have its + // sibling fields silently dropped, producing the same "null downstream + // values" failure the Form Trigger validator exists to prevent. + const envelopeKeys = new Set(['body', 'headers', 'query']); + const inputKeys = Object.keys(inputData); + const looksLikeEnvelope = + inputKeys.length > 0 && + inputKeys.every((k) => envelopeKeys.has(k)) && + typeof inputData.body === 'object' && + inputData.body !== null; + const body = looksLikeEnvelope ? (inputData.body as Record) : inputData; + const headers = + looksLikeEnvelope && typeof inputData.headers === 'object' && inputData.headers !== null + ? (inputData.headers as Record) + : {}; + const query = + looksLikeEnvelope && typeof inputData.query === 'object' && inputData.query !== null + ? (inputData.query as Record) + : {}; return { [node.name]: [ { - json: { - headers: {}, - query: {}, - body: inputData, - }, + json: { headers, query, body }, }, ], }; + } case SCHEDULE_TRIGGER_NODE_TYPE: { const now = new Date(); diff --git a/packages/cli/src/modules/instance-ai/instance-ai.service.ts b/packages/cli/src/modules/instance-ai/instance-ai.service.ts index 328e94d7b47..b4493523394 100644 --- a/packages/cli/src/modules/instance-ai/instance-ai.service.ts +++ b/packages/cli/src/modules/instance-ai/instance-ai.service.ts @@ -39,6 +39,7 @@ import { PlannedTaskCoordinator, PlannedTaskStorage, applyPlannedTaskPermissions, + PLANNED_TASK_PERMISSION_OVERRIDES, releaseTraceClient, submitLangsmithUserFeedback, resumeAgentRun, @@ -62,6 +63,7 @@ import { type PlannedTaskRecord, type SandboxConfig, type SpawnBackgroundTaskOptions, + type SpawnBackgroundTaskResult, type ServiceProxyConfig, type StreamableAgent, type SuspendedRunState, @@ -187,6 +189,14 @@ export class InstanceAiService { /** Per-thread promise chain that serializes schedulePlannedTasks calls. */ private readonly schedulerLocks = new Map>(); + /** + * Checkpoint re-entries that could not fire when their parent-tagged child + * settled (an orchestrator run was live, or other parent siblings were + * still running). Drained from the post-run cleanup path so the checkpoint + * is never left orphaned. + */ + private readonly pendingCheckpointReentries = new Map>(); + /** Periodic sweep that auto-rejects timed-out HITL confirmations. */ private confirmationTimeoutInterval?: NodeJS.Timeout; @@ -865,6 +875,13 @@ export class InstanceAiService { researchMode, }); + // Persist the user's time zone so checkpoint / replan / synthesize + // follow-up runs can reinject it into the planner and system prompt + // instead of falling back to GENERIC_TIMEZONE. + if (timeZone) { + this.runState.setTimeZone(threadId, timeZone); + } + if (pushRef !== undefined) { this.threadPushRef.set(threadId, pushRef); } @@ -936,6 +953,16 @@ export class InstanceAiService { } } + // Clean up any awaiting_approval plan graph for this thread. The user + // cancelled before approving, so leaving the graph persisted would (a) + // cause doSchedulePlannedTasks() to republish the stale checklist on + // every later pass via syncPlannedTasksToUi(), and (b) incorrectly let a + // future unrelated create-tasks call bypass the replan-only guard via + // threadHasExistingPlan(). Only target awaiting_approval — active and + // awaiting_replan graphs have their own settlement logic via the + // background-task cancellations above. + void this.cancelAwaitingApprovalPlan(threadId); + const { active, suspended } = this.runState.cancelThread(threadId); if (active) { active.abortController.abort(); @@ -1237,9 +1264,9 @@ export class InstanceAiService { } private buildPlannedTaskFollowUpMessage( - type: 'synthesize' | 'replan', + type: 'synthesize' | 'replan' | 'checkpoint', graph: PlannedTaskGraph, - failedTask?: PlannedTaskRecord, + options: { failedTask?: PlannedTaskRecord; checkpoint?: PlannedTaskRecord } = {}, ): string { const payload: Record = { tasks: graph.tasks.map((task) => ({ @@ -1253,13 +1280,32 @@ export class InstanceAiService { })), }; - if (failedTask) { + if (options.failedTask) { payload.failedTask = { - id: failedTask.id, - title: failedTask.title, - kind: failedTask.kind, - error: failedTask.error, - result: failedTask.result, + id: options.failedTask.id, + title: options.failedTask.title, + kind: options.failedTask.kind, + error: options.failedTask.error, + result: options.failedTask.result, + }; + } + + if (options.checkpoint) { + const depOutcomes = graph.tasks + .filter((t) => options.checkpoint!.deps.includes(t.id)) + .map((t) => ({ + id: t.id, + title: t.title, + kind: t.kind, + status: t.status, + result: t.result, + outcome: t.outcome, + })); + payload.checkpoint = { + id: options.checkpoint.id, + title: options.checkpoint.title, + instructions: options.checkpoint.spec, + dependsOn: depOutcomes, }; } @@ -1286,6 +1332,34 @@ export class InstanceAiService { }); } + /** + * Drop any persisted planned-task graph that is still `awaiting_approval`, + * and clear the UI checklist. Called on run cancellation and HITL timeout so + * stale approval state doesn't linger. A graph in `active` / `awaiting_replan` + * is already in-flight and has its own settlement logic. + */ + private async cancelAwaitingApprovalPlan(threadId: string): Promise { + try { + const { plannedTaskService, taskStorage } = await this.createPlannedTaskState(); + const graph = await plannedTaskService.getGraph(threadId); + if (!graph || graph.status !== 'awaiting_approval') return; + + await plannedTaskService.clear(threadId); + await taskStorage.save(threadId, { tasks: [] }); + this.eventBus.publish(threadId, { + type: 'tasks-update', + runId: graph.planRunId, + agentId: ORCHESTRATOR_AGENT_ID, + payload: { tasks: { tasks: [] }, planItems: [] }, + }); + } catch (error) { + this.logger.warn('Failed to clean up awaiting_approval plan on cancel', { + threadId, + error: error instanceof Error ? error.message : String(error), + }); + } + } + private async createExecutionEnvironment( user: User, threadId: string, @@ -1541,6 +1615,43 @@ export class InstanceAiService { }; } + /** + * Resolve the workflow IDs the checkpoint task is verifying so the runWorkflow + * permission override can be scoped. Walks the checkpoint's `dependsOn` to find + * the build-workflow tasks it depends on and reads their `outcome.workflowId`. + * Returns an empty set when the graph is missing or the checkpoint has no + * resolved workflow deps (in which case the override applies broadly via the + * `allowList === undefined` short-circuit only if we don't set the field). + */ + private async getCheckpointAllowedWorkflowIds( + threadId: string, + checkpointTaskId: string, + ): Promise> { + try { + const { plannedTaskService } = await this.createPlannedTaskState(); + const graph = await plannedTaskService.getGraph(threadId); + const checkpoint = graph?.tasks.find((t) => t.id === checkpointTaskId); + if (!graph || !checkpoint) return new Set(); + const deps = new Set(checkpoint.deps); + const allowed = new Set(); + for (const task of graph.tasks) { + if (!deps.has(task.id)) continue; + const workflowId = task.outcome?.workflowId; + if (typeof workflowId === 'string' && workflowId.length > 0) { + allowed.add(workflowId); + } + } + return allowed; + } catch (error) { + this.logger.warn('Failed to resolve checkpoint allowed workflow IDs', { + threadId, + checkpointTaskId, + error: error instanceof Error ? error.message : String(error), + }); + return new Set(); + } + } + private async handlePlannedTaskSettlement( user: User, task: ManagedBackgroundTask, @@ -1580,6 +1691,7 @@ export class InstanceAiService { researchMode: boolean | undefined, messageGroupId?: string, isReplanFollowUp: boolean = false, + checkpoint?: { isCheckpointFollowUp: true; checkpointTaskId: string }, ): Promise { if (this.runState.hasLiveRun(threadId)) { this.logger.warn('Skipping internal follow-up: active run exists', { threadId }); @@ -1593,6 +1705,12 @@ export class InstanceAiService { messageGroupId, }); + // Resolve user time zone from the thread's run-state snapshot (captured on the + // initial user-facing run) before falling back to the instance default. Follow-up + // runs (checkpoint / replan / synthesize) used to drop this context, which made + // the planner emit "instance default timezone" for user-local schedules. + const timeZone = this.runState.getTimeZone(threadId) ?? this.defaultTimeZone; + void this.executeRun( user, threadId, @@ -1602,8 +1720,9 @@ export class InstanceAiService { researchMode, undefined, messageGroupId, - undefined, + timeZone, isReplanFollowUp, + checkpoint, ); return runId; @@ -1634,26 +1753,92 @@ export class InstanceAiService { if (action.type === 'replan') { await this.syncPlannedTasksToUi(threadId, action.graph); - await this.startInternalFollowUpRun( + const startedRunId = await this.startInternalFollowUpRun( user, threadId, - this.buildPlannedTaskFollowUpMessage('replan', action.graph, action.failedTask), + this.buildPlannedTaskFollowUpMessage('replan', action.graph, { + failedTask: action.failedTask, + }), this.runState.getThreadResearchMode(threadId), action.graph.messageGroupId, true, ); + // tick() already transitioned the graph to `awaiting_replan`. If the + // follow-up run couldn't start (live run present), revert the status + // so the next schedulePlannedTasks() pass can re-emit this action. + // Without this, tick() returns `none` for non-active graphs and the + // replan is silently lost. + if (!startedRunId) { + await plannedTaskService.revertToActive(threadId); + } return; } if (action.type === 'synthesize') { await this.syncPlannedTasksToUi(threadId, action.graph); - await this.startInternalFollowUpRun( + const startedRunId = await this.startInternalFollowUpRun( user, threadId, this.buildPlannedTaskFollowUpMessage('synthesize', action.graph), this.runState.getThreadResearchMode(threadId), action.graph.messageGroupId, ); + // Same rollback as replan: tick() transitioned to `completed`, but if + // the synthesize follow-up didn't actually start, revert so the next + // tick can emit it again. + if (!startedRunId) { + await plannedTaskService.revertToActive(threadId); + } + return; + } + + if (action.type === 'orchestrate-checkpoint') { + // Defer if a run is already active or suspended. The currently-live + // run's post-finally reschedule hook will pick this checkpoint up. + if (this.runState.hasLiveRun(threadId)) { + return; + } + + const checkpoint = action.tasks[0]; + + // Mark running before starting the follow-up so complete-checkpoint + // (which requires status === 'running') always sees the correct state. + // If startInternalFollowUpRun no-ops below (tight race), we roll back + // the transition to avoid leaving the task in a phantom 'running' state. + await plannedTaskService.markRunning(threadId, checkpoint.id, { + agentId: ORCHESTRATOR_AGENT_ID, + }); + const graphAfterMark = (await plannedTaskService.getGraph(threadId)) ?? action.graph; + await this.syncPlannedTasksToUi(threadId, graphAfterMark); + + const checkpointRecord = + graphAfterMark.tasks.find((t) => t.id === checkpoint.id) ?? checkpoint; + + const startedRunId = await this.startInternalFollowUpRun( + user, + threadId, + this.buildPlannedTaskFollowUpMessage('checkpoint', graphAfterMark, { + checkpoint: checkpointRecord, + }), + this.runState.getThreadResearchMode(threadId), + action.graph.messageGroupId, + false, + { isCheckpointFollowUp: true, checkpointTaskId: checkpoint.id }, + ); + + if (!startedRunId) { + // Rare race: the outer hasLiveRun check passed but the inner guard + // in startInternalFollowUpRun did not (another path started a run + // between our two checks). Revert the checkpoint back to `planned` + // so the next scheduler tick re-emits `orchestrate-checkpoint` — + // marking it `failed` here would cascade cancel to every dependent + // and destroy downstream work even though nothing actually failed. + this.logger.warn( + 'Checkpoint follow-up run did not start — reverting checkpoint to planned for retry', + { threadId, checkpointTaskId: checkpoint.id }, + ); + await plannedTaskService.revertCheckpointToPlanned(threadId, checkpoint.id); + } return; } @@ -1685,6 +1870,7 @@ export class InstanceAiService { messageGroupId?: string, timeZone?: string, isReplanFollowUp: boolean = false, + checkpoint?: { isCheckpointFollowUp: true; checkpointTaskId: string }, ): Promise { const signal = abortController.signal; let mastraRunId = ''; @@ -1735,6 +1921,24 @@ export class InstanceAiService { orchestrationContext.isReplanFollowUp = isReplanFollowUp; orchestrationContext.timeZone = timeZone ?? this.defaultTimeZone; + if (checkpoint?.isCheckpointFollowUp) { + orchestrationContext.isCheckpointFollowUp = true; + orchestrationContext.checkpointTaskId = checkpoint.checkpointTaskId; + // Plan approval authorizes verification; grant runWorkflow on the adapter context + // because createInstanceAgent builds domain tools from `context`, not `orchestrationContext.domainContext`. + context.permissions = { + ...context.permissions, + ...(PLANNED_TASK_PERMISSION_OVERRIDES.checkpoint ?? {}), + } as typeof context.permissions; + // Scope the runWorkflow override to the workflows this checkpoint is verifying: + // the orchestrator can call `executions(action="run")` on a depended-on workflow + // without HITL, but any other workflow id still requires user approval. + context.allowedRunWorkflowIds = await this.getCheckpointAllowedWorkflowIds( + threadId, + checkpoint.checkpointTaskId, + ); + } + // Thread attachments into the domain context so parse-file can access them if (attachments && attachments.length > 0) { context.currentUserAttachments = attachments; @@ -1804,7 +2008,6 @@ export class InstanceAiService { mcpServers, memoryConfig, memory, - workspace: orchestrationContext.workspace, disableDeferredTools: true, timeZone: timeZone ?? this.defaultTimeZone, }); @@ -2018,6 +2221,7 @@ export class InstanceAiService { messageGroupId, createdAt: Date.now(), tracing, + checkpoint, }); } @@ -2142,9 +2346,215 @@ export class InstanceAiService { if (!this.runState.hasSuspendedRun(threadId) && mastraRunId) { void this.cleanupMastraSnapshots(mastraRunId); } + // Post-run planned-task wiring (only when the run is actually ending, + // not when it merely suspended for HITL): + // 1. Checkpoint deadlock fallback — if this run was a checkpoint + // follow-up and the orchestrator exited without calling + // complete-checkpoint, mark the task failed so the scheduler + // can transition to awaiting_replan. + // 2. Unconditional reschedule — drive the next tick. This covers + // the case where a background task settled during an ordinary + // chat run: its schedulePlannedTasks call may have skipped the + // checkpoint branch because hasLiveRun was true. Ticking again + // now (with no live run) picks it up. schedulerLocks serializes + // this call, and tick() is a no-op when no graph exists. + if (!this.runState.hasSuspendedRun(threadId)) { + if (checkpoint?.isCheckpointFollowUp) { + await this.finalizeCheckpointFollowUp(user, threadId, checkpoint.checkpointTaskId); + } else { + await this.schedulePlannedTasks(user, threadId); + } + await this.drainPendingCheckpointReentries(user, threadId); + } } } + /** + * Post-run cleanup for a checkpoint follow-up. Ensures the checkpoint task is + * terminal (marking it failed if the orchestrator abandoned it) and re-ticks + * the scheduler so the next planned action can fire. + */ + private queuePendingCheckpointReentry(threadId: string, checkpointTaskId: string): void { + let set = this.pendingCheckpointReentries.get(threadId); + if (!set) { + set = new Set(); + this.pendingCheckpointReentries.set(threadId, set); + } + set.add(checkpointTaskId); + } + + /** + * Drain any checkpoint re-entries whose parent-tagged children settled while + * an orchestrator run was live (or while other siblings were still running). + * Called from the post-run cleanup path in every run-ending `finally` block, + * so the checkpoint is never left orphaned when the settlement path could + * not fire immediately. + */ + private async drainPendingCheckpointReentries(user: User, threadId: string): Promise { + const set = this.pendingCheckpointReentries.get(threadId); + if (!set || set.size === 0) return; + const snapshot = [...set]; + for (const checkpointTaskId of snapshot) { + // If a new run started while we were draining, stop — the next run's + // cleanup will pick up the remaining markers. + if (this.runState.getActiveRunId(threadId) || this.runState.hasSuspendedRun(threadId)) { + return; + } + // A new parent-tagged child is running — let its settlement drive the + // checkpoint instead of racing another re-entry. + const siblings = this.backgroundTasks.getRunningTasksByParentCheckpoint( + threadId, + checkpointTaskId, + ); + if (siblings.length > 0) continue; + set.delete(checkpointTaskId); + await this.reenterCheckpointById(user, threadId, checkpointTaskId); + } + if (set.size === 0) this.pendingCheckpointReentries.delete(threadId); + } + + /** + * Fire a synthetic `` for the + * given checkpoint task id when the parent-tagged children that drove it + * are no longer running and no new orchestrator run is live. Used by both + * the immediate re-entry path (via `maybeReenterParentCheckpoint`) and the + * deferred drain (via `drainPendingCheckpointReentries`). + */ + private async reenterCheckpointById( + user: User, + threadId: string, + checkpointTaskId: string, + messageGroupId?: string, + ): Promise { + try { + const { plannedTaskService } = await this.createPlannedTaskState(); + const graph = await plannedTaskService.getGraph(threadId); + const checkpoint = graph?.tasks.find((t) => t.id === checkpointTaskId); + if (!graph || !checkpoint || checkpoint.kind !== 'checkpoint') return false; + if (checkpoint.status !== 'running') return false; + + const startedRunId = await this.startInternalFollowUpRun( + user, + threadId, + this.buildPlannedTaskFollowUpMessage('checkpoint', graph, { checkpoint }), + this.runState.getThreadResearchMode(threadId), + messageGroupId, + false, + { isCheckpointFollowUp: true, checkpointTaskId }, + ); + if (!startedRunId) return false; + this.logger.debug('Re-entered checkpoint follow-up', { + threadId, + checkpointTaskId, + messageGroupId, + }); + return true; + } catch (error) { + this.logger.error('Failed to re-enter checkpoint follow-up', { + threadId, + checkpointTaskId, + error: error instanceof Error ? error.message : String(error), + }); + return false; + } + } + + /** + * When a direct background task (builder/research/data-table/delegate) + * settles and was spawned inside a checkpoint follow-up, try to re-enter + * that checkpoint so the orchestrator can call `complete-checkpoint`. + * + * Returns `true` only when a follow-up was actually started. Returns + * `false` in every other case (checkpoint no longer running, siblings + * still in-flight, an orchestrator run is active or suspended, or the + * graph no longer has the checkpoint). The caller is responsible for + * queuing a deferred re-entry in the false case — never falling through + * to a generic `` shell, which would re-open + * the orphan bug. + */ + private async maybeReenterParentCheckpoint( + user: User, + threadId: string, + task: ManagedBackgroundTask, + ): Promise { + const parentCheckpointId = task.parentCheckpointId; + if (!parentCheckpointId) return false; + + // If other parent-tagged children are still running, let the LAST one + // re-drive the checkpoint; emitting multiple re-dispatches would race. + const siblings = this.backgroundTasks + .getRunningTasksByParentCheckpoint(threadId, parentCheckpointId) + .filter((t) => t.taskId !== task.taskId); + if (siblings.length > 0) return false; + + // If a run is live, defer — startInternalFollowUpRun would be rejected + // and we must not fall through to the shell path. + if (this.runState.getActiveRunId(threadId) || this.runState.hasSuspendedRun(threadId)) { + return false; + } + + return await this.reenterCheckpointById( + user, + threadId, + parentCheckpointId, + task.messageGroupId, + ); + } + + private async finalizeCheckpointFollowUp( + user: User, + threadId: string, + checkpointTaskId: string, + ): Promise { + try { + const { plannedTaskService } = await this.createPlannedTaskState(); + const graph = await plannedTaskService.getGraph(threadId); + const task = graph?.tasks.find((t) => t.id === checkpointTaskId); + if (task && task.status === 'running') { + // If the orchestrator spawned a detached sub-agent inside this + // checkpoint's turn (builder, research, data-table, delegate) and + // that child is still running, leave the checkpoint running. The + // child's settlement path re-emits `orchestrate-checkpoint` so the + // orchestrator re-enters the same checkpoint context and can then + // call `complete-checkpoint`. + const inflightChildren = this.backgroundTasks.getRunningTasksByParentCheckpoint( + threadId, + checkpointTaskId, + ); + if (inflightChildren.length > 0) { + this.logger.debug( + 'Checkpoint run ended with in-flight child tasks — deferring finalization', + { + threadId, + checkpointTaskId, + inflightTaskIds: inflightChildren.map((t) => t.taskId), + }, + ); + } else { + this.logger.warn('Checkpoint run ended without reporting completion — marking failed', { + threadId, + checkpointTaskId, + }); + await plannedTaskService.markCheckpointFailed(threadId, checkpointTaskId, { + error: 'Checkpoint run ended without reporting completion', + }); + const nextGraph = await plannedTaskService.getGraph(threadId); + if (nextGraph) { + await this.syncPlannedTasksToUi(threadId, nextGraph); + } + } + } + } catch (error) { + this.logger.error('Checkpoint finalization failed', { + threadId, + checkpointTaskId, + error: error instanceof Error ? error.message : String(error), + }); + } + + await this.schedulePlannedTasks(user, threadId); + } + async resolveConfirmation( requestingUserId: string, requestId: string, @@ -2180,8 +2590,17 @@ export class InstanceAiService { return false; } - const { agent, runId, mastraRunId, threadId, user, toolCallId, abortController, tracing } = - suspended; + const { + agent, + runId, + mastraRunId, + threadId, + user, + toolCallId, + abortController, + tracing, + checkpoint, + } = suspended; if (user.id !== requestingUserId) return false; this.runState.activateSuspendedRun(threadId); @@ -2213,6 +2632,7 @@ export class InstanceAiService { abortController, snapshotStorage: this.dbSnapshotStorage, tracing, + checkpoint, }); return true; } @@ -2230,6 +2650,7 @@ export class InstanceAiService { abortController: AbortController; snapshotStorage: DbSnapshotStorage; tracing?: InstanceAiTraceContext; + checkpoint?: { isCheckpointFollowUp: true; checkpointTaskId: string }; }, ): Promise { let messageTraceFinalization: MessageTraceFinalization | undefined; @@ -2289,6 +2710,7 @@ export class InstanceAiService { messageGroupId: this.traceContextsByRunId.get(opts.runId)?.messageGroupId, createdAt: Date.now(), tracing: opts.tracing, + checkpoint: opts.checkpoint, }); } @@ -2407,6 +2829,22 @@ export class InstanceAiService { if (messageTraceFinalization) { await this.maybeFinalizeRunTraceRoot(opts.runId, messageTraceFinalization); } + // Post-run planned-task wiring — mirror the executeRun finally. + // Resumed ordinary-chat runs also need to drive the scheduler in case + // a background task settled while they were active or suspended and + // the orchestrate-checkpoint branch was skipped because of hasLiveRun. + if (!this.runState.hasSuspendedRun(opts.threadId)) { + if (opts.checkpoint?.isCheckpointFollowUp) { + await this.finalizeCheckpointFollowUp( + opts.user, + opts.threadId, + opts.checkpoint.checkpointTaskId, + ); + } else { + await this.schedulePlannedTasks(opts.user, opts.threadId); + } + await this.drainPendingCheckpointReentries(opts.user, opts.threadId); + } } } @@ -2417,8 +2855,8 @@ export class InstanceAiService { opts: SpawnBackgroundTaskOptions, snapshotStorage: DbSnapshotStorage, messageGroupIdOverride?: string, - ): void { - this.backgroundTasks.spawn({ + ): SpawnBackgroundTaskResult { + const outcome = this.backgroundTasks.spawn({ taskId: opts.taskId, threadId: opts.threadId, runId, @@ -2428,6 +2866,8 @@ export class InstanceAiService { plannedTaskId: opts.plannedTaskId, workItemId: opts.workItemId, traceContext: opts.traceContext, + dedupeKey: opts.dedupeKey, + parentCheckpointId: opts.parentCheckpointId, run: opts.run, onLimitReached: async (errorMessage) => { await this.finalizeDetachedTraceRun(opts.taskId, opts.traceContext, { @@ -2495,35 +2935,113 @@ export class InstanceAiService { // orchestrator run is active, resume the orchestrator so it can // synthesize results for the user. Planned tasks handle this via // schedulePlannedTasks(); this covers direct build-workflow-with-agent calls. - if (!task.plannedTaskId) { - const remaining = this.backgroundTasks.getRunningTasks(opts.threadId); - const hasActiveRun = !!this.runState.getActiveRunId(opts.threadId); - const hasSuspendedRun = this.runState.hasSuspendedRun(opts.threadId); - if (remaining.length === 0 && !hasActiveRun && !hasSuspendedRun) { - const user = this.runState.getThreadUser(opts.threadId); - if (user) { - const payload = JSON.stringify( - { - role: opts.role, - status: task.result ? 'completed' : task.error ? 'failed' : 'finished', - result: task.result ?? undefined, - error: task.error ?? undefined, - }, - null, - 2, - ); - await this.startInternalFollowUpRun( - user, - opts.threadId, - `\n${payload}\n\n\n${AUTO_FOLLOW_UP_MESSAGE}`, - this.runState.getThreadResearchMode(opts.threadId), - task.messageGroupId, - ); - } + if (task.plannedTaskId) return; + + // Parent-tagged children (patch-builder etc. spawned inside a + // checkpoint follow-up) must NEVER emit a generic + // `` shell — the orchestrator would + // land outside the checkpoint context and the checkpoint would + // be orphaned. Try immediate re-entry; if the run state or + // still-running siblings block it, queue a deferred marker that + // the post-run drain hook will pick up. + const parentCheckpointId = task.parentCheckpointId; + if (parentCheckpointId) { + const user = this.runState.getThreadUser(opts.threadId); + if (!user) { + this.queuePendingCheckpointReentry(opts.threadId, parentCheckpointId); + return; + } + const reentered = await this.maybeReenterParentCheckpoint(user, opts.threadId, task); + if (!reentered) { + this.queuePendingCheckpointReentry(opts.threadId, parentCheckpointId); + } + return; + } + + const remaining = this.backgroundTasks.getRunningTasks(opts.threadId); + const hasActiveRun = !!this.runState.getActiveRunId(opts.threadId); + const hasSuspendedRun = this.runState.hasSuspendedRun(opts.threadId); + if (remaining.length === 0 && !hasActiveRun && !hasSuspendedRun) { + const user = this.runState.getThreadUser(opts.threadId); + if (user) { + const payload = JSON.stringify( + { + role: opts.role, + status: task.result ? 'completed' : task.error ? 'failed' : 'finished', + result: task.result ?? undefined, + outcome: task.outcome ?? undefined, + error: task.error ?? undefined, + }, + null, + 2, + ); + await this.startInternalFollowUpRun( + user, + opts.threadId, + `\n${payload}\n\n\n${AUTO_FOLLOW_UP_MESSAGE}`, + this.runState.getThreadResearchMode(opts.threadId), + task.messageGroupId, + ); } } }, }); + + if (outcome.status === 'started') { + return { status: 'started', taskId: outcome.task.taskId, agentId: outcome.task.agentId }; + } + if (outcome.status === 'duplicate') { + this.logger.warn('Background task dispatch deduped — task already in flight', { + threadId: opts.threadId, + requestedTaskId: opts.taskId, + existingTaskId: outcome.existing.taskId, + plannedTaskId: opts.dedupeKey?.plannedTaskId, + workflowId: opts.dedupeKey?.workflowId, + role: opts.role, + }); + // The sub-agent dispatch tools publish `agent-spawned` and allocate a + // detached LangSmith trace root BEFORE calling spawnBackgroundTask, so + // the freshly-generated subAgentId for this deduped attempt already has + // a phantom sub-agent node in the event stream and an unfinished trace + // root. Compensate the same way `onLimitReached` does so the agent tree + // snapshot doesn't keep a ghost child and the trace client is released. + void this.finalizeDetachedTraceRun(opts.taskId, opts.traceContext, { + status: 'cancelled', + outputs: { + taskId: opts.taskId, + agentId: opts.agentId, + role: opts.role, + deduped_to: outcome.existing.taskId, + }, + metadata: { + deduped: true, + existing_task_id: outcome.existing.taskId, + ...(opts.plannedTaskId ? { planned_task_id: opts.plannedTaskId } : {}), + ...(opts.workItemId ? { work_item_id: opts.workItemId } : {}), + }, + }); + this.eventBus.publish(opts.threadId, { + type: 'agent-completed', + runId, + agentId: opts.agentId, + payload: { + role: opts.role, + result: '', + error: `Deduped: task already in flight as ${outcome.existing.taskId}`, + }, + }); + return { + status: 'duplicate', + existing: { + taskId: outcome.existing.taskId, + agentId: outcome.existing.agentId, + role: outcome.existing.role, + plannedTaskId: outcome.existing.plannedTaskId, + workItemId: outcome.existing.workItemId, + }, + }; + } + return { status: 'limit-reached' }; } private async buildMessageWithRunningTasks(threadId: string, message: string): Promise { diff --git a/packages/frontend/@n8n/i18n/src/locales/en.json b/packages/frontend/@n8n/i18n/src/locales/en.json index 986fe3b58d3..b50f2e4926d 100644 --- a/packages/frontend/@n8n/i18n/src/locales/en.json +++ b/packages/frontend/@n8n/i18n/src/locales/en.json @@ -5459,6 +5459,7 @@ "instanceAi.tools.update-tasks": "Updating tasks", "instanceAi.tools.report-verification-verdict": "Verifying workflow", "instanceAi.tools.verify-built-workflow": "Verifying workflow", + "instanceAi.tools.complete-checkpoint": "Completing checkpoint", "instanceAi.tools.updateWorkingMemory": "Updating memory", "instanceAi.tools.apply-workflow-credentials": "Applying credentials", "instanceAi.tools.setup-workflow": "Setting up workflow", diff --git a/packages/frontend/editor-ui/src/features/ai/instanceAi/__tests__/toolLabels.test.ts b/packages/frontend/editor-ui/src/features/ai/instanceAi/__tests__/toolLabels.test.ts index a7fec841f08..9176bfd1c06 100644 --- a/packages/frontend/editor-ui/src/features/ai/instanceAi/__tests__/toolLabels.test.ts +++ b/packages/frontend/editor-ui/src/features/ai/instanceAi/__tests__/toolLabels.test.ts @@ -29,6 +29,10 @@ function makeToolCall(overrides: Partial = {}): Instanc } describe('getToolIcon', () => { + test('returns circle-check for complete-checkpoint', () => { + expect(getToolIcon('complete-checkpoint')).toBe('circle-check'); + }); + test('returns share for delegate', () => { expect(getToolIcon('delegate')).toBe('share'); }); diff --git a/packages/frontend/editor-ui/src/features/ai/instanceAi/toolLabels.ts b/packages/frontend/editor-ui/src/features/ai/instanceAi/toolLabels.ts index 6795dca6249..b02dff78ce5 100644 --- a/packages/frontend/editor-ui/src/features/ai/instanceAi/toolLabels.ts +++ b/packages/frontend/editor-ui/src/features/ai/instanceAi/toolLabels.ts @@ -6,6 +6,7 @@ import type { InstanceAiToolCallState } from '@n8n/api-types'; const NO_TOGGLE_TOOLS = new Set(['updateWorkingMemory', 'plan', 'task-control']); export function getToolIcon(toolName: string): IconName { + if (toolName === 'complete-checkpoint') return 'circle-check'; if (toolName === 'delegate' || toolName.endsWith('-with-agent')) return 'share'; if (toolName === 'data-tables') return 'table'; if ( diff --git a/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777023322118-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777023322118-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index 4fb9bda5c34..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777023322118-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": [ - "1728" - ], - "vary": [ - "Accept-Encoding" - ], - "strict-transport-security": [ - "max-age=31536000; includeSubDomains; preload" - ], - "set-cookie": [ - "_cfuvid=OybM2FjqjIz6T6tN31TIFl2YjwTqHiSz8z6MuDVmKzc-1777023316.203343-1.0.1.1-8VflBFRT1EhfFqZJcS7gnt9TDnA2jdsO2Lrmrye_me4; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": [ - "x-originResponse;dur=1735" - ], - "request-id": [ - "req_011CaNNKxaidbpTTboGh6BcD" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "anthropic-ratelimit-tokens-reset": [ - "2026-04-24T09:35:16Z" - ], - "anthropic-ratelimit-tokens-remaining": [ - "26981000" - ], - "anthropic-ratelimit-tokens-limit": [ - "27000000" - ], - "anthropic-ratelimit-requests-reset": [ - "2026-04-24T09:35:16Z" - ], - "anthropic-ratelimit-requests-remaining": [ - "19998" - ], - "anthropic-ratelimit-requests-limit": [ - "20000" - ], - "anthropic-ratelimit-output-tokens-reset": [ - "2026-04-24T09:35:16Z" - ], - "anthropic-ratelimit-output-tokens-remaining": [ - "4500000" - ], - "anthropic-ratelimit-output-tokens-limit": [ - "4500000" - ], - "anthropic-ratelimit-input-tokens-reset": [ - "2026-04-24T09:35:16Z" - ], - "anthropic-ratelimit-input-tokens-remaining": [ - "22481000" - ], - "anthropic-ratelimit-input-tokens-limit": [ - "22500000" - ], - "X-Robots-Tag": [ - "none" - ], - "Server": [ - "cloudflare" - ], - "Date": [ - "Fri, 24 Apr 2026 09:35:18 GMT" - ], - "Content-Type": [ - "text/event-stream; charset=utf-8" - ], - "Content-Security-Policy": [ - "default-src 'none'; frame-ancestors 'none'" - ], - "Cache-Control": [ - "no-cache" - ], - "CF-RAY": [ - "9f141dee4e1fb8e3-BCN" - ] - }, - "cookies": { - "_cfuvid": "OybM2FjqjIz6T6tN31TIFl2YjwTqHiSz8z6MuDVmKzc-1777023316.203343-1.0.1.1-8VflBFRT1EhfFqZJcS7gnt9TDnA2jdsO2Lrmrye_me4" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01NYL5pYTwbaaguHFC9HcnBZ\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":337,\"cache_creation_input_tokens\":10602,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":10602,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":53,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01BpaX4k3GussxVenU1Bv1b8\",\"name\":\"workflows\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"actio\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n\\\": \\\"l\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ist\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"query\\\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"B3 F\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ull \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Wiza\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rd Apply\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":337,\"cache_creation_input_tokens\":10602,\"cache_read_input_tokens\":0,\"output_tokens\":75} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxTllMNXBZVHdiYWFndUhGQzlIY25CWiIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjMzNywiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxMDYwMiwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjEwNjAyLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6NTMsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0b29sX3VzZSIsImlkIjoidG9vbHVfMDFCcGFYNGszR3Vzc3hWZW5VMUJ2MWI4IiwibmFtZSI6IndvcmtmbG93cyIsImlucHV0Ijp7fSwiY2FsbGVyIjp7InR5cGUiOiJkaXJlY3QifX0gfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IntcImFjdGlvIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im5cIjogXCJsIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpc3RcIiJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIsIFwicXVlcnlcIjogIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlwiQjMgRiJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ1bGwgIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IldpemEifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InJkIEFwcGx5XCJ9In0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RvcApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0b3AiLCJpbmRleCI6MCAgICAgICAgICAgICB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJ0b29sX3VzZSIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6MzM3LCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjEwNjAyLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MCwib3V0cHV0X3Rva2VucyI6NzV9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICAgICAgICAgICAgIH0KCg==", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1777023322118-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777023322119-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777023322119-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index a1d58bac5fe..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777023322119-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": [ - "1332" - ], - "vary": [ - "Accept-Encoding" - ], - "strict-transport-security": [ - "max-age=31536000; includeSubDomains; preload" - ], - "set-cookie": [ - "_cfuvid=dR3cKPVgSCe3Kvs94W2Aeo1rC0dxaNIKRTCn62hwXYA-1777023318.7123675-1.0.1.1-96TCOCTyCc9HsnYOmgcjpBsS7UtnoZVJNEHx62fN9kM; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": [ - "x-originResponse;dur=1337" - ], - "request-id": [ - "req_011CaNNL9JeGVNYKxYz8X8k4" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "anthropic-ratelimit-tokens-reset": [ - "2026-04-24T09:35:18Z" - ], - "anthropic-ratelimit-tokens-remaining": [ - "26981000" - ], - "anthropic-ratelimit-tokens-limit": [ - "27000000" - ], - "anthropic-ratelimit-requests-reset": [ - "2026-04-24T09:35:18Z" - ], - "anthropic-ratelimit-requests-remaining": [ - "19998" - ], - "anthropic-ratelimit-requests-limit": [ - "20000" - ], - "anthropic-ratelimit-output-tokens-reset": [ - "2026-04-24T09:35:18Z" - ], - "anthropic-ratelimit-output-tokens-remaining": [ - "4500000" - ], - "anthropic-ratelimit-output-tokens-limit": [ - "4500000" - ], - "anthropic-ratelimit-input-tokens-reset": [ - "2026-04-24T09:35:18Z" - ], - "anthropic-ratelimit-input-tokens-remaining": [ - "22481000" - ], - "anthropic-ratelimit-input-tokens-limit": [ - "22500000" - ], - "X-Robots-Tag": [ - "none" - ], - "Server": [ - "cloudflare" - ], - "Date": [ - "Fri, 24 Apr 2026 09:35:20 GMT" - ], - "Content-Type": [ - "text/event-stream; charset=utf-8" - ], - "Content-Security-Policy": [ - "default-src 'none'; frame-ancestors 'none'" - ], - "Cache-Control": [ - "no-cache" - ], - "CF-RAY": [ - "9f141dfdf941307e-BCN" - ] - }, - "cookies": { - "_cfuvid": "dR3cKPVgSCe3Kvs94W2Aeo1rC0dxaNIKRTCn62hwXYA-1777023318.7123675-1.0.1.1-96TCOCTyCc9HsnYOmgcjpBsS7UtnoZVJNEHx62fN9kM" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_012FhR4GJPSsujZfDXcyqYQd\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":532,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":10602,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":68,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_0129xdQiT8FNaf9NzbAsBxoH\",\"name\":\"workflows\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"ac\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tion\\\": \\\"s\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"etu\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"p\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"workflo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"wId\\\": \\\"We\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Q1q\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"GrgcTD1\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"oaA8\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":532,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":10602,\"output_tokens\":84} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxMkZoUjRHSlBTc3VqWmZEWGN5cVlRZCIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjUzMiwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTA2MDIsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjo2OCwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRvb2xfdXNlIiwiaWQiOiJ0b29sdV8wMTI5eGRRaVQ4Rk5hZjlOemJBc0J4b0giLCJuYW1lIjoid29ya2Zsb3dzIiwiaW5wdXQiOnt9LCJjYWxsZXIiOnsidHlwZSI6ImRpcmVjdCJ9fSAgICAgICAgIH0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoie1wiYWMifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InRpb25cIjogXCJzIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZXR1In0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InBcIiJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIsIFwid29ya2ZsbyJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoid0lkXCI6IFwiV2UifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlExcSJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiR3JnY1REMSJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvYUE4XCJ9In0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjAgICB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJ0b29sX3VzZSIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6NTMyLCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjoxMDYwMiwib3V0cHV0X3Rva2VucyI6ODR9ICAgICAgICAgICB9CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgICAgICAgICAgICAgIH0KCg==", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1777023322119-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777373979523-unknown-host-POST-_v1_messages-e7a67275.json b/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777373979523-unknown-host-POST-_v1_messages-e7a67275.json new file mode 100644 index 00000000000..3ece83454b3 --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777373979523-unknown-host-POST-_v1_messages-e7a67275.json @@ -0,0 +1,111 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You are an expert n8n workflow builder\\. You generate com[\\s\\S]*\"type\"\\s*:\\s*\"tool_use\"[\\s\\S]{0,300}\"name\"\\s*:\\s*\"build-workflow\"[\\s\\S]*" + } + }, + "httpResponse": { + "statusCode": 200, + "reasonPhrase": "OK", + "headers": { + "x-envoy-upstream-service-time": [ + "1027" + ], + "vary": [ + "Accept-Encoding" + ], + "strict-transport-security": [ + "max-age=31536000; includeSubDomains; preload" + ], + "set-cookie": [ + "_cfuvid=dR33gMXkzAc6j93mq2ZP3OP4FErgVaPt3SdJgr02y6Q-1777373966.9623053-1.0.1.1-53qNyPi9.nhalsyxtD_3E9Hd2o3Oa.lByByK6yec8yk; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" + ], + "server-timing": [ + "x-originResponse;dur=1031" + ], + "request-id": [ + "req_011CaW3ywEz1up5JV3ACYHNi" + ], + "cf-cache-status": [ + "DYNAMIC" + ], + "anthropic-ratelimit-tokens-reset": [ + "2026-04-28T10:59:27Z" + ], + "anthropic-ratelimit-tokens-remaining": [ + "26966000" + ], + "anthropic-ratelimit-tokens-limit": [ + "27000000" + ], + "anthropic-ratelimit-requests-reset": [ + "2026-04-28T10:59:27Z" + ], + "anthropic-ratelimit-requests-remaining": [ + "19998" + ], + "anthropic-ratelimit-requests-limit": [ + "20000" + ], + "anthropic-ratelimit-output-tokens-reset": [ + "2026-04-28T10:59:27Z" + ], + "anthropic-ratelimit-output-tokens-remaining": [ + "4500000" + ], + "anthropic-ratelimit-output-tokens-limit": [ + "4500000" + ], + "anthropic-ratelimit-input-tokens-reset": [ + "2026-04-28T10:59:27Z" + ], + "anthropic-ratelimit-input-tokens-remaining": [ + "22466000" + ], + "anthropic-ratelimit-input-tokens-limit": [ + "22500000" + ], + "X-Robots-Tag": [ + "none" + ], + "Server": [ + "cloudflare" + ], + "Date": [ + "Tue, 28 Apr 2026 10:59:28 GMT" + ], + "Content-Type": [ + "text/event-stream; charset=utf-8" + ], + "Content-Security-Policy": [ + "default-src 'none'; frame-ancestors 'none'" + ], + "Cache-Control": [ + "no-cache" + ], + "CF-RAY": [ + "9f358ebd8c03b58b-PRG" + ] + }, + "cookies": { + "_cfuvid": "dR33gMXkzAc6j93mq2ZP3OP4FErgVaPt3SdJgr02y6Q-1777373966.9623053-1.0.1.1-53qNyPi9.nhalsyxtD_3E9Hd2o3Oa.lByByK6yec8yk" + }, + "body": { + "type": "STRING", + "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01TMAHdn4NsZzBxnR9hqa9JW\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":695,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":21523,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":3,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Workflow is\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" ready. Click the Manual Trigger and hit \\\"Test workflow\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"\\\" to run it — then customize the Set node to add whatever fields you need.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":695,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":21523,\"output_tokens\":35} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", + "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxVE1BSGRuNE5zWnpCeG5SOWhxYTlKVyIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjY5NSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MjE1MjMsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjozLCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0gICB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRleHQiLCJ0ZXh0IjoiIn0gICAgICAgfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiJXb3JrZmxvdyBpcyJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIgcmVhZHkuIENsaWNrIHRoZSBNYW51YWwgVHJpZ2dlciBhbmQgaGl0IFwiVGVzdCB3b3JrZmxvdyJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiJcIiB0byBydW4gaXQg4oCUIHRoZW4gY3VzdG9taXplIHRoZSBTZXQgbm9kZSB0byBhZGQgd2hhdGV2ZXIgZmllbGRzIHlvdSBuZWVkLiJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjAgICAgICAgICAgICAgICB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJlbmRfdHVybiIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6Njk1LCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjoyMTUyMywib3V0cHV0X3Rva2VucyI6MzV9ICAgfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICAgICAgICAgfQoK", + "contentType": "text/event-stream; charset=utf-8" + } + }, + "id": "1777373979523-unknown-host-POST-_v1_messages-e7a67275.json", + "priority": 0, + "timeToLive": { + "unlimited": true + }, + "times": { + "unlimited": true + } +} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777373979524-unknown-host-POST-_v1_messages-abc49c4f.json b/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777373979524-unknown-host-POST-_v1_messages-abc49c4f.json new file mode 100644 index 00000000000..4fbd7e85a74 --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777373979524-unknown-host-POST-_v1_messages-abc49c4f.json @@ -0,0 +1,111 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde[\\s\\S]*Set up the workflow named \\\\\"B3 Full Wizard Apply\\\\\"\\.[\\s\\S]*" + } + }, + "httpResponse": { + "statusCode": 200, + "reasonPhrase": "OK", + "headers": { + "x-envoy-upstream-service-time": [ + "1129" + ], + "vary": [ + "Accept-Encoding" + ], + "strict-transport-security": [ + "max-age=31536000; includeSubDomains; preload" + ], + "set-cookie": [ + "_cfuvid=pnbMU0JKL6VIeGtoQmnMJjyYTJBjJYTB19126AmlRvI-1777373973.2591949-1.0.1.1-JHRmYS_Sh_ZJas5yscrNAHLciVGqvmac3_N.GZu4DgI; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" + ], + "server-timing": [ + "x-originResponse;dur=1131" + ], + "request-id": [ + "req_011CaW3zQAEertU27yw7WpZR" + ], + "cf-cache-status": [ + "DYNAMIC" + ], + "anthropic-ratelimit-tokens-reset": [ + "2026-04-28T10:59:33Z" + ], + "anthropic-ratelimit-tokens-remaining": [ + "26975000" + ], + "anthropic-ratelimit-tokens-limit": [ + "27000000" + ], + "anthropic-ratelimit-requests-reset": [ + "2026-04-28T10:59:33Z" + ], + "anthropic-ratelimit-requests-remaining": [ + "19998" + ], + "anthropic-ratelimit-requests-limit": [ + "20000" + ], + "anthropic-ratelimit-output-tokens-reset": [ + "2026-04-28T10:59:33Z" + ], + "anthropic-ratelimit-output-tokens-remaining": [ + "4500000" + ], + "anthropic-ratelimit-output-tokens-limit": [ + "4500000" + ], + "anthropic-ratelimit-input-tokens-reset": [ + "2026-04-28T10:59:33Z" + ], + "anthropic-ratelimit-input-tokens-remaining": [ + "22475000" + ], + "anthropic-ratelimit-input-tokens-limit": [ + "22500000" + ], + "X-Robots-Tag": [ + "none" + ], + "Server": [ + "cloudflare" + ], + "Date": [ + "Tue, 28 Apr 2026 10:59:34 GMT" + ], + "Content-Type": [ + "text/event-stream; charset=utf-8" + ], + "Content-Security-Policy": [ + "default-src 'none'; frame-ancestors 'none'" + ], + "Cache-Control": [ + "no-cache" + ], + "CF-RAY": [ + "9f358ee4d86ddf72-PRG" + ] + }, + "cookies": { + "_cfuvid": "pnbMU0JKL6VIeGtoQmnMJjyYTJBjJYTB19126AmlRvI-1777373973.2591949-1.0.1.1-JHRmYS_Sh_ZJas5yscrNAHLciVGqvmac3_N.GZu4DgI" + }, + "body": { + "type": "STRING", + "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01KTnakuKpWLGnRMwaQzgKdV\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":337,\"cache_creation_input_tokens\":14091,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":14091,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Let\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" me look up that workflow first.\"}}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01A94TsW82xTinxnAX4yAVF6\",\"name\":\"workflows\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"act\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"io\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n\\\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"list\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"query\\\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"B3 \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Full Wiza\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rd Apply\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":337,\"cache_creation_input_tokens\":14091,\"cache_read_input_tokens\":0,\"output_tokens\":83} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", + "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxS1RuYWt1S3BXTEduUk13YVF6Z0tkViIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjMzNywiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxNDA5MSwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjE0MDkxLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6MSwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRleHQiLCJ0ZXh0IjoiIn0gICAgICAgfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiJMZXQifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiIG1lIGxvb2sgdXAgdGhhdCB3b3JrZmxvdyBmaXJzdC4ifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjoxLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0b29sX3VzZSIsImlkIjoidG9vbHVfMDFBOTRUc1c4MnhUaW54bkFYNHlBVkY2IiwibmFtZSI6IndvcmtmbG93cyIsImlucHV0Ijp7fSwiY2FsbGVyIjp7InR5cGUiOiJkaXJlY3QifX0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IntcImFjdCJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpbyJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuXCI6ICJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXCJsaXN0XCIifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIsIFwicXVlcnlcIjogIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcIkIzICJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJGdWxsIFdpemEifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InJkIEFwcGx5In0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXCJ9In0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjoxICAgICAgICAgICB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJ0b29sX3VzZSIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6MzM3LCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjE0MDkxLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MCwib3V0cHV0X3Rva2VucyI6ODN9ICAgIH0KCmV2ZW50OiBtZXNzYWdlX3N0b3AKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdG9wIiAgICAgIH0KCg==", + "contentType": "text/event-stream; charset=utf-8" + } + }, + "id": "1777373979524-unknown-host-POST-_v1_messages-abc49c4f.json", + "priority": 0, + "timeToLive": { + "unlimited": true + }, + "times": { + "unlimited": true + } +} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777373979525-unknown-host-POST-_v1_messages-c17e02f9.json b/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777373979525-unknown-host-POST-_v1_messages-c17e02f9.json new file mode 100644 index 00000000000..c2db059c0d7 --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/1777373979525-unknown-host-POST-_v1_messages-c17e02f9.json @@ -0,0 +1,105 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde[\\s\\S]*\"type\"\\s*:\\s*\"tool_use\"[\\s\\S]{0,300}\"name\"\\s*:\\s*\"workflows\"[\\s\\S]{0,500}\"action\"\\s*:\\s*\"list\"[\\s\\S]*" + } + }, + "httpResponse": { + "statusCode": 200, + "reasonPhrase": "OK", + "headers": { + "x-envoy-upstream-service-time": [ + "1417" + ], + "strict-transport-security": [ + "max-age=31536000; includeSubDomains; preload" + ], + "set-cookie": [ + "_cfuvid=7zOcfTVfjLjlOdvU7FDFjOiBGngj.K.vU1IjWO.Cf3U-1777373975.836431-1.0.1.1-VJw6NTGZjJMQCc02tAtKZbsaW0ISTztfRQAjr6vOBEg; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" + ], + "request-id": [ + "req_011CaW3zbFjE4WwUkSNComLY" + ], + "cf-cache-status": [ + "DYNAMIC" + ], + "anthropic-ratelimit-tokens-reset": [ + "2026-04-28T10:59:35Z" + ], + "anthropic-ratelimit-tokens-remaining": [ + "26975000" + ], + "anthropic-ratelimit-tokens-limit": [ + "27000000" + ], + "anthropic-ratelimit-requests-reset": [ + "2026-04-28T10:59:35Z" + ], + "anthropic-ratelimit-requests-remaining": [ + "19998" + ], + "anthropic-ratelimit-requests-limit": [ + "20000" + ], + "anthropic-ratelimit-output-tokens-reset": [ + "2026-04-28T10:59:35Z" + ], + "anthropic-ratelimit-output-tokens-remaining": [ + "4500000" + ], + "anthropic-ratelimit-output-tokens-limit": [ + "4500000" + ], + "anthropic-ratelimit-input-tokens-reset": [ + "2026-04-28T10:59:36Z" + ], + "anthropic-ratelimit-input-tokens-remaining": [ + "22475000" + ], + "anthropic-ratelimit-input-tokens-limit": [ + "22500000" + ], + "X-Robots-Tag": [ + "none" + ], + "Server": [ + "cloudflare" + ], + "Date": [ + "Tue, 28 Apr 2026 10:59:37 GMT" + ], + "Content-Type": [ + "text/event-stream; charset=utf-8" + ], + "Content-Security-Policy": [ + "default-src 'none'; frame-ancestors 'none'" + ], + "Cache-Control": [ + "no-cache" + ], + "CF-RAY": [ + "9f358ef4fb3cbb9c-PRG" + ] + }, + "cookies": { + "_cfuvid": "7zOcfTVfjLjlOdvU7FDFjOiBGngj.K.vU1IjWO.Cf3U-1777373975.836431-1.0.1.1-VJw6NTGZjJMQCc02tAtKZbsaW0ISTztfRQAjr6vOBEg" + }, + "body": { + "type": "STRING", + "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_018sM6MviEiG3T1QP1ktkjqj\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":541,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":14091,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":68,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01Qm84eUUf1P3CfD4Yk56bSc\",\"name\":\"workflows\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"act\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ion\\\": \\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"setup\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"work\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"flow\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Id\\\": \\\"cKA\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"KMg8cquA\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"9y35\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"K\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":541,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":14091,\"output_tokens\":84} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\"}\n\n", + "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxOHNNNk12aUVpRzNUMVFQMWt0a2pxaiIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjU0MSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTQwOTEsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjo2OCwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0b29sX3VzZSIsImlkIjoidG9vbHVfMDFRbTg0ZVVVZjFQM0NmRDRZazU2YlNjIiwibmFtZSI6IndvcmtmbG93cyIsImlucHV0Ijp7fSwiY2FsbGVyIjp7InR5cGUiOiJkaXJlY3QifX0gICAgICAgICAgICAgfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ7XCIifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiYWN0In0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiaW9uXCI6IFwiIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InNldHVwXCIifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiwgXCJ3b3JrIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJmbG93In0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJJZFwiOiBcImNLQSJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJLTWc4Y3F1QSJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiI5eTM1In0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiS1wifSJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICAgICAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoidG9vbF91c2UiLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjU0MSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTQwOTEsIm91dHB1dF90b2tlbnMiOjg0fSAgICAgICB9CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCJ9Cgo=", + "contentType": "text/event-stream; charset=utf-8" + } + }, + "id": "1777373979525-unknown-host-POST-_v1_messages-c17e02f9.json", + "priority": 0, + "timeToLive": { + "unlimited": true + }, + "times": { + "unlimited": true + } +} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/trace.jsonl b/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/trace.jsonl index 8f7f0da1310..6b92bbc17e1 100644 --- a/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/trace.jsonl +++ b/packages/testing/playwright/expectations/instance-ai/should-apply-parameter-and-credential-edits-and-persist-them-to-the-workflow/trace.jsonl @@ -1,4 +1,4 @@ -{"kind":"header","version":1,"testName":"recording","recordedAt":"2026-04-24T09:35:15.766Z"} -{"kind":"tool-call","stepId":1,"agentRole":"orchestrator","toolName":"workflows","input":{"action":"list","query":"B3 Full Wizard Apply"},"output":{"workflows":[{"id":"WeQ1qGrgcTD1oaA8","name":"B3 Full Wizard Apply","versionId":"ddd666a7-e12a-4e98-89c8-98cdb6495738","activeVersionId":null,"createdAt":"2026-04-24T09:35:14.256Z","updatedAt":"2026-04-24T09:35:14.256Z"}]}} -{"kind":"tool-call","stepId":2,"agentRole":"orchestrator","toolName":"workflows","input":{"action":"setup","workflowId":"WeQ1qGrgcTD1oaA8"},"output":{"success":false}} -{"kind":"tool-resume","stepId":3,"agentRole":"orchestrator","toolName":"workflows","input":{"action":"setup","workflowId":"WeQ1qGrgcTD1oaA8"},"output":{"success":true,"completedNodes":[{"nodeName":"HTTP Request","parametersSet":["url"]}],"updatedNodes":[{"id":"trigger","name":"Manual Trigger","type":"n8n-nodes-base.manualTrigger","typeVersion":1,"position":[0,0],"parameters":{}},{"id":"http","name":"HTTP Request","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[220,-120],"parameters":{"method":"GET","url":"https://example.com/api","authentication":"none"}},{"id":"slack","name":"Slack","type":"n8n-nodes-base.slack","typeVersion":2.3,"position":[220,120],"parameters":{"resource":"message","operation":"post","select":"channel","channelId":{"__rl":true,"value":"C0000000000","mode":"id"},"text":"hello from setup e2e"},"credentials":{"slackApi":{"id":"L3ha3TfgeHqrnmgk","name":"B3 Apply Slack Primary"}}}],"updatedConnections":{"Manual Trigger":{"main":[[{"node":"HTTP Request","type":"main","index":0},{"node":"Slack","type":"main","index":0}]]}}},"resumeData":{"approved":true,"credentials":{},"action":"apply","nodeParameters":{"HTTP Request":{"url":"https://example.com/api"}}}} +{"kind":"header","version":1,"testName":"recording","recordedAt":"2026-04-28T10:59:33.145Z"} +{"kind":"tool-call","stepId":1,"agentRole":"orchestrator","toolName":"workflows","input":{"action":"list","query":"B3 Full Wizard Apply"},"output":{"workflows":[{"id":"cKAKMg8cquA9y35K","name":"B3 Full Wizard Apply","versionId":"1e867e5e-50fd-4326-8c0f-6ad69d9616aa","activeVersionId":null,"createdAt":"2026-04-28T10:59:29.306Z","updatedAt":"2026-04-28T10:59:29.306Z"}]}} +{"kind":"tool-call","stepId":2,"agentRole":"orchestrator","toolName":"workflows","input":{"action":"setup","workflowId":"cKAKMg8cquA9y35K"},"output":{"success":false}} +{"kind":"tool-resume","stepId":3,"agentRole":"orchestrator","toolName":"workflows","input":{"action":"setup","workflowId":"cKAKMg8cquA9y35K"},"output":{"success":true,"completedNodes":[{"nodeName":"HTTP Request","parametersSet":["url"]}],"updatedNodes":[{"id":"trigger","name":"Manual Trigger","type":"n8n-nodes-base.manualTrigger","typeVersion":1,"position":[0,0],"parameters":{}},{"id":"http","name":"HTTP Request","type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[220,-120],"parameters":{"method":"GET","url":"https://example.com/api","authentication":"none"}},{"id":"slack","name":"Slack","type":"n8n-nodes-base.slack","typeVersion":2.3,"position":[220,120],"parameters":{"resource":"message","operation":"post","select":"channel","channelId":{"__rl":true,"value":"C0000000000","mode":"id"},"text":"hello from setup e2e"},"credentials":{"slackApi":{"id":"oR4HYz4azgE1NUGj","name":"B3 Apply Slack Primary"}}}],"updatedConnections":{"Manual Trigger":{"main":[[{"node":"HTTP Request","type":"main","index":0},{"node":"Slack","type":"main","index":0}]]}}},"resumeData":{"approved":true,"credentials":{},"action":"apply","nodeParameters":{"HTTP Request":{"url":"https://example.com/api"}}}} diff --git a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992870-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992870-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index f04616b74c0..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992870-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["1804"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=xwcYiDoOlJxY8yWiGl1UMelxQPGR7q4liimU0As__Qw-1775805970.499006-1.0.1.1-vx_Xq7BBPtvUoej0b5XoXUmgUyLJG.OM.Eb7L1E1PzY; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=1808"], - "request-id": ["req_011CZuhAAty5MHT9SpcCJaEJ"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:26:10Z"], - "anthropic-ratelimit-tokens-remaining": ["26976000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:26:10Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:26:10Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:26:10Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22476000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:26:12 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9ea005939b44c637-TXL"] - }, - "cookies": { - "_cfuvid": "xwcYiDoOlJxY8yWiGl1UMelxQPGR7q4liimU0As__Qw-1775805970.499006-1.0.1.1-vx_Xq7BBPtvUoej0b5XoXUmgUyLJG.OM.Eb7L1E1PzY" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01X9F6QxQqXBvSpQJJZUdJQd\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":1060,\"cache_creation_input_tokens\":12360,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":12360,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":41,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01U5wxkkr1z8yt8pDCgtK7ju\",\"name\":\"build-workflow-with-agent\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"task\\\": \\\"B\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"uild a simpl\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e workfl\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ow with \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"a Manual \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Trigger \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"node and a\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Se\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t nod\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e called \\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"prev\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"iew aut\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"o-open test\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\". The Set\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" node d\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"oesn'\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t need any s\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"pe\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"cific fields\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" — \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"just\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" the \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"node named \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"correctly.\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"co\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nversationCo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ntex\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t\\\": \\\"User wa\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nts\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" a simpl\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e t\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"est\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" workflow \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"with a\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Manual \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Trigger\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" and a Set n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ode named\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" \\\\\\\"p\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"review\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" auto-\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"open test\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\".\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":1060,\"cache_creation_input_tokens\":12360,\"cache_read_input_tokens\":0,\"output_tokens\":135} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxWDlGNlF4UXFYQnZTcFFKSlpVZEpRZCIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEwNjAsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MTIzNjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjoxMjM2MCwiZXBoZW1lcmFsXzFoX2lucHV0X3Rva2VucyI6MH0sIm91dHB1dF90b2tlbnMiOjQxLCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRvb2xfdXNlIiwiaWQiOiJ0b29sdV8wMVU1d3hra3Ixejh5dDhwRENndEs3anUiLCJuYW1lIjoiYnVpbGQtd29ya2Zsb3ctd2l0aC1hZ2VudCIsImlucHV0Ijp7fSwiY2FsbGVyIjp7InR5cGUiOiJkaXJlY3QifX0gICAgICAgIH0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoie1widGFza1wiOiBcIkIifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InVpbGQgYSBzaW1wbCJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImUgd29ya2ZsIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvdyB3aXRoICJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhIE1hbnVhbCAifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlRyaWdnZXIgIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJub2RlIGFuZCBhIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBTZSJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0IG5vZCJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlIGNhbGxlZCBcXCJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcInByZXYifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImlldyBhdXQifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvLW9wZW4gdGVzdFxcIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXCIuIFRoZSBTZXQifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBub2RlIGQifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvZXNuJyJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidCBuZWVkIGFueSBzIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoicGUifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJjaWZpYyBmaWVsZHMifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIOKAlCAifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Imp1c3QifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiB0aGUgIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJub2RlIG5hbWVkICJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImNvcnJlY3RseS4ifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcIiJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIsIFwiY28ifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibnZlcnNhdGlvbkNvIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im50ZXgifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0XCI6IFwiVXNlciB3YSJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im50cyJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIGEgc2ltcGwifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlIHQifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZXN0In0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiB3b3JrZmxvdyAifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IndpdGggYSJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBNYW51YWwgIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJUcmlnZ2VyIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgYW5kIGEgU2V0IG4ifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvZGUgbmFtZWQifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBcXFwicCJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InJldmlldyJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgYXV0by0ifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9wZW4gdGVzdCJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcXFwiIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIuXCJ9In0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjAgICB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJ0b29sX3VzZSIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6MTA2MCwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxMjM2MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsIm91dHB1dF90b2tlbnMiOjEzNX0gICAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICAgICAgICAgIH0KCg==", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805992870-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992906-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992906-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index dc39147dc87..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992906-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["2144"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=hYM2Wjb_E2XYeEiakXKYruxDi85_0iAQHotJYYL_rh4-1775805976.061354-1.0.1.1-DJQ9KbS5gpIlwRS7Bnrli3dkRhFeJe0z85aEghEjKIw; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=2145"], - "request-id": ["req_011CZuhAap989dhULJXrTQar"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:26:16Z"], - "anthropic-ratelimit-tokens-remaining": ["26976000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:26:16Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:26:16Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:26:16Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22476000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:26:18 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9ea005b66d9733a5-TXL"] - }, - "cookies": { - "_cfuvid": "hYM2Wjb_E2XYeEiakXKYruxDi85_0iAQHotJYYL_rh4-1775805976.061354-1.0.1.1-DJQ9KbS5gpIlwRS7Bnrli3dkRhFeJe0z85aEghEjKIw" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01Brf49UhYvAGoWQ1imjuWtG\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":1269,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":12360,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Building\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" your \\\"preview auto-open test\\\" workflow now!\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":1269,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":12360,\"output_tokens\":15} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxQnJmNDlVaFl2QUdvV1ExaW1qdVd0RyIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEyNjksImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjEyMzYwLCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjowLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6MSwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRleHQiLCJ0ZXh0IjoiIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiQnVpbGRpbmcifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiIHlvdXIgXCJwcmV2aWV3IGF1dG8tb3BlbiB0ZXN0XCIgd29ya2Zsb3cgbm93ISJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX2RlbHRhCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2VfZGVsdGEiLCJkZWx0YSI6eyJzdG9wX3JlYXNvbiI6ImVuZF90dXJuIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsfSwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjoxMjY5LCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjoxMjM2MCwib3V0cHV0X3Rva2VucyI6MTV9ICAgICAgICAgICAgICB9CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805992906-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992921-unknown-host-POST-_v1_messages-18622610.json b/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992921-unknown-host-POST-_v1_messages-18622610.json deleted file mode 100644 index 54384dcff3c..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992921-unknown-host-POST-_v1_messages-18622610.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "You generate a short descriptive title for a conversation", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["940"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=7.XiVbOXIR2WD60h.PEsXOTs0A5LcIFlDaLTiiq.Z8w-1775805979.34705-1.0.1.1-0ZPG4wCERfoe0f3NdOBzJiGKmhX0P2heXKMnYLvImio; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=946"], - "request-id": ["req_011CZuhAphp8tASuZLU6522t"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:26:20Z"], - "anthropic-ratelimit-tokens-remaining": ["27000000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:26:19Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:26:20Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:26:20Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22500000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:26:20 GMT"], - "Content-Type": ["application/json"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "CF-RAY": ["9ea005cae94f761f-TXL"] - }, - "cookies": { - "_cfuvid": "7.XiVbOXIR2WD60h.PEsXOTs0A5LcIFlDaLTiiq.Z8w-1775805979.34705-1.0.1.1-0ZPG4wCERfoe0f3NdOBzJiGKmhX0P2heXKMnYLvImio" - }, - "body": { - "contentType": "application/json", - "type": "JSON", - "json": { - "model": "claude-sonnet-4-6", - "id": "msg_01WFGshA9oCcsDMq9m6f2RHk", - "type": "message", - "role": "assistant", - "content": [ - { - "type": "text", - "text": "Preview auto-open test workflow" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "stop_details": null, - "usage": { - "input_tokens": 140, - "cache_creation_input_tokens": 0, - "cache_read_input_tokens": 0, - "cache_creation": { - "ephemeral_5m_input_tokens": 0, - "ephemeral_1h_input_tokens": 0 - }, - "output_tokens": 9, - "service_tier": "standard", - "inference_geo": "global" - } - }, - "rawBytes": "eyJtb2RlbCI6ImNsYXVkZS1zb25uZXQtNC02IiwiaWQiOiJtc2dfMDFXRkdzaEE5b0Njc0RNcTltNmYyUkhrIiwidHlwZSI6Im1lc3NhZ2UiLCJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiUHJldmlldyBhdXRvLW9wZW4gdGVzdCB3b3JrZmxvdyJ9XSwic3RvcF9yZWFzb24iOiJlbmRfdHVybiIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbCwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjoxNDAsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjo5LCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0=" - } - }, - "id": "1775805992921-unknown-host-POST-_v1_messages-18622610.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992925-unknown-host-POST-_v1_messages-4d1c93f7.json b/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992925-unknown-host-POST-_v1_messages-4d1c93f7.json deleted file mode 100644 index c2017be2cb6..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992925-unknown-host-POST-_v1_messages-4d1c93f7.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are an expert n8n workflow builder. You generate com", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["2210"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=cHWiQSPcOuehTuMG8J67nrbecE9xNrRwVIm_c_kbqd8-1775805976.4168134-1.0.1.1-JOOAWpzMDZLRPZig2_FkRFoaHo2EtZPrthvFjhxKfZA; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=2213"], - "request-id": ["req_011CZuhAcEDn9sm8bnniDGjm"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:26:16Z"], - "anthropic-ratelimit-tokens-remaining": ["26975000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:26:16Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:26:16Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:26:16Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22475000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:26:18 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9ea005b89f63e506-TXL"] - }, - "cookies": { - "_cfuvid": "cHWiQSPcOuehTuMG8J67nrbecE9xNrRwVIm_c_kbqd8-1775805976.4168134-1.0.1.1-JOOAWpzMDZLRPZig2_FkRFoaHo2EtZPrthvFjhxKfZA" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01TrktmmowcozoyF2rpBC4eM\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":391,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":16176,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":54,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01H8UQxmjS7NPo6jrHGo5ppN\",\"name\":\"build-workflow\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"nam\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e\\\": \\\"previ\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ew \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"auto-o\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"pen t\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"est\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"code\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\": \\\"\\\\nimp\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ort { wo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rk\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"flo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"w, \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"node, trigge\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"r }\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" from\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" '@n8n/work\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"flow-sdk';\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n\\\\ncons\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t m\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"an\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ualT\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rigge\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"r = \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"trigger({\\\\\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n type\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": '\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n8n-nodes\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"-base.m\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"anualTrig\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ger',\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" version: \"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"1,\\\\n con\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"fig: { nam\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e: 'Manu\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"al Trigger' \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"}\\\\n});\\\\n\\\\nc\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"onst prev\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"iewNode =\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" node\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"({\\\\n ty\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"pe: 'n8n-\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nodes-base\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\".set\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"',\\\\n \"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" version:\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" 3.4,\\\\n con\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"fig: \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" name: 'prev\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"iew auto-o\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"pen test',\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" parame\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ters: {\\\\n \"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" assign\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ments\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": {\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" a\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ssignments: \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"[] }\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\",\\\\n op\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tio\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ns: {}\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n }\\\\n }\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n})\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\";\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\nexpor\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t de\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"fault\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" wo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rkflow('p\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"review\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"-auto\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"-open-\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"te\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"st', 'pr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"eview aut\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"o-ope\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n test'\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\")\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\".a\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"dd(manualTri\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"gger)\\\\n .\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"to(p\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"reviewNode)\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\";\\\\n\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":391,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":16176,\"output_tokens\":265} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxVHJrdG1tb3djb3pveUYycnBCQzRlTSIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjM5MSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTYxNzYsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjo1NCwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRvb2xfdXNlIiwiaWQiOiJ0b29sdV8wMUg4VVF4bWpTN05QbzZqckhHbzVwcE4iLCJuYW1lIjoiYnVpbGQtd29ya2Zsb3ciLCJpbnB1dCI6e30sImNhbGxlciI6eyJ0eXBlIjoiZGlyZWN0In19ICAgICAgfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IntcIm5hbSJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlXCI6IFwicHJldmkifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZXcgIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhdXRvLW8ifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJwZW4gdCJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlc3RcIiJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiLCBcImNvZGUifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcIjogXCJcXG5pbXAifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9ydCB7IHdvIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoicmsifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImZsbyJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidywgIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJub2RlLCB0cmlnZ2UifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiciB9In0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBmcm9tIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiAnQG44bi93b3JrIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJmbG93LXNkayc7In0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlxcblxcbmNvbnMifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0IG0ifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImFuIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ1YWxUIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoicmlnZ2UifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJyID0gIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InRyaWdnZXIoe1xcIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibiAgdHlwZSJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IjogJyJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibjhuLW5vZGVzIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiLWJhc2UubSJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhbnVhbFRyaWcifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImdlcicsXFxuIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiAgdmVyc2lvbjogIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiMSxcXG4gIGNvbiJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZmlnOiB7IG5hbSJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImU6ICdNYW51In0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiYWwgVHJpZ2dlcicgIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoifVxcbn0pO1xcblxcbmMifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9uc3QgcHJldiJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpZXdOb2RlID0ifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgbm9kZSJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Iih7XFxuICB0eSJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InBlOiAnbjhuLSJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibm9kZXMtYmFzZSJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Ii5zZXQifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiJyxcXG4gIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIHZlcnNpb246In0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgMy40LFxcbiAgY29uIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZmlnOiAifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ7XFxuICAgIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgbmFtZTogJ3ByZXYifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpZXcgYXV0by1vIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InBlbiB0ZXN0JyxcXG4ifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgICAgcGFyYW1lIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidGVyczoge1xcbiAifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgICAgIGFzc2lnbiJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibWVudHMifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiOiB7In0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIGEifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJzc2lnbm1lbnRzOiAifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IltdIH0ifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIsXFxuICAgICAgb3AifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0aW8ifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibnM6IHt9XFwifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im4gICAgfVxcbiAgfVxcIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im59KSJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiI7XFxuIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcXG5leHBvciJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InQgZGUifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJmYXVsdCJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiB3byJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InJrZmxvdygncCJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJyZXZpZXcifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiLWF1dG8ifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Ii1vcGVuLSJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidGUifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJzdCcsICdwciJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZXZpZXcgYXV0In0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiby1vcGUifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuIHRlc3QnIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IilcXG4gICJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIuYSJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImRkKG1hbnVhbFRyaSJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJnZ2VyKVxcbiAgLiJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InRvKHAifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJyZXZpZXdOb2RlKSJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IjtcXG5cIn0ifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RvcApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0b3AiLCJpbmRleCI6MCAgICAgICB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJ0b29sX3VzZSIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6MzkxLCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjoxNjE3Niwib3V0cHV0X3Rva2VucyI6MjY1fSB9CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgIH0KCg==", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805992925-unknown-host-POST-_v1_messages-4d1c93f7.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992927-unknown-host-POST-_v1_messages-4d1c93f7.json b/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992927-unknown-host-POST-_v1_messages-4d1c93f7.json deleted file mode 100644 index b09a8b03bdc..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992927-unknown-host-POST-_v1_messages-4d1c93f7.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are an expert n8n workflow builder. You generate com", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["1216"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=5wzHd0OoEqvhiaD1IzQ.YvEEyDny.Ftq2KSxzE_VaAo-1775805982.6625264-1.0.1.1-Ra0ySdbHv.EezGVWuEOOEVf7PTDAhBc6tAI9n0FTMwc; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=1219"], - "request-id": ["req_011CZuhB4yJjN1tDBne3Z4Cn"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:26:22Z"], - "anthropic-ratelimit-tokens-remaining": ["26975000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:26:22Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:26:22Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:26:22Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22475000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:26:24 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9ea005dfae3c34b9-TXL"] - }, - "cookies": { - "_cfuvid": "5wzHd0OoEqvhiaD1IzQ.YvEEyDny.Ftq2KSxzE_VaAo-1775805982.6625264-1.0.1.1-Ra0ySdbHv.EezGVWuEOOEVf7PTDAhBc6tAI9n0FTMwc" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01UdEvLW6voE1Jy1KNSBcEiH\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":691,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":16176,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Done\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" — the workflow \\\"preview auto-open test\\\" is ready with a Manual Trigger connected to a Set node named exactly\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" \\\"preview auto-open test\\\".\"}}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":691,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":16176,\"output_tokens\":35} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxVWRFdkxXNnZvRTFKeTFLTlNCY0VpSCIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjY5MSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTYxNzYsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjoxLCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0gICB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRleHQiLCJ0ZXh0IjoiIn0gICAgIH0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiRG9uZSJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIg4oCUIHRoZSB3b3JrZmxvdyBcInByZXZpZXcgYXV0by1vcGVuIHRlc3RcIiBpcyByZWFkeSB3aXRoIGEgTWFudWFsIFRyaWdnZXIgY29ubmVjdGVkIHRvIGEgU2V0IG5vZGUgbmFtZWQgZXhhY3RseSJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IiBcInByZXZpZXcgYXV0by1vcGVuIHRlc3RcIi4ifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjY5MSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTYxNzYsIm91dHB1dF90b2tlbnMiOjM1fSAgfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICAgICAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805992927-unknown-host-POST-_v1_messages-4d1c93f7.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992928-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992928-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index 930e54f6988..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1775805992928-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["3410"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=yWsS2C4dRZNuHPmvx7_gFHBH96x100lgZMrEXHblC7c-1775805986.7840152-1.0.1.1-gn5xKLf_6FuPeOVlisqhzYJdeWigFNJLMzs2ou3SmTw; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=3412"], - "request-id": ["req_011CZuhBNYjBXe9GCUEQxNg3"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:26:27Z"], - "anthropic-ratelimit-tokens-remaining": ["26976000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:26:27Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:26:27Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:26:27Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22476000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:26:30 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9ea005f968a0236c-TXL"] - }, - "cookies": { - "_cfuvid": "yWsS2C4dRZNuHPmvx7_gFHBH96x100lgZMrEXHblC7c-1775805986.7840152-1.0.1.1-gn5xKLf_6FuPeOVlisqhzYJdeWigFNJLMzs2ou3SmTw" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01BBs3FuNkjeYpZhftyTVE32\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":1367,\"cache_creation_input_tokens\":12360,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":12360,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}}}\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"The\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" workflow **\\\"preview auto-open test\\\"** is ready! It has a Manual Trigger connected to a Set node named \\\"preview auto-open test\\\".\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" Let me know if you'd like to run it or make any changes.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":1367,\"cache_creation_input_tokens\":12360,\"cache_read_input_tokens\":0,\"output_tokens\":51}}\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxQkJzM0Z1TmtqZVlwWmhmdHlUVkUzMiIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEzNjcsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MTIzNjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjoxMjM2MCwiZXBoZW1lcmFsXzFoX2lucHV0X3Rva2VucyI6MH0sIm91dHB1dF90b2tlbnMiOjEsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0YXJ0CmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RhcnQiLCJpbmRleCI6MCwiY29udGVudF9ibG9jayI6eyJ0eXBlIjoidGV4dCIsInRleHQiOiIifSAgICAgICAgICB9CgpldmVudDogcGluZwpkYXRhOiB7InR5cGUiOiAicGluZyJ9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IlRoZSJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiIHdvcmtmbG93ICoqXCJwcmV2aWV3IGF1dG8tb3BlbiB0ZXN0XCIqKiBpcyByZWFkeSEgSXQgaGFzIGEgTWFudWFsIFRyaWdnZXIgY29ubmVjdGVkIHRvIGEgU2V0IG5vZGUgbmFtZWQgXCJwcmV2aWV3IGF1dG8tb3BlbiB0ZXN0XCIuIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiIExldCBtZSBrbm93IGlmIHlvdSdkIGxpa2UgdG8gcnVuIGl0IG9yIG1ha2UgYW55IGNoYW5nZXMuIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEzNjcsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MTIzNjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJvdXRwdXRfdG9rZW5zIjo1MX19CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgICAgICAgICAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805992928-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1776069657468-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1776069657468-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index 89ebb1c9b33..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1776069657468-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["2842"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=6OzlT3ueZbTJe4IPIViwKoqnllzA23MA0dz4IapT01A-1776069645.1803155-1.0.1.1-KnQhm2uWNsNOgOGeVMRGnL1plXeT0MQd75S9F2nfk84; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=2847"], - "request-id": ["req_011Ca1UGmSHH3V1tCkiZXvwz"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-13T08:40:45Z"], - "anthropic-ratelimit-tokens-remaining": ["26977000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-13T08:40:45Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-13T08:40:45Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-13T08:40:45Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22477000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Mon, 13 Apr 2026 08:40:48 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9eb92af259eee51a-TXL"] - }, - "cookies": { - "_cfuvid": "6OzlT3ueZbTJe4IPIViwKoqnllzA23MA0dz4IapT01A-1776069645.1803155-1.0.1.1-KnQhm2uWNsNOgOGeVMRGnL1plXeT0MQd75S9F2nfk84" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01WrRsnMeS6C4oZH2ikvZpaT\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":363,\"cache_creation_input_tokens\":12653,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":12653,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":48,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}}}\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01JVJ2SU97i5xarwaEJrrCQ3\",\"name\":\"build-workflow-with-agent\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"task\\\":\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" \\\"Bu\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ild a sim\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ple wor\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"kflow n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"amed \\\\\\\"pre\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"view auto-op\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"en \"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"test\\\\\\\" with\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\":\\\\n1. A Ma\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nual Tr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ig\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ger node\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n2. A Set \"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"node called\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" \\\\\\\"previe\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"w a\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"uto-op\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"en test\\\\\\\"\\\\\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n\\\\nThe Set \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"node \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"can\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" have a s\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"imple exa\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"mple fi\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"eld, \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"li\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ke setti\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ng a field \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\\\\"message\\\\\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" to \\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"He\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"llo World\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\\\\".\\\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"co\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nversation\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Context\\\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"User wan\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ts a sim\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ple test\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" wo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rkf\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"low wit\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"h \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"a ma\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nual trigge\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"r a\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nd a se\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t node.\\\"}\"}}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":363,\"cache_creation_input_tokens\":12653,\"cache_read_input_tokens\":0,\"output_tokens\":148} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxV3JSc25NZVM2QzRvWkgyaWt2WnBhVCIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjM2MywiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxMjY1MywiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjEyNjUzLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6NDgsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0YXJ0CmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RhcnQiLCJpbmRleCI6MCwiY29udGVudF9ibG9jayI6eyJ0eXBlIjoidG9vbF91c2UiLCJpZCI6InRvb2x1XzAxSlZKMlNVOTdpNXhhcndhRUpyckNRMyIsIm5hbWUiOiJidWlsZC13b3JrZmxvdy13aXRoLWFnZW50IiwiaW5wdXQiOnt9LCJjYWxsZXIiOnsidHlwZSI6ImRpcmVjdCJ9fSAgICAgIH0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoie1widGFza1wiOiJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIFwiQnUifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiaWxkIGEgc2ltIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InBsZSB3b3IifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJrZmxvdyBuIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiYW1lZCBcXFwicHJlIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ2aWV3IGF1dG8tb3AifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVuICJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InRlc3RcXFwiIHdpdGgifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiOlxcbjEuIEEgTWEifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJudWFsIFRyIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImlnIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJnZXIgbm9kZSJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlxcbjIuIEEgU2V0ICJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im5vZGUgY2FsbGVkIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgXFxcInByZXZpZSJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ3IGEifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidXRvLW9wIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVuIHRlc3RcXFwiXFwifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuXFxuVGhlIFNldCAifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibm9kZSAifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiY2FuIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBoYXZlIGEgcyJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImltcGxlIGV4YSJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibXBsZSBmaSJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlbGQsICJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImxpIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImtlIHNldHRpIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibmcgYSBmaWVsZCAifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXFxcIm1lc3NhZ2VcXFwiIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIHRvIFxcIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcIkhlIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibGxvIFdvcmxkIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXFxcIi5cIiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiwgXCJjbyJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibnZlcnNhdGlvbiJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiQ29udGV4dFwiOiAifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlwiVXNlciB3YW4ifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InRzIGEgc2ltIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJwbGUgdGVzdCJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIHdvIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJya2YifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJsb3cgd2l0In0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImggIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiYSBtYSJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im51YWwgdHJpZ2dlIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiciBhIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im5kIGEgc2UifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0IG5vZGUuXCJ9In19CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJ0b29sX3VzZSIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6MzYzLCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjEyNjUzLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MCwib3V0cHV0X3Rva2VucyI6MTQ4fSAgICAgICAgICAgICB9CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgICAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776069657468-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1776069657469-unknown-host-POST-_v1_messages-18622610.json b/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1776069657469-unknown-host-POST-_v1_messages-18622610.json deleted file mode 100644 index 922982981df..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1776069657469-unknown-host-POST-_v1_messages-18622610.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"Generate a concise title (max 60 chars) summarizing what", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["1702"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=.y7zyvVlTGKLGGdRloXGaKTJv_TdOfSJ2weEqJR4I_U-1776069651.5247436-1.0.1.1-h9ID_FdX4qf6OiD00.uMhrHg02CPiSUVYBxHKBwSNRY; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=1704"], - "request-id": ["req_011Ca1UHEUyFsWEatb2edCwg"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-13T08:40:53Z"], - "anthropic-ratelimit-tokens-remaining": ["27000000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-13T08:40:51Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-13T08:40:53Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-13T08:40:53Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22500000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Mon, 13 Apr 2026 08:40:53 GMT"], - "Content-Type": ["application/json"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "CF-RAY": ["9eb92b1a0c38c760-TXL"] - }, - "cookies": { - "_cfuvid": ".y7zyvVlTGKLGGdRloXGaKTJv_TdOfSJ2weEqJR4I_U-1776069651.5247436-1.0.1.1-h9ID_FdX4qf6OiD00.uMhrHg02CPiSUVYBxHKBwSNRY" - }, - "body": { - "contentType": "application/json", - "type": "JSON", - "json": { - "model": "claude-sonnet-4-6", - "id": "msg_01DYRxS2jafFvPZ9D75bG7sV", - "type": "message", - "role": "assistant", - "content": [ - { - "type": "text", - "text": "Build workflow with manual trigger and Set node" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "stop_details": null, - "usage": { - "input_tokens": 116, - "cache_creation_input_tokens": 0, - "cache_read_input_tokens": 0, - "cache_creation": { - "ephemeral_5m_input_tokens": 0, - "ephemeral_1h_input_tokens": 0 - }, - "output_tokens": 11, - "service_tier": "standard", - "inference_geo": "global" - } - }, - "rawBytes": "eyJtb2RlbCI6ImNsYXVkZS1zb25uZXQtNC02IiwiaWQiOiJtc2dfMDFEWVJ4UzJqYWZGdlBaOUQ3NWJHN3NWIiwidHlwZSI6Im1lc3NhZ2UiLCJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiQnVpbGQgd29ya2Zsb3cgd2l0aCBtYW51YWwgdHJpZ2dlciBhbmQgU2V0IG5vZGUifV0sInN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGwsInVzYWdlIjp7ImlucHV0X3Rva2VucyI6MTE2LCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjowLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6MTEsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fQ==" - } - }, - "id": "1776069657469-unknown-host-POST-_v1_messages-18622610.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1776069657469-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1776069657469-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index 779a17abb34..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1776069657469-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["855"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=H6DxUD_3DiH9aN0BdiHLJfyd8luvbbpKYDFburkIhUY-1776069650.0681944-1.0.1.1-yBz_K8Kcq6FyDiXig_riqAHR0orDs_vduSK828RYhIc; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=857"], - "request-id": ["req_011Ca1UH8LdcffCz6ps67f8a"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-13T08:40:50Z"], - "anthropic-ratelimit-tokens-remaining": ["26977000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-13T08:40:50Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-13T08:40:50Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-13T08:40:50Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22477000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Mon, 13 Apr 2026 08:40:51 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9eb92b10eff1e52a-TXL"] - }, - "cookies": { - "_cfuvid": "H6DxUD_3DiH9aN0BdiHLJfyd8luvbbpKYDFburkIhUY-1776069650.0681944-1.0.1.1-yBz_K8Kcq6FyDiXig_riqAHR0orDs_vduSK828RYhIc" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01DYMREMwppb4GxwvdNG3YHp\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":581,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":12653,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Building\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" your \\\"preview auto-open test\\\" workflow now!\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":581,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":12653,\"output_tokens\":15}}\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxRFlNUkVNd3BwYjRHeHd2ZE5HM1lIcCIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjU4MSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTI2NTMsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjoxLCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0YXJ0CmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RhcnQiLCJpbmRleCI6MCwiY29udGVudF9ibG9jayI6eyJ0eXBlIjoidGV4dCIsInRleHQiOiIifX0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiQnVpbGRpbmcifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IiB5b3VyIFwicHJldmlldyBhdXRvLW9wZW4gdGVzdFwiIHdvcmtmbG93IG5vdyEifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjU4MSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTI2NTMsIm91dHB1dF90b2tlbnMiOjE1fX0KCmV2ZW50OiBtZXNzYWdlX3N0b3AKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdG9wIiAgICAgICAgICAgICAgIH0KCg==", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776069657469-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1776069657470-unknown-host-POST-_v1_messages-4d1c93f7.json b/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1776069657470-unknown-host-POST-_v1_messages-4d1c93f7.json deleted file mode 100644 index 6921fcf170b..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1776069657470-unknown-host-POST-_v1_messages-4d1c93f7.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are an expert n8n workflow builder. You generate com", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["1578"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=Ydrlw8iWytpMI_y6hCRxAiY.cD9XtQ6ejAaJq7g7g6s-1776069650.2116451-1.0.1.1-.DpJw456xbPmwQpdmX7R.lf4XiSDkd8YgLRGdwhEC6U; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=1580"], - "request-id": ["req_011Ca1UH8vMfGzPipDmzDHzJ"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-13T08:40:50Z"], - "anthropic-ratelimit-tokens-remaining": ["26974000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-13T08:40:50Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-13T08:40:50Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-13T08:40:50Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22474000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Mon, 13 Apr 2026 08:40:51 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9eb92b11ddf3e51d-TXL"] - }, - "cookies": { - "_cfuvid": "Ydrlw8iWytpMI_y6hCRxAiY.cD9XtQ6ejAaJq7g7g6s-1776069650.2116451-1.0.1.1-.DpJw456xbPmwQpdmX7R.lf4XiSDkd8YgLRGdwhEC6U" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01DVrPydpLCoZsVgGnMKPhVK\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":403,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":16876,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":54,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_0199ekdWrttD4wdng3pCCZLs\",\"name\":\"build-workflow\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nam\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": \\\"p\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"review auto\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"-o\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"pen test\\\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"code\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\": \\\"\\\\ni\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"mpor\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t { workf\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"lo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"w, node, tr\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"igger, expr \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"} fro\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"m '@n8n/work\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"flow\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"-sdk';\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n\\\\ncon\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"st manualTr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"igger = tr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"igger({\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" t\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ype: 'n8n-\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nodes-bas\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e.manualT\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rigger\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"',\\\\n ver\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"sio\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n: 1,\\\\n co\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nfig: { name\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": 'Man\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ual \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Trigger' }\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n});\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\ncons\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t setNode\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" = node({\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" t\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ype:\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" 'n8\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n-nodes-b\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"as\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e.set\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"',\\\\n vers\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ion: \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"3.4,\\\\n c\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"onfig\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": {\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" name:\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" 'previe\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"w auto-open\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" t\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"est',\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" pa\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rameters: {\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" assi\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"gnments: {\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" ass\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ignments\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": [\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" { id: '1'\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", name: '\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"me\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ssage', v\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"alue: \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"'Hel\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"lo Wo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rld', \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"type: 'stri\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ng' }\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"]\\\\n },\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" options:\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" {}\\\\n }\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n }\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n});\\\\n\\\\ne\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"xport defa\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ult workf\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"lo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"w(\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"'preview-a\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"uto-open\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"-te\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"st', 'pre\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"view au\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"to-\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"open test')\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n .add(\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"manualTrig\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ger)\\\\n .to(\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"setNode);\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":403,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":16876,\"output_tokens\":300} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxRFZyUHlkcExDb1pzVmdHbk1LUGhWSyIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjQwMywiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTY4NzYsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjo1NCwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0YXJ0CmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RhcnQiLCJpbmRleCI6MCwiY29udGVudF9ibG9jayI6eyJ0eXBlIjoidG9vbF91c2UiLCJpZCI6InRvb2x1XzAxOTlla2RXcnR0RDR3ZG5nM3BDQ1pMcyIsIm5hbWUiOiJidWlsZC13b3JrZmxvdyIsImlucHV0Ijp7fSwiY2FsbGVyIjp7InR5cGUiOiJkaXJlY3QifX0gICAgICAgICAgIH0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoie1wiIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuYW0ifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZVwiIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiOiBcInAifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJyZXZpZXcgYXV0byJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Ii1vIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJwZW4gdGVzdFwiIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiLCBcImNvZGUifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXCI6IFwiXFxuaSJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im1wb3IifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidCB7IHdvcmtmIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibG8ifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidywgbm9kZSwgdHIifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpZ2dlciwgZXhwciAifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoifSBmcm8ifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im0gJ0BuOG4vd29yayJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJmbG93In0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Ii1zZGsnOyJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlxcblxcbmNvbiJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJzdCBtYW51YWxUciJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImlnZ2VyID0gdHIifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiaWdnZXIoe1xcbiJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiAgdCJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoieXBlOiAnbjhuLSJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im5vZGVzLWJhcyJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlLm1hbnVhbFQifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJyaWdnZXIifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiInLFxcbiAgdmVyIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InNpbyJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuOiAxLFxcbiAgY28ifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuZmlnOiB7IG5hbWUifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiOiAnTWFuIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InVhbCAifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJUcmlnZ2VyJyB9In0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXFxufSk7XFxuIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcXG5jb25zIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0IHNldE5vZGUifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiA9IG5vZGUoeyJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXFxuIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiAgdCJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InlwZToifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgJ244In0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuLW5vZGVzLWIifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiYXMifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZS5zZXQifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiJyxcXG4gIHZlcnMifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpb246ICJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIzLjQsXFxuICBjIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvbmZpZyJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiOiB7XFxuICAgIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIG5hbWU6In0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiAncHJldmllIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidyBhdXRvLW9wZW4ifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgdCJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVzdCcsXFxuICJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiICAgcGEifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InJhbWV0ZXJzOiB7XFwifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im4gICAifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgICJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgYXNzaSJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJnbm1lbnRzOiB7XFwifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuICAgICAgIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgIGFzcyJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiaWdubWVudHMifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiOiBbXFxuICAgICJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiAgICAifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgIHsgaWQ6ICcxJyJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiwgbmFtZTogJyJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibWUifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJzc2FnZScsIHYifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhbHVlOiAifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiJ0hlbCJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJsbyBXbyJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InJsZCcsICJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0eXBlOiAnc3RyaSJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im5nJyB9XFxuICAgICJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiICAgICJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXVxcbiAgICAgIH0sIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXFxuICAgIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiICAgb3B0aW9uczoifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiB7fVxcbiAgICB9In0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlxcbiAgfVxcIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibn0pO1xcblxcbmUifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ4cG9ydCBkZWZhIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InVsdCB3b3JrZiJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImxvIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IncoIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIncHJldmlldy1hIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidXRvLW9wZW4ifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Ii10ZSJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJzdCcsICdwcmUifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidmlldyBhdSJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0by0ifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvcGVuIHRlc3QnKVxcIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im4gIC5hZGQoIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJtYW51YWxUcmlnIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJnZXIpXFxuICAudG8oIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoic2V0Tm9kZSk7XFxuIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlwifSJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJ0b29sX3VzZSIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6NDAzLCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjoxNjg3Niwib3V0cHV0X3Rva2VucyI6MzAwfSAgICAgICAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICAgICAgICAgICAgICAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776069657470-unknown-host-POST-_v1_messages-4d1c93f7.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1777373853817-unknown-host-POST-_v1_messages-3dba52c9.json b/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1777373853817-unknown-host-POST-_v1_messages-3dba52c9.json new file mode 100644 index 00000000000..666a0660d35 --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-auto-open-preview-panel-when-workflow-is-built/1777373853817-unknown-host-POST-_v1_messages-3dba52c9.json @@ -0,0 +1,105 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde[\\s\\S]*\n{\n \"name\": \"Artifact Display Test\",\n \"nodes\": [\n {\n \"parameters\": {},\n \"id\": \"1a2b3c4d-0001-0001-0001-000000000001\",\n \"name\": \"Manual Trigger\",\n \"type\": \"n8n-nodes-base.manualTrigger\",\n \"typeVersion\": 1,\n \"position\": [240, 300]\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"field-001\",\n \"name\": \"message\",\n \"value\": \"Hello from the artifact display test!\",\n \"type\": \"string\"\n },\n {\n \"id\": \"field-002\",\n \"name\": \"timestamp\",\n \"value\": \"={{ $now }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"id\": \"1a2b3c4d-0002-0002-0002-000000000002\",\n \"name\": \"artifact display test\",\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [460, 300]\n }\n ],\n \"connections\": {\n \"Manual Trigger\": {\n \"main\": [\n [\n {\n \"node\": \"artifact display test\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"pinData\": {},\n \"settings\": {\n \"executionOrder\": \"v1\"\n }\n}\n\n\n### What this workflow does:\n1. **Manual Trigger** — Starts the workflow when you click \"Test workflow\" in n8n.\n2. **artifact display test** (Set node) — Sets two fields on the output item:\n - `message`: A static string `\"Hello from the artifact display test!\"`\n - `timestamp`: The current date/time using `$now`\n\nYou can import this directly into n8n and run it right away!" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "stop_details": null, - "usage": { - "input_tokens": 136, - "cache_creation_input_tokens": 0, - "cache_read_input_tokens": 0, - "cache_creation": { - "ephemeral_5m_input_tokens": 0, - "ephemeral_1h_input_tokens": 0 - }, - "output_tokens": 579, - "service_tier": "standard", - "inference_geo": "global" - } - }, - "rawBytes": "eyJtb2RlbCI6ImNsYXVkZS1zb25uZXQtNC02IiwiaWQiOiJtc2dfMDE1Qlh1UTFTQ1Rzd29yaW1FTW5ReEFlIiwidHlwZSI6Im1lc3NhZ2UiLCJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiSGVyZSBpcyBhIHNpbXBsZSBuOG4gd29ya2Zsb3cgd2l0aCBhIE1hbnVhbCBUcmlnZ2VyIGFuZCBhIFNldCBub2RlIGNhbGxlZCBcImFydGlmYWN0IGRpc3BsYXkgdGVzdFwiOlxuXG48YXJ0aWZhY3QgaWRlbnRpZmllcj1cIndvcmtmbG93XCIgdHlwZT1cImFwcGxpY2F0aW9uL244bi13b3JrZmxvd1wiIHRpdGxlPVwiQXJ0aWZhY3QgRGlzcGxheSBUZXN0IFdvcmtmbG93XCI+XG57XG4gIFwibmFtZVwiOiBcIkFydGlmYWN0IERpc3BsYXkgVGVzdFwiLFxuICBcIm5vZGVzXCI6IFtcbiAgICB7XG4gICAgICBcInBhcmFtZXRlcnNcIjoge30sXG4gICAgICBcImlkXCI6IFwiMWEyYjNjNGQtMDAwMS0wMDAxLTAwMDEtMDAwMDAwMDAwMDAxXCIsXG4gICAgICBcIm5hbWVcIjogXCJNYW51YWwgVHJpZ2dlclwiLFxuICAgICAgXCJ0eXBlXCI6IFwibjhuLW5vZGVzLWJhc2UubWFudWFsVHJpZ2dlclwiLFxuICAgICAgXCJ0eXBlVmVyc2lvblwiOiAxLFxuICAgICAgXCJwb3NpdGlvblwiOiBbMjQwLCAzMDBdXG4gICAgfSxcbiAgICB7XG4gICAgICBcInBhcmFtZXRlcnNcIjoge1xuICAgICAgICBcImFzc2lnbm1lbnRzXCI6IHtcbiAgICAgICAgICBcImFzc2lnbm1lbnRzXCI6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgXCJpZFwiOiBcImZpZWxkLTAwMVwiLFxuICAgICAgICAgICAgICBcIm5hbWVcIjogXCJtZXNzYWdlXCIsXG4gICAgICAgICAgICAgIFwidmFsdWVcIjogXCJIZWxsbyBmcm9tIHRoZSBhcnRpZmFjdCBkaXNwbGF5IHRlc3QhXCIsXG4gICAgICAgICAgICAgIFwidHlwZVwiOiBcInN0cmluZ1wiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBcImlkXCI6IFwiZmllbGQtMDAyXCIsXG4gICAgICAgICAgICAgIFwibmFtZVwiOiBcInRpbWVzdGFtcFwiLFxuICAgICAgICAgICAgICBcInZhbHVlXCI6IFwiPXt7ICRub3cgfX1cIixcbiAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwic3RyaW5nXCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBdXG4gICAgICAgIH0sXG4gICAgICAgIFwib3B0aW9uc1wiOiB7fVxuICAgICAgfSxcbiAgICAgIFwiaWRcIjogXCIxYTJiM2M0ZC0wMDAyLTAwMDItMDAwMi0wMDAwMDAwMDAwMDJcIixcbiAgICAgIFwibmFtZVwiOiBcImFydGlmYWN0IGRpc3BsYXkgdGVzdFwiLFxuICAgICAgXCJ0eXBlXCI6IFwibjhuLW5vZGVzLWJhc2Uuc2V0XCIsXG4gICAgICBcInR5cGVWZXJzaW9uXCI6IDMuNCxcbiAgICAgIFwicG9zaXRpb25cIjogWzQ2MCwgMzAwXVxuICAgIH1cbiAgXSxcbiAgXCJjb25uZWN0aW9uc1wiOiB7XG4gICAgXCJNYW51YWwgVHJpZ2dlclwiOiB7XG4gICAgICBcIm1haW5cIjogW1xuICAgICAgICBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgXCJub2RlXCI6IFwiYXJ0aWZhY3QgZGlzcGxheSB0ZXN0XCIsXG4gICAgICAgICAgICBcInR5cGVcIjogXCJtYWluXCIsXG4gICAgICAgICAgICBcImluZGV4XCI6IDBcbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIF1cbiAgICB9XG4gIH0sXG4gIFwicGluRGF0YVwiOiB7fSxcbiAgXCJzZXR0aW5nc1wiOiB7XG4gICAgXCJleGVjdXRpb25PcmRlclwiOiBcInYxXCJcbiAgfVxufVxuPC9hcnRpZmFjdD5cblxuIyMjIFdoYXQgdGhpcyB3b3JrZmxvdyBkb2VzOlxuMS4gKipNYW51YWwgVHJpZ2dlcioqIOKAlCBTdGFydHMgdGhlIHdvcmtmbG93IHdoZW4geW91IGNsaWNrIFwiVGVzdCB3b3JrZmxvd1wiIGluIG44bi5cbjIuICoqYXJ0aWZhY3QgZGlzcGxheSB0ZXN0KiogKFNldCBub2RlKSDigJQgU2V0cyB0d28gZmllbGRzIG9uIHRoZSBvdXRwdXQgaXRlbTpcbiAgIC0gYG1lc3NhZ2VgOiBBIHN0YXRpYyBzdHJpbmcgYFwiSGVsbG8gZnJvbSB0aGUgYXJ0aWZhY3QgZGlzcGxheSB0ZXN0IVwiYFxuICAgLSBgdGltZXN0YW1wYDogVGhlIGN1cnJlbnQgZGF0ZS90aW1lIHVzaW5nIGAkbm93YFxuXG5Zb3UgY2FuIGltcG9ydCB0aGlzIGRpcmVjdGx5IGludG8gbjhuIGFuZCBydW4gaXQgcmlnaHQgYXdheSEifV0sInN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGwsInVzYWdlIjp7ImlucHV0X3Rva2VucyI6MTM2LCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjowLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6NTc5LCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0=" - } - }, - "id": "1775805936944-unknown-host-POST-_v1_messages-18622610.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-display-artifact-card-in-timeline-after-workflow-build/1777373474687-unknown-host-POST-_v1_messages-8c32a7fd.json b/packages/testing/playwright/expectations/instance-ai/should-display-artifact-card-in-timeline-after-workflow-build/1777373474687-unknown-host-POST-_v1_messages-8c32a7fd.json new file mode 100644 index 00000000000..afbce16b192 --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-display-artifact-card-in-timeline-after-workflow-build/1777373474687-unknown-host-POST-_v1_messages-8c32a7fd.json @@ -0,0 +1,111 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde[\\s\\S]*Build a simple workflow with a manual trigger and a set node called \\\\\"artifact display test\\\\\"[\\s\\S]*" + } + }, + "httpResponse": { + "statusCode": 200, + "reasonPhrase": "OK", + "headers": { + "x-envoy-upstream-service-time": [ + "1589" + ], + "vary": [ + "Accept-Encoding" + ], + "strict-transport-security": [ + "max-age=31536000; includeSubDomains; preload" + ], + "set-cookie": [ + "_cfuvid=KJLUAJtGQFaRArRNYQ665Ffi8dqHFhIB1lE_FM24bm0-1777373448.4565804-1.0.1.1-q2DT0iMolyRiyD.mF59H6gruOgih1r2kYpToA4Pcdek; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" + ], + "server-timing": [ + "x-originResponse;dur=1591" + ], + "request-id": [ + "req_011CaW3KiQFrzGZVksaK8FcY" + ], + "cf-cache-status": [ + "DYNAMIC" + ], + "anthropic-ratelimit-tokens-reset": [ + "2026-04-28T10:50:48Z" + ], + "anthropic-ratelimit-tokens-remaining": [ + "26975000" + ], + "anthropic-ratelimit-tokens-limit": [ + "27000000" + ], + "anthropic-ratelimit-requests-reset": [ + "2026-04-28T10:50:48Z" + ], + "anthropic-ratelimit-requests-remaining": [ + "19998" + ], + "anthropic-ratelimit-requests-limit": [ + "20000" + ], + "anthropic-ratelimit-output-tokens-reset": [ + "2026-04-28T10:50:48Z" + ], + "anthropic-ratelimit-output-tokens-remaining": [ + "4500000" + ], + "anthropic-ratelimit-output-tokens-limit": [ + "4500000" + ], + "anthropic-ratelimit-input-tokens-reset": [ + "2026-04-28T10:50:48Z" + ], + "anthropic-ratelimit-input-tokens-remaining": [ + "22475000" + ], + "anthropic-ratelimit-input-tokens-limit": [ + "22500000" + ], + "X-Robots-Tag": [ + "none" + ], + "Server": [ + "cloudflare" + ], + "Date": [ + "Tue, 28 Apr 2026 10:50:50 GMT" + ], + "Content-Type": [ + "text/event-stream; charset=utf-8" + ], + "Content-Security-Policy": [ + "default-src 'none'; frame-ancestors 'none'" + ], + "Cache-Control": [ + "no-cache" + ], + "CF-RAY": [ + "9f358214d9726c11-PRG" + ] + }, + "cookies": { + "_cfuvid": "KJLUAJtGQFaRArRNYQ665Ffi8dqHFhIB1lE_FM24bm0-1777373448.4565804-1.0.1.1-q2DT0iMolyRiyD.mF59H6gruOgih1r2kYpToA4Pcdek" + }, + "body": { + "type": "STRING", + "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_016LHDKwMv8B3LxkfsMnXSEM\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":341,\"cache_creation_input_tokens\":14091,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":14091,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":48,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_016LPE39Lt7FTAmoFKA6rXAy\",\"name\":\"build-workflow-with-agent\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"t\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ask\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": \\\"Bu\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ild a simple\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" work\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"flo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"w with a\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Man\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ual Tri\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"gger no\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"de connecte\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"d to a Set \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nod\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e. Nam\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e the Set n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ode\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" \\\\\\\"artifac\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t display \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"test\\\\\\\". Th\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e Se\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t node doe\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"s not ne\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ed any f\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ields config\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ured — jus\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t the node \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"present\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" and conne\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"cted.\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"bypass\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Plan\\\": true\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"reason\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\": \\\"Ne\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"w simp\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"le work\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"flo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"w with\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" manua\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"l trigger\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" and a set \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"node — s\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"traight\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"forwar\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"d s\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ingle-wor\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"kf\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"low bui\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ld\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\".\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":341,\"cache_creation_input_tokens\":14091,\"cache_read_input_tokens\":0,\"output_tokens\":151} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", + "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxNkxIREt3TXY4QjNMeGtmc01uWFNFTSIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjM0MSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxNDA5MSwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjE0MDkxLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6NDgsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRvb2xfdXNlIiwiaWQiOiJ0b29sdV8wMTZMUEUzOUx0N0ZUQW1vRktBNnJYQXkiLCJuYW1lIjoiYnVpbGQtd29ya2Zsb3ctd2l0aC1hZ2VudCIsImlucHV0Ijp7fSwiY2FsbGVyIjp7InR5cGUiOiJkaXJlY3QifX0gICAgICAgICAgIH0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoie1widCJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImFza1wiIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiOiBcIkJ1In0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImlsZCBhIHNpbXBsZSJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIHdvcmsifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJmbG8ifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Incgd2l0aCBhIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBNYW4ifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ1YWwgVHJpIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZ2dlciBubyJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZGUgY29ubmVjdGUifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZCB0byBhIFNldCAifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im5vZCJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImUuIE5hbSJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlIHRoZSBTZXQgbiJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoib2RlIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIFxcXCJhcnRpZmFjIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidCBkaXNwbGF5ICJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InRlc3RcXFwiLiBUaCJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImUgU2UifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidCBub2RlIGRvZSJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJzIG5vdCBuZSJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZWQgYW55IGYifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImllbGRzIGNvbmZpZyJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ1cmVkIOKAlCBqdXMifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InQgdGhlIG5vZGUgIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJwcmVzZW50In0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgYW5kIGNvbm5lIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImN0ZWQuXCIifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiwgXCJieXBhc3MifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiUGxhblwiOiB0cnVlIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIsIFwicmVhc29uIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXCI6IFwiTmUifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidyBzaW1wIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJsZSB3b3JrIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImZsbyJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidyB3aXRoIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIG1hbnVhIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibCB0cmlnZ2VyIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIGFuZCBhIHNldCAifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJub2RlIOKAlCBzIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidHJhaWdodCJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZm9yd2FyIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJkIHMifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiaW5nbGUtd29yIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImtmIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImxvdyBidWkifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibGQifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiLlwifSJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjAgICAgICAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX2RlbHRhCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2VfZGVsdGEiLCJkZWx0YSI6eyJzdG9wX3JlYXNvbiI6InRvb2xfdXNlIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsfSwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjozNDEsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MTQwOTEsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJvdXRwdXRfdG9rZW5zIjoxNTF9ICAgICAgICAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX3N0b3AKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdG9wIiAgIH0KCg==", + "contentType": "text/event-stream; charset=utf-8" + } + }, + "id": "1777373474687-unknown-host-POST-_v1_messages-8c32a7fd.json", + "priority": 0, + "timeToLive": { + "unlimited": true + }, + "times": { + "unlimited": true + } +} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-display-artifact-card-in-timeline-after-workflow-build/1777373474688-unknown-host-POST-_v1_messages-4d84ab6b.json b/packages/testing/playwright/expectations/instance-ai/should-display-artifact-card-in-timeline-after-workflow-build/1777373474688-unknown-host-POST-_v1_messages-4d84ab6b.json new file mode 100644 index 00000000000..b70e9f9efe6 --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-display-artifact-card-in-timeline-after-workflow-build/1777373474688-unknown-host-POST-_v1_messages-4d84ab6b.json @@ -0,0 +1,111 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde[\\s\\S]*\"type\"\\s*:\\s*\"tool_use\"[\\s\\S]{0,300}\"name\"\\s*:\\s*\"build-workflow-with-agent\"[\\s\\S]*" + } + }, + "httpResponse": { + "statusCode": 200, + "reasonPhrase": "OK", + "headers": { + "x-envoy-upstream-service-time": [ + "1202" + ], + "vary": [ + "Accept-Encoding" + ], + "strict-transport-security": [ + "max-age=31536000; includeSubDomains; preload" + ], + "set-cookie": [ + "_cfuvid=ubSwPQOWLCyySiWgADFCMf_2c75.UnZLjsabdhl5RFg-1777373452.8828213-1.0.1.1-f3cfyae22mmz3TJsburJz53XSBnqEBZd47ftBrdE24Q; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" + ], + "server-timing": [ + "x-originResponse;dur=1205" + ], + "request-id": [ + "req_011CaW3L3KYVhZ26eNbS11SW" + ], + "cf-cache-status": [ + "DYNAMIC" + ], + "anthropic-ratelimit-tokens-reset": [ + "2026-04-28T10:50:52Z" + ], + "anthropic-ratelimit-tokens-remaining": [ + "26974000" + ], + "anthropic-ratelimit-tokens-limit": [ + "27000000" + ], + "anthropic-ratelimit-requests-reset": [ + "2026-04-28T10:50:53Z" + ], + "anthropic-ratelimit-requests-remaining": [ + "19998" + ], + "anthropic-ratelimit-requests-limit": [ + "20000" + ], + "anthropic-ratelimit-output-tokens-reset": [ + "2026-04-28T10:50:52Z" + ], + "anthropic-ratelimit-output-tokens-remaining": [ + "4500000" + ], + "anthropic-ratelimit-output-tokens-limit": [ + "4500000" + ], + "anthropic-ratelimit-input-tokens-reset": [ + "2026-04-28T10:50:53Z" + ], + "anthropic-ratelimit-input-tokens-remaining": [ + "22474000" + ], + "anthropic-ratelimit-input-tokens-limit": [ + "22500000" + ], + "X-Robots-Tag": [ + "none" + ], + "Server": [ + "cloudflare" + ], + "Date": [ + "Tue, 28 Apr 2026 10:50:54 GMT" + ], + "Content-Type": [ + "text/event-stream; charset=utf-8" + ], + "Content-Security-Policy": [ + "default-src 'none'; frame-ancestors 'none'" + ], + "Cache-Control": [ + "no-cache" + ], + "CF-RAY": [ + "9f3582308c832759-PRG" + ] + }, + "cookies": { + "_cfuvid": "ubSwPQOWLCyySiWgADFCMf_2c75.UnZLjsabdhl5RFg-1777373452.8828213-1.0.1.1-f3cfyae22mmz3TJsburJz53XSBnqEBZd47ftBrdE24Q" + }, + "body": { + "type": "STRING", + "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01BU7aWfyWZiTcKEVMFyJQ5b\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":574,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":14091,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":34,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_018aD4qW5ho8bLawuFhD9Dpm\",\"name\":\"plan\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":574,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":14091,\"output_tokens\":34} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", + "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxQlU3YVdmeVdaaVRjS0VWTUZ5SlE1YiIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjU3NCwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTQwOTEsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjozNCwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0YXJ0CmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RhcnQiLCJpbmRleCI6MCwiY29udGVudF9ibG9jayI6eyJ0eXBlIjoidG9vbF91c2UiLCJpZCI6InRvb2x1XzAxOGFENHFXNWhvOGJMYXd1RmhEOURwbSIsIm5hbWUiOiJwbGFuIiwiaW5wdXQiOnt9LCJjYWxsZXIiOnsidHlwZSI6ImRpcmVjdCJ9fSAgICAgICAgICAgIH0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICAgIH0KCmV2ZW50OiBtZXNzYWdlX2RlbHRhCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2VfZGVsdGEiLCJkZWx0YSI6eyJzdG9wX3JlYXNvbiI6InRvb2xfdXNlIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsfSwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjo1NzQsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjE0MDkxLCJvdXRwdXRfdG9rZW5zIjozNH0gICAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICAgICAgICAgICB9Cgo=", + "contentType": "text/event-stream; charset=utf-8" + } + }, + "id": "1777373474688-unknown-host-POST-_v1_messages-4d84ab6b.json", + "priority": 0, + "timeToLive": { + "unlimited": true + }, + "times": { + "unlimited": true + } +} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-display-artifact-card-in-timeline-after-workflow-build/1777373474688-unknown-host-POST-_v1_messages-8fc74415.json b/packages/testing/playwright/expectations/instance-ai/should-display-artifact-card-in-timeline-after-workflow-build/1777373474688-unknown-host-POST-_v1_messages-8fc74415.json new file mode 100644 index 00000000000..49ee01fe7ab --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-display-artifact-card-in-timeline-after-workflow-build/1777373474688-unknown-host-POST-_v1_messages-8fc74415.json @@ -0,0 +1,105 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You are the n8n Workflow Planner — you design solution a[\\s\\S]*\\\\n-\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" **\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Projec\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t**:\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"- **Status\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"**:\\\\n- **Key\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" details**:\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n\\\\n# Known\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Issues\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":885,\"cache_creation_input_tokens\":12360,\"cache_read_input_tokens\":0,\"output_tokens\":180} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxQ3pLTTN6anZidVlWc1dVc0I2dnpKMSIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjg4NSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxMjM2MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjEyMzYwLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6NDgsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0YXJ0CmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RhcnQiLCJpbmRleCI6MCwiY29udGVudF9ibG9jayI6eyJ0eXBlIjoidG9vbF91c2UiLCJpZCI6InRvb2x1XzAxS2lacjM5bTFiMUM4bXB4M1d0d1k2NSIsIm5hbWUiOiJ1cGRhdGVXb3JraW5nTWVtb3J5IiwiaW5wdXQiOnt9LCJjYWxsZXIiOnsidHlwZSI6ImRpcmVjdCJ9fSAgICAgICAgICAgICAgfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IntcIm1lIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibW9yeVwiOiBcIiJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIyBVc2VyIENvbnQifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImV4dFxcbi0gKiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IipOYW1lKioifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IjpcXG4tICoqUiJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoib2xlKio6XFxuIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiItICoqT3JnIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImFuaXphdGlvbioqIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiOlxcblxcbiMgVyJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoib3JrZmxvdyBQciJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVmZXJlbmMifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZXNcXG4tICJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IioqUHIifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlZmVycmVkIHQifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJyaWdnZXIgdHlwIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVzKio6XFxuLSAifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIqKiJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IkNvIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibW1vbiBpbnRlIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZ3IifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiYXRpb25zIHVzZWQifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiKio6XFxuLSAqKlcifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9ya2Zsb3cgbmFtaSJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibmcgY29udiJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZW50aW9ucyoifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIqOlxcbi0gKioifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJFcnJvciAifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImhhbiJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZGxpbmcifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgcGF0dGUifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJybnMqKjpcXG5cXG4ifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiMgQSJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImN0aXZlIFByb2plYyJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0XFxuPCEtLSJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBLZWVwIG9uIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJseSB0aGUgT05FICJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoicHJvamVjdCB0In0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiaGUgdXNlciAifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImlzIGN1cnJlbiJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidGx5ICJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ3b3JraW5nICJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9uLiBSZXAifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJsYWNlIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIHcifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImhlbiB0aGUgdXNlIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJyIHN3aXRjaGUifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InMgcHJvaiJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlY3QifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InMuIC0tPlxcbi0ifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiAqKiJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlByb2plYyJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InQqKjpcXG4ifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiItICoqU3RhdHVzIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IioqOlxcbi0gKipLZXkifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIGRldGFpbHMqKjpcXCJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiblxcbiMgS25vd24ifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBJc3N1ZXNcXCJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibjwhLS0gTyJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJubCJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ5IHVucmVzb2x2ZSJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJkIGlzc3Vlcy4gIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiUmVtb3ZlIHdoZW4ifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBmaXhlZC4gLS0+In0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlxcblwifSJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoidG9vbF91c2UiLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjg4NSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxMjM2MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsIm91dHB1dF90b2tlbnMiOjE4MH0gICAgICAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX3N0b3AKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdG9wIiAgICAgICAgICAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805923377-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-display-user-and-assistant-messages-in-timeline/1775805923379-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-display-user-and-assistant-messages-in-timeline/1775805923379-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index e253585703a..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-display-user-and-assistant-messages-in-timeline/1775805923379-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["850"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=0Xwhdh58bSTSdo36ojQnPWqABlSIaA9DRCDd3eRf8jU-1775805920.1855745-1.0.1.1-pXLBaeyXVqRgp6tl2l17dcVimlYIypYb0BOC7IjcvCs; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=852"], - "request-id": ["req_011CZuh6Tk8V77owzf4SQCoy"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:25:20Z"], - "anthropic-ratelimit-tokens-remaining": ["26976000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:25:20Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:25:20Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:25:20Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22476000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:25:21 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9ea00459295fc637-TXL"] - }, - "cookies": { - "_cfuvid": "0Xwhdh58bSTSdo36ojQnPWqABlSIaA9DRCDd3eRf8jU-1775805920.1855745-1.0.1.1-pXLBaeyXVqRgp6tl2l17dcVimlYIypYb0BOC7IjcvCs" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01S78NNZx23evw7NUkGfhZXh\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":1081,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":12360,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":3,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Hello! \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"👋 Great to meet you! I'm your n8n Instance Agent —\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" here to help you build, run, debug, and manage your workflows. What\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" can I help you with today?\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":1081,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":12360,\"output_tokens\":46} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxUzc4Tk5aeDIzZXZ3N05Va0dmaFpYaCIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEwODEsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjEyMzYwLCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjowLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6Mywic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0YXJ0CmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RhcnQiLCJpbmRleCI6MCwiY29udGVudF9ibG9jayI6eyJ0eXBlIjoidGV4dCIsInRleHQiOiIifSAgfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiJIZWxsbyEgIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IvCfkYsgR3JlYXQgdG8gbWVldCB5b3UhIEknbSB5b3VyIG44biBJbnN0YW5jZSBBZ2VudCDigJQifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIgaGVyZSB0byBoZWxwIHlvdSBidWlsZCwgcnVuLCBkZWJ1ZywgYW5kIG1hbmFnZSB5b3VyIHdvcmtmbG93cy4gV2hhdCJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIgY2FuIEkgaGVscCB5b3Ugd2l0aCB0b2RheT8ifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjAgICAgfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEwODEsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjEyMzYwLCJvdXRwdXRfdG9rZW5zIjo0Nn0gICAgICAgICAgICB9CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgICAgICAgICAgICAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805923379-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-display-user-and-assistant-messages-in-timeline/1777373526107-unknown-host-POST-_v1_messages-f134c753.json b/packages/testing/playwright/expectations/instance-ai/should-display-user-and-assistant-messages-in-timeline/1777373526107-unknown-host-POST-_v1_messages-f134c753.json new file mode 100644 index 00000000000..5d8e43af044 --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-display-user-and-assistant-messages-in-timeline/1777373526107-unknown-host-POST-_v1_messages-f134c753.json @@ -0,0 +1,134 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You generate a short descriptive title for a conversatio[\\s\\S]*Generate a title for the following first message of a conversation\\. Do not answer the message — only produce the title\\.\\\\n[\\s\\S]*" + } + }, + "httpResponse": { + "statusCode": 200, + "reasonPhrase": "OK", + "headers": { + "x-envoy-upstream-service-time": [ + "1210" + ], + "vary": [ + "Accept-Encoding" + ], + "strict-transport-security": [ + "max-age=31536000; includeSubDomains; preload" + ], + "set-cookie": [ + "_cfuvid=qAPA4c2QrCEbsuZg9RF16S1SXU6ZUE9Qt..f2SNNXWY-1777373519.8989372-1.0.1.1-E8PYlkHqCUd9ko.VhKIGWKXb0sp8PpsCy1scPd.jpQ4; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" + ], + "server-timing": [ + "x-originResponse;dur=1212" + ], + "request-id": [ + "req_011CaW3QyorJkvgjF9UjqFkH" + ], + "cf-cache-status": [ + "DYNAMIC" + ], + "anthropic-ratelimit-tokens-reset": [ + "2026-04-28T10:52:00Z" + ], + "anthropic-ratelimit-tokens-remaining": [ + "27000000" + ], + "anthropic-ratelimit-tokens-limit": [ + "27000000" + ], + "anthropic-ratelimit-requests-reset": [ + "2026-04-28T10:51:59Z" + ], + "anthropic-ratelimit-requests-remaining": [ + "19998" + ], + "anthropic-ratelimit-requests-limit": [ + "20000" + ], + "anthropic-ratelimit-output-tokens-reset": [ + "2026-04-28T10:52:01Z" + ], + "anthropic-ratelimit-output-tokens-remaining": [ + "4500000" + ], + "anthropic-ratelimit-output-tokens-limit": [ + "4500000" + ], + "anthropic-ratelimit-input-tokens-reset": [ + "2026-04-28T10:52:00Z" + ], + "anthropic-ratelimit-input-tokens-remaining": [ + "22500000" + ], + "anthropic-ratelimit-input-tokens-limit": [ + "22500000" + ], + "X-Robots-Tag": [ + "none" + ], + "Server": [ + "cloudflare" + ], + "Date": [ + "Tue, 28 Apr 2026 10:52:01 GMT" + ], + "Content-Type": [ + "application/json" + ], + "Content-Security-Policy": [ + "default-src 'none'; frame-ancestors 'none'" + ], + "CF-RAY": [ + "9f3583d35fc3b38f-PRG" + ] + }, + "cookies": { + "_cfuvid": "qAPA4c2QrCEbsuZg9RF16S1SXU6ZUE9Qt..f2SNNXWY-1777373519.8989372-1.0.1.1-E8PYlkHqCUd9ko.VhKIGWKXb0sp8PpsCy1scPd.jpQ4" + }, + "body": { + "contentType": "application/json", + "type": "JSON", + "json": { + "model": "claude-sonnet-4-6", + "id": "msg_01UJb7rMewKweX9PEnArLuLY", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "General inquiry about capabilities" + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "stop_details": null, + "usage": { + "input_tokens": 379, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 7, + "service_tier": "standard", + "inference_geo": "global" + } + }, + "rawBytes": "eyJtb2RlbCI6ImNsYXVkZS1zb25uZXQtNC02IiwiaWQiOiJtc2dfMDFVSmI3ck1ld0t3ZVg5UEVuQXJMdUxZIiwidHlwZSI6Im1lc3NhZ2UiLCJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiR2VuZXJhbCBpbnF1aXJ5IGFib3V0IGNhcGFiaWxpdGllcyJ9XSwic3RvcF9yZWFzb24iOiJlbmRfdHVybiIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbCwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjozNzksImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjo3LCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0=" + } + }, + "id": "1777373526107-unknown-host-POST-_v1_messages-f134c753.json", + "priority": 0, + "timeToLive": { + "unlimited": true + }, + "times": { + "unlimited": true + } +} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-display-user-and-assistant-messages-in-timeline/1777373526108-unknown-host-POST-_v1_messages-58170ad1.json b/packages/testing/playwright/expectations/instance-ai/should-display-user-and-assistant-messages-in-timeline/1777373526108-unknown-host-POST-_v1_messages-58170ad1.json new file mode 100644 index 00000000000..617ca4b3cc9 --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-display-user-and-assistant-messages-in-timeline/1777373526108-unknown-host-POST-_v1_messages-58170ad1.json @@ -0,0 +1,105 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde[\\s\\S]*Say hello back to me[\\s\\S]*" + } + }, + "httpResponse": { + "statusCode": 200, + "reasonPhrase": "OK", + "headers": { + "x-envoy-upstream-service-time": [ + "1010" + ], + "strict-transport-security": [ + "max-age=31536000; includeSubDomains; preload" + ], + "set-cookie": [ + "_cfuvid=gshCwBjQv17O7j3hHdQhV22dq8ghaRkG.kzJODIMEy8-1777373524.2681742-1.0.1.1-pEcUw.KR0jVvXqqqsJnqbHLoo.C55lA1NGVBqBF3rDA; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" + ], + "request-id": [ + "req_011CaW3RJdBnRJvQcJQnQKnC" + ], + "cf-cache-status": [ + "DYNAMIC" + ], + "anthropic-ratelimit-tokens-reset": [ + "2026-04-28T10:52:04Z" + ], + "anthropic-ratelimit-tokens-remaining": [ + "26975000" + ], + "anthropic-ratelimit-tokens-limit": [ + "27000000" + ], + "anthropic-ratelimit-requests-reset": [ + "2026-04-28T10:52:04Z" + ], + "anthropic-ratelimit-requests-remaining": [ + "19998" + ], + "anthropic-ratelimit-requests-limit": [ + "20000" + ], + "anthropic-ratelimit-output-tokens-reset": [ + "2026-04-28T10:52:04Z" + ], + "anthropic-ratelimit-output-tokens-remaining": [ + "4500000" + ], + "anthropic-ratelimit-output-tokens-limit": [ + "4500000" + ], + "anthropic-ratelimit-input-tokens-reset": [ + "2026-04-28T10:52:04Z" + ], + "anthropic-ratelimit-input-tokens-remaining": [ + "22475000" + ], + "anthropic-ratelimit-input-tokens-limit": [ + "22500000" + ], + "X-Robots-Tag": [ + "none" + ], + "Server": [ + "cloudflare" + ], + "Date": [ + "Tue, 28 Apr 2026 10:52:05 GMT" + ], + "Content-Type": [ + "text/event-stream; charset=utf-8" + ], + "Content-Security-Policy": [ + "default-src 'none'; frame-ancestors 'none'" + ], + "Cache-Control": [ + "no-cache" + ], + "CF-RAY": [ + "9f3583eeac982783-PRG" + ] + }, + "cookies": { + "_cfuvid": "gshCwBjQv17O7j3hHdQhV22dq8ghaRkG.kzJODIMEy8-1777373524.2681742-1.0.1.1-pEcUw.KR0jVvXqqqsJnqbHLoo.C55lA1NGVBqBF3rDA" + }, + "body": { + "type": "STRING", + "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01LEt1K77h6R2Jt5QeDzFnYz\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":328,\"cache_creation_input_tokens\":14091,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":14091,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":8,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Hello! How can I help you today\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"?\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":328,\"cache_creation_input_tokens\":14091,\"cache_read_input_tokens\":0,\"output_tokens\":12} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", + "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxTEV0MUs3N2g2UjJKdDVRZUR6Rm5ZeiIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjMyOCwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxNDA5MSwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjE0MDkxLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6OCwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0YXJ0CmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RhcnQiLCJpbmRleCI6MCwiY29udGVudF9ibG9jayI6eyJ0eXBlIjoidGV4dCIsInRleHQiOiIifSAgICAgfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiJIZWxsbyEgSG93IGNhbiBJIGhlbHAgeW91IHRvZGF5In0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiPyJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICAgICAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX2RlbHRhCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2VfZGVsdGEiLCJkZWx0YSI6eyJzdG9wX3JlYXNvbiI6ImVuZF90dXJuIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsfSwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjozMjgsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MTQwOTEsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJvdXRwdXRfdG9rZW5zIjoxMn0gIH0KCmV2ZW50OiBtZXNzYWdlX3N0b3AKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdG9wIiAgICAgICAgIH0KCg==", + "contentType": "text/event-stream; charset=utf-8" + } + }, + "id": "1777373526108-unknown-host-POST-_v1_messages-58170ad1.json", + "priority": 0, + "timeToLive": { + "unlimited": true + }, + "times": { + "unlimited": true + } +} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-display-user-and-assistant-messages-in-timeline/trace.jsonl b/packages/testing/playwright/expectations/instance-ai/should-display-user-and-assistant-messages-in-timeline/trace.jsonl index 45b16e51c6b..1377f16713a 100644 --- a/packages/testing/playwright/expectations/instance-ai/should-display-user-and-assistant-messages-in-timeline/trace.jsonl +++ b/packages/testing/playwright/expectations/instance-ai/should-display-user-and-assistant-messages-in-timeline/trace.jsonl @@ -1 +1 @@ -{"kind":"header","version":1,"testName":"recording","recordedAt":"2026-04-10T07:25:00.154Z"} +{"kind":"header","version":1,"testName":"recording","recordedAt":"2026-04-28T10:52:04.142Z"} diff --git a/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601569-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601569-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index 9086463b491..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601569-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["2540"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=6K4P6_Am42vOi2e2D1xaMZFzcOJ_69uQ.PjYihDbHIU-1776069552.4476-1.0.1.1-MNwkq7wY7b9MXfZm3BhbtBcWlIlPloSblvbakCuBYNc; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=2548"], - "request-id": ["req_011Ca1U9vwqLUyaxQaT3L8dF"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-13T08:39:12Z"], - "anthropic-ratelimit-tokens-remaining": ["26977000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-13T08:39:12Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-13T08:39:12Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-13T08:39:12Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22477000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Mon, 13 Apr 2026 08:39:15 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9eb928aecab2e516-TXL"] - }, - "cookies": { - "_cfuvid": "6K4P6_Am42vOi2e2D1xaMZFzcOJ_69uQ.PjYihDbHIU-1776069552.4476-1.0.1.1-MNwkq7wY7b9MXfZm3BhbtBcWlIlPloSblvbakCuBYNc" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01FSKVPyANdZhwsrB5QxEUY6\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":361,\"cache_creation_input_tokens\":12653,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":12653,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":45,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01GjdcF4s5jE4miEZhjkZFoR\",\"name\":\"build-workflow-with-agent\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"ta\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"sk\\\": \\\"Bui\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ld a simpl\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e wo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rkflow\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" with a Manu\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"al Tri\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"gge\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"r no\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"de connec\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"te\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"d to a\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Se\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t nod\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e. The Set \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"node should\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" be\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" named \\\\\\\"n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ode executio\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n test\\\\\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\". \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"No sp\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"eci\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"fi\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"c fi\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"elds need t\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"o be se\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"in the Set n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ode — just\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" the\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" de\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"fault config\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"uration \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"is fin\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e.\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"conve\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rsationConte\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"xt\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\": \\\"Use\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"r want\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"s a sim\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ple workf\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"low: Manu\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"al T\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rigger → \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Set no\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"de named \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\\\\"no\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"de execut\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ion test\\\\\\\".\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":361,\"cache_creation_input_tokens\":12653,\"cache_read_input_tokens\":0,\"output_tokens\":138} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxRlNLVlB5QU5kWmh3c3JCNVF4RVVZNiIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjM2MSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxMjY1MywiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjEyNjUzLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6NDUsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fSB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRvb2xfdXNlIiwiaWQiOiJ0b29sdV8wMUdqZGNGNHM1akU0bWlFWmhqa1pGb1IiLCJuYW1lIjoiYnVpbGQtd29ya2Zsb3ctd2l0aC1hZ2VudCIsImlucHV0Ijp7fSwiY2FsbGVyIjp7InR5cGUiOiJkaXJlY3QifX19CgpldmVudDogcGluZwpkYXRhOiB7InR5cGUiOiAicGluZyJ9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ7XCJ0YSJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoic2tcIjogXCJCdWkifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJsZCBhIHNpbXBsIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImUgd28ifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoicmtmbG93In0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgd2l0aCBhIE1hbnUifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiYWwgVHJpIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJnZ2UifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InIgbm8ifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZGUgY29ubmVjIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InRlIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZCB0byBhIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBTZSJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidCBub2QifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImUuIFRoZSBTZXQgIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJub2RlIHNob3VsZCJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIGJlIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBuYW1lZCBcXFwibiJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9kZSBleGVjdXRpbyJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibiB0ZXN0XFxcIiJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Ii4gIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Ik5vIHNwIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlY2kifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJmaSJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImMgZmkifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlbGRzIG5lZWQgdCJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvIGJlIHNlIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidCAifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImluIHRoZSBTZXQgbiJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9kZSDigJQganVzdCJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgdGhlIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBkZSJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImZhdWx0IGNvbmZpZyJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ1cmF0aW9uICJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImlzIGZpbiJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlLlwiIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIsIFwiY29udmUifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoicnNhdGlvbkNvbnRlIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Inh0In0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcIjogXCJVc2UifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InIgd2FudCJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJzIGEgc2ltIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJwbGUgd29ya2YifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImxvdzogTWFudSJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhbCBUIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJyaWdnZXIg4oaSICJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiU2V0IG5vIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZGUgbmFtZWQgIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcXFwibm8ifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJkZSBleGVjdXQifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpb24gdGVzdFxcXCIuIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlwifSJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjAgICAgICAgICAgICB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJ0b29sX3VzZSIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6MzYxLCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjEyNjUzLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MCwib3V0cHV0X3Rva2VucyI6MTM4fSAgICAgICB9CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgICAgICAgIH0KCg==", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776069601569-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601579-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601579-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index d90dddf6d19..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601579-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["1061"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=QOKJSIRDPCVUSVNykHEa4hbzJe5mvOl1uPMr8ZqYn.0-1776069557.5793178-1.0.1.1-T0Yr8cWDRntBRqd6x8ccj9gTYRAbcJhDwTed4fA1bnc; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=1064"], - "request-id": ["req_011Ca1UAJsCcwSKPXH82esLf"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-13T08:39:17Z"], - "anthropic-ratelimit-tokens-remaining": ["26977000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-13T08:39:17Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-13T08:39:17Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-13T08:39:17Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22477000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Mon, 13 Apr 2026 08:39:18 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9eb928cedbc38131-TXL"] - }, - "cookies": { - "_cfuvid": "QOKJSIRDPCVUSVNykHEa4hbzJe5mvOl1uPMr8ZqYn.0-1776069557.5793178-1.0.1.1-T0Yr8cWDRntBRqd6x8ccj9gTYRAbcJhDwTed4fA1bnc" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_013eej7RKQ9L3H3DTnaMx7Ko\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":569,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":12653,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Building\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" your workflow with a Manual Trigger connected to a Set node called **\\\"node execution test\\\"** now\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"!\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":569,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":12653,\"output_tokens\":26} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxM2VlajdSS1E5TDNIM0RUbmFNeDdLbyIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjU2OSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTI2NTMsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjoxLCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRleHQiLCJ0ZXh0IjoiIn0gICAgICB9CgpldmVudDogcGluZwpkYXRhOiB7InR5cGUiOiAicGluZyJ9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IkJ1aWxkaW5nIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiIHlvdXIgd29ya2Zsb3cgd2l0aCBhIE1hbnVhbCBUcmlnZ2VyIGNvbm5lY3RlZCB0byBhIFNldCBub2RlIGNhbGxlZCAqKlwibm9kZSBleGVjdXRpb24gdGVzdFwiKiogbm93In0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiISJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICAgICB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJlbmRfdHVybiIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6NTY5LCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjoxMjY1Mywib3V0cHV0X3Rva2VucyI6MjZ9ICAgICB9CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgICB9Cgo=", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776069601579-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601581-unknown-host-POST-_v1_messages-18622610.json b/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601581-unknown-host-POST-_v1_messages-18622610.json deleted file mode 100644 index 703d8c72a81..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601581-unknown-host-POST-_v1_messages-18622610.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"Generate a concise title (max 60 chars) summarizing what", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["809"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=26D7Z4LiYkzDE4d6flpVBaRieFjK2sSjqGuGkhebmwc-1776069559.5118701-1.0.1.1-IdvvGhkyjZQYLlwbE7X6r550LVR4jp5ZG688.rTjEOI; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=811"], - "request-id": ["req_011Ca1UATDFUYZV1BXTQ4nuH"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-13T08:39:20Z"], - "anthropic-ratelimit-tokens-remaining": ["27000000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-13T08:39:19Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-13T08:39:20Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-13T08:39:20Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22500000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Mon, 13 Apr 2026 08:39:20 GMT"], - "Content-Type": ["application/json"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "CF-RAY": ["9eb928daf91ac637-TXL"] - }, - "cookies": { - "_cfuvid": "26D7Z4LiYkzDE4d6flpVBaRieFjK2sSjqGuGkhebmwc-1776069559.5118701-1.0.1.1-IdvvGhkyjZQYLlwbE7X6r550LVR4jp5ZG688.rTjEOI" - }, - "body": { - "contentType": "application/json", - "type": "JSON", - "json": { - "model": "claude-sonnet-4-6", - "id": "msg_01Nc8X7biokNTUgotXQbfuLK", - "type": "message", - "role": "assistant", - "content": [ - { - "type": "text", - "text": "Build simple workflow with manual trigger and Set node" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "stop_details": null, - "usage": { - "input_tokens": 115, - "cache_creation_input_tokens": 0, - "cache_read_input_tokens": 0, - "cache_creation": { - "ephemeral_5m_input_tokens": 0, - "ephemeral_1h_input_tokens": 0 - }, - "output_tokens": 12, - "service_tier": "standard", - "inference_geo": "global" - } - }, - "rawBytes": "eyJtb2RlbCI6ImNsYXVkZS1zb25uZXQtNC02IiwiaWQiOiJtc2dfMDFOYzhYN2Jpb2tOVFVnb3RYUWJmdUxLIiwidHlwZSI6Im1lc3NhZ2UiLCJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiQnVpbGQgc2ltcGxlIHdvcmtmbG93IHdpdGggbWFudWFsIHRyaWdnZXIgYW5kIFNldCBub2RlIn1dLCJzdG9wX3JlYXNvbiI6ImVuZF90dXJuIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjExNSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfY3JlYXRpb24iOnsiZXBoZW1lcmFsXzVtX2lucHV0X3Rva2VucyI6MCwiZXBoZW1lcmFsXzFoX2lucHV0X3Rva2VucyI6MH0sIm91dHB1dF90b2tlbnMiOjEyLCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0=" - } - }, - "id": "1776069601581-unknown-host-POST-_v1_messages-18622610.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601583-unknown-host-POST-_v1_messages-4d1c93f7.json b/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601583-unknown-host-POST-_v1_messages-4d1c93f7.json deleted file mode 100644 index 722b35d3a39..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601583-unknown-host-POST-_v1_messages-4d1c93f7.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are an expert n8n workflow builder. You generate com", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["1872"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=GESeGMCKPxcN0ppUlPiLMWGQtTTmdJ6GFvfrQratfK4-1776069557.6390753-1.0.1.1-HukBPcHHPasUp75UlGoVomGozxyLGiNAMcWCOVyJDp0; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=1878"], - "request-id": ["req_011Ca1UAKBJfQSD4CuvuEGQc"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-13T08:39:17Z"], - "anthropic-ratelimit-tokens-remaining": ["26956000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-13T08:39:17Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-13T08:39:17Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-13T08:39:17Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22456000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Mon, 13 Apr 2026 08:39:19 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9eb928cf3be39965-TXL"] - }, - "cookies": { - "_cfuvid": "GESeGMCKPxcN0ppUlPiLMWGQtTTmdJ6GFvfrQratfK4-1776069557.6390753-1.0.1.1-HukBPcHHPasUp75UlGoVomGozxyLGiNAMcWCOVyJDp0" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01EiXYY5xGSCz4w5Cg22A9WW\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":394,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":16876,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":52,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}}}\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_014gkAFKq5pRk8iUChVkgSVN\",\"name\":\"build-workflow\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"name\\\": \\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Manual Tri\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"gger to Set \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Node\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"c\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"od\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e\\\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"\\\\nimport \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{ wor\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"kflow, n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"od\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e, \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"trigger } \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"from \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"'@n8n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"/workfl\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ow-s\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"dk';\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"const man\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ua\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"lTr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"igge\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"r = trigg\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"er({\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" \"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ty\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"pe: 'n8n-n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"odes\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"-ba\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"se\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\".manualTri\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"gger',\\\\n ve\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rsi\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"on\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": 1,\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n con\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"fig: { n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ame: 'Manual\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Trigger'\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" }\\\\n});\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\nco\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nst setNo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"de\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" =\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" node(\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" typ\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e: '\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n8n-nodes\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"-ba\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"se.set'\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\",\\\\n v\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ersi\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"on:\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" 3.4,\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n conf\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ig: {\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"name: 'node\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" ex\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ecution tes\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t',\\\\n pa\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rameters: {\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"assign\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ments: \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{ assignmen\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ts: \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"[]\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" },\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"options:\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" {}\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"}\\\\n }\\\\n});\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n\\\\ne\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"xport d\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"efault wor\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"kflow(\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"'manual-to-s\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"et', 'Manual\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Trigge\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"r to S\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"et Node')\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" .\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ad\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"d(manua\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"lT\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rig\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ger)\\\\n .t\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"o(s\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"etNode\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\");\\\\n\\\"}\"}}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":394,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":16876,\"output_tokens\":261}}\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxRWlYWVk1eEdTQ3o0dzVDZzIyQTlXVyIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjM5NCwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTY4NzYsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjo1Miwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0b29sX3VzZSIsImlkIjoidG9vbHVfMDE0Z2tBRktxNXBSazhpVUNoVmtnU1ZOIiwibmFtZSI6ImJ1aWxkLXdvcmtmbG93IiwiaW5wdXQiOnt9LCJjYWxsZXIiOnsidHlwZSI6ImRpcmVjdCJ9fSAgICAgfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IntcIiJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuYW1lXCI6IFwiIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJNYW51YWwgVHJpIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJnZ2VyIHRvIFNldCAifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJOb2RlXCIifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiwgXCJjIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoib2QifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlXCI6ICJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcIlxcbmltcG9ydCAifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoieyB3b3IifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJrZmxvdywgbiJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvZCJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZSwgIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InRyaWdnZXIgfSAifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImZyb20gIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiInQG44biJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Ii93b3JrZmwifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoib3ctcyJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZGsnO1xcIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuXFxuIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImNvbnN0IG1hbiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InVhIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImxUciJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiaWdnZSJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiciA9IHRyaWdnIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVyKHtcXG4ifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgICJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InR5In0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJwZTogJ244bi1uIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9kZXMifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Ii1iYSJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoic2UifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Ii5tYW51YWxUcmkifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImdnZXInLFxcbiAgdmUifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InJzaSJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9uIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IjogMSwifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlxcbiAgY29uIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZmlnOiB7IG4ifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImFtZTogJ01hbnVhbCJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIFRyaWdnZXInIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIH1cXG59KTtcXG4ifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXFxuY28ifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im5zdCBzZXRObyJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJkZSJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiA9In0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBub2RlKCJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ7XFxuIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgIHR5cCJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlOiAnIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im44bi1ub2RlcyJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiItYmEifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InNlLnNldCcifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IixcXG4gIHYifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVyc2kifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoib246In0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiAzLjQsXFwifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuICBjb25mIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiaWc6IHtcXG4gICAgIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibmFtZTogJ25vZGUifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIGV4In19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZWN1dGlvbiB0ZXMifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InQnLFxcbiAgICBwYSJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InJhbWV0ZXJzOiB7XFwifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuICAgICAgIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhc3NpZ24ifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im1lbnRzOiAifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InsgYXNzaWdubWVuIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0czogIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IltdIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgfSxcXG4gICAgICAifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvcHRpb25zOiJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIge31cXG4gICJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgICJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ9XFxuICB9XFxufSk7XFwifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuXFxuZSJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ4cG9ydCBkIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlZmF1bHQgd29yIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJrZmxvdygifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiInbWFudWFsLXRvLXMifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImV0JywgJ01hbnVhbCJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBUcmlnZ2UifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJyIHRvIFMifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZXQgTm9kZScpXFxuICJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiAuIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhZCJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJkKG1hbnVhIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImxUIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InJpZyJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImdlcilcXG4gIC50In0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvKHMifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImV0Tm9kZSJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Iik7XFxuXCJ9In19CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICAgICAgICAgICAgICB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJ0b29sX3VzZSIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6Mzk0LCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjoxNjg3Niwib3V0cHV0X3Rva2VucyI6MjYxfX0KCmV2ZW50OiBtZXNzYWdlX3N0b3AKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdG9wIiAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776069601583-unknown-host-POST-_v1_messages-4d1c93f7.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601584-unknown-host-POST-_v1_messages-4d1c93f7.json b/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601584-unknown-host-POST-_v1_messages-4d1c93f7.json deleted file mode 100644 index 014866deaf7..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601584-unknown-host-POST-_v1_messages-4d1c93f7.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are an expert n8n workflow builder. You generate com", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["1156"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=jRScQiEF9V3xiJVKcCIEx2gYgaLAjVjqWVNdqvDdB5c-1776069564.5118344-1.0.1.1-myHqeIS._XVxnLTZ1bkZp3tCF3qEIzBMX56DnBsiJ7Y; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=1226"], - "request-id": ["req_011Ca1UApbsAfGi7b8qWHcRc"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-13T08:39:24Z"], - "anthropic-ratelimit-tokens-remaining": ["26974000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-13T08:39:24Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-13T08:39:24Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-13T08:39:24Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22474000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Mon, 13 Apr 2026 08:39:25 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9eb928fa38a9ac01-TXL"] - }, - "cookies": { - "_cfuvid": "jRScQiEF9V3xiJVKcCIEx2gYgaLAjVjqWVNdqvDdB5c-1776069564.5118344-1.0.1.1-myHqeIS._XVxnLTZ1bkZp3tCF3qEIzBMX56DnBsiJ7Y" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01FyafZTMFvr1awN247LyRJU\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":692,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":16876,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Done\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" — the workflow is ready with a Manual Trigger connected to a Set node named \\\"node execution test\\\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" using default configuration.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":692,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":16876,\"output_tokens\":29} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxRnlhZlpUTUZ2cjFhd04yNDdMeVJKVSIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjY5MiwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTY4NzYsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjoxLCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiJ9ICAgICAgICAgICB9CgpldmVudDogcGluZwpkYXRhOiB7InR5cGUiOiAicGluZyJ9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IkRvbmUifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IiDigJQgdGhlIHdvcmtmbG93IGlzIHJlYWR5IHdpdGggYSBNYW51YWwgVHJpZ2dlciBjb25uZWN0ZWQgdG8gYSBTZXQgbm9kZSBuYW1lZCBcIm5vZGUgZXhlY3V0aW9uIHRlc3RcIiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIgdXNpbmcgZGVmYXVsdCBjb25maWd1cmF0aW9uLiJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICAgICAgICAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjY5MiwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTY4NzYsIm91dHB1dF90b2tlbnMiOjI5fSAgICAgICAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICB9Cgo=", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776069601584-unknown-host-POST-_v1_messages-4d1c93f7.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601585-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601585-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index 7706b7a6ed9..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1776069601585-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["1734"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=v5ngmdIHQTaROEKShWt2hD5R67.QJMjzZV.534L7.yY-1776069567.961117-1.0.1.1-o0pIZIsz_GgVbjMA93Y8CnwvoH2.umN7_YtmSJ4e1PY; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=1737"], - "request-id": ["req_011Ca1UB5GRG2rpcG2QBPNKr"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-13T08:39:28Z"], - "anthropic-ratelimit-tokens-remaining": ["26976000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-13T08:39:28Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-13T08:39:28Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-13T08:39:28Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22476000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Mon, 13 Apr 2026 08:39:29 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9eb9290fcd4915ec-TXL"] - }, - "cookies": { - "_cfuvid": "v5ngmdIHQTaROEKShWt2hD5R67.QJMjzZV.534L7.yY-1776069567.961117-1.0.1.1-o0pIZIsz_GgVbjMA93Y8CnwvoH2.umN7_YtmSJ4e1PY" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01LkhALgtSxKzym1r7cKGZWc\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":743,\"cache_creation_input_tokens\":12653,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":12653,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"The\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" workflow is ready! It has a **Manual Trigger** connected to a **\\\"node execution test\\\"** Set node with default configuration.\\n\\nWould you like to\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" test it or make any changes?\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":743,\"cache_creation_input_tokens\":12653,\"cache_read_input_tokens\":0,\"output_tokens\":44}}\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxTGtoQUxndFN4S3p5bTFyN2NLR1pXYyIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjc0MywiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxMjY1MywiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjEyNjUzLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6MSwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0YXJ0CmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RhcnQiLCJpbmRleCI6MCwiY29udGVudF9ibG9jayI6eyJ0eXBlIjoidGV4dCIsInRleHQiOiIifSAgICAgICAgICAgICB9CgpldmVudDogcGluZwpkYXRhOiB7InR5cGUiOiAicGluZyJ9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IlRoZSJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIgd29ya2Zsb3cgaXMgcmVhZHkhIEl0IGhhcyBhICoqTWFudWFsIFRyaWdnZXIqKiBjb25uZWN0ZWQgdG8gYSAqKlwibm9kZSBleGVjdXRpb24gdGVzdFwiKiogU2V0IG5vZGUgd2l0aCBkZWZhdWx0IGNvbmZpZ3VyYXRpb24uXG5cbldvdWxkIHlvdSBsaWtlIHRvIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIgdGVzdCBpdCBvciBtYWtlIGFueSBjaGFuZ2VzPyJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RvcApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0b3AiLCJpbmRleCI6MCAgIH0KCmV2ZW50OiBtZXNzYWdlX2RlbHRhCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2VfZGVsdGEiLCJkZWx0YSI6eyJzdG9wX3JlYXNvbiI6ImVuZF90dXJuIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsfSwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjo3NDMsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MTI2NTMsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJvdXRwdXRfdG9rZW5zIjo0NH19CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgICAgICAgICAgICAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776069601585-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1777373794295-unknown-host-POST-_v1_messages-3dba52c9.json b/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1777373794295-unknown-host-POST-_v1_messages-3dba52c9.json new file mode 100644 index 00000000000..0eb4ad173c6 --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-execute-individual-node-from-node-toolbar/1777373794295-unknown-host-POST-_v1_messages-3dba52c9.json @@ -0,0 +1,105 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde[\\s\\S]* };\n\n/** Edit item fields one by one */\nexport type SetV34ManualParams = {\n mode: 'manual';\n/**\n * Whether this item should be duplicated a set number of times\n * @default false\n */\n duplicateItem?: boolean | Expression;\n/**\n * How many times the item should be duplicated, mainly used for testing and debugging\n * @displayOptions.show { duplicateItem: [true] }\n * @default 0\n */\n duplicateCount?: number | Expression;\n/**\n * Fields to Set\n * @default {}\n */\n assignments?: AssignmentCollectionValue;\n/**\n * Whether to pass to the output all the input fields (along with the fields set in 'Fields to Set')\n * @default false\n */\n includeOtherFields?: boolean | Expression;\n/**\n * How to select the fields you want to include in your output items\n * @displayOptions.hide { /includeOtherFields: [false] }\n * @default all\n */\n include?: 'all' | 'selected' | 'except' | Expression;\n/**\n * Comma-separated list of the field names you want to include in the output. You can drag the selected fields from the input panel.\n * @displayOptions.show { include: [\"selected\"], /includeOtherFields: [true] }\n */\n includeFields?: string | Expression | PlaceholderValue;\n/**\n * Comma-separated list of the field names you want to exclude from the output. You can drag the selected fields from the input panel.\n * @displayOptions.show { include: [\"except\"], /includeOtherFields: [true] }\n */\n excludeFields?: string | Expression | PlaceholderValue;\n options?: {\n /** Whether binary data should be included if present in the input item\n * @default true\n */\n includeBinary?: boolean | Expression;\n /** Whether binary data should be stripped from the input item. Only applies when \"Include Other Input Fields\" is enabled.\n * @displayOptions.show { /includeOtherFields: [true] }\n * @default true\n */\n stripBinary?: boolean | Expression;\n /** Whether to ignore field type errors and apply a less strict type conversion\n * @default false\n */\n ignoreConversionErrors?: boolean | Expression;\n /** By default, dot-notation is used in property names. This means that \"a.b\" will set the property \"b\" underneath \"a\" so { \"a\": { \"b\": value} }. If that is not intended this can be deactivated, it will then set { \"a.b\": value } instead.\n * @default true\n */\n dotNotation?: boolean | Expression;\n };\n};\n\nexport type SetV34ManualNode = {\n type: 'n8n-nodes-base.set';\n version: 3.4;\n config: NodeConfig;\n};"}]}} +{"kind":"tool-call","stepId":9,"agentRole":"workflow-builder","toolName":"build-workflow","input":{"patches":[{"old_str":" parameters: {\n mode: 'passthrough'\n }","new_str":" parameters: {\n mode: 'manual',\n assignments: { assignments: [] },\n includeOtherFields: true,\n include: 'all'\n }"}],"workflowId":"manual-passthrough"},"output":{"success":false,"errors":["Workflow save failed: Workflow not found"]}} +{"kind":"tool-call","stepId":10,"agentRole":"workflow-builder","toolName":"build-workflow","input":{"code":"\nimport { workflow, node, trigger } from '@n8n/workflow-sdk';\n\nconst manualTrigger = trigger({\n type: 'n8n-nodes-base.manualTrigger',\n version: 1,\n config: { name: 'Manual Trigger' }\n});\n\nconst passThrough = node({\n type: 'n8n-nodes-base.set',\n version: 3.4,\n config: {\n name: 'Pass Through',\n parameters: {\n mode: 'manual',\n assignments: { assignments: [] },\n includeOtherFields: true,\n include: 'all'\n }\n }\n});\n\nexport default workflow('manual-passthrough', 'Manual Trigger - Pass Through')\n .add(manualTrigger)\n .to(passThrough);\n","name":"Manual Trigger - Pass Through"},"output":{"success":true,"workflowId":"ifwFrH7k2flyuOB3"}} diff --git a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915171-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915171-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index acef5c5ae39..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915171-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": [ - "1463" - ], - "vary": [ - "Accept-Encoding" - ], - "strict-transport-security": [ - "max-age=31536000; includeSubDomains; preload" - ], - "set-cookie": [ - "_cfuvid=zhABWsOEI4ul0GHN.MUIROjVKXDz00AJi6w7JnHPQGU-1776326886.7942963-1.0.1.1-2JhXBMpbL0r2oXimSdM2OM_ZFr.lfejFbIfgYyDXjKA; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": [ - "x-originResponse;dur=1465" - ], - "request-id": [ - "req_011Ca77D9kvjSfztzgoudtps" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "anthropic-ratelimit-tokens-reset": [ - "2026-04-16T08:08:06Z" - ], - "anthropic-ratelimit-tokens-remaining": [ - "26984000" - ], - "anthropic-ratelimit-tokens-limit": [ - "27000000" - ], - "anthropic-ratelimit-requests-reset": [ - "2026-04-16T08:08:06Z" - ], - "anthropic-ratelimit-requests-remaining": [ - "19998" - ], - "anthropic-ratelimit-requests-limit": [ - "20000" - ], - "anthropic-ratelimit-output-tokens-reset": [ - "2026-04-16T08:08:06Z" - ], - "anthropic-ratelimit-output-tokens-remaining": [ - "4500000" - ], - "anthropic-ratelimit-output-tokens-limit": [ - "4500000" - ], - "anthropic-ratelimit-input-tokens-reset": [ - "2026-04-16T08:08:06Z" - ], - "anthropic-ratelimit-input-tokens-remaining": [ - "22484000" - ], - "anthropic-ratelimit-input-tokens-limit": [ - "22500000" - ], - "X-Robots-Tag": [ - "none" - ], - "Server": [ - "cloudflare" - ], - "Date": [ - "Thu, 16 Apr 2026 08:08:08 GMT" - ], - "Content-Type": [ - "text/event-stream; charset=utf-8" - ], - "Content-Security-Policy": [ - "default-src 'none'; frame-ancestors 'none'" - ], - "Cache-Control": [ - "no-cache" - ], - "CF-RAY": [ - "9ed1b3427bc0e519-TXL" - ] - }, - "cookies": { - "_cfuvid": "zhABWsOEI4ul0GHN.MUIROjVKXDz00AJi6w7JnHPQGU-1776326886.7942963-1.0.1.1-2JhXBMpbL0r2oXimSdM2OM_ZFr.lfejFbIfgYyDXjKA" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_013j5sDcVUkDAT49eD4CXPbm\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":359,\"cache_creation_input_tokens\":8955,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":8955,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":40,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01Do5GeQQmDLyENtvLpgrnkD\",\"name\":\"build-workflow-with-agent\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"task\\\": \\\"Bu\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ild a\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" wor\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"kflow wit\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"h:\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n1. A\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Manual Trig\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ger node\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n2. A \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Wa\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"it \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"node se\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t to 1 \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"second\\\\n3. \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"A Set node\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" named \\\\\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"runnin\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"g s\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tate tes\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t\\\\\\\"\\\\n\\\\nCo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nnect them \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"in \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"or\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"de\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"r: Man\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ual Tri\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"gger \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"→ \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Wai\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t (1 sec\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ond)\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" → Set node \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"(\\\\\\\"runn\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ing state t\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"est\\\\\\\")\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"con\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"versationCo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ntext\\\": \\\"U\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ser \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"wants a\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" sim\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ple\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" 3-\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"node \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"workflow: Ma\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nua\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"l Tri\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"gg\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"er\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" → Wait (\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"1 s\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"econd) \"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"→ Set node\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" named \\\\\\\"ru\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nni\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ng \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"state test\\\\\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\". Af\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ter\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" building, t\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"hey want\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" t\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"o run it\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\".\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":359,\"cache_creation_input_tokens\":8955,\"cache_read_input_tokens\":0,\"output_tokens\":173} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxM2o1c0RjVlVrREFUNDllRDRDWFBibSIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjM1OSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjo4OTU1LCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfY3JlYXRpb24iOnsiZXBoZW1lcmFsXzVtX2lucHV0X3Rva2VucyI6ODk1NSwiZXBoZW1lcmFsXzFoX2lucHV0X3Rva2VucyI6MH0sIm91dHB1dF90b2tlbnMiOjQwLCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0b29sX3VzZSIsImlkIjoidG9vbHVfMDFEbzVHZVFRbURMeUVOdHZMcGdybmtEIiwibmFtZSI6ImJ1aWxkLXdvcmtmbG93LXdpdGgtYWdlbnQiLCJpbnB1dCI6e30sImNhbGxlciI6eyJ0eXBlIjoiZGlyZWN0In19ICAgICAgICAgfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoie1widGFza1wiOiBcIkJ1In0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpbGQgYSJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIHdvciJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImtmbG93IHdpdCJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Img6In0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlxcbjEuIEEifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgTWFudWFsIFRyaWcifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJnZXIgbm9kZVxcIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibjIuIEEgIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJXYSJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpdCAifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibm9kZSBzZSJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0IHRvIDEgIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InNlY29uZFxcbjMuICJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJBIFNldCBub2RlIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgbmFtZWQgXFxcIiJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJydW5uaW4ifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImcgcyJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0YXRlIHRlcyJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InRcXFwiXFxuXFxuQ28ifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im5uZWN0IHRoZW0gIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImluICJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoib3IifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJkZSJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InI6IE1hbiJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InVhbCBUcmkifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJnZ2VyICJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiLihpIgIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiV2FpIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidCAoMSBzZWMifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoib25kKSJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIg4oaSIFNldCBub2RlICJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiKFxcXCJydW5uIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImluZyBzdGF0ZSB0In0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZXN0XFxcIilcIiJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiwgXCJjb24ifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InZlcnNhdGlvbkNvIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibnRleHRcIjogXCJVIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJzZXIgIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ3YW50cyBhIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgc2ltIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InBsZSJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIDMtIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibm9kZSAifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoid29ya2Zsb3c6IE1hIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibnVhIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibCBUcmkifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZ2cifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVyIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiDihpIgV2FpdCAoIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiMSBzIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZWNvbmQpICJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IuKGkiBTZXQgbm9kZSJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBuYW1lZCBcXFwicnUifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJubmkifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibmcgIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoic3RhdGUgdGVzdFxcXCIifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIuIEFmIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidGVyIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgYnVpbGRpbmcsIHQifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJoZXkgd2FudCJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIHQifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im8gcnVuIGl0In0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Ii5cIn0ifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjAgICAgICAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX2RlbHRhCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2VfZGVsdGEiLCJkZWx0YSI6eyJzdG9wX3JlYXNvbiI6InRvb2xfdXNlIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsfSwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjozNTksImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6ODk1NSwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsIm91dHB1dF90b2tlbnMiOjE3M30gICAgfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICAgIH0KCg==", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776326915171-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915172-unknown-host-POST-_v1_messages-4d1c93f7.json b/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915172-unknown-host-POST-_v1_messages-4d1c93f7.json deleted file mode 100644 index 74ca3bba04a..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915172-unknown-host-POST-_v1_messages-4d1c93f7.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are an expert n8n workflow builder. You generate com", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": [ - "1642" - ], - "strict-transport-security": [ - "max-age=31536000; includeSubDomains; preload" - ], - "set-cookie": [ - "_cfuvid=..VlN8clyjK_bTMXRqssxRLjqgMfbHT53uuiPN59YfU-1776326890.6291292-1.0.1.1-4Wu8NLEBuhl2M0uxKG6Foeyt.QD6aN0G40B5e.MGqwA; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": [ - "x-originResponse;dur=1645" - ], - "request-id": [ - "req_011Ca77DSK5vDhmuSxjeVro5" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "anthropic-ratelimit-tokens-reset": [ - "2026-04-16T08:08:10Z" - ], - "anthropic-ratelimit-tokens-remaining": [ - "26966000" - ], - "anthropic-ratelimit-tokens-limit": [ - "27000000" - ], - "anthropic-ratelimit-requests-reset": [ - "2026-04-16T08:08:10Z" - ], - "anthropic-ratelimit-requests-remaining": [ - "19998" - ], - "anthropic-ratelimit-requests-limit": [ - "20000" - ], - "anthropic-ratelimit-output-tokens-reset": [ - "2026-04-16T08:08:10Z" - ], - "anthropic-ratelimit-output-tokens-remaining": [ - "4500000" - ], - "anthropic-ratelimit-output-tokens-limit": [ - "4500000" - ], - "anthropic-ratelimit-input-tokens-reset": [ - "2026-04-16T08:08:10Z" - ], - "anthropic-ratelimit-input-tokens-remaining": [ - "22466000" - ], - "anthropic-ratelimit-input-tokens-limit": [ - "22500000" - ], - "X-Robots-Tag": [ - "none" - ], - "Server": [ - "cloudflare" - ], - "Date": [ - "Thu, 16 Apr 2026 08:08:12 GMT" - ], - "Content-Type": [ - "text/event-stream; charset=utf-8" - ], - "Content-Security-Policy": [ - "default-src 'none'; frame-ancestors 'none'" - ], - "Cache-Control": [ - "no-cache" - ], - "CF-RAY": [ - "9ed1b35a6fb8236c-TXL" - ] - }, - "cookies": { - "_cfuvid": "..VlN8clyjK_bTMXRqssxRLjqgMfbHT53uuiPN59YfU-1776326890.6291292-1.0.1.1-4Wu8NLEBuhl2M0uxKG6Foeyt.QD6aN0G40B5e.MGqwA" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_015kyUMcYmMoWAtL3DFGzNa6\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":442,\"cache_creation_input_tokens\":22307,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":22307,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":47,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_014MVFSCerb4gnLWN5biDLqJ\",\"name\":\"nodes\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"act\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ion\\\": \\\"searc\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"h\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"query\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\": \"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"Wait\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":442,\"cache_creation_input_tokens\":22307,\"cache_read_input_tokens\":0,\"output_tokens\":69} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxNWt5VU1jWW1Nb1dBdEwzREZHek5hNiIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjQ0MiwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoyMjMwNywiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjIyMzA3LCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6NDcsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0YXJ0CmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RhcnQiLCJpbmRleCI6MCwiY29udGVudF9ibG9jayI6eyJ0eXBlIjoidG9vbF91c2UiLCJpZCI6InRvb2x1XzAxNE1WRlNDZXJiNGduTFdONWJpRExxSiIsIm5hbWUiOiJub2RlcyIsImlucHV0Ijp7fSwiY2FsbGVyIjp7InR5cGUiOiJkaXJlY3QifX0gICAgICAgICAgfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ7XCJhY3QifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImlvblwiOiBcInNlYXJjIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImhcIiJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiLCBcInF1ZXJ5In0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXCI6ICJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlwiV2FpdFwifSJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowIH0KCmV2ZW50OiBtZXNzYWdlX2RlbHRhCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2VfZGVsdGEiLCJkZWx0YSI6eyJzdG9wX3JlYXNvbiI6InRvb2xfdXNlIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsfSwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjo0NDIsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MjIzMDcsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJvdXRwdXRfdG9rZW5zIjo2OX0gICAgfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICAgICAgICAgICAgICAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776326915172-unknown-host-POST-_v1_messages-4d1c93f7.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915172-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915172-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index eef07234d82..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915172-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": [ - "2183" - ], - "vary": [ - "Accept-Encoding" - ], - "strict-transport-security": [ - "max-age=31536000; includeSubDomains; preload" - ], - "set-cookie": [ - "_cfuvid=1468sIq7EUG8SFohFZ3H5a2ZBplTdox4uAkVIxqVczQ-1776326890.5143433-1.0.1.1-6LAxltPoGqY3yzFKQwxGzbnVWD3k4xTUIVFpe3BPJ9g; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": [ - "x-originResponse;dur=2185" - ], - "request-id": [ - "req_011Ca77DRk6wAxYoHc6Za7aD" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "anthropic-ratelimit-tokens-reset": [ - "2026-04-16T08:08:10Z" - ], - "anthropic-ratelimit-tokens-remaining": [ - "26983000" - ], - "anthropic-ratelimit-tokens-limit": [ - "27000000" - ], - "anthropic-ratelimit-requests-reset": [ - "2026-04-16T08:08:10Z" - ], - "anthropic-ratelimit-requests-remaining": [ - "19998" - ], - "anthropic-ratelimit-requests-limit": [ - "20000" - ], - "anthropic-ratelimit-output-tokens-reset": [ - "2026-04-16T08:08:10Z" - ], - "anthropic-ratelimit-output-tokens-remaining": [ - "4500000" - ], - "anthropic-ratelimit-output-tokens-limit": [ - "4500000" - ], - "anthropic-ratelimit-input-tokens-reset": [ - "2026-04-16T08:08:10Z" - ], - "anthropic-ratelimit-input-tokens-remaining": [ - "22483000" - ], - "anthropic-ratelimit-input-tokens-limit": [ - "22500000" - ], - "X-Robots-Tag": [ - "none" - ], - "Server": [ - "cloudflare" - ], - "Date": [ - "Thu, 16 Apr 2026 08:08:12 GMT" - ], - "Content-Type": [ - "text/event-stream; charset=utf-8" - ], - "Content-Security-Policy": [ - "default-src 'none'; frame-ancestors 'none'" - ], - "Cache-Control": [ - "no-cache" - ], - "CF-RAY": [ - "9ed1b359bc0c124d-TXL" - ] - }, - "cookies": { - "_cfuvid": "1468sIq7EUG8SFohFZ3H5a2ZBplTdox4uAkVIxqVczQ-1776326890.5143433-1.0.1.1-6LAxltPoGqY3yzFKQwxGzbnVWD3k4xTUIVFpe3BPJ9g" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_013U1b85Uq7wXGkFccdGg6Me\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":604,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":8955,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Building\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" your workflow now — Manual Trigger → Wait (1s) → \\\"running state test\\\".\"}}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01TLvhg4diWEUPMmR8hDu7wB\",\"name\":\"task-control\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"action\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\": \\\"up\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"date-\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"che\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ckli\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"st\\\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"ta\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"sks\\\": [{\\\"id\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\":\\\"buil\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"d\\\",\\\"de\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"scription\\\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\":\\\"Bui\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ld w\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"orkflow\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": Manual Tri\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"gger → Wait\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" (1s\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\") \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"→ Set nod\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e\\\",\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"status\\\":\\\"in\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"_progr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ess\\\"},{\\\"id\\\":\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"r\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"un\\\",\\\"des\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"cr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ip\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ti\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"on\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\":\\\"Run the w\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"orkflow aft\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"er bui\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ld\\\",\\\"s\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tatus\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\":\\\"t\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"odo\\\"}]}\"}}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":604,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":8955,\"output_tokens\":141} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxM1UxYjg1VXE3d1hHa0ZjY2RHZzZNZSIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjYwNCwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6ODk1NSwiY2FjaGVfY3JlYXRpb24iOnsiZXBoZW1lcmFsXzVtX2lucHV0X3Rva2VucyI6MCwiZXBoZW1lcmFsXzFoX2lucHV0X3Rva2VucyI6MH0sIm91dHB1dF90b2tlbnMiOjEsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0YXJ0CmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RhcnQiLCJpbmRleCI6MCwiY29udGVudF9ibG9jayI6eyJ0eXBlIjoidGV4dCIsInRleHQiOiIifX0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiQnVpbGRpbmcifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiIHlvdXIgd29ya2Zsb3cgbm93IOKAlCBNYW51YWwgVHJpZ2dlciDihpIgV2FpdCAoMXMpIOKGkiBcInJ1bm5pbmcgc3RhdGUgdGVzdFwiLiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RvcApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0b3AiLCJpbmRleCI6MCAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjEsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRvb2xfdXNlIiwiaWQiOiJ0b29sdV8wMVRMdmhnNGRpV0VVUE1tUjhoRHU3d0IiLCJuYW1lIjoidGFzay1jb250cm9sIiwiaW5wdXQiOnt9LCJjYWxsZXIiOnsidHlwZSI6ImRpcmVjdCJ9fSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ7XCJhY3Rpb24ifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXCI6IFwidXAifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImRhdGUtIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJjaGUifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJja2xpIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoic3RcIiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiwgXCJ0YSJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InNrc1wiOiBbe1wiaWQifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXCI6XCJidWlsIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJkXCIsXCJkZSJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJzY3JpcHRpb25cIiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IjpcIkJ1aSJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImxkIHcifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9ya2Zsb3cifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiOiBNYW51YWwgVHJpIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZ2dlciDihpIgV2FpdCJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgKDFzIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIpICJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoi4oaSIFNldCBub2QifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVcIixcIiJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJzdGF0dXNcIjpcImluIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Il9wcm9nciJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVzc1wifSx7XCJpZFwiOiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlwiciJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ1blwiLFwiZGVzIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImNyIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiaXAifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0aSJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoib25cIiJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiI6XCJSdW4gdGhlIHcifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9ya2Zsb3cgYWZ0In0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZXIgYnVpIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImxkXCIsXCJzIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0YXR1c1wiIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiOlwidCJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoib2RvXCJ9XX0ifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjEgICAgICAgICAgICAgICB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJ0b29sX3VzZSIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6NjA0LCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjo4OTU1LCJvdXRwdXRfdG9rZW5zIjoxNDF9ICAgICAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX3N0b3AKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdG9wIiAgICAgICB9Cgo=", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776326915172-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915173-unknown-host-POST-_v1_messages-4d1c93f7.json b/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915173-unknown-host-POST-_v1_messages-4d1c93f7.json deleted file mode 100644 index a3a63e05ed5..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915173-unknown-host-POST-_v1_messages-4d1c93f7.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are an expert n8n workflow builder. You generate com", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": [ - "1835" - ], - "strict-transport-security": [ - "max-age=31536000; includeSubDomains; preload" - ], - "set-cookie": [ - "_cfuvid=59uzNzzcyNzkg0JlF.3rzDZsIthkyqtpvQtwlWZAbQ4-1776326892.9713426-1.0.1.1-APRFIItLNOfxlL5o6.3xCYSu21J4G00sxWqyZVu2OO4; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": [ - "x-originResponse;dur=1836" - ], - "request-id": [ - "req_011Ca77DcGd9BRWCPvu7mE1D" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "anthropic-ratelimit-tokens-reset": [ - "2026-04-16T08:08:13Z" - ], - "anthropic-ratelimit-tokens-remaining": [ - "26966000" - ], - "anthropic-ratelimit-tokens-limit": [ - "27000000" - ], - "anthropic-ratelimit-requests-reset": [ - "2026-04-16T08:08:13Z" - ], - "anthropic-ratelimit-requests-remaining": [ - "19998" - ], - "anthropic-ratelimit-requests-limit": [ - "20000" - ], - "anthropic-ratelimit-output-tokens-reset": [ - "2026-04-16T08:08:13Z" - ], - "anthropic-ratelimit-output-tokens-remaining": [ - "4500000" - ], - "anthropic-ratelimit-output-tokens-limit": [ - "4500000" - ], - "anthropic-ratelimit-input-tokens-reset": [ - "2026-04-16T08:08:13Z" - ], - "anthropic-ratelimit-input-tokens-remaining": [ - "22466000" - ], - "anthropic-ratelimit-input-tokens-limit": [ - "22500000" - ], - "X-Robots-Tag": [ - "none" - ], - "Server": [ - "cloudflare" - ], - "Date": [ - "Thu, 16 Apr 2026 08:08:14 GMT" - ], - "Content-Type": [ - "text/event-stream; charset=utf-8" - ], - "Content-Security-Policy": [ - "default-src 'none'; frame-ancestors 'none'" - ], - "Cache-Control": [ - "no-cache" - ], - "CF-RAY": [ - "9ed1b36918c9e529-TXL" - ] - }, - "cookies": { - "_cfuvid": "59uzNzzcyNzkg0JlF.3rzDZsIthkyqtpvQtwlWZAbQ4-1776326892.9713426-1.0.1.1-APRFIItLNOfxlL5o6.3xCYSu21J4G00sxWqyZVu2OO4" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01QcX5XqghaDuydR6XeemeQc\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":4923,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":22307,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":53,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01JNrTGTHTnDYVNE9VPnwgva\",\"name\":\"nodes\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"acti\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"on\\\": \\\"de\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"scrib\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"nodeT\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ype\\\": \\\"n8n-\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nod\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"es-bas\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e.w\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ait\\\"}\"}}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":4923,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":22307,\"output_tokens\":77} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxUWNYNVhxZ2hhRHV5ZFI2WGVlbWVRYyIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjQ5MjMsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjIyMzA3LCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjowLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6NTMsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0b29sX3VzZSIsImlkIjoidG9vbHVfMDFKTnJUR1RIVG5EWVZORTlWUG53Z3ZhIiwibmFtZSI6Im5vZGVzIiwiaW5wdXQiOnt9LCJjYWxsZXIiOnsidHlwZSI6ImRpcmVjdCJ9fSAgICAgICB9CgpldmVudDogcGluZwpkYXRhOiB7InR5cGUiOiAicGluZyJ9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoie1wiYWN0aSJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoib25cIjogXCJkZSJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoic2NyaWIifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZVwiIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiwgIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Ilwibm9kZVQifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ5cGVcIjogXCJuOG4tIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibm9kIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVzLWJhcyJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImUudyJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhaXRcIn0ifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJ0b29sX3VzZSIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6NDkyMywiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MjIzMDcsIm91dHB1dF90b2tlbnMiOjc3fSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX3N0b3AKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdG9wIiAgICAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776326915173-unknown-host-POST-_v1_messages-4d1c93f7.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915174-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915174-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index 9d66be61c94..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915174-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": [ - "1497" - ], - "strict-transport-security": [ - "max-age=31536000; includeSubDomains; preload" - ], - "set-cookie": [ - "_cfuvid=qgI4FIzwqXadnTLWsJmllLOfXt8zYxhGVptmjHGnWcg-1776326894.7148116-1.0.1.1-jqy56mBAG.0rWQ.O0IroXy4ircpv8Ahgbp.ZM0sHsEk; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": [ - "x-originResponse;dur=1500" - ], - "request-id": [ - "req_011Ca77DjfNBm9hgTYQjEy5D" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "anthropic-ratelimit-tokens-reset": [ - "2026-04-16T08:08:14Z" - ], - "anthropic-ratelimit-tokens-remaining": [ - "26983000" - ], - "anthropic-ratelimit-tokens-limit": [ - "27000000" - ], - "anthropic-ratelimit-requests-reset": [ - "2026-04-16T08:08:14Z" - ], - "anthropic-ratelimit-requests-remaining": [ - "19998" - ], - "anthropic-ratelimit-requests-limit": [ - "20000" - ], - "anthropic-ratelimit-output-tokens-reset": [ - "2026-04-16T08:08:14Z" - ], - "anthropic-ratelimit-output-tokens-remaining": [ - "4500000" - ], - "anthropic-ratelimit-output-tokens-limit": [ - "4500000" - ], - "anthropic-ratelimit-input-tokens-reset": [ - "2026-04-16T08:08:14Z" - ], - "anthropic-ratelimit-input-tokens-remaining": [ - "22483000" - ], - "anthropic-ratelimit-input-tokens-limit": [ - "22500000" - ], - "X-Robots-Tag": [ - "none" - ], - "Server": [ - "cloudflare" - ], - "Date": [ - "Thu, 16 Apr 2026 08:08:16 GMT" - ], - "Content-Type": [ - "text/event-stream; charset=utf-8" - ], - "Content-Security-Policy": [ - "default-src 'none'; frame-ancestors 'none'" - ], - "Cache-Control": [ - "no-cache" - ], - "CF-RAY": [ - "9ed1b373fcd9e522-TXL" - ] - }, - "cookies": { - "_cfuvid": "qgI4FIzwqXadnTLWsJmllLOfXt8zYxhGVptmjHGnWcg-1776326894.7148116-1.0.1.1-jqy56mBAG.0rWQ.O0IroXy4ircpv8Ahgbp.ZM0sHsEk" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01C1bwYer9FH2zAH2Ls8LXJA\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":780,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":8955,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":57,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01R5L63JSJXXD6FAUrPSRUyM\",\"name\":\"workflows\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"ac\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tion\\\": \\\"g\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"et\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"workfl\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"owId\\\": \\\"b\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"uild-6LEDN\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"gVD\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":780,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":8955,\"output_tokens\":79} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxQzFid1llcjlGSDJ6QUgyTHM4TFhKQSIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjc4MCwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6ODk1NSwiY2FjaGVfY3JlYXRpb24iOnsiZXBoZW1lcmFsXzVtX2lucHV0X3Rva2VucyI6MCwiZXBoZW1lcmFsXzFoX2lucHV0X3Rva2VucyI6MH0sIm91dHB1dF90b2tlbnMiOjU3LCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0b29sX3VzZSIsImlkIjoidG9vbHVfMDFSNUw2M0pTSlhYRDZGQVVyUFNSVXlNIiwibmFtZSI6IndvcmtmbG93cyIsImlucHV0Ijp7fSwiY2FsbGVyIjp7InR5cGUiOiJkaXJlY3QifX0gICAgICAgICAgICAgIH0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ7XCJhYyJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InRpb25cIjogXCJnIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJldFwiIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiwgXCJ3b3JrZmwifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im93SWRcIjogXCJiIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ1aWxkLTZMRUROIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJnVkQifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcIn0ifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RvcApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0b3AiLCJpbmRleCI6MCAgICAgICB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJ0b29sX3VzZSIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6NzgwLCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjo4OTU1LCJvdXRwdXRfdG9rZW5zIjo3OX0gICB9CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgICAgICAgICAgICAgICB9Cgo=", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776326915174-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915175-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915175-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index 790e0b05b70..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915175-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": [ - "1452" - ], - "vary": [ - "Accept-Encoding" - ], - "strict-transport-security": [ - "max-age=31536000; includeSubDomains; preload" - ], - "set-cookie": [ - "_cfuvid=poJI4hn03OkM53IZXJliJIgM.R8sjmxY6CEGTsQOgWs-1776326898.7971935-1.0.1.1-DAuZBgB9AEPcnNtojU2A1Qe_tijFhw64IPDpQjMYrPo; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": [ - "x-originResponse;dur=1454" - ], - "request-id": [ - "req_011Ca77E3589q5GZ3vpfEV3X" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "anthropic-ratelimit-tokens-reset": [ - "2026-04-16T08:08:18Z" - ], - "anthropic-ratelimit-tokens-remaining": [ - "26983000" - ], - "anthropic-ratelimit-tokens-limit": [ - "27000000" - ], - "anthropic-ratelimit-requests-reset": [ - "2026-04-16T08:08:18Z" - ], - "anthropic-ratelimit-requests-remaining": [ - "19998" - ], - "anthropic-ratelimit-requests-limit": [ - "20000" - ], - "anthropic-ratelimit-output-tokens-reset": [ - "2026-04-16T08:08:18Z" - ], - "anthropic-ratelimit-output-tokens-remaining": [ - "4500000" - ], - "anthropic-ratelimit-output-tokens-limit": [ - "4500000" - ], - "anthropic-ratelimit-input-tokens-reset": [ - "2026-04-16T08:08:18Z" - ], - "anthropic-ratelimit-input-tokens-remaining": [ - "22483000" - ], - "anthropic-ratelimit-input-tokens-limit": [ - "22500000" - ], - "X-Robots-Tag": [ - "none" - ], - "Server": [ - "cloudflare" - ], - "Date": [ - "Thu, 16 Apr 2026 08:08:20 GMT" - ], - "Content-Type": [ - "text/event-stream; charset=utf-8" - ], - "Content-Security-Policy": [ - "default-src 'none'; frame-ancestors 'none'" - ], - "Cache-Control": [ - "no-cache" - ], - "CF-RAY": [ - "9ed1b38d7b97dcd9-TXL" - ] - }, - "cookies": { - "_cfuvid": "poJI4hn03OkM53IZXJliJIgM.R8sjmxY6CEGTsQOgWs-1776326898.7971935-1.0.1.1-DAuZBgB9AEPcnNtojU2A1Qe_tijFhw64IPDpQjMYrPo" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01KMvGWfHt4qQ8kQbDJEPpgx\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":982,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":8955,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":59,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01MDWCzo5GFiWx1rcqDzsgjY\",\"name\":\"workflows\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"a\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ct\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ion\\\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"list\\\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"limit\\\": 5}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":982,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":8955,\"output_tokens\":68} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxS012R1dmSHQ0cVE4a1FiREpFUHBneCIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjk4MiwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6ODk1NSwiY2FjaGVfY3JlYXRpb24iOnsiZXBoZW1lcmFsXzVtX2lucHV0X3Rva2VucyI6MCwiZXBoZW1lcmFsXzFoX2lucHV0X3Rva2VucyI6MH0sIm91dHB1dF90b2tlbnMiOjU5LCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0b29sX3VzZSIsImlkIjoidG9vbHVfMDFNRFdDem81R0ZpV3gxcmNxRHpzZ2pZIiwibmFtZSI6IndvcmtmbG93cyIsImlucHV0Ijp7fSwiY2FsbGVyIjp7InR5cGUiOiJkaXJlY3QifX0gICAgICAgICB9CgpldmVudDogcGluZwpkYXRhOiB7InR5cGUiOiAicGluZyJ9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoie1wiYSJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJjdCJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpb25cIjogIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcImxpc3RcIiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiwgIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXCJsaW1pdFwiOiA1fSJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RvcApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0b3AiLCJpbmRleCI6MCAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoidG9vbF91c2UiLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjk4MiwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6ODk1NSwib3V0cHV0X3Rva2VucyI6Njh9ICAgICAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX3N0b3AKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdG9wIiAgICAgICAgICB9Cgo=", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776326915175-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915176-unknown-host-POST-_v1_messages-4d1c93f7.json b/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915176-unknown-host-POST-_v1_messages-4d1c93f7.json deleted file mode 100644 index d70d17d1b9e..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915176-unknown-host-POST-_v1_messages-4d1c93f7.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are an expert n8n workflow builder. You generate com", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": [ - "1570" - ], - "vary": [ - "Accept-Encoding" - ], - "strict-transport-security": [ - "max-age=31536000; includeSubDomains; preload" - ], - "set-cookie": [ - "_cfuvid=XhcgYvfMpg1g3R1JTEhHtSNNvjlVP6UDboC2NE4kpJE-1776326895.2788043-1.0.1.1-IjEs6dygrWOsk8NLcTehumInEcuYuUGESmCSfl8fn4c; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": [ - "x-originResponse;dur=1572" - ], - "request-id": [ - "req_011Ca77DnCAkzgbCNAonAr1D" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "anthropic-ratelimit-tokens-reset": [ - "2026-04-16T08:08:15Z" - ], - "anthropic-ratelimit-tokens-remaining": [ - "26966000" - ], - "anthropic-ratelimit-tokens-limit": [ - "27000000" - ], - "anthropic-ratelimit-requests-reset": [ - "2026-04-16T08:08:15Z" - ], - "anthropic-ratelimit-requests-remaining": [ - "19998" - ], - "anthropic-ratelimit-requests-limit": [ - "20000" - ], - "anthropic-ratelimit-output-tokens-reset": [ - "2026-04-16T08:08:15Z" - ], - "anthropic-ratelimit-output-tokens-remaining": [ - "4500000" - ], - "anthropic-ratelimit-output-tokens-limit": [ - "4500000" - ], - "anthropic-ratelimit-input-tokens-reset": [ - "2026-04-16T08:08:15Z" - ], - "anthropic-ratelimit-input-tokens-remaining": [ - "22466000" - ], - "anthropic-ratelimit-input-tokens-limit": [ - "22500000" - ], - "X-Robots-Tag": [ - "none" - ], - "Server": [ - "cloudflare" - ], - "Date": [ - "Thu, 16 Apr 2026 08:08:16 GMT" - ], - "Content-Type": [ - "text/event-stream; charset=utf-8" - ], - "Content-Security-Policy": [ - "default-src 'none'; frame-ancestors 'none'" - ], - "Cache-Control": [ - "no-cache" - ], - "CF-RAY": [ - "9ed1b3777e31469d-TXL" - ] - }, - "cookies": { - "_cfuvid": "XhcgYvfMpg1g3R1JTEhHtSNNvjlVP6UDboC2NE4kpJE-1776326895.2788043-1.0.1.1-IjEs6dygrWOsk8NLcTehumInEcuYuUGESmCSfl8fn4c" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01HJnmU1V9vftaYh7BaTjZDv\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":7226,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":22307,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":33,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01Potyv4foqYGN4ke1hoBTs6\",\"name\":\"build-workflow\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"name\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\": \\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Man\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ual \"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Trigger -\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Wait - S\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"et\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"code\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"im\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"port { workf\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"lo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"w, node, tr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ig\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ge\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"r } from '@n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"8n/wor\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"kf\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"low-sd\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"k'\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\";\\\\n\\\\nconst \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"manu\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"alTri\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"gger = \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"trigger({\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" type: '\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n8n-nodes-ba\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"se.\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"manualTrigge\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"r',\\\\n versi\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"on: 1,\\\\n\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" config: \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{ name: 'Man\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ual Trigger'\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" }\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"});\\\\\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n\\\\nc\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ons\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t wai\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tNode \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"= \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"node({\\\\n t\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ype: 'n8n-n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"od\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"es-base.\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"wait\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"',\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n version:\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" 1.1,\\\\n co\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nf\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ig: {\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" name: 'W\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ait',\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n par\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ameters: \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" res\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ume: 'ti\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"meI\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nterval',\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"amount: \"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"1,\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n un\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"it: \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"'seconds'\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" }\\\\n }\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n});\\\\n\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nconst\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" setNod\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e = node(\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" type: \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"'n8n-no\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"des-base.se\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t',\\\\n ver\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"sion: 3.4,\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n \"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"config:\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" {\\\\n n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ame: 'runnin\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"g state tes\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t',\\\\n par\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ameters: {}\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n }\\\\n}\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\");\\\\n\\\\ne\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"xpor\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"default \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"workflow('ru\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nning-stat\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e-test', \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"'Manual \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Trigger \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"- Wait -\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Set')\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n .add\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"(manualTrigg\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"er)\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\".to(w\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ai\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tNod\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e)\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" .t\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"o(setNode);\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":7226,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":22307,\"output_tokens\":334}}\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxSEpubVUxVjl2ZnRhWWg3QmFUalpEdiIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjcyMjYsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjIyMzA3LCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjowLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6MzMsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0b29sX3VzZSIsImlkIjoidG9vbHVfMDFQb3R5djRmb3FZR040a2UxaG9CVHM2IiwibmFtZSI6ImJ1aWxkLXdvcmtmbG93IiwiaW5wdXQiOnt9LCJjYWxsZXIiOnsidHlwZSI6ImRpcmVjdCJ9fSAgICAgICAgICAgICB9CgpldmVudDogcGluZwpkYXRhOiB7InR5cGUiOiAicGluZyJ9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IntcIm5hbWUifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcIjogXCIifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJNYW4ifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InVhbCAifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJUcmlnZ2VyIC0ifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBXYWl0IC0gUyJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImV0XCIifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIsIFwiY29kZSJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlwiOiAifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlwiaW0ifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJwb3J0IHsgd29ya2YifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibG8ifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidywgbm9kZSwgdHIifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImlnIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImdlIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiciB9IGZyb20gJ0BuIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IjhuL3dvciJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJrZiJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Imxvdy1zZCJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImsnIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IjtcXG5cXG5jb25zdCAifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibWFudSJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImFsVHJpIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJnZ2VyID0gIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InRyaWdnZXIoe1xcbiJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgIHR5cGU6ICcifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibjhuLW5vZGVzLWJhIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoic2UuIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im1hbnVhbFRyaWdnZSJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoicicsXFxuICB2ZXJzaSJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9uOiAxLFxcbiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiAgY29uZmlnOiAifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InsgbmFtZTogJ01hbiJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ1YWwgVHJpZ2dlcicifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgfVxcbiJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6In0pO1xcIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiblxcbmMifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9ucyJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidCB3YWkifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0Tm9kZSAifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiI9ICJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibm9kZSh7XFxuICB0In0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoieXBlOiAnbjhuLW4ifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvZCJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVzLWJhc2UuIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoid2FpdCJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IicsXFwifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuICB2ZXJzaW9uOiJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIDEuMSxcXG4gIGNvIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im5mIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImlnOiB7XFxuIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgICAgbmFtZTogJ1cifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImFpdCcsXFwifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuICAgIHBhciJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhbWV0ZXJzOiAifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoie1xcIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuICAgICJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiAgcmVzIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ1bWU6ICd0aSJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im1lSSJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibnRlcnZhbCcsXFwifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im4gICAgICAifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiYW1vdW50OiAifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIxLCJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcXG4gICAgICB1biJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpdDogIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiJ3NlY29uZHMnIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcXG4gICAifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiB9XFxuICB9In0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcXG59KTtcXG5cXCJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im5jb25zdCJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIHNldE5vZCJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZSA9IG5vZGUoIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ7XFxuICJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgdHlwZTogIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiJ244bi1ubyJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZGVzLWJhc2Uuc2UifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InQnLFxcbiAgdmVyIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoic2lvbjogMy40LCJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXFxuICAifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJjb25maWc6In0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiB7XFxuICAgIG4ifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhbWU6ICdydW5uaW4ifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZyBzdGF0ZSB0ZXMifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidCcsXFxuICAgIHBhciJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImFtZXRlcnM6IHt9In0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlxcbiAgfVxcbn0ifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiKTtcXG5cXG5lIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoieHBvciJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0ICJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJkZWZhdWx0ICJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IndvcmtmbG93KCdydSJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibm5pbmctc3RhdCJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlLXRlc3QnLCAifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IidNYW51YWwgIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlRyaWdnZXIgIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiItIFdhaXQgLSJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgU2V0JylcXCJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibiAgLmFkZCJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IihtYW51YWxUcmlnZyJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlcilcXG4gICJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiLnRvKHcifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhaSJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InROb2QifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZSlcXG4gIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIC50In0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvKHNldE5vZGUpOyJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcXG5cIn0ifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX2RlbHRhCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2VfZGVsdGEiLCJkZWx0YSI6eyJzdG9wX3JlYXNvbiI6InRvb2xfdXNlIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsfSwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjo3MjI2LCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjoyMjMwNywib3V0cHV0X3Rva2VucyI6MzM0fX0KCmV2ZW50OiBtZXNzYWdlX3N0b3AKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdG9wIiAgICAgICAgICAgICB9Cgo=", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776326915176-unknown-host-POST-_v1_messages-4d1c93f7.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915177-unknown-host-POST-_v1_messages-4d1c93f7.json b/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915177-unknown-host-POST-_v1_messages-4d1c93f7.json deleted file mode 100644 index 108bba711a2..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915177-unknown-host-POST-_v1_messages-4d1c93f7.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are an expert n8n workflow builder. You generate com", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": [ - "1005" - ], - "strict-transport-security": [ - "max-age=31536000; includeSubDomains; preload" - ], - "set-cookie": [ - "_cfuvid=HVzbAkrn0OkkhKxFzQS2TP4_tJI5uG95Zf.eyxR.uUE-1776326901.3371863-1.0.1.1-MIJBDLji7RI9Y.eD0FN94A2T7vdNraR6kzvxZxBtNhA; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": [ - "x-originResponse;dur=1007" - ], - "request-id": [ - "req_011Ca77EE1wVDnfsncTv1ZKA" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "anthropic-ratelimit-tokens-reset": [ - "2026-04-16T08:08:21Z" - ], - "anthropic-ratelimit-tokens-remaining": [ - "26965000" - ], - "anthropic-ratelimit-tokens-limit": [ - "27000000" - ], - "anthropic-ratelimit-requests-reset": [ - "2026-04-16T08:08:21Z" - ], - "anthropic-ratelimit-requests-remaining": [ - "19998" - ], - "anthropic-ratelimit-requests-limit": [ - "20000" - ], - "anthropic-ratelimit-output-tokens-reset": [ - "2026-04-16T08:08:21Z" - ], - "anthropic-ratelimit-output-tokens-remaining": [ - "4500000" - ], - "anthropic-ratelimit-output-tokens-limit": [ - "4500000" - ], - "anthropic-ratelimit-input-tokens-reset": [ - "2026-04-16T08:08:21Z" - ], - "anthropic-ratelimit-input-tokens-remaining": [ - "22465000" - ], - "anthropic-ratelimit-input-tokens-limit": [ - "22500000" - ], - "X-Robots-Tag": [ - "none" - ], - "Server": [ - "cloudflare" - ], - "Date": [ - "Thu, 16 Apr 2026 08:08:22 GMT" - ], - "Content-Type": [ - "text/event-stream; charset=utf-8" - ], - "Content-Security-Policy": [ - "default-src 'none'; frame-ancestors 'none'" - ], - "Cache-Control": [ - "no-cache" - ], - "CF-RAY": [ - "9ed1b39d5ee094d7-TXL" - ] - }, - "cookies": { - "_cfuvid": "HVzbAkrn0OkkhKxFzQS2TP4_tJI5uG95Zf.eyxR.uUE-1776326901.3371863-1.0.1.1-MIJBDLji7RI9Y.eD0FN94A2T7vdNraR6kzvxZxBtNhA" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01HyzpRxeEqNuEjyWU6Z9Cxp\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":7598,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":22307,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":3,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Workflow is\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" built and ready. It chains Manual Trigger → Wait (1 second,\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" time interval mode) → Set node named \\\"running state test\\\". You can run it now using\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" the manual trigger.\"}}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":7598,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":22307,\"output_tokens\":45} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxSHl6cFJ4ZUVxTnVFanlXVTZaOUN4cCIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjc1OTgsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjIyMzA3LCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjowLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6Mywic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiJ9ICAgIH0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiV29ya2Zsb3cgaXMifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIgYnVpbHQgYW5kIHJlYWR5LiBJdCBjaGFpbnMgTWFudWFsIFRyaWdnZXIg4oaSIFdhaXQgKDEgc2Vjb25kLCJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiIHRpbWUgaW50ZXJ2YWwgbW9kZSkg4oaSIFNldCBub2RlIG5hbWVkIFwicnVubmluZyBzdGF0ZSB0ZXN0XCIuIFlvdSBjYW4gcnVuIGl0IG5vdyB1c2luZyJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiIHRoZSBtYW51YWwgdHJpZ2dlci4ifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjc1OTgsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjIyMzA3LCJvdXRwdXRfdG9rZW5zIjo0NX0gIH0KCmV2ZW50OiBtZXNzYWdlX3N0b3AKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdG9wIiAgICAgICAgICAgICB9Cgo=", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776326915177-unknown-host-POST-_v1_messages-4d1c93f7.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915177-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915177-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index c79079fb3c0..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915177-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": [ - "782" - ], - "strict-transport-security": [ - "max-age=31536000; includeSubDomains; preload" - ], - "set-cookie": [ - "_cfuvid=Z3jdcuPf52XHdt_D6UJdP7gj6odHvQ99b8BwCUFUCdk-1776326900.6503463-1.0.1.1-Qn3m3iWw0jvQrpHyLPVLSP2bzgdulhTavoaLRonDwb8; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": [ - "x-originResponse;dur=787" - ], - "request-id": [ - "req_011Ca77EB4LZnnFDmvP4Wi4Q" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "anthropic-ratelimit-tokens-reset": [ - "2026-04-16T08:08:20Z" - ], - "anthropic-ratelimit-tokens-remaining": [ - "26983000" - ], - "anthropic-ratelimit-tokens-limit": [ - "27000000" - ], - "anthropic-ratelimit-requests-reset": [ - "2026-04-16T08:08:20Z" - ], - "anthropic-ratelimit-requests-remaining": [ - "19998" - ], - "anthropic-ratelimit-requests-limit": [ - "20000" - ], - "anthropic-ratelimit-output-tokens-reset": [ - "2026-04-16T08:08:20Z" - ], - "anthropic-ratelimit-output-tokens-remaining": [ - "4500000" - ], - "anthropic-ratelimit-output-tokens-limit": [ - "4500000" - ], - "anthropic-ratelimit-input-tokens-reset": [ - "2026-04-16T08:08:20Z" - ], - "anthropic-ratelimit-input-tokens-remaining": [ - "22483000" - ], - "anthropic-ratelimit-input-tokens-limit": [ - "22500000" - ], - "X-Robots-Tag": [ - "none" - ], - "Server": [ - "cloudflare" - ], - "Date": [ - "Thu, 16 Apr 2026 08:08:21 GMT" - ], - "Content-Type": [ - "text/event-stream; charset=utf-8" - ], - "Content-Security-Policy": [ - "default-src 'none'; frame-ancestors 'none'" - ], - "Cache-Control": [ - "no-cache" - ], - "CF-RAY": [ - "9ed1b3990ec8e52a-TXL" - ] - }, - "cookies": { - "_cfuvid": "Z3jdcuPf52XHdt_D6UJdP7gj6odHvQ99b8BwCUFUCdk-1776326900.6503463-1.0.1.1-Qn3m3iWw0jvQrpHyLPVLSP2bzgdulhTavoaLRonDwb8" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01QP8epja8TtU5rTUicHLFcq\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":1066,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":8955,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"It\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" looks like the build is still in progress. Let me wait for it to complete.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01NQDWcEGEAbkpLN1vH2pFFN\",\"name\":\"workflows\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"a\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ction\\\": \\\"lis\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"limit\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"10}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":1066,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":8955,\"output_tokens\":87} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxUVA4ZXBqYThUdFU1clRVaWNITEZjcSIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEwNjYsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjg5NTUsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjoxLCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiJ9ICAgICAgICB9CgpldmVudDogcGluZwpkYXRhOiB7InR5cGUiOiAicGluZyJ9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6Ikl0In0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiIGxvb2tzIGxpa2UgdGhlIGJ1aWxkIGlzIHN0aWxsIGluIHByb2dyZXNzLiBMZXQgbWUgd2FpdCBmb3IgaXQgdG8gY29tcGxldGUuIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0YXJ0CmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RhcnQiLCJpbmRleCI6MSwiY29udGVudF9ibG9jayI6eyJ0eXBlIjoidG9vbF91c2UiLCJpZCI6InRvb2x1XzAxTlFEV2NFR0VBYmtwTE4xdkgycEZGTiIsIm5hbWUiOiJ3b3JrZmxvd3MiLCJpbnB1dCI6e30sImNhbGxlciI6eyJ0eXBlIjoiZGlyZWN0In19ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ7XCJhIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiY3Rpb25cIjogXCJsaXMifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InRcIiJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIsIFwibGltaXQifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXCI6ICJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIxMH0ifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RvcApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0b3AiLCJpbmRleCI6MSAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoidG9vbF91c2UiLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEwNjYsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjg5NTUsIm91dHB1dF90b2tlbnMiOjg3fSAgICB9CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgICAgIH0KCg==", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776326915177-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915178-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915178-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index 288250a72bf..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1776326915178-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": [ - "1061" - ], - "vary": [ - "Accept-Encoding" - ], - "strict-transport-security": [ - "max-age=31536000; includeSubDomains; preload" - ], - "set-cookie": [ - "_cfuvid=aanfq25BkTuZnFJm8.trmgHKqM9HZXeQ5D1BcTtUFtw-1776326905.9431152-1.0.1.1-slZyX_smC7IlHwNQXFqjI.0CX9JL54Qr7wH09VaamuA; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": [ - "x-originResponse;dur=1062" - ], - "request-id": [ - "req_011Ca77EZdQENSZ38ycmS2Du" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "anthropic-ratelimit-tokens-reset": [ - "2026-04-16T08:08:26Z" - ], - "anthropic-ratelimit-tokens-remaining": [ - "26983000" - ], - "anthropic-ratelimit-tokens-limit": [ - "27000000" - ], - "anthropic-ratelimit-requests-reset": [ - "2026-04-16T08:08:26Z" - ], - "anthropic-ratelimit-requests-remaining": [ - "19998" - ], - "anthropic-ratelimit-requests-limit": [ - "20000" - ], - "anthropic-ratelimit-output-tokens-reset": [ - "2026-04-16T08:08:26Z" - ], - "anthropic-ratelimit-output-tokens-remaining": [ - "4500000" - ], - "anthropic-ratelimit-output-tokens-limit": [ - "4500000" - ], - "anthropic-ratelimit-input-tokens-reset": [ - "2026-04-16T08:08:26Z" - ], - "anthropic-ratelimit-input-tokens-remaining": [ - "22483000" - ], - "anthropic-ratelimit-input-tokens-limit": [ - "22500000" - ], - "X-Robots-Tag": [ - "none" - ], - "Server": [ - "cloudflare" - ], - "Date": [ - "Thu, 16 Apr 2026 08:08:27 GMT" - ], - "Content-Type": [ - "text/event-stream; charset=utf-8" - ], - "Content-Security-Policy": [ - "default-src 'none'; frame-ancestors 'none'" - ], - "Cache-Control": [ - "no-cache" - ], - "CF-RAY": [ - "9ed1b3ba2b5c4f3e-TXL" - ] - }, - "cookies": { - "_cfuvid": "aanfq25BkTuZnFJm8.trmgHKqM9HZXeQ5D1BcTtUFtw-1776326905.9431152-1.0.1.1-slZyX_smC7IlHwNQXFqjI.0CX9JL54Qr7wH09VaamuA" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_015tq4Hrq55ugesT3ZChvqZa\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":1442,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":8955,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":50,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01V7tPJn8ZPucU4gZjkYxCfc\",\"name\":\"executions\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"action\\\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"run\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"workf\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"lo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"wId\\\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"A\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"o6PFbRGjhy2\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"k5S4\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"wo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rk\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"flowName\\\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"Manual Tr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"igger - \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Wait -\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Set\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":1442,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":8955,\"output_tokens\":112} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxNXRxNEhycTU1dWdlc1QzWkNodnFaYSIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjE0NDIsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjg5NTUsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjo1MCwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0YXJ0CmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RhcnQiLCJpbmRleCI6MCwiY29udGVudF9ibG9jayI6eyJ0eXBlIjoidG9vbF91c2UiLCJpZCI6InRvb2x1XzAxVjd0UEpuOFpQdWNVNGdaamtZeENmYyIsIm5hbWUiOiJleGVjdXRpb25zIiwiaW5wdXQiOnt9LCJjYWxsZXIiOnsidHlwZSI6ImRpcmVjdCJ9fSAgICAgICAgICAgIH0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ7XCJhY3Rpb25cIjogIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlwicnVuXCIifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiwgXCJ3b3JrZiJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImxvIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IndJZFwiOiAifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXCJBIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im82UEZiUkdqaHkyIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiazVTNCJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcIiJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiLCBcIndvIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJyayJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImZsb3dOYW1lXCI6ICJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcIk1hbnVhbCBUciJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImlnZ2VyIC0gIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJXYWl0IC0ifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBTZXRcIn0ifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjAgICAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoidG9vbF91c2UiLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjE0NDIsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjg5NTUsIm91dHB1dF90b2tlbnMiOjExMn0gICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICAgIH0KCg==", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1776326915178-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1777373941132-unknown-host-POST-_v1_messages-3dba52c9.json b/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1777373941132-unknown-host-POST-_v1_messages-3dba52c9.json new file mode 100644 index 00000000000..f0db5479441 --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-mark-all-nodes-as-success-after-execution-completes/1777373941132-unknown-host-POST-_v1_messages-3dba52c9.json @@ -0,0 +1,111 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde[\\s\\S]* {\n return Array.from({ length: parameters.numberInputs || 2 }, (_, i) => ({\n type: 'main',\n displayName: `Input ${(i + 1).toString()}`,\n }));\n})($parameter)}}","outputs":["main"],"score":295},{"name":"n8n-nodes-base.microsoftOutlook","displayName":"Microsoft Outlook","description":"Consume Microsoft Outlook API","version":2,"inputs":["main"],"outputs":["main"],"score":295,"discriminators":{"resources":[{"name":"calendar","operations":["create","delete","get","get_all","update"]},{"name":"contact","operations":["create","delete","get","get_all","update"]},{"name":"draft","operations":["create","delete","get","send","update"]},{"name":"event","operations":["create","delete","get","get_all","update"]},{"name":"folder","operations":["create","delete","get","get_all","update"]},{"name":"folder_message","operations":["get_all"]},{"name":"message","operations":["delete","get","get_all","move","reply","send","send_and_wait","update"]},{"name":"message_attachment","operations":["add","download","get","get_all"]}]}},{"name":"n8n-nodes-base.microsoftTeams","displayName":"Microsoft Teams","description":"Consume Microsoft Teams API","version":2,"inputs":["main"],"outputs":["main"],"score":295,"discriminators":{"resources":[{"name":"channel","operations":["create","delete","get","get_all","update"]},{"name":"channel_message","operations":["create","get_all"]},{"name":"chat_message","operations":["create","get","get_all"]},{"name":"task","operations":["create","delete","get","get_all","update"]}]}},{"name":"n8n-nodes-base.slack","displayName":"Slack","description":"Consume Slack API","version":2.4,"inputs":["main"],"outputs":["main"],"score":295,"discriminators":{"resources":[{"name":"channel","operations":["archive","close","create","get","get_all","history","invite","join","kick","leave","member","open","rename","replies","set_purpose","set_topic","unarchive"]},{"name":"file","operations":["get","get_all","upload"]},{"name":"message","operations":["delete","get_permalink","post","search","send_and_wait","update"]},{"name":"reaction","operations":["add","get","remove"]},{"name":"star","operations":["add","delete","get_all"]},{"name":"user","operations":["get_all","get_presence","get_profile","info","update_profile"]},{"name":"user_group","operations":["create","disable","enable","get_all","get_users","update","update_users"]}]}},{"name":"n8n-nodes-base.telegram","displayName":"Telegram","description":"Sends data to Telegram","version":1.2,"inputs":["main"],"outputs":["main"],"score":295,"discriminators":{"resources":[{"name":"callback","operations":["answer_inline_query","answer_query"]},{"name":"chat","operations":["administrators","get","leave","member","set_description","set_title"]},{"name":"file","operations":["get"]},{"name":"message","operations":["delete_message","edit_message_text","pin_chat_message","send_and_wait","send_animation","send_audio","send_chat_action","send_document","send_location","send_media_group","send_message","send_photo","send_sticker","send_video","unpin_chat_message"]}]}},{"name":"@n8n/n8n-nodes-langchain.chat","displayName":"Chat","description":"Send a message into the chat","version":1.3,"inputs":"={{ ((parameters) => {\n const inputs = [\n {\n type: 'main',\n },\n ];\n if (parameters.options?.memoryConnection) {\n return [\n ...inputs,\n {\n type: 'ai_memory',\n displayName: 'Memory',\n maxConnections: 1,\n },\n ];\n }\n return inputs;\n})($parameter) }}","outputs":["main"],"score":295},{"name":"n8n-nodes-base.whatsAppTool","displayName":"WhatsApp Business Cloud Tool","description":"Access WhatsApp API","version":1.1,"inputs":[],"outputs":["ai_tool"],"score":94.5,"discriminators":{"resources":[{"name":"media","operations":["media_delete","media_upload","media_url_get"]},{"name":"message","operations":["send","send_and_wait","send_template"]}]}},{"name":"n8n-nodes-base.whatsAppHitlTool","displayName":"WhatsApp Business Cloud","description":"Request human approval for tools","version":1.1,"inputs":["ai_tool"],"outputs":["ai_tool"],"score":71.5},{"name":"n8n-nodes-base.awsTranscribeTool","displayName":"AWS Transcribe Tool","description":"Sends data to AWS Transcribe","version":1,"inputs":[],"outputs":["ai_tool"],"score":64.5},{"name":"n8n-nodes-base.writeBinaryFile","displayName":"Write Binary File","description":"Writes a binary file to disk","version":1,"inputs":["main"],"outputs":["main"],"score":49.699999999999996},{"name":"@n8n/n8n-nodes-langchain.toolCode","displayName":"Code Tool","description":"Write a tool in JS or Python","version":1.3,"inputs":[],"outputs":["ai_tool"],"score":49.699999999999996},{"name":"@n8n/n8n-nodes-langchain.vectorStoreWeaviate","displayName":"Weaviate Vector Store","description":"Work with your data in a Weaviate Cluster","version":1.3,"inputs":"={{\n\t\t\t((parameters) => {\n\t\t\t\tconst mode = parameters?.mode;\n\t\t\t\tconst useReranker = parameters?.useReranker;\n\t\t\t\tconst inputs = [{ displayName: \"Embedding\", type: \"ai_embedding\", required: true, maxConnections: 1}]\n\n\t\t\t\tif (['load', 'retrieve', 'retrieve-as-tool'].includes(mode) && useReranker) {\n\t\t\t\t\tinputs.push({ displayName: \"Reranker\", type: \"ai_reranker\", required: true, maxConnections: 1})\n\t\t\t\t}\n\n\t\t\t\tif (mode === 'retrieve-as-tool') {\n\t\t\t\t\treturn inputs;\n\t\t\t\t}\n\n\t\t\t\tif (['insert', 'load', 'update'].includes(mode)) {\n\t\t\t\t\tinputs.push({ displayName: \"\", type: \"main\"})\n\t\t\t\t}\n\n\t\t\t\tif (['insert'].includes(mode)) {\n\t\t\t\t\tinputs.push({ displayName: \"Document\", type: \"ai_document\", required: true, maxConnections: 1})\n\t\t\t\t}\n\t\t\t\treturn inputs\n\t\t\t})($parameter)\n\t\t}}","outputs":"={{\n\t\t\t((parameters) => {\n\t\t\t\tconst mode = parameters?.mode ?? 'retrieve';\n\n\t\t\t\tif (mode === 'retrieve-as-tool') {\n\t\t\t\t\treturn [{ displayName: \"Tool\", type: \"ai_tool\"}]\n\t\t\t\t}\n\n\t\t\t\tif (mode === 'retrieve') {\n\t\t\t\t\treturn [{ displayName: \"Vector Store\", type: \"ai_vectorStore\"}]\n\t\t\t\t}\n\t\t\t\treturn [{ displayName: \"\", type: \"main\"}]\n\t\t\t})($parameter)\n\t\t}}","score":45,"subnodeRequirements":[{"connectionType":"ai_embedding","required":true},{"connectionType":"ai_document","required":true,"displayOptions":{"show":{"mode":["insert"]}}},{"connectionType":"ai_reranker","required":true,"displayOptions":{"show":{"mode":["load","retrieve","retrieve-as-tool"],"useReranker":[true]}}}]},{"name":"n8n-nodes-base.stopAndError","displayName":"Stop and Error","description":"Throw an error in the workflow","version":1,"inputs":["main"],"outputs":[],"score":2.8},{"name":"@n8n/n8n-nodes-langchain.vectorStoreAzureAISearch","displayName":"Azure AI Search Vector Store","description":"Work with your data in Azure AI Search Vector Store","version":1.3,"inputs":"={{\n\t\t\t((parameters) => {\n\t\t\t\tconst mode = parameters?.mode;\n\t\t\t\tconst useReranker = parameters?.useReranker;\n\t\t\t\tconst inputs = [{ displayName: \"Embedding\", type: \"ai_embedding\", required: true, maxConnections: 1}]\n\n\t\t\t\tif (['load', 'retrieve', 'retrieve-as-tool'].includes(mode) && useReranker) {\n\t\t\t\t\tinputs.push({ displayName: \"Reranker\", type: \"ai_reranker\", required: true, maxConnections: 1})\n\t\t\t\t}\n\n\t\t\t\tif (mode === 'retrieve-as-tool') {\n\t\t\t\t\treturn inputs;\n\t\t\t\t}\n\n\t\t\t\tif (['insert', 'load', 'update'].includes(mode)) {\n\t\t\t\t\tinputs.push({ displayName: \"\", type: \"main\"})\n\t\t\t\t}\n\n\t\t\t\tif (['insert'].includes(mode)) {\n\t\t\t\t\tinputs.push({ displayName: \"Document\", type: \"ai_document\", required: true, maxConnections: 1})\n\t\t\t\t}\n\t\t\t\treturn inputs\n\t\t\t})($parameter)\n\t\t}}","outputs":"={{\n\t\t\t((parameters) => {\n\t\t\t\tconst mode = parameters?.mode ?? 'retrieve';\n\n\t\t\t\tif (mode === 'retrieve-as-tool') {\n\t\t\t\t\treturn [{ displayName: \"Tool\", type: \"ai_tool\"}]\n\t\t\t\t}\n\n\t\t\t\tif (mode === 'retrieve') {\n\t\t\t\t\treturn [{ displayName: \"Vector Store\", type: \"ai_vectorStore\"}]\n\t\t\t\t}\n\t\t\t\treturn [{ displayName: \"\", type: \"main\"}]\n\t\t\t})($parameter)\n\t\t}}","score":-15.399999999999999,"subnodeRequirements":[{"connectionType":"ai_embedding","required":true},{"connectionType":"ai_document","required":true,"displayOptions":{"show":{"mode":["insert"]}}},{"connectionType":"ai_reranker","required":true,"displayOptions":{"show":{"mode":["load","retrieve","retrieve-as-tool"],"useReranker":[true]}}}]},{"name":"@n8n/n8n-nodes-langchain.vectorStoreZep","displayName":"Zep Vector Store","description":"Work with your data in Zep Vector Store","version":1.3,"inputs":"={{\n\t\t\t((parameters) => {\n\t\t\t\tconst mode = parameters?.mode;\n\t\t\t\tconst useReranker = parameters?.useReranker;\n\t\t\t\tconst inputs = [{ displayName: \"Embedding\", type: \"ai_embedding\", required: true, maxConnections: 1}]\n\n\t\t\t\tif (['load', 'retrieve', 'retrieve-as-tool'].includes(mode) && useReranker) {\n\t\t\t\t\tinputs.push({ displayName: \"Reranker\", type: \"ai_reranker\", required: true, maxConnections: 1})\n\t\t\t\t}\n\n\t\t\t\tif (mode === 'retrieve-as-tool') {\n\t\t\t\t\treturn inputs;\n\t\t\t\t}\n\n\t\t\t\tif (['insert', 'load', 'update'].includes(mode)) {\n\t\t\t\t\tinputs.push({ displayName: \"\", type: \"main\"})\n\t\t\t\t}\n\n\t\t\t\tif (['insert'].includes(mode)) {\n\t\t\t\t\tinputs.push({ displayName: \"Document\", type: \"ai_document\", required: true, maxConnections: 1})\n\t\t\t\t}\n\t\t\t\treturn inputs\n\t\t\t})($parameter)\n\t\t}}","outputs":"={{\n\t\t\t((parameters) => {\n\t\t\t\tconst mode = parameters?.mode ?? 'retrieve';\n\n\t\t\t\tif (mode === 'retrieve-as-tool') {\n\t\t\t\t\treturn [{ displayName: \"Tool\", type: \"ai_tool\"}]\n\t\t\t\t}\n\n\t\t\t\tif (mode === 'retrieve') {\n\t\t\t\t\treturn [{ displayName: \"Vector Store\", type: \"ai_vectorStore\"}]\n\t\t\t\t}\n\t\t\t\treturn [{ displayName: \"\", type: \"main\"}]\n\t\t\t})($parameter)\n\t\t}}","score":-15.399999999999999,"subnodeRequirements":[{"connectionType":"ai_embedding","required":true},{"connectionType":"ai_document","required":true,"displayOptions":{"show":{"mode":["insert"]}}},{"connectionType":"ai_reranker","required":true,"displayOptions":{"show":{"mode":["load","retrieve","retrieve-as-tool"],"useReranker":[true]}}}]}],"totalResults":20}} -{"kind":"tool-call","stepId":3,"agentRole":"workflow-builder","toolName":"nodes","input":{"action":"describe","nodeType":"n8n-nodes-base.wait"},"output":{"found":true,"name":"n8n-nodes-base.wait","displayName":"Wait","description":"Wait before continue with execution","group":["organization"],"version":1.1,"properties":[{"displayName":"Resume","name":"resume","type":"options","description":"Determines the waiting mode to use before the workflow continues","default":"timeInterval","options":[{"name":"After Time Interval","value":"timeInterval"},{"name":"At Specified Time","value":"specificTime"},{"name":"On Webhook Call","value":"webhook"},{"name":"On Form Submitted","value":"form"}]},{"displayName":"Authentication","name":"incomingAuthentication","type":"options","description":"If and how incoming resume-webhook-requests to $execution.resumeFormUrl should be authenticated for additional security","default":"none","options":[{"name":"Basic Auth","value":"basicAuth"},{"name":"None","value":"none"}]},{"displayName":"Authentication","name":"incomingAuthentication","type":"options","description":"If and how incoming resume-webhook-requests to $execution.resumeUrl should be authenticated for additional security","default":"none","options":[{"name":"Basic Auth","value":"basicAuth"},{"name":"Header Auth","value":"headerAuth"},{"name":"JWT Auth","value":"jwtAuth"},{"name":"None","value":"none"}]},{"displayName":"Date and Time","name":"dateTime","type":"dateTime","required":true,"description":"The date and time to wait for before continuing","default":""},{"displayName":"Wait Amount","name":"amount","type":"number","description":"The time to wait","default":1},{"displayName":"Wait Amount","name":"amount","type":"number","description":"The time to wait","default":5},{"displayName":"Wait Unit","name":"unit","type":"options","description":"The time unit of the Wait Amount value","default":"hours","options":[{"name":"Seconds","value":"seconds"},{"name":"Minutes","value":"minutes"},{"name":"Hours","value":"hours"},{"name":"Days","value":"days"}]},{"displayName":"Wait Unit","name":"unit","type":"options","description":"The time unit of the Wait Amount value","default":"seconds","options":[{"name":"Seconds","value":"seconds"},{"name":"Minutes","value":"minutes"},{"name":"Hours","value":"hours"},{"name":"Days","value":"days"}]},{"displayName":"The webhook URL will be generated at run time. It can be referenced with the $execution.resumeUrl variable. Send it somewhere before getting to this node. More info","name":"webhookNotice","type":"notice","default":""},{"displayName":"The form url will be generated at run time. It can be referenced with the $execution.resumeFormUrl variable. Send it somewhere before getting to this node. More info","name":"formNotice","type":"notice","default":""},{"displayName":"Form Title","name":"formTitle","type":"string","required":true,"description":"Shown at the top of the form","default":""},{"displayName":"Form Description","name":"formDescription","type":"string","description":"Shown underneath the Form Title. Can be used to prompt the user on how to complete the form. Accepts HTML. Does not accept <script>, <style> or <input> tags.","default":""},{"displayName":"Form Elements","name":"formFields","type":"fixedCollection","default":{},"options":[]},{"displayName":"Respond When","name":"responseMode","type":"options","description":"When to respond to the form submission","default":"onReceived","options":[{"name":"Form Is Submitted","value":"onReceived"},{"name":"Workflow Finishes","value":"lastNode"},{"name":"Using 'Respond to Webhook' Node","value":"responseNode"}]},{"displayName":"HTTP Method","name":"httpMethod","type":"options","description":"The HTTP method of the Webhook call","default":"GET","options":[{"name":"DELETE","value":"DELETE"},{"name":"GET","value":"GET"},{"name":"HEAD","value":"HEAD"},{"name":"PATCH","value":"PATCH"},{"name":"POST","value":"POST"},{"name":"PUT","value":"PUT"}]},{"displayName":"Response Code","name":"responseCode","type":"number","description":"The HTTP Response code to return","default":200},{"displayName":"Respond","name":"responseMode","type":"options","description":"When and how to respond to the webhook","default":"onReceived","options":[{"name":"Immediately","value":"onReceived"},{"name":"When Last Node Finishes","value":"lastNode"},{"name":"Using 'Respond to Webhook' Node","value":"responseNode"}]},{"displayName":"Response Data","name":"responseData","type":"options","description":"What data should be returned. If it should return all items as an array or only the first item as object.","default":"firstEntryJson","options":[{"name":"All Entries","value":"allEntries"},{"name":"First Entry JSON","value":"firstEntryJson"},{"name":"First Entry Binary","value":"firstEntryBinary"},{"name":"No Response Body","value":"noData"}]},{"displayName":"Property Name","name":"responseBinaryPropertyName","type":"string","required":true,"description":"Name of the binary property to return","default":"data"},{"displayName":"Limit Wait Time","name":"limitWaitTime","type":"boolean","description":"Whether to limit the time this node should wait for a user response before execution resumes","default":false},{"displayName":"Limit Type","name":"limitType","type":"options","description":"Sets the condition for the execution to resume. Can be a specified date or after some time.","default":"afterTimeInterval","options":[{"name":"After Time Interval","value":"afterTimeInterval"},{"name":"At Specified Time","value":"atSpecifiedTime"}]},{"displayName":"Amount","name":"resumeAmount","type":"number","description":"The time to wait","default":1},{"displayName":"Unit","name":"resumeUnit","type":"options","description":"Unit of the interval value","default":"hours","options":[{"name":"Seconds","value":"seconds"},{"name":"Minutes","value":"minutes"},{"name":"Hours","value":"hours"},{"name":"Days","value":"days"}]},{"displayName":"Max Date and Time","name":"maxDateAndTime","type":"dateTime","description":"Continue execution after the specified date and time","default":""},{"displayName":"Options","name":"options","type":"collection","default":{},"options":[]},{"displayName":"Options","name":"options","type":"collection","default":{},"options":[]},{"displayName":"Options","name":"options","type":"collection","default":{},"options":[]}],"credentials":[{"name":"httpBasicAuth","required":true},{"name":"httpHeaderAuth","required":true},{"name":"jwtAuth","required":true}],"inputs":["main"],"outputs":["main"],"webhooks":[{"name":"default","httpMethod":"={{$parameter[\"httpMethod\"] || \"GET\"}}","isFullPath":true,"responseCode":"={{((parameters) => {\n if (parameters.responseCode) {\n return parameters.responseCode;\n }\n const responseCodeOptions = parameters.options;\n if (responseCodeOptions?.responseCode?.values) {\n const { responseCode, customCode } = responseCodeOptions.responseCode.values;\n if (customCode) {\n return customCode;\n }\n return responseCode;\n }\n return 200;\n})($parameter)}}","responseMode":"={{$parameter[\"responseMode\"]}}","responseData":"={{$parameter[\"responseData\"]}}","responseBinaryPropertyName":"={{$parameter[\"responseBinaryPropertyName\"]}}","responseContentType":"={{$parameter[\"options\"][\"responseContentType\"]}}","responsePropertyName":"={{$parameter[\"options\"][\"responsePropertyName\"]}}","responseHeaders":"={{$parameter[\"options\"][\"responseHeaders\"]}}","path":"={{$parameter[\"options\"][\"webhookSuffix\"] || \"\"}}","restartWebhook":true},{"name":"default","httpMethod":"GET","responseMode":"onReceived","path":"={{$parameter[\"options\"][\"webhookSuffix\"] || \"\"}}","restartWebhook":true,"isFullPath":true,"nodeType":"form"},{"name":"default","httpMethod":"POST","responseMode":"={{$parameter[\"responseMode\"]}}","responseData":"={{$parameter[\"responseMode\"] === \"lastNode\" ? \"noData\" : undefined}}","path":"={{$parameter[\"options\"][\"webhookSuffix\"] || \"\"}}","restartWebhook":true,"isFullPath":true,"nodeType":"form"}]}} -{"kind":"tool-call","stepId":4,"agentRole":"orchestrator","toolName":"workflows","input":{"action":"list","query":"running state test"},"output":{"workflows":[]}} -{"kind":"tool-call","stepId":5,"agentRole":"orchestrator","toolName":"workflows","input":{"action":"list","limit":5},"output":{"workflows":[]}} -{"kind":"tool-call","stepId":6,"agentRole":"workflow-builder","toolName":"build-workflow","input":{"code":"import { workflow, node, trigger } from '@n8n/workflow-sdk';\n\nconst manualTrigger = trigger({\n type: 'n8n-nodes-base.manualTrigger',\n version: 1,\n config: { name: 'Manual Trigger' }\n});\n\nconst waitNode = node({\n type: 'n8n-nodes-base.wait',\n version: 1.1,\n config: {\n name: 'Wait',\n parameters: {\n resume: 'timeInterval',\n amount: 1,\n unit: 'seconds'\n }\n }\n});\n\nconst setNode = node({\n type: 'n8n-nodes-base.set',\n version: 3.4,\n config: {\n name: 'running state test',\n parameters: {}\n }\n});\n\nexport default workflow('running-state-test', 'Manual Trigger - Wait - Set')\n .add(manualTrigger)\n .to(waitNode)\n .to(setNode);\n","name":"Manual Trigger - Wait - Set"},"output":{"success":true,"workflowId":"Ao6PFbRGjhy2k5S4"}} -{"kind":"tool-call","stepId":7,"agentRole":"orchestrator","toolName":"workflows","input":{"action":"list","limit":10},"output":{"workflows":[{"id":"Ao6PFbRGjhy2k5S4","name":"Manual Trigger - Wait - Set","versionId":"ae0efc0d-31cb-4dcd-a234-7517e2b0735b","activeVersionId":null,"createdAt":"2026-04-16T08:08:21.142Z","updatedAt":"2026-04-16T08:08:21.187Z"}]}} -{"kind":"tool-suspend","stepId":8,"agentRole":"orchestrator","toolName":"executions","input":{"action":"run","workflowId":"Ao6PFbRGjhy2k5S4","workflowName":"Manual Trigger - Wait - Set"},"output":{"executionId":"","status":"error","denied":true,"reason":"Awaiting confirmation"},"suspendPayload":{}} -{"kind":"tool-resume","stepId":9,"agentRole":"orchestrator","toolName":"executions","input":{"action":"run","workflowId":"Ao6PFbRGjhy2k5S4","workflowName":"Manual Trigger - Wait - Set"},"output":{"executionId":"1","status":"waiting","data":{"Manual Trigger":"\n[\n {}\n]\n","Wait":"\n[\n {}\n]\n"},"startedAt":"2026-04-16T08:08:28.652Z","finishedAt":"2026-04-16T08:08:28.684Z"},"resumeData":{"approved":true}} +{"kind":"header","version":1,"testName":"recording","recordedAt":"2026-04-28T10:58:07.074Z"} +{"kind":"tool-call","stepId":1,"agentRole":"orchestrator","toolName":"credentials","input":{"action":"list"},"output":{"credentials":[],"total":0,"hasMore":false}} +{"kind":"tool-call","stepId":2,"agentRole":"orchestrator","toolName":"build-workflow-with-agent","input":{"task":"Build a workflow with:\n1. A Manual Trigger node\n2. A Wait node set to 1 second\n3. A Set node named \"running state test\"\n\nConnect them in order: Manual Trigger → Wait → \"running state test\" (Set node).","conversationContext":"No credentials available. Simple workflow with no external integrations needed."},"output":{"result":"Error: direct builder calls require `bypassPlan: true` + an existing `workflowId` + a one-sentence `reason`. Use that combination for any edit to an existing workflow. For new workflows, multi-workflow builds, or data-table schema changes, call `plan` with a `build-workflow` task instead — the planner discovers credentials, data tables, and best practices, and schedules an orchestrator-run verification checkpoint.","taskId":""}} +{"kind":"tool-call","stepId":3,"agentRole":"planner","toolName":"add-plan-item","input":{"summary":"Build a minimal manual-trigger workflow with a 1-second Wait node and a Set node called 'running state test', then execute it.","assumptions":["Wait node is set to a fixed 1-second resume interval","Set node named 'running state test' has no field modifications — it serves as a labeled passthrough","Workflow is run immediately after build using a manual execution"],"item":{"id":"wf-running-state-test","name":"Running State Test","purpose":"A simple test workflow triggered manually. It pauses for 1 second using a Wait node, then passes through a Set node named 'running state test'. The workflow is designed to be run immediately after creation to verify it executes without errors.","integrations":[],"triggerDescription":"Manual trigger","dependsOn":[],"kind":"workflow"}},"output":{"result":"Added: Build 'Running State Test' workflow (1 item total)"}} +{"kind":"tool-call","stepId":4,"agentRole":"planner","toolName":"add-plan-item","input":{"item":{"id":"chk-running-state-test","title":"Verify 'Running State Test' workflow runs successfully","instructions":"Use the build outcome work item ID for wf-running-state-test to call verify-built-workflow. Confirm the execution completes without errors and passes through both the Wait node and the Set node named 'running state test'. The run must complete (not remain in a waiting/paused state) and produce a successful final output.","dependsOn":["wf-running-state-test"],"kind":"checkpoint"}},"output":{"result":"Added: Verify 'Running State Test' workflow runs successfully (2 items total)"}} +{"kind":"tool-call","stepId":5,"agentRole":"planner","toolName":"submit-plan","input":{},"output":{"approved":false,"feedback":"Awaiting approval"}} +{"kind":"tool-resume","stepId":6,"agentRole":"planner","toolName":"submit-plan","input":{},"output":{"approved":true},"resumeData":{"approved":true}} +{"kind":"tool-call","stepId":7,"agentRole":"orchestrator","toolName":"plan","input":{},"output":{"result":"Plan approved and 2 tasks dispatched."}} +{"kind":"tool-call","stepId":8,"agentRole":"workflow-builder","toolName":"nodes","input":{"action":"type-definition","nodeTypes":["n8n-nodes-base.manualTrigger","n8n-nodes-base.wait","n8n-nodes-base.set"]},"output":{"definitions":[{"nodeType":"n8n-nodes-base.manualTrigger","version":"v1","content":"/**\n * Manual Trigger Node - Version 1\n * Runs the flow on clicking a button in n8n\n */\n\n\nexport interface ManualTriggerV1Params {\n}\n\ninterface ManualTriggerV1NodeBase {\n type: 'n8n-nodes-base.manualTrigger';\n version: 1;\n isTrigger: true;\n}\n\nexport type ManualTriggerV1ParamsNode = ManualTriggerV1NodeBase & {\n config: NodeConfig;\n};\n\nexport type ManualTriggerV1Node = ManualTriggerV1ParamsNode;"},{"nodeType":"n8n-nodes-base.wait","version":"v11","content":"/**\n * Wait Node - Version 1.1\n * Wait before continue with execution\n */\n\n\nexport interface WaitV11Params {\n/**\n * Determines the waiting mode to use before the workflow continues\n * @builderHint For user approval workflows, consider using nodes with operation: \"sendAndWait\" (e.g., email, Slack) instead of Wait node. If using \"webhook\", the URL will be generated at runtime and can be referenced with {{ $execution.resumeUrl }}.\n * @default timeInterval\n */\n resume?: 'timeInterval' | 'specificTime' | 'webhook' | 'form' | Expression;\n/**\n * If and how incoming resume-webhook-requests to $execution.resumeFormUrl should be authenticated for additional security\n * @displayOptions.show { resume: [\"form\", \"webhook\"] }\n * @default none\n */\n incomingAuthentication?: 'basicAuth' | 'none' | Expression;\n/**\n * The date and time to wait for before continuing\n * @displayOptions.show { resume: [\"specificTime\"] }\n */\n dateTime: string | Expression;\n/**\n * The time to wait\n * @displayOptions.show { resume: [\"timeInterval\"] }\n * @default 5\n */\n amount?: number | Expression;\n/**\n * The time unit of the Wait Amount value\n * @displayOptions.show { resume: [\"timeInterval\"] }\n * @default seconds\n */\n unit?: 'seconds' | 'minutes' | 'hours' | 'days' | Expression;\n/**\n * Shown at the top of the form\n * @displayOptions.show { resume: [\"form\"] }\n */\n formTitle: string | Expression | PlaceholderValue;\n/**\n * Shown underneath the Form Title. Can be used to prompt the user on how to complete the form. Accepts HTML. Does not accept <code><script></code>, <code><style></code> or <code><input></code> tags.\n * @displayOptions.show { resume: [\"form\"] }\n */\n formDescription?: string | Expression | PlaceholderValue;\n/**\n * Form Elements\n * @displayOptions.show { resume: [\"form\"] }\n * @default {}\n */\n formFields?: {\n /** Values\n */\n values?: Array<{\n /** The name of the field, used in input attributes and referenced by the workflow\n * @displayOptions.hide { fieldType: [\"html\"] }\n */\n fieldName?: string | Expression | PlaceholderValue;\n /** Label that appears above the input field\n * @displayOptions.hide { fieldType: [\"hiddenField\", \"html\"] }\n */\n fieldLabel?: string | Expression | PlaceholderValue;\n /** Label that appears above the input field\n * @displayOptions.hide { fieldType: [\"hiddenField\", \"html\"] }\n */\n fieldLabel?: string | Expression | PlaceholderValue;\n /** The name of the field, used in input attributes and referenced by the workflow\n * @displayOptions.show { fieldType: [\"hiddenField\"] }\n */\n fieldName?: string | Expression | PlaceholderValue;\n /** The type of field to add to the form\n * @default text\n */\n fieldType?: 'checkbox' | 'html' | 'date' | 'dropdown' | 'email' | 'file' | 'hiddenField' | 'number' | 'password' | 'radio' | 'text' | 'textarea' | Expression;\n /** Optional field. It can be used to include the html in the output.\n * @displayOptions.show { fieldType: [\"html\"] }\n */\n elementName?: string | Expression | PlaceholderValue;\n /** The name of the field, used in input attributes and referenced by the workflow\n * @displayOptions.hide { fieldType: [\"html\"] }\n */\n fieldName?: string | Expression | PlaceholderValue;\n /** Sample text to display inside the field\n * @displayOptions.hide { fieldType: [\"dropdown\", \"date\", \"file\", \"html\", \"hiddenField\", \"radio\", \"checkbox\"] }\n */\n placeholder?: string | Expression | PlaceholderValue;\n /** Default value that will be pre-filled in the form field\n * @displayOptions.show { fieldType: [\"text\", \"number\", \"email\", \"textarea\"] }\n */\n defaultValue?: string | Expression | PlaceholderValue;\n /** Default date value that will be pre-filled in the form field (format: YYYY-MM-DD)\n * @displayOptions.show { fieldType: [\"date\"] }\n */\n defaultValue?: string | Expression;\n /** Default value that will be pre-selected. Must match one of the option labels.\n * @displayOptions.show { fieldType: [\"dropdown\", \"radio\"] }\n */\n defaultValue?: string | Expression | PlaceholderValue;\n /** Default value(s) that will be pre-selected. Must match one or multiple of the option labels. Separate multiple pre-selected options with a comma.\n * @displayOptions.show { fieldType: [\"checkbox\"] }\n */\n defaultValue?: string | Expression | PlaceholderValue;\n /** Input value can be set here or will be passed as a query parameter via Field Name if no value is set\n * @displayOptions.show { fieldType: [\"hiddenField\"] }\n */\n fieldValue?: string | Expression | PlaceholderValue;\n /** List of options that can be selected from the dropdown\n * @displayOptions.show { fieldType: [\"dropdown\"] }\n * @default {\"values\":[{\"option\":\"\"}]}\n */\n fieldOptions?: {\n /** Values\n */\n values?: Array<{\n /** Option\n */\n option?: string | Expression | PlaceholderValue;\n }>;\n };\n /** Checkboxes\n * @displayOptions.show { fieldType: [\"checkbox\"] }\n * @default {\"values\":[{\"option\":\"\"}]}\n */\n fieldOptions?: {\n /** Values\n */\n values?: Array<{\n /** Checkbox Label\n */\n option?: string | Expression | PlaceholderValue;\n }>;\n };\n /** Radio Buttons\n * @displayOptions.show { fieldType: [\"radio\"] }\n * @default {\"values\":[{\"option\":\"\"}]}\n */\n fieldOptions?: {\n /** Values\n */\n values?: Array<{\n /** Radio Button Label\n */\n option?: string | Expression | PlaceholderValue;\n }>;\n };\n /** Whether to allow the user to select multiple options from the dropdown list\n * @displayOptions.show { fieldType: [\"dropdown\"] }\n * @default false\n */\n multiselect?: boolean | Expression;\n /** Limit Selection\n * @displayOptions.show { fieldType: [\"checkbox\"] }\n * @default unlimited\n */\n limitSelection?: 'exact' | 'range' | 'unlimited' | Expression;\n /** Number of Selections\n * @displayOptions.show { fieldType: [\"checkbox\"], limitSelection: [\"exact\"] }\n * @default 1\n */\n numberOfSelections?: number | Expression;\n /** Minimum Selections\n * @displayOptions.show { fieldType: [\"checkbox\"], limitSelection: [\"range\"] }\n * @default 0\n */\n minSelections?: number | Expression;\n /** Maximum Selections\n * @displayOptions.show { fieldType: [\"checkbox\"], limitSelection: [\"range\"] }\n * @default 1\n */\n maxSelections?: number | Expression;\n /** HTML elements to display on the form page\n * @hint Does not accept <code><script></code>, <code><style></code> or <code><input></code> tags\n * @displayOptions.show { fieldType: [\"html\"] }\n */\n html?: string;\n /** Whether to allow the user to select multiple files from the file input or just one\n * @displayOptions.show { fieldType: [\"file\"] }\n * @default true\n */\n multipleFiles?: boolean | Expression;\n /** Comma-separated list of allowed file extensions\n * @hint Leave empty to allow all file types\n * @displayOptions.show { fieldType: [\"file\"] }\n */\n acceptFileTypes?: string | Expression | PlaceholderValue;\n /** Whether to require the user to enter a value for this field before submitting the form\n * @displayOptions.hide { fieldType: [\"html\", \"hiddenField\"] }\n * @default false\n */\n requiredField?: boolean | Expression;\n }>;\n };\n/**\n * When to respond to the form submission\n * @displayOptions.show { resume: [\"form\", \"webhook\"] }\n * @default onReceived\n */\n responseMode?: 'onReceived' | 'lastNode' | 'responseNode' | Expression;\n/**\n * The HTTP method of the Webhook call\n * @displayOptions.show { resume: [\"webhook\"] }\n * @default GET\n */\n httpMethod?: 'DELETE' | 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT' | Expression;\n/**\n * The HTTP Response code to return\n * @displayOptions.show { resume: [\"webhook\"] }\n * @displayOptions.hide { responseMode: [\"responseNode\"] }\n * @default 200\n */\n responseCode?: number | Expression;\n/**\n * What data should be returned. If it should return all items as an array or only the first item as object.\n * @displayOptions.show { responseMode: [\"lastNode\"], resume: [\"webhook\"] }\n * @default firstEntryJson\n */\n responseData?: 'allEntries' | 'firstEntryJson' | 'firstEntryBinary' | 'noData' | Expression;\n/**\n * Name of the binary property to return\n * @displayOptions.show { responseData: [\"firstEntryBinary\"], resume: [\"webhook\"] }\n * @default data\n */\n responseBinaryPropertyName?: string | Expression | PlaceholderValue;\n/**\n * Whether to limit the time this node should wait for a user response before execution resumes\n * @displayOptions.show { resume: [\"webhook\", \"form\"] }\n * @default false\n */\n limitWaitTime?: boolean | Expression;\n/**\n * Sets the condition for the execution to resume. Can be a specified date or after some time.\n * @displayOptions.show { limitWaitTime: [true], resume: [\"webhook\", \"form\"] }\n * @default afterTimeInterval\n */\n limitType?: 'afterTimeInterval' | 'atSpecifiedTime' | Expression;\n/**\n * The time to wait\n * @displayOptions.show { limitType: [\"afterTimeInterval\"], limitWaitTime: [true], resume: [\"webhook\", \"form\"] }\n * @default 1\n */\n resumeAmount?: number | Expression;\n/**\n * Unit of the interval value\n * @displayOptions.show { limitType: [\"afterTimeInterval\"], limitWaitTime: [true], resume: [\"webhook\", \"form\"] }\n * @default hours\n */\n resumeUnit?: 'seconds' | 'minutes' | 'hours' | 'days' | Expression;\n/**\n * Continue execution after the specified date and time\n * @displayOptions.show { limitType: [\"atSpecifiedTime\"], limitWaitTime: [true], resume: [\"webhook\", \"form\"] }\n */\n maxDateAndTime?: string | Expression;\n/**\n * Options\n * @displayOptions.show { resume: [\"webhook\", \"form\"] }\n * @default {}\n */\n options?: {\n /** Whether the webhook will receive binary data\n * @displayOptions.show { /httpMethod: [\"PATCH\", \"PUT\", \"POST\"] }\n * @default false\n */\n binaryData?: boolean | Expression;\n /** If the data gets received via \"Form-Data Multipart\" it will be the prefix and a number starting with 0 will be attached to it\n * @hint The name of the output binary field to put the file in\n * @displayOptions.show { binaryData: [true] }\n * @default data\n */\n binaryPropertyName?: string | Expression | PlaceholderValue;\n /** The name of the output field to put any binary file data in. Only relevant if binary data is received.\n * @default data\n */\n binaryPropertyName?: string | Expression | PlaceholderValue;\n /** Whether to ignore requests from bots like link previewers and web crawlers\n * @default false\n */\n ignoreBots?: boolean | Expression;\n /** Comma-separated list of allowed IP addresses or CIDR ranges. Leave empty to allow all IPs.\n */\n ipWhitelist?: string | Expression | PlaceholderValue;\n /** Whether to send any body in the response\n * @displayOptions.show { /responseMode: [\"onReceived\"] }\n * @displayOptions.hide { rawBody: [true] }\n * @default false\n */\n noResponseBody?: boolean | Expression;\n /** Raw body (binary)\n * @displayOptions.hide { binaryData: [true], noResponseBody: [true] }\n * @default false\n */\n rawBody?: boolean | Expression;\n /** Whether to return the raw body\n * @displayOptions.hide { noResponseBody: [true] }\n * @default false\n */\n rawBody?: boolean | Expression;\n /** Custom response data to send\n * @displayOptions.show { /responseMode: [\"onReceived\"] }\n * @displayOptions.hide { noResponseBody: [true] }\n */\n responseData?: string | Expression | PlaceholderValue;\n /** Set a custom content-type to return if another one as the \"application/json\" should be returned\n * @displayOptions.show { /responseData: [\"firstEntryJson\"], /responseMode: [\"lastNode\"] }\n */\n responseContentType?: string | Expression | PlaceholderValue;\n /** Add headers to the webhook response\n * @default {}\n */\n responseHeaders?: {\n /** Entries\n */\n entries?: Array<{\n /** Name of the header\n */\n name?: string | Expression | PlaceholderValue;\n /** Value of the header\n */\n value?: string | Expression | PlaceholderValue;\n }>;\n };\n /** Name of the property to return the data of instead of the whole JSON\n * @displayOptions.show { /responseData: [\"firstEntryJson\"], /responseMode: [\"lastNode\"] }\n * @default data\n */\n responsePropertyName?: string | Expression | PlaceholderValue;\n /** This suffix path will be appended to the restart URL. Helpful when using multiple wait nodes.\n */\n webhookSuffix?: string;\n /** Whether to include the link “Form automated with n8n” at the bottom of the form\n * @default true\n */\n appendAttribution?: boolean | Expression;\n /** Form Response\n * @default {\"values\":{\"respondWith\":\"text\"}}\n */\n respondWithOptions?: {\n /** Values\n */\n values?: {\n /** Respond With\n * @default text\n */\n respondWith?: 'text' | 'redirect' | Expression;\n /** The text displayed to users after they fill the form. Leave it empty if don't want to show any additional text.\n * @displayOptions.show { respondWith: [\"text\"] }\n * @default Your response has been recorded\n */\n formSubmittedText?: string | Expression | PlaceholderValue;\n /** The URL to redirect users to after they fill the form. Must be a valid URL.\n * @displayOptions.show { respondWith: [\"redirect\"] }\n */\n redirectUrl?: string | Expression | PlaceholderValue;\n };\n };\n };\n}\n\nexport interface WaitV11Credentials {\n httpBasicAuth: CredentialReference;\n httpHeaderAuth: CredentialReference;\n jwtAuth: CredentialReference;\n}\n\ninterface WaitV11NodeBase {\n type: 'n8n-nodes-base.wait';\n version: 1.1;\n credentials?: WaitV11Credentials;\n}\n\nexport type WaitV11ParamsNode = WaitV11NodeBase & {\n config: NodeConfig;\n};\n\nexport type WaitV11Node = WaitV11ParamsNode;"},{"nodeType":"n8n-nodes-base.set","content":"","error":"Node 'n8n-nodes-base.set' requires mode discriminator. Available modes: manual, raw."}]}} +{"kind":"tool-call","stepId":9,"agentRole":"workflow-builder","toolName":"nodes","input":{"action":"type-definition","nodeTypes":[{"nodeType":"n8n-nodes-base.set","mode":"manual"}]},"output":{"definitions":[{"nodeType":"n8n-nodes-base.set","version":"v34","content":"/**\n * Edit Fields (Set) Node - Version 3.4\n * Discriminator: mode=manual\n */\n\n\n// Helper types for special n8n fields\n/**\n * Assignment type determines how the value is interpreted.\n * - string: Direct string value or expression evaluating to string\n * - number: Direct number value or expression evaluating to number\n * - boolean: Direct boolean value or expression evaluating to boolean\n * - array: Expression that evaluates to an array, e.g. ={{ [1, 2, 3] }} or ={{ $json.items }}\n * - object: Expression that evaluates to a plain object (not an array — use the array type for arrays), e.g. ={{ { key: 'value' } }} or ={{ $json.data }}\n * - binary: Property name of binary data in the input item, or expression to access binary data from previous nodes, e.g. ={{ $('Node').item.binary.data }}\n */\ntype AssignmentType = 'string' | 'number' | 'boolean' | 'array' | 'object' | 'binary';\ntype AssignmentCollectionValue = { assignments: Array<{ id: string; name: string; value: unknown; type: AssignmentType }> };\n\n/** Edit item fields one by one */\nexport type SetV34ManualParams = {\n mode: 'manual';\n/**\n * Whether this item should be duplicated a set number of times\n * @default false\n */\n duplicateItem?: boolean | Expression;\n/**\n * How many times the item should be duplicated, mainly used for testing and debugging\n * @displayOptions.show { duplicateItem: [true] }\n * @default 0\n */\n duplicateCount?: number | Expression;\n/**\n * Fields to Set\n * @default {}\n */\n assignments?: AssignmentCollectionValue;\n/**\n * Whether to pass to the output all the input fields (along with the fields set in 'Fields to Set')\n * @default false\n */\n includeOtherFields?: boolean | Expression;\n/**\n * How to select the fields you want to include in your output items\n * @displayOptions.hide { /includeOtherFields: [false] }\n * @default all\n */\n include?: 'all' | 'selected' | 'except' | Expression;\n/**\n * Comma-separated list of the field names you want to include in the output. You can drag the selected fields from the input panel.\n * @displayOptions.show { include: [\"selected\"], /includeOtherFields: [true] }\n */\n includeFields?: string | Expression | PlaceholderValue;\n/**\n * Comma-separated list of the field names you want to exclude from the output. You can drag the selected fields from the input panel.\n * @displayOptions.show { include: [\"except\"], /includeOtherFields: [true] }\n */\n excludeFields?: string | Expression | PlaceholderValue;\n options?: {\n /** Whether binary data should be included if present in the input item\n * @default true\n */\n includeBinary?: boolean | Expression;\n /** Whether binary data should be stripped from the input item. Only applies when \"Include Other Input Fields\" is enabled.\n * @displayOptions.show { /includeOtherFields: [true] }\n * @default true\n */\n stripBinary?: boolean | Expression;\n /** Whether to ignore field type errors and apply a less strict type conversion\n * @default false\n */\n ignoreConversionErrors?: boolean | Expression;\n /** By default, dot-notation is used in property names. This means that \"a.b\" will set the property \"b\" underneath \"a\" so { \"a\": { \"b\": value} }. If that is not intended this can be deactivated, it will then set { \"a.b\": value } instead.\n * @default true\n */\n dotNotation?: boolean | Expression;\n };\n};\n\nexport type SetV34ManualNode = {\n type: 'n8n-nodes-base.set';\n version: 3.4;\n config: NodeConfig;\n};"}]}} +{"kind":"tool-call","stepId":10,"agentRole":"workflow-builder","toolName":"build-workflow","input":{"code":"import { workflow, node, trigger } from '@n8n/workflow-sdk';\n\nconst manualTrigger = trigger({\n type: 'n8n-nodes-base.manualTrigger',\n version: 1,\n config: { name: 'Manual Trigger' }\n});\n\nconst waitNode = node({\n type: 'n8n-nodes-base.wait',\n version: 1.1,\n config: {\n name: 'Wait 1 Second',\n parameters: {\n resume: 'timeInterval',\n amount: 1,\n unit: 'seconds'\n }\n }\n});\n\nconst setNode = node({\n type: 'n8n-nodes-base.set',\n version: 3.4,\n config: {\n name: 'running state test',\n parameters: {\n mode: 'manual',\n assignments: { assignments: [] }\n }\n }\n});\n\nexport default workflow('running-state-test', 'Running State Test')\n .add(manualTrigger)\n .to(waitNode)\n .to(setNode);\n","name":"Running State Test"},"output":{"success":true,"workflowId":"9nFJ6aBXnqaFIPYA"}} +{"kind":"header","version":1,"testName":"recording","recordedAt":"2026-04-28T10:58:43.169Z"} +{"kind":"tool-call","stepId":1,"agentRole":"orchestrator","toolName":"workflows","input":{"action":"list","query":"Running State Test"},"output":{"workflows":[{"id":"9nFJ6aBXnqaFIPYA","name":"Running State Test","versionId":"13a68c2f-8588-45ad-8651-4864a6265907","activeVersionId":null,"createdAt":"2026-04-28T10:58:40.693Z","updatedAt":"2026-04-28T10:58:40.765Z"}]}} +{"kind":"tool-call","stepId":2,"agentRole":"orchestrator","toolName":"workflows","input":{"action":"get","workflowId":"9nFJ6aBXnqaFIPYA"},"output":{"id":"9nFJ6aBXnqaFIPYA","name":"Running State Test","versionId":"13a68c2f-8588-45ad-8651-4864a6265907","activeVersionId":null,"createdAt":"2026-04-28T10:58:40.693Z","updatedAt":"2026-04-28T10:58:40.765Z","nodes":[{"name":"Manual Trigger","type":"n8n-nodes-base.manualTrigger","position":[0,0]},{"name":"Wait 1 Second","type":"n8n-nodes-base.wait","parameters":{"resume":"timeInterval","amount":1,"unit":"seconds"},"position":[224,0],"webhookId":"4b1f996e-cdde-4158-bd4e-c4a9a5538cd4"},{"name":"running state test","type":"n8n-nodes-base.set","parameters":{"mode":"manual","assignments":{"assignments":[]}},"position":[448,0]}],"connections":{"Manual Trigger":{"main":[[{"node":"Wait 1 Second","type":"main","index":0}]]},"Wait 1 Second":{"main":[[{"node":"running state test","type":"main","index":0}]]}},"settings":{}}} +{"kind":"tool-suspend","stepId":3,"agentRole":"orchestrator","toolName":"executions","input":{"action":"run","workflowId":"9nFJ6aBXnqaFIPYA","timeout":30000},"output":{"executionId":"","status":"error","denied":true,"reason":"Awaiting confirmation"},"suspendPayload":{}} +{"kind":"tool-resume","stepId":4,"agentRole":"orchestrator","toolName":"executions","input":{"action":"run","workflowId":"9nFJ6aBXnqaFIPYA","timeout":30000},"output":{"executionId":"5","status":"success","data":{"Manual Trigger":"\n[\n {}\n]\n","Wait 1 Second":"\n[\n {}\n]\n","running state test":"\n[\n {}\n]\n"},"startedAt":"2026-04-28T10:58:51.065Z","finishedAt":"2026-04-28T10:58:52.082Z"},"resumeData":{"approved":true}} +{"kind":"tool-call","stepId":5,"agentRole":"orchestrator","toolName":"complete-checkpoint","input":{"taskId":"chk-running-state-test","status":"succeeded","result":"Execution 5 completed successfully in ~1 second. All nodes ran in order: Manual Trigger → Wait 1 Second → running state test (Set). No errors.","outcome":{"executionId":"5","status":"success","durationMs":1017}},"output":{"result":"Checkpoint chk-running-state-test marked succeeded.","ok":true}} +{"kind":"header","version":1,"testName":"recording","recordedAt":"2026-04-28T10:58:57.388Z"} diff --git a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949867-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949867-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index ee2b8f9c353..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949867-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["1838"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=99BoBs39y78drrQ7Enem0r75XF2vQzu4PonTi1kISwo-1775805914.0108118-1.0.1.1-5.uZyPVNmeArANHIbseXd0y77kcoNAS_RC8Shw1VaRo; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=1843"], - "request-id": ["req_011CZuh61QMUXct3H2cG3dnQ"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:25:14Z"], - "anthropic-ratelimit-tokens-remaining": ["26977000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:25:14Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:25:14Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:25:14Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22477000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:25:15 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9ea004328bf7e508-TXL"] - }, - "cookies": { - "_cfuvid": "99BoBs39y78drrQ7Enem0r75XF2vQzu4PonTi1kISwo-1775805914.0108118-1.0.1.1-5.uZyPVNmeArANHIbseXd0y77kcoNAS_RC8Shw1VaRo" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01BYR6SVKjxjbskErcn1uPzc\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":898,\"cache_creation_input_tokens\":12360,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":12360,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":34,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01VdMciqfJf3wXmzw1MN94TL\",\"name\":\"build-workflow-with-agent\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"task\\\": \\\"Bu\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ild a \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"simple wo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rkflo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"w with \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"a manu\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"al\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" trigger\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" and\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" a Se\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t node. Nam\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e the workf\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"low \\\\\\\"a\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rtifac\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t click te\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"st\\\\\\\". T\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"he Set n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ode\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" s\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"hould be na\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"med \\\\\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"arti\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"fact cli\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ck test\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\\\\" \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"as wel\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"l.\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"c\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"onversationC\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"onte\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"xt\\\": \\\"User w\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ants a \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"simple wor\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"kflow\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" with a manu\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"al \"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tri\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"gger a\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nd \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"a set nod\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e called \\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"ar\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tifact cl\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ick te\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"st\\\\\\\".\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":898,\"cache_creation_input_tokens\":12360,\"cache_read_input_tokens\":0,\"output_tokens\":128} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxQllSNlNWS2p4amJza0VyY24xdVB6YyIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjg5OCwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxMjM2MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjEyMzYwLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6MzQsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0YXJ0CmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RhcnQiLCJpbmRleCI6MCwiY29udGVudF9ibG9jayI6eyJ0eXBlIjoidG9vbF91c2UiLCJpZCI6InRvb2x1XzAxVmRNY2lxZkpmM3dYbXp3MU1OOTRUTCIsIm5hbWUiOiJidWlsZC13b3JrZmxvdy13aXRoLWFnZW50IiwiaW5wdXQiOnt9LCJjYWxsZXIiOnsidHlwZSI6ImRpcmVjdCJ9fSB9CgpldmVudDogcGluZwpkYXRhOiB7InR5cGUiOiAicGluZyJ9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IntcInRhc2tcIjogXCJCdSJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImlsZCBhICJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InNpbXBsZSB3byJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InJrZmxvIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidyB3aXRoICJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiYSBtYW51In0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImFsIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiB0cmlnZ2VyIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIGFuZCJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgYSBTZSJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidCBub2RlLiBOYW0ifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZSB0aGUgd29ya2YifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJsb3cgXFxcImEifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InJ0aWZhYyJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidCBjbGljayB0ZSJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InN0XFxcIi4gVCJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImhlIFNldCBuIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvZGUifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgcyJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiaG91bGQgYmUgbmEifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibWVkIFxcXCIifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhcnRpIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJmYWN0IGNsaSJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImNrIHRlc3QifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXFxcIiAifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhcyB3ZWwifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJsLlwiIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiLCBcImMifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvbnZlcnNhdGlvbkMifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvbnRlIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Inh0XCI6IFwiVXNlciB3In0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiYW50cyBhICJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJzaW1wbGUgd29yIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImtmbG93In0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiB3aXRoIGEgbWFudSJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiYWwgIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidHJpIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJnZ2VyIGEifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuZCAifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiYSBzZXQgbm9kIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZSBjYWxsZWQgXFwifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcImFyIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0aWZhY3QgY2wifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpY2sgdGUifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InN0XFxcIi5cIn0ifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoidG9vbF91c2UiLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjg5OCwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxMjM2MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsIm91dHB1dF90b2tlbnMiOjEyOH0gICAgICAgICAgICAgICB9CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgICAgICAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805949867-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949874-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949874-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index 5728e6a958f..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949874-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["1242"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=npLo.QiSpSUARn.NXFLECZExmsRpB8xPB5q1nW46s6s-1775805921.4736652-1.0.1.1-95EfV5ZB9LWTf3y2b8pmjwZpon6ho3gehjzm6cl_j2o; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=1244"], - "request-id": ["req_011CZuh6ZG1rpmLPEN4WDwMp"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:25:21Z"], - "anthropic-ratelimit-tokens-remaining": ["26976000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:25:21Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:25:21Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:25:21Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22476000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:25:22 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9ea004613b32e527-TXL"] - }, - "cookies": { - "_cfuvid": "npLo.QiSpSUARn.NXFLECZExmsRpB8xPB5q1nW46s6s-1775805921.4736652-1.0.1.1-95EfV5ZB9LWTf3y2b8pmjwZpon6ho3gehjzm6cl_j2o" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_0195pi12XXNj9gzhk6HPfX9Z\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":1096,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":12360,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Building\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" your \\\"artifact click test\\\" workflow now!\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":1096,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":12360,\"output_tokens\":13} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxOTVwaTEyWFhOajlnemhrNkhQZlg5WiIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEwOTYsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjEyMzYwLCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjowLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6MSwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiJ9ICAgICAgICAgfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiJCdWlsZGluZyJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIgeW91ciBcImFydGlmYWN0IGNsaWNrIHRlc3RcIiB3b3JrZmxvdyBub3chIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX3N0b3AKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdG9wIiwiaW5kZXgiOjAgfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEwOTYsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjEyMzYwLCJvdXRwdXRfdG9rZW5zIjoxM30gICAgICAgICAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX3N0b3AKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdG9wIiAgICAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805949874-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949876-unknown-host-POST-_v1_messages-18622610.json b/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949876-unknown-host-POST-_v1_messages-18622610.json deleted file mode 100644 index 88064ea2f4e..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949876-unknown-host-POST-_v1_messages-18622610.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "You generate a short descriptive title for a conversation", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["992"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=VApID_nWlbeCpLAsPadbqzTHqNT8Otes0x7.lLub01Q-1775805924.025991-1.0.1.1-vVL8To_GI6SQnSNFkauGyNd3J5fn5fiDiWQf1UL1Lhk; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=1027"], - "request-id": ["req_011CZuh6kREGtEybpFhad7L6"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:25:24Z"], - "anthropic-ratelimit-tokens-remaining": ["27000000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:25:24Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:25:25Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:25:24Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22500000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:25:25 GMT"], - "Content-Type": ["application/json"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "CF-RAY": ["9ea004712e609e00-TXL"] - }, - "cookies": { - "_cfuvid": "VApID_nWlbeCpLAsPadbqzTHqNT8Otes0x7.lLub01Q-1775805924.025991-1.0.1.1-vVL8To_GI6SQnSNFkauGyNd3J5fn5fiDiWQf1UL1Lhk" - }, - "body": { - "contentType": "application/json", - "type": "JSON", - "json": { - "model": "claude-sonnet-4-6", - "id": "msg_01FtaPGtz3wBhwx43Tj6j2mY", - "type": "message", - "role": "assistant", - "content": [ - { - "type": "text", - "text": "Simple workflow with manual trigger and Set node" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "stop_details": null, - "usage": { - "input_tokens": 136, - "cache_creation_input_tokens": 0, - "cache_read_input_tokens": 0, - "cache_creation": { - "ephemeral_5m_input_tokens": 0, - "ephemeral_1h_input_tokens": 0 - }, - "output_tokens": 11, - "service_tier": "standard", - "inference_geo": "global" - } - }, - "rawBytes": "eyJtb2RlbCI6ImNsYXVkZS1zb25uZXQtNC02IiwiaWQiOiJtc2dfMDFGdGFQR3R6M3dCaHd4NDNUajZqMm1ZIiwidHlwZSI6Im1lc3NhZ2UiLCJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiU2ltcGxlIHdvcmtmbG93IHdpdGggbWFudWFsIHRyaWdnZXIgYW5kIFNldCBub2RlIn1dLCJzdG9wX3JlYXNvbiI6ImVuZF90dXJuIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEzNiwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfY3JlYXRpb24iOnsiZXBoZW1lcmFsXzVtX2lucHV0X3Rva2VucyI6MCwiZXBoZW1lcmFsXzFoX2lucHV0X3Rva2VucyI6MH0sIm91dHB1dF90b2tlbnMiOjExLCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0=" - } - }, - "id": "1775805949876-unknown-host-POST-_v1_messages-18622610.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949884-unknown-host-POST-_v1_messages-4d1c93f7.json b/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949884-unknown-host-POST-_v1_messages-4d1c93f7.json deleted file mode 100644 index 3637e416901..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949884-unknown-host-POST-_v1_messages-4d1c93f7.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are an expert n8n workflow builder. You generate com", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["2054"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=5y3IjEz8KF4_z1RXu6wVVbzAqmEhpEAExLPDuxpPmKQ-1775805921.6433945-1.0.1.1-Iix0gdPsVaCDq7qeBTn3gZ2DEvzfA5R.odZshGOqT5s; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=2056"], - "request-id": ["req_011CZuh6ZyvhPMTzVGihNxRP"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:25:21Z"], - "anthropic-ratelimit-tokens-remaining": ["26975000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:25:21Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:25:21Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:25:21Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22475000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:25:23 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9ea004624816e51d-TXL"] - }, - "cookies": { - "_cfuvid": "5y3IjEz8KF4_z1RXu6wVVbzAqmEhpEAExLPDuxpPmKQ-1775805921.6433945-1.0.1.1-Iix0gdPsVaCDq7qeBTn3gZ2DEvzfA5R.odZshGOqT5s" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01AxEDgftDbhnSpFy9jjxRzF\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":384,\"cache_creation_input_tokens\":16176,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":16176,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":49,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01WCqov4Vy7MeM34xUAvRGiG\",\"name\":\"build-workflow\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"name\\\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"a\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rtif\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"act click te\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"st\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"code\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": \\\"\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"import\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" { workflo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"w, node,\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" trigger \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"} from\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" '@n8n/w\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"orkflow\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"-sdk';\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n\\\\nconst \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"manualTrigg\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"er \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"= tr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"igger({\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" type: 'n8n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"-nodes-base\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\".manualT\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rigger'\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\",\\\\n ver\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"sion:\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" 1,\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" confi\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"g: { name\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": 'When\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" clic\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"king \\\\\\\"Test \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"workfl\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ow\\\\\\\"' }\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n});\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n\\\\ncon\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"st setNo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"de\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" = node\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"({\\\\n type:\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" 'n8n-nodes-\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"base.set',\\\\\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n vers\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ion: 3.\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"4,\\\\n co\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"nfig:\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" {\\\\n na\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"me: 'artifac\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t click tes\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t',\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" parameter\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"s: {\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" assignments\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" as\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"signments: [\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"]\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" },\\\\n \"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"opt\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ions: {}\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" }\\\\n \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" }\\\\n});\\\\n\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"export d\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ef\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"au\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"lt workflow(\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"'artifact-cl\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ick-test\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"', 'art\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ifact cl\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ick test\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"')\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n .ad\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"d(manualTr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"igger\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\")\\\\n .to\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"(setNode);\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":384,\"cache_creation_input_tokens\":16176,\"cache_read_input_tokens\":0,\"output_tokens\":262} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxQXhFRGdmdERiaG5TcEZ5OWpqeFJ6RiIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjM4NCwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxNjE3NiwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjE2MTc2LCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6NDksInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0b29sX3VzZSIsImlkIjoidG9vbHVfMDFXQ3FvdjRWeTdNZU0zNHhVQXZSR2lHIiwibmFtZSI6ImJ1aWxkLXdvcmtmbG93IiwiaW5wdXQiOnt9LCJjYWxsZXIiOnsidHlwZSI6ImRpcmVjdCJ9fSAgICB9CgpldmVudDogcGluZwpkYXRhOiB7InR5cGUiOiAicGluZyJ9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ7XCJuYW1lXCI6ICJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXCJhIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJydGlmIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhY3QgY2xpY2sgdGUifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoic3RcIiJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiLCBcImNvZGVcIiJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiI6IFwiXFxuIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImltcG9ydCJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiB7IHdvcmtmbG8ifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ3LCBub2RlLCJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIHRyaWdnZXIgIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoifSBmcm9tIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgJ0BuOG4vdyJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvcmtmbG93In0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiLXNkayc7In0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXFxuXFxuY29uc3QgIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibWFudWFsVHJpZ2cifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZXIgIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiI9IHRyIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImlnZ2VyKHtcXG4gIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiB0eXBlOiAnbjhuIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiLW5vZGVzLWJhc2UifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Ii5tYW51YWxUIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJyaWdnZXInIn0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiLFxcbiAgdmVyIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InNpb246In0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIDEsXFxuICJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBjb25maSJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJnOiB7IG5hbWUifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IjogJ1doZW4ifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgY2xpYyJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImtpbmcgXFxcIlRlc3QgIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ3b3JrZmwifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im93XFxcIicgfSJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcXG59KTsifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IlxcblxcbmNvbiJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InN0IHNldE5vIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJkZSJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiA9IG5vZGUifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Iih7XFxuICB0eXBlOiJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiICduOG4tbm9kZXMtIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiYmFzZS5zZXQnLFxcIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibiAgdmVycyJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImlvbjogMy4ifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiNCxcXG4gIGNvIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuZmlnOiJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIHtcXG4gICAgbmEifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJtZTogJ2FydGlmYWMifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InQgY2xpY2sgdGVzIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidCcsIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXFxuICAgIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBwYXJhbWV0ZXIifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJzOiB7XFxuICAgICAifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIGFzc2lnbm1lbnRzIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiOiAifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IntcXG4gICJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgICAgICBhcyJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoic2lnbm1lbnRzOiBbIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Il1cXG4gIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiICAgIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiAgfSxcXG4gICAgICAifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvcHQifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiaW9uczoge31cXG4ifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiICAgIH1cXG4gIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgfVxcbn0pO1xcblxcbiJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImV4cG9ydCBkIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZWYifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhdSJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Imx0IHdvcmtmbG93KCJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiInYXJ0aWZhY3QtY2wifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpY2stdGVzdCJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiJywgJ2FydCJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiaWZhY3QgY2wifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpY2sgdGVzdCJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiJykifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcXG4gIC5hZCJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJkKG1hbnVhbFRyIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJpZ2dlciJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiKVxcbiAgLnRvIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiKHNldE5vZGUpO1xcIn0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiblwifSJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX2RlbHRhCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2VfZGVsdGEiLCJkZWx0YSI6eyJzdG9wX3JlYXNvbiI6InRvb2xfdXNlIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsfSwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjozODQsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MTYxNzYsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJvdXRwdXRfdG9rZW5zIjoyNjJ9ICAgICAgICB9CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgICAgICAgICAgIH0KCg==", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805949884-unknown-host-POST-_v1_messages-4d1c93f7.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949891-unknown-host-POST-_v1_messages-4d1c93f7.json b/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949891-unknown-host-POST-_v1_messages-4d1c93f7.json deleted file mode 100644 index e064fe67592..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949891-unknown-host-POST-_v1_messages-4d1c93f7.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are an expert n8n workflow builder. You generate com", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["782"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=ZZWtRjPmEQu9DR4YUbo4pyuIcIU1WjeHJP1vRX9L0d4-1775805928.0917044-1.0.1.1-n9dJI34I84KgsprACweehy5A3oxvgA0AVIm5QHA5FZc; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=784"], - "request-id": ["req_011CZuh73Z7b4q9TibJFQD6B"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:25:28Z"], - "anthropic-ratelimit-tokens-remaining": ["26975000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:25:28Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:25:28Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:25:28Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22475000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:25:28 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9ea0048a9d15e508-TXL"] - }, - "cookies": { - "_cfuvid": "ZZWtRjPmEQu9DR4YUbo4pyuIcIU1WjeHJP1vRX9L0d4-1775805928.0917044-1.0.1.1-n9dJI34I84KgsprACweehy5A3oxvgA0AVIm5QHA5FZc" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_011ZXi4fnvre2gBqfSfEqbhj\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":683,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":16176,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}}}\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Done\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" — the workflow \\\"artifact click test\\\" is ready with a manual trigger connected to a Set node named \\\"artifact click test\\\".\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":683,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":16176,\"output_tokens\":29}}\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxMVpYaTRmbnZyZTJnQnFmU2ZFcWJoaiIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjY4MywiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTYxNzYsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjAsImVwaGVtZXJhbF8xaF9pbnB1dF90b2tlbnMiOjB9LCJvdXRwdXRfdG9rZW5zIjoxLCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX19CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRleHQiLCJ0ZXh0IjoiIn0gICAgICAgfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiJEb25lIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiIOKAlCB0aGUgd29ya2Zsb3cgXCJhcnRpZmFjdCBjbGljayB0ZXN0XCIgaXMgcmVhZHkgd2l0aCBhIG1hbnVhbCB0cmlnZ2VyIGNvbm5lY3RlZCB0byBhIFNldCBub2RlIG5hbWVkIFwiYXJ0aWZhY3QgY2xpY2sgdGVzdFwiLiJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX2RlbHRhCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2VfZGVsdGEiLCJkZWx0YSI6eyJzdG9wX3JlYXNvbiI6ImVuZF90dXJuIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsfSwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjo2ODMsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjE2MTc2LCJvdXRwdXRfdG9rZW5zIjoyOX19CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgICAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805949891-unknown-host-POST-_v1_messages-4d1c93f7.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949895-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949895-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index b91e00f0202..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949895-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["2104"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=KHMVN87EWtv5eWxUmxHTwh0ck89i2AWOOp_uEdDXwYA-1775805932.6827078-1.0.1.1-_sBq2BCmtfuk1QXiwHKGoEyyvjzOmgHdhm0dKk4Z9us; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=2107"], - "request-id": ["req_011CZuh7PDYpP5PcrdhfmpXE"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:25:32Z"], - "anthropic-ratelimit-tokens-remaining": ["26976000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:25:32Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:25:32Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:25:32Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22476000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:25:34 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9ea004a74b8b1a34-TXL"] - }, - "cookies": { - "_cfuvid": "KHMVN87EWtv5eWxUmxHTwh0ck89i2AWOOp_uEdDXwYA-1775805932.6827078-1.0.1.1-_sBq2BCmtfuk1QXiwHKGoEyyvjzOmgHdhm0dKk4Z9us" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_017PpgU42UzvvpQ3Wr4unYD3\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":1186,\"cache_creation_input_tokens\":12360,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":12360,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Your\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" workflow **\\\"artifact click test\\\"** is ready! It has a Manual Trigger connected to a Set node named \\\"artifact click test\\\".\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" You can run it anytime using the manual trigger.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01GNCZMYajSUprWBSqYyiy9i\",\"name\":\"updateWorkingMemory\",\"input\":{},\"caller\":{\"type\":\"direct\"}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"memory\\\": \\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"# User Con\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"text\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n- **Nam\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e*\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"*:\\\\n- **Ro\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"le**:\\\\n- **O\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rganization*\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"*:\\\\n\\\\n# \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Workfl\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ow Prefe\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rence\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"s\\\\n- **\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Pref\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"erred tr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"igger type\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"s**:\\\\n- *\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"*Common i\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ntegrations \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"used**:\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n-\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" **Workf\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"low\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" naming c\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"onvent\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ion\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"s**:\\\\n- \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"**Error\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" handli\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ng patter\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ns**:\\\\n\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"# Acti\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ve Proje\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ct\\\\n- **Pr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ojec\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t**: artifa\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ct clic\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"k test wo\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rkflow\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n- **Statu\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"s**: Comp\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"leted\\\\n- **K\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ey d\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"etails**:\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Simple work\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"flow \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"wit\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"h a manu\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"al trigger \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"and a Set no\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"de name\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"d \\\\\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"artifact cl\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ick tes\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t\\\\\\\"\\\\n\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"# Known\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Issues\\\\n<\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"!--\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Only unreso\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"lved issu\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"es. R\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"emov\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"e when fix\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ed. -->\\\\n\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":1186,\"cache_creation_input_tokens\":12360,\"cache_read_input_tokens\":0,\"output_tokens\":217} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxN1BwZ1U0MlV6dnZwUTNXcjR1bllEMyIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjExODYsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MTIzNjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjoxMjM2MCwiZXBoZW1lcmFsXzFoX2lucHV0X3Rva2VucyI6MH0sIm91dHB1dF90b2tlbnMiOjEsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRleHQiLCJ0ZXh0IjoiIn0gfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiJZb3VyIn0gICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIgd29ya2Zsb3cgKipcImFydGlmYWN0IGNsaWNrIHRlc3RcIioqIGlzIHJlYWR5ISBJdCBoYXMgYSBNYW51YWwgVHJpZ2dlciBjb25uZWN0ZWQgdG8gYSBTZXQgbm9kZSBuYW1lZCBcImFydGlmYWN0IGNsaWNrIHRlc3RcIi4ifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IiBZb3UgY2FuIHJ1biBpdCBhbnl0aW1lIHVzaW5nIHRoZSBtYW51YWwgdHJpZ2dlci4ifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RvcApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0b3AiLCJpbmRleCI6MCB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjEsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRvb2xfdXNlIiwiaWQiOiJ0b29sdV8wMUdOQ1pNWWFqU1VwcldCU3FZeWl5OWkiLCJuYW1lIjoidXBkYXRlV29ya2luZ01lbW9yeSIsImlucHV0Ijp7fSwiY2FsbGVyIjp7InR5cGUiOiJkaXJlY3QifX0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ7XCJtZW1vcnlcIjogXCIifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIyBVc2VyIENvbiJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidGV4dFxcIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuLSAqKk5hbSJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZSoifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIqOlxcbi0gKipSbyJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibGUqKjpcXG4tICoqTyJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJyZ2FuaXphdGlvbioifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Iio6XFxuXFxuIyAifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiV29ya2ZsIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvdyBQcmVmZSJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InJlbmNlIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoic1xcbi0gKioifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiUHJlZiJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlcnJlZCB0ciJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImlnZ2VyIHR5cGUifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJzKio6XFxuLSAqIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IipDb21tb24gaSJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im50ZWdyYXRpb25zICJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InVzZWQqKjoifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiXFxuLSJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgKipXb3JrZiJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibG93In0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgbmFtaW5nIGMifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoib252ZW50In0gICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiaW9uIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InMqKjpcXG4tICJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IioqRXJyb3IifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgaGFuZGxpIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuZyBwYXR0ZXIifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJucyoqOlxcblxcbiJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIjIEFjdGkifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidmUgUHJvamUifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJjdFxcbi0gKipQciJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvamVjIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0Kio6IGFydGlmYSJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiY3QgY2xpYyJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiayB0ZXN0IHdvIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJya2Zsb3cifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJcXG4tICoqU3RhdHUifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoicyoqOiBDb21wIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJsZXRlZFxcbi0gKipLIn19CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZXkgZCJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJldGFpbHMqKjoifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgU2ltcGxlIHdvcmsifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJmbG93ICJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoid2l0In0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImggYSBtYW51In0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImFsIHRyaWdnZXIgIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImFuZCBhIFNldCBubyJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZGUgbmFtZSJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImQgXFxcIiJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImFydGlmYWN0IGNsIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImljayB0ZXMifX0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0XFxcIlxcblxcbiJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIjIEtub3duIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgSXNzdWVzXFxuPCJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiEtLSJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgT25seSB1bnJlc28ifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Imx2ZWQgaXNzdSJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjEsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZXMuIFIifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlbW92In0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MSwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJlIHdoZW4gZml4In0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjoxLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVkLiAtLT5cXG5cIn0ifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RvcApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0b3AiLCJpbmRleCI6MSAgICAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX2RlbHRhCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2VfZGVsdGEiLCJkZWx0YSI6eyJzdG9wX3JlYXNvbiI6InRvb2xfdXNlIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsfSwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjoxMTg2LCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjEyMzYwLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MCwib3V0cHV0X3Rva2VucyI6MjE3fSAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805949895-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949917-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949917-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index 55e11735c60..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1775805949917-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["4448"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=4qYQoTUCuYxVKPn_qUZsPCvtAVkrHRaP25y1MxXsWD0-1775805938.8596892-1.0.1.1-hpFm6U._DW8S7pWpkXKQXtztz5vAYP1YD1ku4rol8q8; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=4450"], - "request-id": ["req_011CZuh7qi1BXgmyAuzoUvgi"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:25:39Z"], - "anthropic-ratelimit-tokens-remaining": ["26976000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:25:39Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:25:39Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:25:39Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22476000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:25:43 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9ea004cdda1f3237-TXL"] - }, - "cookies": { - "_cfuvid": "4qYQoTUCuYxVKPn_qUZsPCvtAVkrHRaP25y1MxXsWD0-1775805938.8596892-1.0.1.1-hpFm6U._DW8S7pWpkXKQXtztz5vAYP1YD1ku4rol8q8" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_016rujCeP96cM6BdQdvJpKJq\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":1419,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":12360,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":3,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Your workflow **\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"\\\"artifact click test\\\"** is ready! It has a Manual Trigger connected to a Set node named \\\"artifact click test\\\". You can run it anytime using the manual trigger.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":1419,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":12360,\"output_tokens\":43} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxNnJ1akNlUDk2Y002QmRRZHZKcEtKcSIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjE0MTksImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjEyMzYwLCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjowLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6Mywic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRleHQiLCJ0ZXh0IjoiIn0gICAgICAgfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiJZb3VyIHdvcmtmbG93ICoqIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiJcImFydGlmYWN0IGNsaWNrIHRlc3RcIioqIGlzIHJlYWR5ISBJdCBoYXMgYSBNYW51YWwgVHJpZ2dlciBjb25uZWN0ZWQgdG8gYSBTZXQgbm9kZSBuYW1lZCBcImFydGlmYWN0IGNsaWNrIHRlc3RcIi4gWW91IGNhbiBydW4gaXQgYW55dGltZSB1c2luZyB0aGUgbWFudWFsIHRyaWdnZXIuIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RvcApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0b3AiLCJpbmRleCI6MCAgICAgICB9CgpldmVudDogbWVzc2FnZV9kZWx0YQpkYXRhOiB7InR5cGUiOiJtZXNzYWdlX2RlbHRhIiwiZGVsdGEiOnsic3RvcF9yZWFzb24iOiJlbmRfdHVybiIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInN0b3BfZGV0YWlscyI6bnVsbH0sInVzYWdlIjp7ImlucHV0X3Rva2VucyI6MTQxOSwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MTIzNjAsIm91dHB1dF90b2tlbnMiOjQzfSAgICAgfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICAgICAgICAgICAgICAgfQoK", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805949917-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1777373504109-unknown-host-POST-_v1_messages-3dba52c9.json b/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1777373504109-unknown-host-POST-_v1_messages-3dba52c9.json new file mode 100644 index 00000000000..4a7a5a0b5d6 --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-open-workflow-preview-when-clicking-artifact-card/1777373504109-unknown-host-POST-_v1_messages-3dba52c9.json @@ -0,0 +1,111 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde[\\s\\S]*\\\\n-\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" **Projec\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"t**:\\\\n- **S\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tat\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"us**:\\\\n-\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" **K\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ey detai\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ls**:\\\\n\\\\\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n# Known Is\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"sues\\\\n\\\\n- **Pr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"oject\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"**:\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"- **Sta\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tus*\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"*:\\\\n- **Key\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" det\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ails**:\\\\n\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"# Kno\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"wn Issues\\\\n\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\\n\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":1007,\"cache_creation_input_tokens\":12360,\"cache_read_input_tokens\":0,\"output_tokens\":180} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxQUVXY1ZLeVk2WGhINk5GNlNkS2pvciIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEwMDcsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MTIzNjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjoxMjM2MCwiZXBoZW1lcmFsXzFoX2lucHV0X3Rva2VucyI6MH0sIm91dHB1dF90b2tlbnMiOjU0LCJzZXJ2aWNlX3RpZXIiOiJzdGFuZGFyZCIsImluZmVyZW5jZV9nZW8iOiJnbG9iYWwifX0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0b29sX3VzZSIsImlkIjoidG9vbHVfMDFCREppcXhWVlNwYkxhRmRCb0ZnWjhMIiwibmFtZSI6InVwZGF0ZVdvcmtpbmdNZW1vcnkiLCJpbnB1dCI6e30sImNhbGxlciI6eyJ0eXBlIjoiZGlyZWN0In19ICAgICAgICAgIH0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIifSAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ7XCJtIn0gICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVtb3J5XCI6IFwiIn0gICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIjIFVzZXIgQyJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9udCJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZXh0XFxuLSAqIn0gICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IipOYW1lKiJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiKjpcXG4tICoqUiJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Im9sZSoqOlxcbiJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiItICoqT3JnYW5pemEifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidGlvbioqOlxcIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuXFxuIyBXb3JrZmwifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoib3cgUHIifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImVmZXJlbmNlc1xcbiJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiLSAqKlAifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJyZWZlcnIifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZWQgIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidHJpZ2dlciAifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InR5cGVzKio6XFxuLSAifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IioqQ29tbW9uIGluIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ0ZWdyYSJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoidGlvbnMgdXMifSAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZWQqIn0gICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIqOlxcbi0gIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IioqV29ya2Zsb3cgbiJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiYW1pbmcifSAgICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgY29udmVudGkifSAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJvbnMqKjpcXG4tICoifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIqRXJyb3IgaGFuZGwifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiaW5nIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgcGF0dGVyIn0gICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibnMqKjpcXG5cXCJ9IH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuIyBBY3RpdmUgUCJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoicm8ifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImplY3RcXG48ISJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiItLSBLZWVwIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBvbmx5IHRoZSBPTiJ9ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IkUgcHJvamUifSAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImN0IHRoZSB1c2VyIn0gICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgaSJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InMgY3VycmUifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibnRseSJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIgd29ya2luZyBvIn0gIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJuLiAifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiUmVwbCJ9ICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJhY2Ugd2hlIn0gICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoibiB0aGUgdXNlciAifSB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoic3dpdGNoZSJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InMgcHJvamVjdHMuICJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiItLT5cXG4tICoqUHIifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoib2plY3QifSAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IioqOlxcbiJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6Ii0gKipTdGEifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InR1cyoifSAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiIqOlxcbi0gKipLZXkifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBkZXQifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImFpbHMqKjpcXG5cXG4ifSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiMgS25vIn0gICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ3biBJc3N1ZXNcXG4ifSAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiPCEtLSJ9ICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6IiBPbmwifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6InkgdW5yZXNvbHZlZCJ9ICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIGlzc3Vlcy4ifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiIFJlbW92ZSB3In0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoiaW5wdXRfanNvbl9kZWx0YSIsInBhcnRpYWxfanNvbiI6ImhlbiBmaSJ9ICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6ImlucHV0X2pzb25fZGVsdGEiLCJwYXJ0aWFsX2pzb24iOiJ4ZSJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJpbnB1dF9qc29uX2RlbHRhIiwicGFydGlhbF9qc29uIjoiZC4gLS0+XFxuXCJ9In0gICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICAgICAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoidG9vbF91c2UiLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEwMDcsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MTIzNjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJvdXRwdXRfdG9rZW5zIjoxODB9ICAgfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICAgIH0KCg==", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805995519-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1775805995520-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1775805995520-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index 8c93cb07fbb..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1775805995520-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["762"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=URhDSEghonkCoTlCJLbGWy_Fp7LsoaXpqkMZGffnZA0-1775805954.1053233-1.0.1.1-YqhvhpRtyKYbNBlG7WYNbDEvxamXOPWRoI03jIaaoI0; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=763"], - "request-id": ["req_011CZuh8xmS6xJdVJMGz1uNn"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:25:54Z"], - "anthropic-ratelimit-tokens-remaining": ["26976000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:25:54Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:25:54Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:25:54Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22476000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:25:54 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9ea0052d2f204ae6-TXL"] - }, - "cookies": { - "_cfuvid": "URhDSEghonkCoTlCJLbGWy_Fp7LsoaXpqkMZGffnZA0-1775805954.1053233-1.0.1.1-YqhvhpRtyKYbNBlG7WYNbDEvxamXOPWRoI03jIaaoI0" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01VZzuQWW9JTt6cF5LD5VW9V\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":1203,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":12360,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Hey\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" there! 👋 It looks like your message came through, but it seems\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" like it might have been a test or got cut off. How can I help you today?\\n\\nWhether you need\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" to **build a workflow**, **debug an execution**, **manage\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" credentials**, or anything else in n8n — just let me know!\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":1203,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":12360,\"output_tokens\":72} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxVlp6dVFXVzlKVHQ2Y0Y1TEQ1Vlc5ViIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEyMDMsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjEyMzYwLCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjowLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6MSwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiJ9ICAgICAgICAgICB9CgpldmVudDogcGluZwpkYXRhOiB7InR5cGUiOiAicGluZyJ9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IkhleSJ9fQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIgdGhlcmUhIPCfkYsgSXQgbG9va3MgbGlrZSB5b3VyIG1lc3NhZ2UgY2FtZSB0aHJvdWdoLCBidXQgaXQgc2VlbXMifSAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIgbGlrZSBpdCBtaWdodCBoYXZlIGJlZW4gYSB0ZXN0IG9yIGdvdCBjdXQgb2ZmLiBIb3cgY2FuIEkgaGVscCB5b3UgdG9kYXk/XG5cbldoZXRoZXIgeW91IG5lZWQifSAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiIHRvICoqYnVpbGQgYSB3b3JrZmxvdyoqLCAqKmRlYnVnIGFuIGV4ZWN1dGlvbioqLCAqKm1hbmFnZSJ9ICAgICAgICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiIGNyZWRlbnRpYWxzKiosIG9yIGFueXRoaW5nIGVsc2UgaW4gbjhuIOKAlCBqdXN0IGxldCBtZSBrbm93ISJ9ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEyMDMsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjEyMzYwLCJvdXRwdXRfdG9rZW5zIjo3Mn0gfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICAgICAgICAgIH0KCg==", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805995520-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1775805995521-unknown-host-POST-_v1_messages-18622610.json b/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1775805995521-unknown-host-POST-_v1_messages-18622610.json deleted file mode 100644 index c2bf882e92b..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1775805995521-unknown-host-POST-_v1_messages-18622610.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "You generate a short descriptive title for a conversation", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["1923"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=UINQePMuxbGBVNwLkxgbBEuMjeQXnb_GSQY8DxGXXj4-1775805957.8490736-1.0.1.1-nrG68eu9jGn73rWcozuFSxoPooI6nuyI_1I0FGxXTw0; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=1925"], - "request-id": ["req_011CZuh9Em7TiBHuwYCb6aTL"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:25:59Z"], - "anthropic-ratelimit-tokens-remaining": ["27000000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:25:57Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:25:59Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:25:59Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22500000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:25:59 GMT"], - "Content-Type": ["application/json"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "CF-RAY": ["9ea005448dfde52f-TXL"] - }, - "cookies": { - "_cfuvid": "UINQePMuxbGBVNwLkxgbBEuMjeQXnb_GSQY8DxGXXj4-1775805957.8490736-1.0.1.1-nrG68eu9jGn73rWcozuFSxoPooI6nuyI_1I0FGxXTw0" - }, - "body": { - "contentType": "application/json", - "type": "JSON", - "json": { - "model": "claude-sonnet-4-6", - "id": "msg_017HeC6A9qNVSgGXQqG2ADd3", - "type": "message", - "role": "assistant", - "content": [ - { - "type": "text", - "text": "First Thread Message" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "stop_details": null, - "usage": { - "input_tokens": 108, - "cache_creation_input_tokens": 0, - "cache_read_input_tokens": 0, - "cache_creation": { - "ephemeral_5m_input_tokens": 0, - "ephemeral_1h_input_tokens": 0 - }, - "output_tokens": 6, - "service_tier": "standard", - "inference_geo": "global" - } - }, - "rawBytes": "eyJtb2RlbCI6ImNsYXVkZS1zb25uZXQtNC02IiwiaWQiOiJtc2dfMDE3SGVDNkE5cU5WU2dHWFFxRzJBRGQzIiwidHlwZSI6Im1lc3NhZ2UiLCJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiRmlyc3QgVGhyZWFkIE1lc3NhZ2UifV0sInN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGwsInVzYWdlIjp7ImlucHV0X3Rva2VucyI6MTA4LCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjowLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6Niwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19" - } - }, - "id": "1775805995521-unknown-host-POST-_v1_messages-18622610.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1775805995521-unknown-host-POST-_v1_messages-8a23f6c2.json b/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1775805995521-unknown-host-POST-_v1_messages-8a23f6c2.json deleted file mode 100644 index 655391ddda7..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1775805995521-unknown-host-POST-_v1_messages-8a23f6c2.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "[{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["2986"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=rcAHYvDYqqUuW1yhAuGcLEvSW4CD4gGfKy1pV7jJXnQ-1775805959.2643197-1.0.1.1-W0qwZM5JbaW4hQYJuBN47mEjRVu37JWfDBgxJ1yoILA; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=2988"], - "request-id": ["req_011CZuh9LuT3BmMFSnnLN6t5"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:25:59Z"], - "anthropic-ratelimit-tokens-remaining": ["26976000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:25:59Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:25:59Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:25:59Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22476000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:26:02 GMT"], - "Content-Type": ["text/event-stream; charset=utf-8"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "Cache-Control": ["no-cache"], - "CF-RAY": ["9ea0054d6ee8339b-TXL"] - }, - "cookies": { - "_cfuvid": "rcAHYvDYqqUuW1yhAuGcLEvSW4CD4gGfKy1pV7jJXnQ-1775805959.2643197-1.0.1.1-W0qwZM5JbaW4hQYJuBN47mEjRVu37JWfDBgxJ1yoILA" - }, - "body": { - "type": "STRING", - "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_015Ck21K5LXec4RkZBpUN8C5\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":1007,\"cache_creation_input_tokens\":12360,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":12360,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"It\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" looks like your message came through, but it seems like it might have been a test or placeholder\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" — \\\"Message in second thread\\\" doesn't give me much to go on!\\n\\nHow\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" can I help you? Whether it's building a workflow, debugging an execution,\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" managing credentials, or something else — just let me know! 😊\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":1007,\"cache_creation_input_tokens\":12360,\"cache_read_input_tokens\":0,\"output_tokens\":72} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxNUNrMjFLNUxYZWM0UmtaQnBVTjhDNSIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEwMDcsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MTIzNjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjoxMjM2MCwiZXBoZW1lcmFsXzFoX2lucHV0X3Rva2VucyI6MH0sIm91dHB1dF90b2tlbnMiOjEsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fSAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RhcnQKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19zdGFydCIsImluZGV4IjowLCJjb250ZW50X2Jsb2NrIjp7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IiJ9ICAgICAgICAgICAgfQoKZXZlbnQ6IHBpbmcKZGF0YTogeyJ0eXBlIjogInBpbmcifQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiJJdCJ9ICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIgbG9va3MgbGlrZSB5b3VyIG1lc3NhZ2UgY2FtZSB0aHJvdWdoLCBidXQgaXQgc2VlbXMgbGlrZSBpdCBtaWdodCBoYXZlIGJlZW4gYSB0ZXN0IG9yIHBsYWNlaG9sZGVyIn0gICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIg4oCUIFwiTWVzc2FnZSBpbiBzZWNvbmQgdGhyZWFkXCIgZG9lc24ndCBnaXZlIG1lIG11Y2ggdG8gZ28gb24hXG5cbkhvdyJ9ICAgICAgIH0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiIGNhbiBJIGhlbHAgeW91PyBXaGV0aGVyIGl0J3MgYnVpbGRpbmcgYSB3b3JrZmxvdywgZGVidWdnaW5nIGFuIGV4ZWN1dGlvbiwifSAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IiBtYW5hZ2luZyBjcmVkZW50aWFscywgb3Igc29tZXRoaW5nIGVsc2Ug4oCUIGp1c3QgbGV0IG1lIGtub3chIPCfmIoifSAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICAgIH0KCmV2ZW50OiBtZXNzYWdlX2RlbHRhCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2VfZGVsdGEiLCJkZWx0YSI6eyJzdG9wX3JlYXNvbiI6ImVuZF90dXJuIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsfSwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjoxMDA3LCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjEyMzYwLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MCwib3V0cHV0X3Rva2VucyI6NzJ9ICAgICAgICAgfQoKZXZlbnQ6IG1lc3NhZ2Vfc3RvcApkYXRhOiB7InR5cGUiOiJtZXNzYWdlX3N0b3AiICAgICAgICAgICAgIH0KCg==", - "contentType": "text/event-stream; charset=utf-8" - } - }, - "id": "1775805995521-unknown-host-POST-_v1_messages-8a23f6c2.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1775805995522-unknown-host-POST-_v1_messages-18622610.json b/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1775805995522-unknown-host-POST-_v1_messages-18622610.json deleted file mode 100644 index 0bf9c3aedfd..00000000000 --- a/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1775805995522-unknown-host-POST-_v1_messages-18622610.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/v1/messages", - "body": { - "type": "STRING", - "string": "You generate a short descriptive title for a conversation", - "subString": true - } - }, - "httpResponse": { - "statusCode": 200, - "reasonPhrase": "OK", - "headers": { - "x-envoy-upstream-service-time": ["4246"], - "vary": ["Accept-Encoding"], - "strict-transport-security": ["max-age=31536000; includeSubDomains; preload"], - "set-cookie": [ - "_cfuvid=SJqJIUK0ikJ83xF0sC9ne_yOYes70qEt1v_kWNCPvmA-1775805966.4138567-1.0.1.1-HuovodjHbigm2kPAHgs57Tz4WLJxW7ll7UhBlduFHK0; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" - ], - "server-timing": ["x-originResponse;dur=4251"], - "request-id": ["req_011CZuh9sQVzR8reX9pDbjAZ"], - "cf-cache-status": ["DYNAMIC"], - "anthropic-ratelimit-tokens-reset": ["2026-04-10T07:26:10Z"], - "anthropic-ratelimit-tokens-remaining": ["27000000"], - "anthropic-ratelimit-tokens-limit": ["27000000"], - "anthropic-ratelimit-requests-reset": ["2026-04-10T07:26:06Z"], - "anthropic-ratelimit-requests-remaining": ["19998"], - "anthropic-ratelimit-requests-limit": ["20000"], - "anthropic-ratelimit-output-tokens-reset": ["2026-04-10T07:26:10Z"], - "anthropic-ratelimit-output-tokens-remaining": ["4500000"], - "anthropic-ratelimit-output-tokens-limit": ["4500000"], - "anthropic-ratelimit-input-tokens-reset": ["2026-04-10T07:26:10Z"], - "anthropic-ratelimit-input-tokens-remaining": ["22500000"], - "anthropic-ratelimit-input-tokens-limit": ["22500000"], - "X-Robots-Tag": ["none"], - "Server": ["cloudflare"], - "Date": ["Fri, 10 Apr 2026 07:26:10 GMT"], - "Content-Type": ["application/json"], - "Content-Security-Policy": ["default-src 'none'; frame-ancestors 'none'"], - "CF-RAY": ["9ea0057a1d981eca-TXL"] - }, - "cookies": { - "_cfuvid": "SJqJIUK0ikJ83xF0sC9ne_yOYes70qEt1v_kWNCPvmA-1775805966.4138567-1.0.1.1-HuovodjHbigm2kPAHgs57Tz4WLJxW7ll7UhBlduFHK0" - }, - "body": { - "contentType": "application/json", - "type": "JSON", - "json": { - "model": "claude-sonnet-4-6", - "id": "msg_01MzxnBwG9ckn9ZpjupJ8Gt3", - "type": "message", - "role": "assistant", - "content": [ - { - "type": "text", - "text": "Second Thread Message" - } - ], - "stop_reason": "end_turn", - "stop_sequence": null, - "stop_details": null, - "usage": { - "input_tokens": 108, - "cache_creation_input_tokens": 0, - "cache_read_input_tokens": 0, - "cache_creation": { - "ephemeral_5m_input_tokens": 0, - "ephemeral_1h_input_tokens": 0 - }, - "output_tokens": 6, - "service_tier": "standard", - "inference_geo": "global" - } - }, - "rawBytes": "eyJtb2RlbCI6ImNsYXVkZS1zb25uZXQtNC02IiwiaWQiOiJtc2dfMDFNenhuQndHOWNrbjlacGp1cEo4R3QzIiwidHlwZSI6Im1lc3NhZ2UiLCJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiU2Vjb25kIFRocmVhZCBNZXNzYWdlIn1dLCJzdG9wX3JlYXNvbiI6ImVuZF90dXJuIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjEwOCwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfY3JlYXRpb24iOnsiZXBoZW1lcmFsXzVtX2lucHV0X3Rva2VucyI6MCwiZXBoZW1lcmFsXzFoX2lucHV0X3Rva2VucyI6MH0sIm91dHB1dF90b2tlbnMiOjYsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fQ==" - } - }, - "id": "1775805995522-unknown-host-POST-_v1_messages-18622610.json", - "priority": 0, - "timeToLive": { - "unlimited": true - }, - "times": { - "unlimited": true - } -} diff --git a/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1777373639573-unknown-host-POST-_v1_messages-f134c753.json b/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1777373639573-unknown-host-POST-_v1_messages-f134c753.json new file mode 100644 index 00000000000..d64e02ec48f --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1777373639573-unknown-host-POST-_v1_messages-f134c753.json @@ -0,0 +1,134 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You generate a short descriptive title for a conversatio[\\s\\S]*Generate a title for the following first message of a conversation\\. Do not answer the message — only produce the title\\.\\\\n[\\s\\S]*" + } + }, + "httpResponse": { + "statusCode": 200, + "reasonPhrase": "OK", + "headers": { + "x-envoy-upstream-service-time": [ + "1127" + ], + "vary": [ + "Accept-Encoding" + ], + "strict-transport-security": [ + "max-age=31536000; includeSubDomains; preload" + ], + "set-cookie": [ + "_cfuvid=Ml69kXuKBFN_LAAT1L2OzmpTHjKp45dgBTBR63JfSVI-1777373628.7382483-1.0.1.1-_SMEFhj3ozNPLk6wMbihwJnACd2Xi6XUk4vnEXj88lY; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" + ], + "server-timing": [ + "x-originResponse;dur=1129" + ], + "request-id": [ + "req_011CaW3Z18wNu447S7Fh5stg" + ], + "cf-cache-status": [ + "DYNAMIC" + ], + "anthropic-ratelimit-tokens-reset": [ + "2026-04-28T10:53:49Z" + ], + "anthropic-ratelimit-tokens-remaining": [ + "27000000" + ], + "anthropic-ratelimit-tokens-limit": [ + "27000000" + ], + "anthropic-ratelimit-requests-reset": [ + "2026-04-28T10:53:48Z" + ], + "anthropic-ratelimit-requests-remaining": [ + "19998" + ], + "anthropic-ratelimit-requests-limit": [ + "20000" + ], + "anthropic-ratelimit-output-tokens-reset": [ + "2026-04-28T10:53:49Z" + ], + "anthropic-ratelimit-output-tokens-remaining": [ + "4500000" + ], + "anthropic-ratelimit-output-tokens-limit": [ + "4500000" + ], + "anthropic-ratelimit-input-tokens-reset": [ + "2026-04-28T10:53:49Z" + ], + "anthropic-ratelimit-input-tokens-remaining": [ + "22500000" + ], + "anthropic-ratelimit-input-tokens-limit": [ + "22500000" + ], + "X-Robots-Tag": [ + "none" + ], + "Server": [ + "cloudflare" + ], + "Date": [ + "Tue, 28 Apr 2026 10:53:49 GMT" + ], + "Content-Type": [ + "application/json" + ], + "Content-Security-Policy": [ + "default-src 'none'; frame-ancestors 'none'" + ], + "CF-RAY": [ + "9f35867b9caee68c-PRG" + ] + }, + "cookies": { + "_cfuvid": "Ml69kXuKBFN_LAAT1L2OzmpTHjKp45dgBTBR63JfSVI-1777373628.7382483-1.0.1.1-_SMEFhj3ozNPLk6wMbihwJnACd2Xi6XUk4vnEXj88lY" + }, + "body": { + "contentType": "application/json", + "type": "JSON", + "json": { + "model": "claude-sonnet-4-6", + "id": "msg_015eaEKSppTb3Jo2zeKEB6tE", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "Second thread message" + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "stop_details": null, + "usage": { + "input_tokens": 367, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 6, + "service_tier": "standard", + "inference_geo": "global" + } + }, + "rawBytes": "eyJtb2RlbCI6ImNsYXVkZS1zb25uZXQtNC02IiwiaWQiOiJtc2dfMDE1ZWFFS1NwcFRiM0pvMnplS0VCNnRFIiwidHlwZSI6Im1lc3NhZ2UiLCJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiU2Vjb25kIHRocmVhZCBtZXNzYWdlIn1dLCJzdG9wX3JlYXNvbiI6ImVuZF90dXJuIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjM2NywiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MCwiY2FjaGVfY3JlYXRpb24iOnsiZXBoZW1lcmFsXzVtX2lucHV0X3Rva2VucyI6MCwiZXBoZW1lcmFsXzFoX2lucHV0X3Rva2VucyI6MH0sIm91dHB1dF90b2tlbnMiOjYsInNlcnZpY2VfdGllciI6InN0YW5kYXJkIiwiaW5mZXJlbmNlX2dlbyI6Imdsb2JhbCJ9fQ==" + } + }, + "id": "1777373639573-unknown-host-POST-_v1_messages-f134c753.json", + "priority": 0, + "timeToLive": { + "unlimited": true + }, + "times": { + "unlimited": true + } +} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1777373639574-unknown-host-POST-_v1_messages-00842afc.json b/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1777373639574-unknown-host-POST-_v1_messages-00842afc.json new file mode 100644 index 00000000000..0ba0849957d --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1777373639574-unknown-host-POST-_v1_messages-00842afc.json @@ -0,0 +1,111 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde[\\s\\S]*Message in first thread[\\s\\S]*" + } + }, + "httpResponse": { + "statusCode": 200, + "reasonPhrase": "OK", + "headers": { + "x-envoy-upstream-service-time": [ + "1807" + ], + "vary": [ + "Accept-Encoding" + ], + "strict-transport-security": [ + "max-age=31536000; includeSubDomains; preload" + ], + "set-cookie": [ + "_cfuvid=whIXMrlreDvmBtdoZrg9n3wn6llToYNjP8AEBXYQ.MM-1777373633.3265924-1.0.1.1-FToxDtPusBCSmCz_BpSfQDSmiSzDt4dLn_GbYuN3cNs; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" + ], + "server-timing": [ + "x-originResponse;dur=1811" + ], + "request-id": [ + "req_011CaW3ZLpcw3YYCcVJUxTQU" + ], + "cf-cache-status": [ + "DYNAMIC" + ], + "anthropic-ratelimit-tokens-reset": [ + "2026-04-28T10:53:53Z" + ], + "anthropic-ratelimit-tokens-remaining": [ + "26975000" + ], + "anthropic-ratelimit-tokens-limit": [ + "27000000" + ], + "anthropic-ratelimit-requests-reset": [ + "2026-04-28T10:53:53Z" + ], + "anthropic-ratelimit-requests-remaining": [ + "19998" + ], + "anthropic-ratelimit-requests-limit": [ + "20000" + ], + "anthropic-ratelimit-output-tokens-reset": [ + "2026-04-28T10:53:53Z" + ], + "anthropic-ratelimit-output-tokens-remaining": [ + "4500000" + ], + "anthropic-ratelimit-output-tokens-limit": [ + "4500000" + ], + "anthropic-ratelimit-input-tokens-reset": [ + "2026-04-28T10:53:53Z" + ], + "anthropic-ratelimit-input-tokens-remaining": [ + "22475000" + ], + "anthropic-ratelimit-input-tokens-limit": [ + "22500000" + ], + "X-Robots-Tag": [ + "none" + ], + "Server": [ + "cloudflare" + ], + "Date": [ + "Tue, 28 Apr 2026 10:53:55 GMT" + ], + "Content-Type": [ + "text/event-stream; charset=utf-8" + ], + "Content-Security-Policy": [ + "default-src 'none'; frame-ancestors 'none'" + ], + "Cache-Control": [ + "no-cache" + ], + "CF-RAY": [ + "9f3586984cfaf99e-PRG" + ] + }, + "cookies": { + "_cfuvid": "whIXMrlreDvmBtdoZrg9n3wn6llToYNjP8AEBXYQ.MM-1777373633.3265924-1.0.1.1-FToxDtPusBCSmCz_BpSfQDSmiSzDt4dLn_GbYuN3cNs" + }, + "body": { + "type": "STRING", + "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_0122XwxbSouJcKKaf22wniAU\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":327,\"cache_creation_input_tokens\":14091,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":14091,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"It\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" looks like your message came through, but it seems like it might be incomplete\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" — \\\"Message in first thread\\\" reads like a placeholder or test.\\n\\nWhat would you like to\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" do? I can help you build workflows, run executions, manage credentials, debug\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" issues, or anything else in your n8n instance.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":327,\"cache_creation_input_tokens\":14091,\"cache_read_input_tokens\":0,\"output_tokens\":68} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", + "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxMjJYd3hiU291SmNLS2FmMjJ3bmlBVSIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjMyNywiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxNDA5MSwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjE0MDkxLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6MSwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRleHQiLCJ0ZXh0IjoiIn0gICAgICAgICAgIH0KCmV2ZW50OiBwaW5nCmRhdGE6IHsidHlwZSI6ICJwaW5nIn0KCmV2ZW50OiBjb250ZW50X2Jsb2NrX2RlbHRhCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfZGVsdGEiLCJpbmRleCI6MCwiZGVsdGEiOnsidHlwZSI6InRleHRfZGVsdGEiLCJ0ZXh0IjoiSXQifSAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIgbG9va3MgbGlrZSB5b3VyIG1lc3NhZ2UgY2FtZSB0aHJvdWdoLCBidXQgaXQgc2VlbXMgbGlrZSBpdCBtaWdodCBiZSBpbmNvbXBsZXRlIn0gfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfZGVsdGEKZGF0YTogeyJ0eXBlIjoiY29udGVudF9ibG9ja19kZWx0YSIsImluZGV4IjowLCJkZWx0YSI6eyJ0eXBlIjoidGV4dF9kZWx0YSIsInRleHQiOiIg4oCUIFwiTWVzc2FnZSBpbiBmaXJzdCB0aHJlYWRcIiByZWFkcyBsaWtlIGEgcGxhY2Vob2xkZXIgb3IgdGVzdC5cblxuV2hhdCB3b3VsZCB5b3UgbGlrZSB0byJ9ICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IiBkbz8gSSBjYW4gaGVscCB5b3UgYnVpbGQgd29ya2Zsb3dzLCBydW4gZXhlY3V0aW9ucywgbWFuYWdlIGNyZWRlbnRpYWxzLCBkZWJ1ZyJ9ICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IiBpc3N1ZXMsIG9yIGFueXRoaW5nIGVsc2UgaW4geW91ciBuOG4gaW5zdGFuY2UuIn0gICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19zdG9wCmRhdGE6IHsidHlwZSI6ImNvbnRlbnRfYmxvY2tfc3RvcCIsImluZGV4IjowICAgfQoKZXZlbnQ6IG1lc3NhZ2VfZGVsdGEKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9kZWx0YSIsImRlbHRhIjp7InN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGx9LCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjMyNywiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxNDA5MSwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsIm91dHB1dF90b2tlbnMiOjY4fSAgICAgICB9CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgICB9Cgo=", + "contentType": "text/event-stream; charset=utf-8" + } + }, + "id": "1777373639574-unknown-host-POST-_v1_messages-00842afc.json", + "priority": 0, + "timeToLive": { + "unlimited": true + }, + "times": { + "unlimited": true + } +} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1777373639574-unknown-host-POST-_v1_messages-f134c753.json b/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1777373639574-unknown-host-POST-_v1_messages-f134c753.json new file mode 100644 index 00000000000..d4198281cff --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1777373639574-unknown-host-POST-_v1_messages-f134c753.json @@ -0,0 +1,134 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You generate a short descriptive title for a conversatio[\\s\\S]*Generate a title for the following first message of a conversation\\. Do not answer the message — only produce the title\\.\\\\n[\\s\\S]*" + } + }, + "httpResponse": { + "statusCode": 200, + "reasonPhrase": "OK", + "headers": { + "x-envoy-upstream-service-time": [ + "781" + ], + "vary": [ + "Accept-Encoding" + ], + "strict-transport-security": [ + "max-age=31536000; includeSubDomains; preload" + ], + "set-cookie": [ + "_cfuvid=SX_ua5ynOiWltWRWrovpRl8Dzqv_2.fuqApO88GTpKk-1777373636.9777873-1.0.1.1-gm1aLqFZZp3sNWO3wAyMfR5LTBIGzymtGJ3cFSflo6w; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" + ], + "server-timing": [ + "x-originResponse;dur=783" + ], + "request-id": [ + "req_011CaW3ZcNzvsisHFroJc9oy" + ], + "cf-cache-status": [ + "DYNAMIC" + ], + "anthropic-ratelimit-tokens-reset": [ + "2026-04-28T10:53:57Z" + ], + "anthropic-ratelimit-tokens-remaining": [ + "27000000" + ], + "anthropic-ratelimit-tokens-limit": [ + "27000000" + ], + "anthropic-ratelimit-requests-reset": [ + "2026-04-28T10:53:57Z" + ], + "anthropic-ratelimit-requests-remaining": [ + "19998" + ], + "anthropic-ratelimit-requests-limit": [ + "20000" + ], + "anthropic-ratelimit-output-tokens-reset": [ + "2026-04-28T10:53:57Z" + ], + "anthropic-ratelimit-output-tokens-remaining": [ + "4500000" + ], + "anthropic-ratelimit-output-tokens-limit": [ + "4500000" + ], + "anthropic-ratelimit-input-tokens-reset": [ + "2026-04-28T10:53:57Z" + ], + "anthropic-ratelimit-input-tokens-remaining": [ + "22500000" + ], + "anthropic-ratelimit-input-tokens-limit": [ + "22500000" + ], + "X-Robots-Tag": [ + "none" + ], + "Server": [ + "cloudflare" + ], + "Date": [ + "Tue, 28 Apr 2026 10:53:57 GMT" + ], + "Content-Type": [ + "application/json" + ], + "Content-Security-Policy": [ + "default-src 'none'; frame-ancestors 'none'" + ], + "CF-RAY": [ + "9f3586af1c2c5d09-PRG" + ] + }, + "cookies": { + "_cfuvid": "SX_ua5ynOiWltWRWrovpRl8Dzqv_2.fuqApO88GTpKk-1777373636.9777873-1.0.1.1-gm1aLqFZZp3sNWO3wAyMfR5LTBIGzymtGJ3cFSflo6w" + }, + "body": { + "contentType": "application/json", + "type": "JSON", + "json": { + "model": "claude-sonnet-4-6", + "id": "msg_01T9P5R2kcm4iNRccpWnrRHg", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "First thread message" + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "stop_details": null, + "usage": { + "input_tokens": 369, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 6, + "service_tier": "standard", + "inference_geo": "global" + } + }, + "rawBytes": "eyJtb2RlbCI6ImNsYXVkZS1zb25uZXQtNC02IiwiaWQiOiJtc2dfMDFUOVA1UjJrY200aU5SY2NwV25yUkhnIiwidHlwZSI6Im1lc3NhZ2UiLCJyb2xlIjoiYXNzaXN0YW50IiwiY29udGVudCI6W3sidHlwZSI6InRleHQiLCJ0ZXh0IjoiRmlyc3QgdGhyZWFkIG1lc3NhZ2UifV0sInN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJzdG9wX2RldGFpbHMiOm51bGwsInVzYWdlIjp7ImlucHV0X3Rva2VucyI6MzY5LCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiOjAsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJjYWNoZV9jcmVhdGlvbiI6eyJlcGhlbWVyYWxfNW1faW5wdXRfdG9rZW5zIjowLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6Niwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19" + } + }, + "id": "1777373639574-unknown-host-POST-_v1_messages-f134c753.json", + "priority": 0, + "timeToLive": { + "unlimited": true + }, + "times": { + "unlimited": true + } +} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1777373639575-unknown-host-POST-_v1_messages-155d19ce.json b/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1777373639575-unknown-host-POST-_v1_messages-155d19ce.json new file mode 100644 index 00000000000..e3a3af9e6e0 --- /dev/null +++ b/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/1777373639575-unknown-host-POST-_v1_messages-155d19ce.json @@ -0,0 +1,111 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/v1/messages", + "body": { + "type": "REGEX", + "regex": "[\\s\\S]*\\[\\{\"type\":\"text\",\"text\":\"You are the n8n Instance Agent — an AI assistant embedde[\\s\\S]*Message in second thread[\\s\\S]*" + } + }, + "httpResponse": { + "statusCode": 200, + "reasonPhrase": "OK", + "headers": { + "x-envoy-upstream-service-time": [ + "1163" + ], + "vary": [ + "Accept-Encoding" + ], + "strict-transport-security": [ + "max-age=31536000; includeSubDomains; preload" + ], + "set-cookie": [ + "_cfuvid=mvdsQYYSttNqAU31BwsPpQbx0j94gMTu7uGrTOZd9R8-1777373637.23709-1.0.1.1-0EWHXk1nRALUKZGysPxiUg0kIKEkHXWC_G5sLMtM5OY; HttpOnly; SameSite=None; Secure; Path=/; Domain=api.anthropic.com" + ], + "server-timing": [ + "x-originResponse;dur=1166" + ], + "request-id": [ + "req_011CaW3ZdWiCsYp6tY9aqYgf" + ], + "cf-cache-status": [ + "DYNAMIC" + ], + "anthropic-ratelimit-tokens-reset": [ + "2026-04-28T10:53:57Z" + ], + "anthropic-ratelimit-tokens-remaining": [ + "26975000" + ], + "anthropic-ratelimit-tokens-limit": [ + "27000000" + ], + "anthropic-ratelimit-requests-reset": [ + "2026-04-28T10:53:57Z" + ], + "anthropic-ratelimit-requests-remaining": [ + "19998" + ], + "anthropic-ratelimit-requests-limit": [ + "20000" + ], + "anthropic-ratelimit-output-tokens-reset": [ + "2026-04-28T10:53:57Z" + ], + "anthropic-ratelimit-output-tokens-remaining": [ + "4500000" + ], + "anthropic-ratelimit-output-tokens-limit": [ + "4500000" + ], + "anthropic-ratelimit-input-tokens-reset": [ + "2026-04-28T10:53:57Z" + ], + "anthropic-ratelimit-input-tokens-remaining": [ + "22475000" + ], + "anthropic-ratelimit-input-tokens-limit": [ + "22500000" + ], + "X-Robots-Tag": [ + "none" + ], + "Server": [ + "cloudflare" + ], + "Date": [ + "Tue, 28 Apr 2026 10:53:58 GMT" + ], + "Content-Type": [ + "text/event-stream; charset=utf-8" + ], + "Content-Security-Policy": [ + "default-src 'none'; frame-ancestors 'none'" + ], + "Cache-Control": [ + "no-cache" + ], + "CF-RAY": [ + "9f3586b0b8b46e75-PRG" + ] + }, + "cookies": { + "_cfuvid": "mvdsQYYSttNqAU31BwsPpQbx0j94gMTu7uGrTOZd9R8-1777373637.23709-1.0.1.1-0EWHXk1nRALUKZGysPxiUg0kIKEkHXWC_G5sLMtM5OY" + }, + "body": { + "type": "STRING", + "string": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01RArw5uzbXYQJcBdMay5goH\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":327,\"cache_creation_input_tokens\":14091,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":14091,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"It\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" looks like your message may have been cut off or sent without content. Could you share\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" what you'd like help with?\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":327,\"cache_creation_input_tokens\":14091,\"cache_read_input_tokens\":0,\"output_tokens\":28}}\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", + "rawBytes": "ZXZlbnQ6IG1lc3NhZ2Vfc3RhcnQKZGF0YTogeyJ0eXBlIjoibWVzc2FnZV9zdGFydCIsIm1lc3NhZ2UiOnsibW9kZWwiOiJjbGF1ZGUtc29ubmV0LTQtNiIsImlkIjoibXNnXzAxUkFydzV1emJYWVFKY0JkTWF5NWdvSCIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsImNvbnRlbnQiOltdLCJzdG9wX3JlYXNvbiI6bnVsbCwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjMyNywiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjoxNDA5MSwiY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMiOjAsImNhY2hlX2NyZWF0aW9uIjp7ImVwaGVtZXJhbF81bV9pbnB1dF90b2tlbnMiOjE0MDkxLCJlcGhlbWVyYWxfMWhfaW5wdXRfdG9rZW5zIjowfSwib3V0cHV0X3Rva2VucyI6MSwic2VydmljZV90aWVyIjoic3RhbmRhcmQiLCJpbmZlcmVuY2VfZ2VvIjoiZ2xvYmFsIn19ICB9CgpldmVudDogY29udGVudF9ibG9ja19zdGFydApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0YXJ0IiwiaW5kZXgiOjAsImNvbnRlbnRfYmxvY2siOnsidHlwZSI6InRleHQiLCJ0ZXh0IjoiIn0gICAgICAgICAgICB9CgpldmVudDogcGluZwpkYXRhOiB7InR5cGUiOiAicGluZyJ9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6Ikl0In0gICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IiBsb29rcyBsaWtlIHlvdXIgbWVzc2FnZSBtYXkgaGF2ZSBiZWVuIGN1dCBvZmYgb3Igc2VudCB3aXRob3V0IGNvbnRlbnQuIENvdWxkIHlvdSBzaGFyZSJ9ICAgICAgICAgICAgICB9CgpldmVudDogY29udGVudF9ibG9ja19kZWx0YQpkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX2RlbHRhIiwiaW5kZXgiOjAsImRlbHRhIjp7InR5cGUiOiJ0ZXh0X2RlbHRhIiwidGV4dCI6IiB3aGF0IHlvdSdkIGxpa2UgaGVscCB3aXRoPyJ9ICAgICAgICAgICAgICAgfQoKZXZlbnQ6IGNvbnRlbnRfYmxvY2tfc3RvcApkYXRhOiB7InR5cGUiOiJjb250ZW50X2Jsb2NrX3N0b3AiLCJpbmRleCI6MCAgICAgIH0KCmV2ZW50OiBtZXNzYWdlX2RlbHRhCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2VfZGVsdGEiLCJkZWx0YSI6eyJzdG9wX3JlYXNvbiI6ImVuZF90dXJuIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwic3RvcF9kZXRhaWxzIjpudWxsfSwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjozMjcsImNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VucyI6MTQwOTEsImNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zIjowLCJvdXRwdXRfdG9rZW5zIjoyOH19CgpldmVudDogbWVzc2FnZV9zdG9wCmRhdGE6IHsidHlwZSI6Im1lc3NhZ2Vfc3RvcCIgICAgICAgICAgfQoK", + "contentType": "text/event-stream; charset=utf-8" + } + }, + "id": "1777373639575-unknown-host-POST-_v1_messages-155d19ce.json", + "priority": 0, + "timeToLive": { + "unlimited": true + }, + "times": { + "unlimited": true + } +} \ No newline at end of file diff --git a/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/trace.jsonl b/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/trace.jsonl index bc7ec8b91ff..e8755f5c733 100644 --- a/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/trace.jsonl +++ b/packages/testing/playwright/expectations/instance-ai/should-switch-between-threads/trace.jsonl @@ -1,2 +1,2 @@ -{"kind":"header","version":1,"testName":"recording","recordedAt":"2026-04-10T07:25:46.515Z"} -{"kind":"header","version":1,"testName":"recording","recordedAt":"2026-04-10T07:25:58.030Z"} +{"kind":"header","version":1,"testName":"recording","recordedAt":"2026-04-28T10:53:53.208Z"} +{"kind":"header","version":1,"testName":"recording","recordedAt":"2026-04-28T10:53:57.108Z"} diff --git a/packages/testing/playwright/pages/InstanceAiPage.ts b/packages/testing/playwright/pages/InstanceAiPage.ts index bed33f93abd..5eed35fb21a 100644 --- a/packages/testing/playwright/pages/InstanceAiPage.ts +++ b/packages/testing/playwright/pages/InstanceAiPage.ts @@ -220,4 +220,14 @@ export class InstanceAiPage extends BasePage { async waitForRunComplete(timeoutMs = 180_000): Promise { await this.getStopButton().waitFor({ state: 'hidden', timeout: timeoutMs }); } + + /** + * Wait for the plan-review panel to appear and approve it. New workflow + * builds now route through the planner and pause at `awaiting_approval` + * until the user approves — without this step the build never starts. + */ + async approveBuildPlan(timeout = 120_000): Promise { + await this.getPlanApproveButton().waitFor({ state: 'visible', timeout }); + await this.getPlanApproveButton().click(); + } } diff --git a/packages/testing/playwright/tests/e2e/instance-ai/fixtures.ts b/packages/testing/playwright/tests/e2e/instance-ai/fixtures.ts index 1a484e31470..ba56e6e94fe 100644 --- a/packages/testing/playwright/tests/e2e/instance-ai/fixtures.ts +++ b/packages/testing/playwright/tests/e2e/instance-ai/fixtures.ts @@ -35,6 +35,102 @@ async function writeTraceFile(folder: string, events: unknown[]): Promise await fs.writeFile(filePath, jsonl); } +type AnthropicMessage = { + role?: unknown; + content?: unknown; +}; + +type AnthropicContentBlock = { + type?: unknown; + text?: unknown; + name?: unknown; + input?: unknown; +}; + +function escapeRegex(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} + +function asContentBlocks(content: unknown): AnthropicContentBlock[] { + if (typeof content === 'string') return [{ type: 'text', text: content }]; + if (!Array.isArray(content)) return []; + return content.filter( + (block): block is AnthropicContentBlock => + typeof block === 'object' && block !== null && !Array.isArray(block), + ); +} + +function getStableTextAnchor(text: string): string | undefined { + const trimmed = text.trimStart(); + if (!trimmed) return undefined; + + const tagMatch = /^<[a-z-]+/.exec(trimmed); + if (tagMatch) return escapeRegex(tagMatch[0]); + + return escapeRegex(JSON.stringify(trimmed.slice(0, 120)).slice(1, -1)); +} + +function getToolUseAnchor(block: AnthropicContentBlock): string | undefined { + if (block.type !== 'tool_use' || typeof block.name !== 'string') return undefined; + + const toolNameMatcher = `"type"\\s*:\\s*"tool_use"[\\s\\S]{0,300}"name"\\s*:\\s*"${escapeRegex(block.name)}"`; + const input = block.input; + if (typeof input !== 'object' || input === null || Array.isArray(input)) { + return toolNameMatcher; + } + + const action = Reflect.get(input, 'action'); + if (typeof action !== 'string') return toolNameMatcher; + + return `${toolNameMatcher}[\\s\\S]{0,500}"action"\\s*:\\s*"${escapeRegex(action)}"`; +} + +function getLatestMessageAnchor(messages: AnthropicMessage[] | undefined): string | undefined { + if (!messages) return undefined; + + for (let messageIndex = messages.length - 1; messageIndex >= 0; messageIndex--) { + const blocks = asContentBlocks(messages[messageIndex]?.content); + for (let blockIndex = blocks.length - 1; blockIndex >= 0; blockIndex--) { + const block = blocks[blockIndex]; + if (block.type === 'text' && typeof block.text === 'string') { + const textAnchor = getStableTextAnchor(block.text); + if (textAnchor) return textAnchor; + } + + const toolUseAnchor = getToolUseAnchor(block); + if (toolUseAnchor) return toolUseAnchor; + } + } + + return undefined; +} + +function createAnthropicBodyMatcher(raw: string): { type: 'REGEX'; regex: string } | undefined { + const parsed = JSON.parse(raw) as { + system?: string | unknown[]; + messages?: AnthropicMessage[]; + }; + + const system = + typeof parsed.system === 'string' + ? parsed.system + : Array.isArray(parsed.system) + ? JSON.stringify(parsed.system) + : undefined; + if (!system) return undefined; + + const systemSnippet = escapeRegex(system.slice(0, 80)); + const latestMessageAnchor = getLatestMessageAnchor(parsed.messages); + const matcher = latestMessageAnchor + ? `${systemSnippet}[\\s\\S]*${latestMessageAnchor}` + : systemSnippet; + + return { + type: 'REGEX', + regex: `[\\s\\S]*${matcher}[\\s\\S]*`, + }; +} + type InstanceAiFixtures = { anthropicApiKey: string; instanceAiProxySetup: undefined; @@ -73,6 +169,15 @@ export const test = base.extend({ const testSlug = slugify(testInfo.title); const folder = `instance-ai/${testSlug}`; + // Wipe instance-ai threads, per-thread in-memory state, background tasks, + // and user workflows before clearing the proxy so cleanup traffic from a + // previous test cannot be captured into this test's recording. + try { + await fetch(`${backendUrl}/rest/instance-ai/test/reset`, { method: 'POST' }); + } catch { + // Endpoint may not be available + } + await services.proxy.clearAllExpectations(); // Install a success response for Slack's `users.profile.get` — the @@ -100,15 +205,6 @@ export const test = base.extend({ times: { unlimited: true }, }); - // Wipe instance-ai threads, per-thread in-memory state, background tasks, - // and user workflows so the orchestrator's `list-workflows` tool can't see - // leftovers from a prior test and contaminate this test's recorded responses. - try { - await fetch(`${backendUrl}/rest/instance-ai/test/reset`, { method: 'POST' }); - } catch { - // Endpoint may not be available - } - // Recording mode: real API key, not CI → proxy forwards to real API, // backend records tool I/O. Replay mode: load existing expectations // and trace events so the proxy serves recorded responses and the @@ -162,8 +258,8 @@ export const test = base.extend({ } // Keep a minimal body matcher so the proxy can distinguish - // between different LLM call types (title gen vs orchestrator - // vs sub-agent) which may arrive in different order during replay. + // between agent type and stable turn context without matching + // volatile tool output such as workflow and execution IDs. const request = expectation.httpRequest as { // eslint-disable-next-line id-denylist -- `string` is MockServer's body matcher field name body?: { type?: string; string?: string; json?: Record }; @@ -174,23 +270,9 @@ export const test = base.extend({ (request.body.json ? JSON.stringify(request.body.json) : undefined); if (raw) { try { - const parsed = JSON.parse(raw) as { system?: string | unknown[] }; - // Extract a short substring from the system prompt to - // distinguish title-generation from orchestrator from sub-agent. - const system = - typeof parsed.system === 'string' - ? parsed.system - : Array.isArray(parsed.system) - ? JSON.stringify(parsed.system) - : undefined; - if (system) { - const snippet = system.slice(0, 80); - request.body = { - type: 'STRING', - // eslint-disable-next-line id-denylist -- `string` is MockServer's body matcher field name - string: snippet, - subString: true, - } as unknown as typeof request.body; + const bodyMatcher = createAnthropicBodyMatcher(raw); + if (bodyMatcher) { + request.body = bodyMatcher as unknown as typeof request.body; } else { delete request.body; } diff --git a/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-artifacts.spec.ts b/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-artifacts.spec.ts index 31b8cf9aab8..3adcc930951 100644 --- a/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-artifacts.spec.ts +++ b/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-artifacts.spec.ts @@ -15,6 +15,9 @@ test.describe( 'Build a simple workflow with a manual trigger and a set node called "artifact display test"', ); + // New builds route through the planner and pause for user approval. + await n8n.instanceAi.approveBuildPlan(); + // Wait for build to complete (no confirmation for simple builds) await n8n.instanceAi.waitForAssistantResponse(120_000); @@ -29,6 +32,8 @@ test.describe( 'Build a simple workflow with a manual trigger and a set node called "artifact click test"', ); + await n8n.instanceAi.approveBuildPlan(); + await n8n.instanceAi.waitForAssistantResponse(120_000); // Preview should auto-open after build diff --git a/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-chat-basics.spec.ts b/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-chat-basics.spec.ts index 74383bc2314..d43b8642660 100644 --- a/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-chat-basics.spec.ts +++ b/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-chat-basics.spec.ts @@ -45,15 +45,17 @@ test.describe( await n8n.navigate.toInstanceAi(); await expect(n8n.instanceAi.getChatInput()).toBeVisible({ timeout: 30_000 }); - // The old thread should be visible in the sidebar — click it to restore. - // Thread title is LLM-generated ("Persistence message noted" from recording). - // Use partial match to be resilient to minor title variations. - const oldThread = n8n.instanceAi.sidebar.getThreadByTitle('Persistence message'); + // The old thread should be visible in the sidebar. Its title is generated by the model, + // so restore it by position rather than by exact title text. + const oldThread = n8n.instanceAi.sidebar.getThreadItems().first(); await expect(oldThread).toBeVisible({ timeout: 10_000 }); await oldThread.click(); // Messages from the old thread should be visible - await expect(n8n.instanceAi.getUserMessages().first()).toBeVisible({ timeout: 30_000 }); + await expect(n8n.instanceAi.getUserMessages().first()).toContainText( + 'Remember this persistence message', + { timeout: 30_000 }, + ); await expect(n8n.instanceAi.getAssistantMessages().first()).toBeVisible({ timeout: 30_000 }); }); }, diff --git a/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-confirmations.spec.ts b/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-confirmations.spec.ts index adc044cecc0..904085182d0 100644 --- a/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-confirmations.spec.ts +++ b/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-confirmations.spec.ts @@ -16,6 +16,9 @@ test.describe( 'Build a simple workflow with a manual trigger and a set node called "approval test" and run it', ); + // Approve the build plan so the orchestrator proceeds to the run step. + await n8n.instanceAi.approveBuildPlan(); + await expect(n8n.instanceAi.getConfirmApproveButton()).toBeVisible({ timeout: 120_000 }); await n8n.instanceAi.getConfirmApproveButton().click(); @@ -32,6 +35,8 @@ test.describe( 'Build a simple workflow with a manual trigger and a set node called "deny test" and run it', ); + await n8n.instanceAi.approveBuildPlan(); + await expect(n8n.instanceAi.getConfirmDenyButton()).toBeVisible({ timeout: 120_000 }); await n8n.instanceAi.getConfirmDenyButton().click(); diff --git a/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-sidebar.spec.ts b/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-sidebar.spec.ts index fd155411d5f..78b0fbc2551 100644 --- a/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-sidebar.spec.ts +++ b/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-sidebar.spec.ts @@ -47,8 +47,10 @@ test.describe( await n8n.instanceAi.sendMessage('Message in second thread'); await n8n.instanceAi.waitForResponseComplete(); - // Switch back to first thread by its title (LLM-generated from recording) - await n8n.instanceAi.sidebar.getThreadByTitle('First Thread Message').click(); + // Sidebar is ordered by most recent activity, so the first thread is now second. + const firstThread = n8n.instanceAi.sidebar.getThreadItems().nth(1); + await expect(firstThread).toBeVisible({ timeout: 10_000 }); + await firstThread.click(); // Should show the first thread's user message (messages load async) await expect(n8n.instanceAi.getUserMessages().first()).toContainText( @@ -86,9 +88,11 @@ test.describe( await n8n.instanceAi.sendMessage('Thread to delete'); await n8n.instanceAi.waitForResponseComplete(); - // Verify target thread is visible in the sidebar - const targetThread = n8n.instanceAi.sidebar.getThreadByTitle('Thread to Delete'); + // Verify target thread is visible in the sidebar. Its generated title is not part of + // the behavior under test, so use the current thread item instead of title text. + const targetThread = n8n.instanceAi.sidebar.getThreadItems().first(); await expect(targetThread).toBeVisible({ timeout: 10_000 }); + const threadCountBefore = await n8n.instanceAi.sidebar.getThreadItems().count(); // Hover the target thread to reveal the three-dots button, then click it await targetThread.hover(); @@ -101,8 +105,8 @@ test.describe( await n8n.instanceAi.sidebar.getDeleteMenuItem().click(); // Thread should no longer be visible - await expect(n8n.instanceAi.sidebar.getThreadByTitle('Thread to Delete')).toBeHidden({ - timeout: 5_000, + await expect(n8n.instanceAi.sidebar.getThreadItems()).toHaveCount(threadCountBefore - 1, { + timeout: 10_000, }); }); }, diff --git a/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-timeline.spec.ts b/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-timeline.spec.ts index e4f977dd6db..003b600238f 100644 --- a/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-timeline.spec.ts +++ b/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-timeline.spec.ts @@ -15,6 +15,8 @@ test.describe( 'Build a simple workflow with a manual trigger and a set node called "artifact card test"', ); + await n8n.instanceAi.approveBuildPlan(); + await n8n.instanceAi.waitForAssistantResponse(120_000); // Artifact cards (N8nCard) should appear in the timeline after build diff --git a/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-workflow-execution.spec.ts b/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-workflow-execution.spec.ts index b59bf4b9114..75009c26a18 100644 --- a/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-workflow-execution.spec.ts +++ b/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-workflow-execution.spec.ts @@ -15,6 +15,9 @@ test.describe( 'Build a simple workflow with a manual trigger and a set node called "run button visibility test"', ); + // New builds route through the planner and pause for user approval. + await n8n.instanceAi.approveBuildPlan(); + // Wait for preview to show canvas nodes await expect(n8n.instanceAi.getPreviewCanvasNodes().first()).toBeVisible({ timeout: 120_000, @@ -33,6 +36,8 @@ test.describe( 'Build a simple workflow with a manual trigger connected to a set node called "full execution test"', ); + await n8n.instanceAi.approveBuildPlan(); + // Wait for preview to show canvas nodes await expect(n8n.instanceAi.getPreviewCanvasNodes().first()).toBeVisible({ timeout: 120_000, @@ -54,6 +59,8 @@ test.describe( 'Build a simple workflow with a manual trigger connected to a set node called "node execution test"', ); + await n8n.instanceAi.approveBuildPlan(); + // Wait for preview to show canvas nodes await expect(n8n.instanceAi.getPreviewCanvasNodes().first()).toBeVisible({ timeout: 120_000, @@ -84,6 +91,8 @@ test.describe( 'Build a simple workflow with a manual trigger connected to a set node called "ndv output test"', ); + await n8n.instanceAi.approveBuildPlan(); + // Wait for preview to show canvas nodes await expect(n8n.instanceAi.getPreviewCanvasNodes().first()).toBeVisible({ timeout: 120_000, @@ -118,6 +127,8 @@ test.describe( 'Build a simple workflow with a manual trigger connected to a set node called "re-run test"', ); + await n8n.instanceAi.approveBuildPlan(); + // Wait for preview to show canvas nodes await expect(n8n.instanceAi.getPreviewCanvasNodes().first()).toBeVisible({ timeout: 120_000, diff --git a/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-workflow-preview.spec.ts b/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-workflow-preview.spec.ts index d6550385838..2126ee8e1e9 100644 --- a/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-workflow-preview.spec.ts +++ b/packages/testing/playwright/tests/e2e/instance-ai/instance-ai-workflow-preview.spec.ts @@ -14,6 +14,7 @@ test.describe( await n8n.instanceAi.sendMessage( 'Build a simple workflow with a manual trigger and a set node called "preview auto-open test"', ); + await n8n.instanceAi.approveBuildPlan(); // Preview should auto-open with canvas nodes visible (no confirmation for simple builds) await expect(n8n.instanceAi.getPreviewCanvasNodes().first()).toBeVisible({ @@ -27,6 +28,7 @@ test.describe( await n8n.instanceAi.sendMessage( 'Build a workflow with manual trigger connected to a set node called "canvas nodes test"', ); + await n8n.instanceAi.approveBuildPlan(); // Should show canvas nodes in the preview await expect(n8n.instanceAi.getPreviewCanvasNodes().first()).toBeVisible({ @@ -42,6 +44,9 @@ test.describe( testInfo.project.name.includes('multi-main'), 'Execution preview replay is not yet stable in multi-main mode', ); + // End-to-end: plan + approve + build + execute + final assertions take >60s + // when recording against the real Anthropic API. + test.setTimeout(180_000); await n8n.navigate.toInstanceAi(); // A Wait node creates a window where the downstream node is briefly @@ -52,6 +57,7 @@ test.describe( 'and a Set node called "running state test". After it is built, ' + 'run it.', ); + await n8n.instanceAi.approveBuildPlan(); await expect(n8n.instanceAi.getConfirmApproveButton()).toBeVisible({ timeout: 120_000 }); await n8n.instanceAi.getConfirmApproveButton().click(); @@ -70,6 +76,7 @@ test.describe( await n8n.instanceAi.sendMessage( 'Build a simple workflow with a manual trigger and a set node called "close preview test"', ); + await n8n.instanceAi.approveBuildPlan(); // Wait for preview to auto-open await expect(n8n.instanceAi.getPreviewCanvasNodes().first()).toBeVisible({