Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
208671f
fix(chat): chat finishes long jobs instead of stopping partway (#15925)
hazemadelkhalel Sep 30, 2026
7e08a33
fix: Activepieces AI credits now only run the models offered in the p…
hazemadelkhalel Sep 30, 2026
112cac0
fix(sandbox): code steps can import node: builtins again (#15980)
MrChaker Sep 30, 2026
c43336d
feat(elevenlabs): add AI actions and output schemas (#15981)
kishanprmr Sep 30, 2026
5908109
feat(xml): add Create XML action (#15884)
OdaiAhmed99 Sep 30, 2026
3bcc362
feat(ntfy): update, clear and delete notifications, send files and tr…
OdaiAhmed99 Sep 30, 2026
d1764cf
feat(convertapi): merge, split and convert files with ConvertAPI (#15…
OdaiAhmed99 Sep 30, 2026
02d219a
feat(0codekit): validate business data and work with dates and conver…
OdaiAhmed99 Sep 30, 2026
7e7e380
fix(chat): changing a saved agent after the chat read your data now a…
hazemadelkhalel Sep 30, 2026
a921e45
feat(ghostcms): let AI agents manage Ghost posts, pages, members, new…
OdaiAhmed99 Sep 30, 2026
6fe5f5f
feat(customer-io): add filtering Reporting Webhook trigger (#15658)
AdamSelene Sep 30, 2026
4d73a95
feat(convertkit): let AI agents manage Kit subscribers, tags, forms, …
OdaiAhmed99 Sep 30, 2026
e44f97e
fix(xml): keep leading zeros in Convert XML to JSON (#15856)
OdaiAhmed99 Sep 30, 2026
5a04282
feat(jsm-operations): add Jira Service Management Operations piece (O…
OdaiAhmed99 Sep 30, 2026
68e8189
feat(exa): run Exa agents, watch searches with a monitor trigger, and…
OdaiAhmed99 Sep 30, 2026
15547e9
feat(zoho-crm): work with records in any module, watch new and update…
OdaiAhmed99 Sep 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions brain/knowledge/ai-intelligence/ai-providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ enqueued. `AP_MODEL_TIERS_URL` overrides the URL. The file is published from the
decision 000041. The console publishes both lists and both fast pointers on every Publish, and on its first load
after a file without chat keys it seeds the chat list from the live flow list.
### Gotchas
- **The managed key only runs models the tiers or the chat allow-list permit, enforced in `aiUtils.createModel`.** The managed provider is OpenRouter underneath, so before this guard a crafted step naming any OpenRouter model ran on our key; the picker hid it but nothing denied it. `assertManagedModelAllowed` (`server/utils/src/ai-utils.ts`) checks `managedChatModelIds()` plus both surfaces' published tier `modelId`s and throws a `VALIDATION` error. Image models are checked too, in `createModel` (`imageGeneration: true`) and `createModelForImages`: only `ACTIVEPIECES_IMAGE_TIERS` model ids, plus the id the chat path passes as `adminChosenImageModelId` (the server-chosen Capabilities model). The worker now calls `modelTierCatalog.warmUp()` at start so a cold worker does not judge a newly published tier against the bundled list.
- **A catalog change takes up to ~2 days to reach a dropdown, through three caches in series.** CDN edge (`--cache-control max-age=3600`, 1h) → the server's in-memory catalog (`CATALOG_TTL_MS`, 24h) → `modelsCache` (flushed by the nightly `cron.schedule('0 0 * * *')`). So "I republished but the UI still shows the old price" is expected, not a bug; restarting the API short-circuits the two in-process layers. The edge TTL is deliberately 1h and not the 604800 that `publish-embed-sdk.yml` uses — that path is version-stamped, ours is a stable key rewritten in place, so a week-long edge cache would pin stale prices for a week.
- **`Sync AI Model Catalog` is the only workflow that proves the CDN S3 credentials still work — a green `Publish Embed SDK` proves nothing.** Both read the same `CDN_S3_ACCESS_KEY_ID` / `CDN_S3_SECRET_ACCESS_KEY` / `CDN_S3_BUCKET` / `CDN_S3_ENDPOINT` secrets, but `publish-embed-sdk.yml` guards its upload job on `needs.check.outputs.publish == 'true'`, which is false whenever the version in `packages/ee/embed-sdk/package.json` is already on the CDN. Its daily cron then finishes in about nine seconds with the upload skipped and the run still marked success, so the key can rot for weeks behind a green tick — that is how the model-catalog cron came to fail with `InvalidAccessKeyId` on three consecutive Mondays while the embed SDK looked healthy. To date a dead key, find the last embed-SDK run whose `publish` job actually ran (`gh run list --workflow=publish-embed-sdk.yml`, look for a duration in minutes rather than seconds) and compare it against the first model-catalog failure. To test a rotated key, dispatch `sync-model-catalog.yml` — it uploads unconditionally.
- **Publishing is an overwrite of one S3 key, and it only ever happens on the Monday cron or a manual `workflow_dispatch`.** Never on merge, deploy or release. There is no versioning and no history: last write wins and the previous contents are gone, which is why the object carries `generatedAt` — `curl -s https://cdn.activepieces.com/ai/model-catalog.json | jq .generatedAt` is the only way to tell how fresh what you are serving is. Editing the generator changes nothing in production until someone dispatches the workflow.
Expand Down
3 changes: 2 additions & 1 deletion brain/knowledge/flows-execution/chat.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ A turn is kept alive / reclaimed by three separate mechanisms in `execute-agent-
- **Stream idle watchdog** (`STREAM_IDLE_TIMEOUT_MS` 90s, in `streamChunksToClient`): aborts the turn if the drain-stream reader is silent 90s. It must be SUSPENDED while legitimate silent work is in flight — pending tool calls AND in-flight reasoning (`reasoning-start`→`reasoning-end`). **Reasoning-awareness was missing and caused the bug where long "thinking" on the Expert tier randomly aborted a healthy turn** (a >90s gap between reasoning deltas looked like a wedge). Backstop for a genuine mid-reasoning wedge is `MAX_TURN_WALL_CLOCK_MS` (20 min).

### Gotchas
- **Chat has no fixed step cap.** A chat turn is bounded by credits (checked after every step), the runaway-token ceiling (`RUNAWAY_TURN_CONTEXT_MULTIPLE` × the context window), the identical-failure guard and the 2-hour `MAX_AGENT_TURN_WALL_CLOCK_MS`, so it finishes long jobs. A saved agent's author-set `maxSteps` is still honored on its last step: an agent with structured output is forced to call `TASK_COMPLETION_TOOL_NAME` so the flow gets a result, and any other agent runs with `toolChoice: 'none'` plus a wrap-up note, so it replies with what's done and what's left. Never a silent stop or an error.
- **The streaming lock is per run, not per conversation.** A re-send can claim `activeRunId` before the first job reaches `getAgentConfig`. `agentHelpers.acquireStreamingLock` only lets the owning run set STREAMING; an older run gets `AGENT_RUN_SUPERSEDED` and the worker exits quietly, with no ERROR save and no events. A lock that ignored `runId` let the old run stream unowned while the new one was rejected as busy and marked ERROR, which is how users saw nothing after tapping a starter card twice.
- **A failed turn used to leave status ERROR with an empty reply.** The error text only travelled as a websocket `ERROR` event, so a reload, another tab, or a user who was away saw a dead conversation (and often no user message either when the job died inside `getAgentConfig`, before it persists the turn). The `execute-agent-run.ts` catch now sends `failure: { message, userMessage? }` on the empty `saveAgentMessages` call and `conversation-rpc.ts` appends it to `uiMessages` as an assistant text reply; `use-chat.ts` shows the Retry banner when a loaded conversation is ERROR. Stale STREAMING to IDLE recovery, a worker that never picks the job up, and `assertAgentMessageRateLimitNotExceeded` still leave no reply of their own.
- **A built flow ends with a "Turn it on?" card, never an auto-publish**: an audit found 40% of built-but-unpublished flows ended on "open it to review", some claiming LIVE. Chat never publishes on its own; only a yes to the card calls `ap_lock_and_publish` (`build_flow.md` "Turn it on?"). Pinned by the `build-then-ask-turn-it-on` fixture (`askedToTurnItOn`, `noLiveClaimWithoutPublish`). The live-claim check is a regex plus "was `ap_lock_and_publish` called", so it cannot see whether publish succeeded.
- **Server-managed connections**: the LLM never sees connection externalIds; `ap_execute_action` auto-fills them from a Redis store.
- **Prompt-injection taint**: a per-turn `taintState` flips to `tainted` once the turn reads outside or user data (MCP tools, web/search/scrape, `ap_explore_data`, `ap_execute_action`, `ap_run_code`, `ap_list_across_projects`, configured tools). It forces the action-preview gate on non-read-only actions, blocks saved-agent edits, and makes `ap_remember` ask before saving (memory reaches every future conversation). It carries one message: each saved reply stores `tainted` (this reply's own reads, via `createTaintState`), and the next message starts from it. Deletes are confirmed always, not by taint.
- **Prompt-injection taint**: a per-turn `taintState` flips to `tainted` once the turn reads outside or user data (MCP tools, web/search/scrape, `ap_explore_data`, `ap_execute_action`, `ap_run_code`, `ap_list_across_projects`, configured tools). It forces the action-preview gate on non-read-only actions, makes saved-agent edits (`ap_update_agent`, `ap_add_agent_tool`, `ap_remove_agent_tool`, `ap_create_agent`) ask for approval on the action card instead of refusing, and makes `ap_remember` ask before saving (memory reaches every future conversation). It carries one message: each saved reply stores `tainted` (this reply's own reads, via `createTaintState`), and the next message starts from it. Deletes are confirmed always, not by taint.
- **Write-check gate**: before a live `ap_test_flow`, `__flow_write_check` RPC flags write/destructive PIECE steps; read-only flows run ungated; gate fails open on RPC error.
- **Cloud rollout cap**: opens to non-embed users without `chatEnabled` until 200 distinct users have sent a message (`CLOUD_CHAT_ROLLOUT_CAP`); grandfathered after close. Embedded sessions never see chat.
- **Flow correctness is 100% prompt/guide-driven — nothing in code enforces it.** The "#1 silent bug" ("Class A"): the agent frames a *recurring* automation as a *one-time task* and omits any anti-reprocessing step, so run N+1 redoes run N's work (re-pays, re-sends). It's a design-time reasoning gap, not a testing gap — `ap_test_flow` runs ONCE, so a single test looks perfect; the bug only shows on the 2nd run. Fix lives in the prompt (`chat-system-prompt.md` `<decision_framework>` + `build_flow.md` "Recurring flows must not reprocess") + capability eval fixtures with a `recurring_avoids_reprocessing` judge dimension. The platform already has every primitive (Tables New-Record webhook, polling `DedupeStrategy`, `_dedupe_key`, Store, update/delete-record); the agent just wasn't reaching for them. Watch the `build_flow.md` "don't over-build" bias — it once actively discouraged the fix.
Expand Down
73 changes: 61 additions & 12 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions docs/install/reference/breaking-changes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ icon: "hammer"

### What has changed?

#### Zoho CRM Read File and Custom API Call only send the token to the connection's Zoho CRM hosts

Read File used to send the connection's Zoho access token to whatever URL it was given, including hosts outside Zoho. From Zoho CRM 0.4.0 it only fetches `https` URLs on the connection's own Zoho API host under `/crm/` (for example `https://www.zohoapis.com/crm/bulk/v8/read/<job>/result`), or on that data centre's download hosts (for example `https://download-accl.zoho.com/v2/crm/...` for a data backup). Custom Zoho function URLs (`/crm/.../functions/...`) and URLs in another data centre are refused. Any other URL fails before a request is made. Redirects are followed only to those same hosts; a redirect anywhere else stops the download before that host is requested. The file is streamed, so the deployment's file size limit (`AP_MAX_FILE_SIZE_MB`) applies.

Custom API Call keeps working with paths such as `/Leads` and with full URLs on the connection's own API host (for example `https://www.zohoapis.com/crm/v8/...`). A full URL on any other host, including other Zoho hosts, now fails before a request is made instead of receiving the token.

#### What you need to do

Nothing if your Read File steps point at Zoho CRM backup, bulk-read or API file URLs of the connected account, and your Custom API Call steps use a path or a URL on the connection's API host. If a step calls any other URL, replace it with the HTTP piece's Send HTTP Request action. Steps keep running on the version they were built with until you upgrade them.

#### Instagram for Business no longer reports success when a reel fails to publish

Publishing a reel uploads the video to Instagram and then waits for Instagram to finish processing it before the post goes live. The piece used to give up after about a hundred seconds and return the boolean `false`, which the flow recorded as a **successful** step. Anything downstream carried on with `false` where a media id was expected, and nothing in the run said the post had not been published.
Expand Down
26 changes: 26 additions & 0 deletions packages/pieces/community/0codekit/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"extends": ["../../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], "rules": {} },
{
"files": ["*.ts", "*.tsx"],
"rules": {
"no-restricted-imports": [
"error",
{
"patterns": [
"lodash",
"lodash/*",
"@activepieces/core-*",
"@activepieces/server*",
"@activepieces/engine",
"@activepieces/shared"
]
}
]
}
},
{ "files": ["*.js", "*.jsx"], "rules": {} }
]
}
Loading
Loading