Skip to content

vapi: add Customer Phone Number prop to create-call (outbound calls were impossible)#21084

Open
VibhanshuPandey wants to merge 3 commits into
PipedreamHQ:masterfrom
VibhanshuPandey:vapi-create-call-customer-number
Open

vapi: add Customer Phone Number prop to create-call (outbound calls were impossible)#21084
VibhanshuPandey wants to merge 3 commits into
PipedreamHQ:masterfrom
VibhanshuPandey:vapi-create-call-customer-number

Conversation

@VibhanshuPandey
Copy link
Copy Markdown

@VibhanshuPandey VibhanshuPandey commented Jun 6, 2026

WHY

vapi-create-call currently sends only assistantId, squadId, phoneNumberId, name and customerId to POST /call. The Vapi API requires a call destination via customer: { number } (or customerId), but Vapi exposes no customer CRUD endpoints — so customerId is effectively unusable and there is no way to specify who to call. Every outbound phone call made with this action fails with:

400: Couldn't Get Customer. Need Either `customerId` Or `customer`.

(Reproduced today against api.vapi.ai with a valid assistant + phone number and all existing props set.)

Changes

  • create-call: new optional Customer Phone Number prop (E.164, e.g. +14155551234) passed to the API as customer: { number }. Added an early ConfigurationError mirroring the API requirement so users get a clear message instead of the raw 400. Kept optional so any existing configs using customerId are untouched.
  • vapi.app.mjs: phone-number options are now labeled name (number) with fallbacks. Vapi auto-names provisioned numbers (e.g. "Twilio"), so name-only labels made multiple numbers indistinguishable in the dropdown.
  • Version bumps: create-call 0.0.2 → 0.1.0, list-phone-number-id-options 0.0.1 → 0.0.2 (its output labels change), package 0.3.0 → 0.4.0.

Summary by CodeRabbit

  • New Features

    • Create Call action accepts an optional customer phone number (E.164) as an alternative to customer ID.
  • Improvements

    • Phone number dropdowns now show "name (number)" when available for clearer selection.
  • Updates

    • Vapi integration package bumped to 0.4.0.
  • Chores

    • Multiple action and source metadata versions incremented for internal releases.

The create-call action sent only assistantId, squadId, phoneNumberId,
name and customerId to POST /call. The Vapi API requires a destination
via customer: { number } (or customerId), but Vapi has no customer CRUD,
so every outbound phone call failed with:
400: Couldn't Get Customer. Need Either `customerId` Or `customer`.

- create-call: optional Customer Phone Number prop (E.164) sent as
  customer: { number }, plus an early ConfigurationError mirroring the
  API requirement
- vapi.app.mjs: phone number options labeled as "name (number)" so
  auto-named numbers are distinguishable
- version bumps
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 6, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
pipedream-docs-redirect-do-not-edit Ignored Ignored Jun 8, 2026 5:52am

Request Review

@pipedream-component-development
Copy link
Copy Markdown
Collaborator

Thank you so much for submitting this! We've added it to our backlog to review, and our team has been notified.

@pipedream-component-development
Copy link
Copy Markdown
Collaborator

Thanks for submitting this PR! When we review PRs, we follow the Pipedream component guidelines. If you're not familiar, here's a quick checklist:

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 6, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b5e7cb08-b9a1-49c9-bbdd-5b284ec17146

📥 Commits

Reviewing files that changed from the base of the PR and between 056e65d and 222daac.

📒 Files selected for processing (5)
  • components/vapi/actions/list-assistant-id-options/list-assistant-id-options.mjs
  • components/vapi/actions/list-squad-id-options/list-squad-id-options.mjs
  • components/vapi/actions/update-assistant-settings/update-assistant-settings.mjs
  • components/vapi/actions/upload-file/upload-file.mjs
  • components/vapi/sources/new-conversation/new-conversation.mjs

📝 Walkthrough

Walkthrough

Adds optional customerNumber to the Vapi Create Call action (requires customerId or customerNumber), includes customer.number in the startConversation payload when provided, improves phone-number option label formatting, and bumps related action and package versions.

Changes

Vapi Component Enhancements

Layer / File(s) Summary
Create Call action with customer number support
components/vapi/actions/create-call/create-call.mjs
Added optional customerNumber prop (E.164). Updated runtime validation to require either customerId or customerNumber. Modified startConversation payload to set customer to { number: customerNumber } when provided. Version bumped to 0.1.0.
Phone number label formatting in app options
components/vapi/vapi.app.mjs
phoneNumberId options mapping now formats labels as name (number) with fallback name ?? number ?? value.
Action and package version updates
components/vapi/actions/list-phone-number-id-options/list-phone-number-id-options.mjs, components/vapi/package.json, components/vapi/actions/list-assistant-id-options/list-assistant-id-options.mjs, components/vapi/actions/list-squad-id-options/list-squad-id-options.mjs, components/vapi/actions/update-assistant-settings/update-assistant-settings.mjs, components/vapi/actions/upload-file/upload-file.mjs, components/vapi/sources/new-conversation/new-conversation.mjs
Bumped various action version fields and package version from 0.3.00.4.0.

Sequence Diagram(s)

sequenceDiagram
  participant CreateCallRun as CreateCall.run
  participant Validator as run validation
  participant PayloadBuilder as startConversation payload
  participant VapiAPI as Vapi API
  CreateCallRun->>Validator: ensure customerId or customerNumber
  Validator-->>CreateCallRun: validated
  CreateCallRun->>PayloadBuilder: construct payload (customerId, customer?: { number })
  PayloadBuilder->>VapiAPI: POST /startConversation
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Suggested labels

HIGH PRIORITY

Suggested reviewers

  • GTFalcao
  • mariano-pd
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and specifically describes the main change: adding a Customer Phone Number prop to the create-call action to fix the critical issue that made outbound calls impossible.
Description check ✅ Passed The PR description provides a comprehensive explanation of the problem, all changes made, and version updates. It includes a clear 'WHY' section and 'Changes' section covering all modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/vapi/actions/create-call/create-call.mjs`:
- Around line 49-54: The description for the customerNumber prop uses bolded
**Customer ID**, which could be mistaken for a tool name; update the text in the
customerNumber property (the label "Customer Phone Number" / property key
customerNumber) to reference the other prop plainly (e.g., "Customer ID" without
bolding or by using the exact prop name customerId) and reword the sentence to
say "The API requires either this or the customerId property for outbound phone
calls" so it's unambiguous to agents.

In `@components/vapi/vapi.app.mjs`:
- Around line 54-61: phoneNumberId.async options() currently fetches only a
single page (limit: LIMIT) and ignores prevContext/page, causing truncated
dropdowns; update this function to use the existing async *paginate() helper (or
replicate its logic) so it consumes prevContext and params.page and iteratively
requests GET /phone-number using the response pagination metadata
(meta.current_page / meta.last_page or currentPage) to load additional pages,
accumulating or yielding mapped option objects (preserving the label/value
mapping) until all pages are fetched, and return the combined context for next
calls; ensure prevContext/page are passed through and that paginate()'s
cursor/state is returned so load-more works.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 42d122ef-2432-4144-8a41-e0eb2befcda7

📥 Commits

Reviewing files that changed from the base of the PR and between a773cd3 and c00814f.

📒 Files selected for processing (4)
  • components/vapi/actions/create-call/create-call.mjs
  • components/vapi/actions/list-phone-number-id-options/list-phone-number-id-options.mjs
  • components/vapi/package.json
  • components/vapi/vapi.app.mjs

Comment thread components/vapi/actions/create-call/create-call.mjs
Comment on lines 54 to 61
return phoneNumbers.map(({
id: value, name: label,
id: value, name, number,
}) => ({
label,
label: (name && number)
? `${name} (${number})`
: (name ?? number ?? value),
value,
}));
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Jun 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check if other propDefinitions in this app use pagination

# Search for propDefinitions that use the paginate helper
rg -n -A10 'async options\(' components/vapi/vapi.app.mjs | rg -C3 'paginate'

Repository: PipedreamHQ/pipedream

Length of output: 47


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="components/vapi/vapi.app.mjs"

echo "=== phoneNumberId propDefinition area (approx lines 1-120) ==="
nl -ba "$FILE" | sed -n '1,140p'

echo
echo "=== Look for prevContext/page usage in vapi.app.mjs ==="
rg -n --hidden --no-ignore-vcs -S "prevContext|\\bpage\\b" "$FILE" || true

echo
echo "=== Find paginate helper definition / usage in vapi.app.mjs ==="
rg -n "paginate" "$FILE" || true

echo
echo "=== Find phone-number API calls & pagination-related params ==="
rg -n -S "phone[-_ ]?number|phoneNumber|/phone-number" "$FILE" || true
rg -n -S "limit|offset|starting_after|startingAfter|cursor|page|has_more|next_" "$FILE" || true

Repository: PipedreamHQ/pipedream

Length of output: 189


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="components/vapi/vapi.app.mjs"

echo "=== phoneNumberId propDefinition area (start of file through ~140) ==="
cat -n "$FILE" | sed -n '1,140p'

echo
echo "=== Look for prevContext/page usage in vapi.app.mjs ==="
rg -n --hidden --no-ignore-vcs -S "prevContext|\\bpage\\b" "$FILE" || true

echo
echo "=== Find paginate helper definition / usage in vapi.app.mjs ==="
rg -n "paginate" "$FILE" || true

echo
echo "=== Find phone-number API calls & pagination-related params ==="
rg -n -S "phone[-_ ]?number|phoneNumber|/phone-number" "$FILE" || true
rg -n -S "limit|offset|starting_after|startingAfter|cursor|page|has_more|next_" "$FILE" || true

Repository: PipedreamHQ/pipedream

Length of output: 5033


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="components/vapi/vapi.app.mjs"

echo "=== paginate() implementation (approx lines 120-220) ==="
cat -n "$FILE" | sed -n '120,220p'

echo
echo "=== Find uses of paginate() within vapi components ==="
rg -n "this\\.paginate\\(|\\.paginate\\(" components/vapi -S || true

echo
echo "=== Find any async options() in vapi components that use prevContext/page ==="
rg -n --glob='components/vapi/**/*.{mjs,js,ts}' "async options\\(\\)|prevContext|\\bpage\\b" -S || true

echo
echo "=== Find other uses of listPhoneNumbers in vapi components ==="
rg -n --glob='components/vapi/**/*.{mjs,js,ts}' "listPhoneNumbers\\(" -S || true

Repository: PipedreamHQ/pipedream

Length of output: 1890


🌐 Web query:

Vapi API GET /phone-number pagination params current_page last_page page limit

💡 Result:

Vapi API GET /phone-number pagination params (list phone numbers) 1) Query parameters - limit: maximum number of items to return (defaults to 100) [1] 2) Pagination fields returned in response.metadata - currentPage: current page number (from PaginationMeta) [2][3] 3) Your requested params - current_page: not used as a request query param name; the request uses limit, and the response metadata uses currentPage [1][2] - last_page: not documented as a request query parameter or returned pagination field for phone numbers; only currentPage (plus itemsPerPage and totalItems) is shown in PaginationMeta [2] - page: not shown as a query parameter for the phone-number list endpoint in the official docs; the endpoint documents limit (and filtering fields), not page-based params [1] If you want, paste an example of the response JSON you’re getting for list phone numbers and I can map exactly which pagination fields are present in your case.

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Search repo for vapi phone-number usage ==="
rg -n --glob='components/**/*.{mjs,js,ts}' -S "path: \"/phone-number\"|/phone-number" components/vapi components -S || true

echo
echo "=== Search for current_page/last_page/meta usage in vapi app/components ==="
rg -n --glob='components/vapi/**/*.{mjs,js,ts}' -S "current_page|last_page|meta: \\{|next|has_more" || true

echo
echo "=== Search for phoneNumberId propDefinition usage ==="
rg -n --glob='components/vapi/**/*.{mjs,js,ts}' -S "phoneNumberId" || true

Repository: PipedreamHQ/pipedream

Length of output: 2467


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n --glob='components/vapi/**/*.{mjs,js,ts}' "phoneNumberId\\.options" components/vapi || true

echo "=== Inspect components/vapi/actions/list-phone-number-id-options/list-phone-number-id-options.mjs ==="
FILE="components/vapi/actions/list-phone-number-id-options/list-phone-number-id-options.mjs"
cat -n "$FILE" | sed -n '1,200p'

Repository: PipedreamHQ/pipedream

Length of output: 1149


Add load-more pagination support to phoneNumberId options()
components/vapi/vapi.app.mjs’s phoneNumberId.async options() fetches only limit: LIMIT and doesn’t accept/use prevContext or page. The app already has an async *paginate() helper (using params.page and meta.current_page/last_page), but it isn’t used here; meanwhile GET /phone-number returns pagination metadata (e.g., currentPage), so this dropdown may silently truncate results. Wire prevContext/page into phoneNumberId.options() (likely via paginate()), or explicitly justify why pagination can’t be requested for this endpoint. See the documentation

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/vapi/vapi.app.mjs` around lines 54 - 61, phoneNumberId.async
options() currently fetches only a single page (limit: LIMIT) and ignores
prevContext/page, causing truncated dropdowns; update this function to use the
existing async *paginate() helper (or replicate its logic) so it consumes
prevContext and params.page and iteratively requests GET /phone-number using the
response pagination metadata (meta.current_page / meta.last_page or currentPage)
to load additional pages, accumulating or yielding mapped option objects
(preserving the label/value mapping) until all pages are fetched, and return the
combined context for next calls; ensure prevContext/page are passed through and
that paginate()'s cursor/state is returned so load-more works.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping this one - three reasons:

  1. GET /phone-number returns a plain array, not the { data, meta: { current_page, last_page } } shape the existing paginate() helper consumes, so it can't be reused for this endpoint (Vapi uses createdAtLt cursor pagination on these list endpoints).
  2. The single-page fetch is pre-existing behavior shared identically by the assistantId and squadId propDefinitions, which this PR doesn't touch - the diff only changes the label mapping.
  3. LIMIT is already 1000, the documented per-request maximum, so truncation only occurs for accounts with 1000+ phone numbers.

Happy to address pagination across all three propDefinitions in a separate PR if maintainers want it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@VibhanshuPandey, all three points are well-reasoned — thanks for the detailed explanation. The mismatch between the plain-array response shape and the paginate() helper's expected { data, meta: { current_page, last_page } } structure is the key blocker, and since LIMIT is already at the API's documented maximum of 1000, the practical impact is minimal. Deferring a proper cursor-based pagination refactor across all three propDefinitions to a follow-up PR makes sense.

Would you like me to open a GitHub issue to track that follow-up work (pagination for phoneNumberId, assistantId, and squadId propDefinitions using createdAtLt cursor pagination)?

🐇 ( ˘ᵕ˘) noted and filed away


✏️ Learnings added
Learnt from: VibhanshuPandey
Repo: PipedreamHQ/pipedream PR: 21084
File: components/vapi/vapi.app.mjs:54-61
Timestamp: 2026-06-06T09:48:46.537Z
Learning: In `components/vapi/vapi.app.mjs`, the Vapi `GET /phone-number`, `GET /assistant`, and `GET /squad` list endpoints all return plain arrays, NOT the `{ data, meta: { current_page, last_page } }` shape that the existing `async *paginate()` helper in the same file consumes. Vapi uses `createdAtLt` cursor pagination on these list endpoints. Therefore, the existing `paginate()` helper CANNOT be used for `phoneNumberId`, `assistantId`, or `squadId` propDefinition `async options()`. The `LIMIT` constant is 1000, the documented per-request maximum for these endpoints, so truncation only affects accounts with more than 1000 records. Do not flag the absence of `prevContext`/`page` pagination in these three propDefinitions as a blocker until a proper cursor-based pagination implementation is available.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: CR
Repo: PipedreamHQ/pipedream PR: 0
File: .github/pipedream-component-guidelines.md:0-0
Timestamp: 2026-04-29T00:52:39.465Z
Learning: Applies to components/*/*.app.mjs : Prop definitions in app files must include both `label` and `description`. If a definition includes `async options()` that calls a paginated API endpoint, it must support `prevContext` or `page`.

Learnt from: CR
Repo: PipedreamHQ/pipedream PR: 0
File: .github/pipedream-component-guidelines.md:0-0
Timestamp: 2026-04-29T00:52:39.465Z
Learning: Applies to components/**/*.mjs : Prop descriptions must describe the expected format for non-obvious values (dates, IDs, JSON structures, enum strings), include concrete examples for JSON objects or constructed values, explain where to get IDs if the user might only have a name or URL, avoid UI language like "select from the dropdown", and point to discovery tools when valid values must be looked up

Learnt from: CR
Repo: PipedreamHQ/pipedream PR: 0
File: .github/pipedream-component-guidelines.md:0-0
Timestamp: 2026-04-29T00:52:39.465Z
Learning: Applies to components/**/*.mjs : Every prop definition with `async options()` that calls a paginated API endpoint must support `prevContext` or `page` (starts at 0) for "load more" functionality

Learnt from: s0s0physm
Repo: PipedreamHQ/pipedream PR: 0
File: :0-0
Timestamp: 2026-04-29T23:16:37.561Z
Learning: In the Stripe list actions (e.g., `components/stripe/actions/list-customers/list-customers.mjs`, `list-invoices`, `list-payouts`, `list-balance-history`, `list-refunds`, `list-payment-intents`), pagination metadata (`has_more`, `next_starting_after`) is exposed via an opt-in boolean prop `returnPaginationInfo` (default `false`). When `false`, actions return `Array<T>` exactly as before (no breaking change). When `true`, actions fetch `limit + 1` items, trim to `limit`, derive `has_more`, and return `{ data, has_more, next_starting_after }`. This opt-in design makes the version bump `0.1.4` → `0.2.0` (MINOR, not MAJOR) correct per Pipedream semver guidelines. Do not flag this as a breaking change or suggest a major version bump.

Learnt from: michelle0927
Repo: PipedreamHQ/pipedream PR: 20911
File: components/freshchat/actions/list-agent-id-options/list-agent-id-options.mjs:16-22
Timestamp: 2026-05-18T18:55:29.937Z
Learning: In PipedreamHQ/pipedream, for list-options utility action components under `components/<app>/actions/list-*-options/`, the `page` integer prop does NOT require a `max` constraint. Only a `min: 0` and `default: 0` are needed. Do not flag the absence of a `max` value on page pagination props in these components.

Learnt from: CR
Repo: PipedreamHQ/pipedream PR: 0
File: .github/pipedream-source-guidelines.md:0-0
Timestamp: 2026-04-13T20:20:15.870Z
Learning: Applies to **/*source*.{js,ts} : Paginate through all new items when the API supports pagination — do not stop after the first page

Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 14137
File: components/tricentis_qtest/tricentis_qtest.app.mjs:39-54
Timestamp: 2024-10-08T15:33:38.240Z
Learning: The Tricentis qTest API endpoint used for fetching requirements does not support pagination, so pagination is unnecessary in the `options` method for `requirementId`.

Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 14137
File: components/tricentis_qtest/tricentis_qtest.app.mjs:39-54
Timestamp: 2024-09-29T22:37:26.269Z
Learning: The Tricentis qTest API endpoint used for fetching requirements does not support pagination, so pagination is unnecessary in the `options` method for `requirementId`.

Learnt from: michelle0927
Repo: PipedreamHQ/pipedream PR: 20865
File: components/envoy/actions/list-employee-id-options/list-employee-id-options.mjs:17-23
Timestamp: 2026-05-14T19:04:45.522Z
Learning: In PipedreamHQ/pipedream, for lightweight "list prop options" utility action components (actions under `components/<app>/actions/list-*-options/` whose sole purpose is to retrieve and return available options for a prop field), it is NOT necessary to pass the `$` context into `propDefinitions.options.call(this.<app>)` calls or the underlying API methods they invoke (e.g., `listEmployeesOps()`). The `$` context requirement is waived for these read-only utility actions since they are simple option-retrieval helpers.

Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 20678
File: components/moodle/actions/search-users/search-users.mjs:16-40
Timestamp: 2026-04-28T18:14:58.414Z
Learning: For Pipedream component files under components/**/*.mjs: the "[See the documentation](...)" link is required only in the top-level component `description` field. For any individual prop `description` fields, write the description specifically for AI agent consumption—include concrete inline examples. Prop `description` fields do not need to end with a documentation link.

Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 20832
File: components/getty_images/common/constants.mjs:1-74
Timestamp: 2026-05-11T22:13:55.006Z
Learning: In Pipedream component files under `components/**/*.mjs`, follow this naming convention: use `UPPER_SNAKE_CASE` for module-level constants (e.g., option arrays like `IMAGE_TYPE_OPTIONS`, `ORIENTATION_OPTIONS`). For all other identifiers, use `camelCase`—specifically local variables inside functions/methods, prop names, and method names. `UPPER_SNAKE_CASE` at module scope for constants is an accepted convention in this codebase and should not be flagged.

Learnt from: michelle0927
Repo: PipedreamHQ/pipedream PR: 20853
File: components/surecart/actions/create-checkout/create-checkout.mjs:7-7
Timestamp: 2026-05-13T17:22:52.552Z
Learning: When reviewing a connector “fix/republish” PR in PipedreamHQ/pipedream, a breaking input-contract change in the republished connector/component should NOT automatically trigger a major version bump if the previous connector/component version was never successfully published (e.g., the publish pipeline failed with a UserError). In that case, a patch bump is acceptable (e.g., 0.0.1 → 0.0.2) because no users could have relied on the unpublished interface. Before flagging an incorrect bump level, verify the prior version’s unpublished status using the PR description and/or linked issue(s).

Learnt from: michelle0927
Repo: PipedreamHQ/pipedream PR: 20884
File: components/jira_data_center/actions/list-filter-id-options/list-filter-id-options.mjs:1-1
Timestamp: 2026-05-15T16:31:34.394Z
Learning: When reviewing Pipedream component files, do not require the imported app module identifier (the local import variable) to be snake_case. Both snake_case and camelCase local import variable names are acceptable (e.g., `import jiraDataCenter from "../../jira_data_center.app.mjs"` is fine even if the app filename uses `jira_data_center`). However, ensure the key(s) used in the component’s `props` object match exactly what the referenced app module exports; mismatches between the app’s exported prop name(s) and the component `props` keys should be flagged. The local import variable name itself is flexible as long as `props` keys align with the app exports.

Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 20884
File: components/youtube_data_api/actions/list-language-options/list-language-options.mjs:1-1
Timestamp: 2026-05-15T19:23:37.145Z
Learning: For Pipedream component files under `components/**/*.mjs`, follow `pipedream-component-guidelines.md`: require camelCase for all prop names, method names, and local variables (including import identifiers used as local variables). Do not flag camelCase import identifiers (e.g., `import youtubeDataApi from "..."` with `props: { youtubeDataApi }`) for being “snake_case to match the app key.” The only exception is API request parameter names: keep their casing as required by the upstream API spec.

Learnt from: michelle0927
Repo: PipedreamHQ/pipedream PR: 20908
File: components/clockwork_recruiting/actions/list-tag-ids-options/list-tag-ids-options.mjs:1-1
Timestamp: 2026-05-18T18:42:14.701Z
Learning: In Pipedream component files, the general camelCase naming rule should NOT be applied to (1) API request parameter names and (2) the snake_case app import identifier (the local variable name used for the app import) and its corresponding prop key. When reviewing `components/**/*.mjs`, do not flag `snake_case` for those exempt app identifiers/prop keys (e.g., `clockwork_recruiting`), but continue to require camelCase for all other local variables, prop names (other than the exempt app prop key), and method names.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai Yes, please open the issue to track the pagination follow-up.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
gh issue create \
  --repo PipedreamHQ/pipedream \
  --title "vapi: add cursor-based pagination to phoneNumberId, assistantId, and squadId propDefinitions" \
  --body "## Summary

The \`phoneNumberId\`, \`assistantId\`, and \`squadId\` propDefinitions in \`components/vapi/vapi.app.mjs\` currently fetch only a single page of results using \`limit: LIMIT\` (1000 records — the documented per-request maximum). Truncation is therefore only an issue for accounts with more than 1000 records per resource type, but the \`async options()\` functions should ideally support load-more pagination.

## Background

Raised during review of `#21084` (comment: https://github.com/PipedreamHQ/pipedream/pull/21084#discussion_r3367045633).

The existing \`async *paginate()\` helper in \`vapi.app.mjs\` consumes a \`{ data, meta: { current_page, last_page } }\` response shape, but the Vapi \`GET /phone-number\`, \`GET /assistant\`, and \`GET /squad\` list endpoints return **plain arrays**, not that shape. Vapi uses \`createdAtLt\` cursor pagination on these endpoints.

## Work needed

- Implement cursor-based (\`createdAtLt\`) pagination for the three propDefinitions:
  - \`phoneNumberId\`\`GET /phone-number\`
  - \`assistantId\`\`GET /assistant\`
  - \`squadId\`\`GET /squad\`
- Either add a new \`paginateCursor()\` helper to the app file, or replicate the cursor logic inline in each \`async options()\`.
- Wire up \`prevContext\` to pass the cursor between load-more calls.
- Bump the app package version accordingly.

## References

- PR where this was deferred: `#21084`
- Vapi phone-number list docs: https://docs.vapi.ai/api-reference/phone-numbers/list

/cc `@VibhanshuPandey`" \
  --assignee VibhanshuPandey

Length of output: 2047


🏁 Script executed:

#!/bin/bash
gh issue create \
  --repo PipedreamHQ/pipedream \
  --title "vapi: add cursor-based pagination to phoneNumberId, assistantId, and squadId propDefinitions" \
  --body "## Summary

The \`phoneNumberId\`, \`assistantId\`, and \`squadId\` propDefinitions in \`components/vapi/vapi.app.mjs\` currently fetch only a single page of results using \`limit: LIMIT\` (1000 records — the documented per-request maximum). Truncation is therefore only an issue for accounts with more than 1000 records per resource type, but the \`async options()\` functions should ideally support load-more pagination.

## Background

Raised during review of `#21084` (comment: https://github.com/PipedreamHQ/pipedream/pull/21084#discussion_r3367045633).

The existing \`async *paginate()\` helper in \`vapi.app.mjs\` consumes a \`{ data, meta: { current_page, last_page } }\` response shape, but the Vapi \`GET /phone-number\`, \`GET /assistant\`, and \`GET /squad\` list endpoints return **plain arrays**, not that shape. Vapi uses \`createdAtLt\` cursor pagination on these endpoints.

## Work needed

- Implement cursor-based (\`createdAtLt\`) pagination for the three propDefinitions:
  - \`phoneNumberId\`\`GET /phone-number\`
  - \`assistantId\`\`GET /assistant\`
  - \`squadId\`\`GET /squad\`
- Either add a new \`paginateCursor()\` helper to the app file, or replicate the cursor logic inline in each \`async options()\`.
- Wire up \`prevContext\` to pass the cursor between load-more calls.
- Bump the app package version accordingly.

## References

- PR where this was deferred: `#21084`
- Vapi phone-number list docs: https://docs.vapi.ai/api-reference/phone-numbers/list

/cc `@VibhanshuPandey`"

Length of output: 1795



@VibhanshuPandey, the follow-up issue has been created: #21086

It tracks implementing createdAtLt cursor-based pagination across all three propDefinitions (phoneNumberId, assistantId, squadId) in components/vapi/vapi.app.mjs.

🐇 ᓚᘏᗢ filed and ready for the next sprint


🧠 Learnings used
Learnt from: VibhanshuPandey
Repo: PipedreamHQ/pipedream PR: 21084
File: components/vapi/vapi.app.mjs:54-61
Timestamp: 2026-06-06T09:48:46.537Z
Learning: In `components/vapi/vapi.app.mjs`, the Vapi `GET /phone-number`, `GET /assistant`, and `GET /squad` list endpoints all return plain arrays, NOT the `{ data, meta: { current_page, last_page } }` shape that the existing `async *paginate()` helper in the same file consumes. Vapi uses `createdAtLt` cursor pagination on these list endpoints. Therefore, the existing `paginate()` helper CANNOT be used for `phoneNumberId`, `assistantId`, or `squadId` propDefinition `async options()`. The `LIMIT` constant is 1000, the documented per-request maximum for these endpoints, so truncation only affects accounts with more than 1000 records. Do not flag the absence of `prevContext`/`page` pagination in these three propDefinitions as a blocker until a proper cursor-based pagination implementation is available.

Learnt from: CR
Repo: PipedreamHQ/pipedream PR: 0
File: .github/pipedream-component-guidelines.md:0-0
Timestamp: 2026-04-29T00:52:39.465Z
Learning: Applies to components/*/*.app.mjs : Prop definitions in app files must include both `label` and `description`. If a definition includes `async options()` that calls a paginated API endpoint, it must support `prevContext` or `page`.

Learnt from: CR
Repo: PipedreamHQ/pipedream PR: 0
File: .github/pipedream-component-guidelines.md:0-0
Timestamp: 2026-04-29T00:52:39.465Z
Learning: Applies to components/**/*.mjs : Prop descriptions must describe the expected format for non-obvious values (dates, IDs, JSON structures, enum strings), include concrete examples for JSON objects or constructed values, explain where to get IDs if the user might only have a name or URL, avoid UI language like "select from the dropdown", and point to discovery tools when valid values must be looked up

Learnt from: s0s0physm
Repo: PipedreamHQ/pipedream PR: 0
File: :0-0
Timestamp: 2026-04-29T23:16:37.561Z
Learning: In the Stripe list actions (e.g., `components/stripe/actions/list-customers/list-customers.mjs`, `list-invoices`, `list-payouts`, `list-balance-history`, `list-refunds`, `list-payment-intents`), pagination metadata (`has_more`, `next_starting_after`) is exposed via an opt-in boolean prop `returnPaginationInfo` (default `false`). When `false`, actions return `Array<T>` exactly as before (no breaking change). When `true`, actions fetch `limit + 1` items, trim to `limit`, derive `has_more`, and return `{ data, has_more, next_starting_after }`. This opt-in design makes the version bump `0.1.4` → `0.2.0` (MINOR, not MAJOR) correct per Pipedream semver guidelines. Do not flag this as a breaking change or suggest a major version bump.

Learnt from: CR
Repo: PipedreamHQ/pipedream PR: 0
File: .github/pipedream-component-guidelines.md:0-0
Timestamp: 2026-04-29T00:52:39.465Z
Learning: Applies to components/**/*.mjs : Every prop definition with `async options()` that calls a paginated API endpoint must support `prevContext` or `page` (starts at 0) for "load more" functionality

Learnt from: michelle0927
Repo: PipedreamHQ/pipedream PR: 20911
File: components/freshchat/actions/list-agent-id-options/list-agent-id-options.mjs:16-22
Timestamp: 2026-05-18T18:55:29.937Z
Learning: In PipedreamHQ/pipedream, for list-options utility action components under `components/<app>/actions/list-*-options/`, the `page` integer prop does NOT require a `max` constraint. Only a `min: 0` and `default: 0` are needed. Do not flag the absence of a `max` value on page pagination props in these components.

Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 20990
File: components/ashby/actions/get-file-url/get-file-url.mjs:19-19
Timestamp: 2026-05-27T08:44:16.428Z
Learning: In the PipedreamHQ/pipedream Ashby integration (and likely other connectors), when a prop value is a pass-through from another API response (e.g., `fileHandle` in `components/ashby/actions/get-file-url/get-file-url.mjs`), do NOT require or suggest adding a concrete inline example for that prop's description. Since the format is opaque and controlled entirely by the upstream API, hardcoding an example risks becoming stale. Instead, the description should cross-reference the source action (e.g., **Get Candidate**) where the value can be obtained. Do not flag the absence of a concrete example for pass-through / API-derived identifiers.

Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 20783
File: components/monday/actions/common/common-create-item.mjs:18-18
Timestamp: 2026-05-04T22:10:40.584Z
Learning: In Pipedream component files (components/**/*.mjs) for the monday.com integration: when a prop uses `propDefinition` that provides async options (e.g., the `columns`/`column` prop in `components/monday/actions/common/common-create-item.mjs`), concrete inline format examples in the `description` field are not required because the agent/user selects from the returned option list rather than constructing values manually. Do not flag the absence of inline examples for such props.

Learnt from: CR
Repo: PipedreamHQ/pipedream PR: 0
File: .github/pipedream-source-guidelines.md:0-0
Timestamp: 2026-04-13T20:20:15.870Z
Learning: Applies to **/*source*.{js,ts} : Paginate through all new items when the API supports pagination — do not stop after the first page

Learnt from: michelle0927
Repo: PipedreamHQ/pipedream PR: 20865
File: components/envoy/actions/list-employee-id-options/list-employee-id-options.mjs:17-23
Timestamp: 2026-05-14T19:04:45.522Z
Learning: In PipedreamHQ/pipedream, for lightweight "list prop options" utility action components (actions under `components/<app>/actions/list-*-options/` whose sole purpose is to retrieve and return available options for a prop field), it is NOT necessary to pass the `$` context into `propDefinitions.options.call(this.<app>)` calls or the underlying API methods they invoke (e.g., `listEmployeesOps()`). The `$` context requirement is waived for these read-only utility actions since they are simple option-retrieval helpers.

Learnt from: ashwins01
Repo: PipedreamHQ/pipedream PR: 21031
File: components/hubspot/sources/new-engagement/new-engagement.mjs:33-39
Timestamp: 2026-06-02T13:28:47.253Z
Learning: In the PipedreamHQ/pipedream repo, for HubSpot "New Engagement" source (`components/hubspot/sources/new-engagement/new-engagement.mjs`), the component description intentionally lists multiple per-activity HubSpot documentation links (Calls, Emails, Meetings, Notes, Postal Mail, Tasks) instead of a single consolidated "See the documentation" link. This is by design because each engagement type has its own separate v3 API endpoint and docs page. When reviewing this specific source, do not flag the multiple inline links as a violation of the single-docs-link convention unless the final link is also missing the required `[See the documentation](...)` closing link.

Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 20678
File: components/moodle/actions/search-users/search-users.mjs:16-40
Timestamp: 2026-04-28T18:14:58.414Z
Learning: For Pipedream component files under components/**/*.mjs: the "[See the documentation](...)" link is required only in the top-level component `description` field. For any individual prop `description` fields, write the description specifically for AI agent consumption—include concrete inline examples. Prop `description` fields do not need to end with a documentation link.

Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 20832
File: components/getty_images/common/constants.mjs:1-74
Timestamp: 2026-05-11T22:13:55.006Z
Learning: In Pipedream component files under `components/**/*.mjs`, follow this naming convention: use `UPPER_SNAKE_CASE` for module-level constants (e.g., option arrays like `IMAGE_TYPE_OPTIONS`, `ORIENTATION_OPTIONS`). For all other identifiers, use `camelCase`—specifically local variables inside functions/methods, prop names, and method names. `UPPER_SNAKE_CASE` at module scope for constants is an accepted convention in this codebase and should not be flagged.

Learnt from: michelle0927
Repo: PipedreamHQ/pipedream PR: 20853
File: components/surecart/actions/create-checkout/create-checkout.mjs:7-7
Timestamp: 2026-05-13T17:22:52.552Z
Learning: When reviewing a connector “fix/republish” PR in PipedreamHQ/pipedream, a breaking input-contract change in the republished connector/component should NOT automatically trigger a major version bump if the previous connector/component version was never successfully published (e.g., the publish pipeline failed with a UserError). In that case, a patch bump is acceptable (e.g., 0.0.1 → 0.0.2) because no users could have relied on the unpublished interface. Before flagging an incorrect bump level, verify the prior version’s unpublished status using the PR description and/or linked issue(s).

Learnt from: michelle0927
Repo: PipedreamHQ/pipedream PR: 20884
File: components/jira_data_center/actions/list-filter-id-options/list-filter-id-options.mjs:1-1
Timestamp: 2026-05-15T16:31:34.394Z
Learning: When reviewing Pipedream component files, do not require the imported app module identifier (the local import variable) to be snake_case. Both snake_case and camelCase local import variable names are acceptable (e.g., `import jiraDataCenter from "../../jira_data_center.app.mjs"` is fine even if the app filename uses `jira_data_center`). However, ensure the key(s) used in the component’s `props` object match exactly what the referenced app module exports; mismatches between the app’s exported prop name(s) and the component `props` keys should be flagged. The local import variable name itself is flexible as long as `props` keys align with the app exports.

Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 20884
File: components/youtube_data_api/actions/list-language-options/list-language-options.mjs:1-1
Timestamp: 2026-05-15T19:23:37.145Z
Learning: For Pipedream component files under `components/**/*.mjs`, follow `pipedream-component-guidelines.md`: require camelCase for all prop names, method names, and local variables (including import identifiers used as local variables). Do not flag camelCase import identifiers (e.g., `import youtubeDataApi from "..."` with `props: { youtubeDataApi }`) for being “snake_case to match the app key.” The only exception is API request parameter names: keep their casing as required by the upstream API spec.

Learnt from: michelle0927
Repo: PipedreamHQ/pipedream PR: 20908
File: components/clockwork_recruiting/actions/list-tag-ids-options/list-tag-ids-options.mjs:1-1
Timestamp: 2026-05-18T18:42:14.701Z
Learning: In Pipedream component files, the general camelCase naming rule should NOT be applied to (1) API request parameter names and (2) the snake_case app import identifier (the local variable name used for the app import) and its corresponding prop key. When reviewing `components/**/*.mjs`, do not flag `snake_case` for those exempt app identifiers/prop keys (e.g., `clockwork_recruiting`), but continue to require camelCase for all other local variables, prop names (other than the exempt app prop key), and method names.

The create-call PR modifies vapi.app.mjs, so every component importing
the app must have its version bumped per the "Ensure component commits
modify component versions" CI check. Bumps list-assistant-id-options,
list-squad-id-options, update-assistant-settings, upload-file, and the
new-conversation source.
@VibhanshuPandey
Copy link
Copy Markdown
Author

Pushed 222daac1 to bump the 5 dependent component versions flagged by the "Ensure component commits modify component versions" check (these components transitively import vapi.app.mjs, which this PR modifies):

  • list-assistant-id-options 0.0.1 → 0.0.2
  • list-squad-id-options 0.0.1 → 0.0.2
  • update-assistant-settings 0.0.2 → 0.0.3
  • upload-file 0.0.5 → 0.0.6
  • sources/new-conversation 0.0.1 → 0.0.2

Could a maintainer re-approve the CI run so the version check can go green? Ready for re-review. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

User submitted Submitted by a user

Projects

Status: Ready for PR Review

Development

Successfully merging this pull request may close these issues.

4 participants