Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
994bb1b
Replace AGENTSPAN_SERVER_URL with CONDUCTOR_SERVER_URL
Jul 28, 2026
8459fe5
Remove unwanted AGENTSPAN_CLI_PATH
Jul 28, 2026
752bd12
ci: remove dead agentspan CLI binary download step
Jul 28, 2026
9931a89
docs: finish legacy-branding prose sweep in agent docs
Jul 28, 2026
261aee1
feat(agents): add CONDUCTOR_* env var aliases for worker/streaming/li…
Jul 28, 2026
78c05d9
docs: add JS/Java/Python documentation-parity map and docs hub
Jul 28, 2026
05511d4
ci: add doc link-check and legacy-branding guard
Jul 28, 2026
d80ff49
fix: restore AGENTSPAN_SERVER_URL as the legacy fallback tier
Jul 28, 2026
cd399f4
docs: changelog entry for the documentation alignment pass
Jul 28, 2026
bed7d5b
fix(agents): rename AgentConfig env vars to CONDUCTOR_AGENT_*, drop A…
Jul 28, 2026
50b9080
fix(agents): rename AgentspanError to ConductorAgentError
Jul 28, 2026
0e36ca8
docs(agents): remove remaining legacy AGENTSPAN_* references from docs
Jul 28, 2026
12ef864
Remove unwanted AGENTSPAN_LLM_MODEL
Jul 28, 2026
d947844
fix(sdk): drop AGENTSPAN_* fallback from resolveOrkesConfig/logger en…
Jul 28, 2026
59bf508
Close remaining AGENTSPAN_ gaps in examples/e2e and dead test scaffol…
Jul 28, 2026
4307cdc
Scrub literal AGENTSPAN_ identifiers and cross-SDK/legacy framing ent…
Jul 28, 2026
55e1603
Fix top-level-await crash in 13 core agent examples
Jul 28, 2026
5032a45
Align agent doc tree structure and content with python-sdk
Jul 29, 2026
90e3bfb
Align core/operations doc guides with python-sdk, close WMQ doc gap
Jul 29, 2026
234516f
Replace use of Agentspan with Conductor on comments
Jul 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 2 additions & 16 deletions .github/workflows/agent-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ name: Agent E2E
# (Maven Central — it has no GitHub release assets), which ships the
# /agent/* control plane + TaskDef.runtimeMetadata persistence (conductor-oss
# PR #1255) and the agent runtime on by default from 3.32.0-rc.8 onward.
# The Agentspan server JAR is no longer used as a server flavor here; the
# Agentspan CLI binary is still downloaded (its own separate pin) since the
# CLI/skill e2e suites still drive it against this same server.
# The Conductor server JAR is no longer used as a server flavor here.
# Port of the Python SDK's proven agent-e2e workflow; JS deltas only
# (Node toolchain, jest runner; Python kept solely for mcp-testkit).
#
Expand All @@ -21,7 +19,6 @@ concurrency:
cancel-in-progress: true

env:
AGENTSPAN_CLI_VERSION: "0.4.4" # pinned CLI release — independent of the server
CONDUCTOR_OSS_VERSION: "3.32.0-rc.8" # pinned conductor-oss release — bump deliberately

jobs:
Expand All @@ -31,8 +28,7 @@ jobs:
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
AGENTSPAN_SERVER_URL: http://localhost:8080/api
AGENTSPAN_CLI_PATH: ${{ github.workspace }}/agentspan
CONDUCTOR_SERVER_URL: http://localhost:8080/api
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand Down Expand Up @@ -69,16 +65,6 @@ jobs:
curl -sfL "https://repo1.maven.org/maven2/org/conductoross/conductor-server/${CONDUCTOR_OSS_VERSION}/conductor-server-${CONDUCTOR_OSS_VERSION}-boot.jar" \
--output conductor-server-boot.jar

# Agentspan CLI (CLI/skill suites) — kept on its own separate pin,
# independent of which server JAR is under test.
- name: Download CLI binary from release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release download "v${AGENTSPAN_CLI_VERSION}" --repo agentspan-ai/agentspan \
--pattern "agentspan_linux_amd64" --output agentspan
chmod +x agentspan

- name: Install SDK deps and build
run: |
npm ci
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,32 @@ concurrency:
cancel-in-progress: true

jobs:
docs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Validate documentation links
uses: lycheeverse/lychee-action@v2
with:
args: --offline --no-progress --include-fragments README.md docs

- name: Reject outdated product branding
run: |
# Scoped to README.md, AGENTS.md, docs/, and cli-bin/ -- the areas
# this sweep actually covers. This does NOT scan examples/, e2e/,
# or src/.
#
# Excluded inline: the `_agentspan` internal serializer markers,
# the external `agentspan` CLI binary name, and the historical
# "conductor server > 0.4.2" version reference.
if grep -rIn -iE 'agent[s]pan' README.md AGENTS.md docs/ cli-bin/ \
| grep -viE '_agentspan|agentspan CLI helper scripts|conductor server > 0\.4\.2'; then
echo "Outdated product branding found — use Conductor terminology."
exit 1
fi

linter:
runs-on: ubuntu-latest
steps:
Expand Down
17 changes: 10 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ src/open-api/ # OpenAPI layer
types.ts # Extended types - add custom fields here
src/integration-tests/ # E2E tests against real Conductor server
utils/ # waitForWorkflowStatus, executeWorkflowWithRetry, etc.
src/agents/ # Durable agent layer (merged Agentspan TS SDK)
src/agents/ # Durable agent layer (merged from the standalone agent SDK)
index.ts # Agent, AgentRuntime, tool, guardrails, handoffs, ...
frameworks/ # LangGraph/LangChain/generic serializers + detection
testing/ # Agent testing toolkit (/agents/testing subpath)
wrappers/ # Vercel AI / LangGraph / LangChain drop-in wrappers
__tests__/ # Colocated jest unit tests (picked up by test:unit)
e2e/ # Agent e2e suites vs live agentspan server (jest.e2e.config.mjs)
e2e/ # Agent e2e suites vs a live Conductor server (jest.e2e.config.mjs)
cli-bin/ # agentspan CLI helper scripts (Go CLI walk-up probe target)
examples/agents/ # Agent examples (own tsconfig; run via npx tsx)
docs/agents/ # Agent layer documentation
Expand Down Expand Up @@ -76,9 +76,12 @@ docs/agents/ # Agent layer documentation
Framework subdirs (adk/, langgraph/, openai/, vercel-ai/) install their own
deps (`scripts/install-example-deps.sh`); `examples/agents` is excluded from
the root tsconfig.
- `AGENTSPAN_*` env vars (`AGENTSPAN_SERVER_URL`, default
`http://localhost:8080/api`) are the agent layer's config surface — kept
working as-is; `CONDUCTOR_*` aliases are a possible follow-up.
- The agent layer's connection config (`CONDUCTOR_SERVER_URL`, default
`http://localhost:8080/api`; `CONDUCTOR_AUTH_KEY`/`CONDUCTOR_AUTH_SECRET`)
reads the same env vars every other Conductor client does
(`resolveOrkesConfig.ts`). The worker/streaming/liveness knobs in
`src/agents/config.ts` read `CONDUCTOR_AGENT_*` only, with no other
fallback.

## Commands

Expand All @@ -94,9 +97,9 @@ CONDUCTOR_AUTH_KEY=key CONDUCTOR_AUTH_SECRET=secret \
ORKES_BACKEND_VERSION=5 \
npm run test:integration:orkes-v5

# Agent e2e (requires a running agentspan server + LLM keys; CI does this
# Agent e2e (requires a running Conductor server + LLM keys; CI does this
# against the pinned release JAR — see .github/workflows/agent-e2e.yml)
AGENTSPAN_SERVER_URL=http://localhost:8080/api npm run test:agent-e2e
CONDUCTOR_SERVER_URL=http://localhost:8080/api npm run test:agent-e2e
```

## Post-Change Verification (Required)
Expand Down
12 changes: 8 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Migration for `@conductor-oss/conductor-agent-sdk` users:** install `@io-orkes/conductor-javascript` and rewrite import specifiers -- `@conductor-oss/conductor-agent-sdk` becomes `@io-orkes/conductor-javascript/agents`, and the wrapper subpaths gain the `/agents` prefix (e.g. `.../vercel-ai` becomes `.../agents/vercel-ai`).
- New optional peer dependencies (all lazily resolved, install only what you use): `zod`, `zod-to-json-schema`, `ai`, `@langchain/core`, `@langchain/langgraph`. `dotenv` becomes a runtime dependency (the agent entry points load it at import time; the package `sideEffects` field allowlists `dist/agents/**` so bundlers keep that bootstrap).
- **Agent clients in `sdk/clients`, one client for both planes** -- `AgentClient` is an interface (the `/agent/*` control-plane surface); `OrkesAgentClient` is the implementation, obtained via `runtime.client` or `OrkesClients.getAgentClient()`. Both share a single underlying `ConductorClient` (and its one token mint) across control-plane and worker-plane calls -- no bespoke agent-layer auth/transport code exists. Naming note: `getWorkflowClient()` returns the general-purpose `WorkflowExecutor`; the agent `WorkflowClient` (`OrkesClients.getAgentClient().workflows` / `getAgentWorkflowClient()`) adds the agent-execution 404 fallback and token-usage rollup.
- **`AgentRuntime(configuration?, settings?)`** -- two independent, optional constructor arguments: `configuration` (connection/auth -- `OrkesApiConfig` or a pre-built `ConductorClient`, same env chain as every other Conductor client: `CONDUCTOR_*` -> explicit config -> `AGENTSPAN_*` fallback -> `http://localhost:8080` default) and `settings` (behavior-only `AgentConfigOptions`: worker polling/threads, streaming, liveness -- no connection fields). `AgentConfig` carries only behavior now.
- **`AgentRuntime(configuration?, settings?)`** -- two independent, optional constructor arguments: `configuration` (connection/auth -- `OrkesApiConfig` or a pre-built `ConductorClient`, same env chain as every other Conductor client: `CONDUCTOR_*` -> explicit config -> `http://localhost:8080` default, no other fallback) and `settings` (behavior-only `AgentConfigOptions`: worker polling/threads, streaming, liveness -- no connection fields). `AgentConfig` carries only behavior now.
- **`AgentConfigOptions`'s env vars are `CONDUCTOR_AGENT_*`-prefixed** -- `CONDUCTOR_AGENT_WORKER_POLL_INTERVAL`, `CONDUCTOR_AGENT_WORKER_THREADS`, `CONDUCTOR_AGENT_AUTO_START_WORKERS`, `CONDUCTOR_AGENT_STREAMING_ENABLED`, `CONDUCTOR_AGENT_LIVENESS_ENABLED`, `CONDUCTOR_AGENT_LIVENESS_STALL_SECONDS`, `CONDUCTOR_AGENT_LIVENESS_CHECK_INTERVAL_SECONDS`. No other names are read -- this is a clean break, not an alias.
- **`AgentspanError` renamed to `ConductorAgentError`** -- the base class every agent-SDK error extends (`AgentAPIError`, `AgentNotFoundError`, `ConfigurationError`, `CredentialNotFoundError`, `CredentialAuthError`, `CredentialRateLimitError`, `CredentialServiceError`, `SSETimeoutError`, `SSEUnavailableError`, `TerminalToolError`, `WorkerStallError`, `GuardrailFailedError`) -- the old product name no longer appears anywhere in the public error hierarchy.
- **Documentation alignment pass** -- [`docs/documentation-parity.md`](docs/documentation-parity.md), an honest map of JS/Java/Python documentation parity; [`docs/README.md`](docs/README.md), a full hub matching Java/Python's Start-here/Build/Operate/Reference shape; remaining outdated product-name prose reworded to Conductor terminology in `AGENTS.md`, `cli-bin/shared.ts`, and the `docs/agents/` guides; new CI checks (`lycheeverse/lychee-action` doc-link validation, a product-branding grep guard scoped to `README.md`/`AGENTS.md`/`docs/`/`cli-bin/`); `getting-started.md`'s quickstart table fixed to name the actual primary env vars (`CONDUCTOR_AUTH_KEY`/`CONDUCTOR_AUTH_SECRET`) and dropped a documented bearer-token option that nothing in this package actually reads. Full structural restructuring now shipped: the `docs/agents/{concepts,reference,frameworks}/` split (content-checked topic-by-topic against Python, four doc-only gaps closed: memory, agent-schema wire contract, crash-recovery naming, SSE-fallback behavior) and ~20 core/operations guide landing pages (`docs/{server-setup,core-quickstart,connection-authentication,workers,workflows,workflow-lifecycle,workflow-testing,schema-client,schedules-events,reliability,security,deployment-scaling,observability,debugging,compatibility,upgrading,examples,api-map,documentation-standard}.md`) linking into existing root `README.md`/`docs/api-reference/*.md`/`METRICS.md`/`LEASE_EXTENSION.md` content. Also added `docs/workflow-message-queue.md` (previously undocumented outside a passing mention in the agent tools guide), a missing "Pull Workflow Messages Task" section in `docs/api-reference/task-generators.md`, and corrected a stale JSDoc in `src/agents/tool.ts` that referenced a non-existent `AgentRuntime.sendMessage` method -- pushing a message into a workflow's queue from outside is not yet exposed by this SDK's client. Remaining gap: five clients (`SchemaClient`, `SecretClient`, `AuthorizationClient`, `IntegrationClient`, `PromptClient`) still lack dedicated `docs/api-reference/*.md` pages, tracked in `docs/documentation-parity.md`.
- **Verb contract** -- `serve(...agents, { blocking? })` now deploys (registers the workflow def, same as `deploy`) *and* serves in one call; `{ blocking: false }` returns once deploy + worker registration + polling have started instead of blocking until SIGINT/SIGTERM. `deploy(...agents)` gained a variadic form (`DeploymentInfo[]`) alongside the existing single-agent `deploy(agent, { schedules? })` form. `AgentHandle`/`ClientHandle` gained `stop()`. `wait()` (both handle flavors) now rejects once a deadline passes (`timeoutSeconds`-derived, or 10 min default) with an `AgentAPIError` naming the last known status, instead of polling forever.
- **`RunSettings`** -- `RunOptions.runSettings` (`model`, `temperature`, `maxTokens`, `reasoningEffort`, `thinkingBudgetTokens`) applies per-run LLM overrides to `run`/`start`/`stream` without mutating the agent's own config; unset fields keep the agent's values and overrides don't cascade to sub-agents. `RunOptions.model` is sugar for `runSettings.model`.
- **Credentials via `Task.runtimeMetadata`, fail-closed** -- the server resolves declared credentials at poll time and delivers them wire-only on the polled task's `runtimeMetadata`; the SDK injects them into the worker's `process.env` for the call (mutate-invoke-restore) and never fetches or persists them separately. A tool whose declared credential wasn't delivered fails non-retryably naming the missing name -- there is no ambient-env fallback. Requires a server that persists `TaskDef.runtimeMetadata` and delivers `Task.runtimeMetadata` (conductor-oss PR #1255 / agentspan server > 0.4.2); the CI matrix now runs the full agent e2e suite against both `agentspan-server` and the mainline `conductor-oss` boot jar.
- **Credentials via `Task.runtimeMetadata`, fail-closed** -- the server resolves declared credentials at poll time and delivers them wire-only on the polled task's `runtimeMetadata`; the SDK injects them into the worker's `process.env` for the call (mutate-invoke-restore) and never fetches or persists them separately. A tool whose declared credential wasn't delivered fails non-retryably naming the missing name -- there is no ambient-env fallback. Requires a server that persists `TaskDef.runtimeMetadata` and delivers `Task.runtimeMetadata` (conductor-oss PR #1255 / conductor server > 0.4.2); the CI matrix now runs the full agent e2e suite against both `agentspan-server` and the mainline `conductor-oss` boot jar.
- **Liveness monitoring** -- for a stateful (domain-routed) run, a new liveness monitor polls the execution's workflow every `livenessCheckIntervalSeconds` (`AgentConfigOptions.livenessEnabled`, default `true`); a `SCHEDULED`/`IN_PROGRESS` task in that run's domain unpolled (`pollCount === 0`) past `livenessStallSeconds` (default 30s) rejects a blocking `wait()` with the new `WorkerStallError` instead of hanging forever. Framework-spawned agents (no per-run domain) are unaffected.
- **Swarm hand-off contract** -- the per-tool `{source}_transfer_to_{target}` no-op worker now accepts an optional `message` string and echoes it back; the `{agent}_check_transfer` worker adds `transfer_message` (the winning transfer call's message) and, when an LLM turn emits more than one transfer call, `dropped_transfers` (with a warning identifying the honored vs. dropped targets) so a fan-out intent is never silently collapsed to one transfer.
- **`SchedulerClient` pause/resume works on both server families** -- per-schedule pause/resume verbs differ by Conductor family (OSS/embedded map them PUT-only, Orkes GET-only). `pauseSchedule`/`resumeSchedule` now issue PUT first and retry via GET only on HTTP 405 (stateless per call; the new optional `reason` on pause survives the fallback). Previously the GET-only calls failed against OSS/embedded servers. Admin bulk endpoints are unchanged.
Expand All @@ -28,9 +31,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `retryServerErrors` option in `OrkesApiConfig` / `RetryFetchOptions` and `CONDUCTOR_RETRY_SERVER_ERRORS` env var: opt-in retry of HTTP 502/503/504 for idempotent methods (GET, HEAD, OPTIONS, PUT, DELETE). Default `false`; set to `true` to enable.
- `WorkflowStatusProbe` in harness: opt-in probe (via `HARNESS_PROBE_RATE_PER_SEC`) that exercises UUID-bearing endpoints to validate template URI metrics.
- `WORKER_LEGACY_METRICS` is reserved for future use. Once canonical metrics become the default, setting `WORKER_LEGACY_METRICS=true` will re-activate the legacy surface. It is not read by the current implementation.
- `resolveOrkesConfig` (used by `createConductorClient`, and so every `OrkesApiConfig`-based client) gains an `AGENTSPAN_*` fallback tier for server URL and auth: `CONDUCTOR_SERVER_URL` -> explicit config -> `AGENTSPAN_SERVER_URL` -> default `http://localhost:8080` (previously an unset server URL threw; it now defaults instead). Auth follows the same shape: `CONDUCTOR_AUTH_KEY`/`SECRET` -> explicit config -> `AGENTSPAN_AUTH_KEY`/`SECRET`.
- `resolveOrkesConfig` (used by `createConductorClient`, and so every `OrkesApiConfig`-based client): `CONDUCTOR_SERVER_URL` -> explicit config -> default `http://localhost:8080` (previously an unset server URL threw; it now defaults instead). Auth follows the same shape: `CONDUCTOR_AUTH_KEY`/`SECRET` -> explicit config -> `undefined`. No other env var names are read.
- `createConductorClient()`'s returned client gains `getAuthenticationHeaders()` (the same `X-Authorization` header the standard call path attaches, for transports that can't go through `client.request`, e.g. SSE -- borrows the client's TTL-aware token, mints/caches nothing of its own) and `stopBackgroundRefresh()` (stops the client's background token-refresh interval; previously that handle was captured locally and dropped, leaking the interval for the life of the process).
- Logger env chain: `DefaultLogger` now also reads `AGENTSPAN_LOG_LEVEL` as a fallback when `CONDUCTOR_LOG_LEVEL` is unset.

### Changed

Expand All @@ -42,7 +44,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Removed

- **Agent `ScheduleClient` and `SchedulerFetcher`** (agents subpath; never released, no backward compatibility) -- schedules now ride the SDK `SchedulerClient`, re-exported from `@io-orkes/conductor-javascript/agents`. Method names and signatures are unchanged; migration is the import/type rename only (`ScheduleClient` -> `SchedulerClient`). The `schedules.*` namespace, `runtime.schedulesClient()`, `deploy({ schedules })` and `AgentClient.schedule()` are untouched.
- **Alternate env var names for the base connection config and logger, entirely** -- `resolveOrkesConfig.ts` (server URL, auth key/secret) and the logger's level resolution no longer read any name other than `CONDUCTOR_*` at all. Breaking change for anyone migrating from the standalone `@conductor-oss/conductor-agent-sdk` package who kept the old env var names set -- rename to the `CONDUCTOR_*` equivalents.

### Deprecated

- Legacy metric names remain the default during the transition period. Migration guidance is in [METRICS.md](METRICS.md#migrating-from-legacy-to-canonical).

Loading
Loading