@jxburros/ai-nugget 0.3.1 → 0.6.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 (183) hide show
  1. package/README.md +134 -271
  2. package/UPGRADING.md +158 -0
  3. package/dist/adapters/engines/anthropic.d.ts +7 -1
  4. package/dist/adapters/engines/anthropic.js +64 -37
  5. package/dist/adapters/engines/base.d.ts +29 -2
  6. package/dist/adapters/engines/base.js +52 -8
  7. package/dist/adapters/engines/google.d.ts +17 -1
  8. package/dist/adapters/engines/google.js +93 -29
  9. package/dist/adapters/engines/ollama.d.ts +2 -1
  10. package/dist/adapters/engines/ollama.js +51 -15
  11. package/dist/adapters/engines/openaiChat.d.ts +2 -1
  12. package/dist/adapters/engines/openaiChat.js +60 -30
  13. package/dist/adapters/profiles.d.ts +21 -1
  14. package/dist/adapters/profiles.js +12 -2
  15. package/dist/agent/loop.d.ts +43 -1
  16. package/dist/agent/loop.js +120 -13
  17. package/dist/cjs/adapters/engines/anthropic.js +308 -0
  18. package/dist/cjs/adapters/engines/base.js +147 -0
  19. package/dist/cjs/adapters/engines/google.js +284 -0
  20. package/dist/cjs/adapters/engines/ollama.js +199 -0
  21. package/dist/cjs/adapters/engines/openaiChat.js +261 -0
  22. package/dist/cjs/adapters/index.js +22 -0
  23. package/dist/cjs/adapters/profiles.js +125 -0
  24. package/dist/cjs/agent/index.js +18 -0
  25. package/dist/cjs/agent/loop.js +372 -0
  26. package/dist/cjs/agent/tools.js +51 -0
  27. package/dist/cjs/connect.js +27 -0
  28. package/dist/cjs/errors.js +110 -0
  29. package/dist/cjs/handler.js +561 -0
  30. package/dist/cjs/index.js +27 -0
  31. package/dist/cjs/json.js +121 -0
  32. package/dist/cjs/keys.js +81 -0
  33. package/dist/cjs/package.json +3 -0
  34. package/dist/cjs/policy.js +42 -0
  35. package/dist/cjs/redact.js +78 -0
  36. package/dist/cjs/tokens.js +22 -0
  37. package/dist/cjs/transport.js +172 -0
  38. package/dist/cjs/types.js +6 -0
  39. package/dist/cjs/util.js +112 -0
  40. package/dist/connect.d.ts +31 -0
  41. package/dist/connect.js +25 -0
  42. package/dist/errors.js +25 -1
  43. package/dist/handler.d.ts +61 -1
  44. package/dist/handler.js +247 -61
  45. package/dist/index.d.ts +1 -0
  46. package/dist/index.js +1 -0
  47. package/dist/keys.js +1 -4
  48. package/dist/redact.d.ts +18 -0
  49. package/dist/redact.js +29 -1
  50. package/dist/transport.d.ts +3 -1
  51. package/dist/transport.js +21 -1
  52. package/dist/types.d.ts +96 -2
  53. package/dist/util.d.ts +16 -0
  54. package/dist/util.js +50 -0
  55. package/nugget/VERSION.txt +2 -2
  56. package/nugget/dist/adapters/engines/anthropic.d.ts +14 -0
  57. package/nugget/dist/adapters/engines/anthropic.d.ts.map +1 -0
  58. package/nugget/dist/adapters/engines/anthropic.js +305 -0
  59. package/nugget/dist/adapters/engines/anthropic.js.map +1 -0
  60. package/nugget/dist/adapters/engines/base.d.ts +50 -0
  61. package/nugget/dist/adapters/engines/base.d.ts.map +1 -0
  62. package/nugget/dist/adapters/engines/base.js +137 -0
  63. package/nugget/dist/adapters/engines/base.js.map +1 -0
  64. package/nugget/dist/adapters/engines/google.d.ts +24 -0
  65. package/nugget/dist/adapters/engines/google.d.ts.map +1 -0
  66. package/nugget/dist/adapters/engines/google.js +281 -0
  67. package/nugget/dist/adapters/engines/google.js.map +1 -0
  68. package/nugget/dist/adapters/engines/ollama.d.ts +11 -0
  69. package/nugget/dist/adapters/engines/ollama.d.ts.map +1 -0
  70. package/nugget/dist/adapters/engines/ollama.js +196 -0
  71. package/nugget/dist/adapters/engines/ollama.js.map +1 -0
  72. package/nugget/dist/adapters/engines/openaiChat.d.ts +16 -0
  73. package/nugget/dist/adapters/engines/openaiChat.d.ts.map +1 -0
  74. package/nugget/dist/adapters/engines/openaiChat.js +258 -0
  75. package/nugget/dist/adapters/engines/openaiChat.js.map +1 -0
  76. package/nugget/dist/adapters/index.d.ts +5 -0
  77. package/nugget/dist/adapters/index.d.ts.map +1 -0
  78. package/nugget/dist/adapters/index.js +17 -0
  79. package/nugget/dist/adapters/index.js.map +1 -0
  80. package/nugget/dist/adapters/profiles.d.ts +62 -0
  81. package/nugget/dist/adapters/profiles.d.ts.map +1 -0
  82. package/nugget/dist/adapters/profiles.js +121 -0
  83. package/nugget/dist/adapters/profiles.js.map +1 -0
  84. package/nugget/dist/agent/index.d.ts +3 -0
  85. package/nugget/dist/agent/index.d.ts.map +1 -0
  86. package/nugget/dist/agent/index.js +3 -0
  87. package/nugget/dist/agent/index.js.map +1 -0
  88. package/nugget/dist/agent/loop.d.ts +112 -0
  89. package/nugget/dist/agent/loop.d.ts.map +1 -0
  90. package/nugget/dist/agent/loop.js +370 -0
  91. package/nugget/dist/agent/loop.js.map +1 -0
  92. package/nugget/dist/agent/tools.d.ts +29 -0
  93. package/nugget/dist/agent/tools.d.ts.map +1 -0
  94. package/nugget/dist/agent/tools.js +48 -0
  95. package/nugget/dist/agent/tools.js.map +1 -0
  96. package/nugget/dist/cjs/adapters/engines/anthropic.js +308 -0
  97. package/nugget/dist/cjs/adapters/engines/base.js +147 -0
  98. package/nugget/dist/cjs/adapters/engines/google.js +284 -0
  99. package/nugget/dist/cjs/adapters/engines/ollama.js +199 -0
  100. package/nugget/dist/cjs/adapters/engines/openaiChat.js +261 -0
  101. package/nugget/dist/cjs/adapters/index.js +22 -0
  102. package/nugget/dist/cjs/adapters/profiles.js +125 -0
  103. package/nugget/dist/cjs/agent/index.js +18 -0
  104. package/nugget/dist/cjs/agent/loop.js +372 -0
  105. package/nugget/dist/cjs/agent/tools.js +51 -0
  106. package/nugget/dist/cjs/connect.js +27 -0
  107. package/nugget/dist/cjs/errors.js +110 -0
  108. package/nugget/dist/cjs/handler.js +561 -0
  109. package/nugget/dist/cjs/index.js +27 -0
  110. package/nugget/dist/cjs/json.js +121 -0
  111. package/nugget/dist/cjs/keys.js +81 -0
  112. package/nugget/dist/cjs/package.json +3 -0
  113. package/nugget/dist/cjs/policy.js +42 -0
  114. package/nugget/dist/cjs/redact.js +78 -0
  115. package/nugget/dist/cjs/tokens.js +22 -0
  116. package/nugget/dist/cjs/transport.js +172 -0
  117. package/nugget/dist/cjs/types.js +6 -0
  118. package/nugget/dist/cjs/util.js +112 -0
  119. package/nugget/dist/connect.d.ts +31 -0
  120. package/nugget/dist/connect.d.ts.map +1 -0
  121. package/nugget/dist/connect.js +25 -0
  122. package/nugget/dist/connect.js.map +1 -0
  123. package/nugget/dist/errors.d.ts +22 -0
  124. package/nugget/dist/errors.d.ts.map +1 -0
  125. package/nugget/dist/errors.js +104 -0
  126. package/nugget/dist/errors.js.map +1 -0
  127. package/nugget/dist/handler.d.ts +108 -0
  128. package/nugget/dist/handler.d.ts.map +1 -0
  129. package/nugget/dist/handler.js +557 -0
  130. package/nugget/dist/handler.js.map +1 -0
  131. package/nugget/dist/index.d.ts +12 -0
  132. package/nugget/dist/index.d.ts.map +1 -0
  133. package/nugget/dist/index.js +12 -0
  134. package/nugget/dist/index.js.map +1 -0
  135. package/nugget/dist/json.d.ts +7 -0
  136. package/nugget/dist/json.d.ts.map +1 -0
  137. package/nugget/dist/json.js +114 -0
  138. package/nugget/dist/json.js.map +1 -0
  139. package/nugget/dist/keys.d.ts +7 -0
  140. package/nugget/dist/keys.d.ts.map +1 -0
  141. package/nugget/dist/keys.js +75 -0
  142. package/nugget/dist/keys.js.map +1 -0
  143. package/nugget/dist/policy.d.ts +6 -0
  144. package/nugget/dist/policy.d.ts.map +1 -0
  145. package/nugget/dist/policy.js +37 -0
  146. package/nugget/dist/policy.js.map +1 -0
  147. package/nugget/dist/redact.d.ts +26 -0
  148. package/nugget/dist/redact.d.ts.map +1 -0
  149. package/nugget/dist/redact.js +74 -0
  150. package/nugget/dist/redact.js.map +1 -0
  151. package/nugget/dist/tokens.d.ts +5 -0
  152. package/nugget/dist/tokens.d.ts.map +1 -0
  153. package/nugget/dist/tokens.js +18 -0
  154. package/nugget/dist/tokens.js.map +1 -0
  155. package/nugget/dist/transport.d.ts +30 -0
  156. package/nugget/dist/transport.d.ts.map +1 -0
  157. package/nugget/dist/transport.js +165 -0
  158. package/nugget/dist/transport.js.map +1 -0
  159. package/nugget/dist/types.d.ts +285 -0
  160. package/nugget/dist/types.d.ts.map +1 -0
  161. package/nugget/dist/types.js +4 -0
  162. package/nugget/dist/types.js.map +1 -0
  163. package/nugget/dist/util.d.ts +24 -0
  164. package/nugget/dist/util.d.ts.map +1 -0
  165. package/nugget/dist/util.js +101 -0
  166. package/nugget/dist/util.js.map +1 -0
  167. package/nugget/src/adapters/engines/anthropic.ts +62 -37
  168. package/nugget/src/adapters/engines/base.ts +50 -7
  169. package/nugget/src/adapters/engines/google.ts +92 -29
  170. package/nugget/src/adapters/engines/ollama.ts +51 -17
  171. package/nugget/src/adapters/engines/openaiChat.ts +61 -32
  172. package/nugget/src/adapters/profiles.ts +53 -3
  173. package/nugget/src/agent/loop.ts +158 -14
  174. package/nugget/src/connect.ts +48 -0
  175. package/nugget/src/errors.ts +25 -1
  176. package/nugget/src/handler.ts +286 -59
  177. package/nugget/src/index.ts +1 -0
  178. package/nugget/src/keys.ts +1 -5
  179. package/nugget/src/redact.ts +32 -1
  180. package/nugget/src/transport.ts +20 -1
  181. package/nugget/src/types.ts +96 -1
  182. package/nugget/src/util.ts +55 -0
  183. package/package.json +20 -6
@@ -0,0 +1,114 @@
1
+ import { AIError } from './errors.js';
2
+ export function extractJson(text) {
3
+ const trimmed = text.trim();
4
+ if (!trimmed)
5
+ return null;
6
+ const direct = tryParse(trimmed);
7
+ if (direct.ok)
8
+ return direct.value;
9
+ const fenced = /```(?:json)?\s*([\s\S]*?)```/i.exec(text);
10
+ if (fenced?.[1]) {
11
+ const parsed = tryParse(fenced[1].trim());
12
+ if (parsed.ok)
13
+ return parsed.value;
14
+ }
15
+ for (const [open, close] of [['{', '}'], ['[', ']']]) {
16
+ for (const span of balancedSpans(text, open, close)) {
17
+ const parsed = tryParse(span);
18
+ if (parsed.ok)
19
+ return parsed.value;
20
+ }
21
+ }
22
+ return null;
23
+ }
24
+ /**
25
+ * Yields each top-level `open`/`close` balanced substring of `text`, tracking
26
+ * nesting depth and skipping over string-literal content (including escapes)
27
+ * so a stray brace inside a string or trailing prose can't prematurely close
28
+ * or extend a span. Used instead of first-`indexOf`/last-`lastIndexOf` so
29
+ * multiple JSON regions (or JSON followed by unrelated braces) don't get
30
+ * spliced into one bogus span.
31
+ */
32
+ function* balancedSpans(text, open, close) {
33
+ let depth = 0;
34
+ let spanStart = -1;
35
+ let inString = false;
36
+ let escaped = false;
37
+ for (let i = 0; i < text.length; i += 1) {
38
+ const ch = text[i];
39
+ if (inString) {
40
+ if (escaped)
41
+ escaped = false;
42
+ else if (ch === '\\')
43
+ escaped = true;
44
+ else if (ch === '"')
45
+ inString = false;
46
+ continue;
47
+ }
48
+ if (ch === '"') {
49
+ inString = true;
50
+ continue;
51
+ }
52
+ if (ch === open) {
53
+ if (depth === 0)
54
+ spanStart = i;
55
+ depth += 1;
56
+ continue;
57
+ }
58
+ if (ch === close && depth > 0) {
59
+ depth -= 1;
60
+ if (depth === 0 && spanStart >= 0) {
61
+ yield text.slice(spanStart, i + 1);
62
+ spanStart = -1;
63
+ }
64
+ }
65
+ }
66
+ }
67
+ export function extractJsonWithSchema(text, parse) {
68
+ const value = extractJson(text);
69
+ if (value === null)
70
+ throw new AIError('No JSON object or array found in model output', { kind: 'invalid_response' });
71
+ try {
72
+ return parse(value);
73
+ }
74
+ catch (error) {
75
+ const message = error instanceof Error ? error.message : 'JSON did not match expected schema';
76
+ throw new AIError(message, { kind: 'invalid_response', cause: error });
77
+ }
78
+ }
79
+ export function requireString(record, key) {
80
+ const value = record[key];
81
+ if (typeof value !== 'string')
82
+ throw new Error(`Expected ${key} to be a string`);
83
+ return value;
84
+ }
85
+ export function requireNumber(record, key) {
86
+ const value = record[key];
87
+ if (typeof value !== 'number' || !Number.isFinite(value))
88
+ throw new Error(`Expected ${key} to be a number`);
89
+ return value;
90
+ }
91
+ export function requireStringArray(record, key) {
92
+ const value = record[key];
93
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== 'string')) {
94
+ throw new Error(`Expected ${key} to be a string array`);
95
+ }
96
+ return value;
97
+ }
98
+ export function requireOptionalString(record, key) {
99
+ const value = record[key];
100
+ if (value === undefined || value === null)
101
+ return undefined;
102
+ if (typeof value !== 'string')
103
+ throw new Error(`Expected ${key} to be a string when present`);
104
+ return value;
105
+ }
106
+ function tryParse(text) {
107
+ try {
108
+ return { ok: true, value: JSON.parse(text) };
109
+ }
110
+ catch {
111
+ return { ok: false };
112
+ }
113
+ }
114
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { KeyRef, KeySource } from './types.js';
2
+ export declare function parseKeyRef(value?: string | null): KeyRef;
3
+ export declare function envKeySource(env?: Record<string, string | undefined>): KeySource;
4
+ export declare function literalKeySource(): KeySource;
5
+ export declare function memoryKeySource(values: Record<string, string | null | undefined>): KeySource;
6
+ export declare function chainKeySources(...sources: KeySource[]): KeySource;
7
+ //# sourceMappingURL=keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGpD,wBAAgB,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAWzD;AAED,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,SAAS,CAS7F;AAED,wBAAgB,gBAAgB,IAAI,SAAS,CAQ5C;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,SAAS,CAU5F;AAED,wBAAgB,eAAe,CAAC,GAAG,OAAO,EAAE,SAAS,EAAE,GAAG,SAAS,CAgBlE"}
@@ -0,0 +1,75 @@
1
+ import { globalEnv } from './util.js';
2
+ export function parseKeyRef(value) {
3
+ const trimmed = value?.trim();
4
+ if (!trimmed)
5
+ return { kind: 'none' };
6
+ const braced = /^\$\{([A-Z0-9_]+)\}$/.exec(trimmed);
7
+ if (braced?.[1])
8
+ return { kind: 'env', name: braced[1] };
9
+ const dollar = /^\$([A-Z0-9_]+)$/.exec(trimmed);
10
+ if (dollar?.[1])
11
+ return { kind: 'env', name: dollar[1] };
12
+ if (/^[A-Z][A-Z0-9_]{2,}$/.test(trimmed))
13
+ return { kind: 'env', name: trimmed };
14
+ if (trimmed.startsWith('secret://'))
15
+ return { kind: 'brokered', ref: trimmed };
16
+ if (trimmed.startsWith('stored://'))
17
+ return { kind: 'stored', ref: trimmed.slice('stored://'.length) };
18
+ return { kind: 'literal', value: trimmed };
19
+ }
20
+ export function envKeySource(env = globalEnv()) {
21
+ return {
22
+ async resolve(ref) {
23
+ if (ref.kind === 'none')
24
+ return { ok: true, apiKey: null };
25
+ if (ref.kind !== 'env')
26
+ return { ok: false, reason: 'denied' };
27
+ const apiKey = env[ref.name]?.trim();
28
+ return apiKey ? { ok: true, apiKey } : { ok: false, reason: 'missing' };
29
+ },
30
+ };
31
+ }
32
+ export function literalKeySource() {
33
+ return {
34
+ async resolve(ref) {
35
+ if (ref.kind === 'none')
36
+ return { ok: true, apiKey: null };
37
+ if (ref.kind === 'literal')
38
+ return { ok: true, apiKey: ref.value };
39
+ return { ok: false, reason: 'denied' };
40
+ },
41
+ };
42
+ }
43
+ export function memoryKeySource(values) {
44
+ return {
45
+ async resolve(ref) {
46
+ if (ref.kind === 'none')
47
+ return { ok: true, apiKey: null };
48
+ if (ref.kind === 'literal')
49
+ return { ok: true, apiKey: ref.value };
50
+ const key = ref.kind === 'env' ? ref.name : ref.ref;
51
+ const value = values[key]?.trim();
52
+ return value ? { ok: true, apiKey: value } : { ok: false, reason: 'missing' };
53
+ },
54
+ };
55
+ }
56
+ export function chainKeySources(...sources) {
57
+ return {
58
+ async resolve(ref) {
59
+ let missing = false;
60
+ for (const source of sources) {
61
+ const result = await source.resolve(ref);
62
+ if (result.ok)
63
+ return result;
64
+ if (result.reason === 'locked')
65
+ return result;
66
+ if (result.reason === 'missing') {
67
+ missing = true;
68
+ continue;
69
+ }
70
+ }
71
+ return missing ? { ok: false, reason: 'missing' } : { ok: false, reason: 'denied' };
72
+ },
73
+ };
74
+ }
75
+ //# sourceMappingURL=keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { GovernancePolicy } from './types.js';
2
+ export declare function allowAllPolicy(): GovernancePolicy;
3
+ export declare function blocklistPolicy(patterns: RegExp[]): GovernancePolicy;
4
+ export declare function allowlistPolicy(prefixesByProvider: Record<string, string[]>): GovernancePolicy;
5
+ export declare function composePolicies(...policies: GovernancePolicy[]): GovernancePolicy;
6
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,wBAAgB,cAAc,IAAI,gBAAgB,CAEjD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAQpE;AAED,wBAAgB,eAAe,CAAC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,gBAAgB,CAU9F;AAED,wBAAgB,eAAe,CAAC,GAAG,QAAQ,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,CAUjF"}
@@ -0,0 +1,37 @@
1
+ export function allowAllPolicy() {
2
+ return { checkModel: () => ({ allowed: true }) };
3
+ }
4
+ export function blocklistPolicy(patterns) {
5
+ return {
6
+ checkModel(provider, model) {
7
+ const target = `${provider}/${model}`;
8
+ const blocked = patterns.find((pattern) => pattern.test(target));
9
+ return blocked ? { allowed: false, reason: `Model blocked by policy: ${blocked}` } : { allowed: true };
10
+ },
11
+ };
12
+ }
13
+ export function allowlistPolicy(prefixesByProvider) {
14
+ return {
15
+ checkModel(provider, model) {
16
+ const prefixes = prefixesByProvider[provider];
17
+ if (!prefixes || prefixes.length === 0)
18
+ return { allowed: false, reason: `No models are allowed for provider ${provider}` };
19
+ return prefixes.some((prefix) => prefix === '*' || model.startsWith(prefix))
20
+ ? { allowed: true }
21
+ : { allowed: false, reason: `Model is not allowed for provider ${provider}` };
22
+ },
23
+ };
24
+ }
25
+ export function composePolicies(...policies) {
26
+ return {
27
+ checkModel(provider, model) {
28
+ for (const policy of policies) {
29
+ const result = policy.checkModel(provider, model);
30
+ if (!result.allowed)
31
+ return result;
32
+ }
33
+ return { allowed: true };
34
+ },
35
+ };
36
+ }
37
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,cAAc;IAC5B,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAkB;IAChD,OAAO;QACL,UAAU,CAAC,QAAQ,EAAE,KAAK;YACxB,MAAM,MAAM,GAAG,GAAG,QAAQ,IAAI,KAAK,EAAE,CAAC;YACtC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACjE,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,4BAA4B,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACzG,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,kBAA4C;IAC1E,OAAO;QACL,UAAU,CAAC,QAAQ,EAAE,KAAK;YACxB,MAAM,QAAQ,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAC9C,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,sCAAsC,QAAQ,EAAE,EAAE,CAAC;YAC5H,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;gBAC1E,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE;gBACnB,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,qCAAqC,QAAQ,EAAE,EAAE,CAAC;QAClF,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAG,QAA4B;IAC7D,OAAO;QACL,UAAU,CAAC,QAAQ,EAAE,KAAK;YACxB,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;gBAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;gBAClD,IAAI,CAAC,MAAM,CAAC,OAAO;oBAAE,OAAO,MAAM,CAAC;YACrC,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { Redactor } from './types.js';
2
+ /**
3
+ * Prefixed secret formats. Each pattern is anchored on a vendor prefix that is
4
+ * distinctive enough that a match is a secret, not a coincidence.
5
+ */
6
+ export declare const SECRET_PATTERNS: RegExp[];
7
+ /**
8
+ * Unprefixed/opaque secrets — Azure OpenAI `api-key` values, AWS *secret*
9
+ * access keys, generic bearer/session tokens — carry no distinctive prefix, so
10
+ * matching them on shape alone would redact commit SHAs, content hashes, and
11
+ * base64 payloads. These patterns instead anchor on the *label* that precedes
12
+ * the value (`api-key: …`, `"aws_secret_access_key": "…"`, `password=…`) and
13
+ * redact only the value, keeping the label readable in logs.
14
+ *
15
+ * Exact-match registration (`SessionRedactor.addSecret`, which the handler does
16
+ * for every resolved key) remains the only guaranteed catch for a bare,
17
+ * unlabeled, unprefixed secret.
18
+ */
19
+ export declare const LABELED_SECRET_PATTERNS: RegExp[];
20
+ export declare function createDefaultRedactor(extraSecrets?: Iterable<string>): Redactor;
21
+ export declare class SessionRedactor implements Redactor {
22
+ private secrets;
23
+ addSecret(value: string | null | undefined): void;
24
+ redact(text: string): string;
25
+ }
26
+ //# sourceMappingURL=redact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,EAqBnC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,EAU3C,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,YAAY,GAAE,QAAQ,CAAC,MAAM,CAAM,GAAG,QAAQ,CAanF;AAED,qBAAa,eAAgB,YAAW,QAAQ;IAC9C,OAAO,CAAC,OAAO,CAAqB;IAEpC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI;IAIjD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAG7B"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Prefixed secret formats. Each pattern is anchored on a vendor prefix that is
3
+ * distinctive enough that a match is a secret, not a coincidence.
4
+ */
5
+ export const SECRET_PATTERNS = [
6
+ /sk-[A-Za-z0-9_-]{20,}/g,
7
+ /sk-proj-[A-Za-z0-9_-]{20,}/g,
8
+ /sk-ant-[A-Za-z0-9_-]{20,}/g,
9
+ /AIza[0-9A-Za-z_-]{20,}/g,
10
+ /gsk_[0-9A-Za-z_-]{20,}/g,
11
+ /xai-[0-9A-Za-z_-]{20,}/g,
12
+ /hf_[0-9A-Za-z]{20,}/g,
13
+ /nvapi-[0-9A-Za-z_-]{20,}/g,
14
+ /ghp_[0-9A-Za-z_]{20,}/g,
15
+ /github_pat_[0-9A-Za-z_]{20,}/g,
16
+ /glpat-[0-9A-Za-z_-]{20,}/g,
17
+ /\bBearer\s+[A-Za-z0-9._~+/=-]{20,}/gi,
18
+ /xox[baprs]-[0-9A-Za-z-]{10,}/g,
19
+ /AKIA[0-9A-Z]{16}/g,
20
+ /ASIA[0-9A-Z]{16}/g,
21
+ /SG\.[0-9A-Za-z_-]{10,}\.[0-9A-Za-z_-]{10,}/g,
22
+ /rk_live_[0-9A-Za-z]{20,}/g,
23
+ /pk_live_[0-9A-Za-z]{20,}/g,
24
+ /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,
25
+ /eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,
26
+ ];
27
+ /**
28
+ * Unprefixed/opaque secrets — Azure OpenAI `api-key` values, AWS *secret*
29
+ * access keys, generic bearer/session tokens — carry no distinctive prefix, so
30
+ * matching them on shape alone would redact commit SHAs, content hashes, and
31
+ * base64 payloads. These patterns instead anchor on the *label* that precedes
32
+ * the value (`api-key: …`, `"aws_secret_access_key": "…"`, `password=…`) and
33
+ * redact only the value, keeping the label readable in logs.
34
+ *
35
+ * Exact-match registration (`SessionRedactor.addSecret`, which the handler does
36
+ * for every resolved key) remains the only guaranteed catch for a bare,
37
+ * unlabeled, unprefixed secret.
38
+ */
39
+ export const LABELED_SECRET_PATTERNS = [
40
+ new RegExp(
41
+ // Lookbehind rather than `\b` so an underscore-joined prefix still matches
42
+ // the label (`aws_secret_access_key`, `azure_api_key`).
43
+ String.raw `(?<![A-Za-z0-9])(api[_-]?key|apikey|secret[_-]?access[_-]?key|access[_-]?token|auth[_-]?token|session[_-]?token|client[_-]?secret|refresh[_-]?token|private[_-]?key|password|passwd)` +
44
+ // Optional closing quote handles JSON keys (`"api_key": "…"`).
45
+ String.raw `(["']?\s*[:=]\s*|\s+)` +
46
+ String.raw `(["']?)([A-Za-z0-9/+_.~-]{16,}={0,2})\3`, 'gi'),
47
+ ];
48
+ export function createDefaultRedactor(extraSecrets = []) {
49
+ const secrets = new Set([...extraSecrets].filter((value) => value.length >= 6));
50
+ return {
51
+ redact(text) {
52
+ let output = text;
53
+ for (const pattern of SECRET_PATTERNS)
54
+ output = output.replace(pattern, '[REDACTED]');
55
+ for (const pattern of LABELED_SECRET_PATTERNS) {
56
+ output = output.replace(pattern, (_match, label, separator, quote) => `${label}${separator}${quote}[REDACTED]${quote}`);
57
+ }
58
+ for (const secret of secrets)
59
+ output = output.split(secret).join('[REDACTED]');
60
+ return output;
61
+ },
62
+ };
63
+ }
64
+ export class SessionRedactor {
65
+ secrets = new Set();
66
+ addSecret(value) {
67
+ if (value && value.length >= 6)
68
+ this.secrets.add(value);
69
+ }
70
+ redact(text) {
71
+ return createDefaultRedactor(this.secrets).redact(text);
72
+ }
73
+ }
74
+ //# sourceMappingURL=redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAa;IACvC,wBAAwB;IACxB,6BAA6B;IAC7B,4BAA4B;IAC5B,yBAAyB;IACzB,yBAAyB;IACzB,yBAAyB;IACzB,sBAAsB;IACtB,2BAA2B;IAC3B,wBAAwB;IACxB,+BAA+B;IAC/B,2BAA2B;IAC3B,sCAAsC;IACtC,+BAA+B;IAC/B,mBAAmB;IACnB,mBAAmB;IACnB,6CAA6C;IAC7C,2BAA2B;IAC3B,2BAA2B;IAC3B,6EAA6E;IAC7E,oDAAoD;CACrD,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAa;IAC/C,IAAI,MAAM;IACR,2EAA2E;IAC3E,wDAAwD;IACxD,MAAM,CAAC,GAAG,CAAA,sLAAsL;QAC9L,+DAA+D;QAC/D,MAAM,CAAC,GAAG,CAAA,uBAAuB;QACjC,MAAM,CAAC,GAAG,CAAA,yCAAyC,EACrD,IAAI,CACL;CACF,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,eAAiC,EAAE;IACvE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;IAChF,OAAO;QACL,MAAM,CAAC,IAAY;YACjB,IAAI,MAAM,GAAG,IAAI,CAAC;YAClB,KAAK,MAAM,OAAO,IAAI,eAAe;gBAAE,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YACtF,KAAK,MAAM,OAAO,IAAI,uBAAuB,EAAE,CAAC;gBAC9C,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,KAAa,EAAE,SAAiB,EAAE,KAAa,EAAE,EAAE,CAAC,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,aAAa,KAAK,EAAE,CAAC,CAAC;YAClJ,CAAC;YACD,KAAK,MAAM,MAAM,IAAI,OAAO;gBAAE,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC/E,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,eAAe;IAClB,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,SAAS,CAAC,KAAgC;QACxC,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,OAAO,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1D,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ import type { Usage } from './types.js';
2
+ export declare function estimateTokens(text: string): number;
3
+ export declare function estimatedUsage(inputText: string, outputText: string): Usage;
4
+ export declare function mergeUsage(a: Usage, b: Usage): Usage;
5
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,KAAK,CAM3E;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,CAMpD"}
@@ -0,0 +1,18 @@
1
+ export function estimateTokens(text) {
2
+ return Math.ceil(text.length / 4);
3
+ }
4
+ export function estimatedUsage(inputText, outputText) {
5
+ return {
6
+ inputTokens: estimateTokens(inputText),
7
+ outputTokens: estimateTokens(outputText),
8
+ estimated: true,
9
+ };
10
+ }
11
+ export function mergeUsage(a, b) {
12
+ return {
13
+ inputTokens: (a.inputTokens ?? 0) + (b.inputTokens ?? 0),
14
+ outputTokens: (a.outputTokens ?? 0) + (b.outputTokens ?? 0),
15
+ estimated: a.estimated || b.estimated,
16
+ };
17
+ }
18
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAiB,EAAE,UAAkB;IAClE,OAAO;QACL,WAAW,EAAE,cAAc,CAAC,SAAS,CAAC;QACtC,YAAY,EAAE,cAAc,CAAC,UAAU,CAAC;QACxC,SAAS,EAAE,IAAI;KAChB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAQ,EAAE,CAAQ;IAC3C,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC;QACxD,YAAY,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC;QAC3D,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS;KACtC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,30 @@
1
+ export declare function withTimeout(ms: number, external?: AbortSignal, idleMs?: number): {
2
+ signal: AbortSignal;
3
+ done(): void;
4
+ timedOut(): boolean;
5
+ /** Reset the idle timer. No-op unless `idleMs` was supplied. Call on each chunk. */
6
+ bump(): void;
7
+ };
8
+ export declare function fetchJson(url: string, init: RequestInit & {
9
+ timeoutMs: number;
10
+ provider?: string;
11
+ }): Promise<{
12
+ data: unknown;
13
+ status: number;
14
+ totalMs: number;
15
+ }>;
16
+ /**
17
+ * POST a JSON body and return the raw {@link Response} for streaming.
18
+ *
19
+ * The caller owns the abort/timeout `signal` and is responsible for keeping it
20
+ * alive until the response body has been fully consumed — passing a
21
+ * `withTimeout()` signal here and cleaning it up only after the stream ends is
22
+ * what lets external cancellation and the timeout apply for the *whole* stream,
23
+ * not merely the connection handshake. Non-2xx responses are classified and
24
+ * thrown before the body is handed back.
25
+ */
26
+ export declare function postResponse(url: string, body: unknown, headers: Record<string, string>, signal: AbortSignal, provider: string): Promise<Response>;
27
+ export declare function sseLines(res: Response): AsyncIterable<string>;
28
+ export declare function ndjsonLines(res: Response): AsyncIterable<unknown>;
29
+ export declare function textLines(res: Response): AsyncIterable<string>;
30
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG;IAChF,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,IAAI,IAAI,CAAC;IACb,QAAQ,IAAI,OAAO,CAAC;IACpB,oFAAoF;IACpF,IAAI,IAAI,IAAI,CAAC;CACd,CAuCA;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC;IAClH,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAcD;AAED;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,QAAQ,CAAC,CAiBnB;AAED,wBAAuB,QAAQ,CAAC,GAAG,EAAE,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CASpE;AAED,wBAAuB,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,CAUxE;AAED,wBAAuB,SAAS,CAAC,GAAG,EAAE,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CA+BrE"}
@@ -0,0 +1,165 @@
1
+ import { AIError, classify, fromUnknown } from './errors.js';
2
+ export function withTimeout(ms, external, idleMs) {
3
+ const controller = new AbortController();
4
+ let didTimeOut = false;
5
+ const timer = setTimeout(() => {
6
+ didTimeOut = true;
7
+ controller.abort(new AIError(`Request timed out after ${ms}ms`, { kind: 'timeout' }));
8
+ }, ms);
9
+ // Optional idle timeout: aborts only when no chunk has arrived for `idleMs`,
10
+ // rearmed on every `bump()`. Keeps a long but healthy stream alive while the
11
+ // total `ms` ceiling still bounds a truly stuck call.
12
+ let idleTimer;
13
+ const armIdle = () => {
14
+ if (idleMs === undefined)
15
+ return;
16
+ if (idleTimer)
17
+ clearTimeout(idleTimer);
18
+ idleTimer = setTimeout(() => {
19
+ didTimeOut = true;
20
+ controller.abort(new AIError(`Request idle for ${idleMs}ms`, { kind: 'timeout' }));
21
+ }, idleMs);
22
+ };
23
+ const onAbort = () => controller.abort(external?.reason);
24
+ if (external) {
25
+ if (external.aborted)
26
+ onAbort();
27
+ else
28
+ external.addEventListener('abort', onAbort, { once: true });
29
+ }
30
+ armIdle();
31
+ return {
32
+ signal: controller.signal,
33
+ done() {
34
+ clearTimeout(timer);
35
+ if (idleTimer)
36
+ clearTimeout(idleTimer);
37
+ external?.removeEventListener('abort', onAbort);
38
+ },
39
+ timedOut() {
40
+ return didTimeOut;
41
+ },
42
+ bump() {
43
+ armIdle();
44
+ },
45
+ };
46
+ }
47
+ export async function fetchJson(url, init) {
48
+ const timeout = withTimeout(init.timeoutMs, init.signal ?? undefined);
49
+ const started = Date.now();
50
+ try {
51
+ const res = await fetch(url, { ...init, signal: timeout.signal });
52
+ const raw = await res.text().catch(() => '');
53
+ if (!res.ok)
54
+ throw classify(res.status, raw, init.provider, res.headers);
55
+ return { data: raw.trim() ? tolerantJson(raw) : null, status: res.status, totalMs: Date.now() - started };
56
+ }
57
+ catch (error) {
58
+ if (timeout.timedOut())
59
+ throw new AIError(`Request timed out after ${init.timeoutMs}ms`, { kind: 'timeout', provider: init.provider });
60
+ throw fromUnknown(error, init.provider);
61
+ }
62
+ finally {
63
+ timeout.done();
64
+ }
65
+ }
66
+ /**
67
+ * POST a JSON body and return the raw {@link Response} for streaming.
68
+ *
69
+ * The caller owns the abort/timeout `signal` and is responsible for keeping it
70
+ * alive until the response body has been fully consumed — passing a
71
+ * `withTimeout()` signal here and cleaning it up only after the stream ends is
72
+ * what lets external cancellation and the timeout apply for the *whole* stream,
73
+ * not merely the connection handshake. Non-2xx responses are classified and
74
+ * thrown before the body is handed back.
75
+ */
76
+ export async function postResponse(url, body, headers, signal, provider) {
77
+ let res;
78
+ try {
79
+ res = await fetch(url, {
80
+ method: 'POST',
81
+ headers: { 'content-type': 'application/json', ...headers },
82
+ body: JSON.stringify(body),
83
+ signal,
84
+ });
85
+ }
86
+ catch (error) {
87
+ throw fromUnknown(error, provider);
88
+ }
89
+ if (!res.ok) {
90
+ const raw = await res.text().catch(() => '');
91
+ throw classify(res.status, raw, provider, res.headers);
92
+ }
93
+ return res;
94
+ }
95
+ export async function* sseLines(res) {
96
+ for await (const line of textLines(res)) {
97
+ const trimmed = line.trim();
98
+ if (!trimmed || trimmed.startsWith(':'))
99
+ continue;
100
+ if (!trimmed.startsWith('data:'))
101
+ continue;
102
+ const data = trimmed.slice(5).trim();
103
+ if (!data || data === '[DONE]')
104
+ continue;
105
+ yield data;
106
+ }
107
+ }
108
+ export async function* ndjsonLines(res) {
109
+ for await (const line of textLines(res)) {
110
+ const trimmed = line.trim();
111
+ if (!trimmed)
112
+ continue;
113
+ try {
114
+ yield JSON.parse(trimmed);
115
+ }
116
+ catch {
117
+ throw new AIError('Provider returned malformed NDJSON', { kind: 'invalid_response' });
118
+ }
119
+ }
120
+ }
121
+ export async function* textLines(res) {
122
+ if (!res.body) {
123
+ const raw = await res.text().catch(() => '');
124
+ for (const line of raw.split(/\r?\n/))
125
+ yield line;
126
+ return;
127
+ }
128
+ const reader = res.body.getReader();
129
+ const decoder = new TextDecoder();
130
+ let buffer = '';
131
+ let completed = false;
132
+ try {
133
+ for (;;) {
134
+ const { value, done } = await reader.read();
135
+ if (done) {
136
+ completed = true;
137
+ break;
138
+ }
139
+ buffer += decoder.decode(value, { stream: true });
140
+ let newlineIndex;
141
+ while ((newlineIndex = buffer.indexOf('\n')) >= 0) {
142
+ const line = buffer.slice(0, newlineIndex);
143
+ buffer = buffer.slice(newlineIndex + 1);
144
+ yield line;
145
+ }
146
+ }
147
+ buffer += decoder.decode();
148
+ if (buffer.trim())
149
+ yield buffer;
150
+ }
151
+ finally {
152
+ if (!completed)
153
+ await reader.cancel().catch(() => undefined);
154
+ reader.releaseLock();
155
+ }
156
+ }
157
+ function tolerantJson(raw) {
158
+ try {
159
+ return JSON.parse(raw);
160
+ }
161
+ catch {
162
+ return { text: raw };
163
+ }
164
+ }
165
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}