dspy 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +67 -385
- data/lib/dspy/chain_of_thought.rb +123 -86
- data/lib/dspy/evaluate.rb +554 -0
- data/lib/dspy/example.rb +203 -0
- data/lib/dspy/few_shot_example.rb +81 -0
- data/lib/dspy/instrumentation/token_tracker.rb +6 -6
- data/lib/dspy/instrumentation.rb +199 -18
- data/lib/dspy/lm/adapter_factory.rb +6 -8
- data/lib/dspy/lm.rb +79 -35
- data/lib/dspy/mixins/instrumentation_helpers.rb +133 -0
- data/lib/dspy/mixins/struct_builder.rb +133 -0
- data/lib/dspy/mixins/type_coercion.rb +67 -0
- data/lib/dspy/predict.rb +83 -128
- data/lib/dspy/prompt.rb +222 -0
- data/lib/dspy/propose/grounded_proposer.rb +560 -0
- data/lib/dspy/re_act.rb +242 -173
- data/lib/dspy/registry/registry_manager.rb +504 -0
- data/lib/dspy/registry/signature_registry.rb +725 -0
- data/lib/dspy/storage/program_storage.rb +442 -0
- data/lib/dspy/storage/storage_manager.rb +331 -0
- data/lib/dspy/subscribers/langfuse_subscriber.rb +669 -0
- data/lib/dspy/subscribers/logger_subscriber.rb +180 -5
- data/lib/dspy/subscribers/newrelic_subscriber.rb +686 -0
- data/lib/dspy/subscribers/otel_subscriber.rb +538 -0
- data/lib/dspy/teleprompt/data_handler.rb +107 -0
- data/lib/dspy/teleprompt/mipro_v2.rb +790 -0
- data/lib/dspy/teleprompt/simple_optimizer.rb +497 -0
- data/lib/dspy/teleprompt/teleprompter.rb +336 -0
- data/lib/dspy/teleprompt/utils.rb +380 -0
- data/lib/dspy/version.rb +5 -0
- data/lib/dspy.rb +105 -0
- metadata +32 -12
- data/lib/dspy/lm/adapters/ruby_llm_adapter.rb +0 -81
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd8c98014ede76d7f232ebbb1e46789efa57fdca83203548d0e9b564054d859d
|
4
|
+
data.tar.gz: f654cf96ac2976fbdd101e6d9d3b5b69346a5a32857cfcff2683e659173c9483
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 425bf005503285726f84aff2009e53cfcad853afc5b11cce7b600a978e5546ddf8cddd8d9e50d9e54701c26834ff47511d34719bf1a2f78c60f8e8b17a5d92e2
|
7
|
+
data.tar.gz: 6c2f6eeb7686a9e116642f8097154aee5610cfe75542973e973b4ba851f1c7428e71f6241a9502b7489fad40a59f35921fc377aa3af008fd506a17d18043320a
|
data/README.md
CHANGED
@@ -2,14 +2,9 @@
|
|
2
2
|
|
3
3
|
**Build reliable LLM applications in Ruby using composable, type-safe modules.**
|
4
4
|
|
5
|
-
DSPy.rb brings structured LLM programming to Ruby developers.
|
6
|
-
Instead of wrestling with prompt strings and parsing responses,
|
7
|
-
you define typed signatures and compose them into pipelines that just work.
|
5
|
+
DSPy.rb brings structured LLM programming to Ruby developers. Instead of wrestling with prompt strings and parsing responses, you define typed signatures and compose them into pipelines that just work.
|
8
6
|
|
9
|
-
Traditional prompting is like writing code with string concatenation: it works until
|
10
|
-
it doesn't. DSPy.rb brings you the programming approach pioneered
|
11
|
-
by [dspy.ai](https://dspy.ai/): instead of crafting fragile prompts, you define
|
12
|
-
modular signatures and let the framework handle the messy details.
|
7
|
+
Traditional prompting is like writing code with string concatenation: it works until it doesn't. DSPy.rb brings you the programming approach pioneered by [dspy.ai](https://dspy.ai/): instead of crafting fragile prompts, you define modular signatures and let the framework handle the messy details.
|
13
8
|
|
14
9
|
The result? LLM applications that actually scale and don't break when you sneeze.
|
15
10
|
|
@@ -19,36 +14,43 @@ The result? LLM applications that actually scale and don't break when you sneeze
|
|
19
14
|
- **Signatures** - Define input/output schemas using Sorbet types
|
20
15
|
- **Predict** - Basic LLM completion with structured data
|
21
16
|
- **Chain of Thought** - Step-by-step reasoning for complex problems
|
22
|
-
- **ReAct** - Tool-using agents
|
23
|
-
- **
|
24
|
-
|
25
|
-
|
17
|
+
- **ReAct** - Tool-using agents with basic tool integration
|
18
|
+
- **Manual Composition** - Combine multiple LLM calls into workflows
|
19
|
+
|
20
|
+
**Optimization & Evaluation:**
|
21
|
+
- **Prompt Objects** - Manipulate prompts as first-class objects instead of strings
|
22
|
+
- **Typed Examples** - Type-safe training data with automatic validation
|
23
|
+
- **Evaluation Framework** - Basic testing with simple metrics
|
24
|
+
- **Basic Optimization** - Simple prompt optimization techniques
|
25
|
+
|
26
|
+
**Production Features:**
|
27
|
+
- **File-based Storage** - Basic optimization result persistence
|
28
|
+
- **Multi-Platform Observability** - OpenTelemetry, New Relic, and Langfuse integration
|
29
|
+
- **Basic Instrumentation** - Event tracking and logging
|
30
|
+
|
31
|
+
**Developer Experience:**
|
32
|
+
- LLM provider support using official Ruby clients:
|
33
|
+
- [OpenAI Ruby](https://github.com/openai/openai-ruby)
|
34
|
+
- [Anthropic Ruby SDK](https://github.com/anthropics/anthropic-sdk-ruby)
|
26
35
|
- Runtime type checking with [Sorbet](https://sorbet.org/)
|
27
36
|
- Type-safe tool definitions for ReAct agents
|
37
|
+
- Comprehensive instrumentation and observability
|
28
38
|
|
29
39
|
## Fair Warning
|
30
40
|
|
31
|
-
This is fresh off the oven and evolving fast.
|
32
|
-
I'm actively building this as a Ruby port of the [DSPy library](https://dspy.ai/).
|
33
|
-
If you hit bugs or want to contribute, just email me directly!
|
41
|
+
This is fresh off the oven and evolving fast. I'm actively building this as a Ruby port of the [DSPy library](https://dspy.ai/). If you hit bugs or want to contribute, just email me directly!
|
34
42
|
|
35
|
-
##
|
36
|
-
These are my goals to release v1.0.
|
37
|
-
|
38
|
-
- Solidify prompt optimization
|
39
|
-
- OTel Integration
|
40
|
-
- Ollama support
|
43
|
+
## Quick Start
|
41
44
|
|
42
|
-
|
45
|
+
### Installation
|
43
46
|
|
44
47
|
Skip the gem for now - install straight from this repo while I prep the first release:
|
48
|
+
|
45
49
|
```ruby
|
46
50
|
gem 'dspy', github: 'vicentereig/dspy.rb'
|
47
51
|
```
|
48
52
|
|
49
|
-
|
50
|
-
|
51
|
-
### Simple Prediction
|
53
|
+
### Your First DSPy Program
|
52
54
|
|
53
55
|
```ruby
|
54
56
|
# Define a signature for sentiment classification
|
@@ -80,380 +82,60 @@ end
|
|
80
82
|
|
81
83
|
# Create the predictor and run inference
|
82
84
|
classify = DSPy::Predict.new(Classify)
|
83
|
-
result = classify.call(sentence: "This book was super fun to read
|
85
|
+
result = classify.call(sentence: "This book was super fun to read!")
|
84
86
|
|
85
|
-
# result is a properly typed T::Struct instance
|
86
87
|
puts result.sentiment # => #<Sentiment::Positive>
|
87
88
|
puts result.confidence # => 0.85
|
88
89
|
```
|
89
90
|
|
90
|
-
|
91
|
-
|
92
|
-
```ruby
|
93
|
-
class AnswerPredictor < DSPy::Signature
|
94
|
-
description "Provides a concise answer to the question"
|
95
|
-
|
96
|
-
input do
|
97
|
-
const :question, String
|
98
|
-
end
|
99
|
-
|
100
|
-
output do
|
101
|
-
const :answer, String
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
# Chain of thought automatically adds a 'reasoning' field to the output
|
106
|
-
qa_cot = DSPy::ChainOfThought.new(AnswerPredictor)
|
107
|
-
result = qa_cot.call(question: "Two dice are tossed. What is the probability that the sum equals two?")
|
108
|
-
|
109
|
-
puts result.reasoning # => "There is only one way to get a sum of 2..."
|
110
|
-
puts result.answer # => "1/36"
|
111
|
-
```
|
112
|
-
|
113
|
-
### ReAct Agents with Tools
|
114
|
-
|
115
|
-
```ruby
|
116
|
-
|
117
|
-
class DeepQA < DSPy::Signature
|
118
|
-
description "Answer questions with consideration for the context"
|
119
|
-
|
120
|
-
input do
|
121
|
-
const :question, String
|
122
|
-
end
|
123
|
-
|
124
|
-
output do
|
125
|
-
const :answer, String
|
126
|
-
end
|
127
|
-
end
|
91
|
+
## Documentation
|
128
92
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
tool_description 'Performs basic arithmetic operations'
|
134
|
-
|
135
|
-
sig { params(operation: String, num1: Float, num2: Float).returns(T.any(Float, String)) }
|
136
|
-
def call(operation:, num1:, num2:)
|
137
|
-
case operation.downcase
|
138
|
-
when 'add' then num1 + num2
|
139
|
-
when 'subtract' then num1 - num2
|
140
|
-
when 'multiply' then num1 * num2
|
141
|
-
when 'divide'
|
142
|
-
return "Error: Cannot divide by zero" if num2 == 0
|
143
|
-
num1 / num2
|
144
|
-
else
|
145
|
-
"Error: Unknown operation '#{operation}'. Use add, subtract, multiply, or divide"
|
146
|
-
end
|
147
|
-
end
|
93
|
+
### Getting Started
|
94
|
+
- **[Installation & Setup](docs/getting-started/installation.md)** - Detailed installation and configuration
|
95
|
+
- **[Quick Start Guide](docs/getting-started/quick-start.md)** - Your first DSPy programs
|
96
|
+
- **[Core Concepts](docs/getting-started/core-concepts.md)** - Understanding signatures, predictors, and modules
|
148
97
|
|
149
|
-
|
150
|
-
|
98
|
+
### Core Features
|
99
|
+
- **[Signatures & Types](docs/core-concepts/signatures.md)** - Define typed interfaces for LLM operations
|
100
|
+
- **[Predictors](docs/core-concepts/predictors.md)** - Predict, ChainOfThought, ReAct, and more
|
101
|
+
- **[Modules & Pipelines](docs/core-concepts/modules.md)** - Compose complex multi-stage workflows
|
102
|
+
- **[Examples & Validation](docs/core-concepts/examples.md)** - Type-safe training data
|
151
103
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
104
|
+
### Optimization
|
105
|
+
- **[Evaluation Framework](docs/optimization/evaluation.md)** - Basic testing with simple metrics
|
106
|
+
- **[Prompt Optimization](docs/optimization/prompt-optimization.md)** - Manipulate prompts as objects
|
107
|
+
- **[MIPROv2 Optimizer](docs/optimization/miprov2.md)** - Basic automatic optimization
|
108
|
+
- **[Simple Optimizer](docs/optimization/simple-optimizer.md)** - Random search experimentation
|
157
109
|
|
158
|
-
###
|
159
|
-
|
160
|
-
|
161
|
-
```ruby
|
110
|
+
### Production Features
|
111
|
+
- **[Storage System](docs/production/storage.md)** - Basic file-based persistence
|
112
|
+
- **[Observability](docs/production/observability.md)** - Multi-platform monitoring and metrics
|
162
113
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
description "Outline a thorough overview of a topic."
|
169
|
-
|
170
|
-
input do
|
171
|
-
const :topic, String
|
172
|
-
end
|
173
|
-
|
174
|
-
output do
|
175
|
-
const :title, String
|
176
|
-
const :sections, T::Array[String]
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
class DraftSection < DSPy::Signature
|
181
|
-
description "Draft a section of an article"
|
182
|
-
|
183
|
-
input do
|
184
|
-
const :topic, String
|
185
|
-
const :title, String
|
186
|
-
const :section, String
|
187
|
-
end
|
188
|
-
|
189
|
-
output do
|
190
|
-
const :content, String
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
class ArticleDrafter < DSPy::Module
|
195
|
-
def initialize
|
196
|
-
@build_outline = DSPy::ChainOfThought.new(Outline)
|
197
|
-
@draft_section = DSPy::ChainOfThought.new(DraftSection)
|
198
|
-
end
|
199
|
-
|
200
|
-
def forward(topic:)
|
201
|
-
outline = @build_outline.call(topic: topic)
|
202
|
-
|
203
|
-
sections = outline.sections.map do |section|
|
204
|
-
@draft_section.call(
|
205
|
-
topic: topic,
|
206
|
-
title: outline.title,
|
207
|
-
section: section
|
208
|
-
)
|
209
|
-
end
|
210
|
-
|
211
|
-
{
|
212
|
-
title: outline.title,
|
213
|
-
sections: sections.map(&:content)
|
214
|
-
}
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
```
|
219
|
-
|
220
|
-
## Working with Complex Types
|
221
|
-
|
222
|
-
### Enums
|
223
|
-
|
224
|
-
```ruby
|
225
|
-
class Color < T::Enum
|
226
|
-
enums do
|
227
|
-
Red = new
|
228
|
-
Green = new
|
229
|
-
Blue = new
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
|
-
class ColorSignature < DSPy::Signature
|
234
|
-
description "Identify the dominant color in a description"
|
235
|
-
|
236
|
-
input do
|
237
|
-
const :description, String,
|
238
|
-
description: 'Description of an object or scene'
|
239
|
-
end
|
240
|
-
|
241
|
-
output do
|
242
|
-
const :color, Color,
|
243
|
-
description: 'The dominant color (Red, Green, or Blue)'
|
244
|
-
end
|
245
|
-
end
|
114
|
+
### Advanced Usage
|
115
|
+
- **[Complex Types](docs/advanced/complex-types.md)** - Basic Sorbet type integration
|
116
|
+
- **[Manual Pipelines](docs/advanced/pipelines.md)** - Manual module composition patterns
|
117
|
+
- **[RAG Patterns](docs/advanced/rag.md)** - Manual RAG implementation with external services
|
118
|
+
- **[Custom Metrics](docs/advanced/custom-metrics.md)** - Proc-based evaluation logic
|
246
119
|
|
247
|
-
|
248
|
-
result = predictor.call(description: "A red apple on a wooden table")
|
249
|
-
puts result.color # => #<Color::Red>
|
250
|
-
```
|
251
|
-
|
252
|
-
### Optional Fields and Defaults
|
253
|
-
|
254
|
-
```ruby
|
255
|
-
class AnalysisSignature < DSPy::Signature
|
256
|
-
description "Analyze text with optional metadata"
|
257
|
-
|
258
|
-
input do
|
259
|
-
const :text, String,
|
260
|
-
description: 'Text to analyze'
|
261
|
-
const :include_metadata, T::Boolean,
|
262
|
-
description: 'Whether to include metadata in analysis',
|
263
|
-
default: false
|
264
|
-
end
|
265
|
-
|
266
|
-
output do
|
267
|
-
const :summary, String,
|
268
|
-
description: 'Summary of the text'
|
269
|
-
const :word_count, Integer,
|
270
|
-
description: 'Number of words (optional)',
|
271
|
-
default: 0
|
272
|
-
end
|
273
|
-
end
|
274
|
-
```
|
275
|
-
|
276
|
-
## Advanced Usage Patterns
|
277
|
-
|
278
|
-
### Multi-stage Pipelines
|
279
|
-
|
280
|
-
```ruby
|
281
|
-
class TopicSignature < DSPy::Signature
|
282
|
-
description "Extract main topic from text"
|
283
|
-
|
284
|
-
input do
|
285
|
-
const :content, String,
|
286
|
-
description: 'Text content to analyze'
|
287
|
-
end
|
288
|
-
|
289
|
-
output do
|
290
|
-
const :topic, String,
|
291
|
-
description: 'Main topic of the content'
|
292
|
-
end
|
293
|
-
end
|
294
|
-
|
295
|
-
class SummarySignature < DSPy::Signature
|
296
|
-
description "Create summary focusing on specific topic"
|
297
|
-
|
298
|
-
input do
|
299
|
-
const :content, String,
|
300
|
-
description: 'Original text content'
|
301
|
-
const :topic, String,
|
302
|
-
description: 'Topic to focus on'
|
303
|
-
end
|
304
|
-
|
305
|
-
output do
|
306
|
-
const :summary, String,
|
307
|
-
description: 'Topic-focused summary'
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
class ArticlePipeline < DSPy::Signature
|
312
|
-
extend T::Sig
|
313
|
-
|
314
|
-
def initialize
|
315
|
-
@topic_extractor = DSPy::Predict.new(TopicSignature)
|
316
|
-
@summarizer = DSPy::ChainOfThought.new(SummarySignature)
|
317
|
-
end
|
318
|
-
|
319
|
-
sig { params(content: String).returns(T.untyped) }
|
320
|
-
def forward(content:)
|
321
|
-
# Extract topic
|
322
|
-
topic_result = @topic_extractor.call(content: content)
|
323
|
-
|
324
|
-
# Create focused summary
|
325
|
-
summary_result = @summarizer.call(
|
326
|
-
content: content,
|
327
|
-
topic: topic_result.topic
|
328
|
-
)
|
329
|
-
|
330
|
-
{
|
331
|
-
topic: topic_result.topic,
|
332
|
-
summary: summary_result.summary,
|
333
|
-
reasoning: summary_result.reasoning
|
334
|
-
}
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
# Usage
|
339
|
-
pipeline = ArticlePipeline.new
|
340
|
-
result = pipeline.call(content: "Long article content...")
|
341
|
-
```
|
342
|
-
|
343
|
-
### Retrieval Augmented Generation
|
344
|
-
|
345
|
-
```ruby
|
346
|
-
class ContextualQA < DSPy::Signature
|
347
|
-
description "Answer questions using relevant context"
|
348
|
-
|
349
|
-
input do
|
350
|
-
const :question, String,
|
351
|
-
description: 'The question to answer'
|
352
|
-
const :context, T::Array[String],
|
353
|
-
description: 'Relevant context passages'
|
354
|
-
end
|
355
|
-
|
356
|
-
output do
|
357
|
-
const :answer, String,
|
358
|
-
description: 'Answer based on the provided context'
|
359
|
-
const :confidence, Float,
|
360
|
-
description: 'Confidence in the answer (0.0 to 1.0)'
|
361
|
-
end
|
362
|
-
end
|
363
|
-
|
364
|
-
# Usage with retriever
|
365
|
-
retriever = YourRetrieverClass.new
|
366
|
-
qa = DSPy::ChainOfThought.new(ContextualQA)
|
367
|
-
|
368
|
-
question = "What is the capital of France?"
|
369
|
-
context = retriever.retrieve(question) # Returns array of strings
|
370
|
-
|
371
|
-
result = qa.call(question: question, context: context)
|
372
|
-
puts result.reasoning # Step-by-step reasoning
|
373
|
-
puts result.answer # "Paris"
|
374
|
-
puts result.confidence # 0.95
|
375
|
-
```
|
376
|
-
|
377
|
-
## Instrumentation & Observability
|
378
|
-
|
379
|
-
DSPy.rb includes built-in instrumentation that captures detailed events and
|
380
|
-
performance metrics from your LLM operations. Perfect for monitoring your
|
381
|
-
applications and integrating with observability tools.
|
382
|
-
|
383
|
-
### Available Events
|
384
|
-
|
385
|
-
Subscribe to these events to monitor different aspects of your LLM operations:
|
386
|
-
|
387
|
-
| Event Name | Triggered When | Key Payload Fields |
|
388
|
-
|------------|----------------|-------------------|
|
389
|
-
| `dspy.lm.request` | LLM API request lifecycle | `gen_ai_system`, `model`, `provider`, `duration_ms`, `status` |
|
390
|
-
| `dspy.lm.tokens` | Token usage tracking | `tokens_input`, `tokens_output`, `tokens_total` |
|
391
|
-
| `dspy.predict` | Prediction operations | `signature_class`, `input_size`, `duration_ms`, `status` |
|
392
|
-
| `dspy.chain_of_thought` | CoT reasoning | `signature_class`, `model`, `duration_ms`, `status` |
|
393
|
-
| `dspy.react` | Agent operations | `max_iterations`, `tools_used`, `duration_ms`, `status` |
|
394
|
-
| `dspy.react.tool_call` | Tool execution | `tool_name`, `tool_input`, `tool_output`, `duration_ms` |
|
395
|
-
|
396
|
-
### Event Payloads
|
397
|
-
|
398
|
-
The instrumentation emits events with structured payloads you can process:
|
399
|
-
|
400
|
-
```ruby
|
401
|
-
# Example event payload for dspy.predict
|
402
|
-
{
|
403
|
-
signature_class: "QuestionAnswering",
|
404
|
-
model: "gpt-4o-mini",
|
405
|
-
provider: "openai",
|
406
|
-
input_size: 45,
|
407
|
-
duration_ms: 1234.56,
|
408
|
-
cpu_time_ms: 89.12,
|
409
|
-
status: "success",
|
410
|
-
timestamp: "2024-01-15T10:30:00Z"
|
411
|
-
}
|
412
|
-
|
413
|
-
# Example token usage payload
|
414
|
-
{
|
415
|
-
tokens_input: 150,
|
416
|
-
tokens_output: 45,
|
417
|
-
tokens_total: 195,
|
418
|
-
gen_ai_system: "openai",
|
419
|
-
signature_class: "QuestionAnswering"
|
420
|
-
}
|
421
|
-
```
|
422
|
-
|
423
|
-
Events are emitted via dry-monitor notifications, giving you flexibility to
|
424
|
-
process them however you need - logging, metrics, alerts, or custom monitoring.
|
425
|
-
|
426
|
-
### Token Tracking
|
427
|
-
|
428
|
-
Token usage is extracted from actual API responses (OpenAI and Anthropic only),
|
429
|
-
giving you precise cost tracking:
|
430
|
-
|
431
|
-
```ruby
|
432
|
-
# Token events include:
|
433
|
-
{
|
434
|
-
tokens_input: 150, # From API response
|
435
|
-
tokens_output: 45, # From API response
|
436
|
-
tokens_total: 195, # From API response
|
437
|
-
gen_ai_system: "openai",
|
438
|
-
gen_ai_request_model: "gpt-4o-mini"
|
439
|
-
}
|
440
|
-
```
|
441
|
-
|
442
|
-
### Integration with Monitoring Tools
|
443
|
-
|
444
|
-
Subscribe to events for custom processing:
|
120
|
+
## What's Next
|
445
121
|
|
446
|
-
|
447
|
-
# Subscribe to all LM events
|
448
|
-
DSPy::Instrumentation.subscribe('dspy.lm.*') do |event|
|
449
|
-
puts "#{event.id}: #{event.payload[:duration_ms]}ms"
|
450
|
-
end
|
122
|
+
These are my goals to release v1.0.
|
451
123
|
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
124
|
+
- ✅ Prompt objects foundation - *Done*
|
125
|
+
- ✅ Evaluation framework - *Done*
|
126
|
+
- ✅ Teleprompter base classes - *Done*
|
127
|
+
- ✅ MIPROv2 optimization algorithm - *Done*
|
128
|
+
- ✅ Storage & persistence system - *Done*
|
129
|
+
- ✅ Registry & version management - *Done*
|
130
|
+
- ✅ OpenTelemetry integration - *Done*
|
131
|
+
- ✅ New Relic integration - *Done*
|
132
|
+
- ✅ Langfuse integration - *Done*
|
133
|
+
- 🚧 Ollama support
|
134
|
+
- Context Engineering (see recent research: [How Contexts Fail](https://www.dbreunig.com/2025/06/22/how-contexts-fail-and-how-to-fix-them.html), [How to Fix Your Context](https://www.dbreunig.com/2025/06/26/how-to-fix-your-context.html), [Context Engineering](https://simonwillison.net/2025/Jun/27/context-engineering/))
|
135
|
+
- Agentic Memory support
|
136
|
+
- MCP Support
|
137
|
+
- Documentation website
|
138
|
+
- Performance benchmarks
|
457
139
|
|
458
140
|
## License
|
459
141
|
|