## Summary
Live PostHog (2026-09-15): since auto-setup was restored on Sep 14, 704
installer-triggered `composio setup` runs found no host 397 times (56%);
of the 316 that found one, 282 installed the plugin (89%). The gap is
host detection, and today a real absence is indistinguishable from a
PATH miss. Manual `composio setup` over 30 days: 888 succeeded, 626
failed, and `CLI_SETUP_FAILED` only carried `error_name`. 103 of those
failures (`yes=false, target=auto, stdout_is_tty=false`) are agents
following the daily hint text into "Non-interactive setup requires
`--yes`". No event said whether the CLI was running inside Claude Code
or Codex at all.
Event contract (metrics.composio.io is being built against these names):
- Every CLI event gains `agent_host_env: 'claude' | 'codex' | 'none'`,
derived from `CLAUDECODE` / `CODEX_THREAD_ID` / `CODEX_SANDBOX`.
- `CLI_SETUP_HOST_DETECTED` gains `host_config_dir_present` and
`host_binary_in_known_paths` when `available=false`
(`$CLAUDE_CONFIG_DIR`/`~/.claude`, `$CODEX_HOME`/`~/.codex`;
`~/.claude/local`, `~/.local/bin`, `~/.npm-global/bin`,
`/usr/local/bin`, `/opt/homebrew/bin`). Both omitted when the host is
detected.
- New `CLI_PLUGIN_HINT_SHOWN` (journey stage `setup`) with `source`,
`invocation_origin`, `cli_version`, `command_path`, `agent_host`,
emitted once per printed hint and never on suppression.
- `CLI_SETUP_FAILED` gains `failure_reason_code`:
`all_requires_both_hosts | unsupported_host | target_not_installed |
no_host_detected | non_interactive_requires_yes | marketplace_conflict |
unknown`, carried on `SetupCommandError.reasonCode`.
- Hint text is now `Tip: running under <host> without the Composio
plugin — 'composio setup --yes' installs it.`
Structural notes: `agent_host_env` is stamped in `trackCliEventEffect`
(`analytics/dispatch.ts`) next to `org_id`, so every enqueued envelope
carries it with no module state or bootstrap hook. `SetupCommandError`
and `SetupFailureReasonCode` live in the leaf module
`services/setup-command-error.ts` (imports only `effect`) so
`analytics/events.ts` can use `instanceof` without a cycle;
`setup.cmd.ts` keeps its original `setupCommandError` helper with the
reason code as a third argument, and the two validate-stage failures in
`services/setup.ts` (`marketplace_conflict`, `target_not_installed`) are
raised as `SetupCommandError` directly. The raw host-env read,
`detectPluginHost`, and the known-path install probe live in
`services/agent-host-env.ts`, shared by `dispatch.ts`, `plugin-hint.ts`,
and `setup.ts`. `CLI_SETUP_HOST_DETECTED` passes the two presence
booleans straight through; `setup.ts` only probes an undetected host.
The hint tracks `CLI_PLUGIN_HINT_SHOWN` right where it prints.
## Validation
- `pnpm --filter @composio/cli` `pnpm run test` (validate:skills,
validate:boundaries, vitest): 132 files, 1374 passed, 1 skipped.
- `pnpm run typecheck` (src + test): clean.
- `oxlint` on the 14 changed TS files: clean. `prettier --check` on
changed files: clean. `git diff --check`: clean.
- `pnpm validate:agent-skills` and `pnpm validate:skill-routing`: pass
(skill reference doc changed).
- Manual, built binary with isolated
`HOME`/`COMPOSIO_CACHE_DIR`/`CLAUDE_CONFIG_DIR` and a dummy PostHog key
pointed at a dead local port: `CLAUDECODE=1 composio whoami
--telemetry-debug` printed the new hint once and enqueued
`CLI_PLUGIN_HINT_SHOWN` (`command_path: whoami`, `agent_host: claude`)
plus `CLI_COMMAND_INVOKED`/`SUCCEEDED`, all with `agent_host_env:
claude`; a second run printed no hint and no hint event.
`PATH=/usr/bin:/bin composio setup --target codex --yes
--telemetry-debug` enqueued `CLI_SETUP_HOST_DETECTED` with `available:
false, host_config_dir_present: true, host_binary_in_known_paths: false`
and `CLI_SETUP_FAILED` with `failure_reason_code: target_not_installed`.
Re-run after each simplification pass with identical output; with the
host markers unset the same events carry `agent_host_env: none`.
## Known verification limitations
- No changeset: `@composio/cli` is ignored by Changesets per
`ts/AGENTS.md`; the note went into `ts/packages/cli/CHANGELOG.md`
instead.
- Docker CLI E2E not run; no binary output contract changed except the
hint line.
- `host_binary_in_known_paths` checks two absolute directories, so the
"absent everywhere" test asserts a boolean rather than `false` to stay
machine-independent.
Not included: any change to `composio setup` help text or to the
dashboard side.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The setup-plugins suite pins the recovery command printed when native
plugin inspection fails. setup remediation messages now carry --yes so
non-interactive agents get a command that completes, so the pinned
'composio setup --target claude' fragment became
'composio setup --yes --target claude'. Matches the exact stderr CI
reported on the failing scratch run.
validateInitialState hardcodes operation 'setup' in its SetupCommandError
while its only caller, the exported inspectSetupTargets, already threads
options.operation for wording. Uninstall skips validation today
(allowMarketplaceConflict: uninstall), so nothing mislabels now, but any
future uninstall caller that validates would get operation 'setup' and the
wrong failure_reason_code in telemetry. Pass options.operation ?? 'setup'
through and use it in both constructions.
The plugin hint learned to say 'composio setup --yes', but the error
messages an agent hits next still suggested bare reruns that deterministically
fail again with non_interactive_requires_yes in a non-TTY shell - the same
103-failure loop this PR set out to fix. Add --yes to the targeted-missing and
no-host messages in setup.cmd, the validate-stage target/marketplace messages,
the verify-stage messages, and the shared recovery-hint command; the most
conflicting case also walked agents through the destructive marketplace
remove before a rerun that could not succeed.
Interactive users can drop the flag; agents get a command that actually
completes. Adds rerun-message assertions for the three reachable failure
paths.
showPluginHint claims the 24h stamp before printing, so a print that did
not succeed left the stamp standing: the hint was never delivered yet both
the hint and CLI_PLUGIN_HINT_SHOWN stayed muted for the full interval.
Capture the print with Effect.exit and remove the just-created stamp on
any non-success exit so the next invocation can retry.
Tracking stays best-effort by contract: trackCliEventEffect never fails,
so a delivered hint with a lost event is accepted and does not un-claim.
resolvePluginHintConfig inlined the same env-override-else-~/.claude and
~/.codex fallback expressions that agent-host-env.ts now owns, leaving the
host-dir default written three times across two files. Use the shared
helper for both file paths and drop the now-unused NodeOs yield.
The 'preserves nonblank path overrides' test asserted verbatim pass-through
of relative overrides, which was the cwd dependence the probe hardening
removes. It now pins absolute overrides preserved as-is plus a new case
asserting relative overrides anchor to the home directory.
CLAUDE_CONFIG_DIR / CODEX_HOME were passed verbatim to the install probe,
so a relative override resolved against the process cwd (making
host_config_dir_present depend on where composio was invoked) and a plain
file at the config path counted as 'present'. Resolve overrides against
the home directory - matching how the known-binary list already resolves -
and probe with stat so presence means an actual directory. Unreadable
paths report false instead of failing the probe.
rawHostEnvironment re-implemented by hand what src/services/config.ts already
provides: a fresh unprefixed ConfigProvider.fromEnv() per execution with
orDie error handling. Build the five host keys as one Config.all and load
them via loadHostConfig, deleting the bespoke readOptionalEnv helper and the
per-call provideServiceEffect override. The fromEnv snapshot rationale now
lives only in config.ts's documented getBaseConfigProvider.
Behavior is unchanged: same live-env semantics (vi.stubEnv stays observable),
same blank-marker handling, same orDie on config failures.
## Summary
Rebuilds the docs social preview (`/api/og`) as one shared shell with a
slot per section, on the docs dark surface.
- **Shell:** dark ground with a faded pixel-grid background, Composio
wordmark top-left, mono uppercase section eyebrow top-right, centered
content. `theme=light` renders the flat light surface.
- **Docs:** balanced title plus description.
- **Toolkits:** Composio mark and toolkit logo in linked tiles, "<Name>
Toolkit" title, description. No tile when there is no logo. Logos load
only from `logos.composio.dev` / `assets.composio.dev` over https and
use the CDN's `theme=dark` variant.
- **API reference:** REST API pill with the version label.
- **Changelog:** date shown once as an eyebrow; multi-entry days use "N
updates" as the title so the date is not repeated.
- **Home:** headline with brand-blue accent and a description that
counts apps from the live catalog label.
Type is Geist Sans / Geist Mono, vendored as TTF with the OFL because
Satori cannot read the site's woff2 files. The wordmark and mark are
sliced from the existing logo SVGs; no new brand asset was added. Fonts,
logos, and the background are added to `outputFileTracingIncludes` so
the route ships them on Vercel.
`getOgImageUrl` now emits `section` and optional `logo`, `date`, and
`version` params; the toolkit, changelog, and reference pages pass them.
## Before / after
Before: charcoal card, orange accent, default sans-serif, identical for
every section.
After (dark by default):
| Home | Toolkit | Reference | Changelog |
| --- | --- | --- | --- |
| headline + description | mark ⟶ logo, title, description | pill +
version, title | date eyebrow, title |
## Notes
- Output PNGs are ~1.5 MB each because of the photographic background; a
flatter texture would bring that down if it matters.
- Typecheck errors in this branch (`LayoutProps`, `PageProps`,
`docs-index`) predate the change and come from missing generated types
without a build.
- The 8 failing static tests are in `kb-update-workflow.test.ts` and are
unrelated.
## Test plan
- [x] `bun test tests/static/og-image.test.ts` — 6 tests: every section
renders a 1200×630 PNG, URL builder forwards params, logo host
allowlist, theme default and override
- [x] Rendered every variant locally and reviewed the PNGs
- [ ] Verify a deployed preview URL renders
`/api/og?section=toolkits&title=GitHub&logo=https%3A%2F%2Flogos.composio.dev%2Fapi%2Fgithub`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reference pages fall back to the page title for their meta description.
Pass only a real description to the card, and have the route drop any
description that merely repeats the title.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- only catalog toolkit pages ("<Name> - Composio Toolkit") get the
"<Name> Toolkit" card title; the toolkits index and MDX guides keep
their own titles instead of "Toolkits Toolkit"
- the home card description is a shared constant used by the URL
builder, so the /docs index page and the root layout produce the same
image URL and the live app count is never dropped
- update the integration expectation from ?variant=home to the new
section=home URL
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Rebuild the /api/og route around a shared shell with a slot per section
(docs, toolkits, API reference, changelog, home) on the docs dark surface,
with a light variant behind theme=light.
- Geist Sans / Mono vendored as TTF (Satori cannot read the site's woff2)
- Composio wordmark and mark sliced from the existing logo SVGs
- toolkit cards link the Composio mark to the toolkit logo; logos only
load from Composio hosts and use the CDN's dark variant
- reference cards show a REST API pill and version; changelog cards show
the date once as an eyebrow
- home card counts apps from the live catalog label
- balanced title and description wrapping, faded pixel-grid background
- assets traced for the build via outputFileTracingIncludes
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This PR:
- builds on top of https://github.com/ComposioHQ/composio/pull/4475
- stores `composio execute` responses over 40,000 UTF-8 bytes in a
session file, replacing the check for more than 10,000 o200k tokens
added in https://github.com/ComposioHQ/composio/pull/2979
- keeps `tokenCount` in the stored-output summary as an estimate
(`ceil(sizeBytes / 4)`), adds `sizeBytes`, and logs `Response stored in
<path> (N KB, ~M tokens)`
- removes `js-tiktoken` and the `execute-output-encoder-runtime`
companion from https://github.com/ComposioHQ/composio/pull/4469, with
its tsdown entry, build-guard and startup-import patterns, upgrade
fixture entry, and the encoder fallback and special-token tests
- keeps `execute-output-encoder-runtime.mjs` in the three uninstall
lists, so installs that shipped it can still remove the leftover file
- behavior change: a 10–40KB response of more than 10,000 tokens now
prints inline, and dense non-ASCII output (about 1–2 bytes per token)
can print inline at up to ~20,000 tokens
- verified: CLI typecheck, full CLI vitest (131 files, 1343 passed, 1
skipped), `test/release-workflow.test.ts`, and
`build-companion-modules.ts` with the executable graph check
## Context
Nothing reads `tokenCount` as a number: it appears only in the
stored-output summary, the two log lines, session history, and a debug
log in `run-helpers-runtime.ts`. o200k is not the tokenizer of the model
that reads the output, so the exact count only moved the cutoff. It cost
the 2.3MB rank table, ~330ms after large tool calls (measured in #4469,
not re-measured here), and a separately shipped companion whose absence
made `composio run` require a repair download after an upgrade.
Atomic Agent is a local-first AI agent (CLI and TUI) that ships a
built-in Composio integration. It connects to the hosted tool router
over Streamable HTTP MCP, so Composio tools are registered at startup as
`mcp.composio.*`.
This adds it to the Composio Connect client list alongside the other
terminal agents.
**Changes**
- New `ConnectClientOption` entry in
`docs/content/docs/composio-connect.mdx`
- Client icon at `docs/public/images/clients/atomic-agent.svg`
- `atomic agent` appended to the page keywords
The setup steps document the agent's own flow (Integrations tab, or
`COMPOSIO_API_KEY` in its `.env`) rather than a CLI install, since the
integration is native.
Repo: https://github.com/AtomicBot-ai/atomic-agent
Happy to adjust the wording, the description, or the placement, or to
close this if you would rather add the entry yourselves.
This PR:
- fixes the raw `:raises ...:` reST directives leaking into the
generated Python SDK reference, flagged by [Greptile on the
auto-generated docs
PR](https://github.com/ComposioHQ/composio/pull/4479#discussion_r4004672537)
- teaches `python/scripts/generate-docs.py` to parse `:raises Exc:`
docstring fields (plus `:raise`/`:except`/`:throws` synonyms) into a
structured `**Raises**` section, with indented continuation-line support
- normalizes inline reST in all rendered prose:
`:class:`/`:func:`/`:meth:`/`:mod:` roles honor `~` short-name
semantics, and double-backtick literals become single-backtick inline
code
- regenerates `docs/content/reference/sdk-reference/python/` pages
- adds regression tests for raises parsing and reST normalization in
`python/tests/test_generate_docs.py`
## Context
The Python SDK reference pages are generated by
`python/scripts/generate-docs.py` (workflow: `generate-sdk-docs.yml`),
so the fix lives in the generator rather than the MDX — hand-edits would
be overwritten by the next auto-regen PR. Unrecognized `:raises` lines
previously fell through into the `:returns:` description text.
## Summary
`PusherService.subscribe` binds `pusher:subscription_error` after the
Pusher subscription call returns. `pusher-js` dispatches this event
asynchronously without catching listener exceptions, so authentication,
permission, server, or network subscription failures could escape as
uncaught exceptions in Node applications.
Fixes#4445
## Changes
- Log asynchronous Pusher subscription errors at the SDK error boundary
instead of throwing from the event callback.
- Add regression coverage that emits `pusher:subscription_error` after
`subscribe()` resolves and verifies that it does not throw.
- Add a patch changeset for the fixed `@composio/core`/`@composio/slim`
package group.
## Type of change
- [x] Bug fix
- [ ] New feature
- [ ] Refactor/Chore
- [ ] Documentation
- [ ] Breaking change
## How Has This Been Tested?
- Node `v24.17.0` / pnpm `11.8.0`
- `pnpm --filter @composio/core exec vitest run
test/services/pusher.test.ts test/utils/pusher.test.ts` — 2 files, 5
tests passed
- `pnpm --filter @composio/core test` — 55 test files passed; 1,289
tests passed and 2 existing tests reported expected failures; command
exited successfully
- `pnpm --filter @composio/core typecheck`
- `pnpm lint` — passed with existing repository warnings
- `pnpm validate:changesets`
- `pusher-js` `v8.6.0` runtime probe confirmed that an exception thrown
from a `pusher:subscription_error` listener reaches Node's
`uncaughtException` handler; the regression test verifies the SDK
callback no longer throws.
## Screenshots (if applicable)
Not applicable.
## Checklist
- [x] I have read the Code of Conduct and this PR adheres to it
- [x] I ran linters/tests locally and they passed
- [x] I updated documentation as needed
- [x] I added tests or explain why not applicable
- [x] I added a changeset if this change affects published packages
## Additional context
This patch is intentionally limited to the live `PusherService` path.
XHR timeout handling is a separate concern and is not included here. The
older unreferenced `PusherUtils` helper is unchanged to keep this fix
scoped to the path used by `Triggers`.
## Summary
Fixes#4147.
Updates stale OpenAI Assistants API examples to use the Responses API,
matching OpenAI's current migration guidance that the Assistants API is
deprecated and shuts down on August 26, 2026.
## Changes
- Rewrote the Python OpenAI demo to use `OpenAIResponsesProvider` and
`client.responses.create`.
- Replaced the TypeScript provider docs' Assistants/Threads examples
with a Responses API tool-call loop.
- Removed deprecated `openai.beta.assistants` / `openai.beta.threads`
references from the targeted demo and docs page.
## Type of change
- [ ] Bug fix
- [ ] New feature
- [ ] Refactor/Chore
- [x] Documentation
- [ ] Breaking change
## How Has This Been Tested?
- `python -m py_compile
python/providers/openai/openai_assistant_demo.py` (passed)
- `rg -n
"openai\.beta|Assistants|assistants|threads|waitAndHandleAssistant|AssistantStream"
python/providers/openai/openai_assistant_demo.py
ts/docs/providers/openai.md` (no matches)
- `git diff --check` (passed)
## Screenshots (if applicable)
N/A
## Checklist
- [x] I have read the Code of Conduct and this PR adheres to it
- [x] I ran linters/tests locally and they passed
- [x] I updated documentation as needed
- [ ] I added tests or explain why not applicable (not applicable;
docs/demo cleanup only)
- [x] I added a changeset if this change affects published packages (not
applicable; docs/demo only)
## Additional context
The OpenAI platform docs mark the Assistants API as deprecated and
direct new agentic flows to the Responses API. This PR keeps Composio's
public OpenAI examples aligned with that path.
pysher performs the channel-auth request synchronously inside
pusher.subscribe(), so an auth rejection raised on the websocket thread
before pusher:subscription_error could ever be bound or fire. The new
on_subscription_error callback was skipped for exactly the failures it
documents, and callers waited out the full connect timeout for a
generic ComposioSDKTimeoutError.
- _connection_handler catches subscribe() failures and routes them
through the error path (log + callback with {'error': ...}).
- The failure is recorded on the subscription and the connect() wait
loop re-raises it on its next poll, so subscribe() fails promptly
with the underlying error and still tears down the pusher.
- Update the Python reference, guide, and docstrings; add regression
coverage for the handler routing, the failure record, and fast-fail.
Addresses the Cursor Bugbot comment on triggers.py:1023.
trackCliEventEffect reads the host environment and adds agent_host_env to
every enqueued envelope, so there is no module-level state and no bootstrap
hook. SetupCommandError lives in a leaf module so analytics/events.ts can
use instanceof without a cycle, setup.cmd.ts keeps its original helper
shape with the reason code as a third argument, and plugin-hint.ts keeps
its original config resolution. Event names and properties are unchanged.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Keep SetupCommandError in services/setup.ts with its reasonCode, read the
code structurally in analytics/events.ts, raise the two validate-stage
failures as SetupCommandError directly instead of a second reason-code
layer, fold the host install probe into agent-host-env.ts, pass the host
presence booleans straight through on CLI_SETUP_HOST_DETECTED, and track
the plugin hint where it is printed. Event names and properties are
unchanged.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Every CLI event now carries agent_host_env (claude, codex, none) read from
the host environment. CLI_SETUP_HOST_DETECTED reports whether the host's
config dir and a binary at a known install location exist when the host is
not detected, CLI_SETUP_FAILED carries a failure_reason_code read from
SetupCommandError, and the daily plugin hint emits CLI_PLUGIN_HINT_SHOWN
once per printed line and points at `composio setup --yes` so agents no
longer run into the non-interactive --yes failure.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
## Summary
Adds canonical guidance for common Composio product-integration
decisions and makes the main paths easy to find from the Knowledge Base
homepage. This PR is independent of #4258 and #4277 and targets `next`
directly.
## Changes
- Add guides for the Composio skill, consumer-agent architecture,
B2B-agent architecture, and moving from prototype to production
- Expand the white-labeling guide with a minimal setup path and FAQ
- Add five Start here cards to `/kb`, before support topics and toolkit
browsing
- Update OAuth callback examples and add relevant sidebar and quickstart
cross-links
## Type of change
- [x] Documentation
## How Has This Been Tested?
- `bun test tests/static/` (528 passed)
- `bun run lint:links`
- `bun run types:check`
- `bun run lint`
- `bun run build`
## Checklist
- [x] I have read the Code of Conduct and this PR adheres to it
- [x] I ran linters/tests locally and they passed
- [x] I updated documentation and structural homepage coverage
- [x] No changeset is required for docs-only changes
The containment around the subscription error callback only caught
synchronous throws. TypeScript accepts an async function against a
void-returning callback type, so a rejected promise escaped as an
unhandled rejection after subscribe() resolved - on modern Node that
can terminate the process, the same failure class this PR contains.
Route the callback result through Promise.resolve(...).catch so both
sync throws and async rejections land in the same contained logger
path, and add a regression test for the async case.
Addresses greptile-apps P1 and Cursor Bugbot review comments.
Mirror the TypeScript API surface from the previous commit:
- Triggers.subscribe accepts an optional on_subscription_error callback,
threaded through _SubcriptionBuilder.connect and bound to pysher's
pusher:subscription_error event on the trigger channel.
- TriggerSubscription._handle_subscription_error logs the failure at the
SDK boundary and invokes the callback with the parsed payload (or
{'raw': frame} for malformed frames); callback exceptions are
contained and logged so a faulty handler cannot tear down pysher's
dispatch thread.
- The parameter is optional; existing callers are unaffected.
- Update the Python triggers reference and the subscribing-to-events
guide.
Python never bound pusher:subscription_error at all, so subscription
failures after connect() were previously invisible to hosts.
The handleAssistantMessage, waitAndHandleAssistantStreamToolCalls, and
waitAndHandleAssistantToolCalls methods target the OpenAI Assistants
API, which shuts down on August 26, 2026. Add a deprecation warning
pointing new flows at OpenAIResponsesProvider.
- Use gpt-5 in the Responses API examples; gpt-4 predates the Responses
API and the repo's other Responses examples use gpt-5.
- Print response.output_text instead of indexing into content items,
which assumes non-empty message content.
- Add the OpenAIResponsesProvider type surface to the Type Definitions
section, which previously only showed the chat completions provider.
- Use gpt-5 like the rest of the repo's examples (getting-started.md,
the pre-PR demo) instead of the gpt-5.2 id used nowhere else.
- Print response.output_text instead of dumping the raw Response object,
matching the final line of the demo.
- PusherService.subscribe and Triggers.subscribe accept an optional
onSubscriptionError callback invoked with the raw pusher
pusher:subscription_error payload, giving hosts a programmatic signal
for post-resolution subscription failures (previously log-only).
- Exceptions thrown from the callback are contained and logged, never
rethrown, so a faulty handler cannot crash the host.
- The parameter is optional; existing callers are unaffected.
- Document the new parameter in the TypeScript triggers reference and
the subscribing-to-events guide; bump the changeset to minor for the
new API surface.
Applies review finding #1 from the PR #4448 review.
## Summary
- classify the existing harness integration guide as both a
general-agent and coding-agent example
- preserve the coding-agent tag because the same integration pattern
applies there too
## Validation
- bun test tests/static/content.test.ts
- git diff --check
Full docs typechecking could not start in this fresh worktree because
fumadocs-mdx is not installed.
- Log the full pusher:subscription_error payload (type, error, status)
instead of a flattened String(data.error) so operators can tell auth
failures from permission failures.
- Log the subscription success message only when Pusher dispatches
pusher:subscription_succeeded, not when subscribe() returns.
- Extend regression coverage for both behaviors.
Applies review findings #2 and #3 from the PR #4448 review.
## Summary
`transformToolkitRetrieveResponse` projects `auth_config_details[]` key
by key and silently dropped
three keys the pinned client declares. `is_secret` and
`legacy_template_name` are snake_case, so zod
stripped them; `auth_hint_url` was never listed.
The API documents `is_secret` as "Clients use it to decide whether to
mask the input". Without it a
consumer rendering its own credential form cannot tell an API key from a
shop subdomain, so a field holding a secret is not reported as one.
## Changes
- Map auth fields explicitly; add `isSecret`, `legacyTemplateName` and
`authHintUrl` to the schemas
- Spread optional keys conditionally, so a key the API omits stays
absent rather than `undefined`,
which would beat a caller's fallback
- Add a runtime test over all four field groups, plus a type-level test
that fails the build on an
unlisted client key in any group. It catches new wire keys, not an
assignment removed from the
mapper; the runtime test pins that for the keys known today
- Add a patch changeset for `@composio/core`
## Type of change
- [x] Bug fix
- [ ] New feature
- [ ] Refactor/Chore
- [ ] Documentation
- [ ] Breaking change
## How Has This Been Tested?
- `pnpm --filter @composio/core test`: 55 files, 1288 passed, 2 expected
fail; typecheck and
`validate:changesets` exit 0
- `pnpm lint:packages`: exit 0 with 54 pre-existing warnings, one in a
file this PR touches; no new
warning on added lines
- The runtime test fails 5 of its 7 cases on `origin/next`; the two
green on both are the regression
guards. The type-level test was checked against all four client
interfaces
- Node 24.18.0; `mise.toml` pins 24.17.0, unavailable here, so it was
not run under it. Not
run: the root workspace suite (its `test:toolchain` needs Bun), Docker
E2E, the Python suite
## Screenshots (if applicable)
N/A
## Checklist
- [x] I have read the Code of Conduct and this PR adheres to it
- [x] I ran linters/tests locally and they passed, with the exceptions
listed above
- [x] I updated documentation as needed (none needed: the new keys carry
TSDoc; the SDK reference is
generated from unchanged signatures)
- [x] I added tests or explain why not applicable
- [x] I added a changeset if this change affects published packages
## Additional context
Left out on purpose: `user_visible` and `required_scopes`, in the spec
but not the pinned client;
`deprecated_auth_provider_details`, which the client marks deprecated;
and the keys this transformer
drops outside `auth_config_details`, all pre-existing and adjacent.
One behavior change: the eager mapping now throws if an auth config
detail arrives without its
`auth_config_creation` group, where the pass-through still returned the
connection fields. The
client declares both groups required and non-nullable, so this affects
only out-of-contract
responses.
## Summary
Auto-generated Python SDK reference docs from `python/composio/`.
Regenerates pages at `docs/content/reference/sdk-reference/python/` to
reflect changes in the Python package's public API (new methods, updated
signatures, changed types).
Replacing the pass-through with an eager projection changed the failure mode for
an auth config detail that omits a field group. Passing the group through left
`undefined` in place, which zod rejected as a handled validation error;
`transformToolkitAuthFieldGroup` instead reads `group.required`, so the same
response now throws a `TypeError` before validation runs and crashes
`toolkits.get()`.
Default a missing or null group, and a missing list inside a group, to empty
lists. This repo's docs pipeline already assumes that shape: the schemas in
`docs/lib/toolkit-api.ts` carry `.catch({ required: [], optional: [] })` on the
same fields. Normalizing also keeps the other group usable when only one is
absent, which is typically the one the caller asked for, where a validation
error would have returned nothing.
Reported by greptile-apps on #4411.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>