Skip to content

feat(plugins): ActivepiecesRecipeBackend — recipes sync over HTTPS - #40

Merged
rrader26 merged 1 commit into
mainfrom
feat/activepieces-recipe-backend
May 13, 2026
Merged

feat(plugins): ActivepiecesRecipeBackend — recipes sync over HTTPS#40
rrader26 merged 1 commit into
mainfrom
feat/activepieces-recipe-backend

Conversation

@rrader26

Copy link
Copy Markdown
Contributor

Summary

  • New `ActivepiecesRecipeBackend` mirrors `ActivepiecesMemoryBackend`. Pairs with flobyteAI PR #694 (the matching Activepieces recipes REST API).
  • Same agentmark binary now supports both local-file and Activepieces-backed recipe storage. Operators pick at construction time.
  • 15 new tests, 506 total. Build clean.

⚠️ Depends on flobyteAI PR #694 landing first. The backend is dormant until the API exists.

Architecture

```ts
const recipes = createRecipesPlugin({
backend: new ActivepiecesRecipeBackend({
baseUrl: process.env.AP_BASE_URL,
apiKey: process.env.AP_API_KEY, // sk-...
projectId: process.env.AP_PROJECT_ID,
chatbotId: process.env.AP_CHATBOT_ID, // optional
}),
})
```

Endpoint contract

Mirrors flobyteAI PR #694 1-to-1. Both project-scoped and chatbot-scoped routes:
```
POST /v1/projects/:projectId/[chatbots/:chatbotId/]recipes ?on_conflict=fail|replace
GET /v1/projects/:projectId/[chatbots/:chatbotId/]recipes ?target_app=
GET /v1/projects/:projectId/[chatbots/:chatbotId/]recipes/:name
DELETE /v1/projects/:projectId/[chatbots/:chatbotId/]recipes/:name
GET /v1/projects/:projectId/[chatbots/:chatbotId/]recipes/describe
```

Field translation

agentmark Activepieces
`target_app` `targetApp` (snake ↔ camel)
everything else identical

Test plan

  • `pnpm build` clean
  • `pnpm test` — 506 pass / 10 skip (15 new tests covering auth, routing, save translation, error semantics)
  • Manual: after flobyteAI PR #694 ships, configure an Activepieces API key + project, save a recipe from Claude Code, verify via the Activepieces UI that the row appears

🤖 Generated with Claude Code

Pairs with flobyteAI PR #694 (Activepieces recipes endpoints). Same
agentmark binary now supports two production-ready recipe deployments:

  - Local-only (default): file-based, single-user laptop
  - Activepieces-backed: hits the live ThinkFleet recipes API, team-
    shareable across users / sessions / on-prem deployments

Mirrors ActivepiecesMemoryBackend exactly so the wiring story stays
uniform: same Bearer sk-* auth, same project + chatbot scope model,
same 404→null/false semantics on get/delete.

Endpoint contract (one-to-one with flobyteAI PR #694):
  POST   /v1/projects/:projectId/[chatbots/:chatbotId/]recipes
         ?on_conflict=fail|replace                   create / replace
  GET    /v1/projects/:projectId/[chatbots/:chatbotId/]recipes
         ?target_app=<name>                          list + filter
  GET    /v1/projects/:projectId/[chatbots/:chatbotId/]recipes/:name
  DELETE /v1/projects/:projectId/[chatbots/:chatbotId/]recipes/:name
  GET    /v1/projects/:projectId/[chatbots/:chatbotId/]recipes/describe

Field-name translation on the wire:
  agentmark `target_app` ↔ Activepieces `targetApp` (snake/camel)
  Everything else is field-identical.

Usage (post-merge of both PRs):

  import { createRecipesPlugin, ActivepiecesRecipeBackend } from '@thinkfleet/agentmark'

  const recipes = createRecipesPlugin({
      backend: new ActivepiecesRecipeBackend({
          baseUrl: process.env.AP_BASE_URL,
          apiKey: process.env.AP_API_KEY,        // sk-...
          projectId: process.env.AP_PROJECT_ID,
          chatbotId: process.env.AP_CHATBOT_ID,  // optional
      }),
  })

Same Claude Code / Cursor / Codex agent now reads and writes recipes
to **real Activepieces storage** instead of a local file. Team
members in the same project share recipes automatically.

Tests (15 new, 506 total):
  - Construction validation (baseUrl, sk- prefix, projectId)
  - Auth shape + project/chatbot routing
  - save() POSTs to /recipes with on_conflict query param
  - save() translates target_app → targetApp on the wire
  - save() translates targetApp → target_app on the response
  - get/delete return null/false on 404 (not throw)
  - list with target_app builds the query string
  - non-2xx throws ActivepiecesRecipeError with status + body
  - describe reports kind=activepieces

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rrader26
rrader26 merged commit 03f732b into main May 13, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants