Skip to content

feat!: align @symbiont/core + @symbiont/agent with Symbiont OSS runtime v1.14.3#9

Merged
jaschadub merged 5 commits into
mainfrom
feat/oss-runtime-1.14.3-parity
May 31, 2026
Merged

feat!: align @symbiont/core + @symbiont/agent with Symbiont OSS runtime v1.14.3#9
jaschadub merged 5 commits into
mainfrom
feat/oss-runtime-1.14.3-parity

Conversation

@jaschadub

Copy link
Copy Markdown
Contributor

Summary

Brings @symbiont/core and @symbiont/agent to parity with the Symbiont OSS runtime v1.14.3 HTTP surface and removes core surface that targeted endpoints the OSS runtime does not serve. Validated by cross-checking every remaining client call against the runtime route table in crates/runtime/src/api/server.rszero phantom paths remain.

⚠️ Breaking for @symbiont/core consumers (see Removed). Core + agent bumped to 1.14.3.

Added (@symbiont/agentAgentClient)

Method Route
sendMessage POST /api/v1/agents/{id}/messages
receiveMessages GET /api/v1/agents/{id}/messages
getMessageStatus GET /api/v1/messages/{id}/status
sendHeartbeat POST /api/v1/agents/{id}/heartbeat
pushEvent POST /api/v1/agents/{id}/events

Wire bodies are snake_case (ttl_seconds, agentpin_jwt, last_result, event_type); undefined optionals omitted. New public types exported from the agent package index.

Fixed

  • /api/v1 prefix normalization via a shared buildRuntimeUrl() helper applied in every kept client's makeRequest (AgentClient, ScheduleClient, ChannelClient, WorkflowClient, SystemClient, MetricsClient). runtimeApiUrl carries no version segment, so prior bare-path calls hit the runtime without /api/v1 and 404'd; URLs now resolve to …/api/v1/<path> with exactly one segment.
  • WorkflowClient.executeWorkflow confirmed at POST /api/v1/workflows/execute.

Removed (BREAKING — @symbiont/core)

Endpoints the OSS runtime does not serve (every call 404'd):

  • Deleted ReasoningClient, ToolCladClient, CommunicationClient, and the entire vector/ (Qdrant) tree; removed their exports + SymbiontClient accessors.
  • MetricsClient trimmed to getMetrics()GET /api/v1/metrics (removed snapshot/scheduler/system/export); client-side exporters unchanged.
  • Removed phantom reExecuteAgent from AgentClient.
  • Kept client-side helpers: MarkdownMemoryStore, SkillScanner, WebhookVerifier, AgentPinClient, auth/config/security.

Scope / follow-up

  • Standalone packages targeting a hosted (non-OSS) runtime — @symbiont/tool-review, @symbiont/vector, and the MCP-management part of @symbiont/mcp — are not changed here; tracked for a follow-up. @symbiont/secrets and @symbiont/policy are local/client-side and unaffected.
  • Runtime routes intentionally left unwrapped: /ws/chat (WebSocket), /health/live, /health/ready.

Validation

jaschadub added 3 commits May 30, 2026 17:31
…me v1.14.3

Brings the core and agent packages to parity with the Symbiont OSS runtime
v1.14.3 HTTP surface and removes core surface that targeted endpoints the OSS
runtime does not serve. Validated by cross-checking every remaining client call
against crates/runtime/src/api/server.rs — zero phantom paths remain.

Added (@symbiont/agent AgentClient):
- sendMessage      -> POST /api/v1/agents/{id}/messages
- receiveMessages  -> GET  /api/v1/agents/{id}/messages
- getMessageStatus -> GET  /api/v1/messages/{id}/status
- sendHeartbeat    -> POST /api/v1/agents/{id}/heartbeat
- pushEvent        -> POST /api/v1/agents/{id}/events
Wire bodies are snake_case (ttl_seconds, agentpin_jwt, last_result, event_type);
undefined optionals omitted. Public types exported from the package index.

Fixed:
- /api/v1 prefix normalization via a shared buildRuntimeUrl() helper applied in
  every kept client's makeRequest (AgentClient, ScheduleClient, ChannelClient,
  WorkflowClient, SystemClient, MetricsClient). runtimeApiUrl carries no version
  segment, so prior bare-path calls hit the runtime without /api/v1 and 404'd;
  URLs now resolve to /api/v1/<path> with exactly one version segment.
- WorkflowClient.executeWorkflow confirmed at POST /api/v1/workflows/execute.

Removed (BREAKING, @symbiont/core) — endpoints the OSS runtime does not serve:
- Deleted ReasoningClient, ToolCladClient, CommunicationClient, and the entire
  vector/ (Qdrant) tree; removed their exports + SymbiontClient accessors.
- MetricsClient trimmed to getMetrics() -> GET /api/v1/metrics (removed
  snapshot/scheduler/system/export); client-side exporters unchanged.
- Removed phantom reExecuteAgent from AgentClient.
- Kept client-side helpers: MarkdownMemoryStore, SkillScanner, WebhookVerifier,
  AgentPinClient, auth/config/security.

Scope: @symbiont/core and @symbiont/agent bumped to 1.14.3 (root monorepo too).
Standalone packages targeting a hosted runtime (@symbiont/tool-review,
@symbiont/vector, the MCP-management part of @symbiont/mcp) are NOT changed here
and are tracked for a follow-up; @symbiont/secrets and @symbiont/policy are
local/client-side and unaffected.

Build clean (tsc + rollup), 780 tests pass (26 files). New tests cover the 5
added methods and the /api/v1 normalization.
Follow-up to the core/agent OSS-runtime alignment (this PR), covering the
remaining standalone packages.

@symbiont/mcp (fixed like core/agent):
- Added urlUtils.buildRuntimeUrl() (copy of the agent/core helper) and applied
  it in McpClient.makeRequest so calls resolve to exactly one /api/v1 segment
  (runtimeApiUrl carries no version segment).
- Kept the real OSS routes: executeWorkflow -> POST /api/v1/workflows/execute
  and checkServerHealth -> GET /api/v1/health.
- Removed phantom methods the OSS runtime does not serve: listWorkflows
  (GET /workflows), getExecutionStatus / cancelExecution (/workflows/executions/*),
  and getConnectionStatus (GET /mcp/status); dropped their now-unused type
  imports.
- Version 1.13.0 -> 1.14.3. mcp vitest: 18 passed.

@symbiont/tool-review (deprecated, NOT deleted; code unchanged):
- Targets the hosted Tool Review API (its own base URL, config.toolReviewApiUrl),
  a separate service the OSS runtime does not expose. Marked deprecated
  non-destructively: a "deprecated" field in package.json, a banner at the top
  of README.md, and an @deprecated JSDoc tag on ToolReviewClient. No logic or
  version change.

Note: there is no standalone vector package in this monorepo (the only
vector code lived in @symbiont/core, already removed in this PR), so no
vector deprecation was needed.

Validated: mcp's only live request paths are /workflows/execute and /health
(zero phantom); tsc clean for both packages.
Investigated the reported `@symbiont/core` rollup build failure
("RollupError: Expected '{', got 'type'" at src/index.ts:32). It was NOT a
source or config bug: core/src is clean (no stale imports of the clients
removed earlier in this branch), and core's package.json already declared the
full rollup toolchain (@rollup/plugin-typescript/-commonjs/-node-resolve,
rollup, typescript) — the committed devDependencies delta is empty.

Root cause was stale local node_modules after the earlier file deletions:
the workspace symlinks / @rollup/plugin-typescript type resolution were out of
sync, so rollup fell back to parsing raw .ts and choked on the first
`export type`. Regenerating with `npm install` fixed it.

This commit carries the resulting package-lock.json sync (the 1.14.3 version
bumps from this branch plus the @symbiont/tool-review `deprecated` field) and
core's version bump to 1.14.3, so a clean `npm ci` produces a correct tree.

Verified after the sync:
- Cold build (all dist/ + *.tsbuildinfo removed, then `npm run build`): exit 0,
  9 bundles created, 0 errors — including @symbiont/core and @symbiont/mcp.
- vitest: 798 passed (27 files).
@jaschadub jaschadub force-pushed the feat/oss-runtime-1.14.3-parity branch from 60106d6 to a21ab11 Compare May 31, 2026 04:58
jaschadub added 2 commits May 31, 2026 00:05
update() stamps the record with new Date() (real now); the test relied on a
real 1ms setTimeout to make the post-update timestamp later than the original,
which flaked in CI when store() and update() landed in the same millisecond
(expected N to be greater than N). Seed the memory one minute in the past
instead, so the post-update timestamp is unambiguously greater regardless of
millisecond timing. get() preserves timestamp (recordAccess only bumps
accessCount). Verified 6/6 consecutive runs.
…th fake timers

The "should update timestamp on update" test flaked in CI:

    AssertionError: expected N to be greater than N

Root cause: BOTH the operations involved stamp wall-clock time.
InMemoryStore.update() sets `timestamp: new Date()`, and — critically — so
does get() via recordAccess() ("Update last access time", InMemoryStore.ts:213).
So the assertion `updated.timestamp > original.timestamp` compares two
`new Date()` reads taken microseconds apart; on a fast runner they land in the
same millisecond and the strict `toBeGreaterThan` fails.

A prior attempt seeded the memory with a past timestamp, but that cannot work:
the first get() immediately overwrites the seeded value with "now" via
recordAccess, so both reads are still "now".

Fix: drive a fake clock (vi.useFakeTimers + setSystemTime) and advance it
1s between the original read and the update, so the post-update read is
deterministically later regardless of real timing. Restores real timers in a
finally. No production-code change.

Verified: the test passes 10/10 consecutive runs; full suite `npx vitest run`
(the CI command) is 883 passed (31 files); `npm run build --workspaces` and
`npm run type-check` are clean.
@jaschadub jaschadub merged commit 501ca48 into main May 31, 2026
3 checks passed
@jaschadub jaschadub deleted the feat/oss-runtime-1.14.3-parity branch May 31, 2026 18:38
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