Skip to content

Commit 00aa8a9

Browse files
committed
📦 NEW: add tracing support
1 parent e8ab438 commit 00aa8a9

File tree

4 files changed

+423
-73
lines changed

4 files changed

+423
-73
lines changed
Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,85 @@
1-
// Experimental upcoming beta AI primitve.
2-
// Please refer to the documentation for more information: https://langbase.com/docs for more information.
3-
1+
// Test script for the simplified proxy approach
42
import 'dotenv/config';
5-
import {Langbase, Workflow} from 'langbase';
3+
import {Langbase} from 'langbase';
64

5+
// Create Langbase instance
76
const langbase = new Langbase({
87
apiKey: process.env.LANGBASE_API_KEY!,
98
});
109

1110
async function main() {
12-
const {step} = new Workflow({debug: true});
13-
14-
const result = await step({
15-
id: 'sumamrize',
16-
run: async () => {
17-
return langbase.llm.run({
18-
model: 'openai:gpt-4o-mini',
19-
apiKey: process.env.OPENAI_API_KEY!,
20-
messages: [
21-
{
22-
role: 'system',
23-
content:
24-
'You are an expert summarizer. Summarize the user input.',
25-
},
26-
{
27-
role: 'user',
28-
content:
29-
'I am testing workflows. I just created an example of summarize workflow. Can you summarize this?',
30-
},
31-
],
32-
stream: false,
33-
});
34-
},
11+
// Create a workflow with debug mode enabled
12+
const workflow = langbase.workflow({
13+
name: 'simplified-proxy-test',
14+
debug: true, // Enable debug logging
3515
});
3616

37-
console.log(result['completion']);
17+
try {
18+
// STEP 1: Call langbase.agent.run but don't return its result directly
19+
const step1Result = await workflow.step({
20+
id: 'call-but-return-custom',
21+
run: async () => {
22+
// Return custom result instead
23+
return {
24+
customField: 'Custom result from simplified proxy',
25+
timestamp: new Date().toISOString(),
26+
};
27+
},
28+
});
29+
30+
// STEP 2: Return agent.run result directly
31+
const step2Result = await workflow.step({
32+
id: 'return-agent-run-directly',
33+
run: async () => {
34+
// Call Langbase API and return the result directly
35+
return langbase.agent.run({
36+
model: 'openai:gpt-4o-mini',
37+
apiKey: process.env.OPENAI_API_KEY!,
38+
instructions: 'Be brief and concise.',
39+
input: 'What is 2+2?',
40+
stream: false,
41+
});
42+
},
43+
});
44+
45+
// STEP 3: Make multiple Langbase calls in one step
46+
const step3Result = await workflow.step({
47+
id: 'multiple-calls',
48+
run: async () => {
49+
// First call
50+
const call1 = await langbase.agent.run({
51+
model: 'openai:gpt-4o-mini',
52+
apiKey: process.env.OPENAI_API_KEY!,
53+
instructions: 'Be brief.',
54+
input: 'First proxy test',
55+
stream: false,
56+
});
57+
58+
// Second call with different method
59+
const call2 = await langbase.agent.run({
60+
model: 'openai:gpt-4o-mini',
61+
apiKey: process.env.OPENAI_API_KEY!,
62+
instructions: 'Be brief.',
63+
input: 'Second proxy test',
64+
stream: false,
65+
});
66+
67+
// Return combined result
68+
return {
69+
summary: 'Multiple calls completed with simplified proxy',
70+
calls: 2,
71+
firstOutput: call1.output,
72+
secondOutput: call2.output,
73+
};
74+
},
75+
});
76+
} catch (error) {
77+
console.error('❌ Workflow error:', error);
78+
} finally {
79+
// End the workflow to show trace report
80+
workflow.end();
81+
}
3882
}
3983

40-
main();
84+
// Run the test
85+
main().catch(console.error);

packages/langbase/src/langbase/langbase.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {convertDocToFormData} from '@/lib/utils/doc-to-formdata';
22
import {Request} from '../common/request';
3+
import {Workflow} from './workflows';
34

45
export type Role = 'user' | 'assistant' | 'system' | 'tool';
56

@@ -602,6 +603,8 @@ export class Langbase {
602603
};
603604
};
604605

606+
public workflow: (config: {debug?: boolean; name: string}) => Workflow;
607+
605608
constructor(options?: LangbaseOptions) {
606609
this.baseUrl = options?.baseUrl ?? 'https://api.langbase.com';
607610
this.apiKey = options?.apiKey ?? '';
@@ -684,6 +687,8 @@ export class Langbase {
684687
this.agent = {
685688
run: this.runAgent.bind(this),
686689
};
690+
691+
this.workflow = (config) => new Workflow({...config, langbase: this});
687692
}
688693

689694
private async runPipe(
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
export interface Trace {
2+
name: string;
3+
startTime: number;
4+
endTime?: number;
5+
steps: StepTrace[];
6+
}
7+
8+
export interface StepTrace {
9+
name: string;
10+
output: any;
11+
traces: string[] | null;
12+
duration: number;
13+
startTime: number;
14+
endTime: number;
15+
}
16+
17+
export class TraceManager {
18+
private traces: Map<string, Trace> = new Map();
19+
20+
createTrace(name: string): string {
21+
const traceId = `trace_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
22+
this.traces.set(traceId, {
23+
name,
24+
startTime: Date.now(),
25+
steps: [],
26+
});
27+
return traceId;
28+
}
29+
30+
addStep(traceId: string, step: StepTrace) {
31+
const trace = this.traces.get(traceId);
32+
if (trace) {
33+
trace.steps.push(step);
34+
}
35+
}
36+
37+
endTrace(traceId: string) {
38+
const trace = this.traces.get(traceId);
39+
if (trace) {
40+
trace.endTime = Date.now();
41+
}
42+
}
43+
44+
getTrace(traceId: string): Trace | undefined {
45+
return this.traces.get(traceId);
46+
}
47+
48+
printTrace(traceId: string) {
49+
const trace = this.traces.get(traceId);
50+
if (trace) {
51+
const duration = trace.endTime
52+
? trace.endTime - trace.startTime
53+
: Date.now() - trace.startTime;
54+
console.log('\n📊 Workflow Trace:');
55+
console.log(`Name: ${trace.name}`);
56+
console.log(`Duration: ${duration}ms`);
57+
console.log(
58+
`Start Time: ${new Date(trace.startTime).toISOString()}`,
59+
);
60+
if (trace.endTime) {
61+
console.log(
62+
`End Time: ${new Date(trace.endTime).toISOString()}`,
63+
);
64+
}
65+
console.log('\nSteps:');
66+
trace.steps.forEach(step => {
67+
console.log(`\n Step: ${step.name}`);
68+
console.log(` Duration: ${step.duration}ms`);
69+
70+
// Make sure to check for both existence and non-empty array
71+
if (step.traces && step.traces.length > 0) {
72+
console.log(` Traces:`, step.traces);
73+
}
74+
75+
console.log(` Output:`, step.output);
76+
});
77+
}
78+
}
79+
}

0 commit comments

Comments
 (0)