@templatical/ai-kit 0.51.1 → 0.52.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 (30) hide show
  1. package/dist/adapters/anthropic.d.ts +1 -3
  2. package/dist/adapters/anthropic.js +2 -3
  3. package/dist/adapters/openai.d.ts +1 -3
  4. package/dist/adapters/openai.js +2 -3
  5. package/dist/adapters/vercel.d.ts +1 -3
  6. package/dist/adapters/vercel.js +2 -3
  7. package/dist/{checks-DvLD3892.js → checks-B-TtaywP.js} +12 -22
  8. package/dist/{checks-DvLD3892.js.map → checks-B-TtaywP.js.map} +1 -1
  9. package/dist/client/index.d.ts +2 -6
  10. package/dist/client/index.js +2 -2
  11. package/dist/{errors-DWshWx18.js → errors-BtORdtK2.js} +3 -4
  12. package/dist/{errors-DWshWx18.js.map → errors-BtORdtK2.js.map} +1 -1
  13. package/dist/{http-provider-Cb41NXd5.d.ts → http-provider-B5riig95.d.ts} +1 -3
  14. package/dist/{http-provider-Cx2ZcLRB.js → http-provider-DLJYM4l8.js} +5 -7
  15. package/dist/{http-provider-Cx2ZcLRB.js.map → http-provider-DLJYM4l8.js.map} +1 -1
  16. package/dist/index.d.ts +1 -1
  17. package/dist/index.js +1 -1
  18. package/dist/{model-xJvGTfLB.d.ts → model-VqqOlLS2.d.ts} +1 -5
  19. package/dist/server/index.d.ts +2 -24
  20. package/dist/server/index.js +5 -8
  21. package/dist/server/index.js.map +1 -1
  22. package/dist/{shared-BuhccY6c.js → shared-DOEVSpBX.js} +4 -5
  23. package/dist/{shared-BuhccY6c.js.map → shared-DOEVSpBX.js.map} +1 -1
  24. package/dist/testing/index.d.ts +3 -15
  25. package/dist/testing/index.js +20 -35
  26. package/dist/testing/index.js.map +1 -1
  27. package/dist/{wire-Cv7Fk-7n.d.ts → wire-BJ4-EWvR.d.ts} +1 -3
  28. package/dist/{wire-B6AF_UGT.js → wire-cYO4W7GH.js} +2 -3
  29. package/dist/{wire-B6AF_UGT.js.map → wire-cYO4W7GH.js.map} +1 -1
  30. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"shared-BuhccY6c.js","names":[],"sources":["../src/adapters/shared.ts"],"sourcesContent":["import { SdkError, ThrottledError } from \"@templatical/types\";\nimport { parseRetryAfter } from \"../client/errors\";\nimport type { AiModelToolCall } from \"../server/model\";\nimport { AI_ERROR_MESSAGES } from \"../wire\";\n\n/** The content an adapter stored as `{ adapter, content }` state, if it's this adapter's. */\nexport function ownState<T>(state: unknown, adapter: string): T[] | undefined {\n if (typeof state !== \"object\" || state === null) return undefined;\n const tagged = state as { adapter?: unknown; content?: unknown };\n return tagged.adapter === adapter && Array.isArray(tagged.content)\n ? (tagged.content as T[])\n : undefined;\n}\n\n/** A tool call's arguments as an object (`{}` when the string isn't a JSON object). */\nexport function toolInput(\n input: AiModelToolCall[\"input\"],\n): Record<string, unknown> {\n if (typeof input !== \"string\") return input;\n try {\n const parsed: unknown = JSON.parse(input);\n return typeof parsed === \"object\" &&\n parsed !== null &&\n !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : {};\n } catch {\n return {};\n }\n}\n\n/** A tool call's arguments as a JSON string. */\nexport function toolArguments(input: AiModelToolCall[\"input\"]): string {\n return typeof input === \"string\" ? input : JSON.stringify(input);\n}\n\n/** A Blob's bytes as base64, with web APIs only (the kit is isomorphic). */\nexport async function blobBase64(blob: Blob): Promise<string> {\n const bytes = new Uint8Array(await blob.arrayBuffer());\n let binary = \"\";\n for (let start = 0; start < bytes.length; start += 0x8000) {\n binary += String.fromCharCode(...bytes.subarray(start, start + 0x8000));\n }\n return btoa(binary);\n}\n\n/** The model refused or a content filter stopped it. */\nexport function refused(): SdkError {\n return new SdkError(\n AI_ERROR_MESSAGES.ai_provider_error,\n 502,\n \"ai_provider_error\",\n );\n}\n\n/** The output hit the token limit while a tool call was being written. */\nexport function cutOff(): SdkError {\n return new SdkError(\n AI_ERROR_MESSAGES.ai_output_invalid,\n 422,\n \"ai_output_invalid\",\n );\n}\n\nfunction retryAfterHeader(headers: unknown): string | null {\n if (typeof Headers !== \"undefined\" && headers instanceof Headers)\n return headers.get(\"retry-after\");\n if (typeof headers !== \"object\" || headers === null) return null;\n for (const [name, value] of Object.entries(headers)) {\n if (name.toLowerCase() === \"retry-after\" && typeof value === \"string\")\n return value;\n }\n return null;\n}\n\n/**\n * A provider's 429 (after the client's own retries) as the kit's\n * `ThrottledError`; anything else unchanged, so it keeps its own details.\n * Reads the provider SDKs' `status`/`headers` and the AI SDK's\n * `statusCode`/`responseHeaders`, unwrapping a retry error's `lastError`.\n */\nexport function providerError(error: unknown): unknown {\n if (typeof error !== \"object\" || error === null) return error;\n const failure = ((error as { lastError?: unknown }).lastError ?? error) as {\n status?: unknown;\n statusCode?: unknown;\n headers?: unknown;\n responseHeaders?: unknown;\n };\n if ((failure.status ?? failure.statusCode) !== 429) return error;\n return new ThrottledError(\n AI_ERROR_MESSAGES.rate_limited,\n parseRetryAfter(\n retryAfterHeader(failure.headers ?? failure.responseHeaders),\n ),\n );\n}\n"],"mappings":";;;;;AAMA,SAAgB,SAAY,OAAgB,SAAkC;CAC5E,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO,KAAA;CACxD,MAAM,SAAS;CACf,OAAO,OAAO,YAAY,WAAW,MAAM,QAAQ,OAAO,OAAO,IAC5D,OAAO,UACR,KAAA;AACN;;AAGA,SAAgB,UACd,OACyB;CACzB,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI;EACF,MAAM,SAAkB,KAAK,MAAM,KAAK;EACxC,OAAO,OAAO,WAAW,YACvB,WAAW,QACX,CAAC,MAAM,QAAQ,MAAM,IAClB,SACD,CAAC;CACP,QAAQ;EACN,OAAO,CAAC;CACV;AACF;;AAGA,SAAgB,cAAc,OAAyC;CACrE,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,KAAK;AACjE;;AAGA,eAAsB,WAAW,MAA6B;CAC5D,MAAM,QAAQ,IAAI,WAAW,MAAM,KAAK,YAAY,CAAC;CACrD,IAAI,SAAS;CACb,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,OACjD,UAAU,OAAO,aAAa,GAAG,MAAM,SAAS,OAAO,QAAQ,KAAM,CAAC;CAExE,OAAO,KAAK,MAAM;AACpB;;AAGA,SAAgB,UAAoB;CAClC,OAAO,IAAI,SACT,kBAAkB,mBAClB,KACA,mBACF;AACF;;AAGA,SAAgB,SAAmB;CACjC,OAAO,IAAI,SACT,kBAAkB,mBAClB,KACA,mBACF;AACF;AAEA,SAAS,iBAAiB,SAAiC;CACzD,IAAI,OAAO,YAAY,eAAe,mBAAmB,SACvD,OAAO,QAAQ,IAAI,aAAa;CAClC,IAAI,OAAO,YAAY,YAAY,YAAY,MAAM,OAAO;CAC5D,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,OAAO,GAChD,IAAI,KAAK,YAAY,MAAM,iBAAiB,OAAO,UAAU,UAC3D,OAAO;CAEX,OAAO;AACT;;;;;;;AAQA,SAAgB,cAAc,OAAyB;CACrD,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,MAAM,UAAY,MAAkC,aAAa;CAMjE,KAAK,QAAQ,UAAU,QAAQ,gBAAgB,KAAK,OAAO;CAC3D,OAAO,IAAI,eACT,kBAAkB,cAClB,gBACE,iBAAiB,QAAQ,WAAW,QAAQ,eAAe,CAC7D,CACF;AACF"}
1
+ {"version":3,"file":"shared-DOEVSpBX.js","names":[],"sources":["../src/adapters/shared.ts"],"sourcesContent":["import { SdkError, ThrottledError } from \"@templatical/types\";\nimport { parseRetryAfter } from \"../client/errors\";\nimport type { AiModelToolCall } from \"../server/model\";\nimport { AI_ERROR_MESSAGES } from \"../wire\";\n\n/** The content an adapter stored as `{ adapter, content }` state, if it's this adapter's. */\nexport function ownState<T>(state: unknown, adapter: string): T[] | undefined {\n if (typeof state !== \"object\" || state === null) return undefined;\n const tagged = state as { adapter?: unknown; content?: unknown };\n return tagged.adapter === adapter && Array.isArray(tagged.content)\n ? (tagged.content as T[])\n : undefined;\n}\n\n/** A tool call's arguments as an object (`{}` when the string isn't a JSON object). */\nexport function toolInput(\n input: AiModelToolCall[\"input\"],\n): Record<string, unknown> {\n if (typeof input !== \"string\") return input;\n try {\n const parsed: unknown = JSON.parse(input);\n return typeof parsed === \"object\" &&\n parsed !== null &&\n !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : {};\n } catch {\n return {};\n }\n}\n\n/** A tool call's arguments as a JSON string. */\nexport function toolArguments(input: AiModelToolCall[\"input\"]): string {\n return typeof input === \"string\" ? input : JSON.stringify(input);\n}\n\n/** A Blob's bytes as base64, with web APIs only (the kit is isomorphic). */\nexport async function blobBase64(blob: Blob): Promise<string> {\n const bytes = new Uint8Array(await blob.arrayBuffer());\n let binary = \"\";\n for (let start = 0; start < bytes.length; start += 0x8000) {\n binary += String.fromCharCode(...bytes.subarray(start, start + 0x8000));\n }\n return btoa(binary);\n}\n\n/** The model refused or a content filter stopped it. */\nexport function refused(): SdkError {\n return new SdkError(\n AI_ERROR_MESSAGES.ai_provider_error,\n 502,\n \"ai_provider_error\",\n );\n}\n\n/** The output hit the token limit while a tool call was being written. */\nexport function cutOff(): SdkError {\n return new SdkError(\n AI_ERROR_MESSAGES.ai_output_invalid,\n 422,\n \"ai_output_invalid\",\n );\n}\n\nfunction retryAfterHeader(headers: unknown): string | null {\n if (typeof Headers !== \"undefined\" && headers instanceof Headers)\n return headers.get(\"retry-after\");\n if (typeof headers !== \"object\" || headers === null) return null;\n for (const [name, value] of Object.entries(headers)) {\n if (name.toLowerCase() === \"retry-after\" && typeof value === \"string\")\n return value;\n }\n return null;\n}\n\n/**\n * A provider's 429 (after the client's own retries) as the kit's\n * `ThrottledError`; anything else unchanged, so it keeps its own details.\n * Reads the provider SDKs' `status`/`headers` and the AI SDK's\n * `statusCode`/`responseHeaders`, unwrapping a retry error's `lastError`.\n */\nexport function providerError(error: unknown): unknown {\n if (typeof error !== \"object\" || error === null) return error;\n const failure = ((error as { lastError?: unknown }).lastError ?? error) as {\n status?: unknown;\n statusCode?: unknown;\n headers?: unknown;\n responseHeaders?: unknown;\n };\n if ((failure.status ?? failure.statusCode) !== 429) return error;\n return new ThrottledError(\n AI_ERROR_MESSAGES.rate_limited,\n parseRetryAfter(\n retryAfterHeader(failure.headers ?? failure.responseHeaders),\n ),\n );\n}\n"],"mappings":";;;;;AAMA,SAAgB,SAAY,OAAgB,SAAkC;CAC5E,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO,KAAA;CACxD,MAAM,SAAS;CACf,OAAO,OAAO,YAAY,WAAW,MAAM,QAAQ,OAAO,OAAO,IAC5D,OAAO,UACR,KAAA;AACN;;AAGA,SAAgB,UACd,OACyB;CACzB,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI;EACF,MAAM,SAAkB,KAAK,MAAM,KAAK;EACxC,OAAO,OAAO,WAAW,YACvB,WAAW,QACX,CAAC,MAAM,QAAQ,MAAM,IAClB,SACD,CAAC;CACP,QAAQ;EACN,OAAO,CAAC;CACV;AACF;;AAGA,SAAgB,cAAc,OAAyC;CACrE,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,KAAK;AACjE;;AAGA,eAAsB,WAAW,MAA6B;CAC5D,MAAM,QAAQ,IAAI,WAAW,MAAM,KAAK,YAAY,CAAC;CACrD,IAAI,SAAS;CACb,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,OACjD,UAAU,OAAO,aAAa,GAAG,MAAM,SAAS,OAAO,QAAQ,KAAM,CAAC;CAExE,OAAO,KAAK,MAAM;AACpB;;AAGA,SAAgB,UAAoB;CAClC,OAAO,IAAI,SACT,kBAAkB,mBAClB,KACA,mBACF;AACF;;AAGA,SAAgB,SAAmB;CACjC,OAAO,IAAI,SACT,kBAAkB,mBAClB,KACA,mBACF;AACF;AAEA,SAAS,iBAAiB,SAAiC;CACzD,IAAI,OAAO,YAAY,eAAe,mBAAmB,SACvD,OAAO,QAAQ,IAAI,aAAa;CAClC,IAAI,OAAO,YAAY,YAAY,YAAY,MAAM,OAAO;CAC5D,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,OAAO,GAChD,IAAI,KAAK,YAAY,MAAM,iBAAiB,OAAO,UAAU,UAC3D,OAAO;CAEX,OAAO;AACT;;;;;;;AAQA,SAAgB,cAAc,OAAyB;CACrD,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,MAAM,UAAY,MAAkC,aAAa;CAMjE,KAAK,QAAQ,UAAU,QAAQ,gBAAgB,KAAK,OAAO;CAC3D,OAAO,IAAI,eACT,kBAAkB,cAClB,gBACE,iBAAiB,QAAQ,WAAW,QAAQ,eAAe,CAC7D,CACF;AACF"}
@@ -1,8 +1,7 @@
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";
1
+ import { t as AiModelAdapter } from "../model-VqqOlLS2.js";
2
+ import { t as HttpAiFeatures } from "../http-provider-B5riig95.js";
3
+ import { C as AiWireEvent } from "../wire-BJ4-EWvR.js";
4
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
5
  interface AiConformanceCheck {
7
6
  name: string;
8
7
  ok: boolean;
@@ -30,8 +29,6 @@ interface AiConformanceOptions {
30
29
  * once against a stand-in editor that applies `operations` with the engine.
31
30
  */
32
31
  export declare function runAiProviderConformance(provider: AiProvider, options?: AiConformanceOptions): Promise<AiConformanceReport>;
33
- //#endregion
34
- //#region src/testing/wire-conformance.d.ts
35
32
  interface AiWireConformanceOptions {
36
33
  baseUrl: string;
37
34
  features?: HttpAiFeatures;
@@ -49,8 +46,6 @@ interface AiWireConformanceOptions {
49
46
  * JSON error. For a backend in any language; run it from Node (no CORS).
50
47
  */
51
48
  export declare function runAiWireConformance(options: AiWireConformanceOptions): Promise<AiConformanceReport>;
52
- //#endregion
53
- //#region src/testing/mock-provider.d.ts
54
49
  /** A wire event to play, or a pause. */
55
50
  type AiRecordedEvent = AiWireEvent | {
56
51
  delayMs: number;
@@ -83,16 +78,12 @@ interface AiMockScript {
83
78
  * after settlement.
84
79
  */
85
80
  export declare function createMockAiProvider(script: AiMockScript): AiProvider;
86
- //#endregion
87
- //#region src/testing/recordings.d.ts
88
81
  /**
89
82
  * Scripted turns for any template: the playground's AI scene and the
90
83
  * conformance suite's self-test play them. Chat answers "dark", "title" and
91
84
  * "fail" specially and otherwise adds a closing paragraph.
92
85
  */
93
86
  export declare const AI_RECORDINGS: AiMockScript;
94
- //#endregion
95
- //#region src/testing/eval-set.d.ts
96
87
  type AiEvalCheck = {
97
88
  type: "applied" | "notApplied";
98
89
  } | {
@@ -248,8 +239,6 @@ export declare function evalAltTextWith(model: AiModelAdapter, options?: {
248
239
  export declare function evalTurnWith(model: AiModelAdapter, options?: {
249
240
  maxSteps?: number;
250
241
  }): (input: AiEvalTurnInput) => Promise<AiEvalTurnOutput>;
251
- //#endregion
252
- //#region src/testing/stand-in-editor.d.ts
253
242
  /** The editor the suites drive: `onOperations` applies with the engine. */
254
243
  interface StandInEditor {
255
244
  content: TemplateContent;
@@ -272,6 +261,5 @@ interface StandInEditor {
272
261
  };
273
262
  }
274
263
  export declare function createStandInEditor(content: TemplateContent, mergeTags?: AiMergeTags): StandInEditor;
275
- //#endregion
276
264
  export type { AiConformanceCheck, AiConformanceOptions, AiConformanceReport, AiEvalAltCheck, AiEvalAltTextInput, AiEvalCase, AiEvalCheck, AiEvalReport, AiEvalTurnInput, AiEvalTurnOutput, AiMockScript, AiRecordedEvent, AiRecordedTurn, AiRecording, AiWireConformanceOptions, StandInEditor };
277
265
  //# sourceMappingURL=index.d.ts.map
@@ -1,12 +1,11 @@
1
- import { l as aiRoutePath, o as AI_SESSION_HEADER, s as AI_WIRE_HEADER, t as AI_ERROR_MESSAGES, u as matchAiRoute } from "../wire-B6AF_UGT.js";
2
- import { n as errorFromEvent } from "../errors-DWshWx18.js";
3
- import { n as createHttpAiProviderWithFetch } from "../http-provider-Cx2ZcLRB.js";
4
- import { g as buildChatRequest, h as buildAltTextRequest, i as checkAltTextAnswer, o as runEditingTurn, p as walkBlocks, r as checkAltText, t as buildAltTextRepairRequest, v as buildFixRequest } from "../checks-DvLD3892.js";
1
+ import { l as aiRoutePath, o as AI_SESSION_HEADER, s as AI_WIRE_HEADER, t as AI_ERROR_MESSAGES, u as matchAiRoute } from "../wire-cYO4W7GH.js";
2
+ import { n as errorFromEvent } from "../errors-BtORdtK2.js";
3
+ import { n as createHttpAiProviderWithFetch } from "../http-provider-DLJYM4l8.js";
4
+ import { g as buildChatRequest, h as buildAltTextRequest, i as checkAltTextAnswer, o as runEditingTurn, p as walkBlocks, r as checkAltText, t as buildAltTextRepairRequest, v as buildFixRequest } from "../checks-B-TtaywP.js";
5
5
  import { CollaborationConflict, OperationError, SdkError, applyOperations, createButtonBlock, createParagraphBlock, createTitleBlock, invertOperations, safeClone } from "@templatical/types";
6
- //#region package.json
7
- var version = "0.51.1";
8
- //#endregion
9
- //#region eval/cases.json
6
+ // package.json
7
+ var version = "0.52.0";
8
+ // eval/cases.json
10
9
  var cases_default = [
11
10
  {
12
11
  "name": "button text",
@@ -652,8 +651,7 @@ var cases_default = [
652
651
  ]
653
652
  }
654
653
  ];
655
- //#endregion
656
- //#region eval/empty.json
654
+ // eval/empty.json
657
655
  var empty_default = {
658
656
  blocks: [],
659
657
  settings: {
@@ -665,8 +663,7 @@ var empty_default = {
665
663
  "locale": "en"
666
664
  }
667
665
  };
668
- //#endregion
669
- //#region eval/domain-mismatch.json
666
+ // eval/domain-mismatch.json
670
667
  var domain_mismatch_default = {
671
668
  blocks: [{
672
669
  "id": "domain-link",
@@ -688,8 +685,7 @@ var domain_mismatch_default = {
688
685
  "locale": "en"
689
686
  }
690
687
  };
691
- //#endregion
692
- //#region eval/low-text.json
688
+ // eval/low-text.json
693
689
  var low_text_default = {
694
690
  blocks: [{
695
691
  "id": "mug-image",
@@ -724,8 +720,7 @@ var low_text_default = {
724
720
  "locale": "en"
725
721
  }
726
722
  };
727
- //#endregion
728
- //#region eval/injection.json
723
+ // eval/injection.json
729
724
  var injection_default = {
730
725
  blocks: [
731
726
  {
@@ -867,8 +862,7 @@ var injection_default = {
867
862
  "locale": "en"
868
863
  }
869
864
  };
870
- //#endregion
871
- //#region eval/promo.json
865
+ // eval/promo.json
872
866
  var promo_default = {
873
867
  blocks: [
874
868
  {
@@ -999,8 +993,7 @@ var promo_default = {
999
993
  "locale": "de"
1000
994
  }
1001
995
  };
1002
- //#endregion
1003
- //#region eval/welcome.json
996
+ // eval/welcome.json
1004
997
  var welcome_default = {
1005
998
  blocks: [
1006
999
  {
@@ -1131,8 +1124,7 @@ var welcome_default = {
1131
1124
  "locale": "en"
1132
1125
  }
1133
1126
  };
1134
- //#endregion
1135
- //#region src/testing/eval-set.ts
1127
+ // src/testing/eval-set.ts
1136
1128
  /** The cases of S7's test set (`eval/cases.json`). An omitted kind means edit. */
1137
1129
  const AI_EVAL_CASES = cases_default;
1138
1130
  const AI_EVAL_TEMPLATES = {
@@ -1428,8 +1420,7 @@ function evalTurnWith(model, options = {}) {
1428
1420
  };
1429
1421
  };
1430
1422
  }
1431
- //#endregion
1432
- //#region src/testing/checks.ts
1423
+ // src/testing/checks.ts
1433
1424
  const KNOWN_CODES = /* @__PURE__ */ new Set([
1434
1425
  "feature_unavailable",
1435
1426
  "limit_reached",
@@ -1463,8 +1454,7 @@ function messageProblem(message) {
1463
1454
  if (!m || typeof m.id !== "string" || !["user", "assistant"].includes(m.role) || !["chat", "fix"].includes(m.kind) || typeof m.text !== "string" || m.attachments !== void 0 && (!Array.isArray(m.attachments) || !m.attachments.every((a) => a && typeof a.name === "string" && ["image", "pdf"].includes(a.kind))) || !Array.isArray(m.batches) || typeof m.undone !== "boolean" || typeof m.createdAt !== "string" || !m.batches.every((batch) => typeof batch.batchId === "string" && (batch.revision === null || Number.isInteger(batch.revision)) && Number.isInteger(batch.operationCount))) return `malformed message: ${JSON.stringify(message)}`;
1464
1455
  return null;
1465
1456
  }
1466
- //#endregion
1467
- //#region src/testing/stand-in-editor.ts
1457
+ // src/testing/stand-in-editor.ts
1468
1458
  function createStandInEditor(content, mergeTags = {
1469
1459
  syntax: "liquid",
1470
1460
  tags: []
@@ -1519,8 +1509,7 @@ function createStandInEditor(content, mergeTags = {
1519
1509
  };
1520
1510
  return editor;
1521
1511
  }
1522
- //#endregion
1523
- //#region src/testing/conformance.ts
1512
+ // src/testing/conformance.ts
1524
1513
  const FEATURES = [
1525
1514
  "chat",
1526
1515
  "fixFinding",
@@ -1898,8 +1887,7 @@ async function runAiProviderConformance(provider, options = {}) {
1898
1887
  checks
1899
1888
  };
1900
1889
  }
1901
- //#endregion
1902
- //#region src/testing/wire-conformance.ts
1890
+ // src/testing/wire-conformance.ts
1903
1891
  /**
1904
1892
  * The provider suite over the wire, through `createHttpAiProvider`, plus the
1905
1893
  * wire's own rules: every response carries `Templatical-AI-Wire: 1`, streams
@@ -2077,8 +2065,7 @@ async function runAiWireConformance(options) {
2077
2065
  checks: all
2078
2066
  };
2079
2067
  }
2080
- //#endregion
2081
- //#region src/testing/mock-provider.ts
2068
+ // src/testing/mock-provider.ts
2082
2069
  function stopped(signal) {
2083
2070
  const reason = signal.reason;
2084
2071
  return reason instanceof Error && reason.name === "AbortError" ? reason : new DOMException("The AI request was stopped.", "AbortError");
@@ -2271,8 +2258,7 @@ function createMockAiProvider(script) {
2271
2258
  } } : {}
2272
2259
  };
2273
2260
  }
2274
- //#endregion
2275
- //#region src/testing/recordings.ts
2261
+ // src/testing/recordings.ts
2276
2262
  const text = (value) => ({
2277
2263
  type: "text",
2278
2264
  text: value
@@ -2439,7 +2425,6 @@ const AI_RECORDINGS = {
2439
2425
  ];
2440
2426
  }
2441
2427
  };
2442
- //#endregion
2443
2428
  export { AI_CONFORMANCE_ALT_TEXT_IMAGE_URL, AI_EVAL_CASES, AI_EVAL_MERGE_TAGS, AI_EVAL_TEMPLATES, AI_RECORDINGS, checkEvalCase, createMockAiProvider, createStandInEditor, evalAltTextWith, evalTurnWith, runAiEvalSet, runAiProviderConformance, runAiWireConformance };
2444
2429
 
2445
2430
  //# sourceMappingURL=index.js.map