You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(sdk): make the published event source configurable (#131)
## Problem
The SDK transports hardcoded the `source` field when publishing user
prompts to the Axon API:
- `sdk/src/claude/transport.ts` → `"claude-sdk-client"`
- `sdk/src/acp/axon-stream.ts` → `"acp-sdk-client"`
Callers had no way to override it, so events from different integrations
writing to the same channel were indistinguishable.
## Approach
Rather than threading `source` through every `send()` / `prompt()` call
(the ACP `prompt()` path delegates to the ACP SDK's
`ClientSideConnection` and has no clean per-message hook), the source is
now a value the **client holds and can change at any time**. The
transport/stream resolves it **lazily at each publish**, so:
```ts
conn.setSource("my-integration");
await conn.send("hello"); // published with source "my-integration"
conn.setSource("other");
await conn.prompt({ ... }); // published with source "other"
```
This works uniformly for both Claude and ACP without touching the SDK
send methods.
## Changes
- **`BaseConnectionOptions.source`** — optional initial `source` for
both connection types.
- **`ClaudeAxonConnection` / `ACPAxonConnection`** — new
`setSource(source)` method and `source` getter; hold a mutable
`currentSource` and pass a resolver (`() => this.currentSource`) to the
transport/stream.
- **`AxonTransportOptions.source` / `AxonStreamOptions.source`** —
accept `string | (() => string | undefined)`, resolved at publish time.
- Defaults unchanged: omit `source` (or return `undefined`) and the
built-in identifiers are still used.
## Tests
Added coverage for: custom static source, lazy per-message resolution,
`undefined` → default fallback (transport + stream), and the
`setSource()` / `source` accessors on both connections.
- `npm run typecheck`, `npm run check` (biome), and `vitest` (512 tests)
all pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Reflex <reflex@runloop.ai>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
0 commit comments