AgentOS Extensions API - v1.0.4
    Preparing search index...

    AgentOS Extensions API - v1.0.4

    AgentOS     Frame.dev

    AgentOS Extensions

    Extension source code for AgentOS — tools, channel adapters, integrations, and starter templates.

    CI Status License: Apache 2.0 API Docs npm: registry npm: catalog NVIDIA Inception

    This package contains the actual implementation source code for AgentOS extensions: the Telegram adapter, web-search tool, voice providers, browser automation, channel adapters for 37 platforms, and more. It also ships starter templates (templates/) for creating new extensions from scratch.

    This is NOT a registry. It is the source code that registries catalog. The relationship between the two sibling packages is:

    Package Role
    @framers/agentos-extensions (this package) Implementation source code, manifests, and templates
    @framers/agentos-extensions-registry Catalog/SDK that references this package's metadata and exposes createCuratedManifest()

    Dependency direction: agentos-extensions-registry depends on metadata from this package, not the other way around. Extensions here are self-contained and can be installed individually without the registry.

    All extensions are published to npm under the @framers scope.

    Package Description npm
    @framers/agentos-ext-web-search Multi-provider web search & fact-checking npm
    @framers/agentos-ext-web-browser Browser automation & content extraction npm
    @framers/agentos-ext-web-scraper Progressive scraping with fetch, Playwright, stealth, recipes, and LLM fallback extraction npm
    @framers/agentos-ext-news-search News article search via NewsAPI npm
    @framers/agentos-ext-giphy GIF & sticker search via Giphy API npm
    @framers/agentos-ext-image-search Stock photo search (Pexels, Unsplash, Pixabay) npm
    @framers/agentos-ext-letterboxd Letterboxd movie lookup with review extraction and direct page fallback npm
    @framers/agentos-ext-omdb Movie and TV metadata with IMDB, Rotten Tomatoes, and Metacritic ratings npm
    @framers/agentos-ext-voice-synthesis Text-to-speech via ElevenLabs npm
    @framers/agentos-ext-cli-executor Shell command execution & file management npm
    @framers/agentos-ext-auth JWT authentication & subscription management npm
    @framers/agentos-ext-clearbit Company and person enrichment via Clearbit npm
    @framers/agentos-ext-telegram Telegram Bot API integration npm
    @framers/agentos-ext-wunderbot-feeds Wunderbot feed ingestion + social content pipeline integration npm
    @framers/agentos-ext-telegram-bot Telegram bot communications handler npm
    @framers/agentos-ext-anchor-providers Solana on-chain provenance anchoring npm
    @framers/agentos-ext-tip-ingestion Tip content processing pipeline (published package; not vendored in this workspace) npm
    @framers/agentos-ext-browser-automation Full browser automation (Playwright) — 10 tools npm
    @framers/agentos-ext-deep-research Multi-source research & investigation — 5 tools npm
    @framers/agentos-ext-content-extraction Content extraction (URLs, YouTube, PDF) — 5 tools npm
    @framers/agentos-ext-credential-vault Encrypted credential management — 5 tools npm
    @framers/agentos-ext-document-export Export reports and decks to PDF, DOCX, PPTX, XLSX, and CSV npm
    @framers/agentos-ext-widget-generator Generate self-contained interactive HTML widgets with file management npm
    @framers/agentos-ext-notifications Multi-channel notification router — 3 tools npm
    Package Description npm
    @framers/agentos-ext-channel-telegram Telegram messaging channel (grammY) npm
    @framers/agentos-ext-channel-whatsapp WhatsApp messaging channel (Baileys) npm
    @framers/agentos-ext-channel-discord Discord messaging channel (discord.js) npm
    @framers/agentos-ext-channel-slack Slack messaging channel (Bolt) npm
    @framers/agentos-ext-channel-webchat Built-in WebChat channel (Socket.IO) npm
    @framers/agentos-ext-channel-twitter Twitter/X social channel (twitter-api-v2) npm
    @framers/agentos-ext-channel-instagram Instagram social channel (Graph API) npm
    @framers/agentos-ext-channel-reddit Reddit social channel (snoowrap) npm
    @framers/agentos-ext-channel-youtube YouTube social channel (googleapis) npm
    @framers/agentos-ext-channel-linkedin LinkedIn social channel (Marketing API) npm
    @framers/agentos-ext-channel-facebook Facebook social channel (Meta Graph API) npm
    @framers/agentos-ext-channel-threads Threads social channel (Meta Graph API) npm
    @framers/agentos-ext-channel-bluesky Bluesky social channel (AT Protocol) npm
    @framers/agentos-ext-channel-mastodon Mastodon social channel (federated) npm
    @framers/agentos-ext-channel-farcaster Farcaster social channel (Neynar API) npm
    @framers/agentos-ext-channel-lemmy Lemmy federated social channel npm
    @framers/agentos-ext-channel-google-business Google Business Profile channel npm
    @framers/agentos-ext-channel-blog-publisher Blog publisher (Dev.to, Hashnode, Medium, WordPress) npm
    @framers/agentos-ext-channel-pinterest Pinterest social channel (API v5) npm
    @framers/agentos-ext-channel-tiktok TikTok social channel (API for Business) npm
    @framers/agentos-ext-channel-email Email messaging channel (SMTP or Resend's HTTPS API, IMAP), with a suppression record and unsubscribe tokens on SQL npm

    AgentOS extensions are organized into two tiers with different versioning and release strategies:

    Seven foundational packages live at the monorepo root under packages/agentos-ext-*. These are independently versioned with semantic-release CI/CD and have their own GitHub Actions workflows:

    Package Description
    agentos-ext-code-safety Static code analysis guardrail (injection, XSS, secrets)
    agentos-ext-pii-redaction PII detection & redaction pipeline
    agentos-ext-grounding-guard Claim extraction & source verification
    agentos-ext-ml-classifiers ML-based content classification (toxicity, jailbreak, injection)
    agentos-ext-topicality Topic drift detection & off-topic filtering
    agentos-ext-http-api HTTP API server for AgentOS
    agentos-ext-skills Skill loading & execution tooling

    Each has its own .github/ CI workflow, .releaserc.json, and publishes to npm independently. Version bumps here do not affect curated extension versions.

    The packages inside registry/curated/ are the full extension catalog: channel adapters, integrations, research tools, media tools, and more. Each is versioned on its own, and a push to master that changes a package's shipped files publishes it in the same run (RELEASING.md).

    • Core extensions are safety-critical guardrails and foundational infrastructure. They need independent semver to signal breaking changes without forcing a catalog-wide release. Their CI runs on every PR to the monorepo root.
    • Curated extensions are the broader catalog. The release keeps their interdependencies aligned: when a package's new version leaves a dependent's range on it, the same run raises that range and publishes the dependent.

    The registry/curated/safety/ directory contains stub READMEs pointing to the canonical core packages at the monorepo root. The actual source code for code-safety, pii-redaction, and grounding-guard lives exclusively in packages/agentos-ext-* at the monorepo root. The ml-classifiers and topicality packages still have curated copies with additional modules (ClassifierOrchestrator, TopicDriftTracker, etc.) that have not yet been merged upstream to the root packages.

    agentos-extensions/
    ├── .github/workflows/ # CI, release, TypeDoc pages
    ├── logos/ # Branding assets
    ├── templates/ # Starter templates for new extensions
    │ ├── basic-tool/ # Single tool template
    │ ├── multi-tool/ # Multiple tools template
    │ ├── guardrail/ # Safety/compliance template
    │ └── workflow/ # Multi-step process template
    ├── registry/
    │ ├── curated/ # Official & verified extensions
    │ │ ├── auth/ # Authentication & subscriptions
    │ │ ├── channels/ # Messaging & social channels (37 platform packs)
    │ │ ├── communications/# Telegram bot, notifications
    │ │ ├── integrations/ # External services (Telegram API)
    │ │ ├── media/ # Giphy, image search, voice synthesis
    │ │ ├── meetings/ # Browser-join meeting bot provider (Google Meet, Microsoft Teams)
    │ │ ├── provenance/ # On-chain anchoring (tip-ingestion package is published separately)
    │ │ ├── research/ # Web search, deep research, content extraction
    │ │ ├── safety/ # Stub READMEs -> core packages (see above)
    │ │ ├── system/ # CLI executor, browser automation, credential vault
    │ │ ├── voice/ # Twilio, Telnyx, Plivo voice providers
    │ │ └── productivity/ # Google Calendar, Gmail
    │ └── community/ # Community-contributed extensions
    ├── scripts/ # Registry build & scaffolding tools
    ├── registry.json # generated by pnpm run build; the published catalog ships in the npm package
    ├── pnpm-workspace.yaml # Workspace packages for publishing
    └── typedoc.json # API docs config

    Load all extensions at once via the curated registry:

    npm install @framers/agentos-extensions-registry
    
    import { AgentOS } from '@framers/agentos';
    import { createCuratedManifest } from '@framers/agentos-extensions-registry';

    const manifest = await createCuratedManifest({
    tools: 'all',
    channels: 'none',
    secrets: {
    'serper.apiKey': process.env.SERPER_API_KEY!,
    'giphy.apiKey': process.env.GIPHY_API_KEY!,
    },
    });

    const agentos = new AgentOS();
    await agentos.initialize({ extensionManifest: manifest });

    Only extensions whose npm packages are installed will load — missing packages are skipped silently.

    npm install @framers/agentos-ext-web-search
    
    import { AgentOS } from '@framers/agentos';
    import webSearch from '@framers/agentos-ext-web-search';

    const agentos = new AgentOS();
    await agentos.initialize({
    extensionManifest: {
    packs: [{
    factory: () => webSearch({ /* config */ })
    }]
    }
    });

    The extension surface is dependency-injected at four layers. Each layer is opt-in by default, so a host that installs five extensions does not pay the cost of the other 95, and an extension that needs a 110MB NER model does not load it until the first call.

    Every extension is its own npm package. Nothing is imported until you npm install it. The @framers/agentos-extensions-registry SDK depends on the extension packages as peerDependenciesMeta.optional, so installing the registry alone gives you the catalog metadata without pulling any extension source. Add @framers/agentos-ext-pii-redaction to your package.json and the registry sees it; remove it and the registry drops it on the next manifest build.

    createCuratedManifest() calls import.meta.resolve() on every catalog entry before adding it to the manifest. If the resolution throws, the entry is omitted. The runtime never sees it. There is no error, no warning, no missing-module crash. This is the difference between a catalog (metadata) and a registry that only emits packs you can actually run.

    // Even if you ask for `tools: 'all'`, only installed packages reach the runtime.
    const manifest = await createCuratedManifest({ tools: 'all' });
    // → manifest.packs contains only @framers/agentos-ext-* packages found on disk.

    Inside a pack, each descriptor (a single tool, guardrail, channel, or workflow) can declare requiredSecrets. Before activation, ExtensionManager checks whether each non-optional secret is resolvable from the secret store, the pack options, or the environment. Missing a secret? The descriptor is skipped and the rest of the pack still activates. Optional secrets unlock optional features (like the PII redaction extension's LLM-judge tier) without making them required.

    // pii-redaction declares its LLM judge as an optional dependency.
    {
    id: 'pii_judge_resolver',
    kind: 'tool',
    requiredSecrets: [{ id: 'anthropic.apiKey', optional: true }],
    // ...
    }
    // No ANTHROPIC_API_KEY in env? The judge is skipped, the rest of the pack works.

    ML models, embedding indexes, ONNX runtimes, NER pipelines, and database pools are not loaded at activation. They are registered as factories and only constructed on the first call that needs them. The same instance is shared across descriptors in the same pack and (with a namespaced key) across packs.

    async onActivate(ctx) {
    // The 110MB BERT NER model. Not loaded yet.
    const nerModel = await ctx.services.getOrCreate('pii:ner-model', async () => {
    const { NerModel } = await import('./NerModel.js');
    return NerModel.load();
    });
    this.scanTool.setNerModel(nerModel);
    this.streamingGuardrail.setNerModel(nerModel);
    }

    The import('./NerModel.js') is a dynamic import: the model file itself does not enter the module graph until something asks for the service. First call pays the load cost; subsequent calls hit the cache. Tear-down releases everything via the registry's lifecycle.

    A host installing @framers/agentos-ext-pii-redaction:

    1. Install. npm install @framers/agentos-ext-pii-redaction @framers/agentos-extensions-registry @framers/agentos. Nothing else.
    2. Manifest build. createCuratedManifest({ tools: 'all' }) resolves only the installed PII pack and emits a single-pack manifest.
    3. Activation. ExtensionManager.loadManifest() runs pack.onActivate(ctx), which registers a pii:ner-model factory in SharedServiceRegistry. The model file is not loaded.
    4. Descriptor registration. Two tool descriptors (pii_scan, pii_redact) and one guardrail descriptor land in the kind-specific registries. The guardrail descriptor's config.canSanitize = true and config.evaluateStreamingChunks = true flag it for the two-phase dispatcher.
    5. First request. A user message hits the input pipeline. The two-phase dispatcher runs Phase 1 sequentially: the PII guardrail's evaluateInput() fires, calls into the NER pipeline, and the model loads on this first call. Subsequent requests hit the cached model.
    6. Streaming output. As the model generates a response, each TEXT_DELTA chunk passes through the guardrail's evaluateOutput(). The dispatcher returns SANITIZE results with redacted text deterministically (Phase 1 chains sequentially), then runs all Phase 2 classifiers in parallel for any remaining checks.
    7. Tear-down. pack.onDeactivate(ctx) runs in reverse order on shutdown. The shared service registry releases the model.

    Same pattern for the four other guardrail packs: @framers/agentos-ext-ml-classifiers lazy-loads ONNX BERT models, @framers/agentos-ext-grounding-guard lazy-loads the NLI pipeline, @framers/agentos-ext-topicality lazy-loads embeddings, @framers/agentos-ext-code-safety is regex-only and pays no load cost.

    This is the same auto-discovery surface that runtime-forged tools join: an agent that invents a function in session N can promote it via SkillExporter into a SKILL.md that the registry picks up on the next process start. Forging grows the surface mid-run; auto-discovery ships it as a first-class capability.

    For the dispatcher mechanics (Phase 1 sanitizers, Phase 2 parallel classifiers, worst-action aggregation, mid-stream override), see Guardrails. For lifecycle internals, see Extension Loading.

    createCuratedManifest() accepts:

    Option Type Default Description
    tools string[] | 'all' | 'none' 'all' Which tool extensions to enable. Pass an array of names (e.g. ['web-search', 'giphy']) to selectively load.
    channels ChannelPlatform[] | 'all' | 'none' 'all' Which messaging channels to enable.
    secrets Record<string, string> {} API keys and tokens. Falls back to environment variables.
    logger RegistryLogger console Custom logger (info, warn, error, debug methods).
    basePriority number 0 Base priority for all extensions.
    overrides Record<string, ExtensionOverrideConfig> — Per-extension overrides for enabled, priority, and options.
    Secret ID Environment Variable Extension
    serper.apiKey SERPER_API_KEY web-search
    serpapi.apiKey SERPAPI_API_KEY web-search
    brave.apiKey BRAVE_API_KEY web-search
    giphy.apiKey GIPHY_API_KEY giphy
    omdb.apiKey OMDB_API_KEY omdb
    clearbit.apiKey CLEARBIT_API_KEY clearbit
    elevenlabs.apiKey ELEVENLABS_API_KEY voice-synthesis
    pexels.apiKey PEXELS_API_KEY image-search
    unsplash.apiKey UNSPLASH_ACCESS_KEY image-search
    pixabay.apiKey PIXABAY_API_KEY image-search
    newsapi.apiKey NEWSAPI_API_KEY news-search
    telegram.botToken TELEGRAM_BOT_TOKEN channel-telegram
    discord.botToken DISCORD_BOT_TOKEN channel-discord
    slack.botToken SLACK_BOT_TOKEN channel-slack
    slack.appToken SLACK_APP_TOKEN channel-slack
    twitter.bearerToken TWITTER_BEARER_TOKEN channel-twitter
    twitter.apiKey TWITTER_API_KEY channel-twitter
    twitter.apiSecret TWITTER_API_SECRET channel-twitter
    twitter.accessToken TWITTER_ACCESS_TOKEN channel-twitter
    twitter.accessSecret TWITTER_ACCESS_SECRET channel-twitter
    instagram.accessToken INSTAGRAM_ACCESS_TOKEN channel-instagram
    linkedin.accessToken LINKEDIN_ACCESS_TOKEN channel-linkedin
    facebook.accessToken FACEBOOK_ACCESS_TOKEN channel-facebook
    threads.accessToken THREADS_ACCESS_TOKEN channel-threads
    bluesky.handle BLUESKY_HANDLE channel-bluesky
    bluesky.appPassword BLUESKY_APP_PASSWORD channel-bluesky
    mastodon.accessToken MASTODON_ACCESS_TOKEN channel-mastodon
    farcaster.neynarApiKey FARCASTER_NEYNAR_API_KEY channel-farcaster
    farcaster.signerUuid FARCASTER_SIGNER_UUID channel-farcaster
    lemmy.instanceUrl LEMMY_INSTANCE_URL channel-lemmy
    lemmy.username LEMMY_USERNAME channel-lemmy
    lemmy.password LEMMY_PASSWORD channel-lemmy
    google.accessToken GOOGLE_ACCESS_TOKEN channel-google-business
    reddit.clientId REDDIT_CLIENT_ID channel-reddit
    reddit.clientSecret REDDIT_CLIENT_SECRET channel-reddit
    reddit.username REDDIT_USERNAME channel-reddit
    reddit.password REDDIT_PASSWORD channel-reddit
    youtube.apiKey YOUTUBE_API_KEY channel-youtube
    pinterest.accessToken PINTEREST_ACCESS_TOKEN channel-pinterest
    tiktok.accessToken TIKTOK_ACCESS_TOKEN channel-tiktok
    email.smtpHost SMTP_HOST channel-email
    email.smtpUser SMTP_USER channel-email
    email.smtpPassword SMTP_PASSWORD channel-email
    email.resendApiKey RESEND_API_KEY channel-email
    // Only web search and giphy, no channels
    const manifest = await createCuratedManifest({
    tools: ['web-search', 'giphy'],
    channels: 'none',
    });

    // Only Telegram and Discord channels, all tools
    const manifest = await createCuratedManifest({
    channels: ['telegram', 'discord'],
    tools: 'all',
    secrets: {
    'telegram.botToken': process.env.TELEGRAM_BOT_TOKEN!,
    'discord.botToken': process.env.DISCORD_BOT_TOKEN!,
    },
    });

    // Override specific extension options
    const manifest = await createCuratedManifest({
    tools: 'all',
    channels: 'none',
    overrides: {
    'web-search': { priority: 10 },
    'cli-executor': { enabled: false },
    },
    });
    # Copy the template, then give the copy its name, its role and its own CHANGELOG.md,
    # as CONTRIBUTING.md's "Adding an extension pack" says
    cp -r templates/basic-tool registry/curated/category/my-extension
    cd registry/curated/category/my-extension
    pnpm install
    pnpm run dev

    A push to master publishes every package whose shipped files changed since its newest version on npm, from the tarball CI built and tested, and tags and releases each version on GitHub. New versions publish from GitHub Actions through npm trusted publishing, with a provenance statement; a new package's first version publishes through the token, as RELEASING.md describes. Nobody writes a changeset or a release note: the merged pull request's title is the note. See RELEASING.md for the full workflow.

    # 1. Change one or more extensions on a branch, and open a pull request titled in
    # the Conventional Commits form: fix(web-search): ..., or feat(web-search)!: ...
    # for a change that breaks users: a minor in place of a patch below 1.0.0;
    # at 1.0.0 or above CI refuses the mark until package.json names the next major

    # 2. Read the summary of CI's step "The packages this push would publish":
    # each package the merge publishes, with its version and the reason

    # 3. Merge it: the push to master publishes those packages to npm, tags each
    # version <name>@<version> and makes its GitHub release

    Each extension is versioned and published independently. A change to web-search does not bump telegram.

    Type Pattern Example
    Extension @framers/agentos-ext-{name} @framers/agentos-ext-web-search
    Template @framers/agentos-template-{type} @framers/agentos-template-basic-tool

    All extensions get free CI/CD via GitHub Actions:

    • CI (ci.yml): plans what the push would publish (scripts/release-plan.mjs), builds the AgentOS core and every pack, runs the release-script tests and each pack's tests, and runs the pack guard on the planned packages, on every pull request
    • Release (release.yml): runs CI on a push to master, then publishes the tarballs CI tested for the packages the push changed, tags each version, makes its GitHub release, and writes the images' version tags
    • TypeDoc (pages-typedoc.yml): API docs deployed to framerslab.github.io/agentos-extensions on a push to master, one deploy at a time: a deploy that has started runs to the end, and a push that lands during it waits, the last push to come in replacing any earlier one still waiting
    • Lockfile (lockfile.yml): resolves the workspace's dependency ranges and offers pnpm-lock.yaml as an artifact to commit, run by hand on a branch whose package.json files changed
    • Meeting bot image (meeting-bot-image.yml): builds the browser meeting bot's container image and runs its lifecycle test on every pull request that touches registry/curated/meetings/browser/, and pushes the image to GHCR from master; the bot's nightly real-join check (nightly-real-join.yml) runs daily and by hand, and its capacity measurement on a worker (measure-meeting-bots.yml) by hand only, as the pack's README describes
    • Document parser image (document-parser-image.yml): builds the document parser's container image and runs its lifecycle test on a pull request that touches registry/curated/tools/document-parser/ or pnpm-lock.yaml, once it is ready for review, and on a push to master that touches the pack, which also pushes the tested image to GHCR as ghcr.io/framerslab/agentos-document-parser:sha-<commit>; the release workflow tags a released version's image :<version>, as the release guide and the pack's README describe. document-parser.yml runs the pack's tests on Node 24, beside CI's Node 22, when a pull request or a push to master touches the pack, pnpm-lock.yaml or pnpm-workspace.yaml
    • Dependabot: weekly dependency updates. dependabot-auto-merge.yml labels an npm minor or patch update landing, and posts one comment for its head commit naming the guards that passed, when CI's build check and the links check have succeeded on that commit, no other workflow check there is pending or failed (skipped and neutral count as passed), every commit is Dependabot's, its review threads are settled and ten minutes have passed since its last push. It never merges: a labelled update lands once its review comments on GitHub are read, those that name a failing input fixed and the rest answered, and its threads resolved. It decides again when a CI or Links run of the update is requested, starts or finishes, when a review is submitted or a comment is made on its diff, and every hour; when a push moves the head or a guard fails, it takes off a label it added, and a label a maintainer added, took off or put back stays. A thread resolved or reopened sends no event a workflow can take, so the next of those runs decides it; a landing waits for every thread to be resolved whatever the label says. Major updates, GitHub Actions updates, and a pull request whose head commit message names a different version than its title (left from an older update after a rebase) wait for a maintainer. The decision is scripts/dependabot-merge-lib.mjs. Dependabot updates pnpm-lock.yaml with pnpm's minimumReleaseAge at three days; pnpm-workspace.yaml exempts @framers/*, the family whose pins the weekly bump (bump-framers-deps.yml) moves to the newest release, and the bump runs Dependabot's update before it opens its pull request
    • TypeScript with strict mode
    • 80% test coverage

    • Apache 2.0 license
    • No hardcoded secrets
    • Professional code review
    • Performance benchmarks
    • Integration tests
    • Migration guides
    Guide What
    Contributing Development setup, adding a pack, commit messages and releases, pull request rules, review threads, contribution licensing
    Release guide What a push to master publishes, and at which version
    Agent instructions Commands and conventions for coding agents
    Maintainers Who reviews and merges changes
    Code of Conduct Community standards
    Security Policy Reporting vulnerabilities privately
    Support Where to get help

    All extensions in this repository are Apache 2.0 licensed.


    AgentOS     Frame.dev

    Built by Frame
    Contact: team@frame.dev