From 8781a19a952c033d4ff496945fe69a13c190bb5c Mon Sep 17 00:00:00 2001 From: nicholascole Date: Tue, 21 Jul 2026 09:12:23 -0700 Subject: [PATCH] Remove superseded agentic-workflows examples; make example docs consistent The examples/agentic-workflows/ folder (5 hand-built LLM-system-task workflow examples) is superseded by the durable agents layer merged in 891bd06 - every scenario it demonstrated (tool calling, multi-agent chat, HITL, MCP) has a richer counterpart under examples/agents/. Delete it and repoint all references (README, examples/README, SDK_DEVELOPMENT, SDK_NEW_LANGUAGE_GUIDE) to the agents examples. Also make the docs consistent about example counts: - examples/agents/README.md catalog rebuilt to list all 111 core examples (65 were missing after the merge) organized by topic; removed a broken link to the nonexistent 27-user-proxy-agent.ts - all counts standardized to "200+" across README, CHANGELOG, SDK_DEVELOPMENT, SDK_NEW_LANGUAGE_GUIDE, and examples READMEs - stale workflow-example counts in SDK_DEVELOPMENT fixed (14 core / 9 api-journeys / 8 advanced) Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 2 +- README.md | 28 ++- SDK_DEVELOPMENT.md | 14 +- SDK_NEW_LANGUAGE_GUIDE.md | 19 +- examples/README.md | 33 ++- .../agentic-workflows/function-calling.ts | 214 ------------------ .../llm-chat-human-in-loop.ts | 138 ----------- examples/agentic-workflows/llm-chat.ts | 123 ---------- .../agentic-workflows/mcp-weather-agent.ts | 121 ---------- examples/agentic-workflows/multiagent-chat.ts | 181 --------------- examples/agents/README.md | 131 +++++++++-- 11 files changed, 168 insertions(+), 836 deletions(-) delete mode 100644 examples/agentic-workflows/function-calling.ts delete mode 100644 examples/agentic-workflows/llm-chat-human-in-loop.ts delete mode 100644 examples/agentic-workflows/llm-chat.ts delete mode 100644 examples/agentic-workflows/mcp-weather-agent.ts delete mode 100644 examples/agentic-workflows/multiagent-chat.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 79878488..d5a1b167 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- **Durable AI agents** -- the Agentspan TypeScript SDK (`@conductor-oss/conductor-agent-sdk`) is merged into this package as new subpath exports: `@io-orkes/conductor-javascript/agents` (core: `Agent`, `AgentRuntime`, `tool`, guardrails, handoffs, memory, schedules, streaming, HITL), `/agents/testing`, and framework wrappers `/agents/vercel-ai`, `/agents/langgraph`, `/agents/langchain`. The agent clients are also first-class citizens of the root export (`AgentClient`, `WorkflowClient`, `Schedule`, `ScheduleInfo`, schedule errors) — the root surface grows additively (minor). Docs at [docs/agents/](docs/agents/README.md); 60+ examples at [examples/agents/](examples/agents/). +- **Durable AI agents** -- the Agentspan TypeScript SDK (`@conductor-oss/conductor-agent-sdk`) is merged into this package as new subpath exports: `@io-orkes/conductor-javascript/agents` (core: `Agent`, `AgentRuntime`, `tool`, guardrails, handoffs, memory, schedules, streaming, HITL), `/agents/testing`, and framework wrappers `/agents/vercel-ai`, `/agents/langgraph`, `/agents/langchain`. The agent clients are also first-class citizens of the root export (`AgentClient`, `WorkflowClient`, `Schedule`, `ScheduleInfo`, schedule errors) — the root surface grows additively (minor). Docs at [docs/agents/](docs/agents/README.md); 200+ examples at [examples/agents/](examples/agents/). - **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. diff --git a/README.md b/README.md index cf040a71..8650a82f 100644 --- a/README.md +++ b/README.md @@ -459,7 +459,7 @@ See the [Examples Guide](examples/README.md) for the full catalog. Key examples: | [test-workflows.ts](examples/test-workflows.ts) | Unit testing with mock outputs (no workers) | `npx ts-node examples/test-workflows.ts` | | [metrics.ts](examples/metrics.ts) | Prometheus metrics + HTTP server on :9090 | `npx ts-node examples/metrics.ts` | | [express-worker-service.ts](examples/express-worker-service.ts) | Express.js + workers in one process | `npx ts-node examples/express-worker-service.ts` | -| [function-calling.ts](examples/agentic-workflows/function-calling.ts) | LLM dynamically picks which worker to call | `npx ts-node examples/agentic-workflows/function-calling.ts` | +| [02-tools.ts](examples/agents/02-tools.ts) | Durable agent: LLM dynamically picks which tool to call | `npx tsx examples/agents/02-tools.ts` | | [fork-join.ts](examples/advanced/fork-join.ts) | Parallel branches with join synchronization | `npx ts-node examples/advanced/fork-join.ts` | | [sub-workflows.ts](examples/advanced/sub-workflows.ts) | Workflow composition with sub-workflows | `npx ts-node examples/advanced/sub-workflows.ts` | | [human-tasks.ts](examples/advanced/human-tasks.ts) | Human-in-the-loop: claim, update, complete | `npx ts-node examples/advanced/human-tasks.ts` | @@ -518,18 +518,20 @@ const run = await workflow.execute({ question: "What is Conductor?" }); console.log(run.output?.answer); ``` -**Agentic Workflows** +**Agentic Examples** -Build AI agents where LLMs dynamically select and call TypeScript workers as tools. -See [examples/agentic-workflows/](examples/agentic-workflows/) for all examples. +To build AI agents where LLMs dynamically select and call tools, use the +durable agents layer (see [Durable AI Agents](#durable-ai-agents) below). +All agent examples live in [examples/agents/](examples/agents/); highlights: | Example | Description | |---------|-------------| -| [llm-chat.ts](examples/agentic-workflows/llm-chat.ts) | Automated multi-turn conversation between two LLMs | -| [llm-chat-human-in-loop.ts](examples/agentic-workflows/llm-chat-human-in-loop.ts) | Interactive chat with WAIT tasks for human input | -| [function-calling.ts](examples/agentic-workflows/function-calling.ts) | LLM dynamically picks which worker function to call | -| [mcp-weather-agent.ts](examples/agentic-workflows/mcp-weather-agent.ts) | MCP tool discovery and invocation for real-time data | -| [multiagent-chat.ts](examples/agentic-workflows/multiagent-chat.ts) | Multi-agent debate: optimist vs skeptic with moderator | +| [01-basic-agent.ts](examples/agents/01-basic-agent.ts) | Simplest possible agent: define, run, print result | +| [02-tools.ts](examples/agents/02-tools.ts) | LLM dynamically picks which tool to call, incl. approval-required tools | +| [03-multi-agent.ts](examples/agents/03-multi-agent.ts) | Multi-agent orchestration: sequential, parallel, handoffs | +| [04-mcp-weather.ts](examples/agents/04-mcp-weather.ts) | MCP tool discovery and invocation for real-time data | +| [09-human-in-the-loop.ts](examples/agents/09-human-in-the-loop.ts) | Agent pauses for human approval mid-run | +| [15-agent-discussion.ts](examples/agents/15-agent-discussion.ts) | Multi-turn debate between agents with opposing viewpoints | **RAG and Vector DB Workflows** @@ -572,9 +574,11 @@ testing toolkit (`/agents/testing`). - **Docs:** [docs/agents/](docs/agents/README.md) — start with [getting-started.md](docs/agents/getting-started.md) -- **Examples:** [examples/agents/](examples/agents/) — 60+ runnable examples, - from a basic agent to the full [kitchen sink](examples/agents/kitchen-sink.ts); - run them with `npx tsx examples/agents/01-basic-agent.ts` +- **Examples:** [examples/agents/](examples/agents/) — 200+ runnable examples + (core examples plus quickstart and framework ports for Google ADK, LangGraph, + OpenAI Agents SDK, and Vercel AI SDK), from a basic agent to the full + [kitchen sink](examples/agents/kitchen-sink.ts); run them with + `npx tsx examples/agents/01-basic-agent.ts` ## Documentation diff --git a/SDK_DEVELOPMENT.md b/SDK_DEVELOPMENT.md index 378e5925..5322deb1 100644 --- a/SDK_DEVELOPMENT.md +++ b/SDK_DEVELOPMENT.md @@ -603,16 +603,16 @@ Read in `resolveOrkesConfig.ts`. Env vars take precedence over config object val ## Examples -The `examples/` directory contains 32 runnable TypeScript files across 3 subdirectories, matching the Python SDK's examples structure. See [examples/README.md](examples/README.md) for the full catalog. +The `examples/` directory contains 31 runnable TypeScript files for the workflow/worker layer, plus 200+ durable AI-agent examples under `examples/agents/`. See [examples/README.md](examples/README.md) for the full catalog. ### Structure ``` examples/ -├── 13 core files # Workers, workflows, metrics, testing -├── agentic-workflows/ # 5 AI/LLM agent examples -├── api-journeys/ # 7 complete API lifecycle demos -└── advanced/ # 7 advanced workflow patterns +├── 14 core files # Workers, workflows, metrics, testing +├── agents/ # 200+ durable AI agent examples (see examples/agents/README.md) +├── api-journeys/ # 9 complete API lifecycle demos +└── advanced/ # 8 advanced workflow patterns ``` ### Conventions @@ -620,7 +620,7 @@ examples/ - **Self-contained**: Every file imports from `../src/sdk`, connects via `OrkesClients.from()`, and is runnable with `npx ts-node examples/.ts` - **Cleanup**: Examples that create resources clean up after themselves in try/finally blocks - **Env vars**: All examples read `CONDUCTOR_SERVER_URL` (required) and optionally `CONDUCTOR_AUTH_KEY`/`CONDUCTOR_AUTH_SECRET` -- **AI examples**: Use `LLM_PROVIDER` and `LLM_MODEL` env vars with defaults to `openai_integration` / `gpt-4o` +- **Agent examples**: `examples/agents/` uses `AGENTSPAN_SERVER_URL`/`AGENTSPAN_LLM_MODEL` plus a provider API key — see [examples/agents/README.md](examples/agents/README.md) - **Naming**: Kebab-case file names matching Python SDK's snake_case pattern (e.g., `fork-join.ts` ↔ `fork_join_script.py`) - **Imports**: Use relative paths from the example file (e.g., `from "../../src/sdk"` for subdirectory examples) @@ -665,8 +665,6 @@ examples/ | `api-journeys/metadata.ts` | `metadata_journey.py` | All metadata APIs | | `api-journeys/prompts.ts` | `prompt_journey.py` | All prompt APIs | | `api-journeys/schedules.ts` | `schedule_journey.py` | All schedule APIs | -| `agentic-workflows/function-calling.ts` | `agentic_workflows/function_calling_example.py` | LLM tool calling | -| `agentic-workflows/multiagent-chat.ts` | `agentic_workflows/multiagent_chat.py` | Multi-agent debate | | `advanced/rag-workflow.ts` | `rag_workflow.py` | RAG pipeline | | `advanced/fork-join.ts` | `orkes/fork_join_script.py` | Parallel execution | diff --git a/SDK_NEW_LANGUAGE_GUIDE.md b/SDK_NEW_LANGUAGE_GUIDE.md index c7f0ec5b..dd2dc2db 100644 --- a/SDK_NEW_LANGUAGE_GUIDE.md +++ b/SDK_NEW_LANGUAGE_GUIDE.md @@ -1417,7 +1417,7 @@ const wf = new ConductorWorkflow(executor, "my_workflow") ### Phase 7: Examples -**Goal:** 36 runnable example files demonstrating all SDK features. +**Goal:** 31 runnable example files demonstrating all SDK features. #### 7.1 Core Examples (14 files) @@ -1451,15 +1451,20 @@ const wf = new ConductorWorkflow(executor, "my_workflow") | `advanced/wait-for-webhook.ts` | Webhook wait pattern | | `advanced/human-tasks.ts` | Human-in-the-loop workflow | -#### 7.3 Agentic / AI Examples (5 files) +#### 7.3 Agentic / AI Examples + +Agentic examples (tool calling, multi-agent, human-in-the-loop, MCP) are +provided by the durable agents layer under `examples/agents/` in the JS SDK +(200+ examples) rather than as hand-built LLM-task workflows. If the new-language SDK includes +an agents layer, mirror that catalog — e.g.: | File | Demonstrates | |------|-------------| -| `agentic-workflows/function-calling.ts` | LLM tool/function calling | -| `agentic-workflows/multiagent-chat.ts` | Multi-agent debate | -| `agentic-workflows/llm-chat.ts` | LLM chat completion | -| `agentic-workflows/llm-chat-human-in-loop.ts` | Human-in-the-loop AI | -| `agentic-workflows/mcp-weather-agent.ts` | MCP tool integration | +| `agents/01-basic-agent.ts` | Basic LLM agent | +| `agents/02-tools.ts` | LLM tool/function calling | +| `agents/03-multi-agent.ts` | Multi-agent orchestration | +| `agents/09-human-in-the-loop.ts` | Human-in-the-loop AI | +| `agents/04-mcp-weather.ts` | MCP tool integration | #### 7.4 API Journey Examples (9 files) diff --git a/examples/README.md b/examples/README.md index 9137646a..ef1c0cf0 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,7 +2,7 @@ Quick reference for example files demonstrating SDK features. -> **Looking for the durable AI-agent examples?** They live in +> **Looking for the durable AI-agent examples?** All 200+ of them live in > [`agents/`](agents/) and demonstrate the `@io-orkes/conductor-javascript/agents` > layer (`Agent`, `AgentRuntime`, tools, guardrails, handoffs) — run them with > `npx tsx examples/agents/01-basic-agent.ts`. The examples in this directory @@ -44,17 +44,21 @@ npx ts-node examples/workers-e2e.ts | **[workflow-ops.ts](workflow-ops.ts)** | Lifecycle: start, pause, resume, terminate, restart, retry, search | `npx ts-node examples/workflow-ops.ts` | | **[test-workflows.ts](test-workflows.ts)** | Unit testing with mock task outputs (no workers needed) | `npx ts-node examples/test-workflows.ts` | -### AI/LLM Workflows +### AI Agents -Require an LLM integration configured in Conductor. Set `LLM_PROVIDER` and `LLM_MODEL` env vars. +Agentic examples live in [`agents/`](agents/) and use the durable agents layer +(`@io-orkes/conductor-javascript/agents`). See [agents/README.md](agents/README.md) +for the full catalog and environment setup (`AGENTSPAN_SERVER_URL`, +`AGENTSPAN_LLM_MODEL`, provider API key). Highlights: | File | Description | Run | |------|-------------|-----| -| **[agentic-workflows/llm-chat.ts](agentic-workflows/llm-chat.ts)** | Two LLMs in automated multi-turn conversation | `npx ts-node examples/agentic-workflows/llm-chat.ts` | -| **[agentic-workflows/llm-chat-human-in-loop.ts](agentic-workflows/llm-chat-human-in-loop.ts)** | Interactive chat with WAIT tasks for human input | `npx ts-node examples/agentic-workflows/llm-chat-human-in-loop.ts` | -| **[agentic-workflows/function-calling.ts](agentic-workflows/function-calling.ts)** | LLM dynamically picks which worker to call | `npx ts-node examples/agentic-workflows/function-calling.ts` | -| **[agentic-workflows/mcp-weather-agent.ts](agentic-workflows/mcp-weather-agent.ts)** | MCP tool discovery + invocation for real-time data | `npx ts-node examples/agentic-workflows/mcp-weather-agent.ts` | -| **[agentic-workflows/multiagent-chat.ts](agentic-workflows/multiagent-chat.ts)** | Multi-agent debate: optimist vs skeptic with moderator | `npx ts-node examples/agentic-workflows/multiagent-chat.ts` | +| **[agents/01-basic-agent.ts](agents/01-basic-agent.ts)** | Simplest possible agent: define, run, print result | `npx tsx examples/agents/01-basic-agent.ts` | +| **[agents/02-tools.ts](agents/02-tools.ts)** | LLM dynamically picks which tool to call | `npx tsx examples/agents/02-tools.ts` | +| **[agents/03-multi-agent.ts](agents/03-multi-agent.ts)** | Multi-agent orchestration: sequential, parallel, handoffs | `npx tsx examples/agents/03-multi-agent.ts` | +| **[agents/04-mcp-weather.ts](agents/04-mcp-weather.ts)** | MCP tool discovery + invocation for real-time data | `npx tsx examples/agents/04-mcp-weather.ts` | +| **[agents/09-human-in-the-loop.ts](agents/09-human-in-the-loop.ts)** | Agent pauses for human approval mid-run | `npx tsx examples/agents/09-human-in-the-loop.ts` | +| **[agents/15-agent-discussion.ts](agents/15-agent-discussion.ts)** | Multi-turn debate between agents with opposing viewpoints | `npx tsx examples/agents/15-agent-discussion.ts` | ### Monitoring @@ -302,9 +306,9 @@ npx ts-node examples/advanced/sub-workflows.ts npx ts-node examples/api-journeys/metadata.ts npx ts-node examples/api-journeys/authorization.ts -# 9. AI/LLM workflows (requires LLM integration) -npx ts-node examples/agentic-workflows/function-calling.ts -npx ts-node examples/agentic-workflows/multiagent-chat.ts +# 9. Durable AI agents (requires an LLM API key — see agents/README.md) +npx tsx examples/agents/01-basic-agent.ts +npx tsx examples/agents/02-tools.ts ``` --- @@ -327,12 +331,7 @@ examples/ ├── metrics.ts # Prometheus metrics + HTTP server ├── express-worker-service.ts # Express.js + workers integration │ -├── agentic-workflows/ # AI/LLM agent examples -│ ├── llm-chat.ts # Multi-turn automated AI conversation -│ ├── llm-chat-human-in-loop.ts # Interactive chat with WAIT pauses -│ ├── function-calling.ts # LLM-driven function routing -│ ├── mcp-weather-agent.ts # MCP tool discovery + invocation -│ └── multiagent-chat.ts # Multi-agent debate with moderator +├── agents/ # 200+ durable AI agent examples (see agents/README.md) │ ├── api-journeys/ # Complete API lifecycle demos │ ├── authorization.ts # Users, groups, permissions (17 calls) diff --git a/examples/agentic-workflows/function-calling.ts b/examples/agentic-workflows/function-calling.ts deleted file mode 100644 index 7b20d445..00000000 --- a/examples/agentic-workflows/function-calling.ts +++ /dev/null @@ -1,214 +0,0 @@ -/** - * Function Calling — LLM dynamically invokes worker functions - * - * Demonstrates the agentic pattern where an LLM decides which tool/function - * to call based on user input. Uses llmChatCompleteTask with tool definitions - * and a dynamic task to execute the chosen function. - * - * Prerequisites: - * - An LLM integration configured in Conductor - * - * Run: - * CONDUCTOR_SERVER_URL=http://localhost:8080 npx ts-node examples/agentic-workflows/function-calling.ts - */ -import { - OrkesClients, - ConductorWorkflow, - TaskHandler, - worker, - llmChatCompleteTask, - simpleTask, - switchTask, - inlineTask, - Role, -} from "../../src/sdk"; -import type { Task } from "../../src/open-api"; - -// ── Tool workers ──────────────────────────────────────────────────── -const _getWeather = worker({ taskDefName: "fn_get_weather", registerTaskDef: true })( - async (task: Task) => { - const city = (task.inputData?.city as string) ?? "Unknown"; - // Simulate weather API - const weather = { - city, - temperature: Math.round(15 + Math.random() * 20), - condition: ["Sunny", "Cloudy", "Rainy", "Windy"][ - Math.floor(Math.random() * 4) - ], - humidity: Math.round(30 + Math.random() * 50), - }; - return { status: "COMPLETED", outputData: weather }; - } -); - -const _getStockPrice = worker({ taskDefName: "fn_get_stock_price", registerTaskDef: true })( - async (task: Task) => { - const symbol = (task.inputData?.symbol as string) ?? "AAPL"; - // Simulate stock API - const price = { - symbol, - price: Math.round(100 + Math.random() * 200 * 100) / 100, - change: Math.round((Math.random() * 10 - 5) * 100) / 100, - currency: "USD", - }; - return { status: "COMPLETED", outputData: price }; - } -); - -const _calculate = worker({ taskDefName: "fn_calculate", registerTaskDef: true })( - async (task: Task) => { - const expression = (task.inputData?.expression as string) ?? "0"; - let result: number; - try { - // Simple safe evaluation (in production, use a proper math parser) - result = Function(`"use strict"; return (${expression})`)(); - } catch { - return { - status: "FAILED", - outputData: { error: `Invalid expression: ${expression}` }, - }; - } - return { status: "COMPLETED", outputData: { expression, result } }; - } -); - -// ── Main ──────────────────────────────────────────────────────────── -async function main() { - const clients = await OrkesClients.from(); - const workflowClient = clients.getWorkflowClient(); - const client = clients.getClient(); - - const provider = process.env.LLM_PROVIDER ?? "openai_integration"; - const model = process.env.LLM_MODEL ?? "gpt-4o"; - - // ── Build the agentic workflow ──────────────────────────────────── - const wf = new ConductorWorkflow(workflowClient, "function_calling_example") - .description("LLM picks which function to call based on user query"); - - // Step 1: LLM decides which function to call - wf.add( - llmChatCompleteTask("decide_ref", provider, model, { - messages: [ - { - role: Role.SYSTEM, - message: `You are a helpful assistant with access to these tools: -1. get_weather(city: string) - Get current weather for a city -2. get_stock_price(symbol: string) - Get current stock price -3. calculate(expression: string) - Evaluate a math expression - -Based on the user's query, respond with ONLY a JSON object: -{"function": "", "args": {"": ""}}`, - }, - { - role: Role.USER, - message: "${workflow.input.query}", - }, - ], - temperature: 0, - maxTokens: 200, - }) - ); - - // Step 2: Parse LLM response - wf.add( - inlineTask( - "parse_ref", - `(function() { - var text = $.decide_ref.output.result; - try { - var parsed = JSON.parse(text); - return parsed; - } catch(e) { - return { function: "unknown", args: {} }; - } - })()`, - "javascript" - ) - ); - - // Step 3: Route to the appropriate function - wf.add( - switchTask( - "route_ref", - "${parse_ref.output.result.function}", - { - get_weather: [ - simpleTask("weather_ref", "fn_get_weather", { - city: "${parse_ref.output.result.args.city}", - }), - ], - get_stock_price: [ - simpleTask("stock_ref", "fn_get_stock_price", { - symbol: "${parse_ref.output.result.args.symbol}", - }), - ], - calculate: [ - simpleTask("calc_ref", "fn_calculate", { - expression: "${parse_ref.output.result.args.expression}", - }), - ], - }, - [ - inlineTask( - "unknown_ref", - '(function() { return { error: "Unknown function requested" }; })()', - "javascript" - ), - ] - ) - ); - - // Step 4: LLM summarizes the result - wf.add( - llmChatCompleteTask("summarize_ref", provider, model, { - messages: [ - { - role: Role.SYSTEM, - message: "Summarize the tool result in a natural, conversational way.", - }, - { - role: Role.USER, - message: - 'User asked: "${workflow.input.query}". Tool result: ${route_ref.output}', - }, - ], - temperature: 0.5, - maxTokens: 200, - }) - ); - - wf.outputParameters({ - query: "${workflow.input.query}", - functionCalled: "${parse_ref.output.result.function}", - summary: "${summarize_ref.output.result}", - }); - - await wf.register(true); - console.log("Registered workflow:", wf.getName()); - - // Start workers - const handler = new TaskHandler({ client, scanForDecorated: true }); - await handler.startWorkers(); - - // Execute with different queries - const queries = [ - "What's the weather like in Tokyo?", - "What's the current price of TSLA stock?", - "Calculate 42 * 17 + 3", - ]; - - for (const query of queries) { - console.log(`\nQuery: "${query}"`); - const run = await wf.execute({ query }); - console.log("Status:", run.status); - console.log("Output:", JSON.stringify(run.output, null, 2)); - } - - await handler.stopWorkers(); - process.exit(0); -} - -main().catch((err) => { - console.error(err); - process.exit(1); -}); diff --git a/examples/agentic-workflows/llm-chat-human-in-loop.ts b/examples/agentic-workflows/llm-chat-human-in-loop.ts deleted file mode 100644 index a526c5e0..00000000 --- a/examples/agentic-workflows/llm-chat-human-in-loop.ts +++ /dev/null @@ -1,138 +0,0 @@ -/** - * LLM Chat with Human-in-the-Loop — Interactive chat with WAIT pauses - * - * Demonstrates an LLM chat where the workflow pauses (WAIT task) for - * human input between turns. The user updates the waiting task to continue. - * - * Prerequisites: - * - An LLM integration configured in Conductor - * - * Run: - * CONDUCTOR_SERVER_URL=http://localhost:8080 npx ts-node examples/agentic-workflows/llm-chat-human-in-loop.ts - */ -import { - OrkesClients, - ConductorWorkflow, - llmChatCompleteTask, - waitTaskDuration, - Role, -} from "../../src/sdk"; - -async function main() { - const clients = await OrkesClients.from(); - const workflowClient = clients.getWorkflowClient(); - const taskClient = clients.getTaskClient(); - - const provider = process.env.LLM_PROVIDER ?? "openai_integration"; - const model = process.env.LLM_MODEL ?? "gpt-4o"; - - // ── Define workflow with WAIT for human input ───────────────────── - const wf = new ConductorWorkflow( - workflowClient, - "llm_chat_human_in_loop" - ) - .description("Interactive LLM chat with human-in-the-loop WAIT tasks") - .timeoutSeconds(3600); - - // Initial LLM greeting - wf.add( - llmChatCompleteTask("greeting_ref", provider, model, { - messages: [ - { - role: Role.SYSTEM, - message: - "You are a helpful assistant. Greet the user and ask how you can help them today. Be concise.", - }, - { - role: Role.USER, - message: "Topic: ${workflow.input.topic}", - }, - ], - temperature: 0.7, - maxTokens: 200, - }) - ); - - // Wait for human response (external signal) - wf.add(waitTaskDuration("human_input_ref", "300s")); - - // LLM responds to human input - wf.add( - llmChatCompleteTask("response_ref", provider, model, { - messages: [ - { - role: Role.SYSTEM, - message: "You are a helpful assistant. Respond to the user's message concisely.", - }, - { - role: Role.ASSISTANT, - message: "${greeting_ref.output.result}", - }, - { - role: Role.USER, - message: "${human_input_ref.output.userMessage}", - }, - ], - temperature: 0.7, - maxTokens: 300, - }) - ); - - wf.outputParameters({ - greeting: "${greeting_ref.output.result}", - userMessage: "${human_input_ref.output.userMessage}", - response: "${response_ref.output.result}", - }); - - await wf.register(true); - console.log("Registered workflow:", wf.getName()); - - // ── Start workflow (async — it will pause at WAIT) ──────────────── - const workflowId = await wf.startWorkflow({ - topic: "TypeScript best practices", - }); - console.log("Started workflow:", workflowId); - console.log("Workflow will pause at WAIT task for human input..."); - - // Wait for workflow to reach the WAIT task - await new Promise((resolve) => setTimeout(resolve, 5000)); - - // Check status - const status = await workflowClient.getWorkflow(workflowId, true); - console.log("Current status:", status.status); - - // Find the waiting task - const waitingTask = status.tasks?.find( - (t) => t.taskDefName === "WAIT" && t.status === "IN_PROGRESS" - ); - - if (waitingTask?.taskId) { - console.log("\nSimulating human input..."); - - // Update the WAIT task with human input - await taskClient.updateTaskResult( - workflowId, - "human_input_ref", - "COMPLETED", - { userMessage: "Tell me about async/await patterns in TypeScript" } - ); - - console.log("Human input provided. Workflow continuing..."); - - // Wait for completion - await new Promise((resolve) => setTimeout(resolve, 10000)); - - const finalStatus = await workflowClient.getWorkflow(workflowId, true); - console.log("\nFinal status:", finalStatus.status); - console.log("Output:", JSON.stringify(finalStatus.output, null, 2)); - } else { - console.log("WAIT task not found. Workflow may have completed or failed."); - } - - process.exit(0); -} - -main().catch((err) => { - console.error(err); - process.exit(1); -}); diff --git a/examples/agentic-workflows/llm-chat.ts b/examples/agentic-workflows/llm-chat.ts deleted file mode 100644 index 9ccc743d..00000000 --- a/examples/agentic-workflows/llm-chat.ts +++ /dev/null @@ -1,123 +0,0 @@ -/** - * LLM Chat — Multi-turn automated AI conversation - * - * Demonstrates two LLMs having a multi-turn conversation using - * llmChatCompleteTask in a do-while loop. One acts as an interviewer, - * the other as a subject matter expert. - * - * Prerequisites: - * - An LLM integration configured in Conductor (e.g., "openai_integration") - * - A model available (e.g., "gpt-4o") - * - * Run: - * CONDUCTOR_SERVER_URL=http://localhost:8080 npx ts-node examples/agentic-workflows/llm-chat.ts - */ -import { - OrkesClients, - ConductorWorkflow, - llmChatCompleteTask, - inlineTask, - setVariableTask, - Role, -} from "../../src/sdk"; - -async function main() { - const clients = await OrkesClients.from(); - const workflowClient = clients.getWorkflowClient(); - - const provider = process.env.LLM_PROVIDER ?? "openai_integration"; - const model = process.env.LLM_MODEL ?? "gpt-4o"; - - const wf = new ConductorWorkflow(workflowClient, "llm_chat_example") - .description("Two LLMs having a multi-turn conversation") - .variables({ turnCount: 0, conversation: [] }); - - // Initialize conversation with a topic - wf.add( - setVariableTask("init_ref", { - turnCount: 0, - topic: "${workflow.input.topic}", - }) - ); - - // Interviewer asks a question - wf.add( - llmChatCompleteTask("interviewer_ref", provider, model, { - messages: [ - { - role: Role.SYSTEM, - message: - "You are a curious interviewer. Ask thoughtful, concise questions about the topic. Keep responses under 100 words.", - }, - { - role: Role.USER, - message: - "Topic: ${workflow.input.topic}. This is turn ${init_ref.output.turnCount}. Ask your next question.", - }, - ], - temperature: 0.7, - maxTokens: 200, - }) - ); - - // Expert responds - wf.add( - llmChatCompleteTask("expert_ref", provider, model, { - messages: [ - { - role: Role.SYSTEM, - message: - "You are a subject matter expert. Give clear, informative answers. Keep responses under 150 words.", - }, - { - role: Role.USER, - message: "${interviewer_ref.output.result}", - }, - ], - temperature: 0.5, - maxTokens: 300, - }) - ); - - // Track conversation turns - wf.add( - inlineTask( - "track_ref", - `(function() { - var turn = ($.init_ref ? $.init_ref.output.turnCount : 0) + 1; - return { - turnCount: turn, - interviewer: $.interviewer_ref.output.result, - expert: $.expert_ref.output.result, - done: turn >= $.maxTurns - }; - })()`, - "javascript" - ) - ); - - wf.outputParameters({ - topic: "${workflow.input.topic}", - turns: "${track_ref.output.result.turnCount}", - lastQuestion: "${interviewer_ref.output.result}", - lastAnswer: "${expert_ref.output.result}", - }); - - await wf.register(true); - console.log("Registered workflow:", wf.getName()); - - // Execute - const run = await wf.execute({ - topic: "The future of quantum computing", - maxTurns: 3, - }); - - console.log("Status:", run.status); - console.log("Output:", JSON.stringify(run.output, null, 2)); - process.exit(0); -} - -main().catch((err) => { - console.error(err); - process.exit(1); -}); diff --git a/examples/agentic-workflows/mcp-weather-agent.ts b/examples/agentic-workflows/mcp-weather-agent.ts deleted file mode 100644 index 15f2f807..00000000 --- a/examples/agentic-workflows/mcp-weather-agent.ts +++ /dev/null @@ -1,121 +0,0 @@ -/** - * MCP Weather Agent — Using MCP tools for real-time data - * - * Demonstrates listMcpToolsTask and callMcpToolTask to discover and invoke - * MCP (Model Context Protocol) server tools from within a workflow. - * - * Prerequisites: - * - An MCP server integration configured in Conductor - * - The MCP server exposes weather-related tools - * - * Run: - * CONDUCTOR_SERVER_URL=http://localhost:8080 npx ts-node examples/agentic-workflows/mcp-weather-agent.ts - */ -import { - OrkesClients, - ConductorWorkflow, - listMcpToolsTask, - callMcpToolTask, - llmChatCompleteTask, - inlineTask, - Role, -} from "../../src/sdk"; - -async function main() { - const clients = await OrkesClients.from(); - const workflowClient = clients.getWorkflowClient(); - - const mcpServer = process.env.MCP_SERVER ?? "weather_mcp_server"; - const provider = process.env.LLM_PROVIDER ?? "openai_integration"; - const model = process.env.LLM_MODEL ?? "gpt-4o"; - - const wf = new ConductorWorkflow(workflowClient, "mcp_weather_agent") - .description("Uses MCP tools to fetch weather data and summarize with LLM"); - - // Step 1: List available MCP tools - wf.add(listMcpToolsTask("list_tools_ref", mcpServer)); - - // Step 2: Log available tools - wf.add( - inlineTask( - "log_tools_ref", - `(function() { - var tools = $.list_tools_ref.output.result || []; - return { - toolCount: tools.length, - toolNames: tools.map(function(t) { return t.name; }) - }; - })()`, - "javascript" - ) - ); - - // Step 3: Call the weather tool - wf.add( - callMcpToolTask("get_weather_ref", mcpServer, "get_current_weather", { - inputParameters: { - city: "${workflow.input.city}", - units: "${workflow.input.units}", - }, - }) - ); - - // Step 4: Call forecast tool - wf.add( - callMcpToolTask("get_forecast_ref", mcpServer, "get_forecast", { - inputParameters: { - city: "${workflow.input.city}", - days: 3, - }, - }) - ); - - // Step 5: LLM summarizes weather data - wf.add( - llmChatCompleteTask("summarize_ref", provider, model, { - messages: [ - { - role: Role.SYSTEM, - message: - "You are a weather assistant. Summarize the weather data in a friendly, concise format.", - }, - { - role: Role.USER, - message: `City: \${workflow.input.city} -Current weather: \${get_weather_ref.output.result} -3-day forecast: \${get_forecast_ref.output.result} - -Please provide a brief weather summary.`, - }, - ], - temperature: 0.5, - maxTokens: 300, - }) - ); - - wf.outputParameters({ - city: "${workflow.input.city}", - availableTools: "${log_tools_ref.output.result.toolNames}", - currentWeather: "${get_weather_ref.output.result}", - forecast: "${get_forecast_ref.output.result}", - summary: "${summarize_ref.output.result}", - }); - - await wf.register(true); - console.log("Registered workflow:", wf.getName()); - - // Execute - const run = await wf.execute({ - city: "San Francisco", - units: "fahrenheit", - }); - - console.log("Status:", run.status); - console.log("Output:", JSON.stringify(run.output, null, 2)); - process.exit(0); -} - -main().catch((err) => { - console.error(err); - process.exit(1); -}); diff --git a/examples/agentic-workflows/multiagent-chat.ts b/examples/agentic-workflows/multiagent-chat.ts deleted file mode 100644 index db479cf6..00000000 --- a/examples/agentic-workflows/multiagent-chat.ts +++ /dev/null @@ -1,181 +0,0 @@ -/** - * Multi-Agent Chat — Multiple LLM agents debate a topic - * - * Demonstrates a multi-agent architecture where: - * - An "optimist" agent argues for a position - * - A "skeptic" agent argues against - * - A "moderator" summarizes and decides the winner - * - * Uses switchTask to route between agents and doWhileTask for rounds. - * - * Prerequisites: - * - An LLM integration configured in Conductor - * - * Run: - * CONDUCTOR_SERVER_URL=http://localhost:8080 npx ts-node examples/agentic-workflows/multiagent-chat.ts - */ -import { - OrkesClients, - ConductorWorkflow, - llmChatCompleteTask, - setVariableTask, - Role, -} from "../../src/sdk"; - -async function main() { - const clients = await OrkesClients.from(); - const workflowClient = clients.getWorkflowClient(); - - const provider = process.env.LLM_PROVIDER ?? "openai_integration"; - const model = process.env.LLM_MODEL ?? "gpt-4o"; - - const wf = new ConductorWorkflow(workflowClient, "multiagent_chat_example") - .description("Multi-agent debate: optimist vs skeptic with moderator"); - - // Initialize - wf.add( - setVariableTask("init_ref", { - round: 0, - topic: "${workflow.input.topic}", - }) - ); - - // Round 1: Optimist opens - wf.add( - llmChatCompleteTask("optimist_ref", provider, model, { - messages: [ - { - role: Role.SYSTEM, - message: - "You are an optimistic debater. Present a compelling positive argument for the topic. Be concise (under 150 words).", - }, - { - role: Role.USER, - message: "Topic: ${workflow.input.topic}. Make your opening argument.", - }, - ], - temperature: 0.7, - maxTokens: 300, - }) - ); - - // Round 1: Skeptic responds - wf.add( - llmChatCompleteTask("skeptic_ref", provider, model, { - messages: [ - { - role: Role.SYSTEM, - message: - "You are a skeptical debater. Counter the optimist's argument with evidence-based concerns. Be concise (under 150 words).", - }, - { - role: Role.USER, - message: - 'Topic: ${workflow.input.topic}. The optimist argued: "${optimist_ref.output.result}". Counter this argument.', - }, - ], - temperature: 0.7, - maxTokens: 300, - }) - ); - - // Round 2: Optimist rebuts - wf.add( - llmChatCompleteTask("optimist_rebuttal_ref", provider, model, { - messages: [ - { - role: Role.SYSTEM, - message: - "You are an optimistic debater. Address the skeptic's concerns and strengthen your position. Be concise (under 150 words).", - }, - { - role: Role.USER, - message: - 'Your opening: "${optimist_ref.output.result}". Skeptic countered: "${skeptic_ref.output.result}". Provide your rebuttal.', - }, - ], - temperature: 0.7, - maxTokens: 300, - }) - ); - - // Round 2: Skeptic rebuts - wf.add( - llmChatCompleteTask("skeptic_rebuttal_ref", provider, model, { - messages: [ - { - role: Role.SYSTEM, - message: - "You are a skeptical debater. Give your final counter-argument. Be concise (under 150 words).", - }, - { - role: Role.USER, - message: - 'Your counter: "${skeptic_ref.output.result}". Optimist rebutted: "${optimist_rebuttal_ref.output.result}". Final response.', - }, - ], - temperature: 0.7, - maxTokens: 300, - }) - ); - - // Moderator judges - wf.add( - llmChatCompleteTask("moderator_ref", provider, model, { - messages: [ - { - role: Role.SYSTEM, - message: - "You are an impartial debate moderator. Summarize both sides, declare a winner with reasoning, and provide a balanced conclusion. Keep it under 200 words.", - }, - { - role: Role.USER, - message: `Topic: \${workflow.input.topic} - -Optimist's opening: "\${optimist_ref.output.result}" -Skeptic's counter: "\${skeptic_ref.output.result}" -Optimist's rebuttal: "\${optimist_rebuttal_ref.output.result}" -Skeptic's rebuttal: "\${skeptic_rebuttal_ref.output.result}" - -Please judge this debate.`, - }, - ], - temperature: 0.3, - maxTokens: 400, - }) - ); - - wf.outputParameters({ - topic: "${workflow.input.topic}", - optimistOpening: "${optimist_ref.output.result}", - skepticCounter: "${skeptic_ref.output.result}", - optimistRebuttal: "${optimist_rebuttal_ref.output.result}", - skepticRebuttal: "${skeptic_rebuttal_ref.output.result}", - moderatorVerdict: "${moderator_ref.output.result}", - }); - - await wf.register(true); - console.log("Registered workflow:", wf.getName()); - - const run = await wf.execute({ - topic: - process.argv[2] ?? "Should AI be used to make hiring decisions?", - }); - - console.log("Status:", run.status); - const output = run.output as Record; - console.log("\n=== DEBATE ==="); - console.log(`Topic: ${output?.topic}`); - console.log(`\n[Optimist] ${output?.optimistOpening}`); - console.log(`\n[Skeptic] ${output?.skepticCounter}`); - console.log(`\n[Optimist Rebuttal] ${output?.optimistRebuttal}`); - console.log(`\n[Skeptic Rebuttal] ${output?.skepticRebuttal}`); - console.log(`\n[MODERATOR VERDICT] ${output?.moderatorVerdict}`); - - process.exit(0); -} - -main().catch((err) => { - console.error(err); - process.exit(1); -}); diff --git a/examples/agents/README.md b/examples/agents/README.md index 07a48c7f..eef8ae93 100644 --- a/examples/agents/README.md +++ b/examples/agents/README.md @@ -2,6 +2,10 @@ Runnable examples demonstrating every feature of the Agentspan TypeScript SDK. +**200+ runnable examples in total**: the core examples cataloged below, plus +the [quickstart/](quickstart/) guides and framework ports for Google ADK, +LangGraph, OpenAI Agents SDK, and Vercel AI SDK. + --- ## Examples vs. Production @@ -149,8 +153,9 @@ cd examples/agents/openai && npx tsx 01-basic-agent.ts |---|---------|---------------------| | 01 | [Basic Agent](01-basic-agent.ts) | Simplest possible agent — single LLM, no tools | | 02 | [Tools](02-tools.ts) | Multiple `tool()` functions, approval-required tools | +| — | [Kitchen Sink](kitchen-sink.ts) | Content publishing platform — every major feature in one example | -## Tool Calling +## Tool Calling & Structured Output | # | Example | What it demonstrates | |---|---------|---------------------| @@ -159,14 +164,20 @@ cd examples/agents/openai && npx tsx 01-basic-agent.ts | 03 | [Structured Output](03-structured-output.ts) | Zod `outputType` for typed, validated responses | | 04 | [HTTP & MCP Tools](04-http-and-mcp-tools.ts) | Server-side tools via `httpTool()` and `mcpTool()` — no workers needed | | 04b | [MCP Weather](04-mcp-weather.ts) | Real-time weather via an MCP server | +| 09 | [Structured Output (agent run)](09-structured-output.ts) | Zod schema as `outputType` — typed result from a full agent run | | 14 | [Existing Workers](14-existing-workers.ts) | Use existing worker task functions directly as agent tools | | 33 | [Single Turn Tool](33-single-turn-tool.ts) | Single-turn tool invocation with immediate response | | 33 | [External Workers](33-external-workers.ts) | Reference workers in other services — no local code needed | +| 45 | [Agent Tool](45-agent-tool.ts) | Invoke a child agent inline as a function call (vs handoff) | +| 51 | [Shared State](51-shared-state.ts) | Tools sharing state across calls via `ToolContext` | +| 71 | [API Tool](71-api-tool.ts) | Auto-discover endpoints from OpenAPI, Swagger, or Postman specs | +| 74 | [CLI Error Output](74-cli-error-output.ts) | Agent sees stdout/stderr when a CLI tool exits non-zero | ## Multi-Agent Orchestration | # | Example | Pattern | |---|---------|---------| +| 03 | [Multi-Agent](03-multi-agent.ts) | Three strategies in one file: sequential, parallel, handoff | | 05 | [Handoffs](05-handoffs.ts) | LLM-driven delegation to sub-agents | | 06 | [Sequential Pipeline](06-sequential-pipeline.ts) | Agents run in order, output chains forward | | 07 | [Parallel Agents](07-parallel-agents.ts) | All agents run concurrently, results aggregated | @@ -176,24 +187,34 @@ cd examples/agents/openai && npx tsx 01-basic-agent.ts | 16 | [Random Strategy](16-random-strategy.ts) | Random agent selected each turn (brainstorming) | | 17 | [Swarm Orchestration](17-swarm-orchestration.ts) | Automatic transitions via handoff conditions | | 18 | [Manual Selection](18-manual-selection.ts) | Human picks which agent speaks each turn | +| 19 | [Composable Termination](19-composable-termination.ts) | AND/OR rules for stopping multi-agent runs | | 20 | [Constrained Transitions](20-constrained-transitions.ts) | Restrict which agents can follow which | | 29 | [Agent Introductions](29-agent-introductions.ts) | Agents introduce themselves before a group discussion | | 38 | [Tech Trends](38-tech-trends.ts) | Multi-agent research pipeline with live HTTP API tools | +| 41 | [Sequential Pipeline with Tools](41-sequential-pipeline-tools.ts) | Stage-level tools in a pipeline | +| 46 | [Transfer Control](46-transfer-control.ts) | Constrained handoff paths between sub-agents | +| 52 | [Nested Strategies](52-nested-strategies.ts) | Parallel agents inside a sequential pipeline | +| 58 | [Scatter-Gather](58-scatter-gather.ts) | Massive parallel multi-agent orchestration | +| 64 | [Swarm with Tools](64-swarm-with-tools.ts) | Sub-agents with their own domain tools | +| 65 | [Parallel with Tools](65-parallel-with-tools.ts) | Each parallel branch has its own tools | +| 66 | [Handoff to Parallel](66-handoff-to-parallel.ts) | Delegate to a multi-agent group | +| 67 | [Router to Sequential](67-router-to-sequential.ts) | Route to a pipeline sub-agent | ## Human-in-the-Loop | # | Example | What it demonstrates | |---|---------|---------------------| +| 06 | [HITL Basics](06-hitl.ts) | Approval-required tool with interactive console prompts | | 09 | [Human-in-the-Loop](09-human-in-the-loop.ts) | Tool approval gate — approve or reject before execution | | 09b | [HITL with Feedback](09b-hitl-with-feedback.ts) | Custom feedback via `respond()` — editorial review | | 09c | [HITL with Streaming](09c-hitl-streaming.ts) | Real-time event stream with approval pauses | | 09d | [Human Tool](09d-human-tool.ts) | Human-as-a-tool for interactive conversations | -| 27 | [User Proxy Agent](27-user-proxy-agent.ts) | Human stand-in agent for interactive conversations | ## Guardrails & Safety | # | Example | What it demonstrates | |---|---------|---------------------| +| 04 | [Guardrail Types](04-guardrails.ts) | Regex, LLM, and custom guardrails in one file | | 10 | [Guardrails](10-guardrails.ts) | Output validation with guardrail functions | | 21 | [Regex Guardrails](21-regex-guardrails.ts) | Pattern-based blocking (emails, SSNs) and allow-listing | | 22 | [LLM Guardrails](22-llm-guardrails.ts) | AI-powered content safety evaluation via a judge LLM | @@ -202,40 +223,122 @@ cd examples/agents/openai && npx tsx 01-basic-agent.ts | 35 | [Standalone Guardrails](35-standalone-guardrails.ts) | Use guardrails as plain callables — no agent needed | | 36 | [Simple Agent Guardrails](36-simple-agent-guardrails.ts) | Mixed regex + custom guardrails on agents | | 37 | [Fix Guardrail](37-fix-guardrail.ts) | Auto-correct output instead of retrying | +| 42 | [Security Testing](42-security-testing.ts) | Multi-agent security testing pipeline | +| 43 | [Data Security Pipeline](43-data-security-pipeline.ts) | Data-safety pipeline with guardrails | +| 44 | [Safety Guardrails](44-safety-guardrails.ts) | Safety guardrails pipeline | +| 62 | [CLI Tool Guardrails](62-cli-tool-guardrails.ts) | Safe command execution | +| 90 | [Guardrail E2E Tests](90-guardrail-e2e-tests.ts) | Full 3×3×3 matrix: position × type × onFail (27 tests) | -## Execution Modes +## Streaming & Execution Modes | # | Example | What it demonstrates | |---|---------|---------------------| +| 05 | [Streaming Basics](05-streaming.ts) | `runtime.stream()` with for-await-of and event type switching | | 11 | [Streaming](11-streaming.ts) | Real-time event stream with `runtime.stream()` | | 12 | [Long-Running](12-long-running.ts) | Async polling with `runtime.start()` | +## Memory & Context + +| # | Example | What it demonstrates | +|---|---------|---------------------| +| 07 | [Memory](07-memory.ts) | `ConversationMemory` windowing + `SemanticMemory` similarity search | +| 25 | [Semantic Memory](25-semantic-memory.ts) | Long-term memory with similarity-based retrieval | +| 49 | [Include Contents](49-include-contents.ts) | Control conversation context passed to sub-agents | +| 68 | [Context Condensation](68-context-condensation.ts) | Stress test: server condenses long history automatically | + +## Planning + +| # | Example | What it demonstrates | +|---|---------|---------------------| +| 48 | [Planner](48-planner.ts) | Agent that plans before executing | +| 57 | [Plan (Dry Run)](57-plan-dry-run.ts) | Compile an agent without executing it | +| 108 | [Plan-Execute Refs](108-plan-execute-refs.ts) | Pipe whole step outputs downstream with `new Ref("step_id")` | +| 115 | [Plan-Execute Planner Context](115-plan-execute-planner-context.ts) | Inject domain-specific planning rules via `plannerContext` | + +## Code Execution + +| # | Example | What it demonstrates | +|---|---------|---------------------| +| 10 | [Code Execution](10-code-execution.ts) | `LocalCodeExecutor.asTool()` attached to an agent | +| 24 | [Code Executors](24-code-execution.ts) | Executor types: local subprocess vs Docker sandbox | +| 39 | [Local Code Execution](39-local-code-execution.ts) | Three config styles, incl. language/command restrictions | +| 39a | [Docker Code Execution](39a-docker-code-execution.ts) | Docker-sandboxed execution | +| 39b | [Jupyter Code Execution](39b-jupyter-code-execution.ts) | Jupyter kernel execution | +| 39c | [Serverless Code Execution](39c-serverless-code-execution.ts) | Serverless sandbox execution | + +## Skills + +| # | Example | What it demonstrates | +|---|---------|---------------------| +| 30 | [Skills: /dg Review](30-skills-dg-review.ts) | Load the /dg skill as a durable agent | +| 31 | [Skills: Conductor](31-skills-conductor.ts) | Load the conductor skill for workflow management | +| 32 | [Skills: Multi-Agent](32-skills-multi-agent.ts) | Skills as sub-agents in multi-agent workflows | + +## Observability & Callbacks + +| # | Example | What it demonstrates | +|---|---------|---------------------| +| 23 | [Token & Cost Tracking](23-token-tracking.ts) | Monitor LLM token usage per agent run | +| 26 | [OpenTelemetry Tracing](26-opentelemetry-tracing.ts) | Industry-standard observability | +| 47 | [Callbacks](47-callbacks.ts) | `CallbackHandler` hooks around LLM and tool calls | +| 53 | [Agent Lifecycle Callbacks](53-agent-lifecycle-callbacks.ts) | Composable handler classes, chained per position | + +## Model & Provider Features + +| # | Example | What it demonstrates | +|---|---------|---------------------| +| 28 | [GPT Assistant Agent](28-gpt-assistant-agent.ts) | Wrap the OpenAI Assistants API as a Conductor agent | +| 30 | [Multimodal Agent](30-multimodal-agent.ts) | Analyze images and video with vision-capable models | +| 40 | [Media Generation Agent](40-media-generation-agent.ts) | Generate media assets from an agent | +| 50 | [Thinking Config](50-thinking-config.ts) | Enable extended reasoning for complex tasks | + ## Credentials | # | Example | What it demonstrates | |---|---------|---------------------| | 08 | [Credentials](08-credentials.ts) | Server-side credential injection | -| 16 | [Isolated Tool](16-credentials-isolated-tool.ts) | Credentials scoped to a single tool | -| 16b | [Non-Isolated](16b-credentials-non-isolated.ts) | Credentials shared across tools | -| 16e | [HTTP Tool](16e-credentials-http-tool.ts) | Credentials in HTTP tool headers | -| 16f | [MCP Tool](16f-credentials-mcp-tool.ts) | Credentials in MCP tool headers | - -## Deployment +| 16 | [Isolated Tool](16-credentials-isolated-tool.ts) | Per-user secrets injected into isolated tool subprocesses | +| 16b | [Non-Isolated](16b-credentials-non-isolated.ts) | In-process tools using `getCredential()` | +| 16c | [CLI Tools](16c-credentials-cli-tools.ts) | CLI tools with explicit credential declarations | +| 16d | [GitHub CLI](16d-credentials-gh-cli.ts) | `gh` with automatic credential injection | +| 16e | [HTTP Tool](16e-credentials-http-tool.ts) | Server-side credential resolution in HTTP tool headers | +| 16f | [MCP Tool](16f-credentials-mcp-tool.ts) | Server-side credential resolution in MCP tool headers | +| 16g | [Framework Passthrough](16g-credentials-framework-passthrough.ts) | Credential injection into framework-wrapped agents | +| 16h | [External Worker](16h-credentials-external-worker.ts) | External worker credential resolution | +| 16i | [LangChain](16i-credentials-langchain.ts) | LangChain AgentExecutor with credential injection | +| 16j | [OpenAI SDK](16j-credentials-openai-sdk.ts) | OpenAI Agents SDK with credential injection | +| 16k | [Google ADK](16k-credentials-google-adk.ts) | Google ADK agent with credential injection | + +## Deployment & Scheduling | # | Example | What it demonstrates | |---|---------|---------------------| +| 17 | [Scheduled Agent](17-scheduled-agent.ts) | Deploy an agent on a cron schedule | | 63 | [Deploy](63-deploy.ts) | Register agent with the server | | 63b | [Serve](63b-serve.ts) | Start a long-running worker | | 63c | [Run by Name](63c-run-by-name.ts) | Execute a pre-deployed agent | | 63d | [Serve from Package](63d-serve-from-package.ts) | Serve agents from a package | | 63e | [Run Monitoring](63e-run-monitoring.ts) | Monitor running executions | +## End-to-End Use Cases + +| # | Example | What it demonstrates | +|---|---------|---------------------| +| 54 | [Software Bug Assistant](54-software-bug-assistant.ts) | `agentTool` + `mcpTool` for bug triage | +| 55 | [ML Engineering](55-ml-engineering.ts) | Multi-agent ML pipeline | +| 56 | [RAG Agent](56-rag-agent.ts) | Vector search + document indexing | +| 59 | [Coding Agent](59-coding-agent.ts) | Write, review, and fix code with a QA tester | +| 60 | [GitHub Coding Agent](60-github-coding-agent.ts) | Pick an issue, code the fix, create a PR | +| 60a | [GitHub Coding Agent (Simple)](60a-github-coding-agent-simple.ts) | Simplified single-agent variant | +| 61 | [GitHub Coding Agent (Chained)](61-github-coding-agent-chained.ts) | Issue-to-PR pipeline | +| 70 | [CE Support Agent](70-ce-support-agent.ts) | Investigate a support ticket across Zendesk, JIRA, HubSpot, Notion, and GitHub | + ## Framework Integrations | Directory | Framework | Examples | |-----------|-----------|----------| -| [adk/](adk/) | Google ADK | 35 examples — agents, tools, streaming, planners, security | -| [langgraph/](langgraph/) | LangGraph | 45 examples — state graphs, react agents, memory, RAG | -| [openai/](openai/) | OpenAI Agents SDK | 10 examples — agents, tools, handoffs, guardrails | -| [vercel-ai/](vercel-ai/) | Vercel AI SDK | 10 examples — agents, tools, streaming, HITL | -| [quickstart/](quickstart/) | Agentspan Quickstart | 5 examples — minimal getting-started guides | +| [adk/](adk/) | Google ADK | Agents, tools, streaming, planners, security | +| [langgraph/](langgraph/) | LangGraph | State graphs, react agents, memory, RAG | +| [openai/](openai/) | OpenAI Agents SDK | Agents, tools, handoffs, guardrails | +| [vercel-ai/](vercel-ai/) | Vercel AI SDK | Agents, tools, streaming, HITL | +| [quickstart/](quickstart/) | Agentspan Quickstart | Minimal getting-started guides |