Skip to content

feat: built-in provider adapters for Webhook and GitHub#691

Merged
2witstudios merged 2 commits intomasterfrom
feat/builtin-provider-adapters
Feb 16, 2026
Merged

feat: built-in provider adapters for Webhook and GitHub#691
2witstudios merged 2 commits intomasterfrom
feat/builtin-provider-adapters

Conversation

@2witstudios
Copy link
Owner

@2witstudios 2witstudios commented Feb 16, 2026

Summary

  • Add Generic Webhook provider adapter with 3 tools: send_webhook (JSON POST), send_get_webhook (GET), send_form_webhook (form POST) — closes [Providers] Task 30: Generic webhook adapter #612
  • Add GitHub provider adapter with 6 tools: list_repos, get_issues, create_issue, create_pr_comment, get_pull_request, list_pull_requestscloses [Providers] Task 27: Built-in GitHub adapter #609
  • Add provider registry with lookup utilities (builtinProviders, getBuiltinProvider, isBuiltinProvider)
  • Fix applyMapping() to support dot-notation source keys (e.g. user.login) for nested property access in output transforms
  • Re-export all provider symbols from the main integrations/index.ts

Adapters are static IntegrationProviderConfig objects — pure data. The execution engine (executeToolSaga) handles all runtime: auth, request building, HTTP execution, retry, rate limiting, output transformation, and audit logging.

Test plan

  • 19 webhook provider tests passing (structure, tools, buildHttpRequest integration, schema compatibility)
  • 28 GitHub provider tests passing (OAuth config, tool categories, rate limits, buildHttpRequest integration, schema compatibility)
  • 11 registry tests passing (lookup, uniqueness, structural invariants)
  • 3 new applyMapping dot-notation tests passing
  • All 343 integration tests passing — no regressions
  • TypeScript: 0 errors

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Nested field access via dot-notation in field mapping (supports per-item array mapping; returns undefined for missing/null intermediate paths)
    • Generic webhook provider for sending POST/GET/form requests
    • GitHub provider for repos, issues, pull requests
    • Built-in provider registry with lookup and membership helpers
  • Tests

    • Comprehensive tests covering providers, request construction, output mapping, and nested-field mapping behaviors

Implements the first two built-in integration provider adapters (#609, #612),
completing the Integration milestone. Also fixes applyMapping() to support
dot-notation source keys for nested property access in output transforms.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 16, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

The changes introduce two new built-in provider adapters (Generic Webhook and GitHub) with comprehensive test coverage, establish a centralized provider registry system with lookup utilities, and enhance transform output to support dot-notation nested property access.

Changes

Cohort / File(s) Summary
Generic Webhook Provider
packages/lib/src/integrations/providers/generic-webhook.ts, packages/lib/src/integrations/providers/generic-webhook.test.ts
New provider adapter defining three webhook tools: POST with JSON body, GET request, and POST with form-encoded body. Includes custom header authentication via webhookSecret credential and rate limiting configuration. Tests validate provider metadata, authentication, tools, and HTTP request construction.
GitHub Provider
packages/lib/src/integrations/providers/github.ts, packages/lib/src/integrations/providers/github.test.ts
New provider adapter with OAuth2 authentication, base API headers, and six tools (list_repos, get_issues, create_issue, create_pr_comment, get_pull_request, list_pull_requests). Each tool specifies path templates, query/body parameters, output transformations with field mappings, and per-tool rate limits. Extensive test coverage validates OAuth config, HTTP request construction, parameter handling, and output shaping.
Provider Registry Infrastructure
packages/lib/src/integrations/providers/index.ts, packages/lib/src/integrations/providers/index.test.ts
New registry module exporting builtinProviders map, builtinProviderList array, getBuiltinProvider, and isBuiltinProvider utilities. Re-exports genericWebhookProvider and githubProvider. Tests verify registry integrity, provider mappings, uniqueness, lookup behavior, and structural invariants.
Transform Output Enhancement
packages/lib/src/integrations/execution/transform-output.ts, packages/lib/src/integrations/execution/transform-output.test.ts
Adds private resolveSourceKey helper enabling dot-notation path resolution for nested property access (e.g., user.login). Updates applyMapping to use the helper. Tests validate nested traversal, null/undefined handling, and array mapping.
Public API Expansion
packages/lib/src/integrations/index.ts
Re-exports built-in provider adapters and registry utilities: builtinProviders, builtinProviderList, getBuiltinProvider, isBuiltinProvider, genericWebhookProvider, githubProvider.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Two new providers hop into the fold,
Generic webhooks and GitHub, bold!
Nested paths now dot their way through,
A registry to help them find what's true!
More tools, more routes, more requests to send! 🚀

🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (16 files):

⚔️ apps/web/src/app/api/ai/page-agents/[agentId]/conversations/__tests__/route.test.ts (content)
⚔️ apps/web/src/app/api/cron/cleanup-orphaned-files/route.ts (content)
⚔️ apps/web/src/app/api/cron/purge-ai-usage-logs/route.ts (content)
⚔️ apps/web/src/app/api/cron/purge-deleted-messages/route.ts (content)
⚔️ apps/web/src/app/api/cron/retention-cleanup/route.ts (content)
⚔️ apps/web/src/app/api/cron/verify-audit-chain/route.ts (content)
⚔️ apps/web/src/app/api/integrations/google-calendar/webhook/route.ts (content)
⚔️ apps/web/src/components/auth/GoogleOneTap.tsx (content)
⚔️ apps/web/src/lib/auth/__tests__/cron-auth.test.ts (content)
⚔️ apps/web/src/lib/auth/cron-auth.ts (content)
⚔️ apps/web/src/lib/integrations/google-calendar/webhook-token.ts (content)
⚔️ apps/web/src/lib/repositories/conversation-repository.ts (content)
⚔️ packages/lib/src/integrations/execution/transform-output.test.ts (content)
⚔️ packages/lib/src/integrations/execution/transform-output.ts (content)
⚔️ packages/lib/src/integrations/index.ts (content)
⚔️ packages/lib/src/integrations/oauth/oauth-state.ts (content)

These conflicts must be resolved before merging into master.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding built-in provider adapters for Webhook and GitHub integration providers.
Linked Issues check ✅ Passed All coding requirements from issues #612 and #609 are implemented: generic webhook tools, GitHub tools, auth configuration, and structured output handling.
Out of Scope Changes check ✅ Passed All changes are directly aligned with PR objectives. Changes include provider adapters (#612, #609), provider registry, applyMapping dot-notation support, and comprehensive tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ 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 feat/builtin-provider-adapters
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch feat/builtin-provider-adapters
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

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

🤖 Fix all issues with AI agents
In `@packages/lib/src/integrations/providers/generic-webhook.ts`:
- Around line 62-70: The path interpolation currently used by pathTemplate
'/{path}' (see interpolatePath) does not URL-encode special characters so query
strings pass through literally; add automated tests for send_get_webhook that
assert values like path: 'status?key=value' produce '/status?key=value' and also
add tests that demonstrate unencoded characters (spaces, &, #) to lock in
current behavior; then update the generic-webhook.ts documentation (or the
send_get_webhook docstring) to state that interpolatePath does not encode path
values and callers must pre-encode if they expect percent-encoding, or
alternatively modify interpolatePath to perform encoding for all characters
except the query delimiter if you prefer server-side encoding (pick one approach
and document the chosen behavior).
🧹 Nitpick comments (3)
packages/lib/src/integrations/providers/github.ts (1)

151-162: labels mapping passes through raw GitHub label objects.

The labels: 'labels' mapping (Line 158) will include the full label objects from the GitHub API (each with id, node_id, url, name, color, default, description). This could be verbose for an AI agent. Consider mapping to a more concise representation if the transform engine supports it, or document that downstream consumers should expect full label objects.

packages/lib/src/integrations/execution/transform-output.ts (1)

64-66: Source keys containing literal dots cannot be accessed.

resolveSourceKey always interprets . as a path separator, so a source key like "user.login" (literal key with a dot) would be traversed as source["user"]["login"] instead of source["user.login"]. This is likely fine for API response data (GitHub, webhooks) but worth documenting in the JSDoc if other providers might have dotted literal keys.

packages/lib/src/integrations/providers/index.ts (1)

1-28: Clean registry module — looks good.

The code is well-structured: typed without any, concise, and the ?? null fallback in getBuiltinProvider is a nice touch over returning undefined. Re-exports are tidy.

One optional nit per the coding guidelines: builtinProviders and builtinProviderList are module-level constants — the guideline calls for UPPER_SNAKE_CASE for constants (e.g., BUILTIN_PROVIDERS, BUILTIN_PROVIDER_LIST). That said, this is a grey area for non-primitive constants and many TS codebases reserve UPPER_SNAKE_CASE for true compile-time constants, so feel free to keep as-is if that's the team convention. As per coding guidelines, "Use UPPER_SNAKE_CASE for constants".

Comment on lines +62 to +70
execution: {
type: 'http',
config: {
method: 'POST',
pathTemplate: '/{path}',
bodyTemplate: { $param: 'body' },
bodyEncoding: 'json',
},
},
Copy link
Contributor

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:

# Find interpolatePath implementation
ast-grep --pattern $'export const interpolatePath = ($$$) => {
  $$$
}'

Repository: 2witstudios/PageSpace

Length of output: 47


🏁 Script executed:

# Search for interpolatePath and URL encoding logic
rg -n 'interpolatePath|encodeURIComponent|encodeURI' --type=ts -C3

Repository: 2witstudios/PageSpace

Length of output: 30276


🏁 Script executed:

# Also check if there are integration tests for the webhook provider
fd -e test.ts -e spec.ts | xargs grep -l "interpolatePath|generic-webhook" 2>/dev/null | head -5

Repository: 2witstudios/PageSpace

Length of output: 47


🏁 Script executed:

# View the interpolatePath implementation
sed -n '14,40p' packages/lib/src/integrations/execution/build-request.ts

Repository: 2witstudios/PageSpace

Length of output: 725


🏁 Script executed:

# View the build-request.test.ts file to see all interpolatePath test cases
cat -n packages/lib/src/integrations/execution/build-request.test.ts | head -100

Repository: 2witstudios/PageSpace

Length of output: 3823


🏁 Script executed:

# Check buildHttpRequest to see how the final URL is constructed
sed -n '130,160p' packages/lib/src/integrations/execution/build-request.ts

Repository: 2witstudios/PageSpace

Length of output: 1012


🏁 Script executed:

# Check generic-webhook.test.ts for path handling tests
cat -n packages/lib/src/integrations/providers/generic-webhook.test.ts | grep -A 10 -B 5 "path\|query"

Repository: 2witstudios/PageSpace

Length of output: 3442


🏁 Script executed:

# View the full generic-webhook.test.ts to see how paths are tested
wc -l packages/lib/src/integrations/providers/generic-webhook.test.ts

Repository: 2witstudios/PageSpace

Length of output: 132


🏁 Script executed:

# Check if there are any tests with special characters in path values
rg -n "path.*\?" packages/lib/src/integrations/providers/generic-webhook.test.ts

Repository: 2witstudios/PageSpace

Length of output: 47


🏁 Script executed:

# Let's check the actual generic-webhook.ts file to see the complete definition
cat -n packages/lib/src/integrations/providers/generic-webhook.ts | head -150

Repository: 2witstudios/PageSpace

Length of output: 4077


🏁 Script executed:

# Check if there are any other URL building utilities or encoding helpers
rg -n "encodeURIComponent|encodeURI" packages/lib/src/integrations/ --type=ts

Repository: 2witstudios/PageSpace

Length of output: 47


🏁 Script executed:

# Verify what happens when URL is constructed with path containing query string
# by checking if there are integration tests that cover this
rg -n "query|searchParams" packages/lib/src/integrations/execution/ --type=ts -A 3

Repository: 2witstudios/PageSpace

Length of output: 3332


🏁 Script executed:

# View more of the build-request.test.ts to see all queryParams tests
sed -n '215,260p' packages/lib/src/integrations/execution/build-request.test.ts

Repository: 2witstudios/PageSpace

Length of output: 1477


🏁 Script executed:

# Check if generic-webhook has any test with query string in path
cat -n packages/lib/src/integrations/providers/generic-webhook.test.ts | grep -A 5 "query\|?"

Repository: 2witstudios/PageSpace

Length of output: 47


Clarify path interpolation behavior and add test coverage for query strings.

The pathTemplate: '/{path}' pattern works correctly with query strings—the ? character is not URL-encoded and will pass through literally (e.g., path: 'status?key=value' produces /status?key=value). However, interpolatePath applies no URL encoding to any special characters in the path value. While this permits query strings by design, it means other special characters (spaces, &, #, etc.) are not encoded either.

Add test coverage for the documented behavior where path "can include query string" (line 82 of send_get_webhook), and consider documenting whether callers are expected to pre-encode path values or if encoding should be applied at the interpolation layer.

🤖 Prompt for AI Agents
In `@packages/lib/src/integrations/providers/generic-webhook.ts` around lines 62 -
70, The path interpolation currently used by pathTemplate '/{path}' (see
interpolatePath) does not URL-encode special characters so query strings pass
through literally; add automated tests for send_get_webhook that assert values
like path: 'status?key=value' produce '/status?key=value' and also add tests
that demonstrate unencoded characters (spaces, &, #) to lock in current
behavior; then update the generic-webhook.ts documentation (or the
send_get_webhook docstring) to state that interpolatePath does not encode path
values and callers must pre-encode if they expect percent-encoding, or
alternatively modify interpolatePath to perform encoding for all characters
except the query delimiter if you prefer server-side encoding (pick one approach
and document the chosen behavior).

…ests

The URL API's pathname setter percent-encodes ?, #, and spaces — so query
strings in the path param are NOT treated as query delimiters. Updated the
send_get_webhook description to remove the misleading "can include query
string" claim, added module-level documentation of encoding behavior, and
added 6 tests locking in the exact encoding for ?, &, #, spaces, and slashes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@2witstudios 2witstudios merged commit 0f857c3 into master Feb 16, 2026
3 checks passed
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.

[Providers] Task 30: Generic webhook adapter [Providers] Task 27: Built-in GitHub adapter

1 participant