Skip to content

feat(sdk-typescript): rename telemetry harness → origin_actor#187

Merged
willwashburn merged 4 commits into
mainfrom
feat/origin-actor-sdk-ts
Jun 11, 2026
Merged

feat(sdk-typescript): rename telemetry harness → origin_actor#187
willwashburn merged 4 commits into
mainfrom
feat/origin-actor-sdk-ts

Conversation

@willwashburn

Copy link
Copy Markdown
Member

Aligns @relaycast/sdk (JS, packages/sdk-typescript) with the engine 3.0.0 contract (relaycast#184). This is the JS-SDK foundation for the spawned-agent (23%) attribution — PR1 only did engine + sdk-rust, so the JS SDK still sent the old header.

Changes

The JS SDK now sends X-Relaycast-Origin-Actor (HTTP) / ?origin_actor= (WS) from an originActor option:

  • origin.ts: HARNESS_HEADERORIGIN_ACTOR_HEADER; sanitizeHarnesssanitizeOriginActor; max 120 → 128 and allow @ for the {app}/{type}/{name}@{version}-{model} path.
  • client.ts / ws.ts / relay.ts / agent.ts: the public harness option + internal _originHarnessoriginActor; WS query harnessorigin_actor.

Breaking

The public harness constructor option is now originActor — no alias (per plan). Domain session-event types are untouched.

Verification

357 sdk-typescript tests pass; tsc --noEmit clean.

Next (the two-repo chain, like the harness saga)

  1. Publish @relaycast/sdk (a new version) — this PR.
  2. relay consumes: withRelaycastTelemetry/relaycastTelemetryOptions pass originActor, bump the @relaycast/sdk dep, and the broker sets the per-worker env to agent-relay-cli/agent/<harness> (folding in the open #1078). That flips the JS spawned-agent traffic from unknown → per-agent harness.

🤖 Generated with Claude Code

Aligns @relaycast/sdk (JS) with the engine 3.0.0 contract (relaycast#184).
The JS SDK now sends the `X-Relaycast-Origin-Actor` header / `?origin_actor=`
WS query from an `originActor` option (was `harness` / `X-Relaycast-Harness`).

- origin.ts: HARNESS_HEADER -> ORIGIN_ACTOR_HEADER; sanitizeHarness ->
  sanitizeOriginActor; max 120 -> 128 and allow `@` for the
  {app}/{type}/{name}@{version}-{model} path.
- client.ts / ws.ts / relay.ts / agent.ts: the `harness` option + internal
  `_originHarness` -> `originActor`; WS query `harness` -> `origin_actor`.

Breaking: the public `harness` constructor option is now `originActor`; no
alias (per cloud/plans/origin-actor.md). The domain session-event types are
untouched.

357 tests pass; tsc clean.

This is the JS-SDK foundation for the spawned-agent (23%) attribution. Once
published, the relay side (telemetry options + broker per-worker env) consumes
it to emit agent-relay-cli/agent/<harness>.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@willwashburn, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 5 minutes and 34 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1fe681e4-d282-44a2-8f3e-ef4ad47a59e4

📥 Commits

Reviewing files that changed from the base of the PR and between 7dce739 and 477a256.

📒 Files selected for processing (3)
  • packages/sdk-typescript/src/agent.ts
  • packages/sdk-typescript/src/relay.ts
  • packages/sdk-typescript/src/ws.ts
📝 Walkthrough

Walkthrough

The PR systematically renames the harness origin identifier concept to originActor across the TypeScript SDK. HTTP client options, WebSocket client options, and internal storage now use originActor with updated header and query-parameter names, with corresponding sanitization and validation logic. Tests validate sanitization behavior, HTTP header stamping, WebSocket query parameter forwarding, and origin precedence rules.

Changes

Origin Actor Refactoring

Layer / File(s) Summary
Origin contract and sanitization
packages/sdk-typescript/src/origin.ts
InternalOrigin replaces harness field with originActor; new ORIGIN_ACTOR_HEADER constant and sanitizeOriginActor() function validate, normalize, length-cap, and lowercase originActor values.
HTTP client integration
packages/sdk-typescript/src/client.ts, packages/sdk-typescript/src/index.ts
ClientOptions adds originActor?: string option; HttpClient stores sanitized _originActor, exposes via getter, conditionally sets X-Relaycast-Origin-Actor header in requests, and forwards to derived clients via withApiKey(). Package exports updated.
WebSocket client integration
packages/sdk-typescript/src/ws.ts, packages/sdk-typescript/src/agent.ts, packages/sdk-typescript/src/relay.ts
WsClientOptions and WsClient store and forward originActor as origin_actor query parameter; RelayCastOptions adds originActor option; agent and relay constructors wire originActor from HTTP client to WebSocket connection setup.
Test coverage
packages/sdk-typescript/src/__tests__/harness.test.ts
Comprehensive test suite validates originActor sanitization (lowercasing, length-capping, trimming, control-character dropping), HTTP header stamping from public option vs. internal origin, omission when absent or invalid, persistence across withApiKey(), internal-origin precedence, and WebSocket query parameter forwarding and omission.
Workspace state updates
memory/workspace/.relay/outbox/capabilities.json, memory/workspace/.relay/state.json
Relay workspace metadata and dispatcher configuration updated with newer timestamps, schema version set to 2, dispatch receipts enabled, and snapshot delete blocker count reduced.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • AgentWorkforce/relaycast#184: The engine and Rust SDK perform a parallel harness → origin_actor rename with extraction and telemetry changes, directly aligning with this PR's TypeScript SDK refactoring.

Poem

🐰 From harness to origin's new name,
The actor now claims rightful fame,
Headers flow, WebSockets sing,
Origin actor—what a thing! 🎭✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: renaming the telemetry field from 'harness' to 'origin_actor' in the SDK TypeScript package.
Description check ✅ Passed The description is well-related to the changeset, providing context about aligning with engine 3.0.0, detailing all affected files and the nature of changes, and explaining breaking changes and verification steps.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/origin-actor-sdk-ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/sdk-typescript/src/__tests__/harness.test.ts (1)

274-297: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Test checks wrong query param name — will always pass.

Line 296 asserts url.searchParams.has('originActor') but the wire query param is origin_actor (snake_case, as correctly checked on line 271). This assertion will always pass regardless of whether the param is present, making the test ineffective.

🐛 Proposed fix
-    expect(url.searchParams.has('originActor')).toBe(false);
+    expect(url.searchParams.has('origin_actor')).toBe(false);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/sdk-typescript/src/__tests__/harness.test.ts` around lines 274 -
297, The test in packages/sdk-typescript/src/__tests__/harness.test.ts is
asserting the wrong query param name — change the assertion at the end of the
test that currently checks url.searchParams.has('originActor') to check for the
correct wire parameter 'origin_actor' so the test actually verifies WsClient
(constructed via new WsClient) omits the snake_case origin_actor param; keep the
rest of the MockWs and construction logic unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@memory/workspace/.relay/state.json`:
- Line 1: The tracked runtime workspace files under .relay (e.g., state.json and
outbox/capabilities.json) should be ignored and removed from the repo; add an
ignore rule like **/.relay/ to your .gitignore (or update existing ignore rules
to include .relay/), then remove the already-tracked files from version control
with git rm --cached for memory/workspace/.relay/state.json and
memory/workspace/.relay/outbox/capabilities.json and commit the change so the
runtime-only reconcile timestamps/counters and environment-specific roots are no
longer committed.

---

Outside diff comments:
In `@packages/sdk-typescript/src/__tests__/harness.test.ts`:
- Around line 274-297: The test in
packages/sdk-typescript/src/__tests__/harness.test.ts is asserting the wrong
query param name — change the assertion at the end of the test that currently
checks url.searchParams.has('originActor') to check for the correct wire
parameter 'origin_actor' so the test actually verifies WsClient (constructed via
new WsClient) omits the snake_case origin_actor param; keep the rest of the
MockWs and construction logic unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b47644c1-1599-4ed9-b477-e21bb291c5de

📥 Commits

Reviewing files that changed from the base of the PR and between 51b391e and 7dce739.

📒 Files selected for processing (9)
  • memory/workspace/.relay/outbox/capabilities.json
  • memory/workspace/.relay/state.json
  • packages/sdk-typescript/src/__tests__/harness.test.ts
  • packages/sdk-typescript/src/agent.ts
  • packages/sdk-typescript/src/client.ts
  • packages/sdk-typescript/src/index.ts
  • packages/sdk-typescript/src/origin.ts
  • packages/sdk-typescript/src/relay.ts
  • packages/sdk-typescript/src/ws.ts

Comment thread memory/workspace/.relay/state.json Outdated
@@ -1 +1 @@
{"workspaceId":"rw_7ccfea89","remoteRoot":"/memory/workspace","localRoot":"/home/daytona/workspace/memory/workspace","mode":"poll","syncMode":"mirror","intervalMs":5000,"lastReconcileAt":"2026-06-10T15:44:24.943864768Z","lastSuccessfulReconcileAt":"2026-06-10T15:44:24.943864768Z","staleAfter":"2026-06-10T15:44:34.943864768Z","status":"ready","states":{"stale":false,"offline":false,"hasConflicts":false,"hasPendingWriteback":false},"pendingWriteback":0,"pendingConflicts":0,"deniedPaths":0,"counters":{"snapshotDeleteBlocked":53},"circuit":{"open":false,"openedAt":"0001-01-01T00:00:00Z","windowMs":60000,"cooldownMs":30000,"threshold":5,"nextRetry":"0001-01-01T00:00:00Z"},"outbox":{"pending":0,"needsAttention":0,"failed":0,"acked":0}}
{"workspaceId":"rw_7ccfea89","remoteRoot":"/memory/workspace","localRoot":"/home/daytona/workspace/memory/workspace","mode":"poll","syncMode":"mirror","intervalMs":5000,"lastReconcileAt":"2026-06-10T23:49:15.652167138Z","lastSuccessfulReconcileAt":"2026-06-10T23:49:15.652167138Z","staleAfter":"2026-06-10T23:49:25.652167138Z","status":"ready","states":{"stale":false,"offline":false,"hasConflicts":false,"hasPendingWriteback":false},"pendingWriteback":0,"pendingConflicts":0,"deniedPaths":0,"counters":{"snapshotDeleteBlocked":16},"circuit":{"open":false,"openedAt":"0001-01-01T00:00:00Z","windowMs":60000,"cooldownMs":30000,"threshold":5,"nextRetry":"0001-01-01T00:00:00Z"},"outbox":{"pending":0,"needsAttention":0,"failed":0,"acked":0}} No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Prevent committing Relay runtime workspace state (memory/workspace/.relay/)

  • memory/workspace/.relay/state.json (and memory/workspace/.relay/outbox/capabilities.json) is currently tracked and contains runtime-only reconcile timestamps/counters and environment-specific roots, so it creates unnecessary repo noise.
  • Add an ignore rule for .relay/ directories (e.g., **/.relay/) and remove the already-tracked files from version control if they aren’t meant to ship.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@memory/workspace/.relay/state.json` at line 1, The tracked runtime workspace
files under .relay (e.g., state.json and outbox/capabilities.json) should be
ignored and removed from the repo; add an ignore rule like **/.relay/ to your
.gitignore (or update existing ignore rules to include .relay/), then remove the
already-tracked files from version control with git rm --cached for
memory/workspace/.relay/state.json and
memory/workspace/.relay/outbox/capabilities.json and commit the change so the
runtime-only reconcile timestamps/counters and environment-specific roots are no
longer committed.

@willwashburn willwashburn merged commit ca87a01 into main Jun 11, 2026
4 of 5 checks passed
@willwashburn willwashburn deleted the feat/origin-actor-sdk-ts branch June 11, 2026 00:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant