pipefy/ai-toolkit

pipefy-ai-agents

Use this skill when the user wants to create, read, update, delete, or troubleshoot AI agents (conversational agents with behaviors).

ソースを見る
リポジトリの原文

見出し、例、コード、表、リンク、参照画像を含む原文を表示しています。

AI Agents

Read only the reference for your active surface: MCP or CLI. The workflows below use shared operation names and arguments.

Conversational AI agents attached to pipes. Each agent has an agent-level instruction and 1–5 behaviors, each with its own trigger event, prompt, and actions.

For traditional automations and AI automations (prompt-driven), see pipefy-automations.


Tools

OperationRead-onlyPurpose
get_ai_agentsYesList AI agents for a pipe (repo_uuid = pipe UUID, not numeric id).
get_ai_agentYesFull agent config including behaviors.
create_ai_agentNoCreate a new conversational agent (active by default; active=false to start disabled).
update_ai_agentNoFull-replace (not patch). Always send complete behaviors. Preserves disabled state.
delete_ai_agentNoDestructive; review and approve first.
toggle_ai_agent_statusNoExplicit activate/deactivate.
validate_ai_agent_behaviorsYesPre-flight check before create/update.

Execution logs live in pipefy-observability (get_ai_agent_logs, get_ai_agent_log_details).


Active lifecycle

  • Agents are active by default. Create-active clears the API default disabled shell via the configure update (omits disabledAt). Create-inactive (active=false) sets disabled_at explicitly on create and the chained update.
  • Routine update_ai_agent preserves disabled state — it does not intentionally reactivate. Prefer passing disabled_at from a prior get_ai_agent (disabledAt) to skip the preserve re-read; when omitted, the SDK re-reads and re-sends.
  • Explicit activate/deactivate: toggle_ai_agent_status.
  • After create/update, check the response's disabled_at and active (active is true when disabled_at is null). On get_ai_agent, disabledAt null means active; behaviors[].active is not agent enablement. An agent with no active behavior is disabled by the API regardless of enablement flags.

Creation workflow (discover → validate → create → verify)

Consent: create or suggest an AI agent only when the user explicitly asked for AI / an agent. If AI seems useful but was not requested, ask first — never introduce agents without being asked.

Never guess event IDs, phase IDs, action types, or field IDs.

1 — Get pipe metadata

Call get_pipe(pipe_id) and extract:

  • uuid → use as repo_uuid in all AI-agent tools.
  • phases[].id / phases[].name → needed for move_card actions.
  • Fields via get_start_form_fields(pipe_id) and/or get_phase_fields(phase_id) → needed for update_card actions.

2 — Check existing agents

get_ai_agents(repo_uuid) to avoid duplicates. To modify an existing agent, use update_ai_agent (not create). For full config, use get_ai_agent(uuid).

3 — Discover valid trigger events

get_automation_events(pipe_id). Common events:

Event (event_id value)event_params requiredExample
card_createdNone{}
card_moved{"to_phase_id":"<phase_id>"}Fires only when card enters that phase.
field_updated{"triggerFieldIds":["<field_id>", ...]}Fires only when those fields change.
manually_triggeredNoneUser clicks button on card.

For card_moved and field_updated, you MUST include event_params. Omitting it makes the behavior fire on every occurrence.

4 — Discover valid action types

get_automation_actions(pipe_id). Known actionType values and their required metadata:

Action (actionType value)metadata required
update_cardpipeId + fieldsAttributes (each entry needs fieldId + inputMode)
move_carddestinationPhaseId
create_cardpipeId + fieldsAttributes
createconnectedcardpipeId + fieldsAttributes (requires pipe relation)
createtablerecordtableId + fieldsAttributes (table field IDs; no pipeId)
sendemailtemplateemailTemplateId; optional allowTemplateModifications (bool)
human_validationemails (recipient list) and title. The API accepts either one alone but rejects empty metadata
mcp_toolmcpServerId + toolName; optional toolInputs, each with name and source: fixed_value with a value, or card_field with a fieldId

fieldId values for card actions accept slug or numeric internal_id; for create_table_record they are table field IDs (validate with get_table / get_table_record, not the pipe).

5 — Build the behavior dict

json
{
  "name": "<descriptive name>",
  "event_id": "<from step 3>",
  "event_params": {},
  "actionParams": {
    "aiBehaviorParams": {
      "instruction": "<prompt for the AI when this event fires>",
      "actionsAttributes": [
        { "name": "<action label>", "actionType": "<from step 4>", "metadata": { } }
      ]
    }
  }
}
  • Each behavior MUST have at least one action in actionsAttributes.
  • Maximum 5 behaviors per agent.
  • `inputMode` is required on every `fieldsAttributes` entry (omitting it fails model validation). Values: fill_with_ai (AI writes the value into an output field), fixed_value (use the literal value), copy_from (value is a %{…} template copying another field).
  • Input field references (%{field:<internal_id>} in the behavior instruction, auto-populated into referencedFieldIds on create/update) are needed only when the AI must read card field values, not for every fill_with_ai (e.g. instruction-only, OCR/attachment, or knowledge-base context). When card inputs are needed and omitted, card.fields arrives empty at trigger time and the model may hallucinate. A wrong numeric input id is accepted silently (validate and create/update) and becomes a dead referencedFieldId; a wrong slug never resolves and is dropped by the digits-only extractor (unresolved token). Either way card.fields stays empty (same hallucination); confirm the id with get_start_form_fields / get_phase_fields. Dotted connected-pipe refs (%{field:<parent>.<child>}) are not forwarded at runtime; to read a connected card field, use a field on the current pipe.
  • For update_card: set destinationPhaseId: "" when not moving the card.

Example identifiers (fictional)

Use real values from get_pipe / get_start_form_fields for your org. Placeholders below match unit-test fixtures in this repo. The syntax matters (pipeId, fieldId, %{field:<internal_id>}, inputMode) — the example digits do not; substitute each pipe's numeric internal_id and phase id.

RoleExample value
Pipe (numeric repo id)987654321
Field internal_id900000101
Destination phase (move_card)900000201
Target pipe (create_card)900000301

Metadata examples

json
// update_card — output field fill_with_ai; input fields referenced in instruction
{ "pipeId": "987654321", "destinationPhaseId": "", "fieldsAttributes": [{ "fieldId": "900000101", "inputMode": "fill_with_ai", "value": "" }] }
// companion instruction (aiBehaviorParams.instruction), not metadata:
// "Read %{field:900000102} (title) and %{field:900000103} (description), then fill the category."

// move_card
{ "destinationPhaseId": "900000201", "fieldsAttributes": [] }

// create_card
{ "pipeId": "900000301", "fieldsAttributes": [{ "fieldId": "title", "inputMode": "fill_with_ai", "value": "" }] }

// create_table_record (fieldsAttributes are TABLE field IDs; no pipeId)
{ "tableId": "<table_id>", "fieldsAttributes": [{ "fieldId": "<table_field_id>", "inputMode": "fill_with_ai", "value": "" }] }

// send_email_template
{ "emailTemplateId": "<template_id>", "allowTemplateModifications": false }

// human_validation
{ "emails": ["reviewer@example.com"], "title": "Review this card" }

// mcp_tool (mcpServerId is an MCP server registered on the pipe)
{ "mcpServerId": "<mcp_server_id>", "toolName": "<tool_name>", "toolInputs": [{ "name": "query", "source": "fixed_value", "value": "acme" }, { "name": "email", "source": "card_field", "fieldId": "customer_email" }] }

5b — Optional: capabilities and LLM provider

Inside actionParams.aiBehaviorParams a behavior may also carry:

  • `capabilitiesAttributes` — advanced tools the behavior can use. Each entry is exactly { "capabilityType": "<type>", "enabled": true|false } (both keys required, no extra keys — bare strings or { "type": ... } are rejected).
Product namecapabilityType
IDP / Intelligent Document Processingadvanced_ocr
Calculations & Analysismath_operations
Web Searchweb_search
Web Scrapingweb_scraping
Max effortmax_effort

capabilityType is not checked against a fixed set — any value passes through and the API validates the enum on write, so new capabilities work without a toolkit update. Validation checks shape only, not entitlement — a capability may still require organization-level enablement to have any effect, so a green pre-flight does not guarantee the capability is active for the org.

  • `providerId` / `systemProviderId` — pick the behavior's LLM provider. Set at most one (a behavior resolves to a single active provider). Discover valid IDs with get_llm_providers: each provider carries type — use providerId for a custom (byom) provider and systemProviderId for a Pipefy-managed (system) one. get_default_llm_provider shows what a behavior falls back to when neither is set. IDs are also visible in the organization's AI settings in the Pipefy UI.

Bring your own model (custom provider). First probe validate_llm_provider_access: read access does not prove the stronger manage_ai_providers permission or eligible plan required for writes. Create a provider with configuration_file_path (a local JSON file) and use its id as providerId. For update_llm_provider, send the full configuration: retain __REDACTED__ placeholders to preserve existing secrets or supply new values to rotate them. Check get_llm_provider_dependencies before delete_llm_provider; use set_llm_provider_active_status for activation. set_default_llm_provider takes exactly one of provider_id / system_provider_id; reset_default_llm_provider clears the default.

  • `dataSourceIds` — knowledge base sources the behavior can draw on. Each ID is a knowledge base item ID from get_ai_knowledge_bases. Agents also carry an agent-level data_source_ids; the two are unioned. See Knowledge bases below for the create → attach flow.
json
{
  "instruction": "Extract totals from the attached invoice.",
  "capabilitiesAttributes": [{ "capabilityType": "advanced_ocr", "enabled": true }],
  "actionsAttributes": [ /* ... */ ]
}

6 — Validate (recommended for complex behaviors)

validate_ai_agent_behaviors(pipe_id, behaviors) checks:

  • Output field IDs (fieldsAttributes[].fieldId) exist in the pipe
  • Phase IDs exist
  • Pipe relations exist for create_connected_card
  • Action types are valid (KNOWN_AI_ACTION_TYPES; create_table_record fieldsAttributes are table field IDs, so they are not checked against the pipe and surface a warning to verify with get_table; send_email_template metadata runs no pipe field-ID checks)
  • Behavior structure passes Pydantic validation (including canonical capabilitiesAttributes shape and at most one of providerId / systemProviderId)
  • fieldsAttributes[].fieldId values (outputs) are checked against start-form and phase fields, accepting both slug id and numeric internal_id. Instruction %{field:...} tokens (inputs) are not existence-checked: a missing id/slug still yields valid: true. Slug → numeric rewrite happens only on create/update, not here.
  • Pass data_source_ids (agent-level) to also check knowledge base membership: it is unioned with each behavior's dataSourceIds and checked against the pipe's knowledge bases. Unknown IDs are warnings only (valid stays true); if the knowledge base list cannot be read, a single warning is added and the check is skipped.

`strict_unknown_action_types` (default true): an actionType outside KNOWN_AI_ACTION_TYPES is reported in problems (blocking). Set false to demote unknown action types to warnings only, so valid stays true.

7 — Create the agent

create_ai_agent with name, repo_uuid, instruction, and behaviors. One-call creation is preferred — avoids partial agent shells. Agents are active by default; pass active=false to start disabled (see Active lifecycle).

On create/update, slug fieldId values are resolved to numeric internal_id, %{field:<slug>} is rewritten to %{field:<internal_id>}, and referencedFieldIds is auto-populated when applicable. The SDK injects action referenceId values and %{action:<uuid>} placeholders for every surface; do not generate them yourself.

8 — Handle responses

  • Success with `agent_uuid` → check disabled_at and active on the write response to verify agent enablement.
  • Partial failure (behaviors rejected) → the SDK raises AiAgentConfigureError; use its .agent_uuid to recover the existing shell. The MCP response carries agent_uuid. Call update_ai_agent with the full required payload: uuid, repo_uuid (same pipe UUID used on create), name, instruction, and complete behaviors (full-replace, not patch). Do NOT create a second agent. The create shell is often disabled; update preserves that state — call toggle_ai_agent_status after a successful recovery update if you need the agent active.
  • Failure without UUID → validation or API error. Trust the hint text in the enriched error.

9 — Verify

get_ai_agent(uuid) to confirm behaviors and enablement (disabledAt null means active). Do not treat behaviors[].active as agent enablement; never assume inactive without confirmation.


Knowledge bases (data sources)

Knowledge bases are pipe-scoped data sources an agent draws on. Attach one by putting its ID in a behavior's dataSourceIds (or the agent-level data_source_ids). All knowledge base operations are scoped by the pipe UUID (pipe_uuid), not the numeric pipe ID — get_pipe returns the uuid.

OperationRead-onlyPurpose
get_ai_knowledge_basesYesList every item on a pipe (plain texts, documents, data lookups); each has an id for dataSourceIds and a type (knowledge_base_plain_texts, knowledge_base_documents, or data_lookups).
get_ai_knowledge_base_plain_textYesFetch one plain text with its content.
create_ai_knowledge_base_plain_textNoCreate a plain text (name, content 1-3500, description 1-900 — all required).
update_ai_knowledge_base_plain_textNoPartial update; pass at least one of name/content/description.
delete_ai_knowledge_base_plain_textNoDestructive; review and approve first.
get_ai_knowledge_base_documentYesFetch one document's metadata (content is the stored URL, not text).
create_ai_knowledge_base_documentNoUpload a PDF (name, description 1-900, file_path). .pdf + 20 MiB cap; indexing is asynchronous.
update_ai_knowledge_base_documentNoMetadata-only update (name/description); no file replacement.
delete_ai_knowledge_base_documentNoDestructive; review and approve first.
get_ai_knowledge_base_data_lookupYesFetch one data lookup; the payload never includes conditions — keep the definition client-side.
create_ai_knowledge_base_data_lookupNoCreate a data lookup (name, description 1-900, source_repo_id numeric pipe ID, output_fields 1-30, conditions — all required).
update_ai_knowledge_base_data_lookupNoFull replacement: resend source_repo_id/output_fields/conditions every call; omitted search_query clears it; only name/description are partial.
delete_ai_knowledge_base_data_lookupNoDestructive; review and approve first.
validate_knowledge_base_accessYesProbe read access before writes.

Flow: validate-access → create plain text → attach

  1. Probe access — validate_knowledge_base_access(pipe_uuid). A green result proves read access only (read_ai_agents), never the manage_ai_agents entitlement writes need.
  2. Create the source — create_ai_knowledge_base_plain_text(pipe_uuid, name, content, description). Limits fail fast client-side: content 1-3500 chars, description 1-900 chars (both required). Keep the returned id.
  3. Attach — add that id to a behavior's dataSourceIds (or the agent-level data_source_ids) when calling create_ai_agent / update_ai_agent. Validate first with validate_ai_agent_behaviors(pipe_id, behaviors, data_source_ids=[...]) — unknown IDs surface as warnings.

For a PDF document, use create_ai_knowledge_base_document with pipe_uuid, name, description, and file_path at step 2. Only .pdf is accepted, with a 20 MiB cap. Indexing is asynchronous, so the document may not be searchable immediately. Keep the returned id and attach it.

Data lookups: create with an AI-filled condition → attach → update (full replacement)

A data lookup lets the agent search cards in a source pipe by conditions and return selected field values. Same flow as above at step 2, with three rules of its own:

  1. Create — create_ai_knowledge_base_data_lookup(pipe_uuid, name, description, source_repo_id, output_fields, conditions). source_repo_id is the numeric ID of the source pipe (a UUID is accepted by the API but the lookup then breaks when the agent runs it). output_fields takes 1-30 field IDs (field slugs plus static fields like id, title, created_at). Each condition needs field + operator (opaque backend string, e.g. "eq", "contains") and is either static (string value required) or AI-filled — the AI asks the user for the value at runtime:
json
   [{"field": "customer_email", "operator": "eq", "usingFillWithAi": true,
     "inputName": "Customer email", "inputType": "text",
     "inputDescription": "The customer's email address"}]
  1. Attach — keep the returned id and add it to dataSourceIds, exactly as for the other kinds. Also keep the definition you sent: reads never return conditions, so your copy is the only complete record of the lookup.
  2. Update replaces everything — update_ai_knowledge_base_data_lookup requires source_repo_id, output_fields, and conditions on every call (the complete condition set, not a delta), and omitting search_query clears it. Only name/description keep their stored values when omitted.

Token normalization & slug resolution

Instructions accept five token aliases — all normalize to canonical %{field:<internal_id>}:

FormBehavior
%{<internal_id>}Canonical short form.
{<internal_id>}Bare; auto-prefixed with %.
{field:<internal_id>}Bare-with-prefix; auto-%.
{field:<slug>}Bare slug; resolved to numeric when behavior action carries pipeId.
%{field:<internal_id>}Canonical full form.

%{field:<slug>} is rewritten to %{field:<internal_id>} when an action in the behavior supplies pipeId. If the Pipefy UI shows plain text instead of chips in token slots, the payload probably still has non-canonical tokens.


Template params / placeholders

Per behavior you can pass template_params (or placeholders) with str → str values and use {{name}} in any string (instruction, metadata IDs, etc.). Optionally set instruction_template instead of aiBehaviorParams.instruction — the final instruction is interpolated and written before the API call (by the MCP tools, the CLI, and the SDK's CreateAiAgentInput / UpdateAiAgentInput). These keys are stripped during validation.

json
{
  "name": "Classify card",
  "event_id": "card_created",
  "instruction_template": "Read {{field_ref}} and classify the card.",
  "template_params": { "field_ref": "%{field:900000101}" },
  "actionParams": {
    "aiBehaviorParams": {
      "actionsAttributes": [
        {
          "name": "Fill classification",
          "actionType": "update_card",
          "metadata": { "pipeId": "{{pipe}}", "fieldsAttributes": [{ "fieldId": "{{class_field}}", "inputMode": "fill_with_ai", "value": "" }] }
        }
      ]
    }
  },
  "placeholders": { "pipe": "987654321", "class_field": "900000101" }
}

template_params and placeholders merge (placeholders wins on conflict).


Naming differences (UI vs API)

Pipefy UIAPI / Tool field
Description (agent creation step 1)instruction (agent-level)
Instruction / Prompt (per behavior)actionParams.aiBehaviorParams.instruction
Pipe UUIDrepo_uuid (from get_pipe().uuid, NOT the numeric id)

Success criteria

  • Agent enablement matches the intended state: get_ai_agent.disabledAt is null when active; behaviors[].active does not establish agent enablement.
  • validate_ai_agent_behaviors reports no errors before creation.
  • Agent appears in the Pipefy UI under the pipe's AI settings.

Failure modes

  • `update_ai_agent` is full-replace, not patch. Read the agent with get_ai_agent, change what you need, and send the complete behaviors list back. A behavior you leave out is deleted. You can send the read behaviors back as they are; the ids and %{action:…} lines they carry are replaced on save. Update never reactivates a disabled agent; use toggle_ai_agent_status for that.
  • A rejected update is not rolled back. Pipefy applies the name and instruction and removes the current behaviors before it saves the new list. When it then rejects the list (RECORD_NOT_SAVED), the agent is left with no behaviors, or only part of the new list, and stays enabled. Before update_ai_agent, keep the get_ai_agent result and run validate_ai_agent_behaviors, which checks each event_id against get_automation_events — warning you when those events cannot be loaded, so an unverified event_id never reads as a clean pass — and validates the human_validation/mcp_tool action metadata. After a failure, call get_ai_agent to see what is left, fix the payload, and send the full list again.
  • `RECORD_NOT_SAVED` does not name the cause. validate_ai_agent_behaviors now names several of them — an unknown event_id (when the pipe's automation events load), and a human_validation or mcp_tool action with missing metadata — so run it first. The same message still covers payload errors the pre-flight cannot see, so rule those named causes out before you conclude the pipe does not support AI agent behaviors.
  • Partial-failure recovery. If create_ai_agent returns a UUID but reports failure, call update_ai_agent(uuid, repo_uuid, name, instruction, behaviors) — all five are required. Reuse the create repo_uuid; send the full behaviors list. Do NOT create a second agent. Update preserves disabled state; use toggle_ai_agent_status to change enablement.
  • Cross-pipe `PERMISSION_DENIED`. Behaviors with create_connected_card or cross-pipe create_card require the service account to be a member of both source and destination pipes. When it is not, the API returns a bare PERMISSION_DENIED. Recovery: get_pipe_members + invite_members on the destination pipe.
  • Phase transition rule on `move_card`. Destination must be reachable from the source phase (cards_can_be_moved_to_phases). Both validate_ai_agent_behaviors and create_ai_agent / update_ai_agent enrich this error with valid_destinations and a hint that transition rules are editable in the Pipefy UI only.
  • Maximum 5 behaviors per agent. Adding a 6th rejects the whole save.
  • Ghost agents. An agent listed by get_ai_agents may return "Agent not found" on get_ai_agent — a Pipefy backend artifact, persists across sessions, do not retry.
  • GraphQL error hints. When a dedicated read tool returns permission-denied or not-found, the error.message may cite concrete tools (e.g. "Use 'get_ai_agents' to list agents..."). Trust the hint; don't improvise alternative flows.
  • Validation rejections. Common issues: invalid trigger_event, prompt too long, missing required action config. Read the errors field per behavior.

See also

  • pipefy-automations — traditional automations and AI automations (different from AI agents).
  • pipefy-observability — agent execution logs and credit usage.
  • docs/mcp/tools/identifiers.md#ai-agents-and-knowledge-bases — canonical map of which tool/argument expects slug vs internal_id vs uuid vs numeric id (AI agents scope by repo_uuid = pipe UUID).
同じリポジトリから

関連する Skills

すべての Skills
pipefy
コミュニティ

pipefy-api-fallback

Use this skill when a toolkit operation fails AND the introspection skill could not resolve the problem. This is the last-resort fallback (Tier 3): call the Pipefy GraphQL API directly using curl or httpx, authenticating with the Service Account (OAuth2) or a Personal Access Token (PAT) available as env var. Follow the 3-tier resolution strategy before reaching this point.

導入数
2
GitHub Stars
50
更新日
10月16日
pipefy
コミュニティ

pipefy-attachments

Use this skill when the user wants to upload a file to a Pipefy card or table-record attachment field. Covers local and downloaded file sources, plus a presigned-URL handshake for uploading files directly.

導入数
2
GitHub Stars
50
更新日
10月16日
pipefy
コミュニティ

pipefy-automations

Use this skill when the user wants to create, read, update, or delete traditional automations (if/then rules) or AI automations (prompt-driven). For AI agents (conversational), see pipefy-ai-agents.

導入数
2
GitHub Stars
50
更新日
10月16日
pipefy
コミュニティ

pipefy-building

Thin router for Pipefy build and configure asks: map user intent to the correct domain skill (pipes, automations, AI agents, iPaaS, portals, etc.). Use when the user wants to create, build, configure, or integrate something in Pipefy and you need to know which skill to open. Do not use this skill as a delivery playbook — if the user already has a building skill or a detailed build prompt, follow that for how to build; use this skill only for which Pipefy domain skill to read.

導入数
2
GitHub Stars
50
更新日
10月16日