@refrakt-md/ai 0.1.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.
@@ -0,0 +1,8 @@
1
+ export { generateSystemPrompt } from './prompt.js';
2
+ export type { RuneInfo } from './prompt.js';
3
+ export type { AIProvider, CompletionOptions, Message } from './provider.js';
4
+ export { createAnthropicProvider } from './providers/anthropic.js';
5
+ export type { AnthropicOptions } from './providers/anthropic.js';
6
+ export { createOllamaProvider } from './providers/ollama.js';
7
+ export type { OllamaOptions } from './providers/ollama.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { generateSystemPrompt } from './prompt.js';
2
+ export { createAnthropicProvider } from './providers/anthropic.js';
3
+ export { createOllamaProvider } from './providers/ollama.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Rune metadata interface — structurally compatible with Rune from @refrakt-md/runes
3
+ * without requiring a runtime dependency.
4
+ */
5
+ export interface RuneInfo {
6
+ name: string;
7
+ aliases: string[];
8
+ description: string;
9
+ reinterprets: Record<string, string>;
10
+ schema: {
11
+ attributes?: Record<string, {
12
+ type?: unknown;
13
+ required?: boolean;
14
+ matches?: unknown;
15
+ }>;
16
+ };
17
+ }
18
+ export declare function generateSystemPrompt(runes: Record<string, RuneInfo>): string;
19
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,MAAM,EAAE;QACP,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;YAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;YACf,QAAQ,CAAC,EAAE,OAAO,CAAC;YACnB,OAAO,CAAC,EAAE,OAAO,CAAC;SAClB,CAAC,CAAC;KACH,CAAC;CACF;AAqUD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,CA8B5E"}
package/dist/prompt.js ADDED
@@ -0,0 +1,320 @@
1
+ /** Runes that are internal or child-only — excluded from prompts */
2
+ const EXCLUDED_RUNES = new Set([
3
+ 'error',
4
+ 'definition',
5
+ 'step',
6
+ 'tab',
7
+ 'music-recording',
8
+ 'accordion-item',
9
+ 'timeline-entry',
10
+ 'changelog-release',
11
+ 'breadcrumb-item',
12
+ ]);
13
+ /** Usage examples for each author-facing rune */
14
+ const RUNE_EXAMPLES = {
15
+ hint: `{% hint type="note" %}
16
+ This is a helpful note for your readers.
17
+ {% /hint %}`,
18
+ cta: `{% cta %}
19
+ # Your Headline
20
+
21
+ A compelling description of what you're offering.
22
+
23
+ - [Get Started](/docs/getting-started)
24
+ - [Learn More](/about)
25
+ {% /cta %}`,
26
+ feature: `{% feature %}
27
+ ## Key Features
28
+
29
+ - **Fast builds**
30
+
31
+ Static generation with incremental rebuilds.
32
+
33
+ - **Type-safe content**
34
+
35
+ Every rune produces typed, validated output.
36
+
37
+ - **Zero config**
38
+
39
+ Convention-based project structure.
40
+ {% /feature %}`,
41
+ grid: `{% grid %}
42
+ Column one content.
43
+
44
+ ---
45
+
46
+ Column two content.
47
+
48
+ ---
49
+
50
+ Column three content.
51
+ {% /grid %}`,
52
+ steps: `{% steps %}
53
+ 1. Install dependencies
54
+
55
+ Run \`npm install\` to get started.
56
+
57
+ 2. Create content
58
+
59
+ Add Markdown files to the \`content/\` directory.
60
+
61
+ 3. Start the server
62
+
63
+ Run \`npm run dev\` to preview your site.
64
+ {% /steps %}`,
65
+ tabs: `{% tabs %}
66
+ ## npm
67
+
68
+ \`\`\`shell
69
+ npm install @refrakt-md/runes
70
+ \`\`\`
71
+
72
+ ## yarn
73
+
74
+ \`\`\`shell
75
+ yarn add @refrakt-md/runes
76
+ \`\`\`
77
+ {% /tabs %}`,
78
+ codegroup: `{% codegroup %}
79
+ \`\`\`js
80
+ console.log('Hello');
81
+ \`\`\`
82
+
83
+ \`\`\`python
84
+ print('Hello')
85
+ \`\`\`
86
+ {% /codegroup %}`,
87
+ pricing: `{% pricing %}
88
+ # Pricing
89
+
90
+ Choose the plan that works for you.
91
+
92
+ {% tier name="Free" priceMonthly="$0" %}
93
+ - 1 project
94
+ - Community support
95
+
96
+ [Get Started](/signup/free)
97
+ {% /tier %}
98
+
99
+ {% tier name="Pro" priceMonthly="$29" featured=true %}
100
+ - Unlimited projects
101
+ - Priority support
102
+
103
+ [Start Trial](/signup/pro)
104
+ {% /tier %}
105
+ {% /pricing %}`,
106
+ tier: `{% tier name="Pro" priceMonthly="$29" featured=true %}
107
+ - Unlimited projects
108
+ - Priority support
109
+
110
+ [Start Trial](/signup/pro)
111
+ {% /tier %}`,
112
+ nav: `{% nav %}
113
+ ## Getting Started
114
+ - getting-started
115
+ - installation
116
+
117
+ ## Guides
118
+ - theming
119
+ - deployment
120
+ {% /nav %}`,
121
+ layout: `{% layout %}
122
+ {% region name="header" %}
123
+ # Site Title
124
+ {% /region %}
125
+
126
+ {% region name="nav" %}
127
+ {% nav %}
128
+ - getting-started
129
+ - runes
130
+ {% /nav %}
131
+ {% /region %}
132
+ {% /layout %}`,
133
+ region: `{% region name="nav" %}
134
+ {% nav %}
135
+ - page-one
136
+ - page-two
137
+ {% /nav %}
138
+ {% /region %}`,
139
+ 'music-playlist': `{% music-playlist audio="/audio/album.mp3" %}
140
+ # Album Title
141
+
142
+ ![Album Cover](/images/cover.jpg)
143
+
144
+ - Track One | 3:42
145
+ - Track Two | 4:15
146
+ {% /music-playlist %}`,
147
+ details: `{% details summary="How does billing work?" %}
148
+ We bill monthly on the date you signed up. You can cancel anytime
149
+ from your account settings.
150
+ {% /details %}`,
151
+ figure: `{% figure size="large" align="center" caption="Dashboard overview" %}
152
+ ![Dashboard](/images/dashboard.png)
153
+ {% /figure %}`,
154
+ accordion: `{% accordion headingLevel=2 %}
155
+ ## What is refrakt.md?
156
+
157
+ A content framework that extends Markdown with semantic runes.
158
+
159
+ ## How do I install it?
160
+
161
+ Run \`npm install @refrakt-md/runes\` to get started.
162
+
163
+ ## Is it free?
164
+
165
+ Yes, refrakt.md is open source and free to use.
166
+ {% /accordion %}`,
167
+ toc: `{% toc depth=3 %}{% /toc %}`,
168
+ hero: `{% hero align="center" %}
169
+ # Build faster with refrakt.md
170
+
171
+ Transform Markdown into beautiful, structured websites with semantic runes.
172
+
173
+ - [Get Started](/docs/getting-started)
174
+ - [View on GitHub](https://github.com/refrakt-md)
175
+ {% /hero %}`,
176
+ breadcrumb: `{% breadcrumb %}
177
+ - [Home](/)
178
+ - [Docs](/docs)
179
+ - [Runes](/docs/runes)
180
+ - Hero
181
+ {% /breadcrumb %}`,
182
+ testimonial: `{% testimonial rating=5 %}
183
+ > refrakt.md completely changed how we think about documentation.
184
+ > The rune system makes our content portable and semantic.
185
+
186
+ **Sarah Chen** — VP of Engineering, Acme Corp
187
+ {% /testimonial %}`,
188
+ compare: `{% compare %}
189
+ \`\`\`javascript
190
+ // Before
191
+ const x = 1;
192
+ const y = 2;
193
+ \`\`\`
194
+
195
+ \`\`\`javascript
196
+ // After
197
+ const [x, y] = [1, 2];
198
+ \`\`\`
199
+ {% /compare %}`,
200
+ timeline: `{% timeline %}
201
+ ## 2021 - Project started
202
+
203
+ We began building the initial prototype.
204
+
205
+ ## 2023 - First release
206
+
207
+ Open-sourced the library and published to npm.
208
+
209
+ ## 2024 - Version 2.0
210
+
211
+ Major rewrite with semantic rune system.
212
+ {% /timeline %}`,
213
+ changelog: `{% changelog project="refrakt.md" %}
214
+ ## v2.1.0 - 2024-03-15
215
+
216
+ - **Added** Timeline and changelog runes
217
+ - **Fixed** Code block rendering in dark mode
218
+
219
+ ## v2.0.0 - 2024-01-01
220
+
221
+ - **Added** Semantic rune system
222
+ - **Changed** Complete rewrite of the rendering engine
223
+ {% /changelog %}`,
224
+ embed: `{% embed url="https://www.youtube.com/watch?v=dQw4w9WgXcQ" %}
225
+ Watch the video for a full walkthrough.
226
+ {% /embed %}`,
227
+ };
228
+ function attributeTypeName(type) {
229
+ if (type === String)
230
+ return 'string';
231
+ if (type === Number)
232
+ return 'number';
233
+ if (type === Boolean)
234
+ return 'boolean';
235
+ if (type === Array)
236
+ return 'array';
237
+ if (typeof type === 'function' && type.name) {
238
+ return type.name;
239
+ }
240
+ return 'unknown';
241
+ }
242
+ function describeAttribute(name, attr) {
243
+ const parts = [` - ${name}: `];
244
+ if (Array.isArray(attr.matches) && attr.matches.length > 0) {
245
+ const values = attr.matches
246
+ .filter((m) => typeof m === 'string')
247
+ .map((v) => `"${v}"`)
248
+ .join(' | ');
249
+ parts.push(values);
250
+ }
251
+ else {
252
+ parts.push(attributeTypeName(attr.type));
253
+ }
254
+ parts.push(attr.required ? ' (required)' : ' (optional)');
255
+ return parts.join('');
256
+ }
257
+ function describeRune(rune) {
258
+ const lines = [];
259
+ lines.push(`### ${rune.name}`);
260
+ if (rune.description) {
261
+ lines.push(rune.description);
262
+ }
263
+ if (rune.aliases.length > 0) {
264
+ lines.push(`Aliases: ${rune.aliases.join(', ')}`);
265
+ }
266
+ // Attributes
267
+ const attrs = rune.schema.attributes;
268
+ if (attrs && Object.keys(attrs).length > 0) {
269
+ lines.push('Attributes:');
270
+ for (const [attrName, attrDef] of Object.entries(attrs)) {
271
+ lines.push(describeAttribute(attrName, attrDef));
272
+ }
273
+ }
274
+ // Reinterprets
275
+ const reinterprets = Object.entries(rune.reinterprets);
276
+ if (reinterprets.length > 0) {
277
+ lines.push('Content interpretation:');
278
+ for (const [element, meaning] of reinterprets) {
279
+ lines.push(` - ${element} → ${meaning}`);
280
+ }
281
+ }
282
+ // Example
283
+ const example = RUNE_EXAMPLES[rune.name];
284
+ if (example) {
285
+ lines.push('Example:');
286
+ lines.push(example);
287
+ }
288
+ return lines.join('\n');
289
+ }
290
+ export function generateSystemPrompt(runes) {
291
+ const runeDescriptions = Object.values(runes)
292
+ .filter(rune => !EXCLUDED_RUNES.has(rune.name))
293
+ .map(rune => describeRune(rune))
294
+ .join('\n\n');
295
+ return `You are a content author for a website built with refrakt.md.
296
+ Write Markdown files using Markdoc tags called "runes" ({% tag %} syntax).
297
+
298
+ Content inside a rune is reinterpreted — a heading inside {% cta %}
299
+ becomes the hero headline, while inside {% nav %} it becomes a group title.
300
+ This context-dependent meaning is what makes runes powerful.
301
+
302
+ Every page should begin with YAML frontmatter:
303
+ ---
304
+ title: Page Title
305
+ description: A brief description
306
+ ---
307
+
308
+ ## Writing rules
309
+
310
+ - Use standard Markdown for body text (paragraphs, bold, italic, links, images, code fences, lists).
311
+ - Use runes ({% tag %} ... {% /tag %}) for semantic structure.
312
+ - Runes can be nested where it makes sense (e.g. {% tier %} inside {% pricing %}).
313
+ - Horizontal rules (---) delimit grid cells inside {% grid %} and {% codegroup %}.
314
+ - Do NOT invent rune names that are not listed below.
315
+
316
+ ## Available Runes
317
+
318
+ ${runeDescriptions}`;
319
+ }
320
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAkBA,oEAAoE;AACpE,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC9B,OAAO;IACP,YAAY;IACZ,MAAM;IACN,KAAK;IACL,iBAAiB;IACjB,gBAAgB;IAChB,gBAAgB;IAChB,mBAAmB;IACnB,iBAAiB;CACjB,CAAC,CAAC;AAEH,iDAAiD;AACjD,MAAM,aAAa,GAA2B;IAC7C,IAAI,EAAE;;YAEK;IAEX,GAAG,EAAE;;;;;;;WAOK;IAEV,OAAO,EAAE;;;;;;;;;;;;;;eAcK;IAEd,IAAI,EAAE;;;;;;;;;;YAUK;IAEX,KAAK,EAAE;;;;;;;;;;;;aAYK;IAEZ,IAAI,EAAE;;;;;;;;;;;;YAYK;IAEX,SAAS,EAAE;;;;;;;;iBAQK;IAEhB,OAAO,EAAE;;;;;;;;;;;;;;;;;;eAkBK;IAEd,IAAI,EAAE;;;;;YAKK;IAEX,GAAG,EAAE;;;;;;;;WAQK;IAEV,MAAM,EAAE;;;;;;;;;;;cAWK;IAEb,MAAM,EAAE;;;;;cAKK;IAEb,gBAAgB,EAAE;;;;;;;sBAOG;IAErB,OAAO,EAAE;;;eAGK;IAEd,MAAM,EAAE;;cAEK;IAEb,SAAS,EAAE;;;;;;;;;;;;iBAYK;IAEhB,GAAG,EAAE,6BAA6B;IAElC,IAAI,EAAE;;;;;;;YAOK;IAEX,UAAU,EAAE;;;;;kBAKK;IAEjB,WAAW,EAAE;;;;;mBAKK;IAElB,OAAO,EAAE;;;;;;;;;;;eAWK;IAEd,QAAQ,EAAE;;;;;;;;;;;;gBAYK;IAEf,SAAS,EAAE;;;;;;;;;;iBAUK;IAEhB,KAAK,EAAE;;aAEK;CACZ,CAAC;AAEF,SAAS,iBAAiB,CAAC,IAAa;IACvC,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,QAAQ,CAAC;IACrC,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,QAAQ,CAAC;IACrC,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,SAAS,CAAC;IACvC,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,OAAO,CAAC;IACnC,IAAI,OAAO,IAAI,KAAK,UAAU,IAAK,IAA0B,CAAC,IAAI,EAAE,CAAC;QACpE,OAAQ,IAAyB,CAAC,IAAI,CAAC;IACxC,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,iBAAiB,CACzB,IAAY,EACZ,IAA+D;IAE/D,MAAM,KAAK,GAAa,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;IAE1C,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO;aACzB,MAAM,CAAC,CAAC,CAAU,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;aAC1D,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;aAC5B,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC;SAAM,CAAC;QACP,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAE1D,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACvB,CAAC;AAED,SAAS,YAAY,CAAC,IAAc;IACnC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC9B,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,aAAa;IACb,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;IACrC,IAAI,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1B,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzD,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QAClD,CAAC;IACF,CAAC;IAED,eAAe;IACf,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACtC,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,YAAY,EAAE,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,MAAM,OAAO,EAAE,CAAC,CAAC;QAC3C,CAAC;IACF,CAAC;IAED,UAAU;IACV,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,OAAO,EAAE,CAAC;QACb,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAA+B;IACnE,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;SAC3C,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC9C,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;SAC/B,IAAI,CAAC,MAAM,CAAC,CAAC;IAEf,OAAO;;;;;;;;;;;;;;;;;;;;;;;EAuBN,gBAAgB,EAAE,CAAC;AACrB,CAAC"}
@@ -0,0 +1,15 @@
1
+ export interface Message {
2
+ role: 'system' | 'user' | 'assistant';
3
+ content: string;
4
+ }
5
+ export interface CompletionOptions {
6
+ messages: Message[];
7
+ model?: string;
8
+ maxTokens?: number;
9
+ temperature?: number;
10
+ }
11
+ export interface AIProvider {
12
+ name: string;
13
+ complete(options: CompletionOptions): AsyncIterable<string>;
14
+ }
15
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACvB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;CAC5D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":""}
@@ -0,0 +1,25 @@
1
+ import type { AIProvider, CompletionOptions } from '../provider.js';
2
+ export interface AnthropicOptions {
3
+ apiKey: string;
4
+ baseUrl?: string;
5
+ defaultModel?: string;
6
+ /** Override fetch for testing */
7
+ fetch?: typeof globalThis.fetch;
8
+ }
9
+ interface AnthropicMessage {
10
+ role: 'user' | 'assistant';
11
+ content: string;
12
+ }
13
+ export declare function formatAnthropicRequest(options: CompletionOptions, defaults: {
14
+ model: string;
15
+ }): {
16
+ system: string | undefined;
17
+ messages: AnthropicMessage[];
18
+ model: string;
19
+ max_tokens: number;
20
+ stream: boolean;
21
+ };
22
+ export declare function parseAnthropicSSE(response: Response): AsyncIterable<string>;
23
+ export declare function createAnthropicProvider(options: AnthropicOptions): AIProvider;
24
+ export {};
25
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAW,MAAM,gBAAgB,CAAC;AAE7E,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CAChC;AAED,UAAU,gBAAgB;IACzB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,sBAAsB,CACrC,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAmBlH;AAED,wBAAuB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAmClF;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,gBAAgB,GAAG,UAAU,CA6B7E"}
@@ -0,0 +1,82 @@
1
+ export function formatAnthropicRequest(options, defaults) {
2
+ let system;
3
+ const messages = [];
4
+ for (const msg of options.messages) {
5
+ if (msg.role === 'system') {
6
+ system = msg.content;
7
+ }
8
+ else {
9
+ messages.push({ role: msg.role, content: msg.content });
10
+ }
11
+ }
12
+ return {
13
+ system,
14
+ messages,
15
+ model: options.model ?? defaults.model,
16
+ max_tokens: options.maxTokens ?? 4096,
17
+ stream: true,
18
+ };
19
+ }
20
+ export async function* parseAnthropicSSE(response) {
21
+ const body = response.body;
22
+ if (!body)
23
+ return;
24
+ const reader = body.getReader();
25
+ const decoder = new TextDecoder();
26
+ let buffer = '';
27
+ try {
28
+ while (true) {
29
+ const { done, value } = await reader.read();
30
+ if (done)
31
+ break;
32
+ buffer += decoder.decode(value, { stream: true });
33
+ const lines = buffer.split('\n');
34
+ buffer = lines.pop();
35
+ for (const line of lines) {
36
+ if (!line.startsWith('data: '))
37
+ continue;
38
+ const data = line.slice(6);
39
+ if (data === '[DONE]')
40
+ return;
41
+ try {
42
+ const parsed = JSON.parse(data);
43
+ if (parsed.type === 'content_block_delta' && parsed.delta?.type === 'text_delta') {
44
+ yield parsed.delta.text;
45
+ }
46
+ }
47
+ catch {
48
+ // skip non-JSON lines
49
+ }
50
+ }
51
+ }
52
+ }
53
+ finally {
54
+ reader.releaseLock();
55
+ }
56
+ }
57
+ export function createAnthropicProvider(options) {
58
+ const baseUrl = options.baseUrl ?? 'https://api.anthropic.com';
59
+ const defaultModel = options.defaultModel ?? 'claude-sonnet-4-5-20250929';
60
+ const fetchFn = options.fetch ?? globalThis.fetch;
61
+ return {
62
+ name: 'anthropic',
63
+ async *complete(completionOptions) {
64
+ const body = formatAnthropicRequest(completionOptions, { model: defaultModel });
65
+ const response = await fetchFn(`${baseUrl}/v1/messages`, {
66
+ method: 'POST',
67
+ headers: {
68
+ 'content-type': 'application/json',
69
+ 'x-api-key': options.apiKey,
70
+ 'anthropic-version': '2023-06-01',
71
+ },
72
+ body: JSON.stringify(body),
73
+ });
74
+ if (!response.ok) {
75
+ const text = await response.text();
76
+ throw new Error(`Anthropic API error (${response.status}): ${text}`);
77
+ }
78
+ yield* parseAnthropicSSE(response);
79
+ },
80
+ };
81
+ }
82
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { AIProvider, CompletionOptions, Message } from '../provider.js';
2
+ export interface OllamaOptions {
3
+ host?: string;
4
+ defaultModel?: string;
5
+ /** Override fetch for testing */
6
+ fetch?: typeof globalThis.fetch;
7
+ }
8
+ export declare function formatOllamaRequest(options: CompletionOptions, defaults: {
9
+ model: string;
10
+ }): {
11
+ model: string;
12
+ messages: Message[];
13
+ stream: boolean;
14
+ options?: {
15
+ temperature?: number;
16
+ num_predict?: number;
17
+ };
18
+ };
19
+ export declare function parseOllamaNDJSON(response: Response): AsyncIterable<string>;
20
+ export declare function createOllamaProvider(options?: OllamaOptions): AIProvider;
21
+ //# sourceMappingURL=ollama.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../src/providers/ollama.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE7E,MAAM,WAAW,aAAa;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CAChC;AAED,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAWnH;AAED,wBAAuB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAkClF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,UAAU,CA2BxE"}
@@ -0,0 +1,73 @@
1
+ export function formatOllamaRequest(options, defaults) {
2
+ const reqOptions = {};
3
+ if (options.temperature !== undefined)
4
+ reqOptions.temperature = options.temperature;
5
+ if (options.maxTokens !== undefined)
6
+ reqOptions.num_predict = options.maxTokens;
7
+ return {
8
+ model: options.model ?? defaults.model,
9
+ messages: options.messages,
10
+ stream: true,
11
+ ...(Object.keys(reqOptions).length > 0 ? { options: reqOptions } : {}),
12
+ };
13
+ }
14
+ export async function* parseOllamaNDJSON(response) {
15
+ const body = response.body;
16
+ if (!body)
17
+ return;
18
+ const reader = body.getReader();
19
+ const decoder = new TextDecoder();
20
+ let buffer = '';
21
+ try {
22
+ while (true) {
23
+ const { done, value } = await reader.read();
24
+ if (done)
25
+ break;
26
+ buffer += decoder.decode(value, { stream: true });
27
+ const lines = buffer.split('\n');
28
+ buffer = lines.pop();
29
+ for (const line of lines) {
30
+ if (!line.trim())
31
+ continue;
32
+ try {
33
+ const parsed = JSON.parse(line);
34
+ if (parsed.message?.content) {
35
+ yield parsed.message.content;
36
+ }
37
+ if (parsed.done)
38
+ return;
39
+ }
40
+ catch {
41
+ // skip malformed lines
42
+ }
43
+ }
44
+ }
45
+ }
46
+ finally {
47
+ reader.releaseLock();
48
+ }
49
+ }
50
+ export function createOllamaProvider(options) {
51
+ const host = options?.host ?? 'http://localhost:11434';
52
+ const defaultModel = options?.defaultModel ?? 'llama3.2';
53
+ const fetchFn = options?.fetch ?? globalThis.fetch;
54
+ return {
55
+ name: 'ollama',
56
+ async *complete(completionOptions) {
57
+ const body = formatOllamaRequest(completionOptions, { model: defaultModel });
58
+ const response = await fetchFn(`${host}/api/chat`, {
59
+ method: 'POST',
60
+ headers: {
61
+ 'content-type': 'application/json',
62
+ },
63
+ body: JSON.stringify(body),
64
+ });
65
+ if (!response.ok) {
66
+ const text = await response.text();
67
+ throw new Error(`Ollama API error (${response.status}): ${text}`);
68
+ }
69
+ yield* parseOllamaNDJSON(response);
70
+ },
71
+ };
72
+ }
73
+ //# sourceMappingURL=ollama.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../src/providers/ollama.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@refrakt-md/ai",
3
+ "description": "AI content generation for refrakt.md",
4
+ "version": "0.1.0",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/refrakt-md/refrakt.git",
10
+ "directory": "packages/ai"
11
+ },
12
+ "bugs": "https://github.com/refrakt-md/refrakt/issues",
13
+ "homepage": "https://github.com/refrakt-md/refrakt",
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "main": "dist/index.js",
18
+ "types": "dist/index.d.ts",
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsc"
24
+ },
25
+ "devDependencies": {
26
+ "@refrakt-md/runes": "0.1.0"
27
+ }
28
+ }