diff --git a/.github/workflows/agent-e2e.yml b/.github/workflows/agent-e2e.yml index 5790939f..de362d9c 100644 --- a/.github/workflows/agent-e2e.yml +++ b/.github/workflows/agent-e2e.yml @@ -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). # @@ -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: @@ -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 @@ -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 diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 79ff70e9..0b5939ca 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -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: diff --git a/AGENTS.md b/AGENTS.md index 7680b987..27014c99 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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 @@ -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 @@ -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) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5a1b167..90e89f59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. @@ -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 @@ -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). + diff --git a/README.md b/README.md index 8650a82f..0d14a0d5 100644 --- a/README.md +++ b/README.md @@ -556,7 +556,7 @@ const agent = new Agent({ instructions: "You are a friendly assistant. Keep responses brief.", }); -const runtime = new AgentRuntime(); // AGENTSPAN_SERVER_URL, default http://localhost:8080/api +const runtime = new AgentRuntime(); // CONDUCTOR_SERVER_URL, default http://localhost:8080/api try { const result = await runtime.run(agent, "Hello! What can you do?"); result.printResult(); @@ -584,6 +584,7 @@ testing toolkit (`/agents/testing`). | Document | Description | |----------|-------------| +| [Documentation hub](docs/README.md) | Where to start — agent docs, API reference, and Java/Python parity notes | | [SDK Development Guide](SDK_DEVELOPMENT.md) | Architecture, patterns, pitfalls, testing | | [Durable AI Agents](docs/agents/README.md) | Agent authoring layer: tools, guardrails, multi-agent, HITL, framework wrappers | | [Metrics Reference](METRICS.md) | Legacy and canonical Prometheus metrics with migration guide | @@ -592,15 +593,10 @@ testing toolkit (`/agents/testing`). | [Task Management](docs/api-reference/task-client.md) | Task operations, logs, queue management | | [Metadata](docs/api-reference/metadata-client.md) | Task & workflow definitions, tags, rate limits | | [Scheduling](docs/api-reference/scheduler-client.md) | Workflow scheduling with CRON expressions | -| [Authorization](docs/api-reference/authorization-client.md) | Users, groups, permissions | | [Applications](docs/api-reference/application-client.md) | Application management, access keys, roles | | [Events](docs/api-reference/event-client.md) | Event handlers, event-driven workflows | | [Human Tasks](docs/api-reference/human-executor.md) | Human-in-the-loop workflows, form templates | | [Service Registry](docs/api-reference/service-registry-client.md) | Service discovery, circuit breakers | -| [Secrets](docs/api-reference/secret-client.md) | Secret storage and management | -| [Prompts](docs/api-reference/prompt-client.md) | AI/LLM prompt templates | -| [Integrations](docs/api-reference/integration-client.md) | AI/LLM provider integrations | -| [Schemas](docs/api-reference/schema-client.md) | JSON/Avro/Protobuf schema management | ## Support diff --git a/cli-bin/shared.ts b/cli-bin/shared.ts index 26f51656..359f0bbe 100644 --- a/cli-bin/shared.ts +++ b/cli-bin/shared.ts @@ -39,7 +39,7 @@ function collectFiles(dir: string): string[] { /** * Scan a directory recursively for .ts/.js files and discover all agent-like exports, - * including native AgentSpan agents and framework agents (OpenAI, ADK, + * including native Conductor agents and framework agents (OpenAI, ADK, * LangChain, LangGraph). */ export async function discoverAllAgents(scanPath: string): Promise { diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..389f2099 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,40 @@ +# JS/TS SDK documentation + +Build durable workflow workers and Conductor agents with JavaScript/ +TypeScript. These guides cover OSS and Orkes; pages call out capabilities +that require Orkes. + +## Start here + +| Goal | Guide | Expected result | +|---|---|---| +| Connect to a server | [Server setup](server-setup.md) and [connection/authentication](connection-authentication.md) | The SDK can reach an OSS or Orkes API endpoint. | +| Build a workflow and worker | [Core quickstart](core-quickstart.md) | The hello-world workflow prints its result. | +| Build a Conductor agent | [Agent quickstart](agents/getting-started.md) | An LLM-backed agent completes through Conductor. | + +## Build + +- [Workflows](workflows.md), [workflow lifecycle](workflow-lifecycle.md), and [workers](workers.md) +- [Workflow testing](workflow-testing.md), [schemas](schema-client.md), [schedules/events](schedules-events.md), and the [workflow message queue](workflow-message-queue.md) +- [Conductor agents](agents/README.md), [tools](agents/concepts/tools.md), and [framework bridges](agents/README.md#framework-bridges) +- [Recommended examples](examples.md); [examples/README.md](../examples/README.md) is the full catalog. + +## Operate + +- [Reliability](reliability.md), [security](security.md), and [deployment/scaling](deployment-scaling.md) +- [Metrics and logging](observability.md) and [debugging](debugging.md) + +## Reference and upgrades + +- [Core API map](api-map.md), [compatibility](compatibility.md), and [upgrading](upgrading.md) +- One reference page per client in [docs/api-reference/](api-reference/) (`application-client.md`, `task-client.md`, `workflow-executor.md`, ...) +- [Agent runtime](agents/reference/runtime.md), [control plane](agents/reference/client.md), and [agent definition](agents/reference/agent-definition.md) +- [Lease extension / heartbeat](../LEASE_EXTENSION.md) for long-running workers +- [Java/Python documentation parity](documentation-parity.md) — intentional JS mappings, JS-only pages, and unsupported Java/Python-only surfaces + +## Documentation conventions + +Primary guides follow the [documentation standard](documentation-standard.md). +Provider credentials belong on the Conductor server or its secret provider, +not in workflow input, example source, or a client-side `.env` committed to +Git. diff --git a/docs/agents/README.md b/docs/agents/README.md index e7537cb6..bc18083b 100644 --- a/docs/agents/README.md +++ b/docs/agents/README.md @@ -1,20 +1,73 @@ # Durable AI Agents — Documentation -The agent layer of the Conductor JavaScript SDK — long-running, dynamic plan-execute, and event-driven AI agents. +The agent layer of the Conductor JavaScript SDK — long-running, dynamic +plan-execute, and event-driven AI agents. -- **Package:** `@io-orkes/conductor-javascript` — agent layer imported from the `/agents` subpath +- **Package:** `@io-orkes/conductor-javascript` — agent layer imported from + the `/agents` subpath - **Runtime:** Node.js >= 18 - **Module:** ESM and CommonJS (`import` / `require`) -## Contents +## Start here -| Doc | Covers | +- [Getting started](getting-started.md) — install, env vars, and a running + agent in under 30 seconds. +- [Deploy · Serve · Run · Plan](concepts/deploy-serve-run.md) — choose a + runtime mode. +- [Scheduling](concepts/scheduling.md) — manage deployed-agent schedules. + +## Build agents + +- [Agents](concepts/agents.md), [tools](concepts/tools.md), and + [multi-agent](concepts/multi-agent.md) +- [Guardrails](concepts/guardrails.md), + [termination](concepts/termination.md), [callbacks](concepts/callbacks.md) +- [Stateful agents](concepts/stateful.md) (including memory and liveness + monitoring), [streaming and HITL](concepts/streaming-hitl.md), and + [structured output](concepts/structured-output.md) + +## Framework bridges + +- [Google ADK](frameworks/google-adk.md), [LangChain](frameworks/langchain.md), + and [LangGraph](frameworks/langgraph.md) +- [OpenAI Agents SDK](frameworks/openai.md) and + [Vercel AI SDK](frameworks/vercel-ai.md) (JS/Node-ecosystem-specific — no + Java/Python counterpart) + +You don't have to rewrite an agent authored with another framework to run it +on Conductor. `runtime.run()`/`deploy()`/`stream()` **detects** the framework +object you pass in, serializes it to an agent config, and runs it on the +server — the identical call you'd make with a native `Agent`: + +```ts +const runtime = new AgentRuntime(); +const result = await runtime.run(frameworkAgent, prompt); // <-- same entry point for every framework +``` + +Detection is pure duck-typing — no framework package is imported by the SDK, +and every framework's peer dependency is optional (install only what you +use). `detectFramework(agent)` returns the first match: + +| Framework | Detected when the object has… | |---|---| -| [getting-started.md](getting-started.md) | Install, env vars, and a running agent in under 30 seconds. | -| [writing-agents.md](writing-agents.md) | Authoring agents: instructions, tools, multi-agent strategies, handoffs, guardrails, termination, callbacks, streaming, HITL, schedules, agent-from-method, stateful agents. | -| [framework-agents.md](framework-agents.md) | Running agents authored with OpenAI, Google ADK, LangChain, LangGraph, and the Vercel AI SDK. | -| [advanced.md](advanced.md) | Runtime config, the `AgentClient` control plane, the `WorkflowClient`, deploy/serve/run/plan, structured output, credentials, plans / PLAN_EXECUTE, skills. | -| [api-reference.md](api-reference.md) | The public surface, one section per type. | +| native `Agent` | is an instance of `Agent` (runs natively, not as a framework) | +| `langgraph` | `.invoke()` plus a graph shape (`.getGraph()`, a `.nodes` Map, or `.nodes` + `.builder`) | +| `langchain` | `.invoke()` plus an `lc_namespace` array (e.g. an `AgentExecutor`) | +| `openai` | `name` + string/function `instructions` + string `model` + `tools[]` + an OpenAI marker (`handoffs[]`, `inputGuardrails[]`, `asTool()`, `toolUseBehavior`, ...) | +| `google_adk` | `subAgents[]` (orchestration agents), or string `model` + ADK markers (`instruction`, `outputKey`, `generateContentConfig`, `beforeModelCallback`, ...) | + +If nothing matches and the object isn't a native `Agent`, you get a clear +error. All five frameworks use the identical `runtime.run(agentOrGraph, +prompt)` entry point — there is no per-framework runtime API. Framework +agents can be deployed too: `runtime.deploy(frameworkAgent)`. + +## Operate and inspect + +- [Runtime reference](reference/runtime.md), + [control-plane reference](reference/client.md), and + [API map](reference/api.md) +- [Agent-definition fields](reference/agent-definition.md) and + [configuration contract](reference/agent-schema.md) ## At a glance @@ -36,4 +89,5 @@ try { } ``` -You need a running Agentspan server (default `http://localhost:8080/api`). See [getting-started.md](getting-started.md). +You need a running Conductor server (default `http://localhost:8080/api`). +See [getting-started.md](getting-started.md). diff --git a/docs/agents/advanced.md b/docs/agents/advanced.md index 1b360b02..bdbb2c39 100644 --- a/docs/agents/advanced.md +++ b/docs/agents/advanced.md @@ -1,275 +1,8 @@ # Advanced -Runtime configuration, the control-plane and workflow clients, the deploy/serve/run/plan lifecycle, structured output, credentials, plans (PLAN_EXECUTE), and skills. +This page has moved to: -## Runtime configuration - -`new AgentRuntime(configuration?, settings?)` takes two independent, optional arguments: - -- `configuration` — connection/auth, the same shape every other Conductor client takes (`OrkesApiConfig`, or a pre-built `ConductorClient` from `createConductorClient()`/`OrkesClients` to share one client — and one token mint — across control-plane and worker-plane calls). Falls back to `CONDUCTOR_SERVER_URL`/`CONDUCTOR_AUTH_KEY`/`CONDUCTOR_AUTH_SECRET`, then `AGENTSPAN_SERVER_URL`/`AGENTSPAN_AUTH_KEY`/`AGENTSPAN_AUTH_SECRET` (agent-layer fallback), then `http://localhost:8080`. -- `settings` — `AgentConfigOptions`, purely behavioral (no connection fields — those live on `configuration` now). Every field falls back to an env var, then a default; explicit values take precedence. - -```ts -import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; - -const runtime = new AgentRuntime( - { serverUrl: 'http://localhost:8080/api', keyId: '…', keySecret: '…' }, // connection (OrkesApiConfig) - { - workerPollIntervalMs: 100, // AGENTSPAN_WORKER_POLL_INTERVAL - workerThreadCount: 1, // AGENTSPAN_WORKER_THREADS - streamingEnabled: true, // AGENTSPAN_STREAMING_ENABLED - livenessEnabled: true, // AGENTSPAN_LIVENESS_ENABLED - livenessStallSeconds: 30, // AGENTSPAN_LIVENESS_STALL_SECONDS - livenessCheckIntervalSeconds: 10, // AGENTSPAN_LIVENESS_CHECK_INTERVAL_SECONDS - }, -); - -// Both args are optional -- this reads connection + behavior entirely from env: -const defaultRuntime = new AgentRuntime(); -``` - -Full `AgentConfigOptions`: `workerPollIntervalMs`, `workerThreadCount`, `autoStartWorkers`, `streamingEnabled`, `livenessEnabled`, `livenessStallSeconds`, `livenessCheckIntervalSeconds` (see [Liveness monitoring](writing-agents.md#liveness-monitoring)). - -There is also a module-level singleton API for convenience — `configure(configuration?, settings?)`, `run`, `start`, `stream`, `deploy`, `plan`, `serve`, `shutdown` — that operate on a shared runtime: - -```ts -import { configure, run, shutdown } from '@io-orkes/conductor-javascript/agents'; -configure({ serverUrl: 'http://localhost:8080/api' }); -const result = await run(agent, 'hi'); -await shutdown(); -``` - -## deploy vs serve vs run vs plan - -| Method | What it does | Local workers? | -|---|---|---| -| `runtime.run(agent, prompt, opts?)` | Compile + start + stream + return an `AgentResult`. | Yes — registers and polls local `tool()` workers for the run. | -| `runtime.start(agent, prompt, opts?)` | Same as `run` but returns an `AgentHandle` for async interaction (stream, approve, pause, ...). | Yes. | -| `runtime.stream(agent, prompt, opts?)` | `start` + return its `AgentStream`. | Yes. | -| `runtime.deploy(agent, { schedules? })` | Compile + register the workflow definition on the server. No execution, no workers. CI/CD step. Returns `DeploymentInfo`. | No. | -| `runtime.deploy(...agents)` | Variadic form: compile + register multiple agents in one call, no schedules reconciliation. Returns `DeploymentInfo[]`. | No. | -| `runtime.serve(...agents, { blocking? })` | Deploys the given agents (same registration as `deploy`), registers their local tool workers, and starts polling. Blocks until SIGINT/SIGTERM by default; pass a trailing `{ blocking: false }` to return once deploy + registration + polling have started. With no agents, just (re)starts polling for workers already registered. | Yes (and keeps them alive when blocking). | -| `runtime.plan(agent)` | Compile to a workflow definition and return it, without executing. | No. | -| `runtime.shutdown()` | Stop worker polling. | — | - -`serve()` already deploys, so a standalone `deploy()` call beforehand is optional — only worth doing when you want registration decoupled from worker start-up (e.g. a dedicated CI/CD step). The typical production split: run a `serve` process for the tool workers (it registers on the server for you), and trigger executions via the control plane (`runtime.client.run(...)`) or schedules. - -```ts -// Long-lived worker process -- deploys + registers workers + starts polling -await runtime.serve(myAgent); // blocks - -// Trigger (control plane, no local workers needed for LLM-only / remote-tool agents) -const result = await runtime.client.run(myAgent, 'do the thing'); -``` - -## `AgentClient` — control plane - -`runtime.client` is an [`AgentClient`](api-reference.md#agentclient): the control-plane client for the `/agent/*` HTTP surface. `OrkesAgentClient` is the Conductor/Orkes implementation; obtain one directly via `OrkesClients.getAgentClient()`, or use `runtime.client`, which shares the same underlying Conductor client (and its single token mint) as the runtime's worker plane — no bespoke auth/transport lives behind this interface. - -**Control-plane only:** `AgentClient.run/start` compile + start an agent and poll, but do **not** register or poll local tool workers. Use it for LLM-only agents, agents whose tools are remote (HTTP/MCP), or pre-deployed workflows. For agents with local `tool()` functions, use `runtime.run()` instead. - -```ts -const client = runtime.client; // or: orkesClients.getAgentClient() - -// Compile + start + poll to result -const result = await client.run(agent, 'summarize this', { timeoutSeconds: 120 }); - -// Start and interact via a ClientHandle -const handle = await client.start(agent, 'do work'); -const status = await handle.getStatus(); -const final = await handle.wait(); // deadline: timeoutSeconds + 30s, or 10 min default -await handle.approve(); // / reject(reason) / send(message) / respond(body) -await handle.stop(); // stop the execution - -// Compile + register one or more agents (no execution) -const infos = await client.deploy(agentA, agentB); // DeploymentInfo[] - -// Deploy + reconcile cron schedules in one call -import { Schedule } from '@io-orkes/conductor-javascript/agents'; -await client.schedule(agent, [new Schedule({ name: 'nightly', cron: '0 0 0 * * *' })]); -``` - -Low-level endpoints are available too: `startAgent`, `deployAgent`, `compile`, `status`, `respond`, `getExecution`, `stream`. The `client.schedules` accessor is the SDK `SchedulerClient` (shared with `OrkesClients.getSchedulerClient()`); `client.workflows` is a `WorkflowClient` (below). - -## `WorkflowClient` — execution reads - -`runtime.workflows` (also `runtime.client.workflows`) is a read-only [`WorkflowClient`](api-reference.md#workflowclient) over the underlying Conductor workflow API. - -```ts -const wf = await runtime.workflows.getWorkflow(executionId); // full execution (with tasks) -const status = await runtime.workflows.getStatus(executionId); // 'RUNNING' | 'COMPLETED' | ... -const usage = await runtime.workflows.extractTokenUsage(executionId);// aggregated across sub-workflows -// usage -> { promptTokens, completionTokens, totalTokens } | null -``` - -`extractTokenUsage` walks the execution tree (recursing into `SUB_WORKFLOW` tasks) and sums token usage — useful for multi-agent runs where tokens are spread across sub-workflows. Note: `result.tokenUsage` is already populated for you on a normal `run()`; this is for inspecting an execution by id after the fact. - -## Structured output - -Set `outputType` to a JSON Schema object (or a Zod schema — it is converted to JSON Schema). The model returns data conforming to the schema; the structured object lands under `result.output.result`. - -```ts -const ArticleAnalysis = { - type: 'object', - properties: { - title: { type: 'string' }, - category: { type: 'string', enum: ['tech', 'business', 'science'] }, - sentiment: { type: 'string', enum: ['positive', 'neutral', 'negative'] }, - keyTopics: { type: 'array', items: { type: 'string' } }, - }, - required: ['title', 'category', 'sentiment', 'keyTopics'], -}; - -const analyzer = new Agent({ - name: 'analyzer', - model: 'openai/gpt-4o', - instructions: 'Analyze the article and return structured data.', - outputType: ArticleAnalysis, -}); - -const result = await runtime.run(analyzer, 'Analyze: "Quantum Error Correction Hits 99.9% Fidelity"'); -const structured = result.output['result'] as Record; -console.log(structured.category, structured.sentiment); -``` - -## Credentials and secrets - -Pass credential names with `credentials: [...]` at the agent level and/or per tool. The server resolves secrets when it polls each task and delivers them **wire-only**, on that task's `runtimeMetadata` — never persisted, never fetched by the worker separately. The SDK injects them into the worker's `process.env` for the duration of the call (mutate-invoke-restore, serialized so concurrent calls don't clobber each other's env). For HTTP/MCP tools, reference them inline in headers with `${NAME}` substitution. - -**Fail-closed, no fallback:** if a tool declares `credentials: [...]` and the server didn't deliver one of them on `runtimeMetadata` (e.g. an older server that predates `TaskDef.runtimeMetadata` support — conductor-oss PR #1255 / agentspan server > 0.4.2), the task fails with a non-retryable error naming the missing credential. There is no ambient-env fallback to silently read a locally-set variable instead. - -```ts -import { Agent, tool, httpTool, getCredential } from '@io-orkes/conductor-javascript/agents'; - -// A worker tool: the secret is injected into the worker's process.env for the call -const dbLookup = tool( - async (args: { query: string }) => { - const key = process.env.DB_API_KEY ?? ''; - return { ok: key !== '' }; - }, - { - name: 'db_lookup', - description: 'Look up data.', - inputSchema: { type: 'object', properties: { query: { type: 'string' } }, required: ['query'] }, - credentials: ['DB_API_KEY'], - }, -); - -// Or fetch a credential explicitly inside a tool -const analytics = tool( - async (args: { topic: string }) => { - const key = await getCredential('ANALYTICS_KEY'); - return { topic: args.topic, ok: !!key }; - }, - { name: 'analytics', description: 'Query analytics.', inputSchema: { - type: 'object', properties: { topic: { type: 'string' } }, required: ['topic'], - }, credentials: ['ANALYTICS_KEY'] }, -); - -// HTTP tool with ${CRED} header substitution -const searchApi = httpTool({ - name: 'search_api', - description: 'Search.', - url: 'https://api.example.com/search', - headers: { Authorization: 'Bearer ${SEARCH_API_KEY}' }, - credentials: ['SEARCH_API_KEY'], -}); - -const agent = new Agent({ - name: 'credentialed_agent', - model: 'anthropic/claude-sonnet-4-6', - instructions: '…', - tools: [dbLookup, analytics, searchApi], - credentials: ['DB_API_KEY', 'ANALYTICS_KEY', 'SEARCH_API_KEY'], -}); -``` - -You can also pass `credentials` at call time: `runtime.run(agent, prompt, { credentials: ['X'] })`. - -## RunSettings — per-run LLM overrides - -`RunOptions.runSettings` overrides the LLM call for a single `run`/`start`/`stream`, without touching the agent's own config. Only set fields override; unset fields keep the agent's own serialized values, and the override doesn't cascade to sub-agents (each keeps its own settings). - -```ts -import type { RunSettings } from '@io-orkes/conductor-javascript/agents'; - -const result = await runtime.run(agent, prompt, { - runSettings: { - model: 'anthropic/claude-sonnet-4-6', // overrides agent.model for this run - temperature: 0.2, - maxTokens: 4096, - reasoningEffort: 'high', - thinkingBudgetTokens: 8000, // maps to the wire thinkingConfig shape - }, -}); - -// RunOptions.model is sugar for runSettings.model -- an explicit runSettings.model wins: -await runtime.run(agent, prompt, { model: 'openai/gpt-4o-mini' }); -``` - -## Plans / PLAN_EXECUTE - -`strategy: 'plan_execute'` runs a planner sub-agent to produce a JSON plan, then executes it deterministically as a sub-workflow. You **must** provide a `planner` agent (and may provide a `fallback`): - -```ts -const harness = new Agent({ - name: 'plan_harness', - model: 'openai/gpt-4o', - strategy: 'plan_execute', - planner: plannerAgent, // required — produces the JSON plan - fallback: agenticAgent, // optional — runs agentically if the plan can't compile/run - tools: [/* tools the plan steps call */], -}); -const result = await runtime.run(harness, 'Build a release report.'); -``` - -You can also supply a **deterministic static plan** with the typed builders and pass it via `RunOptions.plan` — it wins over the planner's output (the planner still runs, but its output is discarded): - -```ts -import { Plan, Step, Op, Generate, Ref } from '@io-orkes/conductor-javascript/agents'; - -const plan = new Plan({ - steps: [ - new Step('fetch', { operations: [new Op('fetch_data', { args: { source: 'db' } })] }), - new Step('summarize', { - dependsOn: ['fetch'], - operations: [new Op('summarize', { - generate: new Generate({ - instructions: 'Summarize the fetched data.', - outputSchema: '{"type":"object","properties":{"summary":{"type":"string"}}}', - context: new Ref('fetch'), // reference a prior step's output - }), - })], - }), - ], -}); - -const result = await runtime.run(harness, 'Run the pipeline.', { plan }); -``` - -Builders: `Plan({ steps, validation?, onSuccess?, onFailure? })`, `Step(id, { operations?, dependsOn?, parallel? })`, `Op(tool, { args? | generate? })`, `Generate({ instructions, outputSchema, maxTokens?, context? })`, `Validation(tool, { args?, successCondition? })`, `Action(tool, { args? })`, `Ref(stepId)`, `Context({ text? | url?, headers?, required?, maxBytes? })`. - -For planner reference docs, set `plannerContext: [...]` on the agent (strings or `Context` instances; URLs are fetched at runtime, no recompile). - -## Skills - -`skill(path, options?)` loads a `SKILL.md` skill directory as an `Agent`; `loadSkills(dir)` loads every skill subdirectory keyed by name. Skills are framework agents (`_framework: "skill"`) and run via the same `run()` path; they can be wrapped with `agentTool` and used inside other agents. - -```ts -import { skill, loadSkills, agentTool, Agent } from '@io-orkes/conductor-javascript/agents'; - -const reviewer = skill('./skills/code-review', { model: 'openai/gpt-4o' }); -const all = loadSkills('./skills'); // Record - -const orchestrator = new Agent({ - name: 'lead', - model: 'anthropic/claude-sonnet-4-6', - instructions: 'Delegate reviews to the code-review skill.', - tools: [agentTool(reviewer)], -}); -``` - -## See also - -- [api-reference.md](api-reference.md) — the full public surface. -- [writing-agents.md](writing-agents.md) — schedules, HITL, guardrails, callbacks. +- [Deploy · Serve · Run · Plan](concepts/deploy-serve-run.md) — runtime lifecycle, production pattern, `plan_execute` +- [Structured output](concepts/structured-output.md) +- [Runtime reference](reference/runtime.md) and [control plane](reference/client.md) +- [Credentials and secrets](reference/api.md#credentials-and-secrets) and [Skills](reference/api.md#skills) diff --git a/docs/agents/api-reference.md b/docs/agents/api-reference.md index c9b54f9f..404d6f56 100644 --- a/docs/agents/api-reference.md +++ b/docs/agents/api-reference.md @@ -1,341 +1,9 @@ # API Reference -The public surface of `@io-orkes/conductor-javascript/agents`. One section per type. Everything here is exported from the package root unless noted. +This page has moved to: -## AgentRuntime - -Core execution runtime. Manages agent lifecycle and local tool workers. - -```ts -new AgentRuntime(configuration?: OrkesApiConfig | ConductorClient, settings?: AgentConfigOptions) -``` - -`configuration` is connection/auth (the same shape as every other Conductor client, or a pre-built `ConductorClient` to share one client and one token mint across control- and worker-plane calls); `settings` is behavior-only (see [AgentConfig / AgentConfigOptions](#agentconfig--agentconfigoptions)). Both are optional. - -| Member | Signature | Notes | -|---|---|---| -| `config` | `AgentConfig` | Resolved behavior config (readonly). | -| `client` | `AgentClient` | Control-plane client (`/agent/*`) — shares the runtime's underlying Conductor client. | -| `workflows` | `WorkflowClient` | Read-only workflow executions. | -| `run` | `(agent, prompt, options?) => Promise` | Compile + start + stream + return result. Registers local workers. | -| `start` | `(agent, prompt, options?) => Promise` | Async interaction handle. | -| `stream` | `(agent, prompt, options?) => Promise` | Event stream. | -| `deploy` | `(agent, { schedules? }?) => Promise` \| `(...agents) => Promise` | Register workflow def(s) (+ reconcile schedules in the single-agent form). No execution, no workers. | -| `plan` | `(agent) => Promise` | Compile to workflow def without executing. | -| `serve` | `(...agents, options?: ServeOptions) => Promise` | Deploys the given agents, registers workers, starts polling. Blocks until SIGINT/SIGTERM by default; `{ blocking: false }` returns once deploy + registration + polling have started. | -| `getStatus` | `(executionId, signal?) => Promise` | Current execution status. | -| `schedulesClient` | `() => SchedulerClient` | Schedule lifecycle client (the SDK scheduler client). | -| `shutdown` | `() => Promise` | Stop worker polling. | - -`agent` is an `Agent` or a detected framework object. `options?: RunOptions` on `run`/`start`/`stream` includes `runSettings` (see [RunSettings](#runsettings)). Module-level helpers `configure(configuration?, settings?)`, `run`, `start`, `stream`, `deploy`, `plan`, `serve`, `shutdown` operate on a shared singleton runtime. - -## AgentClient - -`AgentClient` is the interface for the `/agent/*` control-plane HTTP surface (11 ops + `close()`); `OrkesAgentClient` is the Conductor/Orkes implementation, which also carries the agent-level convenience methods below (`run`, `start`, `deploy`, `schedule`) and the `workflows`/`schedules` accessors. **Does not run local tool workers.** Every op rides the shared `ConductorClient`'s authenticated call path — no bespoke auth/transport logic lives behind this interface, so it never mints a token independently. - -```ts -new OrkesAgentClient(configuration?: OrkesApiConfig | ConductorClient) -``` - -Obtain one via `runtime.client` (shares the runtime's client) or `OrkesClients.getAgentClient()` (shares whatever `Client` the `OrkesClients` instance was built with). - -| Member | Signature | Notes | -|---|---|---| -| `workflows` | `WorkflowClient` | Read-only workflow client. | -| `schedules` | `SchedulerClient` | Cron lifecycle client (SDK scheduler client over the shared Conductor client). | -| `run` | `(agent, prompt, opts?) => Promise` | Compile + start + poll to result. | -| `start` | `(agent, prompt, opts?) => Promise` | Compile + start; returns a handle. | -| `deploy` | `(agent, { schedules? }?) => Promise` \| `(...agents) => Promise` | Compile + register agent(s) (+ reconcile schedules in the single-agent form). | -| `schedule` | `(agent, schedules) => Promise` | Deploy + reconcile schedules. | -| `startAgent` / `deployAgent` / `compile` | `(payload, signal?) => Promise` | Low-level POST endpoints (spec R1 surface). | -| `status` | `(executionId, signal?) => Promise` | GET status. | -| `getExecution` | `(executionId, signal?) => Promise` | Full execution data (tasks, output, tokens). | -| `listExecutions` | `(params?, signal?) => Promise` | List executions, optionally filtered. | -| `respond` | `(executionId, body, signal?) => Promise` | Complete a pending human task. | -| `stop` | `(executionId, signal?) => Promise` | Stop a running execution. | -| `signal` | `(executionId, message, signal?) => Promise` | Inject persistent context into a running execution. | -| `stream` | `(executionId, lastEventId?, signal?) => Promise` | SSE stream for an execution. | -| `close` | `() => Promise` | Release this client's open `AgentStream`s. | - -### ClientHandle - -Returned by `AgentClient.start`. `{ executionId, getStatus(), wait(pollIntervalMs?), respond(output), approve(output?), reject(reason?), send(message), stop(), stream() }`. `wait()` rejects once its deadline passes (`timeoutSeconds`-derived, or 10 min default) with an `AgentAPIError` naming the last known status. - -## WorkflowClient - -Read-only client for Conductor workflow executions. Available as `runtime.workflows`. - -| Method | Signature | Notes | -|---|---|---| -| `getWorkflow` | `(executionId, includeTasks = true) => Promise` | Full execution (with tasks). | -| `getStatus` | `(executionId) => Promise` | `'RUNNING'` / `'COMPLETED'` / ... or `''`. | -| `extractTokenUsage` | `(executionId) => Promise` | Aggregated across sub-workflows. | - -`WorkflowTokenUsage` = `{ promptTokens, completionTokens, totalTokens }`. - -## AgentConfig / AgentConfigOptions - -Behavior-only — no connection/auth fields (those live on `OrkesApiConfig`, the `AgentRuntime`/`OrkesAgentClient` constructors' first argument). - -```ts -interface AgentConfigOptions { - workerPollIntervalMs?: number; // AGENTSPAN_WORKER_POLL_INTERVAL (100) - workerThreadCount?: number; // AGENTSPAN_WORKER_THREADS (1) - autoStartWorkers?: boolean; // AGENTSPAN_AUTO_START_WORKERS (true) - streamingEnabled?: boolean; // AGENTSPAN_STREAMING_ENABLED (true) - livenessEnabled?: boolean; // AGENTSPAN_LIVENESS_ENABLED (true) - livenessStallSeconds?: number; // AGENTSPAN_LIVENESS_STALL_SECONDS (30) - livenessCheckIntervalSeconds?: number; // AGENTSPAN_LIVENESS_CHECK_INTERVAL_SECONDS (10) -} -``` - -`AgentConfig.fromEnv()` is an exported helper (equivalent to `new AgentConfig()`). See [Liveness monitoring](writing-agents.md#liveness-monitoring) for the liveness fields. - -## Agent / agent() - -```ts -new Agent(options: AgentOptions) -``` - -Key `AgentOptions` fields: - -| Field | Type | Notes | -|---|---|---| -| `name` | `string` | Required. `/^[a-zA-Z][a-zA-Z0-9_-]*$/`. | -| `model` | `string \| ClaudeCode` | e.g. `'anthropic/claude-sonnet-4-6'`. | -| `baseUrl` | `string` | Override LLM provider base URL. | -| `instructions` | `string \| PromptTemplate \| (() => string)` | Static / template / dynamic. | -| `tools` | `unknown[]` | `tool()` wrappers, built-in tool defs, framework tools. | -| `agents` | `Agent[]` | Sub-agents (multi-agent). | -| `strategy` | `Strategy` | `'sequential' \| 'parallel' \| 'handoff' \| 'router' \| 'round_robin' \| 'random' \| 'swarm' \| 'manual' \| 'plan_execute'`. | -| `router` | `Agent \| (() => string)` | Required for `strategy: 'router'`. | -| `outputType` | Zod schema or JSON Schema | Structured output. | -| `guardrails` | `unknown[]` | Guardrail defs / instances. | -| `handoffs` | `HandoffCondition[]` | `OnTextMention` / `OnToolResult` / `OnCondition`. | -| `allowedTransitions` | `Record` | Constrain agent transitions. | -| `termination` | `TerminationCondition` | Stop condition. | -| `gate` | `GateCondition` | `TextGate` / `gate()`. | -| `callbacks` | `CallbackHandler[]` | Lifecycle hooks. | -| `memory` | `ConversationMemory` | Conversation history. | -| `maxTurns` | `number` | Default 25. | -| `maxTokens` / `temperature` / `timeoutSeconds` | `number` | LLM + execution tuning. | -| `credentials` | `string[]` | Secret names to resolve. | -| `stateful` | `boolean` | Per-execution worker isolation + shared state. | -| `planner` / `fallback` | `Agent` | PLAN_EXECUTE named slots. | -| `plannerContext` | `(string \| Context \| object)[]` | PLAN_EXECUTE reference docs. | -| `enablePlanning` | `boolean` | Plan-first preamble. | -| `prefillTools` | `PrefillToolCall[]` | Tools run before the first LLM turn. | -| `cliCommands` / `cliAllowedCommands` / `cliConfig` | — | Enable CLI command execution. | -| `codeExecutionConfig` | `CodeExecutionConfig` | Code execution. | -| `introduction` / `metadata` | — | Agent metadata. | - -Methods: `agent.pipe(other)` builds a sequential pipeline (flattens chains). Getters: `isClaudeCode`, `claudeCodeConfig`. - -Helpers: -- `agent(fn, options)` — functional form; `fn` is the dynamic-instructions callable. -- `scatterGather({ name, workers, model?, instructions?, retryCount?, retryDelaySeconds?, failFast?, timeoutSeconds? })` — coordinator that fans out to worker agents in parallel. -- `AgentDec(options)` + `agentsFrom(instance)` — define agents as decorated class methods. -- `PromptTemplate(name, variables?, version?)` — server-managed prompt reference. - -## tool() and built-in tools - -```ts -tool(fn: (args, ctx?: ToolContext) => Promise, options: ToolOptions): ToolFunction -``` - -`ToolOptions`: `{ name?, description, inputSchema, outputSchema?, approvalRequired?, timeoutSeconds?, external?, credentials?, guardrails?, maxCalls?, retryCount?, retryDelaySeconds?, retryPolicy? }`. `inputSchema`/`outputSchema` accept a Zod schema or a JSON Schema object. - -Built-in tool builders (all return a `ToolDef`): - -| Builder | Required options | toolType | -|---|---|---| -| `httpTool` | `name, description, url` (`method?, headers?, inputSchema?, credentials?`) | `http` | -| `mcpTool` | `serverUrl` (`name?, headers?, toolNames?, maxTools?, credentials?`) | `mcp` | -| `apiTool` | `url` (`name?, headers?, toolNames?, maxTools?, credentials?`) | `api` | -| `agentTool` | `agent` (`name?, description?, retryCount?, retryDelaySeconds?, optional?`) | `agent_tool` | -| `humanTool` | `name, description` (`inputSchema?`) | `human` | -| `imageTool` | `name, description, llmProvider, model` (`style?, size?`) | `generate_image` | -| `audioTool` | `name, description, llmProvider, model` (`voice?, speed?, format?`) | `generate_audio` | -| `videoTool` | `name, description, llmProvider, model` (`duration?, resolution?, fps?, ...`) | `generate_video` | -| `pdfTool` | — (`name?, description?, pageSize?, theme?, fontSize?`) | `generate_pdf` | -| `waitForMessageTool` | `name, description` (`batchSize?` def 1, `blocking?` def true) | `pull_workflow_messages` | -| `searchTool` | `name, description, vectorDb, index, embeddingModelProvider, embeddingModel` (`namespace?, maxResults?, dimensions?`) | `rag_search` | -| `indexTool` | `name, description, vectorDb, index, embeddingModelProvider, embeddingModel` (`namespace?, chunkSize?, chunkOverlap?, dimensions?`) | `rag_index` | - -Discovery / helpers: `Tool(options?)` decorator + `toolsFrom(instance)`; `getToolDef(obj)` / `normalizeToolInput(obj)` (extract a `ToolDef` from a `tool()` wrapper, Vercel AI tool, or raw def); `isZodSchema(obj)`. - -### ToolContext - -Passed as the second arg to a `tool()` function: - -```ts -interface ToolContext { - sessionId: string; - executionId: string; - agentName: string; - metadata: Record; - dependencies: Record; - state: Record; // mutable; mutations propagate between tool calls -} -``` - -## Guardrails - -- `guardrail(fn, { name, position?, onFail?, maxRetries? })` — custom guardrail from a function returning `{ passed, message?, fixedOutput? }`. `guardrail.external({ name, position?, onFail? })` for remote-worker guardrails. -- `new RegexGuardrail({ name, patterns, mode, position?, onFail?, message?, maxRetries? })` — `mode: 'block' | 'allow'`. `.toGuardrailDef()`. -- `new LLMGuardrail({ name, model, policy, position?, onFail?, maxRetries?, maxTokens? })` — server-side LLM judge. `.toGuardrailDef()`. -- `Guardrail(options?)` decorator + `guardrailsFrom(instance)`. - -`position`: `'input' | 'output'` (default `'output'`). `onFail`: `'raise' | 'retry' | 'fix' | 'human'` (default `'raise'`). Attach via `agent.guardrails` or `tool(fn, { guardrails })`. - -## Termination - -All extend `TerminationCondition` and compose via `.and(other)` / `.or(other)` (or variadic `AndCondition(...)` / `OrCondition(...)`). - -| Class | Constructor | -|---|---| -| `TextMention` | `(text, caseSensitive = false)` | -| `StopMessage` | `(stopMessage)` | -| `MaxMessage` | `(maxMessages)` | -| `TokenUsageCondition` | `({ maxTotalTokens?, maxPromptTokens?, maxCompletionTokens? })` | -| `AndCondition` / `OrCondition` | `(...conditions)` | - -## Handoffs - -- `new OnTextMention({ target, text })` — hand off when output mentions `text` (case-insensitive). -- `new OnToolResult({ target, toolName, resultContains? })` — hand off after a tool returns. -- `new OnCondition({ target, condition, agentName? })` — hand off when a predicate (runs as a worker) returns true. -- `new TextGate({ text, caseSensitive? })` — gate on text containment (`gate:` option). -- `gate(fn, { agentName? })` — custom gate from a function. - -`HandoffContext` (passed to conditions): `{ result, toolName?, toolResult?, messages? }`. - -## Callbacks - -Subclass `CallbackHandler` and override hooks (each runs as a server worker): - -```ts -abstract class CallbackHandler { - onAgentStart?(agentName, prompt): Promise; - onAgentEnd?(agentName, result): Promise; - onModelStart?(agentName, messages): Promise; - onModelEnd?(agentName, response): Promise; - onToolStart?(agentName, toolName, args): Promise; - onToolEnd?(agentName, toolName, result): Promise; -} -``` - -`CALLBACK_POSITIONS` maps hook names to wire positions; `getCallbackWorkerNames(agentName, handler)` lists registered worker names. - -## Schedules / SchedulerClient - -```ts -new Schedule({ name, cron, timezone?, input?, catchup?, paused?, startAt?, endAt?, description? }) -``` - -Agent schedules ride the SDK `SchedulerClient` (also available via `OrkesClients.getSchedulerClient()`). Its typed lifecycle methods: `save(schedule, agentName)`, `get(wireName, agentName?)`, `listForAgent(agentName)`, `pause(wireName, reason?)`, `resume(wireName)`, `delete(wireName)`, `runNow(info)`, `previewNext(cron, { n?, startAt?, endAt? })`, `reconcile(agentName, desired)` — plus the endpoint-level wrappers (`saveSchedule`, `getSchedule`, `pauseSchedule`, ...). Pause/resume issue PUT first and fall back to GET on HTTP 405 (per-schedule verbs differ by Conductor server family), so one client works against both OSS/embedded and Orkes servers. - -The `schedules` namespace is a convenience layer over the singleton runtime: `schedules.list({ agent })`, `.get(name, { runtime? })`, `.pause(name, { reason?, runtime? })`, `.resume`, `.delete`, `.runNow`, `.previewNext(cron, { n? })`, `.save(schedule, agent)`. Lifecycle calls key on the **wire name** (the prefixed `name` in `ScheduleInfo`). - -Errors: `ScheduleError`, `ScheduleNameConflict`, `ScheduleNotFound`, `InvalidCronExpression`. `ScheduleInfo` includes `name`, `shortName`, `agent`, `cron`, `timezone`, `paused`, `pausedReason`, `nextRun`, ... - -## AgentResult - -Returned by `run()` / `wait()`. - -```ts -interface AgentResult { - output: Record; // text answer -> { result: "..." } - executionId: string; - correlationId?: string; - messages: unknown[]; - toolCalls: unknown[]; - status: 'COMPLETED' | 'FAILED' | 'TERMINATED' | 'TIMED_OUT'; - finishReason: 'stop' | 'length' | 'tool_calls' | 'error' | 'cancelled' | 'timeout' | 'guardrail' | 'rejected'; - error?: string; - tokenUsage?: { promptTokens; completionTokens; totalTokens }; - metadata?: Record; - events: AgentEvent[]; - subResults?: Record; - readonly isSuccess: boolean; // status === 'COMPLETED' - readonly isFailed: boolean; // FAILED | TIMED_OUT - readonly isRejected: boolean; // finishReason === 'rejected' - printResult(): void; -} -``` - -## AgentHandle - -Returned by `runtime.start()`. - -```ts -interface AgentHandle { - executionId: string; - correlationId: string; - getStatus(): Promise; - wait(pollIntervalMs?): Promise; - respond(output): Promise; - approve(output?): Promise; - reject(reason?): Promise; - send(message): Promise; - pause(): Promise; - resume(): Promise; - cancel(): Promise; - stop(): Promise; - stream(): AgentStream; -} -``` - -`approve()` sends `{ approved: true, ...output }`; `reject(reason)` sends `{ approved: false, reason }`; `send(message)` sends `{ message }`. For a custom human-task response (shaped by `pendingTool.response_schema`), use `respond(body)`. `wait(pollIntervalMs?)` rejects once its deadline passes (`timeoutSeconds`-derived, or 10 min default) with an `AgentAPIError` naming the last known status — and, for a stateful (domain-routed) run with liveness enabled, rejects earlier with `WorkerStallError` if the local worker appears to have died (see [Liveness monitoring](writing-agents.md#liveness-monitoring)). - -## AgentStream / AgentEvent - -`AgentStream` implements `AsyncIterable` — iterate with `for await`. Methods: `respond(output)`, `approve(output?)`, `reject(reason?)`, `send(message)`, and `getResult(): Promise` (drains the stream, polls for the terminal status, returns the result). Fields: `executionId`, `events` (accumulates). - -```ts -interface AgentEvent { - type: 'thinking' | 'tool_call' | 'tool_result' | 'guardrail_pass' | 'guardrail_fail' - | 'waiting' | 'handoff' | 'message' | 'error' | 'done' | string; - content?: string; - toolName?: string; - args?: Record; - result?: unknown; - target?: string; // handoff target - output?: unknown; // on 'done' - pendingTool?: PendingTool;// on 'waiting' - guardrailName?: string; -} -``` - -`AgentStatus`: `{ executionId, isComplete, isRunning, isWaiting, output?, status, reason?, currentTask?, messages, pendingTool? }`. `PendingTool`: `{ taskRefName, toolCalls?: { name, args }[], response_schema?, ... }`. `EventTypes`, `Statuses`, `FinishReasons`, `TERMINAL_STATUSES` enums are exported. - -## Errors - -`AgentspanError` (base), `AgentAPIError`, `AgentNotFoundError`, `ConfigurationError`, `CredentialNotFoundError`, `CredentialAuthError`, `CredentialRateLimitError`, `CredentialServiceError`, `SSETimeoutError`, `TerminalToolError`, `WorkerStallError`, `GuardrailFailedError`. - -## RunSettings - -Per-run LLM overrides, passed as `RunOptions.runSettings` to `run`/`start`/`stream`. See [Advanced: RunSettings](advanced.md#runsettings--per-run-llm-overrides). - -```ts -interface RunSettings { - model?: string; - temperature?: number; - maxTokens?: number; - reasoningEffort?: string; - thinkingBudgetTokens?: number; -} -``` - -## Other exports - -- **Memory:** `ConversationMemory`, `SemanticMemory`, `InMemoryStore`. -- **Plans:** `Plan`, `Step`, `Op`, `Generate`, `Validation`, `Action`, `Ref`, `Context`, `coercePlan`. -- **Skills:** `skill(path, options?)`, `loadSkills(dir, options?)`, `SkillLoadError`. -- **Credentials:** `getCredential`, `runWithCredentialContext`, `setCredentialContext`, `clearCredentialContext`. Values arrive wire-only on the polled task's `runtimeMetadata` (spec R6) — never fetched separately; see [Credentials and secrets](advanced.md#credentials-and-secrets). -- **Liveness:** `LivenessMonitor`, `LivenessMonitorOptions` — see [Liveness monitoring](writing-agents.md#liveness-monitoring). -- **Code execution:** `LocalCodeExecutor`, `DockerCodeExecutor`, `JupyterCodeExecutor`, `ServerlessCodeExecutor`, `CodeExecutor`, `CommandValidator`. -- **Claude Code:** `ClaudeCode(modelName?, permissionMode?)`, `PermissionMode`, `resolveClaudeCodeModel`. -- **Extended agents:** `GPTAssistantAgent({ name, assistantId, model?, instructions? })`. -- **Framework integration:** `detectFramework`, `serializeFrameworkAgent`, `serializeLangGraph`, `serializeLangChain`. -- **Subpath exports:** `@io-orkes/conductor-javascript/agents/vercel-ai`, `@io-orkes/conductor-javascript/agents/langgraph`, `@io-orkes/conductor-javascript/agents/langchain`, `@io-orkes/conductor-javascript/agents/testing`. +- [Agent definition fields](reference/agent-definition.md) — `Agent`/`agent()` options +- [Agent schema](reference/agent-schema.md) — the wire contract +- [Runtime reference](reference/runtime.md) — `AgentRuntime`, `AgentConfig` +- [Control plane](reference/client.md) — `AgentClient`, `WorkflowClient` +- [API map](reference/api.md) — tools, guardrails, termination, handoffs, callbacks, schedules, results, errors, and everything else diff --git a/docs/agents/concepts/agents.md b/docs/agents/concepts/agents.md new file mode 100644 index 00000000..fd207de5 --- /dev/null +++ b/docs/agents/concepts/agents.md @@ -0,0 +1,98 @@ +# Defining agents + +Everything you author is an `Agent`. A simple LLM agent, a tool-using agent, and +a multi-agent orchestration are all the same `Agent` class with different +options. + +All snippets import from `@io-orkes/conductor-javascript/agents` and assume a +runtime: + +```ts +import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; +const runtime = new AgentRuntime(); +``` + +## Defining an agent + +```ts +const agent = new Agent({ + name: 'greeter', // required; must match /^[a-zA-Z][a-zA-Z0-9_-]*$/ + model: 'anthropic/claude-sonnet-4-6', // provider/model string + instructions: 'Keep answers short.', + temperature: 0.7, + maxTurns: 25, // default 25 + maxTokens: 2048, + timeoutSeconds: 0, // 0 = server default +}); +``` + +There is also a functional form, `agent(fn, options)`, where `fn` is the +dynamic-instructions callable (see below): + +```ts +import { agent } from '@io-orkes/conductor-javascript/agents'; + +const a = agent(() => 'You are a helpful assistant.', { + name: 'helper', + model: 'anthropic/claude-sonnet-4-6', +}); +``` + +### Instructions + +Instructions can be a plain string, a callable, or a server-managed prompt +template. + +```ts +// Static +new Agent({ name: 'a', model, instructions: 'You are concise.' }); + +// Dynamic (callable) — evaluated to a string when the agent is serialized +new Agent({ name: 'a', model, instructions: () => `Today is ${new Date().toDateString()}.` }); + +// Server-managed prompt template (referenced by name + version) +import { PromptTemplate } from '@io-orkes/conductor-javascript/agents'; +new Agent({ + name: 'a', + model, + instructions: new PromptTemplate('support_greeting', { brand: 'Acme' }, 1), +}); +``` + +An omitted `model` is valid only for inherited-model designs (a sub-agent that +takes its model from its parent) or external-agent designs (`external: true`). + +## Agent-from-method (`@AgentDec` / `agentsFrom`) + +Define agents as decorated methods on a class and extract them: + +```ts +import { AgentDec, agentsFrom } from '@io-orkes/conductor-javascript/agents'; + +class MyAgents { + @AgentDec({ name: 'summarizer', model: 'anthropic/claude-sonnet-4-6', instructions: 'Summarize text.' }) + summarize() {} + + @AgentDec({ name: 'classifier', model: 'anthropic/claude-sonnet-4-6', instructions: 'Classify text.' }) + classify() {} +} + +const [summarizer, classifier] = agentsFrom(new MyAgents()); // Agent[] +``` + +> `@AgentDec`/`@Tool` are TypeScript experimental decorators — set +> `"experimentalDecorators": true` in your `tsconfig.json`. + +## Common failures + +- A model error normally means the provider credential or model is missing on + the **server**, not merely in the local process. +- A `name` that doesn't match `^[a-zA-Z][a-zA-Z0-9_-]*$` is rejected at + serialization time. + +## Next steps + +Use [tools](tools.md) for capabilities, [multi-agent](multi-agent.md) for +composition, and [runtime modes](deploy-serve-run.md) for deployment. See the +[Agent definition reference](../reference/agent-definition.md) for the full +options table. diff --git a/docs/agents/concepts/callbacks.md b/docs/agents/concepts/callbacks.md new file mode 100644 index 00000000..1a260045 --- /dev/null +++ b/docs/agents/concepts/callbacks.md @@ -0,0 +1,34 @@ +# Callbacks + +Subclass `CallbackHandler` and override the lifecycle hooks you care about. +Each hook runs as a server-registered worker. + +```ts +import { CallbackHandler } from '@io-orkes/conductor-javascript/agents'; + +class Logger extends CallbackHandler { + async onAgentStart(agentName: string, prompt: string) { console.log('[start]', agentName, prompt); } + async onToolStart(agentName: string, toolName: string, args: unknown) { console.log('[tool]', toolName, args); } + async onAgentEnd(agentName: string, result: unknown) { console.log('[end]', agentName); } +} + +const agent = new Agent({ name: 'a', model, instructions: '…', callbacks: [new Logger()] }); +``` + +Hooks: `onAgentStart`, `onAgentEnd`, `onModelStart`, `onModelEnd`, +`onToolStart`, `onToolEnd`. + +## Expected behavior and failures + +Keep callback work fast and non-blocking — move durable business effects +(writes, notifications, audit records) into a `tool()` or a workflow task +instead. Callbacks observe lifecycle events without changing the durable +workflow unless they explicitly throw; don't rely on them as the sole record +of an audit or external write, since a process restart can interrupt a local +observer mid-callback. Treat callback payloads (messages, tool args/results) +as potentially sensitive execution data — redact credentials before logging. + +## Next steps + +Use [streaming](streaming-hitl.md) for caller-visible progress events and +[tools](tools.md) for durable side effects. diff --git a/docs/agents/concepts/deploy-serve-run.md b/docs/agents/concepts/deploy-serve-run.md new file mode 100644 index 00000000..d3a89d87 --- /dev/null +++ b/docs/agents/concepts/deploy-serve-run.md @@ -0,0 +1,122 @@ +# Deploy · Serve · Run · Plan + +`new AgentRuntime(configuration?, settings?)` takes two independent, optional +arguments — `configuration` (connection/auth, same shape as every other +Conductor client) and `settings` (behavior-only: worker/streaming/liveness +tuning). Both fall back to env vars, then defaults; see the +[runtime reference](../reference/runtime.md) for the full option list. + +```ts +import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; + +const runtime = new AgentRuntime(); // reads connection + behavior entirely from env +``` + +## deploy vs serve vs run vs plan + +| Method | What it does | Local workers? | +|---|---|---| +| `runtime.run(agent, prompt, opts?)` | Compile + start + stream + return an `AgentResult`. | Yes — registers and polls local `tool()` workers for the run. | +| `runtime.start(agent, prompt, opts?)` | Same as `run` but returns an `AgentHandle` for async interaction (stream, approve, pause, ...). | Yes. | +| `runtime.stream(agent, prompt, opts?)` | `start` + return its `AgentStream`. | Yes. | +| `runtime.deploy(agent, { schedules? })` | Compile + register the workflow definition on the server. No execution, no workers. CI/CD step. Returns `DeploymentInfo`. | No. | +| `runtime.deploy(...agents)` | Variadic form: compile + register multiple agents in one call, no schedules reconciliation. Returns `DeploymentInfo[]`. | No. | +| `runtime.serve(...agents, { blocking? })` | Deploys the given agents (same registration as `deploy`), registers their local tool workers, and starts polling. Blocks until SIGINT/SIGTERM by default; pass a trailing `{ blocking: false }` to return once deploy + registration + polling have started. With no agents, just (re)starts polling for workers already registered. | Yes (and keeps them alive when blocking). | +| `runtime.plan(agent)` | Compile to a workflow definition and return it, without executing. | No. | +| `runtime.shutdown()` | Stop worker polling. | — | + +`serve()` already deploys, so a standalone `deploy()` call beforehand is +optional — only worth doing when you want registration decoupled from worker +start-up (e.g. a dedicated CI/CD step). + +## Production pattern + +Compile/register with `deploy()` during a release step (or let `serve()` do +it), then run one or more long-lived `serve()` worker processes for the tool +workers. Trigger executions via the control plane +(`runtime.client.run(...)`/`start(...)`) or schedules — not by calling +`run()` from inside the worker process itself. Use `plan()` in CI to inspect +the compiled workflow definition before it's deployed. + +```ts +// Long-lived worker process -- deploys + registers workers + starts polling +await runtime.serve(myAgent); // blocks + +// Trigger (control plane, no local workers needed for LLM-only / remote-tool agents) +const result = await runtime.client.run(myAgent, 'do the thing'); +``` + +Always call `shutdown()` (or dispose cleanly) for short-lived scripts so +worker polling actually stops; a long-lived `serve()` process is expected to +run until `SIGINT`/`SIGTERM`. + +### Recovering after a worker process restart + +There's no execution-scoped reattach call (no `resume(executionId)`). +Recovery is process-level: start a fresh `serve()` with no agents in the +replacement process — it resumes polling for whatever tool workers are +already registered on the server, covering every affected execution's domain +at once. See [stateful agents](stateful.md#recovering-after-a-worker-process-restart) +for how `WorkerStallError`/liveness monitoring surfaces the need to do this. + +## Plans / PLAN_EXECUTE + +`strategy: 'plan_execute'` runs a planner sub-agent to produce a JSON plan, +then executes it deterministically as a sub-workflow. You **must** provide a +`planner` agent (and may provide a `fallback`): + +```ts +const harness = new Agent({ + name: 'plan_harness', + model: 'openai/gpt-4o', + strategy: 'plan_execute', + planner: plannerAgent, // required — produces the JSON plan + fallback: agenticAgent, // optional — runs agentically if the plan can't compile/run + tools: [/* tools the plan steps call */], +}); +const result = await runtime.run(harness, 'Build a release report.'); +``` + +You can also supply a **deterministic static plan** with the typed builders +and pass it via `RunOptions.plan` — it wins over the planner's output (the +planner still runs, but its output is discarded): + +```ts +import { Plan, Step, Op, Generate, Ref } from '@io-orkes/conductor-javascript/agents'; + +const plan = new Plan({ + steps: [ + new Step('fetch', { operations: [new Op('fetch_data', { args: { source: 'db' } })] }), + new Step('summarize', { + dependsOn: ['fetch'], + operations: [new Op('summarize', { + generate: new Generate({ + instructions: 'Summarize the fetched data.', + outputSchema: '{"type":"object","properties":{"summary":{"type":"string"}}}', + context: new Ref('fetch'), // reference a prior step's output + }), + })], + }), + ], +}); + +const result = await runtime.run(harness, 'Run the pipeline.', { plan }); +``` + +Builders: `Plan({ steps, validation?, onSuccess?, onFailure? })`, +`Step(id, { operations?, dependsOn?, parallel? })`, `Op(tool, { args? | +generate? })`, `Generate({ instructions, outputSchema, maxTokens?, context? +})`, `Validation(tool, { args?, successCondition? })`, `Action(tool, { +args? })`, `Ref(stepId)`, `Context({ text? | url?, headers?, required?, +maxBytes? })`. + +For planner reference docs, set `plannerContext: [...]` on the agent +(strings or `Context` instances; URLs are fetched at runtime, no recompile). + +## Next steps + +- [Runtime reference](../reference/runtime.md) — the full `AgentRuntime`/ + `AgentConfig` API. +- [Control plane](../reference/client.md) — `AgentClient`/`WorkflowClient` + for callers without local tool workers. +- [Multi-agent](multi-agent.md) — the other composition strategies. diff --git a/docs/agents/concepts/guardrails.md b/docs/agents/concepts/guardrails.md new file mode 100644 index 00000000..7ba10628 --- /dev/null +++ b/docs/agents/concepts/guardrails.md @@ -0,0 +1,64 @@ +# Guardrails + +Guardrails validate input or output. Attach them at the agent level +(`guardrails: [...]`) or per-tool (`tool(fn, { guardrails: [...] })`). Each has +a `position` (`'input'` | `'output'`, default `'output'`) and an `onFail` +policy (`'raise'` | `'retry'` | `'fix'` | `'human'`, default `'raise'`). + +```ts +import { guardrail, RegexGuardrail, LLMGuardrail } from '@io-orkes/conductor-javascript/agents'; + +// Regex (runs on the server, no worker) +const noSecrets = new RegexGuardrail({ + name: 'no_api_keys', + patterns: ['sk-[A-Za-z0-9]{20,}'], + mode: 'block', // 'block' fails if any pattern matches; 'allow' fails if none match + onFail: 'raise', + message: 'Output contained a secret.', +}); + +// LLM (server-side LLM judge) +const policy = new LLMGuardrail({ + name: 'safety', + model: 'anthropic/claude-sonnet-4-6', + policy: 'Reject any content that gives medical dosage advice.', + position: 'output', + onFail: 'retry', + maxRetries: 2, +}); + +// Custom (your function, runs locally as a worker) +const minLength = guardrail( + (content: string) => ({ passed: content.length >= 10, message: 'Too short' }), + { name: 'min_length', position: 'output', onFail: 'fix' }, +); + +const agent = new Agent({ + name: 'safe_agent', + model, + instructions: '…', + guardrails: [noSecrets.toGuardrailDef?.() ?? noSecrets, policy.toGuardrailDef?.() ?? policy, minLength], +}); +``` + +`RegexGuardrail` / `LLMGuardrail` are class instances; the serializer accepts +the instance directly. There is also a `guardrail.external({ name, position?, +onFail? })` form for guardrails handled by a remote worker, and a +`@Guardrail` decorator with `guardrailsFrom(instance)`. + +## Patterns + +Use `RegexGuardrail` for deterministic format checks, `LLMGuardrail` for +semantic policy checks, and a custom `guardrail()` only when the rule needs +application state. Apply a tool-level guardrail closest to the side effect it +protects; use an agent-level guardrail for broad input/output policy. An +`onFail: 'retry'` policy is appropriate only when a new model response can +plausibly pass — don't retry on a guardrail whose failure reason can't change +between calls. Never send secrets or raw sensitive records into an +`LLMGuardrail`'s prompt; validate a redacted representation instead. + +## Next steps + +Use [termination](termination.md) conditions alongside guardrails to bound +retry loops, and see the [guardrails reference](../reference/api.md#guardrails) +for the complete option list. diff --git a/docs/agents/concepts/multi-agent.md b/docs/agents/concepts/multi-agent.md new file mode 100644 index 00000000..9a008c2f --- /dev/null +++ b/docs/agents/concepts/multi-agent.md @@ -0,0 +1,90 @@ +# Multi-agent composition + +Set `agents: [...]` and a `strategy`. Strategies: `'sequential'`, `'parallel'`, +`'handoff'`, `'router'`, `'round_robin'`, `'random'`, `'swarm'`, `'manual'`, +`'plan_execute'`. `'plan_execute'` runs a planner sub-agent that compiles a +typed, inspectable `Plan` into a durable sub-workflow instead of delegating +turn-by-turn — see [deploy/serve/run/plan](deploy-serve-run.md#plans--plan_execute) +for the planner/fallback setup and the `Plan`/`Step`/`Op` builders. + +```ts +// Sequential — agents run in order. .pipe() is sugar for strategy: 'sequential'. +const pipeline = writer.pipe(editor); +// equivalent to: +// new Agent({ name: 'writer_editor', agents: [writer, editor], strategy: 'sequential' }); + +// Parallel — agents run concurrently, results gathered +const team = new Agent({ name: 'research_team', agents: [webResearcher, dataAnalyst], strategy: 'parallel' }); + +// Handoff — the parent LLM delegates to sub-agents (they appear as callable tools) +const support = new Agent({ + name: 'support', + model, + instructions: 'Route to the right specialist.', + agents: [billingAgent, technicalAgent, salesAgent], + strategy: 'handoff', +}); + +// Router — a router agent (or function) picks the sub-agent +const routed = new Agent({ + name: 'router', + agents: [a, b], + strategy: 'router', + router: routerAgent, // an Agent or (…) => string returning a sub-agent name +}); +``` + +`scatterGather({ name, workers, ... })` is a convenience builder that returns a +coordinator agent which fans a problem out to worker agents in parallel and +synthesizes the results: + +```ts +import { scatterGather } from '@io-orkes/conductor-javascript/agents'; +const coordinator = scatterGather({ name: 'fanout', workers: [worker], retryCount: 2 }); +``` + +## Handoffs + +For `swarm`/`handoff` strategies you can declare explicit handoff transitions +with `handoffs: [...]`. Each condition has a `target` (a sub-agent name). + +```ts +import { OnTextMention, OnToolResult, OnCondition } from '@io-orkes/conductor-javascript/agents'; + +const team = new Agent({ + name: 'coding_team', + model, + agents: [pythonExpert, jsExpert], + strategy: 'swarm', + handoffs: [ + // Hand off when the output mentions text (case-insensitive) + new OnTextMention({ target: 'python_expert', text: 'Python' }), + + // Hand off when a specific tool returns (optionally only if result contains text) + new OnToolResult({ target: 'escalation', toolName: 'detect_severity', resultContains: 'critical' }), + + // Hand off when a custom predicate returns true (runs as a worker task) + new OnCondition({ target: 'fallback', condition: (ctx) => ctx.result.length > 1000 }), + ], +}); +``` + +You can also constrain which transitions are allowed with +`allowedTransitions: { agentName: ['otherAgent', ...] }`. + +## Expected result and failures + +Every child of `agents: [...]` is a durable sub-workflow, visible in +execution history on its own. Set a termination condition and a `maxTurns` +limit for every open-ended design (`handoff`/`router`/`swarm`) — an +unrestricted graph that loops has no other backstop. Use +`allowedTransitions` to restrict which specialists a handoff/swarm can reach, +so an unexpected model output can't route to an unsafe agent. + +## Next steps + +Use [termination](termination.md) to bound multi-agent loops (e.g. +`round_robin` debates), [stateful agents](stateful.md) for shared +per-execution state, [guardrails](guardrails.md) for per-agent/per-tool +validation, and the [handoffs reference](../reference/api.md#handoffs) for the +full condition-class list. diff --git a/docs/agents/concepts/scheduling.md b/docs/agents/concepts/scheduling.md new file mode 100644 index 00000000..d4b43dba --- /dev/null +++ b/docs/agents/concepts/scheduling.md @@ -0,0 +1,50 @@ +# Scheduling + +Attach cron schedules to an agent at deploy time. Reconciliation is +declarative: a list upserts those and prunes the rest; `[]` purges all; +omitting `schedules` leaves them untouched. + +```ts +import { Agent, AgentRuntime, Schedule, schedules } from '@io-orkes/conductor-javascript/agents'; + +const digest = new Agent({ name: 'eng_digest', model, instructions: 'Write a digest.' }); + +await runtime.deploy(digest, { + schedules: [ + new Schedule({ + name: 'weekday-9am', + cron: '0 0 9 * * MON-FRI', + timezone: 'America/Los_Angeles', + input: { channel: '#eng' }, + description: 'Weekday morning digest', + }), + ], +}); + +// Inspect / control via the `schedules` namespace +const infos = await schedules.list({ agent: digest.name }); +await schedules.pause(infos[0].name, { reason: 'cooldown' }); +await schedules.resume(infos[0].name); +const execId = await schedules.runNow(infos[0].name); +const next = await schedules.previewNext('0 0 9 * * MON-FRI', { n: 5 }); + +await runtime.deploy(digest, { schedules: [] }); // purge all +``` + +Lifecycle calls (`get`/`pause`/`resume`/`delete`/`runNow`) key on the **wire +name** (the prefixed `name` returned in `ScheduleInfo`), not the short name +you supplied. The `AgentClient` also has `schedule(agent, schedules)` (see +[control plane](../reference/client.md)). + +Agent schedules ride the SDK's core `SchedulerClient` — the same client every +other Conductor workflow uses, not a separate agent-only facade — so pause/ +resume/delete/list behave identically to scheduling a plain workflow. Deploy +the agent (`runtime.deploy`) before scheduling it: a schedule referencing an +undeployed workflow definition will fail at fire time, not at save time. Use +stable schedule names and idempotent workflow input, since a scheduled fire +that overlaps a retry or a manual `runNow` should be safe to run twice. + +## Next steps + +Read [runtime modes](deploy-serve-run.md) and the +[Schedules / SchedulerClient reference](../reference/api.md#schedules--schedulerclient). diff --git a/docs/agents/concepts/stateful.md b/docs/agents/concepts/stateful.md new file mode 100644 index 00000000..642631f8 --- /dev/null +++ b/docs/agents/concepts/stateful.md @@ -0,0 +1,121 @@ +# Stateful agents + +Set `stateful: true` on an agent (or `stateful: true` on a tool def) to +isolate tool workers per execution via a unique domain UUID. Within a single +run, tools share a mutable `context.state` object; mutations are captured and +propagated between tool calls. + +```ts +import type { ToolContext } from '@io-orkes/conductor-javascript/agents'; + +const addItem = tool( + async (args: { item: string }, ctx?: ToolContext) => { + const items: string[] = (ctx?.state?.list as string[]) ?? []; + items.push(args.item); + if (ctx?.state) ctx.state.list = items; + return { total: items.length }; + }, + { name: 'add_item', description: 'Add an item.', inputSchema: { + type: 'object', properties: { item: { type: 'string' } }, required: ['item'], + }}, +); + +const agent = new Agent({ name: 'list_agent', model, tools: [addItem], stateful: true }); +``` + +Choose a stable session/correlation identifier up front when a session needs +to resume durable conversation state across multiple calls, and classify +which user data is appropriate to persist before enabling `memory` — an +unbounded history placed directly in prompts grows context and cost with no +retention policy; use `ConversationMemory`'s `maxMessages` windowing or a +condensation strategy instead. + +## Memory + +Two memory primitives are available for agents that need to remember things +across turns or across runs: + +- **`ConversationMemory`** — an in-process chat-message log with optional + `maxMessages` windowing. System messages are always preserved; only + non-system messages are trimmed once the window fills. Attach it via + `AgentOptions.memory` — the runtime serializes it onto the wire as part of + the agent config (see [agent schema](../reference/agent-schema.md)). +- **`SemanticMemory`** — a similarity-search store (pluggable via the + `MemoryStore` interface; `InMemoryStore` ships built in) for retrieving + relevant prior content by keyword/semantic overlap rather than replaying + the whole conversation. It isn't a first-class `AgentOptions` field — + query it explicitly from inside a `tool()` handler, or call `getContext()` + to format a result block for injection into instructions. + +```ts +import { + Agent, AgentRuntime, ConversationMemory, SemanticMemory, InMemoryStore, tool, +} from '@io-orkes/conductor-javascript/agents'; + +// ConversationMemory — windowed chat history, pre-populated with context +const conversationMem = new ConversationMemory({ maxMessages: 20 }); +conversationMem.addSystemMessage('You are a helpful research assistant.'); +conversationMem.addUserMessage('I need help researching quantum computing.'); +conversationMem.addAssistantMessage('I can help with that! What specific aspect?'); + +// SemanticMemory — index prior content, retrieve it via a tool +const store = new InMemoryStore(); +const semanticMem = new SemanticMemory({ store }); +semanticMem.add('Quantum error correction is essential for practical quantum computers.'); + +const recallTool = tool( + async (args: { query: string }) => ({ results: semanticMem.search(args.query, 3) }), + { + name: 'recall_articles', + description: 'Search past articles by topic.', + inputSchema: { type: 'object', properties: { query: { type: 'string' } }, required: ['query'] }, + }, +); + +const researchAgent = new Agent({ + name: 'research_agent', + model, + instructions: 'Use your memory and recall tool to answer questions.', + tools: [recallTool], + memory: conversationMem, +}); +``` + +`ConversationMemory.toChatMessages()` returns the (possibly windowed) message +log at any point; `SemanticMemory.searchEntries()` returns full `MemoryEntry` +objects (`id`, `content`, `metadata`, `timestamp`) instead of bare content +strings when you need the metadata. + +## Liveness monitoring + +For a stateful run (one with a domain-isolated worker), `runtime.start()`/ +`run()`/`stream()` also start a liveness monitor: it polls the execution's +workflow every `livenessCheckIntervalSeconds` and, if a `SCHEDULED`/ +`IN_PROGRESS` task in that run's domain sits unpolled (`pollCount === 0`) for +longer than `livenessStallSeconds`, a blocking `wait()` rejects with +`WorkerStallError` instead of hanging forever — the signal that the local +worker process for this run's domain died. The monitor stops on terminal +status or handle disposal and never keeps the process alive on its own. +Configure via `AgentConfig`/env: `livenessEnabled` +(`CONDUCTOR_AGENT_LIVENESS_ENABLED`, default `true`), `livenessStallSeconds` +(`CONDUCTOR_AGENT_LIVENESS_STALL_SECONDS`, default `30`), +`livenessCheckIntervalSeconds` +(`CONDUCTOR_AGENT_LIVENESS_CHECK_INTERVAL_SECONDS`, default `10`). +Framework-spawned agents (LangGraph/LangChain/Vercel AI wrappers) never route +through a per-run domain, so liveness monitoring doesn't apply to them. + +## Recovering after a worker process restart + +`WorkerStallError` tells you the worker for a domain died; to actually +recover, the replacement worker process needs to start polling that domain's +tasks again. There's no execution-scoped "reattach" call — the recovery +pattern is a fresh `serve()` invocation (with no agents) in the new process, +which resumes polling for whatever tool workers are already registered on +the server, covering every in-flight stateful execution's domain at once, +not just one `executionId`. See +[deploy/serve/run/plan](deploy-serve-run.md#deploy-vs-serve-vs-run-vs-plan). + +## Next steps + +Read [streaming and approval](streaming-hitl.md) and +[runtime modes](deploy-serve-run.md). diff --git a/docs/agents/concepts/streaming-hitl.md b/docs/agents/concepts/streaming-hitl.md new file mode 100644 index 00000000..c4fc37ea --- /dev/null +++ b/docs/agents/concepts/streaming-hitl.md @@ -0,0 +1,92 @@ +# Streaming and human-in-the-loop (HITL) + +## Streaming + +`runtime.stream(agent, prompt)` returns an `AgentStream` you can `for await` +over. Events have a `type` (`'thinking'`, `'tool_call'`, `'tool_result'`, +`'waiting'`, `'handoff'`, `'message'`, `'done'`, ...). You can also +`runtime.start(...)` and call `handle.stream()`. + +```ts +const stream = await runtime.stream(agent, 'Plan a 3-day trip to Tokyo.'); +for await (const event of stream) { + if (event.type === 'thinking') console.log('[thinking]', event.content); + else if (event.type === 'tool_call') console.log('[tool]', event.toolName, event.args); + else if (event.type === 'tool_result') console.log('[result]', event.toolName, event.result); + else if (event.type === 'done') console.log('[done]', event.output); +} +const result = await stream.getResult(); // terminal AgentResult after the stream ends +``` + +Don't treat streamed content as a final result until the terminal `'done'` +event (or `stream.getResult()`) arrives — an intermediate `'message'`/ +`'thinking'` event can still be followed by a retry or guardrail-triggered +correction. + +### SSE fallback + +Streaming rides Server-Sent Events (SSE) by default. If the SSE connection +can't be established (a non-2xx response, or the connection drops without +delivering a byte), the stream falls through to status polling +automatically — no action needed from the caller, and no error surfaces for +this case specifically. A stream that repeatedly fails to reconnect mid-flight +retries with backoff before also falling back to polling. + +## Human-in-the-loop (HITL) + +A tool with `approvalRequired: true`, or a `humanTool`, pauses execution and +emits a `waiting` event. Resolve it via the handle / stream: `approve(output?)`, +`reject(reason?)`, `send(message)`, or `respond(body)`. + +```ts +const deleteData = tool( + async (args: { table: string }) => ({ deleted: args.table }), + { + name: 'delete_data', + description: 'Delete a table. Destructive — requires approval.', + inputSchema: { type: 'object', properties: { table: { type: 'string' } }, required: ['table'] }, + approvalRequired: true, + }, +); + +const agent = new Agent({ name: 'ops', model, tools: [deleteData], instructions: '…' }); + +const handle = await runtime.start(agent, 'Delete the stale_cache table.'); +for await (const event of handle.stream()) { + if (event.type === 'waiting') { + // The waiting event carries the pending tool batch on event.pendingTool, + // or fetch the full status: + const status = await handle.getStatus(); + console.log('Approval needed for:', status.pendingTool?.toolCalls); + + await handle.approve(); // approve, or: + // await handle.reject('Not allowed'); + // await handle.respond({ approved: true, note: 'go ahead' }); + } else if (event.type === 'done') { + console.log('done', event.output); + } +} +``` + +One HUMAN task gates the whole batch of pending tool calls with a single +`{ approved, reason }` verdict — iterate `pendingTool.toolCalls` to see every +tool covered. The `pendingTool` is mirrored onto the `waiting` event so you +can read it without a `getStatus()` round-trip. + +`humanTool` works the same way but lets the LLM ask the human a structured +question; the response schema is on `pendingTool.response_schema`. + +### Approval pattern + +Keep the `executionId` (or handle) around across the approval wait — the +pause is a durable Conductor task, not an in-memory continuation, so it +survives a process restart on your side as long as you can look the +execution back up. Resolve pauses through the handle/client control plane +rather than an in-memory web request continuation, and make approval actions +idempotent, since a caller (e.g. a webhook retry) may submit the same +approval twice. + +## Next steps + +See [tools](tools.md), [agent client](../reference/client.md), and +[callbacks](callbacks.md). diff --git a/docs/agents/concepts/structured-output.md b/docs/agents/concepts/structured-output.md new file mode 100644 index 00000000..c4306b1d --- /dev/null +++ b/docs/agents/concepts/structured-output.md @@ -0,0 +1,41 @@ +# Structured output + +Set `outputType` to a JSON Schema object (or a Zod schema — it is converted to +JSON Schema). The model returns data conforming to the schema; the structured +object lands under `result.output.result`. + +```ts +const ArticleAnalysis = { + type: 'object', + properties: { + title: { type: 'string' }, + category: { type: 'string', enum: ['tech', 'business', 'science'] }, + sentiment: { type: 'string', enum: ['positive', 'neutral', 'negative'] }, + keyTopics: { type: 'array', items: { type: 'string' } }, + }, + required: ['title', 'category', 'sentiment', 'keyTopics'], +}; + +const analyzer = new Agent({ + name: 'analyzer', + model: 'openai/gpt-4o', + instructions: 'Analyze the article and return structured data.', + outputType: ArticleAnalysis, +}); + +const result = await runtime.run(analyzer, 'Analyze: "Quantum Error Correction Hits 99.9% Fidelity"'); +const structured = result.output['result'] as Record; +console.log(structured.category, structured.sentiment); +``` + +Keep the schema small and make optional fields explicit — a schema that's +larger or more ambiguous than what the prompt actually asks for tends to +produce more validation failures, not fewer. Treat a validation failure as +retryable only when a different model response could plausibly satisfy the +schema; otherwise it means the instructions and the schema disagree about +what's being asked for. + +## Next steps + +See [agent schema](../reference/agent-schema.md), [guardrails](guardrails.md), +and [runtime reference](../reference/runtime.md). diff --git a/docs/agents/concepts/termination.md b/docs/agents/concepts/termination.md new file mode 100644 index 00000000..9dd3a84a --- /dev/null +++ b/docs/agents/concepts/termination.md @@ -0,0 +1,47 @@ +# Termination + TextGate + +Termination conditions decide when a multi-turn / multi-agent loop should +stop. Pass one to `termination:`. They compose with `.and()` / `.or()` (or the +variadic `AndCondition` / `OrCondition`). + +```ts +import { TextMention, MaxMessage, TokenUsageCondition, StopMessage } from '@io-orkes/conductor-javascript/agents'; + +const agent = new Agent({ + name: 'debate', + model, + agents: [a, b], + strategy: 'round_robin', + termination: new TextMention('TERMINATE') // stop when output mentions text + .or(new MaxMessage(10)) // …or after 10 messages + .or(new TokenUsageCondition({ maxTotalTokens: 50000 })), +}); +``` + +Available conditions: `TextMention(text, caseSensitive?)`, +`StopMessage(stopMessage)`, `MaxMessage(maxMessages)`, +`TokenUsageCondition({ maxTotalTokens?, maxPromptTokens?, +maxCompletionTokens? })`, and the composites `AndCondition(...)` / +`OrCondition(...)`. + +`TextGate` and `gate()` gate transitions (e.g. on `gate:`): + +```ts +import { TextGate } from '@io-orkes/conductor-javascript/agents'; +new Agent({ name: 'a', model, gate: new TextGate({ text: 'APPROVED', caseSensitive: false }) }); +``` + +## Bounding cost and stopping safely + +Set a meaningful `maxTurns` in addition to any termination condition — it's +the backstop when a text/token condition never triggers. Stop a live +execution through `AgentHandle.stop()` / `AgentClient.stop()`: make the call +safe to repeat, and don't assume an in-flight external tool call is +reversible — if a tool has already started, stopping the agent doesn't undo +its side effect. Design compensating work where a stopped execution can leave +external state partially applied. + +## Next steps + +Continue with [multi-agent](multi-agent.md) and +[agent client control](../reference/client.md). diff --git a/docs/agents/concepts/tools.md b/docs/agents/concepts/tools.md new file mode 100644 index 00000000..67ef06ac --- /dev/null +++ b/docs/agents/concepts/tools.md @@ -0,0 +1,157 @@ +# Tools + +## Local tools — `tool()` + +`tool()` wraps an async function. Pass a Zod schema **or** a plain JSON Schema +object for `inputSchema`. The function runs locally as a Conductor worker that +the runtime polls; the runtime registers and polls it automatically on +`run()` / `serve()`. + +```ts +const getWeather = tool( + async (args: { city: string }) => { + return { city: args.city, tempC: 21, conditions: 'sunny' }; + }, + { + name: 'get_weather', + description: 'Get the current weather for a city.', + inputSchema: { + type: 'object', + properties: { city: { type: 'string', description: 'City name' } }, + required: ['city'], + }, + }, +); + +const agent = new Agent({ + name: 'weather_agent', + model: 'anthropic/claude-sonnet-4-6', + instructions: 'Answer weather questions using the tool.', + tools: [getWeather], +}); +``` + +`tool()` options: `name`, `description`, `inputSchema`, `outputSchema?`, +`approvalRequired?`, `timeoutSeconds?`, `external?`, `credentials?`, +`guardrails?`, `maxCalls?`, `retryCount?`, `retryDelaySeconds?`, `retryPolicy?`. + +The tool function receives an optional second argument, the +[`ToolContext`](../reference/api.md#toolcontext) (`sessionId`, `executionId`, +`agentName`, `metadata`, `dependencies`, and a mutable `state`). See +[Stateful agents](stateful.md). + +**No per-run mutable capture.** A `tool()` handler is registered once and its +Conductor worker is reused across concurrent runs and (for framework-spawned +agents) concurrent process-local executors — never re-created per run. Don't +close over per-run mutable state in the handler itself (a module-level +counter, an array pushed to across calls, a captured `let` reassigned +mid-run); two runs executing the same tool concurrently would corrupt each +other's state. Everything a handler needs that varies per run belongs in +`ToolContext` (`state` for durable per-execution data, `dependencies` for +injected collaborators) or in the function's own arguments — never in a +closure variable mutated across invocations. Tool and agent factories +otherwise take plain data (JSON-serializable configs), so building one is +always safe to repeat. + +## Tool discovery — `@Tool` / `toolsFrom` + +Decorate methods on a class and extract them, bound to the instance: + +```ts +import { Tool, toolsFrom } from '@io-orkes/conductor-javascript/agents'; + +class MathTools { + @Tool({ description: 'Add two numbers.', inputSchema: { + type: 'object', properties: { a: { type: 'number' }, b: { type: 'number' } }, required: ['a', 'b'], + }}) + async add(args: { a: number; b: number }) { return { sum: args.a + args.b }; } +} + +const tools = toolsFrom(new MathTools()); // ToolFunction[] +new Agent({ name: 'calc', model, tools }); +``` + +## Built-in tools + +These return a `ToolDef` that runs server-side (no local worker). Add them to +`tools: [...]`. + +| Builder | Tool type | Purpose | +|---|---|---| +| `httpTool({ name, description, url, method?, headers?, inputSchema?, credentials? })` | `http` | Call an HTTP endpoint. | +| `mcpTool({ serverUrl, name?, description?, headers?, toolNames?, maxTools?, credentials? })` | `mcp` | Expose an MCP server's tools. | +| `apiTool({ url, name?, description?, headers?, toolNames?, maxTools?, credentials? })` | `api` | Expose an OpenAPI/API as tools. | +| `agentTool(agent, { name?, description?, retryCount?, retryDelaySeconds?, optional? })` | `agent_tool` | Call another `Agent` as a tool (sub-agent). | +| `humanTool({ name, description, inputSchema? })` | `human` | Pause for human input (HITL). | +| `imageTool({ name, description, llmProvider, model, style?, size? })` | `generate_image` | Generate images. | +| `audioTool({ name, description, llmProvider, model, voice?, speed?, format? })` | `generate_audio` | Text-to-speech. | +| `videoTool({ name, description, llmProvider, model, duration?, resolution?, fps?, ... })` | `generate_video` | Generate video. | +| `pdfTool({ name?, description?, pageSize?, theme?, fontSize? })` | `generate_pdf` | Render markdown to PDF. | +| `waitForMessageTool({ name, description, batchSize?, blocking? })` | `pull_workflow_messages` | Dequeue messages from the workflow message queue. | +| `searchTool({ name, description, vectorDb, index, embeddingModelProvider, embeddingModel, namespace?, maxResults? })` | `rag_search` | RAG vector search. | +| `indexTool({ name, description, vectorDb, index, embeddingModelProvider, embeddingModel, namespace?, chunkSize?, chunkOverlap? })` | `rag_index` | RAG index/ingest. | + +```ts +import { httpTool, mcpTool } from '@io-orkes/conductor-javascript/agents'; + +const agent = new Agent({ + name: 'researcher', + model: 'anthropic/claude-sonnet-4-6', + tools: [ + httpTool({ + name: 'get_user', + description: 'Fetch a user by id.', + url: 'https://api.example.com/users/{id}', + method: 'GET', + }), + mcpTool({ serverUrl: 'https://mcp.example.com/sse', toolNames: ['search'] }), + ], +}); +``` + +### `waitForMessageTool` — workflow message queue + +`waitForMessageTool` lets a running agent dequeue messages pushed into its +workflow message queue (Conductor `PULL_WORKFLOW_MESSAGES`). No worker is +needed — the server handles it. In blocking mode (default) the task stays in +progress until a message arrives. For plain (non-agent) workflows, use the +`pullWorkflowMessages` task builder instead — see +[workflow-message-queue.md](../../workflow-message-queue.md). + +```ts +import { waitForMessageTool } from '@io-orkes/conductor-javascript/agents'; + +const agent = new Agent({ + name: 'inbox_agent', + model: 'anthropic/claude-sonnet-4-6', + instructions: 'When asked to wait, call wait_for_message and process what arrives.', + tools: [waitForMessageTool({ + name: 'wait_for_message', + description: 'Wait for the next inbound message.', + batchSize: 1, // up to 100; default 1 + blocking: true, // default true + })], +}); +``` + +### `agentTool` — agent as a tool + +```ts +import { agentTool } from '@io-orkes/conductor-javascript/agents'; + +const translator = new Agent({ name: 'translator', model, instructions: 'Translate to French.' }); + +const orchestrator = new Agent({ + name: 'orchestrator', + model, + instructions: 'Use the translator tool when asked to translate.', + tools: [agentTool(translator, { description: 'Translate text to French.' })], +}); +``` + +## Next steps + +See [multi-agent](multi-agent.md) for composing agents as tools via +`agentTool`, [guardrails](guardrails.md) for tool-level validation, and the +[tool reference](../reference/api.md#tool-and-built-in-tools) for the complete +option and type list. diff --git a/docs/agents/framework-agents.md b/docs/agents/framework-agents.md index 0bd187f7..83f9ee42 100644 --- a/docs/agents/framework-agents.md +++ b/docs/agents/framework-agents.md @@ -1,173 +1,10 @@ # Framework Agents -You don't have to rewrite agents authored with another framework to run them on Agentspan. The runtime **detects** the framework object you pass to `run()` / `deploy()` / `stream()`, serializes it to an agent config, and runs it on the server — same call you'd make with a native `Agent`. - -```ts -const runtime = new AgentRuntime(); -const result = await runtime.run(frameworkAgent, prompt); // <-- same entry point -``` - -Supported frameworks: **OpenAI Agents SDK**, **Google ADK**, **LangChain**, **LangGraph**, and the **Vercel AI SDK**. Detection is pure duck-typing — no framework is imported by the SDK. The framework packages are optional peer dependencies; install whichever you use. - -## How detection works - -`runtime.run(agent, ...)` calls `detectFramework(agent)`. It returns the first match: - -| Framework | Detected when the object has… | -|---|---| -| native `Agent` | is an instance of `Agent` (runs natively, not as a framework) | -| `langgraph` | `.invoke()` plus a graph shape (`.getGraph()`, a `.nodes` Map, or `.nodes` + `.builder`) | -| `langchain` | `.invoke()` plus an `lc_namespace` array (e.g. an `AgentExecutor`) | -| `openai` | `name` + string/function `instructions` + string `model` + `tools[]` + an OpenAI marker (`handoffs[]`, `inputGuardrails[]`, `asTool()`, `toolUseBehavior`, ...) | -| `google_adk` | `subAgents[]` (orchestration agents), or string `model` + ADK markers (`instruction`, `outputKey`, `generateContentConfig`, `beforeModelCallback`, ...) | - -If nothing matches and the object isn't a native `Agent`, you get a clear error. - -## OpenAI Agents SDK - -Pass an `@openai/agents` `Agent` straight to the runtime. - -```ts -import { Agent, setTracingDisabled } from '@openai/agents'; -import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; - -setTracingDisabled(true); - -const agent = new Agent({ - name: 'greeter', - instructions: 'You are a friendly assistant. Keep your responses concise and helpful.', - model: 'gpt-4o-mini', -}); - -const runtime = new AgentRuntime(); -try { - const result = await runtime.run(agent, 'Say hello and tell me a fun fact about TypeScript.'); - result.printResult(); -} finally { - await runtime.shutdown(); -} -``` - -## Google ADK - -Pass a `@google/adk` agent (`LlmAgent`, or the `Sequential`/`Parallel`/`Loop` orchestration agents). - -```ts -import { LlmAgent } from '@google/adk'; -import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; - -const agent = new LlmAgent({ - name: 'greeter', - model: 'gemini-2.5-flash', - instruction: 'You are a friendly assistant. Keep your responses concise and helpful.', -}); - -const runtime = new AgentRuntime(); -try { - const result = await runtime.run(agent, 'Say hello and tell me a fun fact about ML.'); - result.printResult(); -} finally { - await runtime.shutdown(); -} -``` - -## LangGraph - -Pass a prebuilt `createReactAgent` graph directly — detection handles it via `.invoke()` + graph shape. - -```ts -import { createReactAgent } from '@langchain/langgraph/prebuilt'; -import { ChatOpenAI } from '@langchain/openai'; -import { DynamicStructuredTool } from '@langchain/core/tools'; -import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; - -const llm = new ChatOpenAI({ model: 'gpt-4o-mini', temperature: 0 }); -const graph = createReactAgent({ llm, tools, name: 'math_agent' }); - -const runtime = new AgentRuntime(); -try { - const result = await runtime.run(graph, 'What is 12 * 9?'); - result.printResult(); -} finally { - await runtime.shutdown(); -} -``` - -For a complex graph where automatic introspection of the model/tools could fail, import `createReactAgent` from the SDK wrapper instead. It stamps `._agentspan` metadata onto the graph so the serializer skips introspection: - -```ts -import { createReactAgent } from '@io-orkes/conductor-javascript/agents/langgraph'; -``` - -You can also pass a model hint at call time when detection can't infer it: `runtime.run(graph, prompt, { model: 'anthropic/claude-sonnet-4-6' })`. - -## LangChain - -A real `langchain` `AgentExecutor` is detected via `.invoke()` + `lc_namespace`. To make the model/tools unambiguous, use the SDK's drop-in builder, which attaches `._agentspan` metadata: - -```ts -import { createAgentExecutor } from '@io-orkes/conductor-javascript/agents/langchain'; -import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; - -const executor = createAgentExecutor({ agent, tools, llm }); - -const runtime = new AgentRuntime(); -try { - const result = await runtime.run(executor, 'Summarize the latest release notes.'); - result.printResult(); -} finally { - await runtime.shutdown(); -} -``` - -The `@io-orkes/conductor-javascript/agents/langchain` subpath also exports `createRunnableWithMetadata(...)` (a runnable-like object with `invoke` + `lc_namespace` + metadata) and `getLangChainModule()`. - -## Vercel AI SDK - -Two ways to use the AI SDK: - -**1. AI SDK tools on a native Agent (recommended).** The tool system is a superset — it auto-detects AI SDK `tool()` objects (Zod `parameters` + `execute`) and converts them to native tool defs. No wrapper needed. - -```ts -import { tool as aiTool } from 'ai'; -import { z } from 'zod'; -import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; - -const weatherTool = aiTool({ - description: 'Get current weather for a city', - parameters: z.object({ city: z.string().describe('City name') }), - execute: async ({ city }) => ({ city, tempF: 62, condition: 'Foggy' }), -}); - -const agent = new Agent({ - name: 'weather_agent', - model: 'anthropic/claude-sonnet-4-6', - instructions: 'Use available tools to answer questions.', - tools: [weatherTool], -}); - -const runtime = new AgentRuntime(); -try { - const result = await runtime.run(agent, 'What is the weather in San Francisco?'); - result.printResult(); -} finally { - await runtime.shutdown(); -} -``` - -**2. Drop-in `generateText` / `streamText`.** The `@io-orkes/conductor-javascript/agents/vercel-ai` subpath exports AI-SDK-shaped `generateText` and `streamText` that internally build an `Agent` + `AgentRuntime` and map the result back into the AI SDK response shape: - -```ts -import { generateText } from '@io-orkes/conductor-javascript/agents/vercel-ai'; - -const { text } = await generateText({ - model: 'anthropic/claude-sonnet-4-6', - prompt: 'Write a haiku about durable execution.', -}); -``` - -## Notes - -- All five frameworks use the identical `runtime.run(agentOrGraph, prompt)` entry point — there is no per-framework runtime API. -- Framework peer deps (`@openai/agents`, `@google/adk`, `@langchain/*`, `ai`, `zod`) are optional; install only what you use. The wrappers lazy-load their dependency and throw an install hint if it's missing. -- Framework agents can be deployed too: `runtime.deploy(frameworkAgent)`. See [advanced.md](advanced.md). +This page has moved to: + +- [Framework bridges overview](README.md#framework-bridges) — supported frameworks and how detection works +- [OpenAI Agents SDK](frameworks/openai.md) +- [Google ADK](frameworks/google-adk.md) +- [LangGraph](frameworks/langgraph.md) +- [LangChain](frameworks/langchain.md) +- [Vercel AI SDK](frameworks/vercel-ai.md) diff --git a/docs/agents/frameworks/google-adk.md b/docs/agents/frameworks/google-adk.md new file mode 100644 index 00000000..90100dd1 --- /dev/null +++ b/docs/agents/frameworks/google-adk.md @@ -0,0 +1,36 @@ +# Google ADK + +Pass a `@google/adk` agent (`LlmAgent`, or the `Sequential`/`Parallel`/`Loop` +orchestration agents) straight to the runtime — no wrapper needed. Detection: +`subAgents[]` (orchestration agents), or a string `.model` + ADK markers +(`.instruction`, `.outputKey`, `.generateContentConfig`, +`.beforeModelCallback`, ...). See +[detection overview](../README.md#framework-bridges) for how this compares +to the other bridges. + +```ts +import { LlmAgent } from '@google/adk'; +import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; + +const agent = new LlmAgent({ + name: 'greeter', + model: 'gemini-2.5-flash', + instruction: 'You are a friendly assistant. Keep your responses concise and helpful.', +}); + +const runtime = new AgentRuntime(); +try { + const result = await runtime.run(agent, 'Say hello and tell me a fun fact about ML.'); + result.printResult(); +} finally { + await runtime.shutdown(); +} +``` + +`@google/adk` is an optional peer dependency — install it only if you use +this bridge. + +## Next steps + +Framework agents can be deployed too: `runtime.deploy(frameworkAgent)`. See +[deploy/serve/run/plan](../concepts/deploy-serve-run.md). diff --git a/docs/agents/frameworks/langchain.md b/docs/agents/frameworks/langchain.md new file mode 100644 index 00000000..cd215720 --- /dev/null +++ b/docs/agents/frameworks/langchain.md @@ -0,0 +1,34 @@ +# LangChain + +A real `langchain` `AgentExecutor` is detected via `.invoke()` + +`lc_namespace` (e.g. an array present on the object). See +[detection overview](../README.md#framework-bridges) for how this compares to +the other bridges. To make the model/tools unambiguous, use the SDK's +drop-in builder, which attaches `._agentspan` metadata: + +```ts +import { createAgentExecutor } from '@io-orkes/conductor-javascript/agents/langchain'; +import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; + +const executor = createAgentExecutor({ agent, tools, llm }); + +const runtime = new AgentRuntime(); +try { + const result = await runtime.run(executor, 'Summarize the latest release notes.'); + result.printResult(); +} finally { + await runtime.shutdown(); +} +``` + +The `@io-orkes/conductor-javascript/agents/langchain` subpath also exports +`createRunnableWithMetadata(...)` (a runnable-like object with `invoke` + +`lc_namespace` + metadata) and `getLangChainModule()`. + +`@langchain/core` (and whichever `@langchain/*` model/tool packages you use) +are optional peer dependencies — install them only if you use this bridge. + +## Next steps + +Framework agents can be deployed too: `runtime.deploy(frameworkAgent)`. See +[deploy/serve/run/plan](../concepts/deploy-serve-run.md). diff --git a/docs/agents/frameworks/langgraph.md b/docs/agents/frameworks/langgraph.md new file mode 100644 index 00000000..576fdadd --- /dev/null +++ b/docs/agents/frameworks/langgraph.md @@ -0,0 +1,44 @@ +# LangGraph + +Pass a prebuilt `createReactAgent` graph directly — detection handles it via +`.invoke()` + graph shape (`.getGraph()`, a `.nodes` Map, or `.nodes` + +`.builder`). See [detection overview](../README.md#framework-bridges) for how +this compares to the other bridges. + +```ts +import { createReactAgent } from '@langchain/langgraph/prebuilt'; +import { ChatOpenAI } from '@langchain/openai'; +import { DynamicStructuredTool } from '@langchain/core/tools'; +import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; + +const llm = new ChatOpenAI({ model: 'gpt-4o-mini', temperature: 0 }); +const graph = createReactAgent({ llm, tools, name: 'math_agent' }); + +const runtime = new AgentRuntime(); +try { + const result = await runtime.run(graph, 'What is 12 * 9?'); + result.printResult(); +} finally { + await runtime.shutdown(); +} +``` + +For a complex graph where automatic introspection of the model/tools could +fail, import `createReactAgent` from the SDK wrapper instead. It stamps +`._agentspan` metadata onto the graph so the serializer skips introspection: + +```ts +import { createReactAgent } from '@io-orkes/conductor-javascript/agents/langgraph'; +``` + +You can also pass a model hint at call time when detection can't infer it: +`runtime.run(graph, prompt, { model: 'anthropic/claude-sonnet-4-6' })`. + +The `@io-orkes/conductor-javascript/agents/langgraph` subpath is an optional +peer-dependent wrapper — `@langchain/langgraph` is only required if you use +this bridge. + +## Next steps + +Framework agents can be deployed too: `runtime.deploy(frameworkAgent)`. See +[deploy/serve/run/plan](../concepts/deploy-serve-run.md). diff --git a/docs/agents/frameworks/openai.md b/docs/agents/frameworks/openai.md new file mode 100644 index 00000000..8ab9450c --- /dev/null +++ b/docs/agents/frameworks/openai.md @@ -0,0 +1,36 @@ +# OpenAI Agents SDK + +Pass an `@openai/agents` `Agent` straight to the runtime — no wrapper needed. +Detection: `.name` + a string/function `.instructions` + a string `.model` + +`.tools[]` + an OpenAI marker (`handoffs[]`, `inputGuardrails[]`, `asTool()`, +`toolUseBehavior`, ...). See [detection overview](../README.md#framework-bridges) +for how this compares to the other bridges. + +```ts +import { Agent, setTracingDisabled } from '@openai/agents'; +import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; + +setTracingDisabled(true); + +const agent = new Agent({ + name: 'greeter', + instructions: 'You are a friendly assistant. Keep your responses concise and helpful.', + model: 'gpt-4o-mini', +}); + +const runtime = new AgentRuntime(); +try { + const result = await runtime.run(agent, 'Say hello and tell me a fun fact about TypeScript.'); + result.printResult(); +} finally { + await runtime.shutdown(); +} +``` + +`@openai/agents` is an optional peer dependency — install it only if you use +this bridge. + +## Next steps + +Framework agents can be deployed too: `runtime.deploy(frameworkAgent)`. See +[deploy/serve/run/plan](../concepts/deploy-serve-run.md). diff --git a/docs/agents/frameworks/vercel-ai.md b/docs/agents/frameworks/vercel-ai.md new file mode 100644 index 00000000..2cac3b1a --- /dev/null +++ b/docs/agents/frameworks/vercel-ai.md @@ -0,0 +1,59 @@ +# Vercel AI SDK + +There is no equivalent of this bridge in java-sdk/python-sdk — it exists +because the Vercel AI SDK is a Node/JS-ecosystem-specific tool convention. +Two ways to use it: + +**1. AI SDK tools on a native Agent (recommended).** The tool system is a +superset — it auto-detects AI SDK `tool()` objects (Zod `parameters` + +`execute`) and converts them to native tool defs. No wrapper needed. + +```ts +import { tool as aiTool } from 'ai'; +import { z } from 'zod'; +import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; + +const weatherTool = aiTool({ + description: 'Get current weather for a city', + parameters: z.object({ city: z.string().describe('City name') }), + execute: async ({ city }) => ({ city, tempF: 62, condition: 'Foggy' }), +}); + +const agent = new Agent({ + name: 'weather_agent', + model: 'anthropic/claude-sonnet-4-6', + instructions: 'Use available tools to answer questions.', + tools: [weatherTool], +}); + +const runtime = new AgentRuntime(); +try { + const result = await runtime.run(agent, 'What is the weather in San Francisco?'); + result.printResult(); +} finally { + await runtime.shutdown(); +} +``` + +**2. Drop-in `generateText` / `streamText`.** The +`@io-orkes/conductor-javascript/agents/vercel-ai` subpath exports +AI-SDK-shaped `generateText` and `streamText` that internally build an +`Agent` + `AgentRuntime` and map the result back into the AI SDK response +shape: + +```ts +import { generateText } from '@io-orkes/conductor-javascript/agents/vercel-ai'; + +const { text } = await generateText({ + model: 'anthropic/claude-sonnet-4-6', + prompt: 'Write a haiku about durable execution.', +}); +``` + +`ai` and `zod` are optional peer dependencies — install them only if you use +this bridge. + +## Next steps + +Framework agents can be deployed too: `runtime.deploy(frameworkAgent)`. See +[deploy/serve/run/plan](../concepts/deploy-serve-run.md). diff --git a/docs/agents/getting-started.md b/docs/agents/getting-started.md index a7a756f9..b2858b46 100644 --- a/docs/agents/getting-started.md +++ b/docs/agents/getting-started.md @@ -18,27 +18,25 @@ npm install zod ## 2. Point at a server -You need a running Agentspan server. The defaults assume a local one at `http://localhost:8080/api` (the SDK auto-appends `/api` if you omit it). +You need a running Conductor server. The defaults assume a local one at `http://localhost:8080/api` (the SDK auto-appends `/api` if you omit it). | Variable | Default | Description | |---|---|---| -| `AGENTSPAN_SERVER_URL` | `http://localhost:8080/api` | Agentspan server URL. | -| `AGENTSPAN_AUTH_KEY` | — | Auth key. Unset = no-auth mode (local / OSS). | -| `AGENTSPAN_AUTH_SECRET` | — | Auth secret. Set together with the key for Orkes Cloud. | -| `AGENTSPAN_API_KEY` | — | Pre-minted bearer token (alternative to key/secret). | +| `CONDUCTOR_SERVER_URL` | `http://localhost:8080/api` | Conductor server URL. | +| `CONDUCTOR_AUTH_KEY` | — | Auth key. Unset = no-auth mode (local / OSS). | +| `CONDUCTOR_AUTH_SECRET` | — | Auth secret. Set together with the key for Orkes Cloud. | ```bash -export AGENTSPAN_SERVER_URL=http://localhost:8080/api +export CONDUCTOR_SERVER_URL=http://localhost:8080/api export OPENAI_API_KEY= -export AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini # Orkes Cloud only: -# export AGENTSPAN_AUTH_KEY=... -# export AGENTSPAN_AUTH_SECRET=... +# export CONDUCTOR_AUTH_KEY=... +# export CONDUCTOR_AUTH_SECRET=... ``` -`AGENTSPAN_AUTH_KEY` / `AGENTSPAN_AUTH_SECRET` are minted into a short-lived JWT and sent as the `X-Authorization` header on every server call. The SDK handles that for you — you only set the env vars. The SDK loads a `.env` file automatically (via `dotenv`). +`CONDUCTOR_AUTH_KEY` / `CONDUCTOR_AUTH_SECRET` are minted into a short-lived JWT and sent as the `X-Authorization` header on every server call. The SDK handles that for you — you only set the env vars. The SDK loads a `.env` file automatically (via `dotenv`). -A handful of other env vars tune workers and logging (`AGENTSPAN_WORKER_POLL_INTERVAL`, `AGENTSPAN_WORKER_THREADS`, `AGENTSPAN_LOG_LEVEL`, ...); see [advanced.md](advanced.md#runtime-configuration). +A handful of other env vars tune workers and logging (`CONDUCTOR_AGENT_WORKER_POLL_INTERVAL`, `CONDUCTOR_AGENT_WORKER_THREADS`, `CONDUCTOR_LOG_LEVEL`, ...); see the [runtime reference](reference/runtime.md). ## 3. Run an agent @@ -70,7 +68,7 @@ That is the whole loop: define an `Agent`, create an `AgentRuntime`, `await runt ## Reading the result -`run()` returns an [`AgentResult`](api-reference.md#agentresult). Common members: +`run()` returns an [`AgentResult`](reference/api.md#agentresult). Common members: ```ts result.printResult(); // formatted summary to stdout @@ -81,10 +79,10 @@ const finish = result.finishReason; // 'stop' | 'length' | 'guardrail' | 'rej const execId = result.executionId; // durable execution id on the server ``` -`output` is always a `Record`. A plain text answer arrives as `{ result: "..." }`; structured output (see [advanced.md](advanced.md#structured-output)) arrives under `output.result` as an object. +`output` is always a `Record`. A plain text answer arrives as `{ result: "..." }`; structured output (see [structured output](concepts/structured-output.md)) arrives under `output.result` as an object. ## Next -- [writing-agents.md](writing-agents.md) — tools, multi-agent orchestration, guardrails, streaming, HITL, schedules. -- [framework-agents.md](framework-agents.md) — run OpenAI / ADK / LangChain / LangGraph / Vercel AI agents as-is. -- [advanced.md](advanced.md) — deploy/serve, the control-plane `AgentClient`, structured output, credentials. +- [Agents](concepts/agents.md), [tools](concepts/tools.md), [multi-agent](concepts/multi-agent.md) — orchestration, guardrails, streaming, HITL, schedules. +- [Framework bridges](README.md#framework-bridges) — run OpenAI / ADK / LangChain / LangGraph / Vercel AI agents as-is. +- [Deploy/serve/run/plan](concepts/deploy-serve-run.md) — the control-plane `AgentClient`, structured output, credentials. diff --git a/docs/agents/reference/agent-definition.md b/docs/agents/reference/agent-definition.md new file mode 100644 index 00000000..25959980 --- /dev/null +++ b/docs/agents/reference/agent-definition.md @@ -0,0 +1,65 @@ +# Agent definition fields + +```ts +new Agent(options: AgentOptions) +``` + +Key `AgentOptions` fields: + +| Field | Type | Notes | +|---|---|---| +| `name` | `string` | Required. `/^[a-zA-Z][a-zA-Z0-9_-]*$/`. | +| `model` | `string \| ClaudeCode` | e.g. `'anthropic/claude-sonnet-4-6'`. | +| `baseUrl` | `string` | Override LLM provider base URL. | +| `instructions` | `string \| PromptTemplate \| (() => string)` | Static / template / dynamic. | +| `tools` | `unknown[]` | `tool()` wrappers, built-in tool defs, framework tools. | +| `agents` | `Agent[]` | Sub-agents (multi-agent). | +| `strategy` | `Strategy` | `'sequential' \| 'parallel' \| 'handoff' \| 'router' \| 'round_robin' \| 'random' \| 'swarm' \| 'manual' \| 'plan_execute'`. | +| `router` | `Agent \| (() => string)` | Required for `strategy: 'router'`. | +| `outputType` | Zod schema or JSON Schema | Structured output. | +| `guardrails` | `unknown[]` | Guardrail defs / instances. | +| `handoffs` | `HandoffCondition[]` | `OnTextMention` / `OnToolResult` / `OnCondition`. | +| `allowedTransitions` | `Record` | Constrain agent transitions. | +| `termination` | `TerminationCondition` | Stop condition. | +| `gate` | `GateCondition` | `TextGate` / `gate()`. | +| `callbacks` | `CallbackHandler[]` | Lifecycle hooks. | +| `memory` | `ConversationMemory` | Conversation history. | +| `maxTurns` | `number` | Default 25. | +| `maxTokens` / `temperature` / `timeoutSeconds` | `number` | LLM + execution tuning. | +| `credentials` | `string[]` | Secret names to resolve. | +| `stateful` | `boolean` | Per-execution worker isolation + shared state. | +| `planner` / `fallback` | `Agent` | PLAN_EXECUTE named slots. | +| `plannerContext` | `(string \| Context \| object)[]` | PLAN_EXECUTE reference docs. | +| `enablePlanning` | `boolean` | Plan-first preamble. | +| `prefillTools` | `PrefillToolCall[]` | Tools run before the first LLM turn. | +| `cliCommands` / `cliAllowedCommands` / `cliConfig` | — | Enable CLI command execution. | +| `codeExecutionConfig` | `CodeExecutionConfig` | Code execution. | +| `introduction` / `metadata` | — | Agent metadata. | + +Methods: `agent.pipe(other)` builds a sequential pipeline (flattens chains). +Getters: `isClaudeCode`, `claudeCodeConfig`. + +Helpers: +- `agent(fn, options)` — functional form; `fn` is the dynamic-instructions + callable. +- `scatterGather({ name, workers, model?, instructions?, retryCount?, + retryDelaySeconds?, failFast?, timeoutSeconds? })` — coordinator that fans + out to worker agents in parallel. +- `AgentDec(options)` + `agentsFrom(instance)` — define agents as decorated + class methods. +- `PromptTemplate(name, variables?, version?)` — server-managed prompt + reference. + +Names must match `^[a-zA-Z][a-zA-Z0-9_-]*$`. An omitted `model` is valid only +for inherited-model or external-agent (`external: true`) designs. The +complete constructor and serialization semantics are maintained in +[`agent.ts`](../../../src/agents/agent.ts) and +[`serializer.ts`](../../../src/agents/serializer.ts); use those sources when +adding a newly supported field, and update the +[agent schema](agent-schema.md) alongside. + +## Next steps + +See [agents](../concepts/agents.md) for authoring patterns, the +[agent schema](agent-schema.md) for the wire contract this maps to, and the +[API reference](api.md) for everything else in the public surface. diff --git a/docs/agents/reference/agent-schema.json b/docs/agents/reference/agent-schema.json new file mode 100644 index 00000000..9d88d12f --- /dev/null +++ b/docs/agents/reference/agent-schema.json @@ -0,0 +1,130 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/conductor-oss/javascript-sdk/blob/main/docs/agents/reference/agent-schema.json", + "title": "Conductor JavaScript AgentConfig", + "description": "The public wire shape emitted by AgentConfigSerializer.serializeAgent() under agentConfig.", + "$ref": "#/$defs/agentConfig", + "$defs": { + "taskReference": { + "type": "object", + "required": ["taskName"], + "properties": { "taskName": { "type": "string", "minLength": 1 } }, + "additionalProperties": false + }, + "tool": { + "type": "object", + "required": ["name", "toolType"], + "properties": { + "name": { "type": "string", "minLength": 1 }, + "description": { "type": "string" }, + "toolType": { "type": "string" }, + "inputSchema": { "type": "object" }, + "outputSchema": { "type": "object" }, + "approvalRequired": { "type": "boolean" }, + "timeoutSeconds": { "type": "integer", "minimum": 0 }, + "stateful": { "type": "boolean" }, + "maxCalls": { "type": "integer", "minimum": 0 }, + "retryCount": { "type": "integer", "minimum": 0 }, + "retryDelaySeconds": { "type": "integer", "minimum": 0 }, + "retryPolicy": { "type": "string" }, + "guardrails": { "type": "array", "items": { "type": "object" } }, + "config": { + "type": "object", + "description": "toolType-specific config (e.g. agent_tool's nested agentConfig, http/mcp/api's URL+headers, and merged-in credentials).", + "additionalProperties": true + } + }, + "additionalProperties": true + }, + "agentConfig": { + "type": "object", + "required": ["name"], + "properties": { + "name": { "type": "string", "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$" }, + "model": { "type": ["string", "null"] }, + "baseUrl": { "type": "string" }, + "instructions": { + "anyOf": [ + { "type": "string" }, + { "type": "object", "description": "PromptTemplate wire form: { type: 'prompt_template', name, variables?, version? }" } + ] + }, + "tools": { "type": "array", "items": { "$ref": "#/$defs/tool" } }, + "agents": { "type": "array", "items": { "$ref": "#/$defs/agentConfig" } }, + "strategy": { "type": "string" }, + "router": { "anyOf": [{ "$ref": "#/$defs/taskReference" }, { "$ref": "#/$defs/agentConfig" }] }, + "outputType": { + "type": "object", + "properties": { + "schema": { "type": "object" }, + "className": { "type": "string" } + }, + "required": ["schema", "className"] + }, + "guardrails": { "type": "array", "items": { "type": "object" } }, + "memory": { + "type": "object", + "properties": { + "messages": { "type": "array" }, + "maxMessages": { "type": "integer", "minimum": 0 } + }, + "required": ["messages"] + }, + "maxTurns": { "type": "integer", "minimum": 0 }, + "maxTokens": { "type": "integer", "minimum": 0 }, + "contextWindowBudget": { "type": "integer", "minimum": 0 }, + "temperature": { "type": "number" }, + "reasoningEffort": { "type": "string" }, + "timeoutSeconds": { "type": "integer", "minimum": 0 }, + "external": { "type": "boolean" }, + "stateful": { "type": "boolean" }, + "stopWhen": { "$ref": "#/$defs/taskReference" }, + "termination": { "type": "object" }, + "handoffs": { "type": "array", "items": { "type": "object" } }, + "allowedTransitions": { + "type": "object", + "additionalProperties": { "type": "array", "items": { "type": "string" } } + }, + "introduction": { "type": "string" }, + "metadata": { "type": "object" }, + "enablePlanning": { "type": "boolean" }, + "planner": { "$ref": "#/$defs/agentConfig" }, + "fallback": { "$ref": "#/$defs/agentConfig" }, + "fallbackMaxTurns": { "type": "integer", "minimum": 0 }, + "planSource": { "type": "string" }, + "plannerContext": { "type": "array", "items": { "type": "object" } }, + "callbacks": { + "type": "array", + "items": { + "type": "object", + "required": ["position", "taskName"], + "properties": { + "position": { "type": "string" }, + "taskName": { "type": "string" } + } + } + }, + "includeContents": { "type": "boolean" }, + "thinkingConfig": { + "type": "object", + "properties": { + "enabled": { "type": "boolean" }, + "budgetTokens": { "type": "integer", "minimum": 0 } + } + }, + "requiredTools": { "type": "array", "items": { "type": "string" } }, + "prefillTools": { "type": "array", "items": { "type": "object" } }, + "gate": { "type": "object" }, + "codeExecution": { "type": "object" }, + "cliConfig": { "type": "object" }, + "maskedFields": { "type": "array", "items": { "type": "string" } }, + "credentials": { "type": "array", "items": { "type": "string" } }, + "_framework": { + "type": "string", + "description": "Present only on framework-passthrough shapes (e.g. 'skill'); absent on native agents." + } + }, + "additionalProperties": false + } + } +} diff --git a/docs/agents/reference/agent-schema.md b/docs/agents/reference/agent-schema.md new file mode 100644 index 00000000..210bda8c --- /dev/null +++ b/docs/agents/reference/agent-schema.md @@ -0,0 +1,47 @@ +# Agent configuration contract + +The canonical wire contract is the object emitted by +[`AgentConfigSerializer.serializeAgent()`](../../../src/agents/serializer.ts) +under the `agentConfig` request field sent to `/agent/*` control-plane +endpoints. Its unit tests validate the supported agent, tool, guardrail, +handoff, memory, termination, callback, planning, and framework-passthrough +shapes. + +All keys are camelCase; `null`/`undefined` fields are omitted rather than +sent as `null`. Nested `agents`, `router`, `planner`, and `fallback` serialize +recursively via the same function. The published +[JSON Schema](agent-schema.json) rejects unknown root agent fields while +allowing intentionally open JSON payloads (tool `inputSchema`/`outputSchema`, +`metadata`, guardrail/termination/handoff objects, and per-toolType `config`). + +## Framework-passthrough shapes + +Two agent kinds bypass the general shape above and emit a minimal +passthrough payload instead, since their real work happens entirely inside a +local worker closure rather than being compiled by the server: + +- **Skill agents** (`agent._framework === 'skill'`) emit `{ name, model, + _framework: "skill", ...rawSkillConfig }` — the raw `SKILL.md`-derived + config, spread onto the payload, so the server's skill normalizer can + compile it. This can include fields outside the schema's declared property + list; the schema's `additionalProperties: false` is a statement about the + native-agent shape, not a promise that every skill payload validates + against it. +- **Claude Agent SDK passthrough** (`agent.isClaudeCode`) emits `{ name, + model, metadata: { _framework_passthrough: true }, tools: [{ name, + toolType: "worker", description: "Claude Agent SDK passthrough worker" }] + }` — every other option on the agent is consumed locally by the worker + closure and never reaches the wire. + +## Compatibility + +The schema describes payloads emitted by the *current* serializer; it isn't +a promise that arbitrary server-side fields can be supplied by callers. +Extend the serializer, the schema, this reference, and `serializer.test.ts` +together when adding a new public agent field. + +## Next steps + +Read [agent definition fields](agent-definition.md) for the authoring-side +options this maps from, and [runtime](runtime.md) for how a compiled +`agentConfig` gets submitted and executed. diff --git a/docs/agents/reference/api.md b/docs/agents/reference/api.md new file mode 100644 index 00000000..284f6e2c --- /dev/null +++ b/docs/agents/reference/api.md @@ -0,0 +1,406 @@ +# Agent API map + +| Need | JS API | Guide | +|---|---|---| +| Define an agent | `Agent`, `agent()`, `AgentDec`/`agentsFrom` | [Agents](../concepts/agents.md), [Agent definition](agent-definition.md) | +| Define tools | `tool()`, built-in tool factories, `Tool`/`toolsFrom` | [Tools](../concepts/tools.md) | +| Run lifecycle operations | `AgentRuntime`, module-level helpers | [Runtime](runtime.md), [Deploy/serve/run/plan](../concepts/deploy-serve-run.md) | +| Control an execution | `AgentClient`, `AgentHandle`, `ClientHandle` | [Control plane](client.md) | +| Add safety controls | guardrail and termination classes | [Guardrails](../concepts/guardrails.md), [Termination](../concepts/termination.md) | +| Compose agents | `Strategy`, handoffs, `plan_execute` | [Multi-agent](../concepts/multi-agent.md) | +| Bridge frameworks | framework detection + subpath wrappers | [Framework bridges](../README.md#framework-bridges) | + +The public surface of `@io-orkes/conductor-javascript/agents`. Everything +below is exported from the package root unless noted. + +## tool() and built-in tools + +```ts +tool(fn: (args, ctx?: ToolContext) => Promise, options: ToolOptions): ToolFunction +``` + +`ToolOptions`: `{ name?, description, inputSchema, outputSchema?, +approvalRequired?, timeoutSeconds?, external?, credentials?, guardrails?, +maxCalls?, retryCount?, retryDelaySeconds?, retryPolicy? }`. +`inputSchema`/`outputSchema` accept a Zod schema or a JSON Schema object. + +Built-in tool builders (all return a `ToolDef`): + +| Builder | Required options | toolType | +|---|---|---| +| `httpTool` | `name, description, url` (`method?, headers?, inputSchema?, credentials?`) | `http` | +| `mcpTool` | `serverUrl` (`name?, headers?, toolNames?, maxTools?, credentials?`) | `mcp` | +| `apiTool` | `url` (`name?, headers?, toolNames?, maxTools?, credentials?`) | `api` | +| `agentTool` | `agent` (`name?, description?, retryCount?, retryDelaySeconds?, optional?`) | `agent_tool` | +| `humanTool` | `name, description` (`inputSchema?`) | `human` | +| `imageTool` | `name, description, llmProvider, model` (`style?, size?`) | `generate_image` | +| `audioTool` | `name, description, llmProvider, model` (`voice?, speed?, format?`) | `generate_audio` | +| `videoTool` | `name, description, llmProvider, model` (`duration?, resolution?, fps?, ...`) | `generate_video` | +| `pdfTool` | — (`name?, description?, pageSize?, theme?, fontSize?`) | `generate_pdf` | +| `waitForMessageTool` | `name, description` (`batchSize?` def 1, `blocking?` def true) | `pull_workflow_messages` | +| `searchTool` | `name, description, vectorDb, index, embeddingModelProvider, embeddingModel` (`namespace?, maxResults?, dimensions?`) | `rag_search` | +| `indexTool` | `name, description, vectorDb, index, embeddingModelProvider, embeddingModel` (`namespace?, chunkSize?, chunkOverlap?, dimensions?`) | `rag_index` | + +Discovery / helpers: `Tool(options?)` decorator + `toolsFrom(instance)`; +`getToolDef(obj)` / `normalizeToolInput(obj)` (extract a `ToolDef` from a +`tool()` wrapper, Vercel AI tool, or raw def); `isZodSchema(obj)`. + +### ToolContext + +Passed as the second arg to a `tool()` function: + +```ts +interface ToolContext { + sessionId: string; + executionId: string; + agentName: string; + metadata: Record; + dependencies: Record; + state: Record; // mutable; mutations propagate between tool calls +} +``` + +## Guardrails + +- `guardrail(fn, { name, position?, onFail?, maxRetries? })` — custom + guardrail from a function returning `{ passed, message?, fixedOutput? }`. + `guardrail.external({ name, position?, onFail? })` for remote-worker + guardrails. +- `new RegexGuardrail({ name, patterns, mode, position?, onFail?, message?, + maxRetries? })` — `mode: 'block' | 'allow'`. `.toGuardrailDef()`. +- `new LLMGuardrail({ name, model, policy, position?, onFail?, maxRetries?, + maxTokens? })` — server-side LLM judge. `.toGuardrailDef()`. +- `Guardrail(options?)` decorator + `guardrailsFrom(instance)`. + +`position`: `'input' | 'output'` (default `'output'`). `onFail`: `'raise' | +'retry' | 'fix' | 'human'` (default `'raise'`). Attach via `agent.guardrails` +or `tool(fn, { guardrails })`. + +## Termination + +All extend `TerminationCondition` and compose via `.and(other)` / +`.or(other)` (or variadic `AndCondition(...)` / `OrCondition(...)`). + +| Class | Constructor | +|---|---| +| `TextMention` | `(text, caseSensitive = false)` | +| `StopMessage` | `(stopMessage)` | +| `MaxMessage` | `(maxMessages)` | +| `TokenUsageCondition` | `({ maxTotalTokens?, maxPromptTokens?, maxCompletionTokens? })` | +| `AndCondition` / `OrCondition` | `(...conditions)` | + +## Handoffs + +- `new OnTextMention({ target, text })` — hand off when output mentions + `text` (case-insensitive). +- `new OnToolResult({ target, toolName, resultContains? })` — hand off after + a tool returns. +- `new OnCondition({ target, condition, agentName? })` — hand off when a + predicate (runs as a worker) returns true. +- `new TextGate({ text, caseSensitive? })` — gate on text containment + (`gate:` option). +- `gate(fn, { agentName? })` — custom gate from a function. + +`HandoffContext` (passed to conditions): `{ result, toolName?, toolResult?, +messages? }`. + +## Callbacks + +Subclass `CallbackHandler` and override hooks (each runs as a server +worker): + +```ts +abstract class CallbackHandler { + onAgentStart?(agentName, prompt): Promise; + onAgentEnd?(agentName, result): Promise; + onModelStart?(agentName, messages): Promise; + onModelEnd?(agentName, response): Promise; + onToolStart?(agentName, toolName, args): Promise; + onToolEnd?(agentName, toolName, result): Promise; +} +``` + +`CALLBACK_POSITIONS` maps hook names to wire positions; +`getCallbackWorkerNames(agentName, handler)` lists registered worker names. + +## Schedules / SchedulerClient + +```ts +new Schedule({ name, cron, timezone?, input?, catchup?, paused?, startAt?, endAt?, description? }) +``` + +Agent schedules ride the SDK `SchedulerClient` (also available via +`OrkesClients.getSchedulerClient()`). Its typed lifecycle methods: +`save(schedule, agentName)`, `get(wireName, agentName?)`, +`listForAgent(agentName)`, `pause(wireName, reason?)`, `resume(wireName)`, +`delete(wireName)`, `runNow(info)`, `previewNext(cron, { n?, startAt?, +endAt? })`, `reconcile(agentName, desired)` — plus the endpoint-level +wrappers (`saveSchedule`, `getSchedule`, `pauseSchedule`, ...). Pause/resume +issue PUT first and fall back to GET on HTTP 405 (per-schedule verbs differ +by Conductor server family), so one client works against both OSS/embedded +and Orkes servers. + +The `schedules` namespace is a convenience layer over the singleton runtime: +`schedules.list({ agent })`, `.get(name, { runtime? })`, `.pause(name, { +reason?, runtime? })`, `.resume`, `.delete`, `.runNow`, `.previewNext(cron, { +n? })`, `.save(schedule, agent)`. Lifecycle calls key on the **wire name** +(the prefixed `name` in `ScheduleInfo`). + +Errors: `ScheduleError`, `ScheduleNameConflict`, `ScheduleNotFound`, +`InvalidCronExpression`. `ScheduleInfo` includes `name`, `shortName`, +`agent`, `cron`, `timezone`, `paused`, `pausedReason`, `nextRun`, ... + +## AgentResult + +Returned by `run()` / `wait()`. + +```ts +interface AgentResult { + output: Record; // text answer -> { result: "..." } + executionId: string; + correlationId?: string; + messages: unknown[]; + toolCalls: unknown[]; + status: 'COMPLETED' | 'FAILED' | 'TERMINATED' | 'TIMED_OUT'; + finishReason: 'stop' | 'length' | 'tool_calls' | 'error' | 'cancelled' | 'timeout' | 'guardrail' | 'rejected'; + error?: string; + tokenUsage?: { promptTokens; completionTokens; totalTokens }; + metadata?: Record; + events: AgentEvent[]; + subResults?: Record; + readonly isSuccess: boolean; // status === 'COMPLETED' + readonly isFailed: boolean; // FAILED | TIMED_OUT + readonly isRejected: boolean; // finishReason === 'rejected' + printResult(): void; +} +``` + +## AgentHandle + +Returned by `runtime.start()`. + +```ts +interface AgentHandle { + executionId: string; + correlationId: string; + getStatus(): Promise; + wait(pollIntervalMs?): Promise; + respond(output): Promise; + approve(output?): Promise; + reject(reason?): Promise; + send(message): Promise; + pause(): Promise; + resume(): Promise; + cancel(): Promise; + stop(): Promise; + stream(): AgentStream; +} +``` + +`approve()` sends `{ approved: true, ...output }`; `reject(reason)` sends `{ +approved: false, reason }`; `send(message)` sends `{ message }`. For a custom +human-task response (shaped by `pendingTool.response_schema`), use +`respond(body)`. `wait(pollIntervalMs?)` rejects once its deadline passes +(`timeoutSeconds`-derived, or 10 min default) with an `AgentAPIError` naming +the last known status — and, for a stateful (domain-routed) run with +liveness enabled, rejects earlier with `WorkerStallError` if the local +worker appears to have died (see +[Liveness monitoring](../concepts/stateful.md#liveness-monitoring)). + +`pause()`/`resume()` here pause/resume a running execution (distinct from +[schedule pause/resume](#schedules--schedulerclient), which pauses a cron +definition, not a live run). + +## AgentStream / AgentEvent + +`AgentStream` implements `AsyncIterable` — iterate with `for +await`. Methods: `respond(output)`, `approve(output?)`, `reject(reason?)`, +`send(message)`, and `getResult(): Promise` (drains the stream, +polls for the terminal status, returns the result). Fields: `executionId`, +`events` (accumulates). + +```ts +interface AgentEvent { + type: 'thinking' | 'tool_call' | 'tool_result' | 'guardrail_pass' | 'guardrail_fail' + | 'waiting' | 'handoff' | 'message' | 'error' | 'done' | string; + content?: string; + toolName?: string; + args?: Record; + result?: unknown; + target?: string; // handoff target + output?: unknown; // on 'done' + pendingTool?: PendingTool;// on 'waiting' + guardrailName?: string; +} +``` + +`AgentStatus`: `{ executionId, isComplete, isRunning, isWaiting, output?, +status, reason?, currentTask?, messages, pendingTool? }`. `PendingTool`: `{ +taskRefName, toolCalls?: { name, args }[], response_schema?, ... }`. +`EventTypes`, `Statuses`, `FinishReasons`, `TERMINAL_STATUSES` enums are +exported. + +## Errors + +`ConductorAgentError` (base), `AgentAPIError`, `AgentNotFoundError`, +`ConfigurationError`, `CredentialNotFoundError`, `CredentialAuthError`, +`CredentialRateLimitError`, `CredentialServiceError`, `SSETimeoutError`, +`TerminalToolError`, `WorkerStallError`, `GuardrailFailedError`. + +`SSEUnavailableError` also extends `ConductorAgentError` but isn't exported +from the package root — it's thrown internally when an SSE connection can't +be established and caught by `AgentStream` itself to trigger the automatic +polling fallback (see [SSE fallback](../concepts/streaming-hitl.md#sse-fallback)); +there's no caller-visible error for this case since the fallback is +transparent. + +## RunSettings + +Per-run LLM overrides, passed as `RunOptions.runSettings` to +`run`/`start`/`stream`. + +```ts +interface RunSettings { + model?: string; + temperature?: number; + maxTokens?: number; + reasoningEffort?: string; + thinkingBudgetTokens?: number; +} +``` + +`RunOptions.runSettings` overrides the LLM call for a single +`run`/`start`/`stream`, without touching the agent's own config. Only set +fields override; unset fields keep the agent's own serialized values, and +the override doesn't cascade to sub-agents (each keeps its own settings). + +```ts +const result = await runtime.run(agent, prompt, { + runSettings: { + model: 'anthropic/claude-sonnet-4-6', // overrides agent.model for this run + temperature: 0.2, + maxTokens: 4096, + reasoningEffort: 'high', + thinkingBudgetTokens: 8000, // maps to the wire thinkingConfig shape + }, +}); + +// RunOptions.model is sugar for runSettings.model -- an explicit runSettings.model wins: +await runtime.run(agent, prompt, { model: 'openai/gpt-4o-mini' }); +``` + +## Credentials and secrets + +Pass credential names with `credentials: [...]` at the agent level and/or +per tool. The server resolves secrets when it polls each task and delivers +them **wire-only**, on that task's `runtimeMetadata` — never persisted, +never fetched by the worker separately. The SDK injects them into the +worker's `process.env` for the duration of the call (mutate-invoke-restore, +serialized so concurrent calls don't clobber each other's env). For +HTTP/MCP tools, reference them inline in headers with `${NAME}` +substitution. + +**Fail-closed, no fallback:** if a tool declares `credentials: [...]` and the +server didn't deliver one of them on `runtimeMetadata` (e.g. an older server +that predates `TaskDef.runtimeMetadata` support), the task fails with a +non-retryable error naming the missing credential. There is no ambient-env +fallback to silently read a locally-set variable instead. + +```ts +import { Agent, tool, httpTool, getCredential } from '@io-orkes/conductor-javascript/agents'; + +// A worker tool: the secret is injected into the worker's process.env for the call +const dbLookup = tool( + async (args: { query: string }) => { + const key = process.env.DB_API_KEY ?? ''; + return { ok: key !== '' }; + }, + { + name: 'db_lookup', + description: 'Look up data.', + inputSchema: { type: 'object', properties: { query: { type: 'string' } }, required: ['query'] }, + credentials: ['DB_API_KEY'], + }, +); + +// Or fetch a credential explicitly inside a tool +const analytics = tool( + async (args: { topic: string }) => { + const key = await getCredential('ANALYTICS_KEY'); + return { topic: args.topic, ok: !!key }; + }, + { name: 'analytics', description: 'Query analytics.', inputSchema: { + type: 'object', properties: { topic: { type: 'string' } }, required: ['topic'], + }, credentials: ['ANALYTICS_KEY'] }, +); + +// HTTP tool with ${CRED} header substitution +const searchApi = httpTool({ + name: 'search_api', + description: 'Search.', + url: 'https://api.example.com/search', + headers: { Authorization: 'Bearer ${SEARCH_API_KEY}' }, + credentials: ['SEARCH_API_KEY'], +}); + +const agent = new Agent({ + name: 'credentialed_agent', + model: 'anthropic/claude-sonnet-4-6', + instructions: '…', + tools: [dbLookup, analytics, searchApi], + credentials: ['DB_API_KEY', 'ANALYTICS_KEY', 'SEARCH_API_KEY'], +}); +``` + +You can also pass `credentials` at call time: `runtime.run(agent, prompt, { +credentials: ['X'] })`. + +## Skills + +`skill(path, options?)` loads a `SKILL.md` skill directory as an `Agent`; +`loadSkills(dir)` loads every skill subdirectory keyed by name. Skills are +framework agents (`_framework: "skill"`) and run via the same `run()` path; +they can be wrapped with `agentTool` and used inside other agents. + +```ts +import { skill, loadSkills, agentTool, Agent } from '@io-orkes/conductor-javascript/agents'; + +const reviewer = skill('./skills/code-review', { model: 'openai/gpt-4o' }); +const all = loadSkills('./skills'); // Record + +const orchestrator = new Agent({ + name: 'lead', + model: 'anthropic/claude-sonnet-4-6', + instructions: 'Delegate reviews to the code-review skill.', + tools: [agentTool(reviewer)], +}); +``` + +## Other exports + +- **Memory:** `ConversationMemory`, `SemanticMemory`, `InMemoryStore` — see + [Stateful agents: Memory](../concepts/stateful.md#memory). +- **Plans:** `Plan`, `Step`, `Op`, `Generate`, `Validation`, `Action`, `Ref`, + `Context`, `coercePlan` — see + [Plans / PLAN_EXECUTE](../concepts/deploy-serve-run.md#plans--plan_execute). +- **Liveness:** `LivenessMonitor`, `LivenessMonitorOptions` — see + [Liveness monitoring](../concepts/stateful.md#liveness-monitoring). +- **Code execution:** `LocalCodeExecutor`, `DockerCodeExecutor`, + `JupyterCodeExecutor`, `ServerlessCodeExecutor`, `CodeExecutor`, + `CommandValidator`. +- **Claude Code:** `ClaudeCode(modelName?, permissionMode?)`, + `PermissionMode`, `resolveClaudeCodeModel`. +- **Extended agents:** `GPTAssistantAgent({ name, assistantId, model?, + instructions? })`. +- **Framework integration:** `detectFramework`, `serializeFrameworkAgent`, + `serializeLangGraph`, `serializeLangChain` — see + [Framework bridges](../README.md#framework-bridges). +- **Subpath exports:** `@io-orkes/conductor-javascript/agents/vercel-ai`, + `@io-orkes/conductor-javascript/agents/langgraph`, + `@io-orkes/conductor-javascript/agents/langchain`, + `@io-orkes/conductor-javascript/agents/testing`. + +## Next steps + +See [agent definition](agent-definition.md) for `Agent`/`AgentOptions`, and +[runtime](runtime.md)/[client](client.md) for the two ways to execute one. diff --git a/docs/agents/reference/client.md b/docs/agents/reference/client.md new file mode 100644 index 00000000..3be0c2c4 --- /dev/null +++ b/docs/agents/reference/client.md @@ -0,0 +1,107 @@ +# AgentClient — control plane + +`AgentClient` is the interface for the `/agent/*` control-plane HTTP surface +(11 ops + `close()`); `OrkesAgentClient` is the Conductor/Orkes +implementation, which also carries the agent-level convenience methods below +(`run`, `start`, `deploy`, `schedule`) and the `workflows`/`schedules` +accessors. **Does not run local tool workers.** Every op rides the shared +`ConductorClient`'s authenticated call path — no bespoke auth/transport logic +lives behind this interface, so it never mints a token independently. + +```ts +new OrkesAgentClient(configuration?: OrkesApiConfig | ConductorClient) +``` + +Obtain one via `runtime.client` (shares the runtime's client, and its single +token mint, across control- and worker-plane calls) or +`OrkesClients.getAgentClient()` (shares whatever `Client` the `OrkesClients` +instance was built with). + +**Control-plane only:** `AgentClient.run`/`start` compile + start an agent +and poll, but do **not** register or poll local tool workers. Use it for +LLM-only agents, agents whose tools are remote (HTTP/MCP), or pre-deployed +workflows. For agents with local `tool()` functions, use `runtime.run()` +instead — see [deploy/serve/run/plan](../concepts/deploy-serve-run.md). + +```ts +const client = runtime.client; // or: orkesClients.getAgentClient() + +// Compile + start + poll to result +const result = await client.run(agent, 'summarize this', { timeoutSeconds: 120 }); + +// Start and interact via a ClientHandle +const handle = await client.start(agent, 'do work'); +const status = await handle.getStatus(); +const final = await handle.wait(); // deadline: timeoutSeconds + 30s, or 10 min default +await handle.approve(); // / reject(reason) / send(message) / respond(body) +await handle.stop(); // stop the execution + +// Compile + register one or more agents (no execution) +const infos = await client.deploy(agentA, agentB); // DeploymentInfo[] + +// Deploy + reconcile cron schedules in one call +import { Schedule } from '@io-orkes/conductor-javascript/agents'; +await client.schedule(agent, [new Schedule({ name: 'nightly', cron: '0 0 0 * * *' })]); +``` + +| Member | Signature | Notes | +|---|---|---| +| `workflows` | `WorkflowClient` | Read-only workflow client. | +| `schedules` | `SchedulerClient` | Cron lifecycle client (SDK scheduler client over the shared Conductor client). | +| `run` | `(agent, prompt, opts?) => Promise` | Compile + start + poll to result. | +| `start` | `(agent, prompt, opts?) => Promise` | Compile + start; returns a handle. | +| `deploy` | `(agent, { schedules? }?) => Promise` \| `(...agents) => Promise` | Compile + register agent(s) (+ reconcile schedules in the single-agent form). | +| `schedule` | `(agent, schedules) => Promise` | Deploy + reconcile schedules. | +| `startAgent` / `deployAgent` / `compile` | `(payload, signal?) => Promise` | Low-level POST endpoints (spec R1 surface). | +| `status` | `(executionId, signal?) => Promise` | GET status. | +| `getExecution` | `(executionId, signal?) => Promise` | Full execution data (tasks, output, tokens). | +| `listExecutions` | `(params?, signal?) => Promise` | List executions, optionally filtered. | +| `respond` | `(executionId, body, signal?) => Promise` | Complete a pending human task. | +| `stop` | `(executionId, signal?) => Promise` | Stop a running execution. | +| `signal` | `(executionId, message, signal?) => Promise` | Inject persistent context into a running execution. | +| `stream` | `(executionId, lastEventId?, signal?) => Promise` | SSE stream for an execution, falling back to status polling automatically if the SSE connection can't be established — see [streaming](../concepts/streaming-hitl.md#sse-fallback). | +| `close` | `() => Promise` | Release this client's open `AgentStream`s. | + +### ClientHandle + +Returned by `AgentClient.start`. `{ executionId, getStatus(), wait(pollIntervalMs?), +respond(output), approve(output?), reject(reason?), send(message), stop(), +stream() }`. `wait()` rejects once its deadline passes +(`timeoutSeconds`-derived, or 10 min default) with an `AgentAPIError` naming +the last known status. + +`stop`, `signal`, and `respond` change a durable execution — authorize +callers before exposing them, and make externally triggered calls (e.g. an +approval webhook) idempotent, since a retried request should be safe to +replay. + +## WorkflowClient — execution reads + +`runtime.workflows` (also `runtime.client.workflows`) is a read-only +`WorkflowClient` over the underlying Conductor workflow API. + +```ts +const wf = await runtime.workflows.getWorkflow(executionId); // full execution (with tasks) +const status = await runtime.workflows.getStatus(executionId); // 'RUNNING' | 'COMPLETED' | ... +const usage = await runtime.workflows.extractTokenUsage(executionId);// aggregated across sub-workflows +// usage -> { promptTokens, completionTokens, totalTokens } | null +``` + +| Method | Signature | Notes | +|---|---|---| +| `getWorkflow` | `(executionId, includeTasks = true) => Promise` | Full execution (with tasks). | +| `getStatus` | `(executionId) => Promise` | `'RUNNING'` / `'COMPLETED'` / ... or `''`. | +| `extractTokenUsage` | `(executionId) => Promise` | Aggregated across sub-workflows. | + +`extractTokenUsage` walks the execution tree (recursing into `SUB_WORKFLOW` +tasks) and sums token usage — useful for multi-agent runs where tokens are +spread across sub-workflows. Note: `result.tokenUsage` is already populated +for you on a normal `run()`; this is for inspecting an execution by id after +the fact. `WorkflowTokenUsage` = `{ promptTokens, completionTokens, +totalTokens }`. + +## Next steps + +See [runtime](runtime.md) for the local-worker-owning `AgentRuntime`, and +[streaming and approval](../concepts/streaming-hitl.md) for the +human-in-the-loop control flow these endpoints back. diff --git a/docs/agents/reference/runtime.md b/docs/agents/reference/runtime.md new file mode 100644 index 00000000..664c478f --- /dev/null +++ b/docs/agents/reference/runtime.md @@ -0,0 +1,102 @@ +# AgentRuntime reference + +```ts +new AgentRuntime(configuration?: OrkesApiConfig | ConductorClient, settings?: AgentConfigOptions) +``` + +`configuration` is connection/auth — the same shape every other Conductor +client takes (`OrkesApiConfig`, or a pre-built `ConductorClient` from +`createConductorClient()`/`OrkesClients` to share one client — and one token +mint — across control-plane and worker-plane calls). Falls back to +`CONDUCTOR_SERVER_URL`/`CONDUCTOR_AUTH_KEY`/`CONDUCTOR_AUTH_SECRET`, then +`http://localhost:8080`. `settings` is `AgentConfigOptions` — purely +behavioral (no connection fields); every field falls back to an env var, +then a default; explicit values take precedence. Both arguments are +optional. + +```ts +import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; + +const runtime = new AgentRuntime( + { serverUrl: 'http://localhost:8080/api', keyId: '…', keySecret: '…' }, // connection (OrkesApiConfig) + { + workerPollIntervalMs: 100, // CONDUCTOR_AGENT_WORKER_POLL_INTERVAL + workerThreadCount: 1, // CONDUCTOR_AGENT_WORKER_THREADS + streamingEnabled: true, // CONDUCTOR_AGENT_STREAMING_ENABLED + livenessEnabled: true, // CONDUCTOR_AGENT_LIVENESS_ENABLED + livenessStallSeconds: 30, // CONDUCTOR_AGENT_LIVENESS_STALL_SECONDS + livenessCheckIntervalSeconds: 10, // CONDUCTOR_AGENT_LIVENESS_CHECK_INTERVAL_SECONDS + }, +); + +// Both args are optional -- this reads connection + behavior entirely from env: +const defaultRuntime = new AgentRuntime(); +``` + +| Member | Signature | Notes | +|---|---|---| +| `config` | `AgentConfig` | Resolved behavior config (readonly). | +| `client` | `AgentClient` | Control-plane client (`/agent/*`) — shares the runtime's underlying Conductor client. | +| `workflows` | `WorkflowClient` | Read-only workflow executions. | +| `run` | `(agent, prompt, options?) => Promise` | Compile + start + stream + return result. Registers local workers. | +| `start` | `(agent, prompt, options?) => Promise` | Async interaction handle. | +| `stream` | `(agent, prompt, options?) => Promise` | Event stream. | +| `deploy` | `(agent, { schedules? }?) => Promise` \| `(...agents) => Promise` | Register workflow def(s) (+ reconcile schedules in the single-agent form). No execution, no workers. | +| `plan` | `(agent) => Promise` | Compile to workflow def without executing. | +| `serve` | `(...agents, options?: ServeOptions) => Promise` | Deploys the given agents, registers workers, starts polling. Blocks until SIGINT/SIGTERM by default; `{ blocking: false }` returns once deploy + registration + polling have started. With no agents, resumes polling for whatever workers are already registered — the crash-recovery pattern (see below). | +| `getStatus` | `(executionId, signal?) => Promise` | Current execution status. | +| `schedulesClient` | `() => SchedulerClient` | Schedule lifecycle client (the SDK scheduler client). | +| `shutdown` | `() => Promise` | Stop worker polling. | + +`agent` is an `Agent` or a detected framework object. `options?: RunOptions` +on `run`/`start`/`stream` includes `runSettings` (see +[RunSettings](api.md#runsettings)). Module-level helpers +`configure(configuration?, settings?)`, `run`, `start`, `stream`, `deploy`, +`plan`, `serve`, `shutdown` operate on a shared singleton runtime. + +```ts +import { configure, run, shutdown } from '@io-orkes/conductor-javascript/agents'; +configure({ serverUrl: 'http://localhost:8080/api' }); +const result = await run(agent, 'hi'); +await shutdown(); +``` + +Share one runtime for an application's lifetime rather than constructing one +per request — each runtime owns its own worker-polling loop and token mint. + +## AgentConfig / AgentConfigOptions + +Behavior-only — no connection/auth fields (those live on `OrkesApiConfig`, +the `AgentRuntime`/`OrkesAgentClient` constructors' first argument). + +```ts +interface AgentConfigOptions { + workerPollIntervalMs?: number; // CONDUCTOR_AGENT_WORKER_POLL_INTERVAL (100) + workerThreadCount?: number; // CONDUCTOR_AGENT_WORKER_THREADS (1) + autoStartWorkers?: boolean; // CONDUCTOR_AGENT_AUTO_START_WORKERS (true) + streamingEnabled?: boolean; // CONDUCTOR_AGENT_STREAMING_ENABLED (true) + livenessEnabled?: boolean; // CONDUCTOR_AGENT_LIVENESS_ENABLED (true) + livenessStallSeconds?: number; // CONDUCTOR_AGENT_LIVENESS_STALL_SECONDS (30) + livenessCheckIntervalSeconds?: number; // CONDUCTOR_AGENT_LIVENESS_CHECK_INTERVAL_SECONDS (10) +} +``` + +Each falls back to its `CONDUCTOR_AGENT_*` env var, then the default above. +`AgentConfig.fromEnv()` is an exported helper (equivalent to `new +AgentConfig()`). See [liveness monitoring](../concepts/stateful.md#liveness-monitoring) +for the liveness fields. + +## Reattaching after a process restart + +There's no `resume(executionId, agent)` method on `AgentRuntime` — recovery +after a worker process crash is process-level, not execution-level: call +`serve()` with no agents in the replacement process, which resumes polling +for whatever tool workers are already registered on the server. See +[stateful agents](../concepts/stateful.md#recovering-after-a-worker-process-restart) +for how a stalled execution surfaces (`WorkerStallError`) in the first place. + +## Cleanup and next steps + +Call `shutdown()` to stop local worker polling. Continue with +[deploy/serve/run/plan](../concepts/deploy-serve-run.md) and +[control plane](client.md). diff --git a/docs/agents/writing-agents.md b/docs/agents/writing-agents.md index 383d6afe..de279b04 100644 --- a/docs/agents/writing-agents.md +++ b/docs/agents/writing-agents.md @@ -1,471 +1,13 @@ # Writing Agents -Everything you author is an `Agent`. A simple LLM agent, a tool-using agent, and a multi-agent orchestration are all the same `Agent` class with different options. This page walks the authoring surface. - -All snippets import from `@io-orkes/conductor-javascript/agents` and assume a runtime: - -```ts -import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; -const runtime = new AgentRuntime(); -``` - -## Defining an agent - -```ts -const agent = new Agent({ - name: 'greeter', // required; must match /^[a-zA-Z][a-zA-Z0-9_-]*$/ - model: 'anthropic/claude-sonnet-4-6', // provider/model string - instructions: 'Keep answers short.', - temperature: 0.7, - maxTurns: 25, // default 25 - maxTokens: 2048, - timeoutSeconds: 0, // 0 = server default -}); -``` - -There is also a functional form, `agent(fn, options)`, where `fn` is the dynamic-instructions callable (see below): - -```ts -import { agent } from '@io-orkes/conductor-javascript/agents'; - -const a = agent(() => 'You are a helpful assistant.', { - name: 'helper', - model: 'anthropic/claude-sonnet-4-6', -}); -``` - -### Instructions - -Instructions can be a plain string, a callable, or a server-managed prompt template. - -```ts -// Static -new Agent({ name: 'a', model, instructions: 'You are concise.' }); - -// Dynamic (callable) — evaluated to a string when the agent is serialized -new Agent({ name: 'a', model, instructions: () => `Today is ${new Date().toDateString()}.` }); - -// Server-managed prompt template (referenced by name + version) -import { PromptTemplate } from '@io-orkes/conductor-javascript/agents'; -new Agent({ - name: 'a', - model, - instructions: new PromptTemplate('support_greeting', { brand: 'Acme' }, 1), -}); -``` - -## Tools - -### Local tools — `tool()` - -`tool()` wraps an async function. Pass a Zod schema **or** a plain JSON Schema object for `inputSchema`. The function runs locally as a Conductor worker that the runtime polls; the runtime registers and polls it automatically on `run()` / `serve()`. - -```ts -const getWeather = tool( - async (args: { city: string }) => { - return { city: args.city, tempC: 21, conditions: 'sunny' }; - }, - { - name: 'get_weather', - description: 'Get the current weather for a city.', - inputSchema: { - type: 'object', - properties: { city: { type: 'string', description: 'City name' } }, - required: ['city'], - }, - }, -); - -const agent = new Agent({ - name: 'weather_agent', - model: 'anthropic/claude-sonnet-4-6', - instructions: 'Answer weather questions using the tool.', - tools: [getWeather], -}); -``` - -`tool()` options: `name`, `description`, `inputSchema`, `outputSchema?`, `approvalRequired?`, `timeoutSeconds?`, `external?`, `credentials?`, `guardrails?`, `maxCalls?`, `retryCount?`, `retryDelaySeconds?`, `retryPolicy?`. - -The tool function receives an optional second argument, the [`ToolContext`](api-reference.md#toolcontext) (`sessionId`, `executionId`, `agentName`, `metadata`, `dependencies`, and a mutable `state`). See [Stateful agents](#stateful-agents). - -**No per-run mutable capture.** A `tool()` handler is registered once and its Conductor worker is reused across concurrent runs and (for framework-spawned agents) concurrent process-local executors — never re-created per run. Don't close over per-run mutable state in the handler itself (a module-level counter, an array pushed to across calls, a captured `let` reassigned mid-run); two runs executing the same tool concurrently would corrupt each other's state. Everything a handler needs that varies per run belongs in `ToolContext` (`state` for durable per-execution data, `dependencies` for injected collaborators) or in the function's own arguments — never in a closure variable mutated across invocations. Tool and agent factories otherwise take plain data (JSON-serializable configs), so building one is always safe to repeat. - -### Tool discovery — `@Tool` / `toolsFrom` - -Decorate methods on a class and extract them, bound to the instance: - -```ts -import { Tool, toolsFrom } from '@io-orkes/conductor-javascript/agents'; - -class MathTools { - @Tool({ description: 'Add two numbers.', inputSchema: { - type: 'object', properties: { a: { type: 'number' }, b: { type: 'number' } }, required: ['a', 'b'], - }}) - async add(args: { a: number; b: number }) { return { sum: args.a + args.b }; } -} - -const tools = toolsFrom(new MathTools()); // ToolFunction[] -new Agent({ name: 'calc', model, tools }); -``` - -> `@Tool`/`@AgentDec` are TypeScript experimental decorators — set `"experimentalDecorators": true` in your `tsconfig.json`. - -### Built-in tools - -These return a `ToolDef` that runs server-side (no local worker). Add them to `tools: [...]`. - -| Builder | Tool type | Purpose | -|---|---|---| -| `httpTool({ name, description, url, method?, headers?, inputSchema?, credentials? })` | `http` | Call an HTTP endpoint. | -| `mcpTool({ serverUrl, name?, description?, headers?, toolNames?, maxTools?, credentials? })` | `mcp` | Expose an MCP server's tools. | -| `apiTool({ url, name?, description?, headers?, toolNames?, maxTools?, credentials? })` | `api` | Expose an OpenAPI/API as tools. | -| `agentTool(agent, { name?, description?, retryCount?, retryDelaySeconds?, optional? })` | `agent_tool` | Call another `Agent` as a tool (sub-agent). | -| `humanTool({ name, description, inputSchema? })` | `human` | Pause for human input (HITL). | -| `imageTool({ name, description, llmProvider, model, style?, size? })` | `generate_image` | Generate images. | -| `audioTool({ name, description, llmProvider, model, voice?, speed?, format? })` | `generate_audio` | Text-to-speech. | -| `videoTool({ name, description, llmProvider, model, duration?, resolution?, fps?, ... })` | `generate_video` | Generate video. | -| `pdfTool({ name?, description?, pageSize?, theme?, fontSize? })` | `generate_pdf` | Render markdown to PDF. | -| `waitForMessageTool({ name, description, batchSize?, blocking? })` | `pull_workflow_messages` | Dequeue messages from the workflow message queue. | -| `searchTool({ name, description, vectorDb, index, embeddingModelProvider, embeddingModel, namespace?, maxResults? })` | `rag_search` | RAG vector search. | -| `indexTool({ name, description, vectorDb, index, embeddingModelProvider, embeddingModel, namespace?, chunkSize?, chunkOverlap? })` | `rag_index` | RAG index/ingest. | - -```ts -import { httpTool, mcpTool } from '@io-orkes/conductor-javascript/agents'; - -const agent = new Agent({ - name: 'researcher', - model: 'anthropic/claude-sonnet-4-6', - tools: [ - httpTool({ - name: 'get_user', - description: 'Fetch a user by id.', - url: 'https://api.example.com/users/{id}', - method: 'GET', - }), - mcpTool({ serverUrl: 'https://mcp.example.com/sse', toolNames: ['search'] }), - ], -}); -``` - -#### `waitForMessageTool` — workflow message queue - -`waitForMessageTool` lets a running agent dequeue messages pushed into its workflow message queue (Conductor `PULL_WORKFLOW_MESSAGES`). No worker is needed — the server handles it. In blocking mode (default) the task stays in progress until a message arrives. - -```ts -import { waitForMessageTool } from '@io-orkes/conductor-javascript/agents'; - -const agent = new Agent({ - name: 'inbox_agent', - model: 'anthropic/claude-sonnet-4-6', - instructions: 'When asked to wait, call wait_for_message and process what arrives.', - tools: [waitForMessageTool({ - name: 'wait_for_message', - description: 'Wait for the next inbound message.', - batchSize: 1, // up to 100; default 1 - blocking: true, // default true - })], -}); -``` - -#### `agentTool` — agent as a tool - -```ts -import { agentTool } from '@io-orkes/conductor-javascript/agents'; - -const translator = new Agent({ name: 'translator', model, instructions: 'Translate to French.' }); - -const orchestrator = new Agent({ - name: 'orchestrator', - model, - instructions: 'Use the translator tool when asked to translate.', - tools: [agentTool(translator, { description: 'Translate text to French.' })], -}); -``` - -## Multi-agent strategies - -Set `agents: [...]` and a `strategy`. Strategies: `'sequential'`, `'parallel'`, `'handoff'`, `'router'`, `'round_robin'`, `'random'`, `'swarm'`, `'manual'`, `'plan_execute'`. - -```ts -// Sequential — agents run in order. .pipe() is sugar for strategy: 'sequential'. -const pipeline = writer.pipe(editor); -// equivalent to: -// new Agent({ name: 'writer_editor', agents: [writer, editor], strategy: 'sequential' }); - -// Parallel — agents run concurrently, results gathered -const team = new Agent({ name: 'research_team', agents: [webResearcher, dataAnalyst], strategy: 'parallel' }); - -// Handoff — the parent LLM delegates to sub-agents (they appear as callable tools) -const support = new Agent({ - name: 'support', - model, - instructions: 'Route to the right specialist.', - agents: [billingAgent, technicalAgent, salesAgent], - strategy: 'handoff', -}); - -// Router — a router agent (or function) picks the sub-agent -const routed = new Agent({ - name: 'router', - agents: [a, b], - strategy: 'router', - router: routerAgent, // an Agent or (…) => string returning a sub-agent name -}); -``` - -`scatterGather({ name, workers, ... })` is a convenience builder that returns a coordinator agent which fans a problem out to worker agents in parallel and synthesizes the results: - -```ts -import { scatterGather } from '@io-orkes/conductor-javascript/agents'; -const coordinator = scatterGather({ name: 'fanout', workers: [worker], retryCount: 2 }); -``` - -## Handoffs - -For `swarm`/`handoff` strategies you can declare explicit handoff transitions with `handoffs: [...]`. Each condition has a `target` (a sub-agent name). - -```ts -import { OnTextMention, OnToolResult, OnCondition } from '@io-orkes/conductor-javascript/agents'; - -const team = new Agent({ - name: 'coding_team', - model, - agents: [pythonExpert, jsExpert], - strategy: 'swarm', - handoffs: [ - // Hand off when the output mentions text (case-insensitive) - new OnTextMention({ target: 'python_expert', text: 'Python' }), - - // Hand off when a specific tool returns (optionally only if result contains text) - new OnToolResult({ target: 'escalation', toolName: 'detect_severity', resultContains: 'critical' }), - - // Hand off when a custom predicate returns true (runs as a worker task) - new OnCondition({ target: 'fallback', condition: (ctx) => ctx.result.length > 1000 }), - ], -}); -``` - -You can also constrain which transitions are allowed with `allowedTransitions: { agentName: ['otherAgent', ...] }`. - -## Guardrails - -Guardrails validate input or output. Attach them at the agent level (`guardrails: [...]`) or per-tool (`tool(fn, { guardrails: [...] })`). Each has a `position` (`'input'` | `'output'`, default `'output'`) and an `onFail` policy (`'raise'` | `'retry'` | `'fix'` | `'human'`, default `'raise'`). - -```ts -import { guardrail, RegexGuardrail, LLMGuardrail } from '@io-orkes/conductor-javascript/agents'; - -// Regex (runs on the server, no worker) -const noSecrets = new RegexGuardrail({ - name: 'no_api_keys', - patterns: ['sk-[A-Za-z0-9]{20,}'], - mode: 'block', // 'block' fails if any pattern matches; 'allow' fails if none match - onFail: 'raise', - message: 'Output contained a secret.', -}); - -// LLM (server-side LLM judge) -const policy = new LLMGuardrail({ - name: 'safety', - model: 'anthropic/claude-sonnet-4-6', - policy: 'Reject any content that gives medical dosage advice.', - position: 'output', - onFail: 'retry', - maxRetries: 2, -}); - -// Custom (your function, runs locally as a worker) -const minLength = guardrail( - (content: string) => ({ passed: content.length >= 10, message: 'Too short' }), - { name: 'min_length', position: 'output', onFail: 'fix' }, -); - -const agent = new Agent({ - name: 'safe_agent', - model, - instructions: '…', - guardrails: [noSecrets.toGuardrailDef?.() ?? noSecrets, policy.toGuardrailDef?.() ?? policy, minLength], -}); -``` - -`RegexGuardrail` / `LLMGuardrail` are class instances; the serializer accepts the instance directly. There is also a `guardrail.external({ name, position?, onFail? })` form for guardrails handled by a remote worker, and a `@Guardrail` decorator with `guardrailsFrom(instance)`. - -## Termination + TextGate - -Termination conditions decide when a multi-turn / multi-agent loop should stop. Pass one to `termination:`. They compose with `.and()` / `.or()` (or the variadic `AndCondition` / `OrCondition`). - -```ts -import { TextMention, MaxMessage, TokenUsageCondition, StopMessage } from '@io-orkes/conductor-javascript/agents'; - -const agent = new Agent({ - name: 'debate', - model, - agents: [a, b], - strategy: 'round_robin', - termination: new TextMention('TERMINATE') // stop when output mentions text - .or(new MaxMessage(10)) // …or after 10 messages - .or(new TokenUsageCondition({ maxTotalTokens: 50000 })), -}); -``` - -Available conditions: `TextMention(text, caseSensitive?)`, `StopMessage(stopMessage)`, `MaxMessage(maxMessages)`, `TokenUsageCondition({ maxTotalTokens?, maxPromptTokens?, maxCompletionTokens? })`, and the composites `AndCondition(...)` / `OrCondition(...)`. - -`TextGate` and `gate()` gate transitions (e.g. on `gate:`): - -```ts -import { TextGate } from '@io-orkes/conductor-javascript/agents'; -new Agent({ name: 'a', model, gate: new TextGate({ text: 'APPROVED', caseSensitive: false }) }); -``` - -## Callbacks - -Subclass `CallbackHandler` and override the lifecycle hooks you care about. Each hook runs as a server-registered worker. - -```ts -import { CallbackHandler } from '@io-orkes/conductor-javascript/agents'; - -class Logger extends CallbackHandler { - async onAgentStart(agentName: string, prompt: string) { console.log('[start]', agentName, prompt); } - async onToolStart(agentName: string, toolName: string, args: unknown) { console.log('[tool]', toolName, args); } - async onAgentEnd(agentName: string, result: unknown) { console.log('[end]', agentName); } -} - -const agent = new Agent({ name: 'a', model, instructions: '…', callbacks: [new Logger()] }); -``` - -Hooks: `onAgentStart`, `onAgentEnd`, `onModelStart`, `onModelEnd`, `onToolStart`, `onToolEnd`. - -## Streaming - -`runtime.stream(agent, prompt)` returns an `AgentStream` you can `for await` over. Events have a `type` (`'thinking'`, `'tool_call'`, `'tool_result'`, `'waiting'`, `'handoff'`, `'message'`, `'done'`, ...). You can also `runtime.start(...)` and call `handle.stream()`. - -```ts -const stream = await runtime.stream(agent, 'Plan a 3-day trip to Tokyo.'); -for await (const event of stream) { - if (event.type === 'thinking') console.log('[thinking]', event.content); - else if (event.type === 'tool_call') console.log('[tool]', event.toolName, event.args); - else if (event.type === 'tool_result') console.log('[result]', event.toolName, event.result); - else if (event.type === 'done') console.log('[done]', event.output); -} -const result = await stream.getResult(); // terminal AgentResult after the stream ends -``` - -## Human-in-the-loop (HITL) - -A tool with `approvalRequired: true`, or a `humanTool`, pauses execution and emits a `waiting` event. Resolve it via the handle / stream: `approve(output?)`, `reject(reason?)`, `send(message)`, or `respond(body)`. - -```ts -const deleteData = tool( - async (args: { table: string }) => ({ deleted: args.table }), - { - name: 'delete_data', - description: 'Delete a table. Destructive — requires approval.', - inputSchema: { type: 'object', properties: { table: { type: 'string' } }, required: ['table'] }, - approvalRequired: true, - }, -); - -const agent = new Agent({ name: 'ops', model, tools: [deleteData], instructions: '…' }); - -const handle = await runtime.start(agent, 'Delete the stale_cache table.'); -for await (const event of handle.stream()) { - if (event.type === 'waiting') { - // The waiting event carries the pending tool batch on event.pendingTool, - // or fetch the full status: - const status = await handle.getStatus(); - console.log('Approval needed for:', status.pendingTool?.toolCalls); - - await handle.approve(); // approve, or: - // await handle.reject('Not allowed'); - // await handle.respond({ approved: true, note: 'go ahead' }); - } else if (event.type === 'done') { - console.log('done', event.output); - } -} -``` - -One HUMAN task gates the whole batch of pending tool calls with a single `{ approved, reason }` verdict — iterate `pendingTool.toolCalls` to see every tool covered. The `pendingTool` is mirrored onto the `waiting` event so you can read it without a `getStatus()` round-trip. - -`humanTool` works the same way but lets the LLM ask the human a structured question; the response schema is on `pendingTool.response_schema`. - -## Schedules - -Attach cron schedules to an agent at deploy time. Reconciliation is declarative: a list upserts those and prunes the rest; `[]` purges all; omitting `schedules` leaves them untouched. - -```ts -import { Agent, AgentRuntime, Schedule, schedules } from '@io-orkes/conductor-javascript/agents'; - -const digest = new Agent({ name: 'eng_digest', model, instructions: 'Write a digest.' }); - -await runtime.deploy(digest, { - schedules: [ - new Schedule({ - name: 'weekday-9am', - cron: '0 0 9 * * MON-FRI', - timezone: 'America/Los_Angeles', - input: { channel: '#eng' }, - description: 'Weekday morning digest', - }), - ], -}); - -// Inspect / control via the `schedules` namespace -const infos = await schedules.list({ agent: digest.name }); -await schedules.pause(infos[0].name, { reason: 'cooldown' }); -await schedules.resume(infos[0].name); -const execId = await schedules.runNow(infos[0].name); -const next = await schedules.previewNext('0 0 9 * * MON-FRI', { n: 5 }); - -await runtime.deploy(digest, { schedules: [] }); // purge all -``` - -Lifecycle calls (`get`/`pause`/`resume`/`delete`/`runNow`) key on the **wire name** (the prefixed `name` returned in `ScheduleInfo`), not the short name you supplied. The `AgentClient` also has `schedule(agent, schedules)` (see [advanced.md](advanced.md#agentclient--control-plane)). - -## Agent-from-method (`@AgentDec` / `agentsFrom`) - -Define agents as decorated methods on a class and extract them: - -```ts -import { AgentDec, agentsFrom } from '@io-orkes/conductor-javascript/agents'; - -class MyAgents { - @AgentDec({ name: 'summarizer', model: 'anthropic/claude-sonnet-4-6', instructions: 'Summarize text.' }) - summarize() {} - - @AgentDec({ name: 'classifier', model: 'anthropic/claude-sonnet-4-6', instructions: 'Classify text.' }) - classify() {} -} - -const [summarizer, classifier] = agentsFrom(new MyAgents()); // Agent[] -``` - -## Stateful agents - -Set `stateful: true` on an agent (or `stateful: true` on a tool def) to isolate tool workers per execution via a unique domain UUID. Within a single run, tools share a mutable `context.state` object; mutations are captured and propagated between tool calls. - -```ts -import type { ToolContext } from '@io-orkes/conductor-javascript/agents'; - -const addItem = tool( - async (args: { item: string }, ctx?: ToolContext) => { - const items: string[] = (ctx?.state?.list as string[]) ?? []; - items.push(args.item); - if (ctx?.state) ctx.state.list = items; - return { total: items.length }; - }, - { name: 'add_item', description: 'Add an item.', inputSchema: { - type: 'object', properties: { item: { type: 'string' } }, required: ['item'], - }}, -); - -const agent = new Agent({ name: 'list_agent', model, tools: [addItem], stateful: true }); -``` - -### Liveness monitoring - -For a stateful run (one with a domain-isolated worker), `runtime.start()`/`run()`/`stream()` also start a liveness monitor: it polls the execution's workflow every `livenessCheckIntervalSeconds` and, if a `SCHEDULED`/`IN_PROGRESS` task in that run's domain sits unpolled (`pollCount === 0`) for longer than `livenessStallSeconds`, a blocking `wait()` rejects with `WorkerStallError` instead of hanging forever — the signal that the local worker process for this run's domain died. The monitor stops on terminal status or handle disposal and never keeps the process alive on its own. Configure via `AgentConfig`/env: `livenessEnabled` (`AGENTSPAN_LIVENESS_ENABLED`, default `true`), `livenessStallSeconds` (`AGENTSPAN_LIVENESS_STALL_SECONDS`, default `30`), `livenessCheckIntervalSeconds` (`AGENTSPAN_LIVENESS_CHECK_INTERVAL_SECONDS`, default `10`). Framework-spawned agents (LangGraph/LangChain/Vercel AI wrappers) never route through a per-run domain, so liveness monitoring doesn't apply to them. - -## Next - -- [framework-agents.md](framework-agents.md) — run OpenAI / ADK / LangChain / LangGraph / Vercel AI agents. -- [advanced.md](advanced.md) — deploy/serve, control plane, structured output, credentials, plans, skills. -- [api-reference.md](api-reference.md) — full public surface. +This page has moved to: + +- [Agents](concepts/agents.md) — defining an agent, instructions, agent-from-method +- [Tools](concepts/tools.md) — `tool()`, discovery, built-in tools +- [Multi-agent](concepts/multi-agent.md) — strategies, handoffs +- [Guardrails](concepts/guardrails.md) +- [Termination](concepts/termination.md) — termination conditions, `TextGate` +- [Callbacks](concepts/callbacks.md) +- [Streaming and HITL](concepts/streaming-hitl.md) +- [Scheduling](concepts/scheduling.md) +- [Stateful agents](concepts/stateful.md) — including memory and liveness monitoring diff --git a/docs/api-map.md b/docs/api-map.md new file mode 100644 index 00000000..097ea1ed --- /dev/null +++ b/docs/api-map.md @@ -0,0 +1,21 @@ +# Core API map + +| Need | JS/TS type | Reference | +|---|---|---| +| Configure transport and auth | `OrkesClients` / `createConductorClient` | [connection/authentication](connection-authentication.md) | +| Run workflow executions | `WorkflowExecutor` | [workflow-executor.md](api-reference/workflow-executor.md) | +| Poll and update tasks | `TaskHandler` / `TaskClient` / `TaskManager` | [task-client.md](api-reference/task-client.md), [task-manager.md](api-reference/task-manager.md) | +| Manage definitions | `MetadataClient` | [metadata-client.md](api-reference/metadata-client.md) | +| Schedule workflows | `SchedulerClient` | [scheduler-client.md](api-reference/scheduler-client.md) | +| Manage schemas | `SchemaClient` | [schema client](schema-client.md) (no dedicated reference page yet) | +| Manage secrets, auth, integrations | `SecretClient` / `AuthorizationClient` / `IntegrationClient` | [security](security.md) (no dedicated reference pages yet) | +| Human-in-the-loop tasks | `HumanExecutor` / `TemplateClient` | [human-executor.md](api-reference/human-executor.md), [template-client.md](api-reference/template-client.md) | +| Events | `EventClient` | [event-client.md](api-reference/event-client.md) | +| Service discovery | `ServiceRegistryClient` | [service-registry-client.md](api-reference/service-registry-client.md) | +| Applications/access keys | `ApplicationClient` | [application-client.md](api-reference/application-client.md) | +| Compile, deploy, run, signal agents | `AgentClient` / `AgentRuntime` | [agent control plane](agents/reference/client.md) | +| Consume the workflow message queue (WMQ) | `pullWorkflowMessages` / `waitForMessageTool` | [workflow-message-queue.md](workflow-message-queue.md) | + +JS does not currently expose a public workflow-scoped `FileClient`; use the +server and task capabilities appropriate to your deployment instead — see +[compatibility](compatibility.md). diff --git a/docs/api-reference/task-generators.md b/docs/api-reference/task-generators.md index fb9744f4..d0aefcdc 100644 --- a/docs/api-reference/task-generators.md +++ b/docs/api-reference/task-generators.md @@ -295,6 +295,23 @@ const task = newLoopTask("loop_ref", 5, [ ]); ``` +## Pull Workflow Messages Task + +_System Task_ - Dequeues messages from the workflow's message queue (WMQ). +Stays `IN_PROGRESS` while the queue is empty; see +[workflow-message-queue.md](../workflow-message-queue.md) for the server +requirement and an agent-facing alternative. + +```typescript +import { pullWorkflowMessages } from "@io-orkes/conductor-javascript"; + +const task = pullWorkflowMessages( + "pull_ref", // taskReferenceName (required) + 5, // batchSize (optional): max messages per execution, default 1 + false // optional (optional): if true, workflow continues on failure +); +``` + ## Workflow Generator Helper function to create workflow definitions. diff --git a/docs/compatibility.md b/docs/compatibility.md new file mode 100644 index 00000000..b94099f7 --- /dev/null +++ b/docs/compatibility.md @@ -0,0 +1,25 @@ +# Compatibility matrix + +| Area | Supported baseline | Notes | +|---|---|---| +| JS/TS SDK | Node.js >= 18 | Defined by `package.json`'s `engines` field. | +| OSS Conductor | Supported server deployment | Test the target server during upgrades. | +| Orkes | Supported tenant API | Enterprise features depend on tenant permissions. | +| Conductor agents | Server agent runtime and provider integration | Provider credentials live on the server, not the client. | + +The JS SDK does not currently provide Java's `FileClient` or Spring Boot +modules — this documentation does not present either as available JS +support. + +## Workflow-scoped files + +The JS SDK does not currently expose a public workflow-scoped `FileClient`. +Use task-appropriate object storage or a server capability selected by your +deployment; do not copy Java `FileClient` examples into JS applications. + +## Framework/runtime integration + +Spring and Spring Boot modules are Java-specific. Host workers and +`AgentRuntime` services in whatever Node.js framework your deployment uses — +see [express-worker-service.ts](../examples/express-worker-service.ts) and +[deployment/scaling](deployment-scaling.md). diff --git a/docs/connection-authentication.md b/docs/connection-authentication.md new file mode 100644 index 00000000..ef7a411b --- /dev/null +++ b/docs/connection-authentication.md @@ -0,0 +1,23 @@ +# Connection and authentication + +Every client (`OrkesClients.from()`, `createConductorClient()`, +`AgentRuntime`, ...) resolves the same way: `CONDUCTOR_SERVER_URL` -> +explicit config -> default `http://localhost:8080`. Auth follows the same +chain: `CONDUCTOR_AUTH_KEY` / `CONDUCTOR_AUTH_SECRET` -> explicit config -> +`undefined` (no-auth). No other env var names are read. + +```typescript +import { OrkesClients } from "@io-orkes/conductor-javascript"; + +const clients = await OrkesClients.from(); // reads CONDUCTOR_* from env +const executor = clients.getWorkflowClient(); +``` + +**OSS:** a local development server may allow anonymous access (leave +`CONDUCTOR_AUTH_KEY`/`SECRET` unset). **Orkes:** use the tenant API endpoint +and an application access key/secret. Never put credentials in workflow +input, agent prompts, task output, example source, or version control. + +If requests fail, verify the URL ends in `/api`, the server is reachable, and +the credentials belong to that endpoint — see [debugging](debugging.md). +Next: [core quickstart](core-quickstart.md). diff --git a/docs/core-quickstart.md b/docs/core-quickstart.md new file mode 100644 index 00000000..642f9efc --- /dev/null +++ b/docs/core-quickstart.md @@ -0,0 +1,18 @@ +# Core workflow and worker quickstart + +**Prerequisites:** Node.js >= 18, `npm install @io-orkes/conductor-javascript`, +and a reachable Conductor server from [server setup](server-setup.md). + +```shell +npx ts-node examples/quickstart.ts +``` + +Expected result: the workflow completes and prints `result: Hello Conductor`. +The example registers a `greetings` workflow, starts a `@worker`-decorated +task handler, executes the workflow, and prints its output. If the task stays +`SCHEDULED`, verify the worker is polling the exact `taskDefName` before the +workflow runs. + +See the root [README's 60-Second Quickstart](../README.md#60-second-quickstart) +for the full walkthrough. Continue with [workers](workers.md) or +[workflows](workflows.md). diff --git a/docs/debugging.md b/docs/debugging.md new file mode 100644 index 00000000..e0b8e89a --- /dev/null +++ b/docs/debugging.md @@ -0,0 +1,18 @@ +# Debugging incidents + +Start with safe evidence: workflow ID, task reference, status, retry count, +and `reasonForIncompletion`. Confirm server reachability and authentication +before changing application code. + +| Symptom | First check | +|---|---| +| Connection error | `CONDUCTOR_SERVER_URL` includes `/api` and the server is healthy. | +| Task stuck in `SCHEDULED` | A worker is polling the exact `taskDefName` (and `domain`, if set) — workers must start before the workflow executes. | +| Authentication failure | `CONDUCTOR_AUTH_KEY`/`CONDUCTOR_AUTH_SECRET` target the active server. | +| Worker stops polling | `TaskHandler` auto-restarts polling loops; check `handler.running`/`handler.runningWorkerCount` and, if metrics are enabled, `worker_restart_total`. | +| Agent cannot call a model | The provider credential is configured on the server, not the client. | + +See the root [README's Troubleshooting section](../README.md#troubleshooting), +[workflow-executor.md](api-reference/workflow-executor.md), and +[agents/reference/client.md](agents/reference/client.md) for the relevant +inspection APIs. diff --git a/docs/deployment-scaling.md b/docs/deployment-scaling.md new file mode 100644 index 00000000..12430a9a --- /dev/null +++ b/docs/deployment-scaling.md @@ -0,0 +1,19 @@ +# Deployment, scaling, and graceful shutdown + +Run `TaskHandler`/worker processes and `AgentRuntime.serve()` as long-lived +Node.js services — containers, VMs, or any process manager. Do not construct +a new client/runtime per request; reuse them for the application's lifetime. + +```typescript +process.on("SIGTERM", async () => { + await handler.stopWorkers(); + process.exit(0); +}); +``` + +Scale by adding worker instances (each polls independently) and use +`concurrency`/`domain` to isolate or parallelize specific task types rather +than the whole process. On shutdown, stop task handlers and runtimes so +in-flight tasks are redelivered instead of abandoned — see +[reliability](reliability.md) for timeout/retry policy that governs +redelivery. diff --git a/docs/documentation-parity.md b/docs/documentation-parity.md new file mode 100644 index 00000000..15d3e053 --- /dev/null +++ b/docs/documentation-parity.md @@ -0,0 +1,89 @@ +# JS/Java/Python documentation parity + +Java and Python follow a shared documentation architecture: a set of core +guides (server setup, quickstart, workflows, workers, lifecycle, testing), a +set of operations guides (schema client, schedules/events, reliability, +security, deployment, observability, debugging), and an agent doc tree split +into `agents/concepts/*`, `agents/reference/*`, and `agents/frameworks/*`. + +The JS SDK's doc tree now follows the same structure for both halves. The +agent doc tree matches content topic-by-topic against Python's +`concepts/`/`reference/` files (four small doc-only gaps found and closed +earlier: memory usage guidance, the agent-schema wire-contract reference, +naming the crash-recovery pattern, and documenting the automatic +SSE-fallback behavior). The core/operations guide split is new short landing +pages that link into JS's existing deep content (root `README.md` sections, +`docs/api-reference/*.md`, `METRICS.md`, `LEASE_EXTENSION.md`) rather than +newly-authored deep reference material — the same relationship Python's own +thin guides have to its deeper `WORKFLOW.md`/`WORKER.md`/`TASK_MANAGEMENT.md` +pages. + +| Java documentation capability | Python counterpart | JS current counterpart | Status | +|---|---|---|---| +| Server, connection, quickstart, workflows, workers, lifecycle, testing, message queue | [Core guides](https://github.com/conductor-oss/python-sdk/blob/main/docs/README.md#build) | [Core guides](README.md#start-here) — `server-setup.md`, `connection-authentication.md`, `core-quickstart.md`, `workflows.md`, `workflow-lifecycle.md`, `workers.md`, `workflow-testing.md`, `workflow-message-queue.md` | Matches Java/Python structurally. `workflow-testing.md` is a short landing page pointing at the runnable example, not a deep reference on Python's `WORKFLOW_TESTING.md` scale (999 lines) — same category as the operations-guide gap below | +| Schema client, schedules/events, reliability, security, deployment, observability, debugging | Operations guides | [Operations guides](README.md#operate) — `schema-client.md`, `schedules-events.md`, `reliability.md`, `security.md`, `deployment-scaling.md`, `observability.md`, `debugging.md` | Matches Java/Python structurally. `schema-client.md`/`security.md` are honest landing pages — `SchemaClient`/`SecretClient`/`AuthorizationClient`/`IntegrationClient` don't have dedicated API reference pages yet (see JS-only-by-design pages below); that's separate content-authoring work, not a structural gap | +| Agent concepts, runtime, API/client, definition contract | `docs/agents/{README,concepts/*,reference/*}` | `docs/agents/{README,getting-started,concepts/*,reference/*}` — same structure, content-checked topic by topic | Matches Java/Python. Old flat `advanced.md`/`api-reference.md`/`framework-agents.md`/`writing-agents.md` kept as redirect stubs (same pattern Python itself uses for its own superseded pages) | +| Framework bridges: Google ADK, LangChain4j, LangGraph4j (Java) / Google ADK, LangChain, LangGraph, OpenAI Agents, Claude Agent SDK (Python) | `agents/frameworks/*.md`, one file per bridge | `docs/agents/frameworks/{google-adk,langchain,langgraph,openai,vercel-ai}.md` | JS supports Google ADK, OpenAI Agents SDK, LangChain, and LangGraph — the same set Python has via detection — plus **Vercel AI** (JS/Node-ecosystem-specific, no Java/Python counterpart). The one real gap: no bridge for a native `@anthropic-ai/claude-agent-sdk` object (Python's `claude-agent-sdk.md`); JS instead has a differently-shaped `ClaudeCode(modelName?, permissionMode?)` model-string passthrough (see [API map](agents/reference/api.md#other-exports)), not an object-detection bridge, so it isn't a like-for-like substitute | +| Workflow-scoped `FileClient` | Not currently exposed as a public Python client | Also not currently exposed | Matches Python; not a JS-specific gap | +| Spring / Spring Boot integration | Not applicable (Java-specific) | Not applicable (Node ecosystem) | Matches Python; not applicable | + +## Python's legacy deep-reference docs + +Python's short landing pages mostly link into large, pre-existing legacy +reference docs rather than being deep content themselves. Every one of those +legacy docs maps to an existing or gap-tracked JS page — none are +unaccounted for: + +| Python legacy doc | JS equivalent | +|---|---| +| `WORKER.md` | [README's Workers section](../README.md#workers) + [task-manager.md](api-reference/task-manager.md) | +| `WORKFLOW.md` | [workflow-executor.md](api-reference/workflow-executor.md) + [task-generators.md](api-reference/task-generators.md) | +| `TASK_MANAGEMENT.md` | [task-client.md](api-reference/task-client.md) + [task-manager.md](api-reference/task-manager.md) | +| `SCHEDULE.md` | [scheduler-client.md](api-reference/scheduler-client.md) | +| `METADATA.md` | [metadata-client.md](api-reference/metadata-client.md) | +| `LEASE_EXTENSION.md` | Same file, kept at JS's existing root path: [`LEASE_EXTENSION.md`](../LEASE_EXTENSION.md) | +| `workflow-message-queue.md` | [workflow-message-queue.md](workflow-message-queue.md) + [agents/concepts/tools.md](agents/concepts/tools.md#waitformessagetool--workflow-message-queue) | +| `SECRET_MANAGEMENT.md` | No dedicated reference page yet — `SecretClient` gap, see [security.md](security.md) | +| `AUTHORIZATION.md` | No dedicated reference page yet — `AuthorizationClient` gap, see [security.md](security.md) | +| `INTEGRATION.md` | No dedicated reference page yet — `IntegrationClient` gap, see [security.md](security.md) | +| `PROMPT.md` | No dedicated reference page yet — `PromptClient` gap | +| `WORKFLOW_TESTING.md` | `workflow-testing.md` landing page only — no deep reference yet, same gap category as the four rows above | + +## Python-only internal design docs + +`docs/design/{AGENT_SDK_PORTING_SPEC,event_driven_interceptor_system, +lease-extension,WORKER_DESIGN,WORKER_SDK_IMPLEMENTATION_GUIDE}.md` are +Python's own internal design/porting-spec records — maintainer-facing +history of how Python's SDK was built, not user-facing capability docs. JS +has the same kind of internal record in `docs/design/api_client.md` and +`docs/superpowers/**`. Neither side's internal design docs are meant to be +ported cross-SDK; they aren't tracked as gaps. + +## JS-only-by-design pages + +These exist only in the JS SDK and are intentional, not gaps against +Java/Python: + +- `docs/api-reference/*.md` (11 files) — one reference page per client + (`application-client.md`, `task-client.md`, `workflow-executor.md`, ...); + JS's own reference-doc convention, predates this alignment effort. Five + clients that exist in source (`AuthorizationClient`, `IntegrationClient`, + `PromptClient`, `SchemaClient`, `SecretClient`) still have no reference + page — `schema-client.md`/`security.md` link to their API-journey example + scripts in the meantime. Authoring the five missing pages is content work, + tracked separately from this alignment pass. +- `docs/design/api_client.md` — internal design rationale for the generated + API client layer +- `docs/superpowers/**` — maintainer-facing plans/specs, not user docs +- Root comparison/dev docs: `API_CLIENT_COMPARISON.md`, `SDK_COMPARISON.md`, + `SDK_DEVELOPMENT.md`, `SDK_NEW_LANGUAGE_GUIDE.md`, + `WORKER_ARCHITECTURE_COMPARISON.md`, `WORKFLOW_BUILDER_COMPARISON.md`, + `BREAKING_CHANGES.md`, `DECISIONS.md`, `METRICS.md`, `OPEN-API-README.md`, + `REVIEW.md` — contributor-facing, predate the Java/Python doc architecture + +## Maintenance rule + +When JS gains a page or bridge from the tables above, update this map (and +[docs/README.md](README.md)) in the same change. Do not claim a Java/Python +guide, reference page, or framework bridge exists in JS before it actually +ships. diff --git a/docs/documentation-standard.md b/docs/documentation-standard.md new file mode 100644 index 00000000..5296e5e7 --- /dev/null +++ b/docs/documentation-standard.md @@ -0,0 +1,11 @@ +# Documentation standard + +Every primary guide must include its audience and prerequisites, an OSS/Orkes +capability label when behavior differs, and a security note when it handles +credentials, user data, tools, or external side effects. + +Commands must be runnable against a real example in the repository (or +explicitly marked as illustrative). State the expected result, common +failure modes, and next steps. Use `@io-orkes/conductor-javascript` and +published npm versions rather than local-only paths. CI validates internal +Markdown links (`lychee`) and a legacy-branding grep guard. diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 00000000..0e87806b --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,18 @@ +# Recommended examples + +The [examples catalog](../examples/README.md) is broad; start with these +maintained paths and review their side effects before using real +credentials. + +| Path | Use | Expected result | +|---|---|---| +| [quickstart.ts](../examples/quickstart.ts) | Core workflow and worker | Prints a completed workflow result. | +| [workers-e2e.ts](../examples/workers-e2e.ts) | End-to-end: 3 chained workers with verification | Prints the verified chain output. | +| [kitchensink.ts](../examples/kitchensink.ts) | All major task types in one workflow | Prints the completed workflow output. | +| [workflow-ops.ts](../examples/workflow-ops.ts) | Lifecycle: pause, resume, terminate, retry, search | Prints each operation's result. | +| [test-workflows.ts](../examples/test-workflows.ts) | Unit testing with mock outputs (no workers) | Prints the simulated status/output. | +| [agents/01-basic-agent.ts](../examples/agents/01-basic-agent.ts) | First Conductor agent | Prints an `AgentResult`. | + +Stop local servers and worker processes after experimenting. Provider +credentials must be configured on the Conductor server, not the client — see +[security](security.md). diff --git a/docs/observability.md b/docs/observability.md new file mode 100644 index 00000000..429d3163 --- /dev/null +++ b/docs/observability.md @@ -0,0 +1,25 @@ +# Metrics and logging + +Enable Prometheus metrics with the built-in collector and configure log +verbosity with `CONDUCTOR_LOG_LEVEL`: + +```typescript +import { createMetricsCollector, MetricsServer, TaskHandler } from "@io-orkes/conductor-javascript"; + +const metrics = createMetricsCollector(); +await new MetricsServer(metrics, 9090).start(); + +const handler = new TaskHandler({ client, eventListeners: [metrics], scanForDecorated: true }); +await handler.startWorkers(); +// GET http://localhost:9090/metrics — Prometheus text format +``` + +Two metric surfaces exist: **legacy** (default) and **canonical** (opt-in via +`WORKER_CANONICAL_METRICS=true`, unprefixed Histogram-based names, bounded +`uri` labels). See [METRICS.md](../METRICS.md) for the full catalog and +migration guide. + +For agent executions, inspect the shared workflow record +([agents/reference/client.md](agents/reference/client.md)) for inputs, +outputs, tool calls, retries, and status. Avoid logging credentials or +unredacted sensitive data. diff --git a/docs/reliability.md b/docs/reliability.md new file mode 100644 index 00000000..185dcc07 --- /dev/null +++ b/docs/reliability.md @@ -0,0 +1,28 @@ +# Reliability: timeouts, retries, idempotency, and domains + +Set poll, response, and execution timeouts on every task definition. Retry +only idempotent or compensated work; use `domain` to route resource-bound +work to isolated worker pools. + +```typescript +@worker({ taskDefName: "validate_order" }) +async function validateOrder(task: Task) { + const order = await getOrder(task.inputData.orderId); + if (!order) { + throw new NonRetryableException("Order not found"); // FAILED_WITH_TERMINAL_ERROR + } + return { status: "COMPLETED" as const, outputData: { validated: true } }; +} +``` + +A worker may receive the same task more than once. Persist idempotency keys +before external side effects. Long-running tasks should return `IN_PROGRESS` +with `setCallbackAfter`/lease extension (see +[LEASE_EXTENSION.md](../LEASE_EXTENSION.md)) rather than blocking the poll +loop. `retryServerErrors`/`CONDUCTOR_RETRY_SERVER_ERRORS` opts idempotent +HTTP methods into retrying transient 502/503/504 responses from the server +itself. + +Verify behavior with failure-path tests +([workflow testing](workflow-testing.md)) and inspect task +`reasonForIncompletion` before retrying — see [debugging](debugging.md). diff --git a/docs/schedules-events.md b/docs/schedules-events.md new file mode 100644 index 00000000..be4fc006 --- /dev/null +++ b/docs/schedules-events.md @@ -0,0 +1,19 @@ +# Schedules and events + +Use `SchedulerClient` for workflow schedules and `EventClient` for +event-driven integration. Give scheduled executions a stable correlation or +idempotency key so retries do not duplicate business effects. + +```typescript +const scheduler = clients.getSchedulerClient(); +await scheduler.saveSchedule({ name: "nightly-report", cronExpression: "0 0 2 * * *", startWorkflowRequest: { name: "report_flow" } }); +``` + +`pauseSchedule`/`resumeSchedule` issue PUT first and fall back to GET on +HTTP 405, so the same call works against both OSS/embedded (PUT-only) and +Orkes Cloud (GET-only) servers. + +See [scheduler-client.md](api-reference/scheduler-client.md) and +[event-client.md](api-reference/event-client.md) for the complete request +models, and [workflow lifecycle](workflow-lifecycle.md) for safe operational +handling of the workflows a schedule triggers. diff --git a/docs/schema-client.md b/docs/schema-client.md new file mode 100644 index 00000000..1d4b9e13 --- /dev/null +++ b/docs/schema-client.md @@ -0,0 +1,19 @@ +# Schema client + +`SchemaClient` (`OrkesClients.getSchemaClient()`) manages versioned schema +definitions through the Conductor schema API — `registerSchema`, `getSchema`, +`getAllSchemas`, `deleteSchema`. + +```typescript +const schemas = clients.getSchemaClient(); +await schemas.registerSchema([{ name: "order", type: "JSON", version: 1, data: {} }]); +``` + +**OSS/Orkes:** availability depends on the server deployment and +permissions. Validate schemas in a non-production environment before making +them required by workers or tasks. + +There is no dedicated `schema-client.md` API reference page yet (tracked in +[documentation-parity.md](documentation-parity.md#js-only-by-design-pages)); +see the [schemas API journey example](../examples/api-journeys/schemas.ts) +for a runnable walkthrough of every method in the meantime. diff --git a/docs/security.md b/docs/security.md new file mode 100644 index 00000000..3c190f7b --- /dev/null +++ b/docs/security.md @@ -0,0 +1,19 @@ +# Security and secrets + +Keep API keys, provider credentials, and signing secrets in the Conductor +server or its configured secret provider (`SecretClient`, +`AuthorizationClient`, `IntegrationClient`). Do not put them in workflow +input, agent prompts, task output, example source, or version control. + +Agent tools declare required credentials via `credentials: [...]`; a capable +server delivers resolved values only in the polled task's `runtimeMetadata`, +fail-closed — a tool whose declared credential wasn't delivered fails +non-retryably naming the missing credential, with no ambient-env fallback. +See [agent tools](agents/reference/api.md#credentials-and-secrets). + +There is no dedicated `security.md`/`secret-client.md` API reference page +yet (tracked in +[documentation-parity.md](documentation-parity.md#js-only-by-design-pages)); +see the [secrets](../examples/api-journeys/secrets.ts) and +[authorization](../examples/api-journeys/authorization.ts) API journey +examples for a runnable walkthrough in the meantime. diff --git a/docs/server-setup.md b/docs/server-setup.md new file mode 100644 index 00000000..b9636f63 --- /dev/null +++ b/docs/server-setup.md @@ -0,0 +1,39 @@ +# Connect the JS/TS SDK to a Conductor server + +**Audience:** developers running workflows, workers, or Conductor agents locally +or against a hosted cluster. **Prerequisites:** Node.js >= 18. + +## Local development + +Pick one: + +```shell +docker run -p 8080:8080 conductoross/conductor:latest +``` + +```shell +curl -sSL https://raw.githubusercontent.com/conductor-oss/conductor/main/conductor_server.sh | sh +``` + +```shell +npm install -g @conductor-oss/conductor-cli +conductor server start +``` + +The Docker image also serves the UI at `http://localhost:8080`; the API is at +`http://localhost:8080/api`. + +## Hosted / Orkes Cloud + +Set the API URL (including `/api`) and credentials: + +```shell +export CONDUCTOR_SERVER_URL="https://your-cluster.orkesconductor.io/api" +export CONDUCTOR_AUTH_KEY="your-key" +export CONDUCTOR_AUTH_SECRET="your-secret" +``` + +For agent runs, configure the LLM provider credential on the server before +starting it — see [security](security.md). + +Continue with [connection/authentication](connection-authentication.md). diff --git a/docs/upgrading.md b/docs/upgrading.md new file mode 100644 index 00000000..f7d83fa2 --- /dev/null +++ b/docs/upgrading.md @@ -0,0 +1,14 @@ +# Upgrade the JS/TS SDK safely + +Before upgrading, read [CHANGELOG.md](../CHANGELOG.md) and +[BREAKING_CHANGES.md](../BREAKING_CHANGES.md), test against the target +Conductor server, and pin the new package version in a staging environment. +Run unit tests and one representative workflow and agent execution before +production rollout. + +Configuration env vars are `CONDUCTOR_*`/`CONDUCTOR_AGENT_*`-prefixed with no +legacy alias — this is a clean break, not a compatibility shim, so renaming +an old env var name is required, not optional, when upgrading across a major +that changed it (see `CHANGELOG.md`'s `[Unreleased]` entries for the current +set). Roll back by restoring the prior package lock and keeping workflow +definitions versioned rather than changing active behavior in place. diff --git a/docs/workers.md b/docs/workers.md new file mode 100644 index 00000000..d29d5314 --- /dev/null +++ b/docs/workers.md @@ -0,0 +1,30 @@ +# Workers + +Workers are TypeScript functions that poll a named task queue, execute +idempotent business logic, and return a result. Decorate a function (or class +method) with `@worker` and run it with `TaskHandler`. + +```typescript +import { worker, TaskHandler } from "@io-orkes/conductor-javascript"; +import type { Task } from "@io-orkes/conductor-javascript"; + +@worker({ taskDefName: "greet", concurrency: 5 }) +async function greet(task: Task) { + return { status: "COMPLETED" as const, outputData: { result: `Hello ${task.inputData.name}` } }; +} + +const handler = new TaskHandler({ client, scanForDecorated: true }); +await handler.startWorkers(); +``` + +Throw `NonRetryableException` for terminal failures (`FAILED_WITH_TERMINAL_ERROR`); +a plain `Error` retries. Use `domain` for multi-tenant task isolation and +`CONDUCTOR_WORKER_*`/`CONDUCTOR_WORKER__*` env vars to tune polling +without code changes. Stop task handlers (`handler.stopWorkers()`) on process +shutdown so in-flight tasks are redelivered instead of abandoned. + +See the root [README's Workers section](../README.md#workers) for both +decorator styles, `TaskContext` for long-running tasks, and event listeners; +[task-manager.md](api-reference/task-manager.md) and +[task-client.md](api-reference/task-client.md) for the full client API. Next: +[reliability](reliability.md) and [workflow testing](workflow-testing.md). diff --git a/docs/workflow-lifecycle.md b/docs/workflow-lifecycle.md new file mode 100644 index 00000000..2b115008 --- /dev/null +++ b/docs/workflow-lifecycle.md @@ -0,0 +1,28 @@ +# Workflow lifecycle and versioning + +Register a versioned workflow, start it through `WorkflowExecutor`, and +inspect its execution before changing behavior. Additive output changes are +normally safe; renamed inputs, removed outputs, and changed task references +are breaking and require a new workflow version. + +```typescript +const workflowId = await executor.startWorkflow({ name: "order_flow", input: { orderId: "ORDER-123" } }); + +await executor.pause(workflowId); +await executor.resume(workflowId); +await executor.retry(workflowId); +await executor.terminate(workflowId, "cancelled by user"); +await executor.restart(workflowId); +await executor.signal(workflowId, TaskResultStatusEnum.COMPLETED, { approved: true }); + +const results = await executor.search("workflowType = 'order_flow' AND status = 'RUNNING'"); +``` + +Use pause/resume for controlled maintenance, retry only transient failures, +and terminate executions with an explicit reason. Inspect failed tasks +(`getTask`/`search` — [task-client.md](api-reference/task-client.md)) before +retrying to avoid replaying unsafe side effects. + +See [workflow-executor.md](api-reference/workflow-executor.md) for the +complete lifecycle API and [workflow-ops.ts](../examples/workflow-ops.ts) for +a runnable example covering all operations above. diff --git a/docs/workflow-message-queue.md b/docs/workflow-message-queue.md new file mode 100644 index 00000000..243cbe44 --- /dev/null +++ b/docs/workflow-message-queue.md @@ -0,0 +1,44 @@ +# Workflow message queue (WMQ) + +Consume messages pushed into a running workflow's queue using the +`PULL_WORKFLOW_MESSAGES` system task. + +## Server requirement + +WMQ must be enabled on the Conductor server: + +```properties +conductor.workflow-message-queue.enabled=true +``` + +## Consuming in a plain workflow + +```typescript +import { pullWorkflowMessages, ConductorWorkflow } from "@io-orkes/conductor-javascript"; + +const pull = pullWorkflowMessages("pull_ref", 5 /* batchSize */); + +const workflow = new ConductorWorkflow(executor, "order_processing").add(pull); +``` + +The task completes with `output.messages` (a list) and `output.count` when +messages are available; while the queue is empty it stays `IN_PROGRESS` and +is re-evaluated roughly every second. See +[pullWorkflowMessages.ts](../src/sdk/builders/tasks/pullWorkflowMessages.ts) +and [task-generators.md](api-reference/task-generators.md#pull-workflow-messages-task) +for the full builder signature. + +## Consuming in an agent + +Agents dequeue from the same queue with `waitForMessageTool` instead of a +task builder — see +[agents/concepts/tools.md](agents/concepts/tools.md#waitformessagetool--workflow-message-queue). + +## Pushing a message + +Python's SDK exposes a `send_message`/`WorkflowClient.send_message` helper +that calls `POST /workflow/{workflowId}/messages`. That operation is not yet +in the JS SDK's generated client — there is currently no supported way to +push a message into a workflow's queue from JS. Track this as an open gap +rather than assuming a `sendMessage` method exists on any client; none does +today. diff --git a/docs/workflow-testing.md b/docs/workflow-testing.md new file mode 100644 index 00000000..7db6b1e0 --- /dev/null +++ b/docs/workflow-testing.md @@ -0,0 +1,19 @@ +# Workflow testing + +`WorkflowExecutor.testWorkflow()` evaluates a workflow definition against +Conductor's `POST /api/workflow/test` endpoint with controlled, mocked task +outputs — no live workers required. Cover successful paths, retryable and +terminal failures, branching, timeouts, and workflow outputs. + +```shell +npx ts-node examples/test-workflows.ts +``` + +Expected result: the script prints the simulated workflow's status and +output for each scenario without executing any real worker code. Do not run +examples with production credentials unless their external side effects have +been reviewed. + +See [test-workflows.ts](../examples/test-workflows.ts) for the runnable +example and [workflow-executor.md](api-reference/workflow-executor.md) for +`testWorkflow()`'s full signature. diff --git a/docs/workflows.md b/docs/workflows.md new file mode 100644 index 00000000..9dfac0db --- /dev/null +++ b/docs/workflows.md @@ -0,0 +1,26 @@ +# Workflows + +Use `ConductorWorkflow` to build a workflow definition from typed task +builders, then register it and run it through `WorkflowExecutor`. + +```typescript +import { ConductorWorkflow, simpleTask } from "@io-orkes/conductor-javascript"; + +const workflow = new ConductorWorkflow(executor, "greetings") + .add(simpleTask("greet_ref", "greet", { name: "${workflow.input.name}" })) + .outputParameters({ result: "${greet_ref.output.result}" }); + +await workflow.register(); +const run = await workflow.execute({ name: "Conductor" }); +``` + +Typed builders exist for HTTP calls, wait, switch/branching, fork-join, +do-while, sub-workflows, and event tasks — see +[task-generators.md](api-reference/task-generators.md) and the root +[README's "What You Can Build"](../README.md#what-you-can-build) section for +runnable snippets of each. Keep versioned definitions compatible with +callers; never place secrets in workflow input. + +See [workflow-executor.md](api-reference/workflow-executor.md) for the full +registration/execution API and [workflow lifecycle](workflow-lifecycle.md) +for pause/resume/retry/terminate. diff --git a/e2e/helpers.ts b/e2e/helpers.ts index c4a48857..e9938b7e 100644 --- a/e2e/helpers.ts +++ b/e2e/helpers.ts @@ -37,10 +37,9 @@ export function expectMsg(actual: unknown, message?: string): ReturnType; } -const SERVER_URL = process.env.AGENTSPAN_SERVER_URL ?? 'http://localhost:8080/api'; +const SERVER_URL = process.env.CONDUCTOR_SERVER_URL ?? 'http://localhost:8080/api'; const BASE_URL = SERVER_URL.replace(/\/api$/, ''); -export const MODEL = process.env.AGENTSPAN_LLM_MODEL ?? 'openai/gpt-4o-mini'; -export const CLI_PATH = process.env.AGENTSPAN_CLI_PATH ?? 'agentspan'; +export const MODEL = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'openai/gpt-4o-mini'; export const MCP_TESTKIT_URL = process.env.MCP_TESTKIT_URL ?? 'http://localhost:3001'; export const TIMEOUT = 300_000; // 5 min per run — CI runners are slower diff --git a/e2e/test_suite11_langgraph.test.ts b/e2e/test_suite11_langgraph.test.ts index 96537968..c906c554 100644 --- a/e2e/test_suite11_langgraph.test.ts +++ b/e2e/test_suite11_langgraph.test.ts @@ -40,7 +40,7 @@ let z: any; let serializeLangGraph: any; let detectFramework: any; -const SERVER_URL = process.env.AGENTSPAN_SERVER_URL ?? 'http://localhost:8080/api'; +const SERVER_URL = process.env.CONDUCTOR_SERVER_URL ?? 'http://localhost:8080/api'; const BASE_URL = SERVER_URL.replace(/\/api$/, ''); try { diff --git a/e2e/test_suite1_basic_validation.test.ts b/e2e/test_suite1_basic_validation.test.ts index e90a5d5a..4f5afbaa 100644 --- a/e2e/test_suite1_basic_validation.test.ts +++ b/e2e/test_suite1_basic_validation.test.ts @@ -296,7 +296,7 @@ function makeKitchenSinkAgent() { // ── LLM Judge ─────────────────────────────────────────────────────────── -const JUDGE_MODEL = process.env.AGENTSPAN_JUDGE_MODEL ?? 'claude-sonnet-4-20250514'; +const JUDGE_MODEL = process.env.CONDUCTOR_AGENT_JUDGE_MODEL ?? 'claude-sonnet-4-20250514'; const JUDGE_SYSTEM_PROMPT = `You are a strict validation judge for a workflow compilation system. diff --git a/e2e/test_suite20_plan_execute.test.ts b/e2e/test_suite20_plan_execute.test.ts index 78bd57ff..f17ba0af 100644 --- a/e2e/test_suite20_plan_execute.test.ts +++ b/e2e/test_suite20_plan_execute.test.ts @@ -600,7 +600,7 @@ describe('Suite 20: Plan-Execute Refs (deterministic)', () => { } async function fetchStepOutputs(executionId: string): Promise> { - const base = (process.env.AGENTSPAN_SERVER_URL ?? 'http://localhost:8080/api') + const base = (process.env.CONDUCTOR_SERVER_URL ?? 'http://localhost:8080/api') .replace(/\/api$/, '') .replace(/\/$/, ''); const parent = (await (await fetch(`${base}/api/workflow/${executionId}?includeTasks=true`)).json()) as { diff --git a/e2e/test_suite21_scheduling.test.ts b/e2e/test_suite21_scheduling.test.ts index a69554a4..c229e7b6 100644 --- a/e2e/test_suite21_scheduling.test.ts +++ b/e2e/test_suite21_scheduling.test.ts @@ -17,7 +17,7 @@ import { } from '@io-orkes/conductor-javascript/agents'; import { expectMsg } from './helpers'; -const SERVER_URL = process.env.AGENTSPAN_SERVER_URL ?? 'http://localhost:8080/api'; +const SERVER_URL = process.env.CONDUCTOR_SERVER_URL ?? 'http://localhost:8080/api'; async function schedulerAvailable(): Promise { try { diff --git a/e2e/test_suite23_agent_client.test.ts b/e2e/test_suite23_agent_client.test.ts index 445e8a50..1640df73 100644 --- a/e2e/test_suite23_agent_client.test.ts +++ b/e2e/test_suite23_agent_client.test.ts @@ -26,7 +26,7 @@ describe('Suite 23: AgentClient / WorkflowClient', () => { // hard when the server is down (the CI workflow health-gates before tests). beforeAll(async () => { if (!(await checkServerHealth())) { - throw new Error('agentspan server is not healthy — these e2e suites need a running server'); + throw new Error('conductor server is not healthy — these e2e suites need a running server'); } }); const client = new OrkesAgentClient(); diff --git a/e2e/tools/_worker-harness.ts b/e2e/tools/_worker-harness.ts index 688341ac..d32a1913 100644 --- a/e2e/tools/_worker-harness.ts +++ b/e2e/tools/_worker-harness.ts @@ -154,7 +154,7 @@ console.log = () => {}; console.warn = () => {}; // Set env vars so AgentRuntime constructor doesn't fail -process.env.AGENTSPAN_SERVER_URL ??= "http://localhost:8080/api"; +process.env.CONDUCTOR_SERVER_URL ??= "http://localhost:8080/api"; process.env.OPENAI_API_KEY ??= "sk-fake"; process.env.ANTHROPIC_API_KEY ??= "sk-fake"; process.env.GOOGLE_API_KEY ??= "fake"; diff --git a/examples/agents/01-basic-agent.ts b/examples/agents/01-basic-agent.ts index d3b6d555..b5ac7c54 100644 --- a/examples/agents/01-basic-agent.ts +++ b/examples/agents/01-basic-agent.ts @@ -5,9 +5,9 @@ * `runtime.run()`, and print the result. * * Requirements: - * - Agentspan server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL set as environment variable (optional) + * - Conductor server with LLM support + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL set as environment variable (optional) */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/02-tools.ts b/examples/agents/02-tools.ts index cdee5e0d..3f1e11a6 100644 --- a/examples/agents/02-tools.ts +++ b/examples/agents/02-tools.ts @@ -8,8 +8,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import * as readline from 'node:readline/promises'; diff --git a/examples/agents/02a-simple-tools.ts b/examples/agents/02a-simple-tools.ts index 5d10b1ea..fa2b3366 100644 --- a/examples/agents/02a-simple-tools.ts +++ b/examples/agents/02a-simple-tools.ts @@ -9,8 +9,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/02b-multi-step-tools.ts b/examples/agents/02b-multi-step-tools.ts index fbfdf807..c303764e 100644 --- a/examples/agents/02b-multi-step-tools.ts +++ b/examples/agents/02b-multi-step-tools.ts @@ -16,8 +16,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/03-multi-agent.ts b/examples/agents/03-multi-agent.ts index 03bead06..9f1c819e 100644 --- a/examples/agents/03-multi-agent.ts +++ b/examples/agents/03-multi-agent.ts @@ -13,7 +13,7 @@ import { OnTextMention, } from '@io-orkes/conductor-javascript/agents'; -const MODEL = process.env.AGENTSPAN_LLM_MODEL ?? 'openai/gpt-4o'; +const MODEL = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'openai/gpt-4o'; // ── Sequential: writer -> editor ───────────────────────── diff --git a/examples/agents/03-structured-output.ts b/examples/agents/03-structured-output.ts index eb5ec025..611b14a7 100644 --- a/examples/agents/03-structured-output.ts +++ b/examples/agents/03-structured-output.ts @@ -6,8 +6,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/04-guardrails.ts b/examples/agents/04-guardrails.ts index cafbb7b2..566239b6 100644 --- a/examples/agents/04-guardrails.ts +++ b/examples/agents/04-guardrails.ts @@ -16,7 +16,7 @@ import { } from '@io-orkes/conductor-javascript/agents'; import type { GuardrailResult } from '@io-orkes/conductor-javascript/agents'; -const MODEL = process.env.AGENTSPAN_LLM_MODEL ?? 'openai/gpt-4o'; +const MODEL = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'openai/gpt-4o'; // -- RegexGuardrail: block PII patterns -- const piiBlocker = new RegexGuardrail({ diff --git a/examples/agents/04-http-and-mcp-tools.ts b/examples/agents/04-http-and-mcp-tools.ts index 5ee158d9..fd87d410 100644 --- a/examples/agents/04-http-and-mcp-tools.ts +++ b/examples/agents/04-http-and-mcp-tools.ts @@ -24,8 +24,8 @@ * Requirements: * - Conductor server with LLM support * - mcp-testkit running on http://localhost:3001 (see setup above) - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool, httpTool, mcpTool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/04-mcp-weather.ts b/examples/agents/04-mcp-weather.ts index 17650bb5..c236da5b 100644 --- a/examples/agents/04-mcp-weather.ts +++ b/examples/agents/04-mcp-weather.ts @@ -24,8 +24,8 @@ * Requirements: * - Conductor server with LLM support * - mcp-testkit running on http://localhost:3001 (see setup above) - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, mcpTool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/05-handoffs.ts b/examples/agents/05-handoffs.ts index 2687a2d0..7911844e 100644 --- a/examples/agents/05-handoffs.ts +++ b/examples/agents/05-handoffs.ts @@ -6,8 +6,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/05-streaming.ts b/examples/agents/05-streaming.ts index f7a2b434..66b0b89c 100644 --- a/examples/agents/05-streaming.ts +++ b/examples/agents/05-streaming.ts @@ -11,7 +11,7 @@ import { EventTypes, } from '@io-orkes/conductor-javascript/agents'; -const MODEL = process.env.AGENTSPAN_LLM_MODEL ?? 'openai/gpt-4o'; +const MODEL = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'openai/gpt-4o'; export const agent = new Agent({ name: 'streaming_agent', diff --git a/examples/agents/06-hitl.ts b/examples/agents/06-hitl.ts index a3982a3a..9a89757c 100644 --- a/examples/agents/06-hitl.ts +++ b/examples/agents/06-hitl.ts @@ -13,7 +13,7 @@ import { tool, } from '@io-orkes/conductor-javascript/agents'; -const MODEL = process.env.AGENTSPAN_LLM_MODEL ?? 'openai/gpt-4o'; +const MODEL = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'openai/gpt-4o'; // -- Tool that requires human approval -- const publishArticle = tool( diff --git a/examples/agents/06-sequential-pipeline.ts b/examples/agents/06-sequential-pipeline.ts index bf7a9b0f..da3850f7 100644 --- a/examples/agents/06-sequential-pipeline.ts +++ b/examples/agents/06-sequential-pipeline.ts @@ -8,8 +8,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/07-memory.ts b/examples/agents/07-memory.ts index 2cdbb01a..84876af2 100644 --- a/examples/agents/07-memory.ts +++ b/examples/agents/07-memory.ts @@ -14,7 +14,7 @@ import { tool, } from '@io-orkes/conductor-javascript/agents'; -const MODEL = process.env.AGENTSPAN_LLM_MODEL ?? 'openai/gpt-4o'; +const MODEL = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'openai/gpt-4o'; // ── ConversationMemory ────────────────────────────────── diff --git a/examples/agents/07-parallel-agents.ts b/examples/agents/07-parallel-agents.ts index cd373317..7d8295e6 100644 --- a/examples/agents/07-parallel-agents.ts +++ b/examples/agents/07-parallel-agents.ts @@ -6,8 +6,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/08-credentials.ts b/examples/agents/08-credentials.ts index f4a82a80..15dbf01e 100644 --- a/examples/agents/08-credentials.ts +++ b/examples/agents/08-credentials.ts @@ -15,7 +15,7 @@ import { } from '@io-orkes/conductor-javascript/agents'; import type { ToolContext } from '@io-orkes/conductor-javascript/agents'; -const MODEL = process.env.AGENTSPAN_LLM_MODEL ?? 'openai/gpt-4o'; +const MODEL = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'openai/gpt-4o'; // -- Tool that declares a credential and reads it at runtime -- const dbLookup = tool( diff --git a/examples/agents/08-router-agent.ts b/examples/agents/08-router-agent.ts index 869bc5ca..408e4ac6 100644 --- a/examples/agents/08-router-agent.ts +++ b/examples/agents/08-router-agent.ts @@ -6,8 +6,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/09-human-in-the-loop.ts b/examples/agents/09-human-in-the-loop.ts index ca4882bb..4c303bed 100644 --- a/examples/agents/09-human-in-the-loop.ts +++ b/examples/agents/09-human-in-the-loop.ts @@ -8,8 +8,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import * as readline from 'node:readline/promises'; diff --git a/examples/agents/09-structured-output.ts b/examples/agents/09-structured-output.ts index 8bcb1be3..e133688b 100644 --- a/examples/agents/09-structured-output.ts +++ b/examples/agents/09-structured-output.ts @@ -7,7 +7,7 @@ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const MODEL = process.env.AGENTSPAN_LLM_MODEL ?? 'openai/gpt-4o'; +const MODEL = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'openai/gpt-4o'; // -- Define a Zod schema for the expected output -- const ArticleAnalysis = { diff --git a/examples/agents/09b-hitl-with-feedback.ts b/examples/agents/09b-hitl-with-feedback.ts index 4cf50ce3..05eb7fef 100644 --- a/examples/agents/09b-hitl-with-feedback.ts +++ b/examples/agents/09b-hitl-with-feedback.ts @@ -11,8 +11,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import * as readline from 'node:readline/promises'; diff --git a/examples/agents/09c-hitl-streaming.ts b/examples/agents/09c-hitl-streaming.ts index 78b6127b..366c1e30 100644 --- a/examples/agents/09c-hitl-streaming.ts +++ b/examples/agents/09c-hitl-streaming.ts @@ -11,8 +11,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import * as readline from 'node:readline/promises'; diff --git a/examples/agents/09d-human-tool.ts b/examples/agents/09d-human-tool.ts index faf7e23c..0fedd23c 100644 --- a/examples/agents/09d-human-tool.ts +++ b/examples/agents/09d-human-tool.ts @@ -16,8 +16,8 @@ * - The LLM using human input to make decisions * * Requirements: - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api - * - AGENTSPAN_LLM_MODEL (default: openai/gpt-4o-mini) + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api + * - CONDUCTOR_AGENT_LLM_MODEL (default: openai/gpt-4o-mini) */ import * as readline from 'node:readline/promises'; diff --git a/examples/agents/10-code-execution.ts b/examples/agents/10-code-execution.ts index 999d5dd1..511a684f 100644 --- a/examples/agents/10-code-execution.ts +++ b/examples/agents/10-code-execution.ts @@ -11,7 +11,7 @@ import { LocalCodeExecutor, } from '@io-orkes/conductor-javascript/agents'; -const MODEL = process.env.AGENTSPAN_LLM_MODEL ?? 'openai/gpt-4o'; +const MODEL = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'openai/gpt-4o'; // -- Create a local code executor -- const executor = new LocalCodeExecutor({ timeout: 10 }); diff --git a/examples/agents/10-guardrails.ts b/examples/agents/10-guardrails.ts index 010752ce..96903584 100644 --- a/examples/agents/10-guardrails.ts +++ b/examples/agents/10-guardrails.ts @@ -19,8 +19,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { diff --git a/examples/agents/108-plan-execute-refs.ts b/examples/agents/108-plan-execute-refs.ts index ad7f7377..add590c5 100644 --- a/examples/agents/108-plan-execute-refs.ts +++ b/examples/agents/108-plan-execute-refs.ts @@ -19,9 +19,9 @@ * required — because we pass `plan` directly to `runtime.run`. * * Requirements: - * - Agentspan server running on http://localhost:8080 (or - * AGENTSPAN_SERVER_URL) - * - AGENTSPAN_LLM_MODEL set (default: openai/gpt-4o-mini) + * - Conductor server running on http://localhost:8080 (or + * CONDUCTOR_SERVER_URL) + * - CONDUCTOR_AGENT_LLM_MODEL set (default: openai/gpt-4o-mini) * * Run: npx tsx examples/108-plan-execute-refs.ts */ @@ -36,7 +36,7 @@ import { tool, } from "../../src/agents/index.js"; -const MODEL = process.env.AGENTSPAN_LLM_MODEL ?? "openai/gpt-4o-mini"; +const MODEL = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? "openai/gpt-4o-mini"; const produce = tool( async ({ record_id }: { record_id: string }) => ({ @@ -151,7 +151,7 @@ async function main() { } async function showPipelineOutputs(executionId: string) { - const base = (process.env.AGENTSPAN_SERVER_URL ?? "http://localhost:8080/api") + const base = (process.env.CONDUCTOR_SERVER_URL ?? "http://localhost:8080/api") .replace(/\/api$/, "") .replace(/\/$/, ""); const parent = (await (await fetch(`${base}/api/workflow/${executionId}?includeTasks=true`)).json()) as { diff --git a/examples/agents/11-streaming.ts b/examples/agents/11-streaming.ts index 50788a62..8ecf6cdd 100644 --- a/examples/agents/11-streaming.ts +++ b/examples/agents/11-streaming.ts @@ -7,8 +7,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, EventTypes } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/115-plan-execute-planner-context.ts b/examples/agents/115-plan-execute-planner-context.ts index 91740133..3001a60b 100644 --- a/examples/agents/115-plan-execute-planner-context.ts +++ b/examples/agents/115-plan-execute-planner-context.ts @@ -25,9 +25,9 @@ * Mirrors sdk/python/examples/115_plan_execute_planner_context.py. * * Requirements: - * - Agentspan server running on http://localhost:8080 (or - * AGENTSPAN_SERVER_URL) - * - AGENTSPAN_LLM_MODEL set (default: openai/gpt-4o-mini) + * - Conductor server running on http://localhost:8080 (or + * CONDUCTOR_SERVER_URL) + * - CONDUCTOR_AGENT_LLM_MODEL set (default: openai/gpt-4o-mini) * * Run: npx tsx examples/115-plan-execute-planner-context.ts */ @@ -39,7 +39,7 @@ import { tool, } from "../../src/agents/index.js"; -const MODEL = process.env.AGENTSPAN_LLM_MODEL ?? "openai/gpt-4o-mini"; +const MODEL = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? "openai/gpt-4o-mini"; // ── Onboarding tools (deterministic, no external calls) ────────────── @@ -215,7 +215,7 @@ async function main(): Promise { async function showExecutedSteps(executionId: string): Promise { const baseUrl = ( - process.env.AGENTSPAN_SERVER_URL ?? "http://localhost:8080/api" + process.env.CONDUCTOR_SERVER_URL ?? "http://localhost:8080/api" ) .replace(/\/$/, "") .replace(/\/api$/, ""); diff --git a/examples/agents/12-long-running.ts b/examples/agents/12-long-running.ts index aaf19098..7caad671 100644 --- a/examples/agents/12-long-running.ts +++ b/examples/agents/12-long-running.ts @@ -7,8 +7,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/13-hierarchical-agents.ts b/examples/agents/13-hierarchical-agents.ts index 586427e9..46aa0b9f 100644 --- a/examples/agents/13-hierarchical-agents.ts +++ b/examples/agents/13-hierarchical-agents.ts @@ -15,8 +15,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, OnTextMention } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/14-existing-workers.ts b/examples/agents/14-existing-workers.ts index 69b7284b..356ddff2 100644 --- a/examples/agents/14-existing-workers.ts +++ b/examples/agents/14-existing-workers.ts @@ -15,8 +15,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/15-agent-discussion.ts b/examples/agents/15-agent-discussion.ts index 56fa8210..ee969793 100644 --- a/examples/agents/15-agent-discussion.ts +++ b/examples/agents/15-agent-discussion.ts @@ -18,8 +18,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/16-credentials-isolated-tool.ts b/examples/agents/16-credentials-isolated-tool.ts index d88048e0..13d29940 100644 --- a/examples/agents/16-credentials-isolated-tool.ts +++ b/examples/agents/16-credentials-isolated-tool.ts @@ -22,9 +22,9 @@ * agentspan credentials set GITHUB_TOKEN # enter token when prompted * * Requirements: - * - Agentspan server running at AGENTSPAN_SERVER_URL (> 0.4.2, for + * - Conductor server running at CONDUCTOR_SERVER_URL (> 0.4.2, for * runtimeMetadata delivery) or conductor-oss (with PR #1255) - * - AGENTSPAN_LLM_MODEL set (or defaults to openai/gpt-4o-mini) + * - CONDUCTOR_AGENT_LLM_MODEL set (or defaults to openai/gpt-4o-mini) * - GITHUB_TOKEN stored via `agentspan credentials set` */ diff --git a/examples/agents/16-random-strategy.ts b/examples/agents/16-random-strategy.ts index a46812d3..4256ce0b 100644 --- a/examples/agents/16-random-strategy.ts +++ b/examples/agents/16-random-strategy.ts @@ -7,8 +7,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/16b-credentials-non-isolated.ts b/examples/agents/16b-credentials-non-isolated.ts index 3e65bebe..e4e3e1be 100644 --- a/examples/agents/16b-credentials-non-isolated.ts +++ b/examples/agents/16b-credentials-non-isolated.ts @@ -9,8 +9,8 @@ * - CredentialNotFoundError handling for graceful degradation * * Requirements: - * - Agentspan server running at AGENTSPAN_SERVER_URL - * - AGENTSPAN_LLM_MODEL set (or defaults to openai/gpt-4o-mini) + * - Conductor server running at CONDUCTOR_SERVER_URL + * - CONDUCTOR_AGENT_LLM_MODEL set (or defaults to openai/gpt-4o-mini) * - STRIPE_SECRET_KEY stored: agentspan credentials set STRIPE_SECRET_KEY */ diff --git a/examples/agents/16c-credentials-cli-tools.ts b/examples/agents/16c-credentials-cli-tools.ts index 068ac5fb..9bb7f6d7 100644 --- a/examples/agents/16c-credentials-cli-tools.ts +++ b/examples/agents/16c-credentials-cli-tools.ts @@ -14,8 +14,8 @@ * agentspan credentials set AWS_SECRET_ACCESS_KEY * * Requirements: - * - Agentspan server running at AGENTSPAN_SERVER_URL - * - AGENTSPAN_LLM_MODEL set (or defaults to openai/gpt-4o-mini) + * - Conductor server running at CONDUCTOR_SERVER_URL + * - CONDUCTOR_AGENT_LLM_MODEL set (or defaults to openai/gpt-4o-mini) * - gh and aws CLIs installed */ diff --git a/examples/agents/16d-credentials-gh-cli.ts b/examples/agents/16d-credentials-gh-cli.ts index cb461188..19f12967 100644 --- a/examples/agents/16d-credentials-gh-cli.ts +++ b/examples/agents/16d-credentials-gh-cli.ts @@ -11,8 +11,8 @@ * agentspan credentials set GH_TOKEN * * Requirements: - * - Agentspan server running at AGENTSPAN_SERVER_URL - * - AGENTSPAN_LLM_MODEL set (or defaults to openai/gpt-4o-mini) + * - Conductor server running at CONDUCTOR_SERVER_URL + * - CONDUCTOR_AGENT_LLM_MODEL set (or defaults to openai/gpt-4o-mini) * - `gh` CLI installed (https://cli.github.com) * - GH_TOKEN stored via `agentspan credentials set` */ diff --git a/examples/agents/16e-credentials-http-tool.ts b/examples/agents/16e-credentials-http-tool.ts index 3a5ea9eb..05a86f6b 100644 --- a/examples/agents/16e-credentials-http-tool.ts +++ b/examples/agents/16e-credentials-http-tool.ts @@ -14,8 +14,8 @@ * agentspan credentials set GITHUB_TOKEN * * Requirements: - * - Agentspan server running at AGENTSPAN_SERVER_URL - * - AGENTSPAN_LLM_MODEL set (or defaults to openai/gpt-4o-mini) + * - Conductor server running at CONDUCTOR_SERVER_URL + * - CONDUCTOR_AGENT_LLM_MODEL set (or defaults to openai/gpt-4o-mini) * - GITHUB_TOKEN stored via `agentspan credentials set` */ diff --git a/examples/agents/16f-credentials-mcp-tool.ts b/examples/agents/16f-credentials-mcp-tool.ts index 5e2fa16f..4f219908 100644 --- a/examples/agents/16f-credentials-mcp-tool.ts +++ b/examples/agents/16f-credentials-mcp-tool.ts @@ -16,8 +16,8 @@ * agentspan credentials set MCP_API_KEY * * Requirements: - * - Agentspan server running at AGENTSPAN_SERVER_URL - * - AGENTSPAN_LLM_MODEL set (or defaults to openai/gpt-4o-mini) + * - Conductor server running at CONDUCTOR_SERVER_URL + * - CONDUCTOR_AGENT_LLM_MODEL set (or defaults to openai/gpt-4o-mini) * - mcp-testkit running on http://localhost:3001 (see setup above) * - MCP_API_KEY stored via CLI or Agentspan UI */ diff --git a/examples/agents/16g-credentials-framework-passthrough.ts b/examples/agents/16g-credentials-framework-passthrough.ts index 52b2bb24..74d4ceb2 100644 --- a/examples/agents/16g-credentials-framework-passthrough.ts +++ b/examples/agents/16g-credentials-framework-passthrough.ts @@ -19,8 +19,8 @@ * agentspan credentials set GITHUB_TOKEN * * Requirements: - * - Agentspan server running at AGENTSPAN_SERVER_URL - * - AGENTSPAN_LLM_MODEL set (or defaults to openai/gpt-4o-mini) + * - Conductor server running at CONDUCTOR_SERVER_URL + * - CONDUCTOR_AGENT_LLM_MODEL set (or defaults to openai/gpt-4o-mini) * - GITHUB_TOKEN stored via `agentspan credentials set` */ diff --git a/examples/agents/16h-credentials-external-worker.ts b/examples/agents/16h-credentials-external-worker.ts index a3968dfa..1884c809 100644 --- a/examples/agents/16h-credentials-external-worker.ts +++ b/examples/agents/16h-credentials-external-worker.ts @@ -23,9 +23,9 @@ * agentspan credentials set GITHUB_TOKEN * * Requirements: - * - Agentspan server running at AGENTSPAN_SERVER_URL (> 0.4.2, for + * - Conductor server running at CONDUCTOR_SERVER_URL (> 0.4.2, for * runtimeMetadata delivery) or conductor-oss (with PR #1255) - * - AGENTSPAN_LLM_MODEL set (or defaults to openai/gpt-4o-mini) + * - CONDUCTOR_AGENT_LLM_MODEL set (or defaults to openai/gpt-4o-mini) * - GITHUB_TOKEN stored via `agentspan credentials set` */ diff --git a/examples/agents/16i-credentials-langchain.ts b/examples/agents/16i-credentials-langchain.ts index 76f4c1f7..9b72fad8 100644 --- a/examples/agents/16i-credentials-langchain.ts +++ b/examples/agents/16i-credentials-langchain.ts @@ -18,8 +18,8 @@ * agentspan credentials set GITHUB_TOKEN * * Requirements: - * - Agentspan server running at AGENTSPAN_SERVER_URL - * - AGENTSPAN_LLM_MODEL set (or defaults to openai/gpt-4o-mini) + * - Conductor server running at CONDUCTOR_SERVER_URL + * - CONDUCTOR_AGENT_LLM_MODEL set (or defaults to openai/gpt-4o-mini) * - GITHUB_TOKEN stored via `agentspan credentials set` */ diff --git a/examples/agents/16j-credentials-openai-sdk.ts b/examples/agents/16j-credentials-openai-sdk.ts index f52fd98b..ffb05c67 100644 --- a/examples/agents/16j-credentials-openai-sdk.ts +++ b/examples/agents/16j-credentials-openai-sdk.ts @@ -19,8 +19,8 @@ * agentspan credentials set GITHUB_TOKEN * * Requirements: - * - Agentspan server running at AGENTSPAN_SERVER_URL - * - AGENTSPAN_LLM_MODEL set (or defaults to openai/gpt-4o-mini) + * - Conductor server running at CONDUCTOR_SERVER_URL + * - CONDUCTOR_AGENT_LLM_MODEL set (or defaults to openai/gpt-4o-mini) * - GITHUB_TOKEN stored via `agentspan credentials set` */ diff --git a/examples/agents/16k-credentials-google-adk.ts b/examples/agents/16k-credentials-google-adk.ts index 291a1e49..9ef09255 100644 --- a/examples/agents/16k-credentials-google-adk.ts +++ b/examples/agents/16k-credentials-google-adk.ts @@ -18,8 +18,8 @@ * agentspan credentials set GITHUB_TOKEN * * Requirements: - * - Agentspan server running at AGENTSPAN_SERVER_URL - * - AGENTSPAN_LLM_MODEL set (or defaults to openai/gpt-4o-mini) + * - Conductor server running at CONDUCTOR_SERVER_URL + * - CONDUCTOR_AGENT_LLM_MODEL set (or defaults to openai/gpt-4o-mini) * - GITHUB_TOKEN stored via `agentspan credentials set` */ diff --git a/examples/agents/17-scheduled-agent.ts b/examples/agents/17-scheduled-agent.ts index f2d94cd4..d3fdbeb3 100644 --- a/examples/agents/17-scheduled-agent.ts +++ b/examples/agents/17-scheduled-agent.ts @@ -16,11 +16,11 @@ * 8. Redeploy with an empty list to purge all schedules (cleanup). * * Requirements: - * - Conductor server at AGENTSPAN_SERVER_URL (default: http://localhost:8080/api) + * - Conductor server at CONDUCTOR_SERVER_URL (default: http://localhost:8080/api) * - Scheduler module enabled (on by default) * * Run: - * AGENTSPAN_SERVER_URL=http://localhost:8080/api \ + * CONDUCTOR_SERVER_URL=http://localhost:8080/api \ * npx ts-node examples/17-scheduled-agent.ts */ diff --git a/examples/agents/17-swarm-orchestration.ts b/examples/agents/17-swarm-orchestration.ts index 6d7ac99f..5fff1000 100644 --- a/examples/agents/17-swarm-orchestration.ts +++ b/examples/agents/17-swarm-orchestration.ts @@ -18,8 +18,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, OnTextMention } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/18-manual-selection.ts b/examples/agents/18-manual-selection.ts index 7a53472f..47728869 100644 --- a/examples/agents/18-manual-selection.ts +++ b/examples/agents/18-manual-selection.ts @@ -13,8 +13,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import * as readline from 'node:readline/promises'; diff --git a/examples/agents/19-composable-termination.ts b/examples/agents/19-composable-termination.ts index 6a038a1c..ac1e9740 100644 --- a/examples/agents/19-composable-termination.ts +++ b/examples/agents/19-composable-termination.ts @@ -11,8 +11,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { diff --git a/examples/agents/20-constrained-transitions.ts b/examples/agents/20-constrained-transitions.ts index 38cba396..30b9536e 100644 --- a/examples/agents/20-constrained-transitions.ts +++ b/examples/agents/20-constrained-transitions.ts @@ -11,8 +11,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/21-regex-guardrails.ts b/examples/agents/21-regex-guardrails.ts index 37294864..28720897 100644 --- a/examples/agents/21-regex-guardrails.ts +++ b/examples/agents/21-regex-guardrails.ts @@ -14,8 +14,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool, RegexGuardrail } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/22-llm-guardrails.ts b/examples/agents/22-llm-guardrails.ts index 6e26bbd8..db757c97 100644 --- a/examples/agents/22-llm-guardrails.ts +++ b/examples/agents/22-llm-guardrails.ts @@ -12,8 +12,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, LLMGuardrail } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/23-token-tracking.ts b/examples/agents/23-token-tracking.ts index 87bc6531..cb431029 100644 --- a/examples/agents/23-token-tracking.ts +++ b/examples/agents/23-token-tracking.ts @@ -6,8 +6,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/24-code-execution.ts b/examples/agents/24-code-execution.ts index e40bd569..77bb074e 100644 --- a/examples/agents/24-code-execution.ts +++ b/examples/agents/24-code-execution.ts @@ -12,8 +12,8 @@ * Requirements: * - Conductor server with LLM support * - Docker (for DockerCodeExecutor example) - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { diff --git a/examples/agents/25-semantic-memory.ts b/examples/agents/25-semantic-memory.ts index e9ef0fd8..a5223891 100644 --- a/examples/agents/25-semantic-memory.ts +++ b/examples/agents/25-semantic-memory.ts @@ -9,8 +9,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { diff --git a/examples/agents/26-opentelemetry-tracing.ts b/examples/agents/26-opentelemetry-tracing.ts index cfed9dad..90940d0c 100644 --- a/examples/agents/26-opentelemetry-tracing.ts +++ b/examples/agents/26-opentelemetry-tracing.ts @@ -14,8 +14,8 @@ * Requirements: * - npm install @opentelemetry/api @opentelemetry/sdk-trace-base * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool, isTracingEnabled } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/28-gpt-assistant-agent.ts b/examples/agents/28-gpt-assistant-agent.ts index 59338b91..0676d706 100644 --- a/examples/agents/28-gpt-assistant-agent.ts +++ b/examples/agents/28-gpt-assistant-agent.ts @@ -12,8 +12,8 @@ * Requirements: * - Conductor server with LLM support * - OPENAI_API_KEY=sk-... as environment variable - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { AgentRuntime, GPTAssistantAgent } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/29-agent-introductions.ts b/examples/agents/29-agent-introductions.ts index 626d5edc..50a11243 100644 --- a/examples/agents/29-agent-introductions.ts +++ b/examples/agents/29-agent-introductions.ts @@ -10,8 +10,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/30-multimodal-agent.ts b/examples/agents/30-multimodal-agent.ts index 71b3b008..87d585b5 100644 --- a/examples/agents/30-multimodal-agent.ts +++ b/examples/agents/30-multimodal-agent.ts @@ -13,8 +13,8 @@ * * Requirements: * - Conductor server with LLM support (OpenAI key configured) - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/30-skills-dg-review.ts b/examples/agents/30-skills-dg-review.ts index e564219b..148efcb5 100644 --- a/examples/agents/30-skills-dg-review.ts +++ b/examples/agents/30-skills-dg-review.ts @@ -10,7 +10,7 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api * - /dg skill installed (https://github.com/v1r3n/dinesh-gilfoyle) */ diff --git a/examples/agents/31-skills-conductor.ts b/examples/agents/31-skills-conductor.ts index bcc0162e..fef46610 100644 --- a/examples/agents/31-skills-conductor.ts +++ b/examples/agents/31-skills-conductor.ts @@ -9,7 +9,7 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api * - conductor-skills installed (https://github.com/conductor-oss/conductor-skills) */ diff --git a/examples/agents/31-tool-guardrails.ts b/examples/agents/31-tool-guardrails.ts index 3f67bfd6..6b590dd1 100644 --- a/examples/agents/31-tool-guardrails.ts +++ b/examples/agents/31-tool-guardrails.ts @@ -9,8 +9,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, guardrail, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/32-human-guardrail.ts b/examples/agents/32-human-guardrail.ts index 48d3e7f1..f1f44503 100644 --- a/examples/agents/32-human-guardrail.ts +++ b/examples/agents/32-human-guardrail.ts @@ -9,8 +9,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import * as readline from 'node:readline/promises'; diff --git a/examples/agents/32-skills-multi-agent.ts b/examples/agents/32-skills-multi-agent.ts index 42b074ec..1d6bb45a 100644 --- a/examples/agents/32-skills-multi-agent.ts +++ b/examples/agents/32-skills-multi-agent.ts @@ -10,7 +10,7 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api * - /dg skill installed (https://github.com/v1r3n/dinesh-gilfoyle) * - conductor skill installed (https://github.com/conductor-oss/conductor-skills) */ diff --git a/examples/agents/33-external-workers.ts b/examples/agents/33-external-workers.ts index 179385b7..56338f73 100644 --- a/examples/agents/33-external-workers.ts +++ b/examples/agents/33-external-workers.ts @@ -15,8 +15,8 @@ * Requirements: * - Conductor server with LLM support * - The referenced workers must be running somewhere - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/33-single-turn-tool.ts b/examples/agents/33-single-turn-tool.ts index 0415239f..5fee8be4 100644 --- a/examples/agents/33-single-turn-tool.ts +++ b/examples/agents/33-single-turn-tool.ts @@ -10,8 +10,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/35-standalone-guardrails.ts b/examples/agents/35-standalone-guardrails.ts index 51751e97..751f9941 100644 --- a/examples/agents/35-standalone-guardrails.ts +++ b/examples/agents/35-standalone-guardrails.ts @@ -13,8 +13,8 @@ * Requirements: * Part 1 (standalone): none -- no server, no LLM, no workers. * Part 2 (as workers): Conductor server - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { guardrail } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/36-simple-agent-guardrails.ts b/examples/agents/36-simple-agent-guardrails.ts index f5df0f28..14d81283 100644 --- a/examples/agents/36-simple-agent-guardrails.ts +++ b/examples/agents/36-simple-agent-guardrails.ts @@ -15,8 +15,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, RegexGuardrail, guardrail } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/37-fix-guardrail.ts b/examples/agents/37-fix-guardrail.ts index cbe72a10..3e252aa8 100644 --- a/examples/agents/37-fix-guardrail.ts +++ b/examples/agents/37-fix-guardrail.ts @@ -17,8 +17,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, guardrail, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/38-tech-trends.ts b/examples/agents/38-tech-trends.ts index 962d604c..cec80822 100644 --- a/examples/agents/38-tech-trends.ts +++ b/examples/agents/38-tech-trends.ts @@ -13,8 +13,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, pdfTool, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/39-local-code-execution.ts b/examples/agents/39-local-code-execution.ts index 8193914c..89895e38 100644 --- a/examples/agents/39-local-code-execution.ts +++ b/examples/agents/39-local-code-execution.ts @@ -12,8 +12,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, LocalCodeExecutor } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/39a-docker-code-execution.ts b/examples/agents/39a-docker-code-execution.ts index 146fd5c5..ea08bb7b 100644 --- a/examples/agents/39a-docker-code-execution.ts +++ b/examples/agents/39a-docker-code-execution.ts @@ -8,8 +8,8 @@ * Requirements: * - Conductor server with LLM support * - Docker installed and daemon running - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, DockerCodeExecutor } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/39b-jupyter-code-execution.ts b/examples/agents/39b-jupyter-code-execution.ts index bd510d04..f4f37b50 100644 --- a/examples/agents/39b-jupyter-code-execution.ts +++ b/examples/agents/39b-jupyter-code-execution.ts @@ -9,8 +9,8 @@ * Requirements: * - Conductor server with LLM support * - Jupyter runtime installed (jupyter_client, ipykernel) - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, JupyterCodeExecutor } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/39c-serverless-code-execution.ts b/examples/agents/39c-serverless-code-execution.ts index c23ced41..d479e08f 100644 --- a/examples/agents/39c-serverless-code-execution.ts +++ b/examples/agents/39c-serverless-code-execution.ts @@ -10,8 +10,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { createServer } from 'http'; diff --git a/examples/agents/40-media-generation-agent.ts b/examples/agents/40-media-generation-agent.ts index a7da64bf..413adaaf 100644 --- a/examples/agents/40-media-generation-agent.ts +++ b/examples/agents/40-media-generation-agent.ts @@ -14,8 +14,8 @@ * * Requirements: * - Conductor server with OpenAI integration configured - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, imageTool, audioTool, videoTool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/41-sequential-pipeline-tools.ts b/examples/agents/41-sequential-pipeline-tools.ts index 7ef8853a..d9edc93f 100644 --- a/examples/agents/41-sequential-pipeline-tools.ts +++ b/examples/agents/41-sequential-pipeline-tools.ts @@ -12,8 +12,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/42-security-testing.ts b/examples/agents/42-security-testing.ts index c8649503..f70baebe 100644 --- a/examples/agents/42-security-testing.ts +++ b/examples/agents/42-security-testing.ts @@ -16,8 +16,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/43-data-security-pipeline.ts b/examples/agents/43-data-security-pipeline.ts index dffc7896..5ebdbccb 100644 --- a/examples/agents/43-data-security-pipeline.ts +++ b/examples/agents/43-data-security-pipeline.ts @@ -15,8 +15,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/44-safety-guardrails.ts b/examples/agents/44-safety-guardrails.ts index a06cf52a..f9c87a05 100644 --- a/examples/agents/44-safety-guardrails.ts +++ b/examples/agents/44-safety-guardrails.ts @@ -16,8 +16,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/45-agent-tool.ts b/examples/agents/45-agent-tool.ts index 833043a9..31eeaa30 100644 --- a/examples/agents/45-agent-tool.ts +++ b/examples/agents/45-agent-tool.ts @@ -12,8 +12,8 @@ * * Requirements: * - Conductor server with AgentTool support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, agentTool, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/46-transfer-control.ts b/examples/agents/46-transfer-control.ts index bb066919..9ad6b22f 100644 --- a/examples/agents/46-transfer-control.ts +++ b/examples/agents/46-transfer-control.ts @@ -7,8 +7,8 @@ * * Requirements: * - Conductor server - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/47-callbacks.ts b/examples/agents/47-callbacks.ts index f555c8f1..128b4b90 100644 --- a/examples/agents/47-callbacks.ts +++ b/examples/agents/47-callbacks.ts @@ -6,8 +6,8 @@ * * Requirements: * - Conductor server with callback support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, CallbackHandler, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/48-planner.ts b/examples/agents/48-planner.ts index 4fb6b6be..ca259c67 100644 --- a/examples/agents/48-planner.ts +++ b/examples/agents/48-planner.ts @@ -7,8 +7,8 @@ * * Requirements: * - Conductor server with planner support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/49-include-contents.ts b/examples/agents/49-include-contents.ts index b683fd82..2611d3c8 100644 --- a/examples/agents/49-include-contents.ts +++ b/examples/agents/49-include-contents.ts @@ -6,8 +6,8 @@ * * Requirements: * - Conductor server with include_contents support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/50-thinking-config.ts b/examples/agents/50-thinking-config.ts index 4f5ced0c..3c828feb 100644 --- a/examples/agents/50-thinking-config.ts +++ b/examples/agents/50-thinking-config.ts @@ -6,8 +6,8 @@ * * Requirements: * - Conductor server with thinking config support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/51-shared-state.ts b/examples/agents/51-shared-state.ts index 4cdd9ec7..170e6149 100644 --- a/examples/agents/51-shared-state.ts +++ b/examples/agents/51-shared-state.ts @@ -6,8 +6,8 @@ * * Requirements: * - Conductor server with state support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/52-nested-strategies.ts b/examples/agents/52-nested-strategies.ts index 90336766..ef26aa99 100644 --- a/examples/agents/52-nested-strategies.ts +++ b/examples/agents/52-nested-strategies.ts @@ -8,8 +8,8 @@ * * Requirements: * - Conductor server - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/53-agent-lifecycle-callbacks.ts b/examples/agents/53-agent-lifecycle-callbacks.ts index 683a88c4..c85285bb 100644 --- a/examples/agents/53-agent-lifecycle-callbacks.ts +++ b/examples/agents/53-agent-lifecycle-callbacks.ts @@ -7,8 +7,8 @@ * * Requirements: * - Conductor server with callback support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, CallbackHandler, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/54-software-bug-assistant.ts b/examples/agents/54-software-bug-assistant.ts index b66c9348..d1d697ef 100644 --- a/examples/agents/54-software-bug-assistant.ts +++ b/examples/agents/54-software-bug-assistant.ts @@ -8,8 +8,8 @@ * * Requirements: * - Conductor server with AgentTool + MCP support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable * - GH_TOKEN in environment (optional, for GitHub MCP) */ diff --git a/examples/agents/55-ml-engineering.ts b/examples/agents/55-ml-engineering.ts index 64156d1d..f4bbf5c3 100644 --- a/examples/agents/55-ml-engineering.ts +++ b/examples/agents/55-ml-engineering.ts @@ -11,8 +11,8 @@ * * Requirements: * - Conductor server - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/56-rag-agent.ts b/examples/agents/56-rag-agent.ts index 6947408d..411449ff 100644 --- a/examples/agents/56-rag-agent.ts +++ b/examples/agents/56-rag-agent.ts @@ -8,8 +8,8 @@ * Requirements: * - Conductor server with RAG system tasks enabled * - A configured vector database (e.g., pgvector) - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, searchTool, indexTool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/57-plan-dry-run.ts b/examples/agents/57-plan-dry-run.ts index 9b588753..f8c1548e 100644 --- a/examples/agents/57-plan-dry-run.ts +++ b/examples/agents/57-plan-dry-run.ts @@ -8,8 +8,8 @@ * * Requirements: * - Conductor server running - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/58-scatter-gather.ts b/examples/agents/58-scatter-gather.ts index 7062e341..443a89d7 100644 --- a/examples/agents/58-scatter-gather.ts +++ b/examples/agents/58-scatter-gather.ts @@ -8,8 +8,8 @@ * * Requirements: * - Conductor server running - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_SECONDARY_LLM_MODEL=openai/gpt-4o as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_SECONDARY_LLM_MODEL=openai/gpt-4o as environment variable */ import { Agent, AgentRuntime, scatterGather, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/59-coding-agent.ts b/examples/agents/59-coding-agent.ts index 24c445f0..43ad5463 100644 --- a/examples/agents/59-coding-agent.ts +++ b/examples/agents/59-coding-agent.ts @@ -9,7 +9,7 @@ * * Requirements: * - Conductor server running - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/60-github-coding-agent.ts b/examples/agents/60-github-coding-agent.ts index b3bc5cdf..c8065626 100644 --- a/examples/agents/60-github-coding-agent.ts +++ b/examples/agents/60-github-coding-agent.ts @@ -9,7 +9,7 @@ * * Requirements: * - Conductor server running - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable * - gh CLI authenticated * - Git configured with push access to the repo */ diff --git a/examples/agents/60a-github-coding-agent-simple.ts b/examples/agents/60a-github-coding-agent-simple.ts index f549fff3..b4dd21cc 100644 --- a/examples/agents/60a-github-coding-agent-simple.ts +++ b/examples/agents/60a-github-coding-agent-simple.ts @@ -6,7 +6,7 @@ * * Requirements: * - Conductor server running - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable * - gh CLI authenticated * - Git configured with push access to the repo */ diff --git a/examples/agents/61-github-coding-agent-chained.ts b/examples/agents/61-github-coding-agent-chained.ts index 7d1fd33c..7a5ab7bc 100644 --- a/examples/agents/61-github-coding-agent-chained.ts +++ b/examples/agents/61-github-coding-agent-chained.ts @@ -7,7 +7,7 @@ * 3. Create pull request (CLI tool: gh) * * Requirements: - * - Agentspan server running + * - Conductor server running * - GITHUB_TOKEN stored: agentspan credentials set GITHUB_TOKEN * - gh CLI installed */ diff --git a/examples/agents/62-cli-tool-guardrails.ts b/examples/agents/62-cli-tool-guardrails.ts index 035aaf50..f054f66d 100644 --- a/examples/agents/62-cli-tool-guardrails.ts +++ b/examples/agents/62-cli-tool-guardrails.ts @@ -6,8 +6,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, RegexGuardrail } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/63-deploy.ts b/examples/agents/63-deploy.ts index 297aed70..aae2411d 100644 --- a/examples/agents/63-deploy.ts +++ b/examples/agents/63-deploy.ts @@ -9,8 +9,8 @@ * * Requirements: * - Conductor server running - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/63b-serve.ts b/examples/agents/63b-serve.ts index 9e0ed3ca..50770aa7 100644 --- a/examples/agents/63b-serve.ts +++ b/examples/agents/63b-serve.ts @@ -13,8 +13,8 @@ * * Requirements: * - Conductor server running - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/63c-run-by-name.ts b/examples/agents/63c-run-by-name.ts index d3783d22..97a6ae30 100644 --- a/examples/agents/63c-run-by-name.ts +++ b/examples/agents/63c-run-by-name.ts @@ -9,8 +9,8 @@ * * Requirements: * - Conductor server running - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { docAssistant } from './63-deploy.js'; diff --git a/examples/agents/63d-serve-from-package.ts b/examples/agents/63d-serve-from-package.ts index 4d6a5040..a9ff67ff 100644 --- a/examples/agents/63d-serve-from-package.ts +++ b/examples/agents/63d-serve-from-package.ts @@ -10,8 +10,8 @@ * * Requirements: * - Conductor server running - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/63e-run-monitoring.ts b/examples/agents/63e-run-monitoring.ts index 56a31bce..1c984cb2 100644 --- a/examples/agents/63e-run-monitoring.ts +++ b/examples/agents/63e-run-monitoring.ts @@ -3,8 +3,8 @@ * * Requirements: * - Conductor server running - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { monitoringAgent } from './63d-serve-from-package.js'; diff --git a/examples/agents/64-swarm-with-tools.ts b/examples/agents/64-swarm-with-tools.ts index 5571ac17..e63c32ca 100644 --- a/examples/agents/64-swarm-with-tools.ts +++ b/examples/agents/64-swarm-with-tools.ts @@ -6,8 +6,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, OnTextMention, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/65-parallel-with-tools.ts b/examples/agents/65-parallel-with-tools.ts index b8b2fef1..b7eed5a6 100644 --- a/examples/agents/65-parallel-with-tools.ts +++ b/examples/agents/65-parallel-with-tools.ts @@ -6,8 +6,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/66-handoff-to-parallel.ts b/examples/agents/66-handoff-to-parallel.ts index f235debd..67dff316 100644 --- a/examples/agents/66-handoff-to-parallel.ts +++ b/examples/agents/66-handoff-to-parallel.ts @@ -6,8 +6,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/67-router-to-sequential.ts b/examples/agents/67-router-to-sequential.ts index e1ddf919..279bbe09 100644 --- a/examples/agents/67-router-to-sequential.ts +++ b/examples/agents/67-router-to-sequential.ts @@ -6,8 +6,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/68-context-condensation.ts b/examples/agents/68-context-condensation.ts index f29e2aad..8c48a64b 100644 --- a/examples/agents/68-context-condensation.ts +++ b/examples/agents/68-context-condensation.ts @@ -10,8 +10,8 @@ * * Requirements: * - Conductor server with LLM support + agentspan.default-context-window=10000 - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, agentTool, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/70-ce-support-agent.ts b/examples/agents/70-ce-support-agent.ts index 1fa004f4..7a3ac96b 100644 --- a/examples/agents/70-ce-support-agent.ts +++ b/examples/agents/70-ce-support-agent.ts @@ -14,8 +14,8 @@ * * Requirements: * - Conductor server - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { Agent, AgentRuntime, RegexGuardrail, agentTool, tool } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/71-api-tool.ts b/examples/agents/71-api-tool.ts index 1d8062b4..1ac7cd38 100644 --- a/examples/agents/71-api-tool.ts +++ b/examples/agents/71-api-tool.ts @@ -24,8 +24,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable * - mcp-testkit running on http://localhost:3001 (for examples 1-3, see setup above) * - For GitHub example: agentspan credentials set GITHUB_TOKEN ghp_xxx */ diff --git a/examples/agents/74-cli-error-output.ts b/examples/agents/74-cli-error-output.ts index c838e91b..e3ac66b0 100644 --- a/examples/agents/74-cli-error-output.ts +++ b/examples/agents/74-cli-error-output.ts @@ -7,8 +7,8 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL (e.g. http://localhost:8080/api) - * - AGENTSPAN_LLM_MODEL (e.g. openai/gpt-4o-mini) + * - CONDUCTOR_SERVER_URL (e.g. http://localhost:8080/api) + * - CONDUCTOR_AGENT_LLM_MODEL (e.g. openai/gpt-4o-mini) */ import { Agent, AgentRuntime } from '@io-orkes/conductor-javascript/agents'; diff --git a/examples/agents/90-guardrail-e2e-tests.ts b/examples/agents/90-guardrail-e2e-tests.ts index f0e81a2f..37e08220 100644 --- a/examples/agents/90-guardrail-e2e-tests.ts +++ b/examples/agents/90-guardrail-e2e-tests.ts @@ -5,8 +5,8 @@ * * Requirements: * - Conductor server running - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable - * - AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api as environment variable + * - CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini as environment variable */ import { diff --git a/examples/agents/README.md b/examples/agents/README.md index eef8ae93..f2cbf011 100644 --- a/examples/agents/README.md +++ b/examples/agents/README.md @@ -23,7 +23,7 @@ In production, the three concerns are separated: ``` ┌──────────────────────────────────────────────────────────────┐ │ 1. DEPLOY (once, during CI/CD) │ -│ Registers the agent definition with the Agentspan server │ +│ Registers the agent definition with the Conductor server │ │ │ │ await runtime.deploy(agent); │ │ // or CLI: agentspan deploy --package my-agents │ @@ -114,15 +114,15 @@ cd vercel-ai && npm install Export environment variables: ```bash -export AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini -export AGENTSPAN_SERVER_URL=http://localhost:8080/api -# export AGENTSPAN_AUTH_KEY= # if authentication is enabled -# export AGENTSPAN_AUTH_SECRET= +export CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini +export CONDUCTOR_SERVER_URL=http://localhost:8080/api +# export CONDUCTOR_AUTH_KEY= # if authentication is enabled +# export CONDUCTOR_AUTH_SECRET= ``` #### 2.1. Choose a model -The `AGENTSPAN_LLM_MODEL` variable uses the `provider/model-name` format. Examples: +The `CONDUCTOR_AGENT_LLM_MODEL` variable uses the `provider/model-name` format. Examples: | Provider | Model string | API key env var | |----------|-------------|-----------------| diff --git a/examples/agents/adk/00-hello-world.ts b/examples/agents/adk/00-hello-world.ts index 0df867ba..0dfae204 100644 --- a/examples/agents/adk/00-hello-world.ts +++ b/examples/agents/adk/00-hello-world.ts @@ -6,13 +6,13 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent } from '@google/adk'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; export const agent = new LlmAgent({ name: 'greeter', diff --git a/examples/agents/adk/01-basic-agent.ts b/examples/agents/adk/01-basic-agent.ts index c71a53c8..25944c4f 100644 --- a/examples/agents/adk/01-basic-agent.ts +++ b/examples/agents/adk/01-basic-agent.ts @@ -3,18 +3,18 @@ * * Demonstrates: * - Defining an agent using Google's Agent Development Kit (ADK) - * - Running via Agentspan passthrough + * - Running via Conductor passthrough * - The runtime serializes the ADK agent and the server normalizes it * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent } from '@google/adk'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; export const agent = new LlmAgent({ name: 'greeter', diff --git a/examples/agents/adk/02-function-tools.ts b/examples/agents/adk/02-function-tools.ts index 99760b68..743d73de 100644 --- a/examples/agents/adk/02-function-tools.ts +++ b/examples/agents/adk/02-function-tools.ts @@ -8,14 +8,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Tool definitions ───────────────────────────────────────────────── diff --git a/examples/agents/adk/03-structured-output.ts b/examples/agents/adk/03-structured-output.ts index 9b7edf1e..b6f451fb 100644 --- a/examples/agents/adk/03-structured-output.ts +++ b/examples/agents/adk/03-structured-output.ts @@ -8,14 +8,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, zodObjectToSchema } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Output schemas ─────────────────────────────────────────────────── diff --git a/examples/agents/adk/04-sub-agents.ts b/examples/agents/adk/04-sub-agents.ts index c55f3cca..9c5843b7 100644 --- a/examples/agents/adk/04-sub-agents.ts +++ b/examples/agents/adk/04-sub-agents.ts @@ -8,14 +8,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Specialist tools ───────────────────────────────────────────────── diff --git a/examples/agents/adk/05-generation-config.ts b/examples/agents/adk/05-generation-config.ts index 3be42135..58d1b093 100644 --- a/examples/agents/adk/05-generation-config.ts +++ b/examples/agents/adk/05-generation-config.ts @@ -8,13 +8,13 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent } from '@google/adk'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Precise agent -- low temperature for factual responses ────────── diff --git a/examples/agents/adk/06-streaming.ts b/examples/agents/adk/06-streaming.ts index bf35d665..d980e036 100644 --- a/examples/agents/adk/06-streaming.ts +++ b/examples/agents/adk/06-streaming.ts @@ -7,14 +7,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Tool ───────────────────────────────────────────────────────────── diff --git a/examples/agents/adk/07-output-key-state.ts b/examples/agents/adk/07-output-key-state.ts index f7b0ae0a..f843b3c9 100644 --- a/examples/agents/adk/07-output-key-state.ts +++ b/examples/agents/adk/07-output-key-state.ts @@ -8,14 +8,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Tool definitions ───────────────────────────────────────────────── diff --git a/examples/agents/adk/08-instruction-templating.ts b/examples/agents/adk/08-instruction-templating.ts index 132162fe..63931f6f 100644 --- a/examples/agents/adk/08-instruction-templating.ts +++ b/examples/agents/adk/08-instruction-templating.ts @@ -8,14 +8,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Tool definitions ───────────────────────────────────────────────── diff --git a/examples/agents/adk/09-multi-tool-agent.ts b/examples/agents/adk/09-multi-tool-agent.ts index 937712dd..9e1915d5 100644 --- a/examples/agents/adk/09-multi-tool-agent.ts +++ b/examples/agents/adk/09-multi-tool-agent.ts @@ -8,14 +8,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Tool definitions ───────────────────────────────────────────────── diff --git a/examples/agents/adk/10-hierarchical-agents.ts b/examples/agents/adk/10-hierarchical-agents.ts index 3a031ee3..541f965d 100644 --- a/examples/agents/adk/10-hierarchical-agents.ts +++ b/examples/agents/adk/10-hierarchical-agents.ts @@ -9,14 +9,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Level 3: Specialist tools ───────────────────────────────────────── diff --git a/examples/agents/adk/11-sequential-agent.ts b/examples/agents/adk/11-sequential-agent.ts index 68fc8060..3ee0a1a8 100644 --- a/examples/agents/adk/11-sequential-agent.ts +++ b/examples/agents/adk/11-sequential-agent.ts @@ -8,13 +8,13 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, SequentialAgent } from '@google/adk'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // Step 1: Research agent gathers facts export const researcher = new LlmAgent({ diff --git a/examples/agents/adk/12-parallel-agent.ts b/examples/agents/adk/12-parallel-agent.ts index a0e9f99f..864095ae 100644 --- a/examples/agents/adk/12-parallel-agent.ts +++ b/examples/agents/adk/12-parallel-agent.ts @@ -8,13 +8,13 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, ParallelAgent } from '@google/adk'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // Three analysts run in parallel export const marketAnalyst = new LlmAgent({ diff --git a/examples/agents/adk/13-loop-agent.ts b/examples/agents/adk/13-loop-agent.ts index ac22486c..04fdda0f 100644 --- a/examples/agents/adk/13-loop-agent.ts +++ b/examples/agents/adk/13-loop-agent.ts @@ -8,13 +8,13 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, SequentialAgent, LoopAgent } from '@google/adk'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // Writer drafts content export const writer = new LlmAgent({ diff --git a/examples/agents/adk/14-callbacks.ts b/examples/agents/adk/14-callbacks.ts index b6c834f0..893b1285 100644 --- a/examples/agents/adk/14-callbacks.ts +++ b/examples/agents/adk/14-callbacks.ts @@ -12,14 +12,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Tool definitions ───────────────────────────────────────────────── diff --git a/examples/agents/adk/15-global-instruction.ts b/examples/agents/adk/15-global-instruction.ts index 5c568c7e..dd662bbd 100644 --- a/examples/agents/adk/15-global-instruction.ts +++ b/examples/agents/adk/15-global-instruction.ts @@ -8,14 +8,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Tool definitions ───────────────────────────────────────────────── diff --git a/examples/agents/adk/16-customer-service.ts b/examples/agents/adk/16-customer-service.ts index 7d6837fb..81b6aef2 100644 --- a/examples/agents/adk/16-customer-service.ts +++ b/examples/agents/adk/16-customer-service.ts @@ -8,14 +8,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Domain tools ────────────────────────────────────────────────── diff --git a/examples/agents/adk/17-financial-advisor.ts b/examples/agents/adk/17-financial-advisor.ts index 8444df53..0e3cdb21 100644 --- a/examples/agents/adk/17-financial-advisor.ts +++ b/examples/agents/adk/17-financial-advisor.ts @@ -8,14 +8,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Portfolio tools ─────────────────────────────────────────────── diff --git a/examples/agents/adk/18-order-processing.ts b/examples/agents/adk/18-order-processing.ts index 3f79cdcf..91c94b11 100644 --- a/examples/agents/adk/18-order-processing.ts +++ b/examples/agents/adk/18-order-processing.ts @@ -8,14 +8,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Tool definitions ───────────────────────────────────────────────── diff --git a/examples/agents/adk/19-supply-chain.ts b/examples/agents/adk/19-supply-chain.ts index 5efe67bf..a12bd8d8 100644 --- a/examples/agents/adk/19-supply-chain.ts +++ b/examples/agents/adk/19-supply-chain.ts @@ -8,14 +8,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Inventory tools ─────────────────────────────────────────────── diff --git a/examples/agents/adk/20-blog-writer.ts b/examples/agents/adk/20-blog-writer.ts index d48ca823..49de2fc0 100644 --- a/examples/agents/adk/20-blog-writer.ts +++ b/examples/agents/adk/20-blog-writer.ts @@ -8,14 +8,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Tool definitions ───────────────────────────────────────────────── diff --git a/examples/agents/adk/21-agent-tool.ts b/examples/agents/adk/21-agent-tool.ts index a4cae9c8..6c1be006 100644 --- a/examples/agents/adk/21-agent-tool.ts +++ b/examples/agents/adk/21-agent-tool.ts @@ -15,14 +15,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool, AgentTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Child agents (each has their own tools) ────────────────────── diff --git a/examples/agents/adk/22-transfer-control.ts b/examples/agents/adk/22-transfer-control.ts index eab1c9fd..88c5b894 100644 --- a/examples/agents/adk/22-transfer-control.ts +++ b/examples/agents/adk/22-transfer-control.ts @@ -15,13 +15,13 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent } from '@google/adk'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Specialist agents with transfer restrictions ──────────────────── diff --git a/examples/agents/adk/23-callbacks-advanced.ts b/examples/agents/adk/23-callbacks-advanced.ts index 979893d9..89a662b2 100644 --- a/examples/agents/adk/23-callbacks-advanced.ts +++ b/examples/agents/adk/23-callbacks-advanced.ts @@ -8,14 +8,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent } from '@google/adk'; import type { BeforeModelCallback, AfterModelCallback } from '@google/adk'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Callback functions ──────────────────────────────────────────── // These run before/after each LLM invocation. diff --git a/examples/agents/adk/24-planner.ts b/examples/agents/adk/24-planner.ts index af2daf97..91c8999e 100644 --- a/examples/agents/adk/24-planner.ts +++ b/examples/agents/adk/24-planner.ts @@ -12,14 +12,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Tool definitions ───────────────────────────────────────────────── diff --git a/examples/agents/adk/25-camel-security.ts b/examples/agents/adk/25-camel-security.ts index 0df8d28b..dae6f2ec 100644 --- a/examples/agents/adk/25-camel-security.ts +++ b/examples/agents/adk/25-camel-security.ts @@ -11,14 +11,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, SequentialAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Tool definitions ───────────────────────────────────────────────── diff --git a/examples/agents/adk/26-safety-guardrails.ts b/examples/agents/adk/26-safety-guardrails.ts index ddaa999a..d4a8fb36 100644 --- a/examples/agents/adk/26-safety-guardrails.ts +++ b/examples/agents/adk/26-safety-guardrails.ts @@ -11,14 +11,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, SequentialAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Tool definitions ───────────────────────────────────────────────── diff --git a/examples/agents/adk/27-security-agent.ts b/examples/agents/adk/27-security-agent.ts index bc7c9d4b..40862ed8 100644 --- a/examples/agents/adk/27-security-agent.ts +++ b/examples/agents/adk/27-security-agent.ts @@ -13,14 +13,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, SequentialAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Tool definitions ───────────────────────────────────────────────── diff --git a/examples/agents/adk/28-movie-pipeline.ts b/examples/agents/adk/28-movie-pipeline.ts index 6aa21faf..9d90f1b2 100644 --- a/examples/agents/adk/28-movie-pipeline.ts +++ b/examples/agents/adk/28-movie-pipeline.ts @@ -11,14 +11,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, SequentialAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Stage tools ────────────────────────────────────────────────────── diff --git a/examples/agents/adk/29-include-contents.ts b/examples/agents/adk/29-include-contents.ts index 7d154872..17c89d82 100644 --- a/examples/agents/adk/29-include-contents.ts +++ b/examples/agents/adk/29-include-contents.ts @@ -11,13 +11,13 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent } from '@google/adk'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Sub-agents ─────────────────────────────────────────────────────── diff --git a/examples/agents/adk/30-thinking-config.ts b/examples/agents/adk/30-thinking-config.ts index 92f17fec..bd929b61 100644 --- a/examples/agents/adk/30-thinking-config.ts +++ b/examples/agents/adk/30-thinking-config.ts @@ -10,14 +10,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Tool definitions ───────────────────────────────────────────────── diff --git a/examples/agents/adk/31-shared-state.ts b/examples/agents/adk/31-shared-state.ts index 5bd67583..906fc4d0 100644 --- a/examples/agents/adk/31-shared-state.ts +++ b/examples/agents/adk/31-shared-state.ts @@ -14,14 +14,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── In-memory state (simulating ADK ToolContext shared state) ──────── // In the real ADK, this would be context.state. For the agentspan diff --git a/examples/agents/adk/32-nested-strategies.ts b/examples/agents/adk/32-nested-strategies.ts index 28bce4eb..1f856907 100644 --- a/examples/agents/adk/32-nested-strategies.ts +++ b/examples/agents/adk/32-nested-strategies.ts @@ -14,13 +14,13 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, ParallelAgent, SequentialAgent } from '@google/adk'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Parallel research agents ───────────────────────────────────────── diff --git a/examples/agents/adk/33-software-bug-assistant.ts b/examples/agents/adk/33-software-bug-assistant.ts index 1146de07..d4217d69 100644 --- a/examples/agents/adk/33-software-bug-assistant.ts +++ b/examples/agents/adk/33-software-bug-assistant.ts @@ -19,14 +19,14 @@ * * Requirements: * - Conductor server with AgentTool + MCP support - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api in env or .env - * - AGENTSPAN_LLM_MODEL=google_gemini/gemini-2.0-flash in env or .env + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api in env or .env + * - CONDUCTOR_AGENT_LLM_MODEL=google_gemini/gemini-2.0-flash in env or .env * - GH_TOKEN in env or .env */ import { Agent, AgentRuntime, agentTool, tool, mcpTool } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'openai/gpt-4o-mini'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'openai/gpt-4o-mini'; // ── In-memory ticket store (mirrors real conductor-oss/conductor issues) ── diff --git a/examples/agents/adk/34-ml-engineering.ts b/examples/agents/adk/34-ml-engineering.ts index 22924a74..1d37e2dd 100644 --- a/examples/agents/adk/34-ml-engineering.ts +++ b/examples/agents/adk/34-ml-engineering.ts @@ -25,13 +25,13 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, SequentialAgent, ParallelAgent, LoopAgent } from '@google/adk'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Phase 1: Data Analysis ─────────────────────────────────────────── diff --git a/examples/agents/adk/35-rag-agent.ts b/examples/agents/adk/35-rag-agent.ts index 23122bc3..5c006dfd 100644 --- a/examples/agents/adk/35-rag-agent.ts +++ b/examples/agents/adk/35-rag-agent.ts @@ -17,14 +17,14 @@ * * Requirements: * - npm install @google/adk zod - * - AGENTSPAN_SERVER_URL for agentspan path + * - CONDUCTOR_SERVER_URL for agentspan path */ import { LlmAgent, FunctionTool } from '@google/adk'; import { z } from 'zod'; import { AgentRuntime } from '@io-orkes/conductor-javascript/agents'; -const model = process.env.AGENTSPAN_LLM_MODEL ?? 'gemini-2.5-flash'; +const model = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'gemini-2.5-flash'; // ── Knowledge base content ─────────────────────────────────────────── diff --git a/examples/agents/adk/README.md b/examples/agents/adk/README.md index 908bd324..571fb8bb 100644 --- a/examples/agents/adk/README.md +++ b/examples/agents/adk/README.md @@ -117,11 +117,11 @@ await runtime.shutdown(); ## Running ```bash -export AGENTSPAN_SERVER_URL=... +export CONDUCTOR_SERVER_URL=... # For Gemini models: export GOOGLE_API_KEY=... # Or override with OpenAI: -export AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini +export CONDUCTOR_AGENT_LLM_MODEL=openai/gpt-4o-mini export OPENAI_API_KEY=... # from the repository root diff --git a/examples/agents/kitchen-sink.ts b/examples/agents/kitchen-sink.ts index 9c802c82..db9024f0 100644 --- a/examples/agents/kitchen-sink.ts +++ b/examples/agents/kitchen-sink.ts @@ -32,7 +32,7 @@ * * Requirements: * - Conductor server with LLM support - * - AGENTSPAN_SERVER_URL, AGENTSPAN_LLM_MODEL env vars + * - CONDUCTOR_SERVER_URL, CONDUCTOR_AGENT_LLM_MODEL env vars * - mcp-testkit running on http://localhost:3001 (for MCP/HTTP tools) * - For full execution: Docker, credential store configured */ @@ -133,7 +133,7 @@ import type { // ── Settings ───────────────────────────────────────────── -const LLM_MODEL = process.env.AGENTSPAN_LLM_MODEL ?? 'openai/gpt-4o'; +const LLM_MODEL = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'openai/gpt-4o'; // ── Mock data (equivalent to Python kitchen_sink_helpers) ─ diff --git a/examples/agents/langgraph/01-hello-world.ts b/examples/agents/langgraph/01-hello-world.ts index b3059cf2..5327ecd5 100644 --- a/examples/agents/langgraph/01-hello-world.ts +++ b/examples/agents/langgraph/01-hello-world.ts @@ -3,7 +3,7 @@ * * Demonstrates: * - Using createReactAgent from @langchain/langgraph/prebuilt - * - Running a graph via Agentspan runtime.run() passthrough + * - Running a graph via Conductor runtime.run() passthrough */ import { createReactAgent } from '@langchain/langgraph/prebuilt'; diff --git a/examples/agents/langgraph/03-memory.ts b/examples/agents/langgraph/03-memory.ts index ae67bdd8..43b53d8e 100644 --- a/examples/agents/langgraph/03-memory.ts +++ b/examples/agents/langgraph/03-memory.ts @@ -3,7 +3,7 @@ * * Demonstrates: * - Attaching a MemorySaver checkpointer to createReactAgent - * - Running via Agentspan passthrough (single turn) + * - Running via Conductor passthrough (single turn) * - How the agent remembers context from earlier messages */ diff --git a/examples/agents/langgraph/04-simple-stategraph.ts b/examples/agents/langgraph/04-simple-stategraph.ts index c2d81eea..d65396a5 100644 --- a/examples/agents/langgraph/04-simple-stategraph.ts +++ b/examples/agents/langgraph/04-simple-stategraph.ts @@ -12,7 +12,7 @@ * Same graph structure: validate → refine → answer (3 nodes, 2 with LLM calls) * * Requirements: - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api * - OPENAI_API_KEY for ChatOpenAI */ diff --git a/examples/agents/langgraph/44-context-condensation.ts b/examples/agents/langgraph/44-context-condensation.ts index 63dd1d93..76a19f92 100644 --- a/examples/agents/langgraph/44-context-condensation.ts +++ b/examples/agents/langgraph/44-context-condensation.ts @@ -387,7 +387,7 @@ const graph = orchBuilder.compile({ name: "research_orchestrator" }); // --------------------------------------------------------------------------- async function main() { console.log('Starting context condensation stress test (LangGraph / TypeScript).'); - console.log("Watch the Agentspan server logs for 'Condensed conversation' entries."); + console.log("Watch the Conductor server logs for 'Condensed conversation' entries."); console.log(); const runtime = new AgentRuntime(); diff --git a/examples/agents/langgraph/46-crash-and-resume.ts b/examples/agents/langgraph/46-crash-and-resume.ts index 3667326c..f46dbde2 100644 --- a/examples/agents/langgraph/46-crash-and-resume.ts +++ b/examples/agents/langgraph/46-crash-and-resume.ts @@ -36,7 +36,7 @@ * await runtime.start(graph, "prompt"); // or via server API / UI * * Requirements: - * - AGENTSPAN_SERVER_URL=http://localhost:8080/api + * - CONDUCTOR_SERVER_URL=http://localhost:8080/api * - OPENAI_API_KEY for ChatOpenAI */ @@ -49,7 +49,7 @@ import * as fs from 'node:fs'; import * as readline from 'node:readline'; const SESSION_FILE = '/tmp/agentspan_langgraph_resume.session'; -const SERVER_URL = process.env.AGENTSPAN_SERVER_URL ?? 'http://localhost:8080/api'; +const SERVER_URL = process.env.CONDUCTOR_SERVER_URL ?? 'http://localhost:8080/api'; const UI_BASE = SERVER_URL.replace('/api', ''); function sleep(ms: number): Promise { diff --git a/examples/agents/langgraph/README.md b/examples/agents/langgraph/README.md index 88d103ac..6e922bd5 100644 --- a/examples/agents/langgraph/README.md +++ b/examples/agents/langgraph/README.md @@ -205,7 +205,7 @@ await runtime.shutdown(); ## Running ```bash -export AGENTSPAN_SERVER_URL=... +export CONDUCTOR_SERVER_URL=... export OPENAI_API_KEY=... # from the repository root npx tsx examples/agents/langgraph/01-hello-world.ts diff --git a/examples/agents/openai/01-basic-agent.ts b/examples/agents/openai/01-basic-agent.ts index 26680002..ea90aeb4 100644 --- a/examples/agents/openai/01-basic-agent.ts +++ b/examples/agents/openai/01-basic-agent.ts @@ -6,10 +6,10 @@ * * Demonstrates: * - Defining an agent using the real @openai/agents SDK - * - Running it via Agentspan passthrough (AgentRuntime) + * - Running it via Conductor passthrough (AgentRuntime) * * Requirements: - * - AGENTSPAN_SERVER_URL for the Agentspan path + * - CONDUCTOR_SERVER_URL for the Agentspan path */ import { Agent, setTracingDisabled } from '@openai/agents'; diff --git a/examples/agents/openai/02-function-tools.ts b/examples/agents/openai/02-function-tools.ts index c1c71c99..d5a41981 100644 --- a/examples/agents/openai/02-function-tools.ts +++ b/examples/agents/openai/02-function-tools.ts @@ -7,10 +7,10 @@ * Demonstrates: * - Defining function tools with zod schemas * - Multiple tools with typed parameters - * - Running via Agentspan passthrough + * - Running via Conductor passthrough * * Requirements: - * - AGENTSPAN_SERVER_URL for the Agentspan path + * - CONDUCTOR_SERVER_URL for the Agentspan path */ import { Agent, tool, setTracingDisabled } from '@openai/agents'; diff --git a/examples/agents/openai/03-structured-output.ts b/examples/agents/openai/03-structured-output.ts index f1428530..8b1f2078 100644 --- a/examples/agents/openai/03-structured-output.ts +++ b/examples/agents/openai/03-structured-output.ts @@ -10,7 +10,7 @@ * - Model settings (temperature) for deterministic output * * Requirements: - * - AGENTSPAN_SERVER_URL for the Agentspan path + * - CONDUCTOR_SERVER_URL for the Agentspan path */ import { Agent, setTracingDisabled } from '@openai/agents'; diff --git a/examples/agents/openai/04-handoffs.ts b/examples/agents/openai/04-handoffs.ts index c42b0040..31bb468f 100644 --- a/examples/agents/openai/04-handoffs.ts +++ b/examples/agents/openai/04-handoffs.ts @@ -7,10 +7,10 @@ * Demonstrates: * - Defining specialist agents with tools * - A triage agent that routes to the correct specialist via handoffs - * - Running via Agentspan passthrough + * - Running via Conductor passthrough * * Requirements: - * - AGENTSPAN_SERVER_URL for the Agentspan path + * - CONDUCTOR_SERVER_URL for the Agentspan path */ import { Agent, tool, setTracingDisabled } from '@openai/agents'; diff --git a/examples/agents/openai/05-guardrails.ts b/examples/agents/openai/05-guardrails.ts index d8e7075f..0edad96a 100644 --- a/examples/agents/openai/05-guardrails.ts +++ b/examples/agents/openai/05-guardrails.ts @@ -7,10 +7,10 @@ * Demonstrates: * - Input guardrails that validate user messages before processing * - Output guardrails that validate agent responses - * - Running via Agentspan passthrough + * - Running via Conductor passthrough * * Requirements: - * - AGENTSPAN_SERVER_URL for the Agentspan path + * - CONDUCTOR_SERVER_URL for the Agentspan path */ import { diff --git a/examples/agents/openai/06-model-settings.ts b/examples/agents/openai/06-model-settings.ts index 4d8d92d6..00b18163 100644 --- a/examples/agents/openai/06-model-settings.ts +++ b/examples/agents/openai/06-model-settings.ts @@ -10,7 +10,7 @@ * - High temperature for creative responses * * Requirements: - * - AGENTSPAN_SERVER_URL for the Agentspan path + * - CONDUCTOR_SERVER_URL for the Agentspan path */ import { Agent, setTracingDisabled } from '@openai/agents'; diff --git a/examples/agents/openai/07-streaming.ts b/examples/agents/openai/07-streaming.ts index a6507a27..bec8047e 100644 --- a/examples/agents/openai/07-streaming.ts +++ b/examples/agents/openai/07-streaming.ts @@ -6,10 +6,10 @@ * * Demonstrates: * - An OpenAI agent with tools - * - Running via Agentspan passthrough + * - Running via Conductor passthrough * * Requirements: - * - AGENTSPAN_SERVER_URL for the Agentspan path + * - CONDUCTOR_SERVER_URL for the Agentspan path */ import { diff --git a/examples/agents/openai/08-agent-as-tool.ts b/examples/agents/openai/08-agent-as-tool.ts index 64b8774f..a5f76c05 100644 --- a/examples/agents/openai/08-agent-as-tool.ts +++ b/examples/agents/openai/08-agent-as-tool.ts @@ -10,7 +10,7 @@ * - Differs from handoffs: manager retains control and synthesizes results * * Requirements: - * - AGENTSPAN_SERVER_URL for the Agentspan path + * - CONDUCTOR_SERVER_URL for the Agentspan path */ import { Agent, tool, setTracingDisabled } from '@openai/agents'; diff --git a/examples/agents/openai/09-dynamic-instructions.ts b/examples/agents/openai/09-dynamic-instructions.ts index 576584d1..f1749448 100644 --- a/examples/agents/openai/09-dynamic-instructions.ts +++ b/examples/agents/openai/09-dynamic-instructions.ts @@ -10,7 +10,7 @@ * - Function tools alongside dynamic instructions * * Requirements: - * - AGENTSPAN_SERVER_URL for the Agentspan path + * - CONDUCTOR_SERVER_URL for the Agentspan path */ import { Agent, tool, setTracingDisabled } from '@openai/agents'; diff --git a/examples/agents/openai/10-multi-model.ts b/examples/agents/openai/10-multi-model.ts index d0af022f..1e2c5e28 100644 --- a/examples/agents/openai/10-multi-model.ts +++ b/examples/agents/openai/10-multi-model.ts @@ -10,7 +10,7 @@ * - Model override for cost/performance optimization * * Requirements: - * - AGENTSPAN_SERVER_URL for the Agentspan path + * - CONDUCTOR_SERVER_URL for the Agentspan path */ import { Agent, tool, setTracingDisabled } from '@openai/agents'; diff --git a/examples/agents/openai/README.md b/examples/agents/openai/README.md index 98d98878..8329a628 100644 --- a/examples/agents/openai/README.md +++ b/examples/agents/openai/README.md @@ -110,7 +110,7 @@ await runtime.shutdown(); ## Running ```bash -export AGENTSPAN_SERVER_URL=... +export CONDUCTOR_SERVER_URL=... export OPENAI_API_KEY=... # from the repository root npx tsx examples/agents/openai/01-basic-agent.ts diff --git a/examples/agents/package.json b/examples/agents/package.json new file mode 100644 index 00000000..75f6a445 --- /dev/null +++ b/examples/agents/package.json @@ -0,0 +1,5 @@ +{ + "name": "conductor-javascript-agent-examples", + "private": true, + "type": "module" +} diff --git a/examples/agents/quickstart/run-all.ts b/examples/agents/quickstart/run-all.ts index 3da2dbfa..79b79c2a 100644 --- a/examples/agents/quickstart/run-all.ts +++ b/examples/agents/quickstart/run-all.ts @@ -42,7 +42,7 @@ const tests: TestCase[] = [ // ── Helpers ───────────────────────────────────────────── -const serverUrl = process.env.AGENTSPAN_SERVER_URL ?? 'http://localhost:8080/api'; +const serverUrl = process.env.CONDUCTOR_SERVER_URL ?? 'http://localhost:8080/api'; async function fetchExecutionTasks(executionId: string): Promise { const url = `${serverUrl}/agent/executions/${executionId}/full`; diff --git a/examples/agents/settings.ts b/examples/agents/settings.ts index 2a9b94ca..b8b468bb 100644 --- a/examples/agents/settings.ts +++ b/examples/agents/settings.ts @@ -1,3 +1,3 @@ -const llmModel = process.env.AGENTSPAN_LLM_MODEL ?? 'openai/gpt-4o-mini'; -const secondaryLlmModel = process.env.AGENTSPAN_SECONDARY_LLM_MODEL ?? 'openai/gpt-4o'; +const llmModel = process.env.CONDUCTOR_AGENT_LLM_MODEL ?? 'openai/gpt-4o-mini'; +const secondaryLlmModel = process.env.CONDUCTOR_AGENT_SECONDARY_LLM_MODEL ?? 'openai/gpt-4o'; export { llmModel, secondaryLlmModel }; diff --git a/examples/agents/vercel-ai/09-credentials.ts b/examples/agents/vercel-ai/09-credentials.ts index 27facb80..5bb9fdac 100644 --- a/examples/agents/vercel-ai/09-credentials.ts +++ b/examples/agents/vercel-ai/09-credentials.ts @@ -2,7 +2,7 @@ * Vercel AI SDK Tools + Native Agent -- Credentials * * Demonstrates agentspan's credential system with AI SDK tools on a native Agent. - * Credentials are declared on the Agent and resolved by the agentspan server + * Credentials are declared on the Agent and resolved by the conductor server * before tool execution -- the tool receives credentials via environment injection. */ @@ -17,7 +17,7 @@ const fetchReport = aiTool({ reportId: z.string().describe('Report ID to fetch'), }), execute: async ({ reportId }) => { - // In production, the agentspan server injects ANALYTICS_API_KEY + // In production, the conductor server injects ANALYTICS_API_KEY // into the environment before this tool executes. const apiKey = process.env.ANALYTICS_API_KEY ?? 'demo-key'; return { @@ -37,7 +37,7 @@ export const agent = new Agent({ 'Use the fetchReport tool to retrieve data when asked.', tools: [fetchReport], credentials: [ - // Credential references resolved by the agentspan server. + // Credential references resolved by the conductor server. // In production, these are stored in the credential vault. 'ANALYTICS_API_KEY', ], diff --git a/examples/agents/vercel-ai/README.md b/examples/agents/vercel-ai/README.md index ccaba243..9c4b4710 100644 --- a/examples/agents/vercel-ai/README.md +++ b/examples/agents/vercel-ai/README.md @@ -168,7 +168,7 @@ await runtime.shutdown(); ## Running ```bash -export AGENTSPAN_SERVER_URL=... +export CONDUCTOR_SERVER_URL=... export OPENAI_API_KEY=... # from the repository root npx tsx examples/agents/vercel-ai/01-basic-agent.ts diff --git a/jest.e2e.config.mjs b/jest.e2e.config.mjs index 7ef48c0b..9962f95a 100644 --- a/jest.e2e.config.mjs +++ b/jest.e2e.config.mjs @@ -1,7 +1,7 @@ import baseConfig from "./jest.config.mjs"; /** - * Agent e2e suites (repo-root e2e/) against a live agentspan server. + * Agent e2e suites (repo-root e2e/) against a live conductor server. * Run with: npm run test:agent-e2e * Not matched by test/test:unit/test:integration globs — per-PR unit CI cost * is unchanged; the agent-e2e workflow runs these against the release JAR. diff --git a/scripts/package-e2e-bundle.sh b/scripts/package-e2e-bundle.sh index 80b4c6b8..bb6b25da 100755 --- a/scripts/package-e2e-bundle.sh +++ b/scripts/package-e2e-bundle.sh @@ -110,12 +110,11 @@ set -euo pipefail # agentspan.embedded=true). # # Required services (NOT started by this script): -# - Conductor server → AGENTSPAN_SERVER_URL (default http://localhost:8080/api) +# - Conductor server → CONDUCTOR_SERVER_URL (default http://localhost:8080/api) # - mcp-testkit → MCP_TESTKIT_URL (default http://localhost:3001) # Optional: -# - AGENTSPAN_LLM_MODEL (default openai/gpt-4o-mini); the provider API key +# - CONDUCTOR_AGENT_LLM_MODEL (default openai/gpt-4o-mini); the provider API key # must be configured on the SERVER — the suites never read it. -# - AGENTSPAN_CLI_PATH (default `agentspan` on PATH) — CLI suites skip if absent. # # Requires node >= 20. Usage: ./run.sh [extra jest args] HERE="$(cd "$(dirname "$0")" && pwd)" @@ -143,10 +142,9 @@ released from agentspan-ai/agentspan. | Requirement | Env var | Default | |-----------------------------------|------------------------|-----------------------------| | node >= 20 | — | — | -| Conductor server w/ agent runtime | `AGENTSPAN_SERVER_URL` | `http://localhost:8080/api` | -| LLM model | `AGENTSPAN_LLM_MODEL` | `openai/gpt-4o-mini` | +| Conductor server w/ agent runtime | `CONDUCTOR_SERVER_URL` | `http://localhost:8080/api` | +| LLM model | `CONDUCTOR_AGENT_LLM_MODEL` | `openai/gpt-4o-mini` | | mcp-testkit (MCP suites) | `MCP_TESTKIT_URL` | `http://localhost:3001` | -| agentspan CLI (CLI suites) | `AGENTSPAN_CLI_PATH` | `agentspan` (on `PATH`) | The server needs the agent runtime: conductor-oss `>= 3.32.0-rc.8`, or orkes-conductor booted with `agentspan.embedded=true`. LLM provider API keys diff --git a/src/agents/__tests__/config.test.ts b/src/agents/__tests__/config.test.ts index 357075a9..77e6e1c0 100644 --- a/src/agents/__tests__/config.test.ts +++ b/src/agents/__tests__/config.test.ts @@ -6,13 +6,13 @@ describe("AgentConfig", () => { // Save and restore env vars to avoid test pollution const savedEnv: Record = {}; const envKeys = [ - "AGENTSPAN_WORKER_POLL_INTERVAL", - "AGENTSPAN_WORKER_THREADS", - "AGENTSPAN_AUTO_START_WORKERS", - "AGENTSPAN_STREAMING_ENABLED", - "AGENTSPAN_LIVENESS_ENABLED", - "AGENTSPAN_LIVENESS_STALL_SECONDS", - "AGENTSPAN_LIVENESS_CHECK_INTERVAL_SECONDS", + "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", ]; beforeEach(() => { @@ -69,35 +69,35 @@ describe("AgentConfig", () => { }); describe("env var loading", () => { - it("reads all AGENTSPAN_ env vars", () => { - process.env.AGENTSPAN_WORKER_POLL_INTERVAL = "200"; - process.env.AGENTSPAN_WORKER_THREADS = "2"; - process.env.AGENTSPAN_AUTO_START_WORKERS = "false"; - process.env.AGENTSPAN_STREAMING_ENABLED = "false"; - process.env.AGENTSPAN_LIVENESS_ENABLED = "false"; - process.env.AGENTSPAN_LIVENESS_STALL_SECONDS = "60.5"; - process.env.AGENTSPAN_LIVENESS_CHECK_INTERVAL_SECONDS = "20.5"; + it("reads all CONDUCTOR_AGENT_ env vars", () => { + process.env.CONDUCTOR_AGENT_WORKER_POLL_INTERVAL = "300"; + process.env.CONDUCTOR_AGENT_WORKER_THREADS = "3"; + process.env.CONDUCTOR_AGENT_AUTO_START_WORKERS = "false"; + process.env.CONDUCTOR_AGENT_STREAMING_ENABLED = "false"; + process.env.CONDUCTOR_AGENT_LIVENESS_ENABLED = "false"; + process.env.CONDUCTOR_AGENT_LIVENESS_STALL_SECONDS = "70.5"; + process.env.CONDUCTOR_AGENT_LIVENESS_CHECK_INTERVAL_SECONDS = "25.5"; const config = new AgentConfig(); - expect(config.workerPollIntervalMs).toBe(200); - expect(config.workerThreadCount).toBe(2); + expect(config.workerPollIntervalMs).toBe(300); + expect(config.workerThreadCount).toBe(3); expect(config.autoStartWorkers).toBe(false); expect(config.streamingEnabled).toBe(false); expect(config.livenessEnabled).toBe(false); - expect(config.livenessStallSeconds).toBe(60.5); - expect(config.livenessCheckIntervalSeconds).toBe(20.5); + expect(config.livenessStallSeconds).toBe(70.5); + expect(config.livenessCheckIntervalSeconds).toBe(25.5); }); it("options override env vars", () => { - process.env.AGENTSPAN_WORKER_THREADS = "9"; + process.env.CONDUCTOR_AGENT_WORKER_THREADS = "9"; const config = new AgentConfig({ workerThreadCount: 3 }); expect(config.workerThreadCount).toBe(3); }); it("handles boolean env var variations", () => { - process.env.AGENTSPAN_AUTO_START_WORKERS = "1"; - process.env.AGENTSPAN_STREAMING_ENABLED = "no"; + process.env.CONDUCTOR_AGENT_AUTO_START_WORKERS = "1"; + process.env.CONDUCTOR_AGENT_STREAMING_ENABLED = "no"; const config = new AgentConfig(); @@ -106,8 +106,8 @@ describe("AgentConfig", () => { }); it("handles invalid numeric env vars gracefully", () => { - process.env.AGENTSPAN_WORKER_POLL_INTERVAL = "not-a-number"; - process.env.AGENTSPAN_WORKER_THREADS = ""; + process.env.CONDUCTOR_AGENT_WORKER_POLL_INTERVAL = "not-a-number"; + process.env.CONDUCTOR_AGENT_WORKER_THREADS = ""; const config = new AgentConfig(); @@ -116,19 +116,20 @@ describe("AgentConfig", () => { }); it("falls back to default when a liveness float env var is empty or invalid", () => { - process.env.AGENTSPAN_LIVENESS_STALL_SECONDS = ""; - process.env.AGENTSPAN_LIVENESS_CHECK_INTERVAL_SECONDS = "not-a-float"; + process.env.CONDUCTOR_AGENT_LIVENESS_STALL_SECONDS = ""; + process.env.CONDUCTOR_AGENT_LIVENESS_CHECK_INTERVAL_SECONDS = "not-a-float"; const config = new AgentConfig(); expect(config.livenessStallSeconds).toBe(30.0); expect(config.livenessCheckIntervalSeconds).toBe(10.0); }); + }); describe("fromEnv", () => { it("creates config from env vars only", () => { - process.env.AGENTSPAN_WORKER_THREADS = "6"; + process.env.CONDUCTOR_AGENT_WORKER_THREADS = "6"; const config = AgentConfig.fromEnv(); expect(config.workerThreadCount).toBe(6); }); diff --git a/src/agents/__tests__/runtime.test.ts b/src/agents/__tests__/runtime.test.ts index 5efeb16e..2f1560e7 100644 --- a/src/agents/__tests__/runtime.test.ts +++ b/src/agents/__tests__/runtime.test.ts @@ -116,12 +116,7 @@ const jsonResponse = (body: unknown, status = 200) => describe("AgentRuntime", () => { const savedEnv: Record = {}; - const envKeys = [ - "AGENTSPAN_SERVER_URL", - "AGENTSPAN_API_KEY", - "AGENTSPAN_AUTH_KEY", - "AGENTSPAN_AUTH_SECRET", - ]; + const envKeys = ["CONDUCTOR_SERVER_URL"]; function mockAgentServer(executionId = "wf-cred-test", fetchCalls?: string[]) { global.fetch = jest.fn().mockImplementation(async (url: string) => { @@ -890,7 +885,7 @@ describe("AgentRuntime", () => { describe("Singleton functions", () => { const savedEnv: Record = {}; - const envKeys = ["AGENTSPAN_SERVER_URL", "AGENTSPAN_API_KEY"]; + const envKeys = ["CONDUCTOR_SERVER_URL"]; beforeEach(() => { for (const key of envKeys) { diff --git a/src/agents/config.ts b/src/agents/config.ts index daf20a3e..8dd0abb1 100644 --- a/src/agents/config.ts +++ b/src/agents/config.ts @@ -60,27 +60,32 @@ export class AgentConfig { constructor(options?: AgentConfigOptions) { const env = process.env; + // Only CONDUCTOR_AGENT_* env vars are read -- no other fallback. this.workerPollIntervalMs = - options?.workerPollIntervalMs ?? parseIntEnv(env.AGENTSPAN_WORKER_POLL_INTERVAL, 100); + options?.workerPollIntervalMs ?? + parseIntEnv(env.CONDUCTOR_AGENT_WORKER_POLL_INTERVAL, 100); this.workerThreadCount = - options?.workerThreadCount ?? parseIntEnv(env.AGENTSPAN_WORKER_THREADS, 1); + options?.workerThreadCount ?? parseIntEnv(env.CONDUCTOR_AGENT_WORKER_THREADS, 1); this.autoStartWorkers = - options?.autoStartWorkers ?? parseBoolEnv(env.AGENTSPAN_AUTO_START_WORKERS, true); + options?.autoStartWorkers ?? + parseBoolEnv(env.CONDUCTOR_AGENT_AUTO_START_WORKERS, true); this.streamingEnabled = - options?.streamingEnabled ?? parseBoolEnv(env.AGENTSPAN_STREAMING_ENABLED, true); + options?.streamingEnabled ?? + parseBoolEnv(env.CONDUCTOR_AGENT_STREAMING_ENABLED, true); this.livenessEnabled = - options?.livenessEnabled ?? parseBoolEnv(env.AGENTSPAN_LIVENESS_ENABLED, true); + options?.livenessEnabled ?? parseBoolEnv(env.CONDUCTOR_AGENT_LIVENESS_ENABLED, true); this.livenessStallSeconds = - options?.livenessStallSeconds ?? parseFloatEnv(env.AGENTSPAN_LIVENESS_STALL_SECONDS, 30.0); + options?.livenessStallSeconds ?? + parseFloatEnv(env.CONDUCTOR_AGENT_LIVENESS_STALL_SECONDS, 30.0); this.livenessCheckIntervalSeconds = options?.livenessCheckIntervalSeconds ?? - parseFloatEnv(env.AGENTSPAN_LIVENESS_CHECK_INTERVAL_SECONDS, 10.0); + parseFloatEnv(env.CONDUCTOR_AGENT_LIVENESS_CHECK_INTERVAL_SECONDS, 10.0); } /** diff --git a/src/agents/errors.ts b/src/agents/errors.ts index 2b69184f..70244955 100644 --- a/src/agents/errors.ts +++ b/src/agents/errors.ts @@ -1,10 +1,10 @@ /** - * Base error for all Agentspan SDK errors. + * Base error for all Conductor agent SDK errors. */ -export class AgentspanError extends Error { +export class ConductorAgentError extends Error { constructor(message: string) { super(message); - this.name = "AgentspanError"; + this.name = "ConductorAgentError"; Object.setPrototypeOf(this, new.target.prototype); } } @@ -18,7 +18,7 @@ export class AgentspanError extends Error { * which 500 responses on /agent/start become impossible to triage from * CI logs alone. */ -export class AgentAPIError extends AgentspanError { +export class AgentAPIError extends ConductorAgentError { readonly statusCode: number; readonly responseBody: string; @@ -38,7 +38,7 @@ export class AgentAPIError extends AgentspanError { /** * Agent not found by name. */ -export class AgentNotFoundError extends AgentspanError { +export class AgentNotFoundError extends ConductorAgentError { readonly agentName: string; constructor(agentName: string) { @@ -52,7 +52,7 @@ export class AgentNotFoundError extends AgentspanError { /** * Configuration error — invalid or missing config values. */ -export class ConfigurationError extends AgentspanError { +export class ConfigurationError extends ConductorAgentError { constructor(message: string) { super(message); this.name = "ConfigurationError"; @@ -63,7 +63,7 @@ export class ConfigurationError extends AgentspanError { /** * Credential not found in the credential store. */ -export class CredentialNotFoundError extends AgentspanError { +export class CredentialNotFoundError extends ConductorAgentError { readonly credentialName: string; constructor(credentialName: string) { @@ -77,7 +77,7 @@ export class CredentialNotFoundError extends AgentspanError { /** * Credential authentication error — execution token invalid or expired. */ -export class CredentialAuthError extends AgentspanError { +export class CredentialAuthError extends ConductorAgentError { constructor(message = "Credential authentication failed") { super(message); this.name = "CredentialAuthError"; @@ -88,7 +88,7 @@ export class CredentialAuthError extends AgentspanError { /** * Credential rate limit exceeded (120 calls/min). */ -export class CredentialRateLimitError extends AgentspanError { +export class CredentialRateLimitError extends ConductorAgentError { constructor(message = "Credential rate limit exceeded") { super(message); this.name = "CredentialRateLimitError"; @@ -99,7 +99,7 @@ export class CredentialRateLimitError extends AgentspanError { /** * Credential service error — server-side failure. */ -export class CredentialServiceError extends AgentspanError { +export class CredentialServiceError extends ConductorAgentError { constructor(message = "Credential service error") { super(message); this.name = "CredentialServiceError"; @@ -110,7 +110,7 @@ export class CredentialServiceError extends AgentspanError { /** * SSE connection timeout — no events received within the timeout window. */ -export class SSETimeoutError extends AgentspanError { +export class SSETimeoutError extends ConductorAgentError { constructor(message = "SSE connection timed out") { super(message); this.name = "SSETimeoutError"; @@ -122,7 +122,7 @@ export class SSETimeoutError extends AgentspanError { * The server rejected the initial SSE connection (non-2xx) — it does not * support streaming for this route. Callers fall back to polling. */ -export class SSEUnavailableError extends AgentspanError { +export class SSEUnavailableError extends ConductorAgentError { constructor(message = "SSE stream is unavailable") { super(message); this.name = "SSEUnavailableError"; @@ -134,7 +134,7 @@ export class SSEUnavailableError extends AgentspanError { * Terminal tool error — non-retryable failure (e.g., CLI command exited non-zero). * Causes the Conductor task to be marked FAILED_WITH_TERMINAL_ERROR. */ -export class TerminalToolError extends AgentspanError { +export class TerminalToolError extends ConductorAgentError { constructor(message: string) { super(message); this.name = "TerminalToolError"; @@ -147,7 +147,7 @@ export class TerminalToolError extends AgentspanError { * for longer than the liveness stall window — the local worker process for * this run's domain likely died. Surfaces from a blocking `wait()`. */ -export class WorkerStallError extends AgentspanError { +export class WorkerStallError extends ConductorAgentError { readonly executionId: string; readonly taskDefName: string; readonly taskId: string; @@ -169,7 +169,7 @@ export class WorkerStallError extends AgentspanError { /** * Guardrail validation failed. */ -export class GuardrailFailedError extends AgentspanError { +export class GuardrailFailedError extends ConductorAgentError { readonly guardrailName: string; readonly failureMessage: string; diff --git a/src/agents/index.ts b/src/agents/index.ts index 25e0dfad..cba47486 100644 --- a/src/agents/index.ts +++ b/src/agents/index.ts @@ -31,7 +31,7 @@ export { createAgentResult, normalizeOutput, stripInternalEventKeys } from "./ty // ── Errors ─────────────────────────────────────────────── export { - AgentspanError, + ConductorAgentError, AgentAPIError, AgentNotFoundError, ConfigurationError, diff --git a/src/agents/runtime.ts b/src/agents/runtime.ts index 7137abf9..34a93e41 100644 --- a/src/agents/runtime.ts +++ b/src/agents/runtime.ts @@ -8,7 +8,7 @@ import type { GuardrailDef, FrameworkId, } from "./types.js"; -import { AgentspanError, AgentAPIError, WorkerStallError } from "./errors.js"; +import { ConductorAgentError, AgentAPIError, WorkerStallError } from "./errors.js"; import { LivenessMonitor } from "./liveness.js"; import { AgentConfig } from "./config.js"; import type { AgentConfigOptions } from "./config.js"; @@ -139,8 +139,8 @@ export class AgentRuntime { * @param configuration a connection config to build the shared client from, * or an already-built {@link ConductorClient} to reuse (the * `OrkesClients` injection pattern). Env-resolved when omitted - * (`AGENTSPAN_SERVER_URL`/`AGENTSPAN_AUTH_KEY`/`AGENTSPAN_AUTH_SECRET` - * fallbacks, `localhost:8080` default — spec R3). + * (`CONDUCTOR_SERVER_URL`/`CONDUCTOR_AUTH_KEY`/`CONDUCTOR_AUTH_SECRET`, + * `localhost:8080` default — spec R3). * @param settings behavior knobs only (spec R4) — no connection/auth here. */ constructor(configuration?: OrkesApiConfig | ConductorClient, settings?: AgentConfigOptions) { @@ -1515,7 +1515,7 @@ export class AgentRuntime { case "skill": return this._serializeSkill(agent as Agent); default: - throw new AgentspanError(`Unsupported framework: ${frameworkId}`); + throw new ConductorAgentError(`Unsupported framework: ${frameworkId}`); } } diff --git a/src/agents/stream.ts b/src/agents/stream.ts index f4056f0d..749ae412 100644 --- a/src/agents/stream.ts +++ b/src/agents/stream.ts @@ -1,6 +1,6 @@ import type { AgentEvent, AgentResult, AgentStatus } from "./types.js"; import { stripInternalEventKeys } from "./types.js"; -import { SSETimeoutError, SSEUnavailableError, AgentspanError } from "./errors.js"; +import { SSETimeoutError, SSEUnavailableError, ConductorAgentError } from "./errors.js"; import { makeAgentResult } from "./result.js"; // ── Constants ─────────────────────────────────────────── @@ -137,7 +137,7 @@ export class AgentStream implements AsyncIterable { } if (!response.body) { - throw new AgentspanError("SSE response has no body"); + throw new ConductorAgentError("SSE response has no body"); } const reader = response.body.getReader(); diff --git a/src/agents/tool.ts b/src/agents/tool.ts index b4b5ee3b..3633713b 100644 --- a/src/agents/tool.ts +++ b/src/agents/tool.ts @@ -830,8 +830,8 @@ export interface WaitForMessageToolOptions { * is empty and completes once messages arrive. In **non-blocking** mode, the * task returns immediately with whatever messages are in the queue. * - * Use {@link AgentRuntime.sendMessage} from outside the workflow to push a - * message into the queue. + * Pushing a message into the queue from outside the workflow is not yet + * exposed by this SDK's client. */ export function waitForMessageTool(opts: WaitForMessageToolOptions): ToolDef { const batchSize = opts.batchSize ?? 1; diff --git a/src/agents/worker.ts b/src/agents/worker.ts index f59610f8..bd370c36 100644 --- a/src/agents/worker.ts +++ b/src/agents/worker.ts @@ -342,7 +342,7 @@ export class WorkerManager { throw new NonRetryableException( `Required credentials not found: ${missing.join(", ")}. Server must persist ` + `TaskDef.runtimeMetadata and deliver Task.runtimeMetadata ` + - `(conductor-oss PR #1255 / agentspan server > 0.4.2).`, + `(conductor-oss PR #1255 / conductor server > 0.4.2).`, ); } resolvedCredentials = Object.fromEntries(pw.credentials.map((name) => [name, delivered[name]])); diff --git a/src/sdk/clients/agent/OrkesAgentClient.ts b/src/sdk/clients/agent/OrkesAgentClient.ts index 56af1976..43a9a3d5 100644 --- a/src/sdk/clients/agent/OrkesAgentClient.ts +++ b/src/sdk/clients/agent/OrkesAgentClient.ts @@ -98,8 +98,8 @@ export class OrkesAgentClient implements AgentClient { /** * Lazily create (once) and return the shared {@link ConductorClient}. * `createConductorClient` is async, so we memoize the promise. Env-resolved - * (`AGENTSPAN_SERVER_URL`/`AGENTSPAN_AUTH_KEY`/`AGENTSPAN_AUTH_SECRET` - * fallbacks, `localhost:8080` default) via `resolveOrkesConfig` (R3) when + * (`CONDUCTOR_SERVER_URL`/`CONDUCTOR_AUTH_KEY`/`CONDUCTOR_AUTH_SECRET`, + * `localhost:8080` default) via `resolveOrkesConfig` (R3) when * no explicit connection config was given. */ getClient(): Promise { diff --git a/src/sdk/createConductorClient/__tests__/createConductorClient.test.ts b/src/sdk/createConductorClient/__tests__/createConductorClient.test.ts index 2361acc6..357a62da 100644 --- a/src/sdk/createConductorClient/__tests__/createConductorClient.test.ts +++ b/src/sdk/createConductorClient/__tests__/createConductorClient.test.ts @@ -458,23 +458,6 @@ describe("createConductorClient integration", () => { expect(client.getConfig().baseUrl).toBe("http://localhost:8080"); }); - it("falls back to AGENTSPAN_SERVER_URL when CONDUCTOR_SERVER_URL and explicit config are absent (spec R3)", async () => { - process.env.AGENTSPAN_SERVER_URL = "http://agentspan-fallback:9090"; - const client = await createConductorClient({}, async () => jsonResponse({})); - expect(client.getConfig().baseUrl).toBe("http://agentspan-fallback:9090"); - delete process.env.AGENTSPAN_SERVER_URL; - }); - - it("explicit config wins over AGENTSPAN_SERVER_URL", async () => { - process.env.AGENTSPAN_SERVER_URL = "http://agentspan-fallback:9090"; - const client = await createConductorClient( - { serverUrl: "http://explicit:1234" }, - async () => jsonResponse({}) - ); - expect(client.getConfig().baseUrl).toBe("http://explicit:1234"); - delete process.env.AGENTSPAN_SERVER_URL; - }); - it("should resolve server URL from env var", async () => { process.env.CONDUCTOR_SERVER_URL = "http://env-server:8080"; const customFetch: typeof fetch = async () => jsonResponse({}); diff --git a/src/sdk/createConductorClient/helpers/__tests__/resolveOrkesConfig.test.ts b/src/sdk/createConductorClient/helpers/__tests__/resolveOrkesConfig.test.ts index 64ab5019..e3575d14 100644 --- a/src/sdk/createConductorClient/helpers/__tests__/resolveOrkesConfig.test.ts +++ b/src/sdk/createConductorClient/helpers/__tests__/resolveOrkesConfig.test.ts @@ -22,9 +22,6 @@ describe("resolveOrkesConfig", () => { "CONDUCTOR_PROXY_URL", "CONDUCTOR_TLS_INSECURE", "CONDUCTOR_DISABLE_HTTP2", - "AGENTSPAN_SERVER_URL", - "AGENTSPAN_AUTH_KEY", - "AGENTSPAN_AUTH_SECRET", ]; beforeEach(() => { @@ -77,55 +74,27 @@ describe("resolveOrkesConfig", () => { expect(result.serverUrl).toBe("http://localhost:8080"); }); - // ─── R3: CONDUCTOR_* -> explicit -> AGENTSPAN_* -> localhost:8080 ───── + // ─── CONDUCTOR_* -> explicit -> localhost:8080 ────────────────────── - it("defaults to http://localhost:8080 when nothing is set (spec R3)", () => { + it("defaults to http://localhost:8080 when nothing is set", () => { expect(resolveOrkesConfig({}).serverUrl).toBe("http://localhost:8080"); }); - it("falls back to AGENTSPAN_SERVER_URL when no CONDUCTOR_SERVER_URL/explicit config (spec R3)", () => { - process.env.AGENTSPAN_SERVER_URL = "http://agentspan:9090"; - expect(resolveOrkesConfig({}).serverUrl).toBe("http://agentspan:9090"); - }); - - it("explicit config wins over AGENTSPAN_SERVER_URL", () => { - process.env.AGENTSPAN_SERVER_URL = "http://agentspan:9090"; - expect(resolveOrkesConfig({ serverUrl: "http://explicit:1234" }).serverUrl).toBe( - "http://explicit:1234" - ); - }); - - it("CONDUCTOR_SERVER_URL wins over both explicit config and AGENTSPAN_SERVER_URL", () => { + it("CONDUCTOR_SERVER_URL wins over explicit config", () => { process.env.CONDUCTOR_SERVER_URL = "http://conductor-env:8080"; - process.env.AGENTSPAN_SERVER_URL = "http://agentspan:9090"; expect(resolveOrkesConfig({ serverUrl: "http://explicit:1234" }).serverUrl).toBe( "http://conductor-env:8080" ); }); }); - // ─── R3: auth key/secret AGENTSPAN_* fallback ─────────────────────── - - describe("auth key/secret AGENTSPAN_* fallback", () => { - it("falls back to AGENTSPAN_AUTH_KEY/SECRET when no CONDUCTOR_* env/explicit config", () => { - process.env.AGENTSPAN_AUTH_KEY = "agentspan-key"; - process.env.AGENTSPAN_AUTH_SECRET = "agentspan-secret"; - const result = resolveOrkesConfig({}); - expect(result.keyId).toBe("agentspan-key"); - expect(result.keySecret).toBe("agentspan-secret"); - }); - - it("explicit config wins over AGENTSPAN_AUTH_KEY/SECRET", () => { - process.env.AGENTSPAN_AUTH_KEY = "agentspan-key"; - const result = resolveOrkesConfig({ keyId: "explicit-key" }); - expect(result.keyId).toBe("explicit-key"); - }); - - it("CONDUCTOR_AUTH_KEY wins over both explicit config and AGENTSPAN_AUTH_KEY", () => { + describe("auth key/secret", () => { + it("CONDUCTOR_AUTH_KEY/SECRET win over explicit config", () => { process.env.CONDUCTOR_AUTH_KEY = "conductor-key"; - process.env.AGENTSPAN_AUTH_KEY = "agentspan-key"; - const result = resolveOrkesConfig({ keyId: "explicit-key" }); + process.env.CONDUCTOR_AUTH_SECRET = "conductor-secret"; + const result = resolveOrkesConfig({ keyId: "explicit-key", keySecret: "explicit-secret" }); expect(result.keyId).toBe("conductor-key"); + expect(result.keySecret).toBe("conductor-secret"); }); }); diff --git a/src/sdk/createConductorClient/helpers/resolveOrkesConfig.ts b/src/sdk/createConductorClient/helpers/resolveOrkesConfig.ts index a5abed4c..bdba1344 100644 --- a/src/sdk/createConductorClient/helpers/resolveOrkesConfig.ts +++ b/src/sdk/createConductorClient/helpers/resolveOrkesConfig.ts @@ -24,29 +24,16 @@ const parseEnvBoolean = (value: string | undefined): boolean | undefined => { export const resolveOrkesConfig = (config?: Partial) => { const logger = config?.logger ?? new DefaultLogger(); - // R3: CONDUCTOR_* env -> explicit config -> AGENTSPAN_* env (agent-layer - // fallback) -> localhost:8080 default. + // CONDUCTOR_* env -> explicit config -> localhost:8080 default. No + // other env var names are read. let serverUrl = - process.env.CONDUCTOR_SERVER_URL || - config?.serverUrl || - process.env.AGENTSPAN_SERVER_URL || - "http://localhost:8080"; + process.env.CONDUCTOR_SERVER_URL || config?.serverUrl || "http://localhost:8080"; if (serverUrl.endsWith("/")) serverUrl = serverUrl.slice(0, -1); if (serverUrl.endsWith("/api")) serverUrl = serverUrl.slice(0, -4); // Trim to avoid "Invalid Access Key" from trailing newlines when pasting into GitHub Secrets or .env - const keyId = ( - process.env.CONDUCTOR_AUTH_KEY || - config?.keyId || - process.env.AGENTSPAN_AUTH_KEY || - "" - ).trim(); - const keySecret = ( - process.env.CONDUCTOR_AUTH_SECRET || - config?.keySecret || - process.env.AGENTSPAN_AUTH_SECRET || - "" - ).trim(); + const keyId = (process.env.CONDUCTOR_AUTH_KEY || config?.keyId || "").trim(); + const keySecret = (process.env.CONDUCTOR_AUTH_SECRET || config?.keySecret || "").trim(); if (!process.env.CONDUCTOR_AUTH_KEY) { logger.debug("CONDUCTOR_AUTH_KEY is not set"); diff --git a/src/sdk/helpers/logger.ts b/src/sdk/helpers/logger.ts index b4e66937..26f6352c 100644 --- a/src/sdk/helpers/logger.ts +++ b/src/sdk/helpers/logger.ts @@ -31,9 +31,7 @@ export class DefaultLogger implements ConductorLogger { const {level, tags = []} = config this.tags = tags const resolvedLevel = - level ?? - (process.env.CONDUCTOR_LOG_LEVEL as ConductorLogLevel | undefined) ?? - (process.env.AGENTSPAN_LOG_LEVEL as ConductorLogLevel | undefined) + level ?? (process.env.CONDUCTOR_LOG_LEVEL as ConductorLogLevel | undefined) if (resolvedLevel && resolvedLevel in LOG_LEVELS) { this.level = LOG_LEVELS[resolvedLevel] } else {