@templatical/ai-kit 0.0.0-stage → 0.51.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.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +63 -2
  3. package/dist/adapters/anthropic.d.ts +31 -0
  4. package/dist/adapters/anthropic.js +139 -0
  5. package/dist/adapters/anthropic.js.map +1 -0
  6. package/dist/adapters/openai.d.ts +29 -0
  7. package/dist/adapters/openai.js +131 -0
  8. package/dist/adapters/openai.js.map +1 -0
  9. package/dist/adapters/vercel.d.ts +17 -0
  10. package/dist/adapters/vercel.js +137 -0
  11. package/dist/adapters/vercel.js.map +1 -0
  12. package/dist/checks-DvLD3892.js +656 -0
  13. package/dist/checks-DvLD3892.js.map +1 -0
  14. package/dist/client/index.d.ts +24 -0
  15. package/dist/client/index.js +3 -0
  16. package/dist/errors-DWshWx18.js +55 -0
  17. package/dist/errors-DWshWx18.js.map +1 -0
  18. package/dist/http-provider-Cb41NXd5.d.ts +22 -0
  19. package/dist/http-provider-Cx2ZcLRB.js +278 -0
  20. package/dist/http-provider-Cx2ZcLRB.js.map +1 -0
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.js +3 -0
  23. package/dist/model-xJvGTfLB.d.ts +84 -0
  24. package/dist/server/index.d.ts +313 -0
  25. package/dist/server/index.js +355 -0
  26. package/dist/server/index.js.map +1 -0
  27. package/dist/shared-BuhccY6c.js +61 -0
  28. package/dist/shared-BuhccY6c.js.map +1 -0
  29. package/dist/testing/index.d.ts +277 -0
  30. package/dist/testing/index.js +2445 -0
  31. package/dist/testing/index.js.map +1 -0
  32. package/dist/wire-B6AF_UGT.js +132 -0
  33. package/dist/wire-B6AF_UGT.js.map +1 -0
  34. package/dist/wire-Cv7Fk-7n.d.ts +136 -0
  35. package/eval/MANIFEST.sha256 +23 -0
  36. package/eval/cases.json +287 -0
  37. package/eval/designs/newsletter.png +0 -0
  38. package/eval/designs/one-page.pdf +0 -0
  39. package/eval/designs/promo.png +0 -0
  40. package/eval/domain-mismatch.json +25 -0
  41. package/eval/empty.json +11 -0
  42. package/eval/images/banner.png +0 -0
  43. package/eval/images/chart.png +0 -0
  44. package/eval/images/divider.png +0 -0
  45. package/eval/images/probe.png +0 -0
  46. package/eval/images/product.png +0 -0
  47. package/eval/injection.json +13 -0
  48. package/eval/low-text.json +41 -0
  49. package/eval/promo.json +12 -0
  50. package/eval/sources/banner.html +16 -0
  51. package/eval/sources/chart.html +16 -0
  52. package/eval/sources/divider.html +16 -0
  53. package/eval/sources/newsletter.html +16 -0
  54. package/eval/sources/one-page.html +16 -0
  55. package/eval/sources/probe.html +16 -0
  56. package/eval/sources/product.html +16 -0
  57. package/eval/sources/promo.html +16 -0
  58. package/eval/welcome.json +12 -0
  59. package/package.json +99 -3
  60. package/prompts/alt-text.md +7 -0
  61. package/prompts/chat-attachments.md +1 -0
  62. package/prompts/chat.md +2 -0
  63. package/prompts/editing.md +10 -0
  64. package/prompts/fix-rules.json +9 -0
  65. package/prompts/fix.md +8 -0
  66. package/prompts/operations.md +127 -0
  67. package/prompts/rewrite-presets.json +8 -0
  68. package/prompts/rewrite.md +4 -0
  69. package/schema/template-content.schema.json +1884 -0
@@ -0,0 +1,277 @@
1
+ import { t as AiModelAdapter } from "../model-xJvGTfLB.js";
2
+ import { t as HttpAiFeatures } from "../http-provider-Cb41NXd5.js";
3
+ import { C as AiWireEvent } from "../wire-Cv7Fk-7n.js";
4
+ import { AiAltTextRequest, AiAppliedBatch, AiChatAttachment, AiChatRequest, AiFixFinding, AiFixRequest, AiMergeTags, AiOperationsResult, AiProvider, AiRewriteRequest, AiTurnHandlers, Operation, TemplateContent } from "@templatical/types";
5
+ //#region src/testing/conformance.d.ts
6
+ interface AiConformanceCheck {
7
+ name: string;
8
+ ok: boolean;
9
+ detail: string;
10
+ }
11
+ interface AiConformanceReport {
12
+ ok: boolean;
13
+ checks: AiConformanceCheck[];
14
+ }
15
+ interface AiConformanceOptions {
16
+ /** The template the suite edits; the test set's welcome email by default. */
17
+ content?: TemplateContent;
18
+ templateId?: string;
19
+ /** Public probe image URL; defaults to AI_CONFORMANCE_ALT_TEXT_IMAGE_URL. */
20
+ altTextImageUrl?: string;
21
+ mergeTags?: AiMergeTags;
22
+ /** How long a stopped call may take to reject (D35). */
23
+ timeoutMs?: number;
24
+ /** An optional shorter call limit; every call is also bounded by `timeoutMs`. */
25
+ callTimeoutMs?: number;
26
+ }
27
+ /**
28
+ * Drive a provider as the editor would and check the contract (A1 §6): any
29
+ * test runner, never throws on a failed check. Each declared feature runs
30
+ * once against a stand-in editor that applies `operations` with the engine.
31
+ */
32
+ export declare function runAiProviderConformance(provider: AiProvider, options?: AiConformanceOptions): Promise<AiConformanceReport>;
33
+ //#endregion
34
+ //#region src/testing/wire-conformance.d.ts
35
+ interface AiWireConformanceOptions {
36
+ baseUrl: string;
37
+ features?: HttpAiFeatures;
38
+ headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
39
+ templateId?: string;
40
+ /** Defaults to AI_CONFORMANCE_ALT_TEXT_IMAGE_URL. */
41
+ altTextImageUrl?: string;
42
+ timeoutMs?: number;
43
+ callTimeoutMs?: number;
44
+ }
45
+ /**
46
+ * The provider suite over the wire, through `createHttpAiProvider`, plus the
47
+ * wire's own rules: every response carries `Templatical-AI-Wire: 1`, streams
48
+ * are `text/event-stream`, and a bad turn is refused before the stream with a
49
+ * JSON error. For a backend in any language; run it from Node (no CORS).
50
+ */
51
+ export declare function runAiWireConformance(options: AiWireConformanceOptions): Promise<AiConformanceReport>;
52
+ //#endregion
53
+ //#region src/testing/mock-provider.d.ts
54
+ /** A wire event to play, or a pause. */
55
+ type AiRecordedEvent = AiWireEvent | {
56
+ delayMs: number;
57
+ };
58
+ /** Events, or events built from the request (to name its blocks). */
59
+ type AiRecording<R> = AiRecordedEvent[] | ((request: R) => AiRecordedEvent[]);
60
+ interface AiRecordedTurn {
61
+ /** The first turn whose `match` fits the message plays; one without `match` always fits. */
62
+ match?: RegExp;
63
+ events: AiRecording<AiChatRequest>;
64
+ }
65
+ /** What the mock plays. A missing feature is off (`false`). */
66
+ interface AiMockScript {
67
+ chat?: false | AiRecordedTurn[];
68
+ fixFinding?: false | AiRecording<AiFixRequest>;
69
+ chatAttachments?: boolean;
70
+ rewrite?: false | AiRecording<AiRewriteRequest>;
71
+ altText?: false | AiRecording<AiAltTextRequest>;
72
+ /** Keep a conversation in memory per template, with Undo and Redo. */
73
+ conversation?: boolean;
74
+ /** A pause before every event, in ms (0 by default). */
75
+ delayMs?: number;
76
+ }
77
+ /**
78
+ * An `AiProvider` that plays recorded streams: for integrators' UI tests and
79
+ * the playground's AI scene (no model, no keys). Turns apply their
80
+ * `operations` through the editor's handlers like a real backend's; with
81
+ * `conversation: true` it keeps history in memory, Undo answering the turn's
82
+ * inverse and Redo the guarded inverse of Undo. Replays change history only
83
+ * after settlement.
84
+ */
85
+ export declare function createMockAiProvider(script: AiMockScript): AiProvider;
86
+ //#endregion
87
+ //#region src/testing/recordings.d.ts
88
+ /**
89
+ * Scripted turns for any template: the playground's AI scene and the
90
+ * conformance suite's self-test play them. Chat answers "dark", "title" and
91
+ * "fail" specially and otherwise adds a closing paragraph.
92
+ */
93
+ export declare const AI_RECORDINGS: AiMockScript;
94
+ //#endregion
95
+ //#region src/testing/eval-set.d.ts
96
+ type AiEvalCheck = {
97
+ type: "applied" | "notApplied";
98
+ } | {
99
+ type: "present" | "missing";
100
+ block: string;
101
+ } | {
102
+ type: "contains" | "notContains";
103
+ block?: string;
104
+ text: string;
105
+ } | {
106
+ type: "lintGone";
107
+ ruleId: string;
108
+ } | {
109
+ type: "field" | "fieldNot";
110
+ block: string;
111
+ path: string;
112
+ matches: string;
113
+ } | {
114
+ type: "setting";
115
+ path: string;
116
+ matches: string;
117
+ } | {
118
+ type: "greater";
119
+ block: string;
120
+ path: string;
121
+ than: number;
122
+ } | {
123
+ type: "maxText";
124
+ block: string;
125
+ chars: number;
126
+ } | {
127
+ type: "countType";
128
+ blockType: string;
129
+ min: number;
130
+ } | {
131
+ type: "order";
132
+ first: string;
133
+ then: string;
134
+ } | {
135
+ type: "firstContains";
136
+ text: string;
137
+ } | {
138
+ type: "reply";
139
+ matches: string;
140
+ };
141
+ type AiEvalAltCheck = {
142
+ type: "nonEmpty" | "withinLimit";
143
+ } | {
144
+ type: "containsAll" | "containsAny";
145
+ texts: string[];
146
+ } | {
147
+ type: "notMatches";
148
+ matches: string;
149
+ } | {
150
+ type: "shortOrMatches";
151
+ chars: number;
152
+ matches: string;
153
+ };
154
+ type EvalTemplate = "welcome" | "promo" | "injection" | "empty" | "domain-mismatch" | "low-text";
155
+ interface EvalTurnCase {
156
+ name: string;
157
+ template: EvalTemplate;
158
+ /** Block ids the case may delete; every other original id must survive. */
159
+ removed?: string[];
160
+ checks: AiEvalCheck[];
161
+ }
162
+ interface AiEvalAltTextInput {
163
+ /** Path relative to the package's eval/ folder. */
164
+ image: string;
165
+ linkHref: string | null;
166
+ nearbyText: string;
167
+ maxLength: number;
168
+ }
169
+ type AiEvalCase = (EvalTurnCase & {
170
+ kind?: "edit";
171
+ message: string;
172
+ selectedBlockId?: string;
173
+ attachments?: {
174
+ file: string;
175
+ kind: "image" | "pdf";
176
+ }[];
177
+ }) | (EvalTurnCase & {
178
+ kind: "fix";
179
+ finding: AiFixFinding;
180
+ }) | (AiEvalAltTextInput & {
181
+ kind: "altText";
182
+ name: string;
183
+ checks: AiEvalAltCheck[];
184
+ });
185
+ /** The cases of S7's test set (`eval/cases.json`). An omitted kind means edit. */
186
+ export declare const AI_EVAL_CASES: AiEvalCase[];
187
+ export declare const AI_EVAL_TEMPLATES: Readonly<Record<EvalTemplate, TemplateContent>>;
188
+ /** The merge tags every case's editor declares. */
189
+ export declare const AI_EVAL_MERGE_TAGS: AiMergeTags;
190
+ interface AiEvalTurnInput {
191
+ content: TemplateContent;
192
+ mergeTags: AiMergeTags;
193
+ message: string;
194
+ selectedBlockId: string | null;
195
+ finding: AiFixFinding | null;
196
+ attachments: AiChatAttachment[];
197
+ }
198
+ interface AiEvalTurnOutput {
199
+ /** The template after the turn. */
200
+ content: TemplateContent;
201
+ reply: string;
202
+ /** Whether the turn changed the template. */
203
+ applied: boolean;
204
+ }
205
+ interface AiEvalReport {
206
+ model: string;
207
+ passed: number;
208
+ /** Cases that ran; skipped cases are excluded. */
209
+ total: number;
210
+ skipped: number;
211
+ /** Whole percent, rounded down. */
212
+ rate: number;
213
+ ok: boolean;
214
+ results: {
215
+ name: string;
216
+ ok: boolean;
217
+ reason: string | null;
218
+ skipped?: true;
219
+ }[];
220
+ }
221
+ /**
222
+ * Run one case's checks against a turn's outcome; the first failure's reason,
223
+ * or `null` when it passed (S7 Cloud Task 11's `failure()`).
224
+ */
225
+ export declare function checkEvalCase(testCase: Exclude<AiEvalCase, {
226
+ kind: "altText";
227
+ }>, original: TemplateContent, output: AiEvalTurnOutput, lintCheck?: (content: TemplateContent) => string[]): string | null;
228
+ /** Text-free public probe image from this package's fixed-version SDK release. */
229
+ export declare const AI_CONFORMANCE_ALT_TEXT_IMAGE_URL: string;
230
+ /**
231
+ * Run each case on a fresh template. Missing optional runners skip their cases;
232
+ * thrown turns or checks fail. The pass rate counts only cases that ran.
233
+ */
234
+ export declare function runAiEvalSet(options: {
235
+ runTurn: (input: AiEvalTurnInput) => Promise<AiEvalTurnOutput>;
236
+ runAltText?: (input: AiEvalAltTextInput) => Promise<string>;
237
+ lintCheck?: (content: TemplateContent) => string[];
238
+ loadFile?: (file: string) => Promise<Blob>;
239
+ model: string;
240
+ cases?: readonly AiEvalCase[];
241
+ minPassRate?: number;
242
+ }): Promise<AiEvalReport>;
243
+ /** A `runAltText` using image URLs; override them for unreleased fixtures. */
244
+ export declare function evalAltTextWith(model: AiModelAdapter, options?: {
245
+ imageUrl?: (file: string) => string;
246
+ }): (input: AiEvalAltTextInput) => Promise<string>;
247
+ /** A `runTurn` on the kit's own loop, for a model behind an `AiModelAdapter`. */
248
+ export declare function evalTurnWith(model: AiModelAdapter, options?: {
249
+ maxSteps?: number;
250
+ }): (input: AiEvalTurnInput) => Promise<AiEvalTurnOutput>;
251
+ //#endregion
252
+ //#region src/testing/stand-in-editor.d.ts
253
+ /** The editor the suites drive: `onOperations` applies with the engine. */
254
+ interface StandInEditor {
255
+ content: TemplateContent;
256
+ readonly mergeTags: AiMergeTags;
257
+ readonly sessionId: string;
258
+ readonly applied: Operation[][];
259
+ readonly refused: {
260
+ code: string;
261
+ opIndex: number;
262
+ message: string;
263
+ }[];
264
+ readonly serverBatches: AiAppliedBatch[];
265
+ /** Apply a batch as the editor would answer `onOperations`. */
266
+ apply(ops: Operation[]): AiOperationsResult;
267
+ /** Fresh handlers for one call; `text` collects what streamed. */
268
+ handlers(extra?: {
269
+ onText?: (text: string) => void;
270
+ }): AiTurnHandlers & {
271
+ readonly text: string;
272
+ };
273
+ }
274
+ export declare function createStandInEditor(content: TemplateContent, mergeTags?: AiMergeTags): StandInEditor;
275
+ //#endregion
276
+ export type { AiConformanceCheck, AiConformanceOptions, AiConformanceReport, AiEvalAltCheck, AiEvalAltTextInput, AiEvalCase, AiEvalCheck, AiEvalReport, AiEvalTurnInput, AiEvalTurnOutput, AiMockScript, AiRecordedEvent, AiRecordedTurn, AiRecording, AiWireConformanceOptions, StandInEditor };
277
+ //# sourceMappingURL=index.d.ts.map