1+ import { configure , Predict , ChainOfThought , RespAct , Signature , InputField , OutputField } from '@ts-dspy/core' ;
2+ import { GeminiLM } from '@ts-dspy/gemini' ;
3+
4+ // Setup - configure global LM
5+ configure ( {
6+ lm : new GeminiLM ( {
7+ apiKey : process . env . GEMINI_API_KEY || '***REDACTED*** ' ,
8+ model : 'gemini-2.0-flash' ,
9+ } )
10+ } ) ;
11+
12+ // Example 1: Simple string signature
13+ async function simpleExample ( ) {
14+ console . log ( '=== Simple Example ===' ) ;
15+
16+ const qa = new Predict ( "question -> answer" ) ;
17+ const result = await qa . forward ( { question : "What is the capital of France?" } ) ;
18+
19+ console . log ( 'Question:' , "What is the capital of France?" ) ;
20+ console . log ( 'Answer:' , result . answer ) ;
21+ }
22+
23+ // Example 2: Typed signature with multiple fields
24+ async function typedExample ( ) {
25+ console . log ( '\n=== Typed Example ===' ) ;
26+
27+ const math = new Predict ( "question -> answer: float, explanation" ) ;
28+ const result = await math . forward ( {
29+ question : "What is the probability of getting heads when flipping a fair coin?"
30+ } ) ;
31+
32+ console . log ( 'Question:' , "What is the probability of getting heads when flipping a fair coin?" ) ;
33+ console . log ( 'Answer:' , result . answer , '(type:' , typeof result . answer , ')' ) ;
34+ console . log ( 'Explanation:' , result . explanation ) ;
35+ }
36+
37+ // Example 3: Class-based signature with decorators
38+ class SentimentAnalysis extends Signature {
39+ @InputField ( { description : "Text to analyze for sentiment" } )
40+ text ! : string ;
41+
42+ @OutputField ( { description : "Sentiment classification" } )
43+ sentiment ! : 'positive' | 'negative' | 'neutral' ;
44+
45+ @OutputField ( { description : "Confidence score between 0 and 1" } )
46+ confidence ! : number ;
47+
48+ static description = "Analyze the sentiment of the given text" ;
49+ }
50+
51+ async function classBasedExample ( ) {
52+ console . log ( '\n=== Class-based Signature Example ===' ) ;
53+
54+ const classifier = new Predict ( SentimentAnalysis ) ;
55+ const result = await classifier . forward ( {
56+ text : "I love this new TypeScript framework! It's amazing!"
57+ } ) ;
58+
59+ console . log ( 'Text:' , "I love this new TypeScript framework! It's amazing!" ) ;
60+ console . log ( 'Sentiment:' , result . sentiment ) ;
61+ console . log ( 'Confidence:' , result . confidence ) ;
62+ }
63+
64+ // Example 4: Chain of Thought reasoning
65+ async function chainOfThoughtExample ( ) {
66+ console . log ( '\n=== Chain of Thought Example ===' ) ;
67+
68+ const reasoner = new ChainOfThought ( "question -> answer: int" ) ;
69+ const result = await reasoner . forward ( {
70+ question : "A store sells apples for $2 each and oranges for $3 each. If someone buys 4 apples and 3 oranges, how much do they pay in total?"
71+ } ) ;
72+
73+ console . log ( 'Question:' , "A store sells apples for $2 each and oranges for $3 each. If someone buys 4 apples and 3 oranges, how much do they pay in total?" ) ;
74+ console . log ( 'Reasoning:' , result . reasoning ) ;
75+ console . log ( 'Answer:' , result . answer ) ;
76+ }
77+
78+ // Example 5: Tool-using agent with RespAct (Enhanced Format)
79+ async function toolExample ( ) {
80+ console . log ( '\n=== Tool Usage Example (Enhanced Format) ===' ) ;
81+ console . log ( '🆕 Using enhanced tools with descriptions for better AI tool selection\n' ) ;
82+
83+ const calculator = new RespAct ( "question -> answer" , {
84+ tools : {
85+ calculate : {
86+ description : "Performs mathematical calculations including arithmetic operations. Use this when you need to compute numerical results." ,
87+ function : ( expression : string ) => {
88+ console . log ( '🔧 TOOL CALLED: calculate(' + expression + ')' ) ;
89+ try {
90+ // Using a safer method than eval for simple expressions
91+ const result = new Function ( 'return ' + expression ) ( ) ;
92+ console . log ( ' → Result:' , result ) ;
93+ return result ;
94+ } catch ( error ) {
95+ console . log ( ' → Error:' , error ) ;
96+ return `Error: ${ error } ` ;
97+ }
98+ }
99+ } ,
100+ } ,
101+ maxSteps : 4
102+ } ) ;
103+
104+ const result = await calculator . forward ( {
105+ question : "What is 15 * 24 + 100 - 50?"
106+ } ) ;
107+
108+ console . log ( 'Question:' , "What is 15 * 24 + 100 - 50?" ) ;
109+ console . log ( 'Answer:' , result . answer ) ;
110+ console . log ( 'Steps taken:' , result . steps ) ;
111+ }
112+
113+ // Example 6: Error handling
114+ async function errorHandlingExample ( ) {
115+ console . log ( '\n=== Error Handling Example ===' ) ;
116+
117+ try {
118+ // This will fail due to missing signature
119+ const badModule = new Predict ( "" ) ;
120+ await badModule . forward ( { input : "test" } ) ;
121+ } catch ( error : any ) {
122+ console . log ( 'Caught expected error:' , error . message ) ;
123+ }
124+ }
125+
126+ // Example 7: Usage statistics
127+ async function usageStatsExample ( ) {
128+ console . log ( '\n=== Usage Statistics Example ===' ) ;
129+
130+ const lm = new GeminiLM ( {
131+ apiKey : process . env . GEMINI_API_KEY || '***REDACTED*** ' ,
132+ model : 'gemini-2.0-flash' ,
133+ } ) ;
134+
135+
136+
137+ lm . resetUsage ( ) ;
138+
139+ const qa = new Predict ( "question -> answer" , lm ) ;
140+ await qa . forward ( { question : "Hello, how are you?" } ) ;
141+
142+ const usage = lm . getUsage ( ) ;
143+ console . log ( 'Usage Statistics (Gemini):' ) ;
144+ console . log ( 'Note: The Gemini API currently does not provide token usage information via this SDK implementation.' ) ;
145+ console . log ( '- Prompt tokens:' , usage . promptTokens ) ;
146+ console . log ( '- Completion tokens:' , usage . completionTokens ) ;
147+ console . log ( '- Total tokens:' , usage . totalTokens ) ;
148+ console . log ( '- Estimated cost: $' , usage . totalCost ?. toFixed ( 4 ) || '0.0000' ) ;
149+ }
150+
151+ // Main execution
152+ async function main ( ) {
153+ console . log ( 'TS-DSPy Gemini Framework Examples\n' ) ;
154+
155+ try {
156+ await simpleExample ( ) ;
157+ await typedExample ( ) ;
158+ await classBasedExample ( ) ;
159+ await chainOfThoughtExample ( ) ;
160+ await toolExample ( ) ;
161+ await errorHandlingExample ( ) ;
162+ await usageStatsExample ( ) ;
163+
164+ console . log ( '\n=== All Gemini Examples Completed Successfully! ===' ) ;
165+ } catch ( error : any ) {
166+ console . error ( 'An example failed:' , error . message ) ;
167+
168+ if ( error . message . includes ( 'API key' ) ) {
169+ console . log ( '\n💡 Tip: Set your Gemini API key in the GEMINI_API_KEY environment variable' ) ;
170+ } else if ( error . message . includes ( 'API Error' ) ) {
171+ console . log ( '\n💡 Tip: This may be due to a blocked prompt. Check the Gemini API safety settings.' ) ;
172+ }
173+ }
174+ }
175+
176+ // Run examples if this file is executed directly
177+ if ( require . main === module ) {
178+ main ( ) . catch ( console . error ) ;
179+ }
180+
181+ export { main } ;
0 commit comments