Skip to content

fix(deploy): normalize trigger provider aliases before cloud deploy - #227

Merged
khaliqgant merged 1 commit into
mainfrom
fix/normalize-trigger-provider-aliases
Jun 11, 2026
Merged

fix(deploy): normalize trigger provider aliases before cloud deploy#227
khaliqgant merged 1 commit into
mainfrom
fix/normalize-trigger-provider-aliases

Conversation

@khaliqgant

Copy link
Copy Markdown
Member

Summary

  • In packages/deploy/src/preflight.ts: after the persona/agent integration cross-check, apply KNOWN_TRIGGER_PROVIDER_ALIASES to rewrite trigger provider keys to their canonical names before the agent spec is returned and serialized into the cloud deploy payload

Why

The cloud's trigger-subscription API uses canonical adapter slugs (gmail, slack, …). Persona authors — and the runtime's own alias map — use the integration provider id instead (google-mail). KNOWN_TRIGGER_PROVIDER_ALIASES already backed the local lint warnings but was never applied to the outbound spec, so deploys failed at the cloud with:

400 {"error":"Unsupported integration trigger 'google-mail:file.created'","code":"unsupported_trigger"}

The fix runs after the integration cross-check so google-mail in agent.triggers still matches persona.integrations['google-mail'] (alias = alias). Only the spec handed to the cloud launcher gets canonical names.

Merge order

Merge AgentWorkforce/relayfile-adapters#170 first (adds granola.file.created to the trigger catalog). This PR has no hard dependency on it, but the two fixes address the same deploy session and the catalog update silences the remaining lint warning once this lands.

Test plan

  • Deploy deadline-watcher — 400 unsupported_trigger for google-mail:file.created should be gone
  • lintTriggers tests still pass (npm test -w packages/persona-kit)
  • Deploy preflight test for an agent with 'google-mail' trigger validates correctly and returns 'gmail' in the agent spec

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@khaliqgant, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 48 minutes and 48 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 73fc8614-a049-47d2-bf64-4abd953fe4f6

📥 Commits

Reviewing files that changed from the base of the PR and between 280c362 and fccd17c.

📒 Files selected for processing (1)
  • packages/deploy/src/preflight.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/normalize-trigger-provider-aliases

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.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces local skill source resolution for personas, allowing relative local skill paths to resolve against the persona JSON directory, and adds trigger provider alias normalization in the deploy preflight step. The review feedback highlights three key improvements: merging trigger arrays during normalization to prevent accidental overwrites, adding defensive checks to handle null or non-object skill elements gracefully, and running trigger linting on the raw agent configuration before normalization to ensure warning paths match the user's source files.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +167 to +170
const normalized: NonNullable<AgentSpec['triggers']> = {};
for (const [provider, list] of Object.entries(triggers)) {
normalized[aliases[provider] ?? provider] = list;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

If an agent configures triggers for both an alias and its canonical counterpart (or multiple aliases mapping to the same canonical name in the future), the current implementation will silently overwrite previous entries in the normalized object. Merging the trigger arrays instead of overwriting them prevents accidental loss of configured triggers.

  const normalized: NonNullable<AgentSpec['triggers']> = {};
  for (const [provider, list] of Object.entries(triggers)) {
    const canonical = aliases[provider] ?? provider;
    normalized[canonical] = normalized[canonical]
      ? [...normalized[canonical], ...list]
      : list;
  }

Comment on lines +945 to +946
return skills.flatMap((skill) => {
const source = skill.source;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

At runtime, skills elements are not guaranteed to be non-null objects before validation. If a user provides an invalid/null skill in their JSON, skill.source will throw a TypeError and crash the CLI. Adding a defensive check ensures that invalid skill entries are handled gracefully and can be caught by the downstream schema validator instead of crashing.

  return skills.flatMap((skill) => {
    if (!skill || typeof skill !== 'object') {
      return [skill];
    }
    const source = skill.source;

Comment on lines +112 to +114
const normalizedAgent = normalizeTriggerProviderAliases(agent);

const triggerLint = lintTriggers(normalizedAgent);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Running lintTriggers on the normalizedAgent causes any trigger warnings to report paths using the canonical provider name (e.g., triggers.gmail[0].on) instead of the alias name actually written in the user's source code (e.g., triggers.google-mail[0].on). Running lintTriggers on the raw agent first ensures that the warning paths match the user's source files exactly, improving developer experience.

Suggested change
const normalizedAgent = normalizeTriggerProviderAliases(agent);
const triggerLint = lintTriggers(normalizedAgent);
const triggerLint = lintTriggers(agent);
const normalizedAgent = normalizeTriggerProviderAliases(agent);

agent-relay-code Bot added a commit that referenced this pull request Jun 11, 2026
agent-relay-code Bot added a commit that referenced this pull request Jun 11, 2026
@agent-relay-code

Copy link
Copy Markdown
Contributor

Implemented two fixes from validated review feedback:

  • preflightPersona now lints the raw authored agent before normalizing aliases, so warnings point at paths users actually wrote, while the returned/cloud-bound agent remains normalized.
  • Local skill source resolution now tolerates malformed skill entries instead of throwing while trying to read skill.source.

Addressed comments

Advisory Notes

None.

Validation run locally:

  • corepack pnpm install --frozen-lockfile
  • corepack pnpm -r run build
  • corepack pnpm -r lint
  • corepack pnpm -r typecheck && corepack pnpm run typecheck:examples
  • corepack pnpm -r test

All passed locally. Remote PR metadata still reports mergeable_state: dirty, and no GitHub Actions workflow run is present for the current remote head SHA, so I am not marking this READY.

@agent-relay-code

Copy link
Copy Markdown
Contributor

Reviewed PR #227 against .workforce/pr.diff, changed files, and current checkout. I did not make code changes because I found no reproducible defect in the PR’s actual scope.

Local CI-equivalent verification run:

  • corepack pnpm install --frozen-lockfile passed
  • corepack pnpm -r run build passed
  • pnpm run lint passed using a temporary local pnpm shim
  • pnpm run typecheck passed
  • pnpm run test passed

Addressed comments

  • Codex review: diff-inventory-not-deterministic in .workflow-artifacts/.../lead-plan.md was not changed; invalid for this PR because it targets an unrelated integrations-discoverability workflow artifact, not the PR fix(deploy): normalize trigger provider aliases before cloud deploy #227 diff.
  • Codex review: offline-all-contract-weakened was not changed; invalid for this PR because it concerns agentworkforce integrations --all, outside the changed files and PR purpose.
  • Claude review: no issues found; no change needed.
  • Codex final review: committed-diff-gate-missing-implementation was not changed; invalid for this PR because it references unrelated workflow artifact gating and implementation paths absent from PR fix(deploy): normalize trigger provider aliases before cloud deploy #227’s changed-file set.
  • Claude final review: no issues found; no change needed.

Advisory Notes

The artifact comments under .workflow-artifacts/generated/spec-agentworkforce-integrations-integration-tri/ appear to belong to a separate integrations-discoverability effort. I left them unchanged to avoid folding unrelated workflow/spec changes into this PR.

I cannot print READY because I cannot verify GitHub-side required check status or mergeability from this sandbox, and the task requires those conditions before using that marker.

Aliases like 'google-mail' are valid integration provider ids (used in
persona.integrations and by the cloud's integration connect flow), but
the cloud's trigger-subscription API only accepts canonical adapter names
('gmail'). KNOWN_TRIGGER_PROVIDER_ALIASES already handled local lint
warnings; this gap meant the preflight passed cleanly locally but the
cloud returned 400 unsupported_trigger on deploy.

Add normalizeTriggerProviderAliases() in preflight.ts that runs AFTER the
integration-provider cross-check (so 'google-mail' still matches
persona.integrations['google-mail']) and replaces alias keys with their
canonical counterparts before the agent spec is returned and serialized
into the cloud deploy payload.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@khaliqgant
khaliqgant force-pushed the fix/normalize-trigger-provider-aliases branch from 01c45b0 to fccd17c Compare June 11, 2026 11:24
@khaliqgant
khaliqgant merged commit d18dd14 into main Jun 11, 2026
2 checks passed
@khaliqgant
khaliqgant deleted the fix/normalize-trigger-provider-aliases branch June 11, 2026 11:27
@agent-relay-code

Copy link
Copy Markdown
Contributor

Fixed a PR-scoped downstream regression from trigger-provider normalization.

The PR normalizes google-mail agent triggers to gmail for the cloud payload, but dev/sandbox runtime credentials still join triggers by persona integration key. That meant integrations["google-mail"] lost its trigger list. I added alias-aware lookup in packages/deploy/src/deploy.ts, with the fallback helper at packages/deploy/src/deploy.ts.

Added coverage:

Addressed comments

  • No bot or reviewer comments were present in the checked-out .workforce artifacts, so there were no external review threads to validate or skip.

Advisory Notes

  • None.

Local validation run:

  • npx pnpm@10.17.1 install --frozen-lockfile
  • npx pnpm@10.17.1 -r run build
  • npx pnpm@10.17.1 --filter @agentworkforce/deploy test
  • npx pnpm@10.17.1 run lint
  • npx pnpm@10.17.1 run typecheck
  • npx pnpm@10.17.1 run test

All completed successfully locally. I also checked for conflict markers and found none. I did not print READY because I could not verify GitHub’s live mergeability/check state from the checkout without using prohibited GitHub tooling.

@agent-relay-code

Copy link
Copy Markdown
Contributor

Fixed two PR-scope issues:

  • packages/deploy/src/preflight.ts:169 now merges trigger arrays when an alias and canonical provider normalize to the same key, instead of overwriting one.
  • packages/deploy/src/deploy.ts:511 now preserves aliased trigger events when building runtime credential payloads for dev/sandbox flows.

Added regression coverage in packages/deploy/src/deploy.test.ts:360 and packages/deploy/src/deploy.test.ts:746.

Addressed comments

  • No bot or reviewer comments were present in .workforce/context.json, so there were no external review threads to resolve.

Advisory Notes

  • None.

Validation run locally with the repo’s CI-equivalent build/test path:

PATH=/home/daytona/.local/bin:$PATH pnpm -r run build && PATH=/home/daytona/.local/bin:$PATH pnpm run lint && PATH=/home/daytona/.local/bin:$PATH pnpm run typecheck && PATH=/home/daytona/.local/bin:$PATH pnpm run test

All completed successfully.

@agent-relay-code

Copy link
Copy Markdown
Contributor

pr-reviewer could not complete review for #227 in AgentWorkforce/workforce.
The review harness exited with code 1.
No review was posted; this needs operator attention.

1 similar comment
@agent-relay-code

Copy link
Copy Markdown
Contributor

pr-reviewer could not complete review for #227 in AgentWorkforce/workforce.
The review harness exited with code 1.
No review was posted; this needs operator attention.

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.

1 participant