Skip to content

Commit f510fd1

Browse files
committed
chore(release): 0.3.0
### Features - Added gemini package for Google Gemini API integration. - Bumped all packages to version 0.3.0.
1 parent 4199a65 commit f510fd1

21 files changed

+800
-48
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# [0.3.0](https://github.com/ardada2468/LLMTypeSafe/compare/v0.2.3...v0.3.0) (2025-06-05)
2+
3+
### Features
4+
5+
* **packages:** add gemini package for Google Gemini API integration ([<commit-hash>](https://github.com/ardada2468/LLMTypeSafe/commit/<commit-hash>))
6+
* **version:** bump all packages to 0.3.0 ([<commit-hash>](https://github.com/ardada2468/LLMTypeSafe/commit/<commit-hash>))
7+
18
## [0.2.3](https://github.com/ardada2468/LLMTypeSafe/compare/v0.2.2...v0.2.3) (2025-06-04)
29

310

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ TS-DSPy brings the powerful paradigms of [Stanford's DSPy framework](https://git
2525
- **🔒 Type-Safe Signatures**: Define input/output schemas with automatic validation and TypeScript inference
2626
- **🧠 ReAct Pattern**: Built-in Reasoning and Acting with intelligent tool integration
2727
- **🛠️ Enhanced Tool Descriptions**: Provide detailed tool descriptions for better AI decision-making
28-
- **🔌 Multiple LLM Support**: Currently supports OpenAI with extensible architecture for other providers
29-
- **⚡ Automatic Parsing**: Convert raw LLM outputs to structured TypeScript objects
28+
- **🔌 Multiple LLM Support**: Supports OpenAI and Gemini with an extensible architecture for other providers
29+
- **⚡ Automatic Parsing**: Converts raw LLM outputs to structured TypeScript objects
3030
- **🛡️ Robust Error Handling**: Comprehensive validation with automatic retries and fallbacks
3131
- **📊 Usage Tracking**: Built-in token usage and cost monitoring
3232
- **🎯 Zero Config**: Works out of the box with minimal setup
@@ -42,6 +42,9 @@ npm install @ts-dspy/core
4242

4343
# OpenAI integration
4444
npm install @ts-dspy/openai
45+
46+
# Gemini integration
47+
npm install @ts-dspy/gemini
4548
```
4649

4750
**Requirements:**

examples/basic-gemini-example.ts

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
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 };

examples/basic-usage.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { configure, Predict, ChainOfThought, RespAct, Signature, InputField, OutputField } from '../packages/core/src/index';
2-
import { OpenAILM } from '../packages/openai/src/index';
1+
import { configure, Predict, ChainOfThought, RespAct, Signature, InputField, OutputField } from '@ts-dspy/core';
2+
import { OpenAILM } from '@ts-dspy/openai';
33

44
// Setup - configure global LM
55
configure({
66
lm: new OpenAILM({
7-
apiKey: process.env.OPENAI_API_KEY || 'OPENAPI KEY'
7+
apiKey: process.env.OPENAI_API_KEY || '***REDACTED*** '
88
})
99
});
1010

@@ -332,7 +332,7 @@ async function usageStatsExample() {
332332
console.log('\n=== Usage Statistics Example ===');
333333

334334
const lm = new OpenAILM({
335-
apiKey: process.env.OPENAI_API_KEY || 'OPENAPI KEY',
335+
apiKey: process.env.OPENAI_API_KEY || '***REDACTED*** ',
336336
model: 'gpt-3.5-turbo'
337337
});
338338

examples/tool-demo.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { configure, RespAct } from '../packages/core/src/index';
2-
import { OpenAILM } from '../packages/openai/src/index';
1+
import { configure, RespAct } from '@ts-dspy/core';
2+
import { OpenAILM } from '@ts-dspy/openai';
33

44
// Configure with your API key
55
configure({

examples/tool-descriptions-demo.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { configure, RespAct } from '../packages/core/src/index';
2-
import { OpenAILM } from '../packages/openai/src/index';
1+
import { configure, RespAct } from '@ts-dspy/core';
2+
import { OpenAILM } from '@ts-dspy/openai';
33

44
// Configure with your API key
55
configure({

examples/tsconfig.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"extends": "../tsconfig.json",
3+
"compilerOptions": {
4+
"composite": false,
5+
"declaration": false,
6+
"declarationMap": false,
7+
"sourceMap": true,
8+
"outDir": "./dist-examples", // Avoid conflicting with package builds
9+
"rootDir": "..",
10+
"paths": {
11+
"@ts-dspy/core": [
12+
"./packages/core/src"
13+
],
14+
"@ts-dspy/openai": [
15+
"./packages/openai/src"
16+
],
17+
"@ts-dspy/gemini": [
18+
"./packages/gemini/src"
19+
]
20+
},
21+
"baseUrl": ".."
22+
},
23+
"include": [
24+
"./**/*.ts"
25+
]
26+
}

lerna.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "0.2.3",
2+
"version": "0.3.0",
33
"npmClient": "npm",
44
"command": {
55
"publish": {
@@ -16,4 +16,4 @@
1616
"packages": [
1717
"packages/*"
1818
]
19-
}
19+
}

package-lock.json

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"clean": "npm run clean --workspaces",
1515
"dev": "npm run dev --workspaces",
1616
"install:all": "npm install",
17-
"run:example:openai": "npx ts-node examples/comprehensive-openai-example.ts"
17+
"run:example:openai": "npx ts-node --project examples/tsconfig.json examples/basic-usage.ts",
18+
"run:example:gemini": "npx ts-node --project examples/tsconfig.json examples/basic-gemini-example.ts"
1819
},
1920
"devDependencies": {
2021
"@types/jest": "^29.5.0",
@@ -38,4 +39,4 @@
3839
"type": "git",
3940
"url": "https://github.com/ardada2468/LLMTypeSafe.git"
4041
}
41-
}
42+
}

0 commit comments

Comments
 (0)