Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions packages/deploy/src/preflight.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { readFile, stat } from 'node:fs/promises';
import path from 'node:path';
import {
KNOWN_TRIGGER_PROVIDER_ALIASES,
lintTriggers,
parsePersonaSpec,
type AgentSpec,
type PersonaIntent,
type PersonaSpec
} from '@agentworkforce/persona-kit';
Expand Down Expand Up @@ -102,14 +104,21 @@ export async function preflightPersona(personaPath: string): Promise<DeployPrefl
}
}

const triggerLint = lintTriggers(agent);
// Normalize trigger provider aliases to canonical names so the cloud API
// receives e.g. 'gmail' instead of 'google-mail'. The integration-provider
// check above runs against the raw (alias) form — the persona and agent can
// both use 'google-mail' and the check still passes. Only the outbound
// agent spec sent to the cloud needs canonical names.
const normalizedAgent = normalizeTriggerProviderAliases(agent);

const triggerLint = lintTriggers(normalizedAgent);
const warnings = triggerLint.map(
(issue) => `${issue.path}: ${issue.message}`
);

return {
persona,
agent,
agent: normalizedAgent,
personaPath: absPath,
personaDir,
onEventPath,
Expand Down Expand Up @@ -143,3 +152,21 @@ async function readPersonaSource(absPath: string): Promise<unknown> {
const { persona } = await loadPersonaSourceFile(absPath);
return persona;
}

/**
* Replace alias trigger provider names with their canonical counterparts so
* the cloud API never sees a name it doesn't recognise. E.g. 'google-mail'
* (the integration provider id) → 'gmail' (the trigger catalog name).
* The persona's `integrations` map is left untouched — the cloud resolves
* integrations and triggers under different namespaces.
*/
function normalizeTriggerProviderAliases(agent: AgentSpec): AgentSpec {
const { triggers } = agent;
if (!triggers) return agent;
const aliases = KNOWN_TRIGGER_PROVIDER_ALIASES as Record<string, string>;
const normalized: NonNullable<AgentSpec['triggers']> = {};
for (const [provider, list] of Object.entries(triggers)) {
normalized[aliases[provider] ?? provider] = list;
}
Comment on lines +167 to +170

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

return { ...agent, triggers: normalized };
}
Loading