@aexol/spectral 0.9.221 → 0.9.222

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 (153) hide show
  1. package/dist/agent/index.d.ts +7 -3
  2. package/dist/agent/index.d.ts.map +1 -1
  3. package/dist/agent/index.js +35 -8
  4. package/dist/extensions/aexol-backend-client.d.ts +85 -0
  5. package/dist/extensions/aexol-backend-client.d.ts.map +1 -0
  6. package/dist/extensions/aexol-backend-client.js +159 -0
  7. package/dist/extensions/aexol-mcp.d.ts +10 -6
  8. package/dist/extensions/aexol-mcp.d.ts.map +1 -1
  9. package/dist/extensions/aexol-mcp.js +21 -106
  10. package/dist/extensions/logic-trace-backend-draft.d.ts +68 -0
  11. package/dist/extensions/logic-trace-backend-draft.d.ts.map +1 -0
  12. package/dist/extensions/logic-trace-backend-draft.js +171 -0
  13. package/dist/extensions/logic-trace-validate.d.ts +33 -0
  14. package/dist/extensions/logic-trace-validate.d.ts.map +1 -0
  15. package/dist/extensions/logic-trace-validate.js +73 -0
  16. package/dist/extensions/logic-trace.d.ts +213 -0
  17. package/dist/extensions/logic-trace.d.ts.map +1 -0
  18. package/dist/extensions/logic-trace.js +1098 -0
  19. package/dist/generated/parser/lexer.d.ts +148 -0
  20. package/dist/generated/parser/lexer.d.ts.map +1 -0
  21. package/dist/generated/parser/lexer.js +877 -0
  22. package/dist/generated/parser/mod.d.ts +26 -0
  23. package/dist/generated/parser/mod.d.ts.map +1 -0
  24. package/dist/generated/parser/mod.js +30 -0
  25. package/dist/generated/parser/parser.d.ts +161 -0
  26. package/dist/generated/parser/parser.d.ts.map +1 -0
  27. package/dist/generated/parser/parser.js +754 -0
  28. package/dist/generated/parser/tokenizer.d.ts +107 -0
  29. package/dist/generated/parser/tokenizer.d.ts.map +1 -0
  30. package/dist/generated/parser/tokenizer.js +202 -0
  31. package/dist/generated/parser/validator.d.ts +45 -0
  32. package/dist/generated/parser/validator.d.ts.map +1 -0
  33. package/dist/generated/parser/validator.js +202 -0
  34. package/dist/generated/zeus/const.d.ts.map +1 -1
  35. package/dist/generated/zeus/const.js +4 -170
  36. package/dist/generated/zeus/index.d.ts +8 -873
  37. package/dist/generated/zeus/index.d.ts.map +1 -1
  38. package/dist/generated/zeus/index.js +0 -7
  39. package/dist/mcp/ui-stream-types.d.ts +2 -2
  40. package/dist/memory/tools/share-project-observation.js +1 -1
  41. package/dist/memory/tools/write-project-observation.d.ts.map +1 -1
  42. package/dist/memory/tools/write-project-observation.js +4 -3
  43. package/dist/sdk/agent-core/harness/types.d.ts +0 -1
  44. package/dist/sdk/agent-core/harness/types.d.ts.map +1 -1
  45. package/dist/sdk/agent-core/index.d.ts +0 -8
  46. package/dist/sdk/agent-core/index.d.ts.map +1 -1
  47. package/dist/sdk/agent-core/index.js +0 -9
  48. package/dist/sdk/coding-agent/core/extensions/index.d.ts +1 -1
  49. package/dist/sdk/coding-agent/core/extensions/index.d.ts.map +1 -1
  50. package/dist/sdk/coding-agent/core/extensions/native-extensions.js +2 -2
  51. package/dist/sdk/coding-agent/core/extensions/types.d.ts +20 -1
  52. package/dist/sdk/coding-agent/core/extensions/types.d.ts.map +1 -1
  53. package/dist/sdk/coding-agent/core/tools/tool-definition-wrapper.d.ts +9 -4
  54. package/dist/sdk/coding-agent/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  55. package/dist/sdk/coding-agent/core/tools/tool-definition-wrapper.js +15 -2
  56. package/dist/sdk/coding-agent/index.d.ts +1 -1
  57. package/dist/sdk/coding-agent/index.d.ts.map +1 -1
  58. package/dist/server/agent-bridge/headless-ui.d.ts +20 -0
  59. package/dist/server/agent-bridge/headless-ui.d.ts.map +1 -0
  60. package/dist/server/agent-bridge/headless-ui.js +85 -0
  61. package/dist/server/agent-bridge/pricing.d.ts +37 -0
  62. package/dist/server/agent-bridge/pricing.d.ts.map +1 -0
  63. package/dist/server/agent-bridge/pricing.js +202 -0
  64. package/dist/server/agent-bridge/rehydrate.d.ts +35 -0
  65. package/dist/server/agent-bridge/rehydrate.d.ts.map +1 -0
  66. package/dist/server/agent-bridge/rehydrate.js +122 -0
  67. package/dist/server/agent-bridge/synthetic-model.d.ts +27 -0
  68. package/dist/server/agent-bridge/synthetic-model.d.ts.map +1 -0
  69. package/dist/server/agent-bridge/synthetic-model.js +92 -0
  70. package/dist/server/agent-bridge.d.ts +11 -1
  71. package/dist/server/agent-bridge.d.ts.map +1 -1
  72. package/dist/server/agent-bridge.js +42 -481
  73. package/dist/server/session-stream/compaction-events.d.ts +13 -0
  74. package/dist/server/session-stream/compaction-events.d.ts.map +1 -0
  75. package/dist/server/session-stream/compaction-events.js +32 -0
  76. package/dist/server/session-stream/history-prune.d.ts +35 -0
  77. package/dist/server/session-stream/history-prune.d.ts.map +1 -0
  78. package/dist/server/session-stream/history-prune.js +182 -0
  79. package/dist/server/session-stream/memory.d.ts +48 -0
  80. package/dist/server/session-stream/memory.d.ts.map +1 -0
  81. package/dist/server/session-stream/memory.js +136 -0
  82. package/dist/server/session-stream/replay-tail.d.ts +4 -0
  83. package/dist/server/session-stream/replay-tail.d.ts.map +1 -0
  84. package/dist/server/session-stream/replay-tail.js +39 -0
  85. package/dist/server/session-stream/turn-events.d.ts +33 -0
  86. package/dist/server/session-stream/turn-events.d.ts.map +1 -0
  87. package/dist/server/session-stream/turn-events.js +65 -0
  88. package/dist/server/session-stream/turn-silence.d.ts +8 -0
  89. package/dist/server/session-stream/turn-silence.d.ts.map +1 -0
  90. package/dist/server/session-stream/turn-silence.js +72 -0
  91. package/dist/server/session-stream.d.ts +137 -36
  92. package/dist/server/session-stream.d.ts.map +1 -1
  93. package/dist/server/session-stream.js +18 -509
  94. package/dist/server/storage/observation-ranking.d.ts +14 -0
  95. package/dist/server/storage/observation-ranking.d.ts.map +1 -0
  96. package/dist/server/storage/observation-ranking.js +37 -0
  97. package/dist/server/storage/preflight.d.ts +20 -0
  98. package/dist/server/storage/preflight.d.ts.map +1 -0
  99. package/dist/server/storage/preflight.js +22 -0
  100. package/dist/server/storage/project-binding.d.ts +5 -0
  101. package/dist/server/storage/project-binding.d.ts.map +1 -0
  102. package/dist/server/storage/project-binding.js +32 -0
  103. package/dist/server/storage/rows.d.ts +104 -0
  104. package/dist/server/storage/rows.d.ts.map +1 -0
  105. package/dist/server/storage/rows.js +2 -0
  106. package/dist/server/storage/schema.d.ts +20 -0
  107. package/dist/server/storage/schema.d.ts.map +1 -0
  108. package/dist/server/storage/schema.js +134 -0
  109. package/dist/server/storage/types.d.ts +66 -0
  110. package/dist/server/storage/types.d.ts.map +1 -0
  111. package/dist/server/storage/types.js +1 -0
  112. package/dist/server/storage.d.ts +7 -94
  113. package/dist/server/storage.d.ts.map +1 -1
  114. package/dist/server/storage.js +6 -224
  115. package/dist/server/wire.d.ts +6 -0
  116. package/dist/server/wire.d.ts.map +1 -1
  117. package/package.json +2 -1
  118. package/dist/sdk/agent-core/harness/agent-harness.d.ts +0 -92
  119. package/dist/sdk/agent-core/harness/agent-harness.d.ts.map +0 -1
  120. package/dist/sdk/agent-core/harness/agent-harness.js +0 -899
  121. package/dist/sdk/agent-core/harness/env/nodejs.d.ts +0 -51
  122. package/dist/sdk/agent-core/harness/env/nodejs.d.ts.map +0 -1
  123. package/dist/sdk/agent-core/harness/env/nodejs.js +0 -485
  124. package/dist/sdk/agent-core/harness/prompt-templates.d.ts +0 -48
  125. package/dist/sdk/agent-core/harness/prompt-templates.d.ts.map +0 -1
  126. package/dist/sdk/agent-core/harness/prompt-templates.js +0 -229
  127. package/dist/sdk/agent-core/harness/session/jsonl-repo.d.ts +0 -26
  128. package/dist/sdk/agent-core/harness/session/jsonl-repo.d.ts.map +0 -1
  129. package/dist/sdk/agent-core/harness/session/jsonl-repo.js +0 -100
  130. package/dist/sdk/agent-core/harness/session/jsonl-storage.d.ts +0 -33
  131. package/dist/sdk/agent-core/harness/session/jsonl-storage.d.ts.map +0 -1
  132. package/dist/sdk/agent-core/harness/session/jsonl-storage.js +0 -230
  133. package/dist/sdk/agent-core/harness/session/memory-repo.d.ts +0 -18
  134. package/dist/sdk/agent-core/harness/session/memory-repo.d.ts.map +0 -1
  135. package/dist/sdk/agent-core/harness/session/memory-repo.js +0 -41
  136. package/dist/sdk/agent-core/harness/session/memory-storage.d.ts +0 -25
  137. package/dist/sdk/agent-core/harness/session/memory-storage.d.ts.map +0 -1
  138. package/dist/sdk/agent-core/harness/session/memory-storage.js +0 -113
  139. package/dist/sdk/agent-core/harness/session/repo-utils.d.ts +0 -11
  140. package/dist/sdk/agent-core/harness/session/repo-utils.d.ts.map +0 -1
  141. package/dist/sdk/agent-core/harness/session/repo-utils.js +0 -38
  142. package/dist/sdk/agent-core/harness/skills.d.ts +0 -44
  143. package/dist/sdk/agent-core/harness/skills.d.ts.map +0 -1
  144. package/dist/sdk/agent-core/harness/skills.js +0 -310
  145. package/dist/sdk/agent-core/harness/utils/shell-output.d.ts +0 -14
  146. package/dist/sdk/agent-core/harness/utils/shell-output.d.ts.map +0 -1
  147. package/dist/sdk/agent-core/harness/utils/shell-output.js +0 -125
  148. package/dist/sdk/agent-core/node.d.ts +0 -3
  149. package/dist/sdk/agent-core/node.d.ts.map +0 -1
  150. package/dist/sdk/agent-core/node.js +0 -2
  151. package/dist/sdk/agent-core/proxy.d.ts +0 -69
  152. package/dist/sdk/agent-core/proxy.d.ts.map +0 -1
  153. package/dist/sdk/agent-core/proxy.js +0 -297
@@ -1,125 +0,0 @@
1
- import { ExecutionError, err, ok, toError, } from "../types.js";
2
- import { DEFAULT_MAX_BYTES, truncateTail } from "./truncate.js";
3
- function toExecutionError(error) {
4
- if (error instanceof ExecutionError)
5
- return error;
6
- const cause = toError(error);
7
- return new ExecutionError("unknown", cause.message, cause);
8
- }
9
- export function sanitizeBinaryOutput(str) {
10
- return Array.from(str)
11
- .filter((char) => {
12
- const code = char.codePointAt(0);
13
- if (code === undefined)
14
- return false;
15
- if (code === 0x09 || code === 0x0a || code === 0x0d)
16
- return true;
17
- if (code <= 0x1f)
18
- return false;
19
- if (code >= 0xfff9 && code <= 0xfffb)
20
- return false;
21
- return true;
22
- })
23
- .join("");
24
- }
25
- export async function executeShellWithCapture(env, command, options) {
26
- const outputChunks = [];
27
- let outputBytes = 0;
28
- const maxOutputBytes = DEFAULT_MAX_BYTES * 2;
29
- const encoder = new TextEncoder();
30
- let totalBytes = 0;
31
- let fullOutputPath;
32
- let writeChain = Promise.resolve(ok(undefined));
33
- let captureError;
34
- const appendFullOutput = (text) => {
35
- if (!fullOutputPath || captureError)
36
- return;
37
- const path = fullOutputPath;
38
- writeChain = writeChain.then(async (previous) => {
39
- if (!previous.ok)
40
- return previous;
41
- const appendResult = await env.appendFile(path, text, options?.abortSignal);
42
- return appendResult.ok ? ok(undefined) : err(toExecutionError(appendResult.error));
43
- });
44
- };
45
- const ensureFullOutputFile = (initialContent) => {
46
- if (fullOutputPath || captureError)
47
- return;
48
- writeChain = writeChain.then(async (previous) => {
49
- if (!previous.ok)
50
- return previous;
51
- const tempFile = await env.createTempFile({
52
- prefix: "bash-",
53
- suffix: ".log",
54
- abortSignal: options?.abortSignal,
55
- });
56
- if (!tempFile.ok)
57
- return err(toExecutionError(tempFile.error));
58
- fullOutputPath = tempFile.value;
59
- const appendResult = await env.appendFile(tempFile.value, initialContent, options?.abortSignal);
60
- return appendResult.ok ? ok(undefined) : err(toExecutionError(appendResult.error));
61
- });
62
- };
63
- const onChunk = (chunk) => {
64
- try {
65
- totalBytes += encoder.encode(chunk).byteLength;
66
- const text = sanitizeBinaryOutput(chunk).replace(/\r/g, "");
67
- if (totalBytes > DEFAULT_MAX_BYTES && !fullOutputPath) {
68
- ensureFullOutputFile(outputChunks.join("") + text);
69
- }
70
- else {
71
- appendFullOutput(text);
72
- }
73
- outputChunks.push(text);
74
- outputBytes += text.length;
75
- while (outputBytes > maxOutputBytes && outputChunks.length > 1) {
76
- const removed = outputChunks.shift();
77
- outputBytes -= removed.length;
78
- }
79
- options?.onChunk?.(text);
80
- }
81
- catch (error) {
82
- captureError = toExecutionError(error);
83
- }
84
- };
85
- try {
86
- const result = await env.exec(command, {
87
- ...(options ?? {}),
88
- onStdout: onChunk,
89
- onStderr: onChunk,
90
- });
91
- const tailOutput = outputChunks.join("");
92
- const truncationResult = truncateTail(tailOutput);
93
- if (truncationResult.truncated && !fullOutputPath) {
94
- ensureFullOutputFile(tailOutput);
95
- }
96
- const writeResult = await writeChain;
97
- if (!writeResult.ok)
98
- return err(writeResult.error);
99
- if (captureError)
100
- return err(captureError);
101
- if (!result.ok) {
102
- if (result.error.code === "aborted" || options?.abortSignal?.aborted) {
103
- return ok({
104
- output: truncationResult.truncated ? truncationResult.content : tailOutput,
105
- exitCode: undefined,
106
- cancelled: true,
107
- truncated: truncationResult.truncated,
108
- fullOutputPath,
109
- });
110
- }
111
- return err(result.error);
112
- }
113
- const cancelled = options?.abortSignal?.aborted ?? false;
114
- return ok({
115
- output: truncationResult.truncated ? truncationResult.content : tailOutput,
116
- exitCode: cancelled ? undefined : result.value.exitCode,
117
- cancelled,
118
- truncated: truncationResult.truncated,
119
- fullOutputPath,
120
- });
121
- }
122
- catch (error) {
123
- return err(toExecutionError(error));
124
- }
125
- }
@@ -1,3 +0,0 @@
1
- export { NodeExecutionEnv } from "./harness/env/nodejs.js";
2
- export * from "./index.js";
3
- //# sourceMappingURL=node.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,cAAc,YAAY,CAAC"}
@@ -1,2 +0,0 @@
1
- export { NodeExecutionEnv } from "./harness/env/nodejs.js";
2
- export * from "./index.js";
@@ -1,69 +0,0 @@
1
- /**
2
- * Proxy stream function for apps that route LLM calls through a server.
3
- * The server manages auth and proxies requests to LLM providers.
4
- */
5
- import { type AssistantMessage, type AssistantMessageEvent, type Context, EventStream, type Model, type SimpleStreamOptions, type StopReason } from "../ai/index.js";
6
- declare class ProxyMessageEventStream extends EventStream<AssistantMessageEvent, AssistantMessage> {
7
- constructor();
8
- }
9
- /**
10
- * Proxy event types - server sends these with partial field stripped to reduce bandwidth.
11
- */
12
- export type ProxyAssistantMessageEvent = {
13
- type: "start";
14
- } | {
15
- type: "text_start";
16
- contentIndex: number;
17
- } | {
18
- type: "text_delta";
19
- contentIndex: number;
20
- delta: string;
21
- } | {
22
- type: "text_end";
23
- contentIndex: number;
24
- contentSignature?: string;
25
- } | {
26
- type: "thinking_start";
27
- contentIndex: number;
28
- } | {
29
- type: "thinking_delta";
30
- contentIndex: number;
31
- delta: string;
32
- } | {
33
- type: "thinking_end";
34
- contentIndex: number;
35
- contentSignature?: string;
36
- } | {
37
- type: "toolcall_start";
38
- contentIndex: number;
39
- id: string;
40
- toolName: string;
41
- } | {
42
- type: "toolcall_delta";
43
- contentIndex: number;
44
- delta: string;
45
- } | {
46
- type: "toolcall_end";
47
- contentIndex: number;
48
- } | {
49
- type: "done";
50
- reason: Extract<StopReason, "stop" | "length" | "toolUse">;
51
- usage: AssistantMessage["usage"];
52
- } | {
53
- type: "error";
54
- reason: Extract<StopReason, "aborted" | "error">;
55
- errorMessage?: string;
56
- usage: AssistantMessage["usage"];
57
- };
58
- type ProxySerializableStreamOptions = Pick<SimpleStreamOptions, "temperature" | "maxTokens" | "reasoning" | "cacheRetention" | "sessionId" | "headers" | "metadata" | "transport" | "thinkingBudgets" | "maxRetryDelayMs">;
59
- export interface ProxyStreamOptions extends ProxySerializableStreamOptions {
60
- /** Local abort signal for the proxy request */
61
- signal?: AbortSignal;
62
- /** Auth token for the proxy server */
63
- authToken: string;
64
- /** Proxy server URL (e.g., "https://genai.example.com") */
65
- proxyUrl: string;
66
- }
67
- export declare function streamProxy(model: Model<any>, context: Context, options: ProxyStreamOptions): ProxyMessageEventStream;
68
- export {};
69
- //# sourceMappingURL=proxy.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/proxy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,OAAO,EACZ,WAAW,EACX,KAAK,KAAK,EAEV,KAAK,mBAAmB,EACxB,KAAK,UAAU,EAEf,MAAM,gBAAgB,CAAC;AAGxB,cAAM,uBAAwB,SAAQ,WAAW,CAAC,qBAAqB,EAAE,gBAAgB,CAAC;;CAWzF;AAED;;GAEG;AACH,MAAM,MAAM,0BAA0B,GACnC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC9E;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC9C;IACA,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC;IAC3D,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;CAChC,GACD;IACA,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,CAAC;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;CAChC,CAAC;AAEL,KAAK,8BAA8B,GAAG,IAAI,CACzC,mBAAmB,EACjB,aAAa,GACb,WAAW,GACX,WAAW,GACX,gBAAgB,GAChB,WAAW,GACX,SAAS,GACT,UAAU,GACV,WAAW,GACX,iBAAiB,GACjB,iBAAiB,CACnB,CAAC;AAEF,MAAM,WAAW,kBAAmB,SAAQ,8BAA8B;IACzE,+CAA+C;IAC/C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;CACjB;AAoCD,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,GAAG,uBAAuB,CAqHrH"}
@@ -1,297 +0,0 @@
1
- /**
2
- * Proxy stream function for apps that route LLM calls through a server.
3
- * The server manages auth and proxies requests to LLM providers.
4
- */
5
- // Internal import for JSON parsing utility
6
- import { EventStream, parseStreamingJsonResult, } from "../ai/index.js";
7
- // Create stream class matching ProxyMessageEventStream
8
- class ProxyMessageEventStream extends EventStream {
9
- constructor() {
10
- super((event) => event.type === "done" || event.type === "error", (event) => {
11
- if (event.type === "done")
12
- return event.message;
13
- if (event.type === "error")
14
- return event.error;
15
- throw new Error("Unexpected event type");
16
- });
17
- }
18
- }
19
- /**
20
- * Stream function that proxies through a server instead of calling LLM providers directly.
21
- * The server strips the partial field from delta events to reduce bandwidth.
22
- * We reconstruct the partial message client-side.
23
- *
24
- * Use this as the `streamFn` option when creating an Agent that needs to go through a proxy.
25
- *
26
- * @example
27
- * ```typescript
28
- * const agent = new Agent({
29
- * streamFn: (model, context, options) =>
30
- * streamProxy(model, context, {
31
- * ...options,
32
- * authToken: await getAuthToken(),
33
- * proxyUrl: "https://genai.example.com",
34
- * }),
35
- * });
36
- * ```
37
- */
38
- function buildProxyRequestOptions(options) {
39
- return {
40
- temperature: options.temperature,
41
- maxTokens: options.maxTokens,
42
- reasoning: options.reasoning,
43
- cacheRetention: options.cacheRetention,
44
- sessionId: options.sessionId,
45
- headers: options.headers,
46
- metadata: options.metadata,
47
- transport: options.transport,
48
- thinkingBudgets: options.thinkingBudgets,
49
- maxRetryDelayMs: options.maxRetryDelayMs,
50
- };
51
- }
52
- export function streamProxy(model, context, options) {
53
- const stream = new ProxyMessageEventStream();
54
- (async () => {
55
- // Initialize the partial message that we'll build up from events
56
- const partial = {
57
- role: "assistant",
58
- stopReason: "stop",
59
- content: [],
60
- api: model.api,
61
- provider: model.provider,
62
- model: model.id,
63
- usage: {
64
- input: 0,
65
- output: 0,
66
- cacheRead: 0,
67
- cacheWrite: 0,
68
- totalTokens: 0,
69
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
70
- },
71
- timestamp: Date.now(),
72
- };
73
- let reader;
74
- const abortHandler = () => {
75
- if (reader) {
76
- reader.cancel("Request aborted by user").catch(() => { });
77
- }
78
- };
79
- if (options.signal) {
80
- options.signal.addEventListener("abort", abortHandler);
81
- }
82
- try {
83
- const response = await fetch(`${options.proxyUrl}/api/stream`, {
84
- method: "POST",
85
- headers: {
86
- Authorization: `Bearer ${options.authToken}`,
87
- "Content-Type": "application/json",
88
- },
89
- body: JSON.stringify({
90
- model,
91
- context,
92
- options: buildProxyRequestOptions(options),
93
- }),
94
- signal: options.signal,
95
- });
96
- if (!response.ok) {
97
- let errorMessage = `Proxy error: ${response.status} ${response.statusText}`;
98
- try {
99
- const errorData = (await response.json());
100
- if (errorData.error) {
101
- errorMessage = `Proxy error: ${errorData.error}`;
102
- }
103
- }
104
- catch {
105
- // Couldn't parse error response
106
- }
107
- throw new Error(errorMessage);
108
- }
109
- reader = response.body.getReader();
110
- const decoder = new TextDecoder();
111
- let buffer = "";
112
- while (true) {
113
- const { done, value } = await reader.read();
114
- if (done)
115
- break;
116
- if (options.signal?.aborted) {
117
- throw new Error("Request aborted by user");
118
- }
119
- buffer += decoder.decode(value, { stream: true });
120
- const lines = buffer.split("\n");
121
- buffer = lines.pop() || "";
122
- for (const line of lines) {
123
- if (line.startsWith("data: ")) {
124
- const data = line.slice(6).trim();
125
- if (data) {
126
- const proxyEvent = JSON.parse(data);
127
- const event = processProxyEvent(proxyEvent, partial);
128
- if (event) {
129
- stream.push(event);
130
- }
131
- }
132
- }
133
- }
134
- }
135
- if (options.signal?.aborted) {
136
- throw new Error("Request aborted by user");
137
- }
138
- stream.end();
139
- }
140
- catch (error) {
141
- const errorMessage = error instanceof Error ? error.message : String(error);
142
- const reason = options.signal?.aborted ? "aborted" : "error";
143
- partial.stopReason = reason;
144
- partial.errorMessage = errorMessage;
145
- stream.push({
146
- type: "error",
147
- reason,
148
- error: partial,
149
- });
150
- stream.end();
151
- }
152
- finally {
153
- if (options.signal) {
154
- options.signal.removeEventListener("abort", abortHandler);
155
- }
156
- }
157
- })();
158
- return stream;
159
- }
160
- /**
161
- * Process a proxy event and update the partial message.
162
- */
163
- function processProxyEvent(proxyEvent, partial) {
164
- switch (proxyEvent.type) {
165
- case "start":
166
- return { type: "start", partial };
167
- case "text_start":
168
- partial.content[proxyEvent.contentIndex] = { type: "text", text: "" };
169
- return { type: "text_start", contentIndex: proxyEvent.contentIndex, partial };
170
- case "text_delta": {
171
- const content = partial.content[proxyEvent.contentIndex];
172
- if (content?.type === "text") {
173
- content.text += proxyEvent.delta;
174
- return {
175
- type: "text_delta",
176
- contentIndex: proxyEvent.contentIndex,
177
- delta: proxyEvent.delta,
178
- partial,
179
- };
180
- }
181
- throw new Error("Received text_delta for non-text content");
182
- }
183
- case "text_end": {
184
- const content = partial.content[proxyEvent.contentIndex];
185
- if (content?.type === "text") {
186
- content.textSignature = proxyEvent.contentSignature;
187
- return {
188
- type: "text_end",
189
- contentIndex: proxyEvent.contentIndex,
190
- content: content.text,
191
- partial,
192
- };
193
- }
194
- throw new Error("Received text_end for non-text content");
195
- }
196
- case "thinking_start":
197
- partial.content[proxyEvent.contentIndex] = { type: "thinking", thinking: "" };
198
- return { type: "thinking_start", contentIndex: proxyEvent.contentIndex, partial };
199
- case "thinking_delta": {
200
- const content = partial.content[proxyEvent.contentIndex];
201
- if (content?.type === "thinking") {
202
- content.thinking += proxyEvent.delta;
203
- return {
204
- type: "thinking_delta",
205
- contentIndex: proxyEvent.contentIndex,
206
- delta: proxyEvent.delta,
207
- partial,
208
- };
209
- }
210
- throw new Error("Received thinking_delta for non-thinking content");
211
- }
212
- case "thinking_end": {
213
- const content = partial.content[proxyEvent.contentIndex];
214
- if (content?.type === "thinking") {
215
- content.thinkingSignature = proxyEvent.contentSignature;
216
- return {
217
- type: "thinking_end",
218
- contentIndex: proxyEvent.contentIndex,
219
- content: content.thinking,
220
- partial,
221
- };
222
- }
223
- throw new Error("Received thinking_end for non-thinking content");
224
- }
225
- case "toolcall_start":
226
- partial.content[proxyEvent.contentIndex] = {
227
- type: "toolCall",
228
- id: proxyEvent.id,
229
- name: proxyEvent.toolName,
230
- arguments: {},
231
- partialJson: "",
232
- };
233
- return { type: "toolcall_start", contentIndex: proxyEvent.contentIndex, partial };
234
- case "toolcall_delta": {
235
- const content = partial.content[proxyEvent.contentIndex];
236
- if (content?.type === "toolCall") {
237
- content.partialJson += proxyEvent.delta;
238
- // A provider is allowed to split a JSON token across arbitrary chunks.
239
- // In particular, the first chunk may be `{"p`, which is not useful to
240
- // the strict streaming parser yet. Never turn that transient state into
241
- // a stream error: doing so aborts the whole agent loop before `done` (and
242
- // before the loop can apply its truncated-tool-call recovery).
243
- try {
244
- content.arguments = parseStreamingJsonResult(content.partialJson).value;
245
- }
246
- catch {
247
- // Keep the last observable arguments. toolcall_end still receives the
248
- // complete accumulated JSON and can update this value when possible.
249
- }
250
- partial.content[proxyEvent.contentIndex] = { ...content }; // Trigger reactivity
251
- return {
252
- type: "toolcall_delta",
253
- contentIndex: proxyEvent.contentIndex,
254
- delta: proxyEvent.delta,
255
- partial,
256
- };
257
- }
258
- throw new Error("Received toolcall_delta for non-toolCall content");
259
- }
260
- case "toolcall_end": {
261
- const content = partial.content[proxyEvent.contentIndex];
262
- if (content?.type === "toolCall") {
263
- try {
264
- const parsed = parseStreamingJsonResult(content.partialJson);
265
- content.arguments = parsed.value;
266
- }
267
- catch {
268
- // Preserve the last partial value rather than failing the response
269
- // stream. The agent loop will validate required arguments and return
270
- // a retryable tool error if the provider really truncated the call.
271
- }
272
- delete content.partialJson;
273
- return {
274
- type: "toolcall_end",
275
- contentIndex: proxyEvent.contentIndex,
276
- toolCall: content,
277
- partial,
278
- };
279
- }
280
- return undefined;
281
- }
282
- case "done":
283
- partial.stopReason = proxyEvent.reason;
284
- partial.usage = proxyEvent.usage;
285
- return { type: "done", reason: proxyEvent.reason, message: partial };
286
- case "error":
287
- partial.stopReason = proxyEvent.reason;
288
- partial.errorMessage = proxyEvent.errorMessage;
289
- partial.usage = proxyEvent.usage;
290
- return { type: "error", reason: proxyEvent.reason, error: partial };
291
- default: {
292
- const _exhaustiveCheck = proxyEvent;
293
- console.warn(`Unhandled proxy event type: ${proxyEvent.type}`);
294
- return undefined;
295
- }
296
- }
297
- }