mirascope 2.0.0-alpha.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.
- package/README.md +397 -0
- package/dist/bun.cjs +447 -0
- package/dist/bun.cjs.map +1 -0
- package/dist/bun.d.cts +53 -0
- package/dist/bun.d.ts +53 -0
- package/dist/bun.js +94 -0
- package/dist/bun.js.map +1 -0
- package/dist/chunk-2R5IW35Y.js +116 -0
- package/dist/chunk-2R5IW35Y.js.map +1 -0
- package/dist/chunk-A6ZCB7BU.js +6826 -0
- package/dist/chunk-A6ZCB7BU.js.map +1 -0
- package/dist/chunk-NSBPE2FW.js +15 -0
- package/dist/chunk-NSBPE2FW.js.map +1 -0
- package/dist/chunk-RMNCGJYW.js +49 -0
- package/dist/chunk-RMNCGJYW.js.map +1 -0
- package/dist/chunk-U4MFJ4DP.js +358 -0
- package/dist/chunk-U4MFJ4DP.js.map +1 -0
- package/dist/index.cjs +7705 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +4859 -0
- package/dist/index.d.ts +4859 -0
- package/dist/index.js +324 -0
- package/dist/index.js.map +1 -0
- package/dist/model-T6IQ7UUA.js +4 -0
- package/dist/model-T6IQ7UUA.js.map +1 -0
- package/dist/tool-schema-Dh-RLHhC.d.cts +45 -0
- package/dist/tool-schema-Dh-RLHhC.d.ts +45 -0
- package/dist/transform/index.cjs +525 -0
- package/dist/transform/index.cjs.map +1 -0
- package/dist/transform/index.d.cts +89 -0
- package/dist/transform/index.d.ts +89 -0
- package/dist/transform/index.js +6 -0
- package/dist/transform/index.js.map +1 -0
- package/dist/transform/plugins/esbuild.cjs +472 -0
- package/dist/transform/plugins/esbuild.cjs.map +1 -0
- package/dist/transform/plugins/esbuild.d.cts +46 -0
- package/dist/transform/plugins/esbuild.d.ts +46 -0
- package/dist/transform/plugins/esbuild.js +5 -0
- package/dist/transform/plugins/esbuild.js.map +1 -0
- package/dist/transform/plugins/vite.cjs +405 -0
- package/dist/transform/plugins/vite.cjs.map +1 -0
- package/dist/transform/plugins/vite.d.cts +50 -0
- package/dist/transform/plugins/vite.d.ts +50 -0
- package/dist/transform/plugins/vite.js +5 -0
- package/dist/transform/plugins/vite.js.map +1 -0
- package/package.json +127 -0
package/README.md
ADDED
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
# Mirascope TypeScript (Alpha)
|
|
2
|
+
|
|
3
|
+
The TypeScript implementation of Mirascope: a type-safe, ergonomic library for building LLM-powered applications. Like its Python counterpart, Mirascope TypeScript provides a "Goldilocks API" - more control than agent frameworks, more ergonomic than raw provider APIs.
|
|
4
|
+
|
|
5
|
+
> [!IMPORTANT]
|
|
6
|
+
> **Alpha Status**: This is an early release. APIs may change.
|
|
7
|
+
> We welcome feedback and contributions!
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Using bun
|
|
13
|
+
bun add mirascope@alpha
|
|
14
|
+
|
|
15
|
+
# Using npm
|
|
16
|
+
npm install mirascope@alpha
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quickstart
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { llm } from "mirascope";
|
|
23
|
+
|
|
24
|
+
// Simple call
|
|
25
|
+
const model = llm.model("anthropic/claude-haiku-4-5")
|
|
26
|
+
const response = await model.call("What's the best way to learn TypeScript?");
|
|
27
|
+
console.log(response.text());
|
|
28
|
+
|
|
29
|
+
// Streaming
|
|
30
|
+
const stream = await model.stream("Tell me a joke");
|
|
31
|
+
for await (const text of stream.textStream()) {
|
|
32
|
+
process.stdout.write(text);
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Defining Calls
|
|
37
|
+
|
|
38
|
+
Use `defineCall` to create reusable, type-safe call functions:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { llm } from "mirascope";
|
|
42
|
+
|
|
43
|
+
const recommendBook = llm.defineCall<{ genre: string }>({
|
|
44
|
+
model: "anthropic/claude-haiku-4-5",
|
|
45
|
+
maxTokens: 1024,
|
|
46
|
+
template: ({ genre }) => `Please recommend a book in ${genre}.`,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const response = await recommendBook({ genre: "fantasy" });
|
|
50
|
+
console.log(response.text());
|
|
51
|
+
|
|
52
|
+
// Streaming
|
|
53
|
+
const stream = await recommendBook.stream({ genre: "sci-fi" });
|
|
54
|
+
for await (const text of stream.textStream()) {
|
|
55
|
+
process.stdout.write(text);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Structured Output
|
|
60
|
+
|
|
61
|
+
> [!NOTE]
|
|
62
|
+
> TypeScript interface patterns (non-Zod) require a compile-time transform. See [Transform Plugin](#transform-plugin) for setup instructions.
|
|
63
|
+
|
|
64
|
+
### With Zod Schema
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { llm } from "mirascope";
|
|
68
|
+
import { z } from "zod";
|
|
69
|
+
|
|
70
|
+
const BookSchema = z.object({
|
|
71
|
+
title: z.string().describe("The book title"),
|
|
72
|
+
author: z.string().describe("The author's name"),
|
|
73
|
+
year: z.number().int().describe("Publication year"),
|
|
74
|
+
});
|
|
75
|
+
type Book = z.infer<typeof BookSchema>;
|
|
76
|
+
|
|
77
|
+
const recommendBook = llm.defineCall<{ genre: string }>({
|
|
78
|
+
model: "anthropic/claude-haiku-4-5",
|
|
79
|
+
format: BookSchema,
|
|
80
|
+
template: ({ genre }) => `Recommend a ${genre} book.`,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const response = await recommendBook({ genre: "mystery" });
|
|
84
|
+
const book: Book = response.parse();
|
|
85
|
+
console.log(`${book.title} by ${book.author} (${book.year})`);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### With TypeScript Interface
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { llm } from "mirascope";
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* A book recommendation.
|
|
95
|
+
*/
|
|
96
|
+
type Book = {
|
|
97
|
+
/** The book title */
|
|
98
|
+
title: string;
|
|
99
|
+
/** The author's name */
|
|
100
|
+
author: string;
|
|
101
|
+
/** Publication year */
|
|
102
|
+
year: number;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const recommendBook = llm.defineCall<{ genre: string }, Book>({
|
|
106
|
+
model: "anthropic/claude-haiku-4-5",
|
|
107
|
+
template: ({ genre }) => `Recommend a ${genre} book.`,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const response = await recommendBook({ genre: "mystery" });
|
|
111
|
+
const book: Book = response.parse();
|
|
112
|
+
console.log(`${book.title} by ${book.author} (${book.year})`);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Tools
|
|
116
|
+
|
|
117
|
+
> [!NOTE]
|
|
118
|
+
> TypeScript interface patterns (non-Zod) require a compile-time transform. See [Transform Plugin](#transform-plugin) for setup instructions.
|
|
119
|
+
|
|
120
|
+
### With Zod Schema
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { llm } from "mirascope";
|
|
124
|
+
import { z } from "zod";
|
|
125
|
+
|
|
126
|
+
const getWeather = llm.defineTool({
|
|
127
|
+
name: "get_weather",
|
|
128
|
+
description: "Get the current weather for a location",
|
|
129
|
+
validator: z.object({
|
|
130
|
+
city: z.string().describe("The city name"),
|
|
131
|
+
units: z.enum(["celsius", "fahrenheit"]).default("celsius"),
|
|
132
|
+
}),
|
|
133
|
+
tool: ({ city, units }) => {
|
|
134
|
+
return { city, temperature: 22, units };
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const assistant = llm.defineCall<{ query: string }>({
|
|
139
|
+
model: "openai/gpt-4o-mini",
|
|
140
|
+
tools: [getWeather],
|
|
141
|
+
template: ({ query }) => query,
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
let response = await assistant({ query: "What's the weather in Tokyo?" });
|
|
145
|
+
|
|
146
|
+
// Execute tools and resume until no more tool calls
|
|
147
|
+
while (response.toolCalls.length > 0) {
|
|
148
|
+
const toolOutputs = await response.executeTools();
|
|
149
|
+
response = await response.resume(toolOutputs);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
console.log(response.text());
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### With TypeScript Interface
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
import { llm } from "mirascope";
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Arguments for the weather tool.
|
|
162
|
+
*/
|
|
163
|
+
type WeatherArgs = {
|
|
164
|
+
/** The city name */
|
|
165
|
+
city: string;
|
|
166
|
+
/** Temperature units */
|
|
167
|
+
units: "celsius" | "fahrenheit";
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const getWeather = llm.defineTool<WeatherArgs>({
|
|
171
|
+
name: "get_weather",
|
|
172
|
+
description: "Get the current weather for a location",
|
|
173
|
+
tool: ({ city, units }) => {
|
|
174
|
+
return { city, temperature: 22, units };
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
const assistant = llm.defineCall<{ query: string }>({
|
|
179
|
+
model: "openai/gpt-4o-mini",
|
|
180
|
+
tools: [getWeather],
|
|
181
|
+
template: ({ query }) => query,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
let response = await assistant({ query: "What's the weather in Tokyo?" });
|
|
185
|
+
|
|
186
|
+
while (response.toolCalls.length > 0) {
|
|
187
|
+
const toolOutputs = await response.executeTools();
|
|
188
|
+
response = await response.resume(toolOutputs);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
console.log(response.text());
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Context
|
|
195
|
+
|
|
196
|
+
Share dependencies (like databases, APIs, etc.) with your tools using context:
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
import { llm, type Context } from "mirascope";
|
|
200
|
+
import { z } from "zod";
|
|
201
|
+
|
|
202
|
+
interface AppDeps {
|
|
203
|
+
db: { getUser: (id: string) => { name: string } };
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const getUserInfo = llm.defineContextTool({
|
|
207
|
+
name: "get_user",
|
|
208
|
+
description: "Look up user information",
|
|
209
|
+
validator: z.object({
|
|
210
|
+
userId: z.string().describe("The user ID to look up"),
|
|
211
|
+
}),
|
|
212
|
+
tool: (ctx: Context<AppDeps>, { userId }) => {
|
|
213
|
+
return ctx.deps.db.getUser(userId);
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const assistant = llm.defineCall<{ ctx: Context<AppDeps>; query: string }>()({
|
|
218
|
+
model: "openai/gpt-4o-mini",
|
|
219
|
+
tools: [getUserInfo],
|
|
220
|
+
template: ({ query }) => query,
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const ctx = llm.createContext<AppDeps>({ db: myDatabase });
|
|
224
|
+
let response = await assistant(ctx, { query: "Tell me about user 123" });
|
|
225
|
+
|
|
226
|
+
while (response.toolCalls.length > 0) {
|
|
227
|
+
const toolOutputs = await response.executeTools(ctx);
|
|
228
|
+
response = await response.resume(ctx, toolOutputs);
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Provider Configuration
|
|
233
|
+
|
|
234
|
+
### Custom API Keys
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
import { llm } from "mirascope";
|
|
238
|
+
|
|
239
|
+
// Use a different API key
|
|
240
|
+
llm.registerProvider("openai", { apiKey: "sk-my-key" });
|
|
241
|
+
|
|
242
|
+
// Or a custom endpoint
|
|
243
|
+
llm.registerProvider("anthropic", { baseURL: "https://my-proxy.example.com" });
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### OpenAI-Compatible Providers
|
|
247
|
+
|
|
248
|
+
Route any OpenAI-compatible provider through the OpenAI adapter:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
import { llm } from "mirascope";
|
|
252
|
+
|
|
253
|
+
// Route grok/ models through xAI's OpenAI-compatible endpoint
|
|
254
|
+
llm.registerProvider("openai", {
|
|
255
|
+
scope: "grok/",
|
|
256
|
+
baseURL: "https://api.x.ai/v1",
|
|
257
|
+
apiKey: process.env.XAI_API_KEY,
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
const response = await llm.model("grok/grok-4-latest").call("Hello!");
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Transform Plugin
|
|
264
|
+
|
|
265
|
+
The transform plugin extracts type information from TypeScript interfaces at compile time, enabling the native TypeScript patterns (without Zod) for tools and structured output. This is **optional** - you can use Zod schemas without any build configuration.
|
|
266
|
+
|
|
267
|
+
### Vite
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
// vite.config.ts
|
|
271
|
+
import { defineConfig } from "vite";
|
|
272
|
+
import { mirascope } from "mirascope/vite";
|
|
273
|
+
|
|
274
|
+
export default defineConfig({
|
|
275
|
+
plugins: [mirascope()],
|
|
276
|
+
});
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### esbuild
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import * as esbuild from "esbuild";
|
|
283
|
+
import { mirascope } from "mirascope/esbuild";
|
|
284
|
+
|
|
285
|
+
await esbuild.build({
|
|
286
|
+
entryPoints: ["src/index.ts"],
|
|
287
|
+
bundle: true,
|
|
288
|
+
outfile: "dist/bundle.js",
|
|
289
|
+
plugins: [mirascope()],
|
|
290
|
+
});
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Bun
|
|
294
|
+
|
|
295
|
+
Bun supports a preload script that applies the transform at runtime:
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
// preload.ts
|
|
299
|
+
import { mirascope } from "mirascope/bun";
|
|
300
|
+
mirascope();
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
```toml
|
|
304
|
+
# bunfig.toml
|
|
305
|
+
preload = ["./preload.ts"]
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Now `bun run your-script.ts` will automatically apply the transform.
|
|
309
|
+
|
|
310
|
+
Alternatively, for production builds, use esbuild:
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
// build.ts
|
|
314
|
+
import { mirascope } from "mirascope/esbuild";
|
|
315
|
+
|
|
316
|
+
await Bun.build({
|
|
317
|
+
entrypoints: ["src/index.ts"],
|
|
318
|
+
outdir: "dist",
|
|
319
|
+
plugins: [mirascope()],
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## Error Handling
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
import { llm } from "mirascope";
|
|
327
|
+
|
|
328
|
+
try {
|
|
329
|
+
const response = await llm.model("openai/gpt-4o").call("Hello");
|
|
330
|
+
} catch (e) {
|
|
331
|
+
if (e instanceof llm.AuthenticationError) {
|
|
332
|
+
console.log("Invalid API key");
|
|
333
|
+
} else if (e instanceof llm.RateLimitError) {
|
|
334
|
+
console.log("Rate limited - try again later");
|
|
335
|
+
} else if (e instanceof llm.MirascopeError) {
|
|
336
|
+
console.log("LLM error:", e.message);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## Supported Providers
|
|
342
|
+
|
|
343
|
+
- **Anthropic**: `anthropic/claude-sonnet-4-5`, `anthropic/claude-haiku-4-5`, etc.
|
|
344
|
+
- **OpenAI**: `openai/gpt-4o`, `openai/gpt-4o-mini`, etc.
|
|
345
|
+
- **Google**: `google/gemini-2.0-flash`, `google/gemini-2.5-pro`, etc.
|
|
346
|
+
- **Ollama**: `ollama/llama3.2`, etc. (local models)
|
|
347
|
+
- **Together**: `together/meta-llama/...`, etc.
|
|
348
|
+
- Any OpenAI-compatible provider via `registerProvider`
|
|
349
|
+
|
|
350
|
+
## Development Setup
|
|
351
|
+
|
|
352
|
+
1. **Clone and install**:
|
|
353
|
+
```bash
|
|
354
|
+
cd typescript
|
|
355
|
+
bun install
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
2. **Environment variables** (for e2e tests):
|
|
359
|
+
```bash
|
|
360
|
+
cp .env.example .env
|
|
361
|
+
# Add your API keys
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
3. **Commands**:
|
|
365
|
+
```bash
|
|
366
|
+
bun run typecheck # Type checking
|
|
367
|
+
bun run lint # Linting + formatting
|
|
368
|
+
bun run test # Run tests
|
|
369
|
+
bun run test:coverage # Tests with coverage (requires 100%)
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
## Examples
|
|
373
|
+
|
|
374
|
+
See the [`examples/`](./examples) directory for more examples:
|
|
375
|
+
|
|
376
|
+
- `calls/` - Basic and advanced call patterns
|
|
377
|
+
- `tools/` - Tool definition and execution
|
|
378
|
+
- `format/` - Structured output with Zod
|
|
379
|
+
- `streaming/` - Streaming responses
|
|
380
|
+
- `context/` - Sharing dependencies with context
|
|
381
|
+
- `chaining/` - Chaining and parallel calls
|
|
382
|
+
- `reliability/` - Retry and fallback patterns
|
|
383
|
+
|
|
384
|
+
Run an example:
|
|
385
|
+
```bash
|
|
386
|
+
bun run example examples/calls/basic.ts
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## Contributing
|
|
390
|
+
|
|
391
|
+
We welcome contributions! Please ensure:
|
|
392
|
+
|
|
393
|
+
1. `bun run typecheck` passes
|
|
394
|
+
2. `bun run lint` passes
|
|
395
|
+
3. `bun run test:coverage` shows 100% coverage
|
|
396
|
+
|
|
397
|
+
For more info, see [the contributing page in our docs](https://mirascope.com/docs/contributing).
|