Skip to content

Commit db66ea0

Browse files
NicholasDColeclaude
andcommitted
Fix agent examples broken by CJS migration and silent failures
Found by a full smoke sweep of all 116 agent examples against a local Conductor OSS 3.32.0-rc.8 server (Anthropic Haiku 4.5). Three groups of fixes: 1. Top-level await (7 files: 12, 57, 63, 63b, 63c, 63d, 63e): upstream agentspan was ESM; this repo's CJS module flavor makes tsx reject top-level await, so these examples did not compile at all. Wrapped in the house-style async main(). 63-deploy and 63d get a require.main === module guard because 63c/63e import their agent definitions - without it, importing would execute the sibling example. 2. 74-cli-error-output: the assertion did String(result.output) on an object, always producing "[object Object]" and false-failing even though the agent surfaced stderr correctly. Stringify properly. Same latent bug fixed in 10-guardrails' PII leak check. 3. Silent failures (10-guardrails, 54-software-bug-assistant): both printed [FAIL] results and exited 0, so any harness built on exit codes passes vacuously. They now set exit code 1 when the run ends non-COMPLETED (and 10-guardrails also when PII leaks); main().catch sets the exit code instead of swallowing errors. Verified: all 7 TLA examples + 74 run green end-to-end against the local stack; 10 and 54 now exit 1 with the real upstream diagnostics (a server ChatMessage deserialization bug and an MCP Authorization-header issue, tracked separately). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 891bd06 commit db66ea0

10 files changed

Lines changed: 202 additions & 122 deletions

examples/agents/10-guardrails.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,19 @@ async function main() {
170170
);
171171
result.printResult();
172172

173+
if (result.status !== 'COMPLETED') {
174+
console.error(`\nFAIL: agent run ended ${result.status}: ${result.error ?? ''}`);
175+
process.exitCode = 1;
176+
return;
177+
}
178+
173179
// Verify the guardrail worked — no raw card number in the output
174-
if (result.output && String(result.output).includes('4532-0150-1234-5678')) {
175-
console.log('[WARN] PII leaked through the guardrail!');
180+
// (stringify: result.output is an object, String() gives "[object Object]")
181+
if (result.output && JSON.stringify(result.output).includes('4532-0150-1234-5678')) {
182+
console.log('[WARN] PII leaked through the guardrail!');
183+
process.exitCode = 1;
176184
} else {
177-
console.log('[OK] PII was redacted from the final output.');
185+
console.log('[OK] PII was redacted from the final output.');
178186
}
179187

180188
// Production pattern:
@@ -190,4 +198,7 @@ async function main() {
190198
}
191199
}
192200

193-
main().catch(console.error);
201+
main().catch((err) => {
202+
console.error(err);
203+
process.exitCode = 1;
204+
});

examples/agents/12-long-running.ts

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,36 @@ export const agent = new Agent({
2424

2525
// Start agent asynchronously (returns immediately)
2626

27-
const runtime = new AgentRuntime();
28-
try {
29-
const result = await runtime.run(
30-
agent,
31-
'What are the key metrics to track for a SaaS product?',
32-
);
33-
result.printResult();
27+
async function main() {
28+
const runtime = new AgentRuntime();
29+
try {
30+
const result = await runtime.run(
31+
agent,
32+
'What are the key metrics to track for a SaaS product?',
33+
);
34+
result.printResult();
3435

35-
// Production pattern:
36-
// 1. Deploy once during CI/CD (optional -- serve() below also deploys):
37-
// await runtime.deploy(agent);
38-
// CLI alternative:
39-
// agentspan deploy --package sdk/typescript/examples --agents saas_analyst
40-
//
41-
// 2. In a separate long-lived worker process (deploys + registers workers + starts polling):
42-
// await runtime.serve(agent);
36+
// Production pattern:
37+
// 1. Deploy once during CI/CD (optional -- serve() below also deploys):
38+
// await runtime.deploy(agent);
39+
// CLI alternative:
40+
// agentspan deploy --package sdk/typescript/examples --agents saas_analyst
41+
//
42+
// 2. In a separate long-lived worker process (deploys + registers workers + starts polling):
43+
// await runtime.serve(agent);
4344

44-
// Async handle alternative:
45-
// const handle = await runtime.start(
46-
// agent,
47-
// 'What are the key metrics to track for a SaaS product?',
48-
// );
49-
// console.log(handle.executionId);
50-
} finally {
51-
await runtime.shutdown();
45+
// Async handle alternative:
46+
// const handle = await runtime.start(
47+
// agent,
48+
// 'What are the key metrics to track for a SaaS product?',
49+
// );
50+
// console.log(handle.executionId);
51+
} finally {
52+
await runtime.shutdown();
53+
}
5254
}
55+
56+
main().catch((err) => {
57+
console.error(err);
58+
process.exitCode = 1;
59+
});

examples/agents/54-software-bug-assistant.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,11 @@ async function main() {
277277
);
278278
result.printResult();
279279

280+
if (result.status !== 'COMPLETED') {
281+
console.error(`\nFAIL: agent run ended ${result.status}: ${result.error ?? ''}`);
282+
process.exitCode = 1;
283+
}
284+
280285
// Production pattern:
281286
// 1. Deploy once during CI/CD (optional -- serve() below also deploys):
282287
// await runtime.deploy(softwareAssistant);
@@ -290,4 +295,7 @@ async function main() {
290295
}
291296
}
292297

293-
main().catch(console.error);
298+
main().catch((err) => {
299+
console.error(err);
300+
process.exitCode = 1;
301+
});

examples/agents/57-plan-dry-run.ts

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -64,28 +64,35 @@ export const agent = new Agent({
6464

6565
// -- Plan: compile without executing -----------------------------------------
6666

67-
const runtime = new AgentRuntime();
68-
try {
69-
const workflowDef = (await runtime.plan(agent)) as Record<string, unknown>;
67+
async function main() {
68+
const runtime = new AgentRuntime();
69+
try {
70+
const workflowDef = (await runtime.plan(agent)) as Record<string, unknown>;
7071

71-
console.log(`Workflow name: ${workflowDef.name}`);
72-
const tasks: Record<string, unknown>[] = (workflowDef.tasks as Record<string, unknown>[]) ?? [];
73-
console.log(`Total tasks: ${tasks.length}`);
74-
console.log();
72+
console.log(`Workflow name: ${workflowDef.name}`);
73+
const tasks: Record<string, unknown>[] = (workflowDef.tasks as Record<string, unknown>[]) ?? [];
74+
console.log(`Total tasks: ${tasks.length}`);
75+
console.log();
7576

76-
// Walk the task tree
77-
for (const task of tasks) {
78-
console.log(` [${task.type}] ${task.taskReferenceName}`);
79-
if (task.type === 'DO_WHILE' && Array.isArray(task.loopOver)) {
80-
for (const sub of task.loopOver as Record<string, unknown>[]) {
81-
console.log(` [${sub.type}] ${sub.taskReferenceName}`);
77+
// Walk the task tree
78+
for (const task of tasks) {
79+
console.log(` [${task.type}] ${task.taskReferenceName}`);
80+
if (task.type === 'DO_WHILE' && Array.isArray(task.loopOver)) {
81+
for (const sub of task.loopOver as Record<string, unknown>[]) {
82+
console.log(` [${sub.type}] ${sub.taskReferenceName}`);
83+
}
8284
}
8385
}
84-
}
8586

86-
// Full JSON for CI/CD validation or export
87-
console.log('\n--- Full workflow JSON ---');
88-
console.log(JSON.stringify(workflowDef, null, 2));
89-
} finally {
90-
await runtime.shutdown();
87+
// Full JSON for CI/CD validation or export
88+
console.log('\n--- Full workflow JSON ---');
89+
console.log(JSON.stringify(workflowDef, null, 2));
90+
} finally {
91+
await runtime.shutdown();
92+
}
9193
}
94+
95+
main().catch((err) => {
96+
console.error(err);
97+
process.exitCode = 1;
98+
});

examples/agents/63-deploy.ts

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,31 @@ export const opsBot = new Agent({
7070

7171
// -- Deploy: compile + register on server ------------------------------------
7272

73-
const runtime = new AgentRuntime();
74-
try {
75-
const result = await runtime.run(docAssistant, 'How do I reset my password?');
76-
result.printResult();
73+
async function main() {
74+
const runtime = new AgentRuntime();
75+
try {
76+
const result = await runtime.run(docAssistant, 'How do I reset my password?');
77+
result.printResult();
7778

78-
// Production pattern:
79-
// 1. Deploy once during CI/CD (optional -- serve() below also deploys):
80-
// await runtime.deploy(docAssistant);
81-
// await runtime.deploy(opsBot);
82-
// CLI alternative:
83-
// agentspan deploy --package sdk/typescript/examples --agents doc_assistant
84-
//
85-
// 2. In a separate long-lived worker process (deploys + registers workers + starts polling):
86-
// await runtime.serve(docAssistant, opsBot);
87-
} finally {
88-
await runtime.shutdown();
79+
// Production pattern:
80+
// 1. Deploy once during CI/CD (optional -- serve() below also deploys):
81+
// await runtime.deploy(docAssistant);
82+
// await runtime.deploy(opsBot);
83+
// CLI alternative:
84+
// agentspan deploy --package sdk/typescript/examples --agents doc_assistant
85+
//
86+
// 2. In a separate long-lived worker process (deploys + registers workers + starts polling):
87+
// await runtime.serve(docAssistant, opsBot);
88+
} finally {
89+
await runtime.shutdown();
90+
}
91+
}
92+
93+
// Guard: 63c-run-by-name.ts imports docAssistant from this file — only run
94+
// when executed directly, not on import.
95+
if (require.main === module) {
96+
main().catch((err) => {
97+
console.error(err);
98+
process.exitCode = 1;
99+
});
89100
}

examples/agents/63b-serve.ts

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,27 @@ export const opsBot = new Agent({
7474

7575
// -- Serve: register workers and block ---------------------------------------
7676

77-
const runtime = new AgentRuntime();
78-
try {
79-
const result = await runtime.run(opsBot, 'Check the status of the API gateway.');
80-
result.printResult();
77+
async function main() {
78+
const runtime = new AgentRuntime();
79+
try {
80+
const result = await runtime.run(opsBot, 'Check the status of the API gateway.');
81+
result.printResult();
8182

82-
// Production pattern:
83-
// 1. Deploy once during CI/CD (optional -- serve() below also deploys):
84-
// await runtime.deploy(docAssistant);
85-
// await runtime.deploy(opsBot);
86-
// CLI alternative:
87-
// agentspan deploy --package sdk/typescript/examples --agents doc_assistant
88-
//
89-
// 2. In a separate long-lived worker process (deploys + registers workers + starts polling):
90-
// await runtime.serve(docAssistant, opsBot);
91-
} finally {
92-
await runtime.shutdown();
83+
// Production pattern:
84+
// 1. Deploy once during CI/CD (optional -- serve() below also deploys):
85+
// await runtime.deploy(docAssistant);
86+
// await runtime.deploy(opsBot);
87+
// CLI alternative:
88+
// agentspan deploy --package sdk/typescript/examples --agents doc_assistant
89+
//
90+
// 2. In a separate long-lived worker process (deploys + registers workers + starts polling):
91+
// await runtime.serve(docAssistant, opsBot);
92+
} finally {
93+
await runtime.shutdown();
94+
}
9395
}
96+
97+
main().catch((err) => {
98+
console.error(err);
99+
process.exitCode = 1;
100+
});

examples/agents/63c-run-by-name.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,26 @@
1616
import { docAssistant } from './63-deploy.js';
1717
import { AgentRuntime } from '@io-orkes/conductor-javascript/agents';
1818

19-
const runtime = new AgentRuntime();
20-
try {
21-
const result = await runtime.run(docAssistant, 'How do I reset my password?');
22-
result.printResult();
19+
async function main() {
20+
const runtime = new AgentRuntime();
21+
try {
22+
const result = await runtime.run(docAssistant, 'How do I reset my password?');
23+
result.printResult();
2324

24-
// Production pattern:
25-
// 1. Deploy once during CI/CD (optional -- serve() below also deploys):
26-
// await runtime.deploy(docAssistant);
27-
// CLI alternative:
28-
// agentspan deploy --package sdk/typescript/examples --agents doc_assistant
29-
//
30-
// 2. In a separate long-lived worker process (deploys + registers workers + starts polling):
31-
// await runtime.serve(docAssistant);
32-
} finally {
33-
await runtime.shutdown();
25+
// Production pattern:
26+
// 1. Deploy once during CI/CD (optional -- serve() below also deploys):
27+
// await runtime.deploy(docAssistant);
28+
// CLI alternative:
29+
// agentspan deploy --package sdk/typescript/examples --agents doc_assistant
30+
//
31+
// 2. In a separate long-lived worker process (deploys + registers workers + starts polling):
32+
// await runtime.serve(docAssistant);
33+
} finally {
34+
await runtime.shutdown();
35+
}
3436
}
37+
38+
main().catch((err) => {
39+
console.error(err);
40+
process.exitCode = 1;
41+
});

examples/agents/63d-serve-from-package.ts

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,30 @@ export const monitoringAgent = new Agent({
4343

4444
// -- Serve -------------------------------------------------------------------
4545

46-
const runtime = new AgentRuntime();
47-
try {
48-
const result = await runtime.run(monitoringAgent, 'Is everything healthy? Run a full check.');
49-
result.printResult();
50-
51-
// Production pattern:
52-
// 1. Deploy once during CI/CD (optional -- serve() below also deploys):
53-
// await runtime.deploy(monitoringAgent);
54-
// CLI alternative:
55-
// agentspan deploy --package sdk/typescript/examples --agents monitoring
56-
//
57-
// 2. In a separate long-lived worker process (deploys + registers workers + starts polling):
58-
// await runtime.serve(monitoringAgent);
59-
} finally {
60-
await runtime.shutdown();
46+
async function main() {
47+
const runtime = new AgentRuntime();
48+
try {
49+
const result = await runtime.run(monitoringAgent, 'Is everything healthy? Run a full check.');
50+
result.printResult();
51+
52+
// Production pattern:
53+
// 1. Deploy once during CI/CD (optional -- serve() below also deploys):
54+
// await runtime.deploy(monitoringAgent);
55+
// CLI alternative:
56+
// agentspan deploy --package sdk/typescript/examples --agents monitoring
57+
//
58+
// 2. In a separate long-lived worker process (deploys + registers workers + starts polling):
59+
// await runtime.serve(monitoringAgent);
60+
} finally {
61+
await runtime.shutdown();
62+
}
63+
}
64+
65+
// Guard: 63e-run-monitoring.ts imports monitoringAgent from this file — only
66+
// run when executed directly, not on import.
67+
if (require.main === module) {
68+
main().catch((err) => {
69+
console.error(err);
70+
process.exitCode = 1;
71+
});
6172
}

examples/agents/63e-run-monitoring.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,26 @@
1010
import { monitoringAgent } from './63d-serve-from-package.js';
1111
import { AgentRuntime } from '@io-orkes/conductor-javascript/agents';
1212

13-
const runtime = new AgentRuntime();
14-
try {
15-
const result = await runtime.run(monitoringAgent, 'Is everything healthy? Run a full check.');
16-
result.printResult();
13+
async function main() {
14+
const runtime = new AgentRuntime();
15+
try {
16+
const result = await runtime.run(monitoringAgent, 'Is everything healthy? Run a full check.');
17+
result.printResult();
1718

18-
// Production pattern:
19-
// 1. Deploy once during CI/CD (optional -- serve() below also deploys):
20-
// await runtime.deploy(monitoringAgent);
21-
// CLI alternative:
22-
// agentspan deploy --package sdk/typescript/examples --agents monitoring
23-
//
24-
// 2. In a separate long-lived worker process (deploys + registers workers + starts polling):
25-
// await runtime.serve(monitoringAgent);
26-
} finally {
27-
await runtime.shutdown();
19+
// Production pattern:
20+
// 1. Deploy once during CI/CD (optional -- serve() below also deploys):
21+
// await runtime.deploy(monitoringAgent);
22+
// CLI alternative:
23+
// agentspan deploy --package sdk/typescript/examples --agents monitoring
24+
//
25+
// 2. In a separate long-lived worker process (deploys + registers workers + starts polling):
26+
// await runtime.serve(monitoringAgent);
27+
} finally {
28+
await runtime.shutdown();
29+
}
2830
}
31+
32+
main().catch((err) => {
33+
console.error(err);
34+
process.exitCode = 1;
35+
});

0 commit comments

Comments
 (0)