-
Notifications
You must be signed in to change notification settings - Fork 10
Milestones
List view
Eradicate raw-dict-walking and dual-alias `.get()` branches across the toolkit by parsing payloads into typed Pydantic models at the boundary, one type/domain per PR. Continues the approach proven in #416 / PR #417. ## The recipe (per issue) 1. **Wire truth first.** Introspect the live GraphQL schema for the input type being modeled and record its `inputFields` in the issue before writing code. The schema is mixed-case per field (graphql-ruby default camelization with per-field opt-outs): e.g. `AutomationEventParamsInput` declares `to_phase_id` (snake) next to `fromPhaseId` (camel). **Per-declared-field aliases only — never a blanket snake→camel transform.** 2. **Check whether the second spelling ever worked.** GraphQL accepts exactly one wire spelling per field, so a dual-alias branch usually masks input the API always rejected. Normalizing it to the declared name is a fix, not a break — tests pinning the broken passthrough get updated, not preserved. 3. **Model shape:** `populate_by_name=True`, per-field aliases matching declared names, `extra="allow"` so unknown/sibling keys round-trip byte-verbatim (GET responses carry `id`, `referenceId`, explicit nulls). Dump with `by_alias=True, exclude_none=True`; verify with a GET→update clone. 4. **Green baseline → migrate → gate.** Run the suite before touching anything. Gate: `uv run pytest -m "not integration"` + ruff + import-linter + a grep proving no dual-alias branches remain in the migrated domain. 5. **Live E2E on a lab pipe** (create → GET → update-clone → delete, cleanup after). Restart the MCP server first — it runs the working tree via `uv run --project`. ## Footguns (each one bit or nearly bit in #416) - when in doubt, look at the Core codebase as the source of truth - Pydantic keeps **references** to nested input dicts — parse-then-mutate mutates the caller's payload. Deep-copy before parsing when the function must not mutate its input. - Helpers on **error-handler paths** (summarizers, enrichers) must never raise on malformed payloads: use a lenient no-validator model (`BehaviorPayload` pattern) with a scalar fallback, not strict `model_validate`. - **Pinned error messages**: tests `match=` on validator strings — move the validator, keep the message. - **Input side vs response side** are different problems. Input: type against the GraphQL input schema. Response: the shape is set by our own query documents (aliases like `eventId: event_id`) — a dual-read there means two queries disagree; align the queries first, then type the row. - Live smoke needs **valid trigger ids** — check `get_automation_events` (a bogus event id produces an opaque "could not save" from the API). - CI only fires on PRs based on `main`/`dev`; after a base retarget, close+reopen. ## Sanctioned exception The scalar fallback in `_summarize_behaviors` (`b.get("eventId") or b.get("event_id")`) is the documented lenient path for unparseable payloads in an error handler. JWT claim precedence (`resource_server.py`) and error-message fallbacks (`cli/agent.py`) are not casing aliases and stay as-is. ## Live proof of the premise (dev, createAutomation) Same mutation, differing only in one field's casing (via `execute_graphql`): - `action_params.field_map[0].field_id` (snake) → `Field is not defined on FieldMapInput` (rejected at GraphQL coercion, before execution). - `action_params.field_map[0].fieldId` (camel) → passes coercion, fails later on business validation only (nothing created). - `action_params.fieldMap` (camel wrapper) → `Field is not defined on AutomationActionParamsInput`. One input type, mixed casing (`field_map` snake wrapper holding camel `fieldId` entries), exactly one accepted spelling per field. Every dual-alias `.get(a) or .get(b)` branch that survives today is accepting an input the API rejects.
No due date•0/6 issues closedGive the SDK, MCP server, and CLI full coverage for configuring Pipefy AI agents: behavior capabilities, knowledge base sources (plain text, documents, data lookups), and LLM provider selection/management (BYOM). Ordered delivery: (1) behavior params hardening, (2) provider discovery (read), (3) KB list + plain text, (4) KB documents, (5) KB data lookups, (6) provider management (write). One phase in flight at a time; each phase ships SDK + MCP + CLI + docs + skills together.
No due date•8/11 issues closedProblems surfaced while users exercised the MCP against `main`. Issues describe pain and evidence only, solution (tool / skill / docs / API) is decided when picking up the issue. Checked against `dev` where noted; some items may already be partial.
No due date•0/11 issues closedShip the six remaining deferred CLI commands in docs/parity.md (SDK and MCP already exist).
No due date•5/6 issues closedHosted MCP server, stage 5 of 5. Migrate to the spec-aligned two-token model once external dependencies close.
No due date•0/2 issues closedHosted MCP server, stage 4 of 5. Multi-audience interim token and gateway trust, and a real third-party connector OAuth round-trip.
No due date•0/2 issues closedHosted MCP server, stage 3 of 5. Rate limiting and abuse protection, and tool-surface progressive discovery.
No due date•0/2 issues closedHosted MCP server, stage 2 of 5. Default-deny remote tool allowlist, hosted-safe attachment path, and per-user observability.
No due date•2/15 issues closedHosted MCP server, stage 1 of 5. HTTP transport, resource-server wiring, request-scoped identity, and the host allowlist behind a flag: the usable hosted foundation. Plus the early dependency verifications.
No due date•17/19 issues closedDeliver a one-command install path, standardize skill distribution via skills.sh, and ship a `/pipefy-login` slash command for in-host re-authentication. Three workstreams (one issue each): - **A. Curl installer** — `install.sh` wraps `uv tool install` + `npx skills add` + MCP client config registration. - **B. Skills standardization** — drop CLI wheel bundling and `sync_starter_pack.py`; rely on `skills.sh` against the existing `skills/<domain>/<name>/SKILL.md` layout. - **C. `/pipefy-login` slash command** — Claude Code plugin marketplace entry that ships the slash command + registers the MCP server. MCP error hints updated to mention both `/pipefy-login` and the `uvx --from git+https://github.com/gbrlcustodio/pipefy-mcp-server pipefy auth login` fallback. Sequence: C → B → A. Each lands as its own PR against `dev`.
No due date•21/23 issues closedRoadmap for the CLI's interactive user-authentication feature. Started with PR #125 (`pipefy auth login`) and PR #131 (stored session operative across commands). Tracks the canonical follow-ups: hardening, commands (status/logout), alternate flows (device), efficiency, naming, docs.
No due date•24/27 issues closed