Develop and extend
How-to

Add an integration

Extend Agent Barn with an external provider across credential validation, encrypted persistence, runtime materialization, Skills, web app configuration, and end-to-end verification.

For
Integration developers and maintainers
On this page
  1. What you will accomplish
  2. Before you begin
  3. Understand the integration boundary
  4. Plan the provider contract
  5. Add the credential model
  6. Preserve credential security
  7. Add live validation
  8. Materialize the integration at runtime
  9. Add the provider Skill
  10. Add the web app configuration
  11. Decide whether credentials can be shared
  12. Add OAuth when required
  13. Handle stored-data compatibility
  14. Test the complete integration
  15. Verify the integration end to end
  16. Troubleshooting
  17. Completion checklist
  18. Source map
  19. Related documentation
  • Integrations
  • Provider contribution
  • 20 minutes

An Agent Barn integration connects an Agent to an external service. A complete integration does more than collect a token: it validates the credential shape, encrypts it, materializes the correct runtime artifacts, teaches the Agent how to use the capability, exposes a safe configuration experience, and proves the entire path with tests.

This guide describes the contribution path for a new external provider. It does not cover adding Slack, Telegram, Discord, or another conversation transport. Those are communication platforms with separate lifecycle and runtime contracts.

Audience
Integration developers and maintainers
Repository
agent-barn
Namespaces
Existing Python and deployment namespaces continue to use agent-farm where already established.

What you will accomplish

By the end of this guide, you will be able to:

  • Classify the provider before changing code
  • Define and validate its credential payload
  • Preserve encrypted-storage and read-response guarantees
  • Add a safe, read-only credential validator
  • Materialize credentials into the correct Agent runtime
  • Add an aai-cli Skill and Agent policy when applicable
  • Expose the provider in every relevant web app surface
  • Decide whether the provider supports Shared Credentials
  • Preserve existing encrypted records when changing a schema
  • Test storage, authorization, runtime generation, UI behavior, and secret safety

Before you begin

You should have:

  • A working Agent Barn development environment
  • Docker available for the API integration-test environment
  • Non-production credentials for the external provider
  • Documentation for the provider’s authentication and permission model
  • A confirmed runtime access path
  • A clear list of operations the Agent should be allowed to perform

Read these guides first:

Before implementing an aai-cli-backed provider, confirm that the required command group is supported by the pinned aai-cli version. An Agent Barn profile cannot provide operations that the installed CLI does not implement.

Understand the integration boundary

Agent Barn has several related concepts that must remain separate.

External provider integration

Gives an Agent tools for an external service

GitHub, Jira, Confluence, Pipedrive

Communication platform

Carries messages between users and the Agent

Slack, Telegram, Discord

Agent Secret

Provider credential owned by one Agent

A per-Agent GitHub token

Shared Credential

Organization-owned credential attachable to Agents

A reusable Jira service account

Deployment secret

Configures the Agent Barn installation

Encryption keys and platform service credentials

Skill

Teaches an Agent how and when to use available tools

The built-in GitHub aai-cli Skill

Live validator

Checks whether a stored credential still works

A read-only provider identity request

Choose the runtime shape

Current integrations follow three main runtime shapes.

Shape Use when Current pattern
aai-cli profile The pinned aai-cli exposes the provider’s operations GitHub, Jira, Confluence, Bitbucket, Zoho Mail, Slack data access, Pipedrive
Dedicated CLI The provider requires an independent tool and credential store Google Workspace through gog
Runtime capability The runtime consumes provider configuration directly Firecrawl web search and fetch

These paths are intentionally different. Do not force a dedicated CLI or runtime-native provider through the aai-cli profile contract.

Keep provider access separate from chat delivery

Slack demonstrates why classification matters:

  • Slack can be the Agent’s communication platform
  • Slack can also provide data-access operations through an aai-cli Skill
  • The aai-cli credential is derived from the configured Slack bot token when a remaining Skill requires it
  • The user does not submit a second manual Slack integration credential

A new provider should only receive similar special handling when its configuration is genuinely derived from another authoritative source.

Plan the provider contract

Write down the provider contract before editing the enum. At minimum, decide:

  • The stable provider ID
  • The display label
  • The authentication method
  • Required and optional credential fields
  • Which fields are secret
  • Which fields affect endpoint or resource selection
  • Whether credentials are entered manually or obtained through OAuth
  • Whether the provider can be used as a Shared Credential
  • Whether the provider uses aai-cli, a dedicated CLI, or runtime-native configuration
  • The minimum safe operation for live validation
  • The expected identity shown after validation
  • Required and recommended provider permissions
  • Whether missing permissions are fatal or should produce a warning
  • Which Skill files teach the Agent the command surface
  • How existing encrypted payloads will remain readable after future changes

Use a stable, lowercase provider value such as acme. This value crosses API, storage, runtime, Skill metadata, and UI boundaries. Treat it as a persisted identifier, not a display string.

Add the credential model

The authoritative provider contract lives in api/domains/agents/models.py. A normal provider addition updates four related definitions:

  1. SecretProvider
  2. A SecretContent subclass
  3. PROVIDER_CONTENT_MODELS
  4. PROVIDER_DISPLAY_NAMES
models.py
class SecretProvider(str, enum.Enum):
    # Existing providers...
    ACME = "acme"


class AcmeContent(SecretContent):
    api_token: str = Field(min_length=1)
    base_url: str = Field(min_length=1)


PROVIDER_CONTENT_MODELS: dict[SecretProvider, type[SecretContent]] = {
    # Existing mappings...
    SecretProvider.ACME: AcmeContent,
}


PROVIDER_DISPLAY_NAMES: dict[SecretProvider, str] = {
    # Existing labels...
    SecretProvider.ACME: "Acme credential",
}

All provider content models inherit:

Base content model
class SecretContent(PydanticBaseModel):
    model_config = ConfigDict(extra="forbid")

This means unknown fields are rejected. Keep that behavior. Silently accepting misspelled or unused credential fields can create credentials that appear configured but cannot work.

Model only what runtime materialization needs

Credential content should contain the minimum data required to configure the runtime.

Good candidates

  • Access token or API token
  • Refresh token
  • Account email
  • Tenant, workspace, or organization identifier
  • Base URL
  • Repository or resource selection
  • OAuth client ID and secret when the token is bound to a user-supplied client

Do not include

  • Display-only UI state
  • Validation results
  • Last-used timestamps
  • Plaintext duplicates of another field
  • Provider API responses
  • Permission lists that can be derived safely
  • Agent policy prose

Validate on both write and read

Agent Barn calls validate_content() before encryption and calls it again after decryption.

Validation
def validate_content(provider: SecretProvider, raw: dict) -> SecretContent:
    return PROVIDER_CONTENT_MODELS[provider].model_validate(raw)

Revalidation after decryption prevents malformed stored content from reaching runtime builders. It also means every schema change must account for existing encrypted payloads.

Preserve credential security

Normal Agent Secret persistence already handles:

  • Provider-specific schema validation
  • Fernet encryption
  • One credential per provider per Agent
  • Server-defined display labels
  • Manual credential upsert
  • Explicit provider removal
  • Shared Credential references
  • Secret lifecycle Domain Events
  • Secret-management authorization

Do not add a provider-specific plaintext column unless the architecture genuinely requires one.

A manual credential is sent through the normal Agent create or update contract:

Request
{
  "secrets": [
    {
      "provider": "acme",
      "content": {
        "api_token": "example-non-production-token",
        "base_url": "https://api.example.invalid"
      }
    }
  ]
}

The API response exposes metadata, not credential content:

Response
{
  "provider": "acme",
  "secret_name": "Acme credential",
  "shared_credential_id": null,
  "shared_credential_name": null
}

Preserve these invariants

  • An Agent has at most one Agent Secret per provider
  • Duplicate providers in one request are rejected
  • A provider cannot be updated and removed in the same request
  • A provider uses either a manual Agent Secret or a Shared Credential attachment, not both
  • Credential content is encrypted before persistence
  • Read APIs never return decrypted content
  • Domain Events never include credential content
  • Logs, validation errors, and exception messages never contain tokens
  • Secret mutation requires the effective agent.secret.manage Permission
  • Inaccessible Agents remain concealed according to the Agent Access contract
  • Integration changes to a running Agent follow the existing stopped-Agent configuration rules

Add live validation

Live validation answers a narrow question: does this stored credential currently authenticate with sufficient access?

Add a provider-specific validator under api/infrastructure/integration_validators/. Use a safe, read-only request — prefer an identity, account, metadata, or list endpoint that cannot mutate provider state.

Illustrative validator
import httpx

from api.domains.agents.models import AcmeContent
from api.infrastructure.integration_validators.result import (
    IntegrationValidationResult,
)

_TIMEOUT = 10


def validate_acme(content: AcmeContent) -> IntegrationValidationResult:
    try:
        response = httpx.get(
            f"{content.base_url.rstrip('/')}/v1/me",
            headers={"Authorization": f"Bearer {content.api_token}"},
            timeout=_TIMEOUT,
        )
    except Exception as exc:
        return IntegrationValidationResult(
            valid=False,
            error=f"Could not reach Acme: {exc}",
        )

    if response.status_code == 401:
        return IntegrationValidationResult(
            valid=False,
            error="Token is invalid or expired",
        )

    if response.status_code == 403:
        return IntegrationValidationResult(
            valid=False,
            error="Credential does not have account access",
        )

    if response.status_code != 200:
        return IntegrationValidationResult(
            valid=False,
            error=f"Acme returned unexpected status {response.status_code}",
        )

    identity = response.json().get("email") or response.json().get("name")
    return IntegrationValidationResult(valid=True, identity=identity)

Register it in api/infrastructure/integration_validators/__init__.py:

Validator registry
PROVIDER_VALIDATORS: dict[SecretProvider, Any] = {
    # Existing validators...
    SecretProvider.ACME: validate_acme,
}

The shared result contract maps to three user-facing states.

Result API status value Meaning
valid=True, no missing scopes valid Authentication and expected access succeeded
valid=True, missing scopes present warning Authentication succeeded, but useful permissions are absent
valid=False invalid Authentication, identity, or required access failed

Use missing_scopes for access that is useful but not required to establish that the credential is real. Return an invalid result when the Agent cannot perform the integration’s essential operations.

Validation must:

  • Avoid writes
  • Use a bounded timeout
  • Handle provider-specific error semantics
  • Avoid returning raw provider response bodies
  • Avoid including credentials in errors
  • Return a useful identity when safely available
  • Test network errors and unexpected statuses
  • Remain non-persisting

Agent validation uses:

Validation endpoint
POST /api/v1/organizations/{organization_id}/agents/{agent_id}/integrations/{provider}/validate

It requires agent.secret.manage. The service decrypts the stored manual or Shared Credential only for the validation call.

Materialize the integration at runtime

Storing a credential does not make it usable. Agent startup must convert the decrypted provider content into runtime artifacts. At startup, Agent Service:

  1. Loads the Agent’s credential rows
  2. Resolves Shared Credential references
  3. Decrypts and revalidates provider content
  4. Builds provider configuration and secret-store setup
  5. Adds sensitive values to the Kubernetes Secret
  6. Adds secret-free setup and configuration to the ConfigMap
  7. Mounts eligible Skills
  8. Appends provider context and policy to the rendered Agent files
  9. Creates the selected Hermes or OpenClaw resources

aai-cli-backed providers

For aai-cli, update api/domains/agents/aai_cli_artifacts.py. An illustrative provider normally needs:

Secret map and profile slug
provider_secrets_map["acme"] = [
    ("acme.api_token", "api_token"),
]

PROFILE_SLUGS[SecretProvider.ACME] = "acme-work"

It also needs a profile builder:

Profile builder
def _acme_block(content: AcmeContent) -> str:
    return (
        f"[profiles.{PROFILE_SLUGS[SecretProvider.ACME]}]\n"
        'provider = "acme"\n'
        'auth_type = "bearer_token"\n'
        f"base_url = {_q(content.base_url)}\n"
        'token_secret = "acme.api_token"\n'
    )


_PROFILE_BUILDERS[SecretProvider.ACME] = _acme_block

Also update the provider label and capability summary used in Agent context:

Labels and capabilities
_INTEGRATION_LABELS[SecretProvider.ACME] = "Acme"

_INTEGRATION_CAPABILITIES[SecretProvider.ACME] = (
    "projects, records, comments, and attachments"
)

For an aai-cli provider, verify all of these surfaces:

  • Secret-store name mapping
  • Temporary setup environment
  • config.toml profile
  • Canonical --profile slug
  • Configured-integrations context
  • Always-loaded Agent policy
  • Capability summary
  • Built-in Skill files
  • Hermes startup
  • OpenClaw startup

Sensitive values belong in the Kubernetes Secret. ConfigMap content, Skill files, TOOLS.md, and AGENTS.md must remain secret-free.

Dedicated CLI providers

If the provider uses a separate CLI, follow the dedicated Google Workspace pattern rather than pretending it is an aai-cli profile. A dedicated CLI integration may require:

  • Its own environment builder
  • Its own setup script
  • Its own on-disk credential home
  • A separate policy block
  • Base-image installation and version pinning
  • Startup hooks in both runtime images
  • Builder parameters for both Hermes and OpenClaw
  • Focused artifact and image-contract tests

Document whether CLI state is persistent or rebuilt on every start. The encrypted database record should remain authoritative unless the architecture explicitly establishes another source of truth.

Runtime-native providers

For a runtime-native capability, add the provider to the specific runtime configuration path. The Firecrawl pattern demonstrates:

  • A platform-level default can configure every Agent
  • A per-Agent credential can override that default
  • Hermes and OpenClaw require different generated configuration
  • Sensitive values remain in the Kubernetes Secret
  • Removing the Agent credential restores the platform default on the next start

Do not add a fake aai-cli profile for a provider that is actually consumed by runtime configuration.

Add the provider Skill

An integration needs instructions as well as credentials. Without a Skill or always-loaded policy, the Agent may not know:

  • That the tool is available
  • Which profile to use
  • Which command hierarchy is valid
  • What operations are supported
  • What an error response means
  • Which actions are read-only or mutating
  • How to return files or attachments

For an aai-cli provider, add a module such as api/domains/agents/aai_cli_skills/acme.py, exporting one or more files:

acme.py
ACME_SKILLS: list[dict[str, str]] = [
    {
        "skill_file_path": "aai-cli/acme_skill.md",
        "skill_content": """\
# aai-cli Acme Skill

## Credentials are already configured

Use the configured profile. Do not ask the user for tokens.

## Required profile

Every command requires `--profile acme-work`.

## Command shape

```text
aai-cli --profile acme-work acme <resource> <verb>
```

Document the real resources, verbs, flags, responses, and errors here.
""",
    },
]

Then import it and register the built-in Skill in api/domains/agents/aai_cli_skills/__init__.py:

Skill registration
{
    "name": "Acme",
    "required_providers": [SecretProvider.ACME],
    "files": ACME_SKILLS,
    "entry_path": ACME_SKILLS[0]["skill_file_path"].removeprefix(
        AAI_CLI_ROOT_DIR + "/"
    ),
    "tools_pointer": (
        "\nFor Acme, use the aai-cli tool. "
        "See ./skills/aai-cli/acme_skill.md\n"
    ),
}

The API startup seeder creates the global built-in Skill when it is absent. When shipped file content changes, it publishes a new Skill version only if the files differ from the latest stored version.

Configured provider credentials implicitly mount matching aai-cli Skills at Agent start. A built-in with no required providers is not automatically mounted.

Add the web app configuration

The provider catalog for Agent configuration lives in ui/src/features/agents/integrations.ts. Add a provider definition with fields matching the backend content model.

integrations.ts
{
  id: "acme",
  label: "Acme",
  scopeNote:
    "Use a token with read access and only the write permissions the Agent requires.",
  fields: [
    {
      key: "apiToken",
      label: "API token",
      type: "secret",
      required: true,
      placeholder: "acme_…",
    },
    {
      key: "baseUrl",
      label: "Base URL",
      type: "text",
      required: true,
      placeholder: "https://api.example.invalid",
    },
  ],
}

The provider ID must exactly match the backend SecretProvider value. Enum values are not converted.

Web app field keys use camel case. The shared API client decamelizes request keys:

Key conversion
apiToken → api_token
baseUrl  → base_url

Supported integration field types currently include:

  • text
  • secret
  • repo-list
  • radio
  • checkbox-list

IntegrationFields is shared by the hiring flow, Agent Skills configuration, and Agent credential settings. Extend the shared component when the provider needs a genuinely new reusable field behavior.

When adding fields:

  • Mark required fields accurately
  • Provide scope guidance
  • Keep token inputs masked
  • Add useful placeholders without showing real credentials
  • Convert string-backed radio values to booleans when the API model expects booleans
  • Update incomplete-integration checks
  • Preserve field behavior while the Agent is running
  • Verify create, edit, remove, and reconnect flows
  • Update fixtures and Playwright expectations together

OAuth is not enabled by a label

Decide whether credentials can be shared

Shared Credentials are Organization-scoped credentials managed independently of an Agent. They are appropriate when:

  • The credential is entered manually
  • Several Agents should use the same service account
  • Rotation should occur once at the Organization level
  • Attaching the credential does not require a user-specific OAuth callback
  • The provider’s authorization model permits shared service credentials

To enable a provider, add it to SHARED_CREDENTIAL_ALLOWED_PROVIDERS in api/domains/shared_credentials/models.py.

Preserve these rules:

  • Only Organization owners and admins create, update, validate, or delete Shared Credentials
  • Organization members can list credential briefs and attach them to accessible Agents
  • Names are unique within an Organization
  • Multiple credentials for the same provider are allowed
  • A credential cannot be read across Organizations
  • An Agent cannot have a manual and shared credential for the same provider
  • Deletion is blocked while a non-deleted Agent references the credential
  • Read responses never contain credential content
  • Runtime startup resolves and decrypts the referenced Shared Credential
  • Live validation uses the same provider validator when one is registered

Add Shared Credential UI coverage if the provider becomes eligible.

Add OAuth when required

OAuth providers need more than a credential schema. A secure OAuth implementation should define:

  1. The provider-specific authorization endpoint
  2. A typed, signed, short-lived state value
  3. The authenticated user or Organization context carried by that state
  4. Requested service and permission choices
  5. Callback handling
  6. Server-side code exchange
  7. Returned identity and granted scopes
  8. Assembly of the normal provider credential payload
  9. Reconnection and token-rotation behavior
  10. Tests for invalid, expired, tampered, and mismatched state

Use the Google Workspace implementation as a concrete repository pattern:

Reference implementation
api/domains/integrations/google_oauth/routes.py
ui/src/features/agents/hooks/use-google-oauth.ts

Do not copy Google-specific assumptions into another provider. Scope derivation, consent behavior, refresh-token rules, callback parameters, and client ownership vary by service.

Handle stored-data compatibility

Provider content is stored as encrypted JSON and validated again after decryption. Changing a model can make every existing credential for that provider unreadable.

Safe additive changes

  • Adding an optional field with a default
  • Adding a field that can be derived after decryption
  • Adding a compatibility validator that converts a legacy shape
  • Preserving an old field while transitioning runtime behavior

Potentially breaking changes

  • Renaming a required field
  • Removing a field from a model with extra="forbid"
  • Changing a string into a list without coercion
  • Changing the provider value
  • Requiring a new secret for existing records
  • Moving a provider between runtime systems without a transition

A compatibility conversion can follow the existing repository-list pattern:

Compatibility validator
@model_validator(mode="before")
@classmethod
def upgrade_legacy_shape(cls, data):
    if isinstance(data, dict) and "old_field" in data and "new_field" not in data:
        upgraded = dict(data)
        upgraded["new_field"] = upgraded.pop("old_field")
        return upgraded
    return data

agent_secret.provider and shared_credential.provider are stored as strings, so adding an enum member alone does not normally require a PostgreSQL enum migration. A migration is still required when the database shape, persisted data, constraints, or existing Skill metadata must change.

Provider removal requires an explicit cleanup plan. Remove or transform affected credential rows and Skill requirements before deleting the enum member.

Test the complete integration

Test the lowest layer that proves each contract, then cover the assembled behavior.

Concern Minimum coverage
Provider enum and display name Unit test covering complete provider mappings
Credential shape Valid, missing-field, extra-field, and default-value unit tests
Encrypted storage Encrypt/decrypt round trip and plaintext-absence assertion
Legacy compatibility Decrypt an old encrypted shape into the new model
Agent create Integration test showing the provider in secret metadata
Agent update Add, replace, and remove behavior
Duplicate provider Request validation failure
Running Agent Lifecycle conflict behavior
Authorization agent.secret.manage, inaccessible Agent, and cross-Organization cases
Domain Events Added, updated, and removed events contain no credential content
Live validation Success, warning, invalid credential, network error, and unexpected response
aai-cli profile Exact TOML, profile slug, secret names, setup environment, and policy
Dedicated CLI Environment, setup script, policy, and image contract
Runtime-native provider Hermes and OpenClaw generated configuration
Skill Required provider, file paths, pointer, and command documentation
Automatic mounting Configured provider mounts its built-in aai-cli Skill
Shared Credential Role, tenant, attach, detach, validation, and deletion restriction
Web app Hiring, credential settings, validation, removal, and Shared Credential selection
Documentation Provider behavior and source map remain accurate

Representative test locations include:

Test locations
api/tests/unit/test_agent_secrets.py
api/tests/unit/test_integration_validators.py
api/tests/unit/test_aai_cli_artifacts.py
api/tests/unit/test_aai_cli_skills.py
api/tests/unit/test_gog_artifacts.py
api/tests/integration/test_agents.py
api/tests/integration/test_shared_credentials.py
api/tests/integration/test_agent_start_shared_credential.py
ui/tests/e2e/hire-dialog.spec.ts
ui/tests/e2e/agent-configuration-page.spec.ts
ui/tests/e2e/shared-credentials.spec.ts

Run the checks for every touched area:

Verification
make check-api
make test-api
make lint-ui
make check-ui
make test-ui

If the integration changes Kubernetes resource generation or runtime images, also run the relevant Kubernetes and image-contract verification.

Kubernetes verification
make test-api-k8s

Use make coverage when you need to inspect API coverage in detail.

Verify the integration end to end

After automated tests pass, verify one complete non-production flow.

  1. Start Agent Barn locally.
  2. Sign in to a test Organization.
  3. Create or select a stopped Agent.
  4. Add the new provider credential.
  5. Confirm the API response contains provider metadata but no content.
  6. Run live validation.
  7. Confirm the expected identity and permission state.
  8. Start the Agent.
  9. Inspect generated runtime configuration without printing secret values.
  10. Confirm the provider Skill is mounted when applicable.
  11. Ask the Agent to perform a safe read operation.
  12. Confirm the Agent uses the documented CLI, profile, or runtime tool.
  13. Exercise one permitted mutation if the integration supports writes.
  14. Stop the Agent.
  15. Rotate or replace the credential.
  16. Restart and confirm the new credential is used.
  17. Remove the credential.
  18. Restart and confirm access is gone or the documented platform default applies.
  19. Review Agent activity and logs for errors or accidental credential exposure.

For a Shared Credential, repeat the flow with two Agents and confirm that rotation affects both after restart.

Troubleshooting

Symptom Likely cause What to check
Provider is rejected with 422 Provider ID or credential fields do not match the backend schema SecretProvider, content model, provider map, and UI key conversion
Provider appears configured but the Agent cannot use it Runtime materialization is incomplete Profile builder, environment, setup script, runtime config, and image dependency
aai-cli reports an unknown provider or command The pinned aai-cli does not support the command surface aai-cli version and the Skill’s documented commands
Agent asks the user for credentials Provider context, policy, or Skill is missing Tool context, Agent policy, Skill registration, and automatic mounting
Validate returns no-validator error The provider was not registered in PROVIDER_VALIDATORS Validator module and registry
Validation succeeds but operations fail The validation probe does not cover essential permissions Required scopes and safe resource probes
Validation reports a warning Authentication works but recommended permissions are absent missing_scopes and provider token configuration
Existing credentials fail after an upgrade The content schema is not backward compatible Defaults, compatibility validators, and stored-data migration plan
Credential appears in API output Response DTO or serialization exposes internal content Agent Secret read model and service mapping
Credential appears in logs or events Secret-bearing values are being formatted or serialized Exceptions, logging, Domain Event payloads, and test assertions
Provider is absent from the hiring flow UI provider catalog was not updated INTEGRATION_PROVIDERS and required-field checks
Shared Credential cannot be created Provider is not eligible or not allowlisted Authentication method and SHARED_CREDENTIAL_ALLOWED_PROVIDERS
Agent start fails only on one runtime Only one runtime builder or startup path was updated Hermes and OpenClaw builders, scripts, and image contents
Configuration works until restart Runtime state is being treated as authoritative Startup reconstruction and encrypted credential source of truth
Removing a credential breaks a required Skill The Skill still declares that provider requirement Skill assignment and remaining-provider validation

Completion checklist

Work through each card before opening the pull request.

  • Provider contract

  • Backend

  • Runtime

  • Skills and policy

  • Web app

  • Verification and documentation

Source map

Concern Authoritative source
Provider enum and credential content api/domains/agents/models.py
Agent Secret persistence api/domains/agents/service.py
Agent Secret queries and events api/domains/agents/repository.py
Provider validation registry api/infrastructure/integration_validators/__init__.py
Provider validators api/infrastructure/integration_validators/
aai-cli runtime artifacts api/domains/agents/aai_cli_artifacts.py
Google Workspace runtime artifacts api/domains/agents/gog_artifacts.py
Runtime orchestration api/domains/agents/service.py
Hermes Kubernetes builders api/domains/agents/builders/hermes.py
OpenClaw Kubernetes builders api/domains/agents/builders/openclaw.py
Built-in aai-cli Skills api/domains/agents/aai_cli_skills/
Built-in Skill seeding api/domains/skills/skill_seeder.py
Shared Credential eligibility api/domains/shared_credentials/models.py
Shared Credential lifecycle api/domains/shared_credentials/
Google OAuth reference flow api/domains/integrations/google_oauth/routes.py
UI provider definitions ui/src/features/agents/integrations.ts
Shared credential inputs ui/src/features/agents/components/integration-fields.tsx
Agent response schemas ui/src/features/agents/schemas.ts
Agent create and update mutations ui/src/features/agents/hooks/use-create-agent.ts, use-update-agent.ts
Live validation hook ui/src/features/agents/hooks/use-validate-integration.ts
Integration feature contract docs/features/integrations.md
Backend conventions docs/guidelines/code.md
Web app conventions docs/guidelines/webapp.md
Test conventions docs/guidelines/testing.md
Documentation