Skip to main content

eachlabs-workflows

Build, run and manage multi-step AI workflows that chain EachLabs models into one API call. Create a workflow from a JSON definition, trigger it, read its results and manage versions. Use when a task chains several models, reuses a fixed prompt, needs a fallback model, runs steps in parallel, routes on a condition, or calls an HTTP API between model steps.

ソース情報

リポジトリ
eachlabs/skills
ソースの最終更新活動
2026年10月7日 13:24
検出された SKILL.md の言語
英語
スター
39
フォーク
5

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

ファイルエクスプローラー
2 ファイル

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
eachlabs-workflows
description
Build, run and manage multi-step AI workflows that chain EachLabs models into one API call. Create a workflow from a JSON definition, trigger it, read its results and manage versions. Use when a task chains several models, reuses a fixed prompt, needs a fallback model, runs steps in parallel, routes on a condition, or calls an HTTP API between model steps.
metadata
{"author":"eachlabs","version":"3.0"}
# EachLabs Workflows Build, manage, and execute multi-step AI pipelines that chain multiple models together. each::workflows is completely free to use - you only pay for underlying model costs. ## Authentication ``` Header: Authorization: Bearer <your-api-key> ``` Set the `EACHLABS_API_KEY` environment variable. Get your key at [eachlabs.ai](https://www.eachlabs.ai/api-keys). The `X-API-Key` header is also accepted. ## Base URL ``` https://api.eachlabs.ai ``` ## Endpoints | Method | Path | Description | |--------|------|-------------| | POST | `/v1/workflows` | Create a workflow (with its first version) | | GET | `/v1/workflows/{workflowID}` | Get a workflow (UUID or slug) with its versions | | PUT | `/v1/workflows/{workflowID}/versions/{versionID}` | Create or update a version | | POST | `/v1/workflows/trigger/{workflowID}/{versionID}` | Run a version | | POST | `/v1/workflows/bulk-trigger/{workflowID}/{versionID}` | Run a version with 1-10 inputs | | GET | `/v1/workflows/{workflowID}/executions` | List runs (filter a batch with `?bulk_id=`) | | GET | `/v1/workflows/executions/{executionID}` | Get a run's status and results | ## When to Use a Workflow | The task wants to… | A workflow gives it | |---|---| | Ship an AI feature as one call | Prompts, models and intermediate files stay on each::labs; the app only sends inputs | | Change it without an app release | Edit a prompt or swap a model in a new version; callers keep the same workflow ID | | Keep working when a model fails | A `fallback` model runs automatically if the first one errors | | Combine image, video, audio and text | Chain an image edit into a video model, then resize, merge clips or add music | | Go faster | Run independent steps (one per photo, one per scene) in `parallel` | | Let AI decide the path | Ask a vision model a question, then route with a `choice` step | | Use your own systems | Call any public HTTPS API from a step to fetch data or run your own code | One model with a prompt the user writes is simpler as a direct prediction. Use a workflow once the prompt is fixed, a fallback is wanted, or there is a second step. ## Building a Workflow ### Step 1: Create the Workflow ```bash curl -X POST https://api.eachlabs.ai/v1/workflows \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $EACHLABS_API_KEY" \ -d '{ "name": "Text to Image Generator", "definition": { "input_schema": { "properties": { "prompt": { "type": "string", "required": true } } }, "steps": [ { "id": "write_prompt", "type": "model", "model": "eachlabs-llm-router", "params": { "model": "google/gemini-3.6-flash", "messages": [ { "role": "system", "content": "Rewrite the idea as one vivid, detailed image prompt. Reply with the prompt only." }, { "role": "user", "content": "$.inputs.prompt" } ] } }, { "id": "generate_image", "type": "model", "model": "nano-banana-2-text-to-image", "params": { "prompt": "$.write_prompt.primary.choices[0].message.content", "aspect_ratio": "16:9" } } ] } }' ``` The response has `workflow_id` and `versions[0].version_id` (`v1`). If it returns `400 invalid argument`, send the same definition to `PUT /v1/workflows/{workflowID}/versions/v1` as `{"definition": {...}}` to see the exact validation error. ### Step 2: Trigger the Workflow ```bash curl -X POST https://api.eachlabs.ai/v1/workflows/trigger/{workflowID}/v1 \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $EACHLABS_API_KEY" \ -d '{ "inputs": {"prompt": "A lighthouse on a cliff at sunset"} }' ``` Response: ```json {"execution_id": "exec-123", "status": "queued"} ``` ### Step 3: Poll for Result ```bash curl https://api.eachlabs.ai/v1/workflows/executions/{executionID} \ -H "Authorization: Bearer $EACHLABS_API_KEY" ``` Response (shortened): ```json { "execution_id": "exec-123", "status": "completed", "output": "https://cdn-us.eachlabs.ai/uploads/3334048f.png", "step_outputs": { "write_prompt": {"status": "completed", "primary": {"choices": [{"message": {"content": "A dramatic wide-angle photograph of a lighthouse..."}}]}}, "generate_image": {"status": "completed", "primary": "https://cdn-us.eachlabs.ai/uploads/3334048f.png"} } } ``` Execution statuses: `running`, `completed`, `failed`, `cancelled` `output` is the result of the last step. `workflow_output` holds named outputs when the version defines `output_mapping`. ## Authoring Rules Follow these and a workflow runs on the first try: 1. Reference values with `$.` paths: `$.inputs.<name>`, `$.<step_id>.primary`, `$.<step_id>.output`, nested fields, and brackets for list items (`$.step.output[0]`). `{{inputs.prompt}}` is NOT a reference; it is sent to the model as literal text. 2. A parameter that is exactly one reference keeps its type (URL, number, list, object). A reference inside a longer string is inserted as text: `"A portrait of $.inputs.name in neon light"`. 3. `primary` is the main result: the file URL for image and video models, the chat completion for `eachlabs-llm-router` (text at `$.step.primary.choices[0].message.content`), the response for `eachlabs-http-step` (JSON fields at `$.step.primary.output.<field>`). 4. If a prompt-like parameter (`prompt`, `user_prompt`, `system_prompt`, `text`, `content`, `message`, `caption`, `title`, `description`) is exactly `$.step.primary` or `$.step.output`, the value arrives JSON-encoded, wrapped in quotes. Reference a deeper field or embed the reference in a sentence. 5. Every step, including steps inside branches, needs a unique `id`. Steps run top to bottom and can only reference inputs and earlier steps. 6. Inputs go in `input_schema.properties`, each with `type`, `required` (`true`/`false`) and an optional `default_value`. Give every optional input a `default_value`: a run fails if a step references an omitted input that has no default. Empty values are dropped from lists, so `["$.inputs.photo1", "$.inputs.photo2"]` works with one or two photos when `photo2` defaults to `""`. 7. Model slugs and parameters are checked when a step runs, not when you save. Read a model's inputs with `GET https://api.eachlabs.ai/v1/models/{slug}` and run the workflow once before shipping it. ## Step Types | Type | Purpose | |------|---------| | `model` | Run a model: `model` (slug), `params`, optional `fallback`, `retry`, `timeout_seconds` | | `parallel` | Run `branches[].steps` at the same time | | `choice` | Evaluate a condition and run `condition_met_branch` or `default_branch` | | `pass` | Return a fixed `result` | HTTP requests and Python code are not step types. They run as model steps through `eachlabs-http-step` (below) and `eachlabs-python-step` (private beta). ### Model Steps ```json { "id": "restyle", "type": "model", "model": "nano-banana-2-edit", "params": { "prompt": "Restyle this photo as $.inputs.style. Keep the person's face unchanged.", "image_urls": ["$.inputs.photo"], "aspect_ratio": "9:16" }, "retry": {"max_attempts": 3, "retry_on": ["server_error"]} } ``` ### HTTP Calls Call any public HTTPS API with the `eachlabs-http-step` model. Params: `url`, `method`, `headers`, `query_params`, `body` (JSON object for `POST`/`PUT`/`PATCH`), `timeout_seconds` (up to 30 recommended) and `fail_on_status` (`"non_2xx"` stops the run on an error response). ```json { "id": "product", "type": "model", "model": "eachlabs-http-step", "params": { "url": "https://dummyjson.com/products/$.inputs.product_id", "method": "GET", "timeout_seconds": 20, "fail_on_status": "non_2xx" } } ``` A later step reads the JSON body as `$.product.primary.output.title`. Put credentials in `headers` (for example `"Authorization": "Bearer <scoped-token>"`); only public URLs are reachable. To run your own code, host it behind an HTTPS endpoint and `POST` to it. ### Parallel Steps ```json { "id": "prepare", "type": "parallel", "branches": [ {"steps": [{"id": "edit_a", "type": "model", "model": "nano-banana-2-edit", "params": {"prompt": "Full-body photo of this person as a traveler in a sunny old-town street.", "image_urls": ["$.inputs.photo_a"]}}]}, {"steps": [{"id": "edit_b", "type": "model", "model": "nano-banana-2-edit", "params": {"prompt": "Full-body photo of this person as a traveler in a sunny old-town street.", "image_urls": ["$.inputs.photo_b"]}}]} ] } ``` Later steps reference branch steps by their own ids: `$.edit_a.primary`, `$.edit_b.primary`. A branch can hold several steps that run in order. ### Choice Steps (Conditional Routing) ```json { "id": "portrait", "type": "choice", "condition": { "expression": "$.subject.primary.choices[0].message.content", "operator": "string_matches", "value": "*PET*" }, "condition_met_branch": { "name": "pet", "steps": [{"id": "pet_portrait", "type": "model", "model": "nano-banana-2-edit", "params": {"prompt": "A royal oil-painting portrait of this animal wearing a small crown.", "image_urls": ["$.inputs.photo"]}}] }, "default_branch": { "name": "person", "steps": [{"id": "person_portrait", "type": "model", "model": "nano-banana-2-edit", "params": {"prompt": "A royal oil-painting portrait of this person wearing a crown. Keep their face unchanged.", "image_urls": ["$.inputs.photo"]}}] } } ``` After the choice, `$.portrait.primary` is the result of whichever branch ran, and `selected` holds its name. **Condition operators:** | Category | Operators | |----------|-----------| | Comparison | `equals`, `not_equals` (type-strict), `greater_than`, `less_than`, `greater_than_or_equal`, `less_than_or_equal` | | String | `string_equals`, `string_matches` (`*` wildcard pattern; without `*` it must match exactly) |
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る