Skip to content

v1.2.0: MCP servers, workflows test mode, and new integrations

Latest

Choose a tag to compare

@weishest weishest released this 18 Jul 11:33
· 4 commits to main since this release
6880c6a

This release focuses on workflows and runtime reliability. Workflows gain a Test mode for running a saved workflow (or a single node) on demand, first-class loops and condition error handling, and structured JSON output. Alongside that, several changes make agent turns and workflow errors visible, and the credential proxy now handles binary uploads and downloads. This version also replaces the Gmail push trigger with a polling model, adds an edit flow for MCP servers, and introduces the Dropbox and Wise integrations.

Workflows

Test mode

Workflows can now be exercised on demand without waiting for a real trigger.

  • Run a full workflow or a single node with a user-supplied trigger payload, and see per-node results overlaid directly on the canvas as the run proceeds.
  • A single node can be run in isolation by passing testNodeId plus seededOutputs for its upstream dependencies. Test runs execute even when the workflow is disabled.
  • Test runs are seeded from real data where a provider supports it: POST /:provider/sample fetches the latest real event (Gmail, Outlook, Google Forms) to use as the payload, without advancing the trigger's cursor.
  • Web: a Test button in the builder, a test-run store, the WorkflowTestDialog, NodeTestOverlay, and RunDataView components, plus a status poller that refreshes every 3 seconds while a run is active.
image

Loops

  • Nodes inside a loop body that are not explicitly mapped now receive the current item ({{loop.item}}, with index and total) instead of the entire source array. Loop instructions are templated the same way.
  • resolveItemsToArray keeps arrays raw and unwraps a single-array wrapper object so common shapes resolve to a clean list.
  • A loop records the { index, item, output } of the last executed body node, which is what downstream nodes read.
  • The builder gains a guided item picker (LoopConfigForm) with a live count preview, clearer "loop start" / "loop end" labels on LoopNode, and a warning when a loop resolves to no items.

MCP servers

This version marks the stable release of the MCP server feature.

  • An edit dialog is added for MCP servers (mcp-add-dialog is renamed to mcp-server-dialog with a create-or-edit mode, and an Edit button is wired into the list page). Editing changes name, URL, transport, auth, and headers through the existing PUT /:id and redacted GET /:id/data endpoints, so the tool cache and agent assignments survive.
  • Header values are masked and echoed back as sentinels; the real secret never reaches the browser.
  • McpService.unredactData is generalized into a nesting-aware sentinel restore (headers, stdio.env, oauth), fixing stdio.env secrets being overwritten with the literal __REDACTED__ and nested oauth/stdio being clobbered by the old shallow merge.
image

Runtime reliability

  • Long-running turns can refresh their sandbox proxy token: the backend issues a refresh token alongside the 15-minute access token, ProxyClient.authedFetch single-flights a refresh on a 401, and POST /v1/runtime/refresh-token exchanges it. This keeps runs alive past the access-token lifetime.

LLM and tools

  • call_api supports multipart/related uploads (multipartSubtype with ordered typed parts) for Google Drive-style uploads, and the run_code required parameters are clarified.

Binary support in call_api

call_api was text-only end to end (JSON string body, response.text()), which corrupted binary files through UTF-8/JSON encoding. Binary is now supported in both directions, with bytes referenced by workspace file path and base64 used only on the internal sandbox-to-host hop, so raw bytes never enter the LLM context.

  • New tool inputs: bodyFile (raw binary body), multipart[] (form-data with file parts), and responseFile (save a binary response to the workspace), with a 25 MB binary cap, reusing resolveWorkspacePath and the write_file mkdir path.

Chat context compaction

A thread's conversation can be summarized so the agent receives [summary] + [messages since] instead of the full history, reducing context-token occupancy. This is soft compaction: the visible scrollback is preserved, and only the LLM-facing view is shortened.

  • agent_threads gains context_summary and compacted_at columns.
  • AgentLlmProxyService.compactThread() summarizes via complete(), resets context_tokens, and emits a context_compacted SSE event.
  • The internal messages route filters at the boundary and injects the summary in-memory, reusing the file-attachment injection pattern.
  • POST /:agentId/threads/:threadId/compact triggers it, and a /compact channel command exposes it on Telegram and Discord through the same shared method.
  • Web UI: a ChatUsageBar button, a thread-menu item, and a "context compacted" divider.
image

Triggers: email polling replaces Gmail push

The Gmail app trigger previously used users.watch with Google Cloud Pub/Sub push, which cannot run or be tested without a public HTTPS endpoint, a per-user Pub/Sub topic and subscription, and 7-day watch renewal — so it never worked on localhost. It is replaced with a polling model, and the polling algorithm is factored into a reusable core.

Integrations

  • Dropbox — an OAuth2 credential (token_access_type=offline for refresh tokens, app_folder / full_dropbox) plus an access-token option. DropboxProvider accepts it for knowledge-base import, and the docs are rewritten into access-token versus OAuth2 options.
  • Wise — a new integration.
  • Google service scopes are now user-definable. The OAuth2 scope for Gmail, Google Analytics, Google Calendar, Google Docs, Google Forms, and Google Sheets moves from a fixed oauth2.scope value to an editable scope property with a default. Users can trim the default (for example, to request read-only access) when creating a credential.

Full Changelog: v1.1.0...v1.2.0