Actionlayer
ActionLayer component for Bijection — run tasks on any website and get reactive status updates in your Bijection app.
git clone https://github.com/bijectionhq/actionlayer.git
cd actionlayer
git checkout 6b66b49d7e1fbeaac0a024132a4fc7cf526c33d4Bijection repository access is required. Request access.
Description
ActionLayer component for Bijection — run tasks on any website and get reactive status updates in your Bijection app.
Explore the package README for API concepts, configuration, and examples. Check the Bijection source for adaptation-specific setup.
Review the source and its dependencies before adopting this package. Source availability does not establish npm publication or runtime qualification.
Getting started
- Get the source at the revision above and read its package documentation.
- Check the required Bijection SDK version, dependencies, and external service credentials.
- Follow the package setup instructions and the guide to using components.
- Exercise the component in your deployment according to your project’s verification rules.
Open source
Maintained source: bijectionhq/actionlayer. Based on ActionLayer-io/actionlayer-convex. License: Apache-2.0. Consult the repository for license terms, notices, and contributor attribution.
From the upstream publisher
ActionLayer component for Convex — run tasks on any website and get reactive status updates in your Convex app.
Explore the demo ↗Upstream overview
From the upstream package documentation.
ActionLayer is a Convex component that submits tasks, then streams task status updates into your Convex database via a scheduled poll loop. It handles anything in the physical world - from restaurant reservations, flower delivery, ride booking, and much more. Task state is stored in a component-owned table and surfaced through reactive queries, so your UI updates without any client-side polling logic.
Use cases
From the upstream package documentation.
- Deliver flowers to a loved one
- Find a plumber or electrician nearby
- Get food delivered
- Sort out your grocery shopping
- Absolutely anything in the physical world, we'll handle it for you!
How it works
From the upstream package documentation.
Register the component in convex/convex.config.ts using app.use(actionlayer), set your ACTIONLAYER_API_KEY environment variable, and run npx convex dev to generate the typed components.actionlayer reference. Then instantiate new ActionLayer(components.actionlayer) inside your Convex functions to get access to the client API.
Call actionLayer.startTask(ctx, { goal }) from a Convex action to submit a task. This calls the ActionLayer API, writes a ticket record to a component-owned table, and schedules a poll loop using the Convex scheduler. The poll loop updates the row as the task progresses through states: pending, blocked_on_user, completed, failed, or cancelled.
Your frontend subscribes to actionLayer.get(ctx, { ticketId }) wrapped in a Convex query and uses useQuery to receive reactive updates. When a task reaches blocked_on_user, the infoRequest field contains what is needed from the user. Call actionLayer.reply(ctx, { ticketId, message }) to resume it, or actionLayer.cancel(ctx, { ticketId }) to stop it. Your app's own tables are never written to by the component.
Upstream package FAQ
Does ActionLayer modify my app's Convex tables?
No. The @actionlayer/convex component stores all task state in its own component-owned table, leaving your app's tables untouched. Task records are scoped to the component and accessed through the generated components.actionlayer API reference.
How does ActionLayer keep my Convex UI updated without polling?
When you call actionLayer.startTask, the component schedules a Convex scheduler-driven poll loop that fetches task status from the ActionLayer API and writes updates to a component table. Because the data lives in Convex, any useQuery subscription to your status query function re-renders automatically on every state change.
What states can an ActionLayer task be in?
An ActionLayer task moves through the states: pending, completed, failed, cancelled, and blocked_on_user. The blocked_on_user state occurs when the task requires additional input from the user, such as a missing detail or a choice. The required information is surfaced in the infoRequest and reason fields of the task record.
How do I cancel an in-flight ActionLayer task?
You can stop a running task by calling actionLayer.cancel(ctx, { ticketId }) from a Convex action. This moves the task to the cancelled terminal state and stops the internal poll loop.
What do I need to configure to use @actionlayer/convex?
You need to install the package, register the component in convex/convex.config.ts using app.use(actionlayer), and add your ACTIONLAYER_API_KEY environment variable in the Convex dashboard under Settings then Environment Variables. After running npx convex dev, the components.actionlayer reference is available in your generated API.
Use with agents and CLI
Give your coding agent the component’s source identity and setup guidance.
Help me integrate Actionlayer with Bijection.
Read: https://bijection.com/components/actionlayer/SKILL.md
Check SDK compatibility and dependency availability.
Follow this project's execution and verification rules.Upstream README.md
View repository ↗Documentation from ActionLayer-io/actionlayer-convex, recorded October 23, 2026. APIs and setup may differ in the Bijection adaptation.
@actionlayer/convex
Run tasks on any website from your Convex app. ActionLayer operates a real browser end-to-end — bookings, signups, checkouts, form fills, data pulls — and this component streams task status into your Convex database, so your UI updates reactively as the task progresses.
Setup
1. Install the package:
npm install @actionlayer/convex
2. Register the component in your app's convex/convex.config.ts (create
the file if it doesn't exist):
// convex/convex.config.ts
import { defineApp } from "convex/server";
import actionlayer from "@actionlayer/convex/convex.config";
const app = defineApp();
app.use(actionlayer);
export default app;
3. Set your API key in the Convex dashboard (Settings → Environment Variables) — get one at actionlayer.io/app#settings:
ACTIONLAYER_API_KEY=ak_...
4. Run codegen so components.actionlayer shows up in your generated API:
npx convex dev
5. Instantiate the ActionLayer client in your Convex functions and call
it — see below.
Use
// convex/tasks.ts
import { action, query } from "./_generated/server";
import { components } from "./_generated/api";
import { ActionLayer } from "@actionlayer/convex";
import { v } from "convex/values";
const actionLayer = new ActionLayer(components.actionlayer);
export const book = action({
args: { goal: v.string() },
handler: async (ctx, args) => {
// e.g. "Book a table for 2 at Lilia Brooklyn this Saturday around 7pm"
return await actionLayer.startTask(ctx, { goal: args.goal });
},
});
export const status = query({
args: { ticketId: v.string() },
handler: async (ctx, args) => {
return await actionLayer.get(ctx, args);
},
});
Your frontend subscribes with useQuery(api.tasks.status, { ticketId }) and
re-renders on every state change — no polling code on your side.
Task lifecycle
state moves through pending → completed | failed | cancelled. If the
task needs something from your user (a choice, a missing detail), it parks at
blocked_on_user with the ask in infoRequest / reason. Send the answer
back and it resumes:
await actionLayer.reply(ctx, { ticketId, message: "the 7:30pm slot works" });
cancel(ctx, { ticketId }) stops an in-flight task.
How it works
startTask calls the ActionLayer API, records the ticket in a component-owned
table, and schedules a poll loop with the Convex scheduler. The loop updates
the row until the task reaches a terminal state; every update flows to your
subscribed queries. Your app's tables are untouched — the component keeps its
state to itself.
Development
npm install
npm run typecheck
npm run build
src/component/_generated is committed — running npx convex dev in an app
that mounts the component regenerates it.
Publishing follows the standard Convex component flow — see docs.convex.dev/components/authoring.