extrait 0.5.2 → 0.5.3
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 +44 -3
- package/dist/conversation.d.ts +8 -0
- package/dist/index.cjs +17 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +17 -0
- package/dist/prompt.d.ts +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -175,19 +175,27 @@ const result = await llm.structured(
|
|
|
175
175
|
Use `images()` to build base64 image content blocks for vision-capable models.
|
|
176
176
|
|
|
177
177
|
```typescript
|
|
178
|
-
import { images } from "extrait";
|
|
178
|
+
import { images, prompt } from "extrait";
|
|
179
179
|
import { readFileSync } from "fs";
|
|
180
180
|
|
|
181
181
|
const base64 = readFileSync("photo.png").toString("base64");
|
|
182
|
+
const img = { base64, mimeType: "image/png" };
|
|
182
183
|
|
|
183
|
-
//
|
|
184
|
+
// With prompt() builder — pass LLMMessageContent array to .user() or .assistant()
|
|
185
|
+
const result = await llm.structured(Schema,
|
|
186
|
+
prompt()
|
|
187
|
+
.system`You are a vision assistant.`
|
|
188
|
+
.user([{ type: "text", text: "Describe this image." }, ...images(img)])
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
// With raw messages array
|
|
184
192
|
const result = await llm.structured(Schema, {
|
|
185
193
|
messages: [
|
|
186
194
|
{
|
|
187
195
|
role: "user",
|
|
188
196
|
content: [
|
|
189
197
|
{ type: "text", text: "Describe this image." },
|
|
190
|
-
...images(
|
|
198
|
+
...images(img),
|
|
191
199
|
],
|
|
192
200
|
},
|
|
193
201
|
],
|
|
@@ -205,6 +213,38 @@ const content = [
|
|
|
205
213
|
|
|
206
214
|
`images()` accepts a single `{ base64, mimeType }` object or an array, and always returns an `LLMImageContent[]` that spreads directly into a content array.
|
|
207
215
|
|
|
216
|
+
### Conversations (multi-turn history)
|
|
217
|
+
|
|
218
|
+
Use `conversation()` to build a `LLMMessage[]` from an existing conversation history. This is the idiomatic way to pass prior turns to the LLM.
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
import { conversation } from "extrait";
|
|
222
|
+
|
|
223
|
+
const messages = conversation("You are a helpful assistant.", [
|
|
224
|
+
{ role: "user", text: "What is the speed of light?" },
|
|
225
|
+
{ role: "assistant", text: "Approximately 299,792 km/s in a vacuum." },
|
|
226
|
+
{ role: "user", text: "How long does light take to reach Earth from the Sun?" },
|
|
227
|
+
]);
|
|
228
|
+
|
|
229
|
+
// Pass to adapter directly
|
|
230
|
+
const response = await llm.adapter.complete({ messages });
|
|
231
|
+
|
|
232
|
+
// Or to structured extraction
|
|
233
|
+
const result = await llm.structured(Schema, { messages });
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Entries with `images` produce multimodal content automatically:
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
const messages = conversation("You are a vision assistant.", [
|
|
240
|
+
{
|
|
241
|
+
role: "user",
|
|
242
|
+
text: "What is in this image?",
|
|
243
|
+
images: [{ base64, mimeType: "image/png" }],
|
|
244
|
+
},
|
|
245
|
+
]);
|
|
246
|
+
```
|
|
247
|
+
|
|
208
248
|
### Result Object
|
|
209
249
|
|
|
210
250
|
```typescript
|
|
@@ -329,6 +369,7 @@ Available examples:
|
|
|
329
369
|
- `multi-step-reasoning` - Chained structured calls ([multi-step-reasoning.ts](examples/multi-step-reasoning.ts))
|
|
330
370
|
- `calculator-tool` - MCP tool integration ([calculator-tool.ts](examples/calculator-tool.ts))
|
|
331
371
|
- `image-analysis` - Multimodal structured extraction from an image file ([image-analysis.ts](examples/image-analysis.ts))
|
|
372
|
+
- `conversation` - Multi-turn conversation history and inline image messages ([conversation.ts](examples/conversation.ts))
|
|
332
373
|
|
|
333
374
|
Pass arguments after the example name:
|
|
334
375
|
```bash
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ImageInput } from "./image";
|
|
2
|
+
import type { LLMMessage } from "./types";
|
|
3
|
+
export interface ConversationEntry {
|
|
4
|
+
role: "user" | "assistant";
|
|
5
|
+
text: string;
|
|
6
|
+
images?: ImageInput[];
|
|
7
|
+
}
|
|
8
|
+
export declare function conversation(systemPrompt: string, entries: ConversationEntry[]): LLMMessage[];
|
package/dist/index.cjs
CHANGED
|
@@ -64,6 +64,7 @@ __export(exports_src, {
|
|
|
64
64
|
createLLM: () => createLLM,
|
|
65
65
|
createDefaultProviderRegistry: () => createDefaultProviderRegistry,
|
|
66
66
|
createAnthropicCompatibleAdapter: () => createAnthropicCompatibleAdapter,
|
|
67
|
+
conversation: () => conversation,
|
|
67
68
|
buildSelfHealPrompt: () => buildSelfHealPrompt,
|
|
68
69
|
buildDefaultStructuredPrompt: () => buildDefaultStructuredPrompt,
|
|
69
70
|
StructuredParseError: () => StructuredParseError,
|
|
@@ -4950,6 +4951,16 @@ async function resizeImage(source, size, mimeType) {
|
|
|
4950
4951
|
const buf = await img.toFormat(sharpFormat).toBuffer();
|
|
4951
4952
|
return { base64: buf.toString("base64"), mimeType: outputMime };
|
|
4952
4953
|
}
|
|
4954
|
+
// src/conversation.ts
|
|
4955
|
+
function conversation(systemPrompt, entries) {
|
|
4956
|
+
return [
|
|
4957
|
+
{ role: "system", content: systemPrompt },
|
|
4958
|
+
...entries.map((entry) => ({
|
|
4959
|
+
role: entry.role,
|
|
4960
|
+
content: entry.images && entry.images.length > 0 ? [{ type: "text", text: entry.text }, ...images(entry.images)] : entry.text
|
|
4961
|
+
}))
|
|
4962
|
+
];
|
|
4963
|
+
}
|
|
4953
4964
|
// src/prompt.ts
|
|
4954
4965
|
function toPromptString(value) {
|
|
4955
4966
|
if (value === null || value === undefined) {
|
|
@@ -5024,6 +5035,12 @@ class PromptMessageBuilderImpl {
|
|
|
5024
5035
|
return this.pushMessage("assistant", input, values);
|
|
5025
5036
|
}
|
|
5026
5037
|
pushMessage(role, input, values) {
|
|
5038
|
+
if (Array.isArray(input) && !isTemplateStringsArray(input)) {
|
|
5039
|
+
if (input.length > 0) {
|
|
5040
|
+
this.messages.push({ role, content: input });
|
|
5041
|
+
}
|
|
5042
|
+
return this;
|
|
5043
|
+
}
|
|
5027
5044
|
const message = toPromptMessage(input, values);
|
|
5028
5045
|
if (message.length > 0) {
|
|
5029
5046
|
this.messages.push({ role, content: message });
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { createLLM, type CreateLLMOptions, type LLMClient } from "./llm";
|
|
|
6
6
|
export { formatZodIssues, parseLLMOutput } from "./parse";
|
|
7
7
|
export { createMCPClient, wrapMCPClient, type CreateMCPClientOptions, type MCPClientInfo, type MCPInMemoryTransportConfig, type MCPStdioTransportConfig, type MCPStreamableHTTPTransportConfig, type MCPTransportConfig, type ManagedMCPToolClient, } from "./mcp";
|
|
8
8
|
export { images, resizeImage, type ImageInput, type ImageSize } from "./image";
|
|
9
|
+
export { conversation, type ConversationEntry } from "./conversation";
|
|
9
10
|
export { prompt, type PromptMessageBuilder } from "./prompt";
|
|
10
11
|
export { s, inspectSchemaMetadata, inferSchemaExample } from "./schema-builder";
|
|
11
12
|
export { buildDefaultStructuredPrompt, DEFAULT_LOOSE_PARSE_OPTIONS, DEFAULT_SELF_HEAL_BY_MODE, DEFAULT_SELF_HEAL_CONTEXT_LABEL, DEFAULT_SELF_HEAL_FIX_INSTRUCTION, DEFAULT_SELF_HEAL_MAX_CONTEXT_CHARS, DEFAULT_SELF_HEAL_NO_ISSUES_MESSAGE, DEFAULT_SELF_HEAL_PROTOCOL, DEFAULT_SELF_HEAL_RAW_OUTPUT_LABEL, DEFAULT_SELF_HEAL_RETURN_INSTRUCTION, DEFAULT_SELF_HEAL_STOP_ON_NO_PROGRESS, DEFAULT_SELF_HEAL_VALIDATION_LABEL, DEFAULT_STRICT_PARSE_OPTIONS, DEFAULT_STRUCTURED_OBJECT_INSTRUCTION, DEFAULT_STRUCTURED_STYLE_INSTRUCTION, buildSelfHealPrompt, structured, StructuredParseError, type BuildDefaultStructuredPromptOptions, type SelfHealPromptTextOptions, } from "./structured";
|
package/dist/index.js
CHANGED
|
@@ -4866,6 +4866,16 @@ async function resizeImage(source, size, mimeType) {
|
|
|
4866
4866
|
const buf = await img.toFormat(sharpFormat).toBuffer();
|
|
4867
4867
|
return { base64: buf.toString("base64"), mimeType: outputMime };
|
|
4868
4868
|
}
|
|
4869
|
+
// src/conversation.ts
|
|
4870
|
+
function conversation(systemPrompt, entries) {
|
|
4871
|
+
return [
|
|
4872
|
+
{ role: "system", content: systemPrompt },
|
|
4873
|
+
...entries.map((entry) => ({
|
|
4874
|
+
role: entry.role,
|
|
4875
|
+
content: entry.images && entry.images.length > 0 ? [{ type: "text", text: entry.text }, ...images(entry.images)] : entry.text
|
|
4876
|
+
}))
|
|
4877
|
+
];
|
|
4878
|
+
}
|
|
4869
4879
|
// src/prompt.ts
|
|
4870
4880
|
function toPromptString(value) {
|
|
4871
4881
|
if (value === null || value === undefined) {
|
|
@@ -4940,6 +4950,12 @@ class PromptMessageBuilderImpl {
|
|
|
4940
4950
|
return this.pushMessage("assistant", input, values);
|
|
4941
4951
|
}
|
|
4942
4952
|
pushMessage(role, input, values) {
|
|
4953
|
+
if (Array.isArray(input) && !isTemplateStringsArray(input)) {
|
|
4954
|
+
if (input.length > 0) {
|
|
4955
|
+
this.messages.push({ role, content: input });
|
|
4956
|
+
}
|
|
4957
|
+
return this;
|
|
4958
|
+
}
|
|
4943
4959
|
const message = toPromptMessage(input, values);
|
|
4944
4960
|
if (message.length > 0) {
|
|
4945
4961
|
this.messages.push({ role, content: message });
|
|
@@ -5170,6 +5186,7 @@ export {
|
|
|
5170
5186
|
createLLM,
|
|
5171
5187
|
createDefaultProviderRegistry,
|
|
5172
5188
|
createAnthropicCompatibleAdapter,
|
|
5189
|
+
conversation,
|
|
5173
5190
|
buildSelfHealPrompt,
|
|
5174
5191
|
buildDefaultStructuredPrompt,
|
|
5175
5192
|
StructuredParseError,
|
package/dist/prompt.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import type { StructuredPromptPayload, StructuredPromptResolver } from "./types";
|
|
1
|
+
import type { LLMMessageContent, StructuredPromptPayload, StructuredPromptResolver } from "./types";
|
|
2
2
|
export interface PromptMessageBuilder extends StructuredPromptResolver {
|
|
3
3
|
system(input: string): PromptMessageBuilder;
|
|
4
4
|
system(strings: TemplateStringsArray, ...values: unknown[]): PromptMessageBuilder;
|
|
5
5
|
user(input: string): PromptMessageBuilder;
|
|
6
6
|
user(strings: TemplateStringsArray, ...values: unknown[]): PromptMessageBuilder;
|
|
7
|
+
user(content: LLMMessageContent): PromptMessageBuilder;
|
|
7
8
|
assistant(input: string): PromptMessageBuilder;
|
|
8
9
|
assistant(strings: TemplateStringsArray, ...values: unknown[]): PromptMessageBuilder;
|
|
10
|
+
assistant(content: LLMMessageContent): PromptMessageBuilder;
|
|
9
11
|
build(): StructuredPromptPayload;
|
|
10
12
|
}
|
|
11
13
|
export declare function prompt(strings: TemplateStringsArray, ...values: unknown[]): string;
|