Skip to content

Conversation

@jcortes
Copy link
Collaborator

@jcortes jcortes commented Oct 27, 2025

WHY

Resolves #18854

Summary by CodeRabbit

  • New Features

    • Added Answer Question action for LLM-powered, citation-informed answers
    • Added Find Similar Links action to locate and retrieve similar web pages
    • Added Get Contents action to fetch full page contents, summaries, and metadata with optional live crawling
    • Added Search action with comprehensive filtering and date/domain controls
  • Chores

    • Expanded app configuration options (additional input fields) and bumped package version to 0.1.0

@jcortes jcortes self-assigned this Oct 27, 2025
@vercel
Copy link

vercel bot commented Oct 27, 2025

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

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
pipedream-docs Ignored Ignored Oct 30, 2025 11:25pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Oct 30, 2025 11:25pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 27, 2025

Walkthrough

Adds four Exa action modules (search, get-contents, find-similar-links, answer-question), expands the Exa app with request helpers and action methods, validates optional JSON schema inputs, and bumps package version while adding a platform dependency.

Changes

Cohort / File(s) Summary
New Exa Actions
components/exa/actions/answer-question/answer-question.mjs, components/exa/actions/find-similar-links/find-similar-links.mjs, components/exa/actions/get-contents/get-contents.mjs, components/exa/actions/search/search.mjs
Adds four action modules. Each exports a default action descriptor (key, name, description, version, type, annotations), prop mappings to the app, and an async run that builds a payload and calls the corresponding app method. get-contents and find-similar-links include optional JSON schema parsing/validation and conditional payload assembly.
App Implementation & Props
components/exa/exa.app.mjs
Expands propDefinitions to many input fields (query, url(s), filters, content options, highlights, summarySchema, livecrawl, extras, etc.). Replaces prior authKeys approach with request helpers: getUrl(path), _headers(), _makeRequest(), post(), and adds action methods search(), getContents(), findSimilar(), answer().
Package Update
components/exa/package.json
Bumps version from 0.0.10.1.0 and adds a dependencies entry for @pipedream/platform ^3.1.0.

Sequence Diagram(s)

sequenceDiagram
  participant Action as Action (search/get-contents/find-similar/answer)
  participant App as exa.app
  participant HTTP as HTTP API

  note right of Action #D6EAF8: action.run({ $ })\nbuilds payload from props
  Action->>App: call app.<operation>({ $, data: payload })
  note left of App #FDEBD0: app.<operation> -> post()
  App->>App: _makeRequest({ $, path, data })
  App->>HTTP: HTTP POST to getUrl(path) with _headers()
  HTTP-->>App: response
  App-->>Action: return API response
  Action->>Action: $.export("$summary", ...)
  Action-->>Caller: returns response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

  • Pay attention to payload construction and conditional merging logic in:
    • components/exa/actions/get-contents/get-contents.mjs
    • components/exa/actions/find-similar-links/find-similar-links.mjs
  • Validate JSON parsing and error handling (ConfigurationError) for summarySchema.
  • Verify propDefinitions in components/exa/exa.app.mjs align with the API and action prop usages.
  • Confirm _makeRequest/post header handling uses this.$auth.api_key securely.

Poem

🐰 A rabbit hops, the code takes flight,
Four actions added, working through the night.
Payloads stitched and schemas checked with care,
Exa answers, finds, and fetches everywhere.
Small hops, big leaps — the rabbit’s glad to share.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title "[Components] Exa - new components" is concise and directly related to the main change in the pull request. It clearly indicates that the PR is adding new components for the Exa service, which is exactly what the changeset contains—four new action modules (search, find-similar-links, get-contents, answer-question) along with supporting infrastructure. While the title doesn't specify individual operations, it accurately summarizes the primary purpose at an appropriate level of specificity for a pull request title.
Linked Issues Check ✅ Passed All five operations requested in linked issue #18854 have been successfully implemented. The PR includes: a search action [search.mjs], a get-contents action for retrieving page content and summaries with configurable summaryQuery and summarySchema parameters [get-contents.mjs], a find-similar-links action [find-similar-links.mjs], and an answer-question action [answer-question.mjs]. Supporting infrastructure has been added to exa.app.mjs with methods for search, getContents, findSimilar, and answer, along with comprehensive propDefinitions covering all required parameters.
Out of Scope Changes Check ✅ Passed All changes in this pull request are directly related to implementing the five Exa operations specified in linked issue #18854. The four new action modules (search, find-similar-links, get-contents, answer-question) implement the requested functionality, while changes to exa.app.mjs provide necessary infrastructure with helper methods and propDefinitions, and the package.json update (version bump from 0.0.1 to 0.1.0 and adding dependencies) is standard version management for a new feature release. No unrelated changes or scope drift is evident.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch exa-new-components

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c658a54 and 84887d6.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • components/exa/actions/answer-question/answer-question.mjs (1 hunks)
  • components/exa/actions/find-similar-links/find-similar-links.mjs (1 hunks)
  • components/exa/actions/get-contents/get-contents.mjs (1 hunks)
  • components/exa/actions/search/search.mjs (1 hunks)
  • components/exa/exa.app.mjs (1 hunks)
  • components/exa/package.json (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • components/exa/actions/search/search.mjs
  • components/exa/package.json
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.

Applied to files:

  • components/exa/exa.app.mjs
📚 Learning: 2024-10-08T15:33:38.240Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 12731
File: components/hackerone/actions/get-members/get-members.mjs:3-28
Timestamp: 2024-10-08T15:33:38.240Z
Learning: When exporting a summary message in the `run` method of an action, ensure the message is correctly formatted. For example, in the `hackerone-get-members` action, the correct format is `Successfully retrieved ${response.data.length} members`.

Applied to files:

  • components/exa/actions/answer-question/answer-question.mjs
🧬 Code graph analysis (3)
components/exa/actions/find-similar-links/find-similar-links.mjs (1)
components/exa/actions/get-contents/get-contents.mjs (2)
  • parsedSchema (123-123)
  • response (136-179)
components/exa/actions/get-contents/get-contents.mjs (1)
components/exa/actions/find-similar-links/find-similar-links.mjs (2)
  • parsedSchema (219-219)
  • response (248-286)
components/exa/actions/answer-question/answer-question.mjs (3)
components/exa/actions/find-similar-links/find-similar-links.mjs (1)
  • response (248-286)
components/exa/actions/get-contents/get-contents.mjs (1)
  • response (136-179)
components/exa/actions/search/search.mjs (1)
  • response (120-138)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: pnpm publish
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Lint Code Base

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
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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9ffd7bf and 4094241.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • components/exa/actions/answer-question/answer-question.mjs (1 hunks)
  • components/exa/actions/find-similar-links/find-similar-links.mjs (1 hunks)
  • components/exa/actions/get-contents/get-contents.mjs (1 hunks)
  • components/exa/actions/search/search.mjs (1 hunks)
  • components/exa/exa.app.mjs (1 hunks)
  • components/exa/package.json (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
components/exa/actions/search/search.mjs (3)
components/exa/actions/answer-question/answer-question.mjs (1)
  • response (46-53)
components/exa/actions/find-similar-links/find-similar-links.mjs (1)
  • response (234-272)
components/exa/actions/get-contents/get-contents.mjs (1)
  • response (122-165)
components/exa/actions/answer-question/answer-question.mjs (3)
components/exa/actions/find-similar-links/find-similar-links.mjs (1)
  • response (234-272)
components/exa/actions/get-contents/get-contents.mjs (1)
  • response (122-165)
components/exa/actions/search/search.mjs (1)
  • response (120-138)
components/exa/actions/get-contents/get-contents.mjs (1)
components/exa/actions/find-similar-links/find-similar-links.mjs (1)
  • response (234-272)
components/exa/actions/find-similar-links/find-similar-links.mjs (2)
components/exa/actions/get-contents/get-contents.mjs (1)
  • response (122-165)
components/exa/actions/search/search.mjs (1)
  • response (120-138)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
  • GitHub Check: pnpm publish
  • GitHub Check: Ensure component commits modify component versions
  • GitHub Check: Lint Code Base
🔇 Additional comments (6)
components/exa/package.json (1)

3-3: LGTM! Version bump and dependency addition are appropriate.

The version bump to 0.1.0 reflects the new action surface, and the platform dependency is correctly specified for the new components.

Also applies to: 15-17

components/exa/actions/search/search.mjs (1)

1-143: LGTM! Clean action implementation.

The action follows Pipedream best practices with proper propDefinitions, clear structure, and appropriate summary export with request tracking.

components/exa/actions/get-contents/get-contents.mjs (1)

103-169: LGTM! Conditional payload construction works correctly.

The pattern of conditionally including nested objects (extras, highlights, summary) is safe since axios's JSON serialization automatically strips undefined values. The implementation correctly handles optional nested parameters.

components/exa/exa.app.mjs (2)

6-214: LGTM! Comprehensive propDefinitions.

The propDefinitions are well-structured with appropriate types, labels, descriptions, and optional flags. The examples and documentation references (like JSON Schema link for summarySchema) enhance usability.


216-263: LGTM! Clean HTTP helper pattern.

The methods follow a clear hierarchy (specific methods → post → _makeRequest) with proper header handling and URL construction. The API key is correctly included via x-api-key header per Exa's authentication requirements.

components/exa/actions/find-similar-links/find-similar-links.mjs (1)

180-276: LGTM! Consistent pattern with proper nested object handling.

The action correctly implements conditional construction of nested objects (highlights, summary, extras) and wraps them in the contents payload when needed. The summary properly includes requestId for tracking.

lcaresia
lcaresia previously approved these changes Oct 28, 2025
Copy link
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

🧹 Nitpick comments (7)
components/exa/actions/get-contents/get-contents.mjs (4)

66-71: Reuse app propDefinition for livecrawlTimeout for consistency

Avoid duplicating labels/descriptions/defaults; align with the app’s canonical prop definition.

-    livecrawlTimeout: {
-      type: "integer",
-      label: "Live Crawl Timeout",
-      description: "Timeout in milliseconds for live crawling (default: 10000)",
-      optional: true,
-    },
+    livecrawlTimeout: {
+      propDefinition: [
+        app,
+        "livecrawlTimeout",
+      ],
+    },

104-121: Avoid shadowing the imported app inside run()

Alias the destructured prop to improve readability and prevent confusion.

-  async run({ $ }) {
-    const {
-      app,
+  async run({ $ }) {
+    const {
+      app: exa,
       urls,
       text,
       ...
     } = this;
-    const response = await app.getContents({
+    const response = await exa.getContents({
       $,
       data: {
         urls,

Also applies to: 136-139


168-177: Only include schema when provided to keep payload clean

Prevents sending schema: undefined.

-        ...(summaryQuery
-          || summarySchema
+        ...(summaryQuery
+          || parsedSchema
           ? {
             summary: {
               query: summaryQuery,
-              schema: parsedSchema,
+              ...(parsedSchema ? { schema: parsedSchema } : {}),
             },
           }
           : undefined
         ),

181-182: Harden $summary for missing requestId

Use optional chaining and a fallback.

-    $.export("$summary", `Successfully retrieved contents with ID \`${response.requestId}\`.`);
+    $.export("$summary", `Successfully retrieved contents (request ID: ${response?.requestId ?? "n/a"}).`);
components/exa/actions/find-similar-links/find-similar-links.mjs (3)

219-238: Only include schema when provided to keep payload clean

Mirror the pattern used in the other action.

-    const summary = contentsSummaryQuery
-      || contentsSummarySchema
+    const summary = contentsSummaryQuery
+      || parsedSchema
       ? {
         query: contentsSummaryQuery,
-        schema: parsedSchema,
+        ...(parsedSchema ? { schema: parsedSchema } : {}),
       }
       : undefined;

181-207: Avoid shadowing the imported app inside run()

Alias the prop to improve readability.

-    const {
-      app,
+    const {
+      app: exa,
       ...
     } = this;
-    const response = await app.findSimilar({
+    const response = await exa.findSimilar({

Also applies to: 248-249


288-289: Harden $summary for missing requestId

Use optional chaining and a fallback.

-    $.export("$summary", `Successfully found similar links with ID \`${response.requestId}\`.`);
+    $.export("$summary", `Successfully found similar links (request ID: ${response?.requestId ?? "n/a"}).`);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f8e36ce and c658a54.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • components/exa/actions/answer-question/answer-question.mjs (1 hunks)
  • components/exa/actions/find-similar-links/find-similar-links.mjs (1 hunks)
  • components/exa/actions/get-contents/get-contents.mjs (1 hunks)
  • components/exa/actions/search/search.mjs (1 hunks)
  • components/exa/exa.app.mjs (1 hunks)
  • components/exa/package.json (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • components/exa/actions/answer-question/answer-question.mjs
  • components/exa/exa.app.mjs
  • components/exa/actions/search/search.mjs
🧰 Additional context used
🧬 Code graph analysis (2)
components/exa/actions/get-contents/get-contents.mjs (1)
components/exa/actions/find-similar-links/find-similar-links.mjs (2)
  • parsedSchema (219-219)
  • response (248-286)
components/exa/actions/find-similar-links/find-similar-links.mjs (1)
components/exa/actions/get-contents/get-contents.mjs (2)
  • parsedSchema (123-123)
  • response (136-179)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Lint Code Base
  • GitHub Check: pnpm publish
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (1)
components/exa/package.json (1)

3-17: Version bump and platform dep look good

No blocking issues here. Proceed.

@jcortes jcortes force-pushed the exa-new-components branch from c658a54 to 84887d6 Compare October 30, 2025 23:25
@jcortes
Copy link
Collaborator Author

jcortes commented Oct 30, 2025

/approve

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ACTION] Exa

3 participants