@copilotkit/runtime 1.71.1 → 1.72.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 (118) hide show
  1. package/README.md +22 -0
  2. package/dist/agent/index.cjs +15 -3
  3. package/dist/agent/index.cjs.map +1 -1
  4. package/dist/agent/index.d.cts +1 -0
  5. package/dist/agent/index.d.cts.map +1 -1
  6. package/dist/agent/index.d.mts +1 -0
  7. package/dist/agent/index.d.mts.map +1 -1
  8. package/dist/agent/index.mjs +15 -3
  9. package/dist/agent/index.mjs.map +1 -1
  10. package/dist/index.cjs +1 -0
  11. package/dist/index.d.cts +9 -1
  12. package/dist/index.d.mts +9 -1
  13. package/dist/index.mjs +2 -2
  14. package/dist/lib/runtime/copilot-runtime.cjs +13 -8
  15. package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
  16. package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
  17. package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
  18. package/dist/lib/runtime/copilot-runtime.mjs +13 -8
  19. package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
  20. package/dist/lib/telemetry-client.cjs.map +1 -1
  21. package/dist/lib/telemetry-client.mjs.map +1 -1
  22. package/dist/package.cjs +6 -4
  23. package/dist/package.mjs +6 -4
  24. package/dist/service-adapters/anthropic/anthropic-adapter.cjs +59 -25
  25. package/dist/service-adapters/anthropic/anthropic-adapter.cjs.map +1 -1
  26. package/dist/service-adapters/anthropic/anthropic-adapter.d.cts +30 -1
  27. package/dist/service-adapters/anthropic/anthropic-adapter.d.cts.map +1 -1
  28. package/dist/service-adapters/anthropic/anthropic-adapter.d.mts +30 -1
  29. package/dist/service-adapters/anthropic/anthropic-adapter.d.mts.map +1 -1
  30. package/dist/service-adapters/anthropic/anthropic-adapter.mjs +59 -26
  31. package/dist/service-adapters/anthropic/anthropic-adapter.mjs.map +1 -1
  32. package/dist/service-adapters/experimental/ollama/ollama-adapter.cjs +16 -0
  33. package/dist/service-adapters/experimental/ollama/ollama-adapter.cjs.map +1 -1
  34. package/dist/service-adapters/experimental/ollama/ollama-adapter.d.cts +14 -0
  35. package/dist/service-adapters/experimental/ollama/ollama-adapter.d.cts.map +1 -1
  36. package/dist/service-adapters/experimental/ollama/ollama-adapter.d.mts +14 -0
  37. package/dist/service-adapters/experimental/ollama/ollama-adapter.d.mts.map +1 -1
  38. package/dist/service-adapters/experimental/ollama/ollama-adapter.mjs +16 -0
  39. package/dist/service-adapters/experimental/ollama/ollama-adapter.mjs.map +1 -1
  40. package/dist/service-adapters/google/google-genai-adapter.cjs +17 -0
  41. package/dist/service-adapters/google/google-genai-adapter.cjs.map +1 -1
  42. package/dist/service-adapters/google/google-genai-adapter.d.cts +10 -0
  43. package/dist/service-adapters/google/google-genai-adapter.d.cts.map +1 -1
  44. package/dist/service-adapters/google/google-genai-adapter.d.mts +10 -0
  45. package/dist/service-adapters/google/google-genai-adapter.d.mts.map +1 -1
  46. package/dist/service-adapters/google/google-genai-adapter.mjs +16 -0
  47. package/dist/service-adapters/google/google-genai-adapter.mjs.map +1 -1
  48. package/dist/service-adapters/index.d.cts +1 -1
  49. package/dist/service-adapters/index.d.mts +1 -1
  50. package/dist/service-adapters/unify/unify-adapter.cjs +14 -2
  51. package/dist/service-adapters/unify/unify-adapter.cjs.map +1 -1
  52. package/dist/service-adapters/unify/unify-adapter.d.cts +9 -1
  53. package/dist/service-adapters/unify/unify-adapter.d.cts.map +1 -1
  54. package/dist/service-adapters/unify/unify-adapter.d.mts +9 -1
  55. package/dist/service-adapters/unify/unify-adapter.d.mts.map +1 -1
  56. package/dist/service-adapters/unify/unify-adapter.mjs +14 -2
  57. package/dist/service-adapters/unify/unify-adapter.mjs.map +1 -1
  58. package/dist/v2/index.cjs +2 -0
  59. package/dist/v2/index.d.cts +2 -1
  60. package/dist/v2/index.d.mts +2 -1
  61. package/dist/v2/index.mjs +2 -1
  62. package/dist/v2/runtime/core/runtime.cjs.map +1 -1
  63. package/dist/v2/runtime/core/runtime.d.cts +2 -1
  64. package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
  65. package/dist/v2/runtime/core/runtime.d.mts +2 -1
  66. package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
  67. package/dist/v2/runtime/core/runtime.mjs.map +1 -1
  68. package/dist/v2/runtime/handlers/handle-run.cjs +2 -1
  69. package/dist/v2/runtime/handlers/handle-run.cjs.map +1 -1
  70. package/dist/v2/runtime/handlers/handle-run.mjs +2 -1
  71. package/dist/v2/runtime/handlers/handle-run.mjs.map +1 -1
  72. package/dist/v2/runtime/handlers/handle-stop.cjs +41 -1
  73. package/dist/v2/runtime/handlers/handle-stop.cjs.map +1 -1
  74. package/dist/v2/runtime/handlers/handle-stop.mjs +42 -2
  75. package/dist/v2/runtime/handlers/handle-stop.mjs.map +1 -1
  76. package/dist/v2/runtime/handlers/intelligence/run.cjs +1 -1
  77. package/dist/v2/runtime/handlers/intelligence/run.cjs.map +1 -1
  78. package/dist/v2/runtime/handlers/intelligence/run.mjs +1 -1
  79. package/dist/v2/runtime/handlers/intelligence/run.mjs.map +1 -1
  80. package/dist/v2/runtime/handlers/intelligence/threads.cjs +2 -3
  81. package/dist/v2/runtime/handlers/intelligence/threads.cjs.map +1 -1
  82. package/dist/v2/runtime/handlers/intelligence/threads.mjs +2 -3
  83. package/dist/v2/runtime/handlers/intelligence/threads.mjs.map +1 -1
  84. package/dist/v2/runtime/handlers/shared/agent-utils.cjs +8 -2
  85. package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
  86. package/dist/v2/runtime/handlers/shared/agent-utils.mjs +8 -2
  87. package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
  88. package/dist/v2/runtime/index.d.cts +1 -0
  89. package/dist/v2/runtime/index.d.cts.map +1 -1
  90. package/dist/v2/runtime/index.d.mts +1 -0
  91. package/dist/v2/runtime/index.d.mts.map +1 -1
  92. package/dist/v2/runtime/intelligence-platform/client.cjs +106 -1
  93. package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
  94. package/dist/v2/runtime/intelligence-platform/client.d.cts +11 -0
  95. package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
  96. package/dist/v2/runtime/intelligence-platform/client.d.mts +11 -0
  97. package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
  98. package/dist/v2/runtime/intelligence-platform/client.mjs +106 -1
  99. package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
  100. package/dist/v2/runtime/intelligence-platform/index.d.cts +1 -0
  101. package/dist/v2/runtime/intelligence-platform/index.d.mts +1 -0
  102. package/dist/v2/runtime/intelligence-platform/learned-skills.cjs +43 -0
  103. package/dist/v2/runtime/intelligence-platform/learned-skills.cjs.map +1 -0
  104. package/dist/v2/runtime/intelligence-platform/learned-skills.d.cts +34 -0
  105. package/dist/v2/runtime/intelligence-platform/learned-skills.d.cts.map +1 -0
  106. package/dist/v2/runtime/intelligence-platform/learned-skills.d.mts +34 -0
  107. package/dist/v2/runtime/intelligence-platform/learned-skills.d.mts.map +1 -0
  108. package/dist/v2/runtime/intelligence-platform/learned-skills.mjs +41 -0
  109. package/dist/v2/runtime/intelligence-platform/learned-skills.mjs.map +1 -0
  110. package/dist/v2/runtime/runner/intelligence.cjs +82 -25
  111. package/dist/v2/runtime/runner/intelligence.cjs.map +1 -1
  112. package/dist/v2/runtime/runner/intelligence.d.cts +3 -0
  113. package/dist/v2/runtime/runner/intelligence.d.cts.map +1 -1
  114. package/dist/v2/runtime/runner/intelligence.d.mts +3 -0
  115. package/dist/v2/runtime/runner/intelligence.d.mts.map +1 -1
  116. package/dist/v2/runtime/runner/intelligence.mjs +83 -26
  117. package/dist/v2/runtime/runner/intelligence.mjs.map +1 -1
  118. package/package.json +11 -7
@@ -57,6 +57,35 @@ declare class AnthropicAdapter implements CopilotServiceAdapter {
57
57
  private shouldGenerateFallbackResponse;
58
58
  process(request: CopilotRuntimeChatCompletionRequest): Promise<CopilotRuntimeChatCompletionResponse>;
59
59
  }
60
+ /**
61
+ * Strips a `<thinking>…</thinking>` block that opens a streamed text content
62
+ * block, passing everything else through unchanged.
63
+ *
64
+ * Only the START of a content block can be a thinking tag. Text is held back
65
+ * while the block's opening characters could still turn into `<thinking>`;
66
+ * the moment they diverge, everything held back is emitted in one piece and
67
+ * the detector disarms for the rest of the block, so a literal `<thinking>`
68
+ * mentioned later in the answer is never treated as a tag. `flush()` releases
69
+ * whatever is still held back when the content block ends (a block that is
70
+ * just `<`, for example).
71
+ */
72
+ declare class FilterThinkingTextBuffer {
73
+ private buffer;
74
+ /**
75
+ * True once the block's start is known to be, or not to be, a thinking tag;
76
+ * from then on chunks pass straight through.
77
+ */
78
+ private resolved;
79
+ onTextChunk(text: string): string;
80
+ /**
81
+ * Text still held back when the content block ends. A partial tag prefix
82
+ * (`<`, `<thin`) is real output and comes back; an unterminated thinking
83
+ * block stays hidden.
84
+ */
85
+ flush(): string;
86
+ reset(): void;
87
+ private release;
88
+ }
60
89
  //#endregion
61
- export { AnthropicAdapter, AnthropicAdapterParams, AnthropicPromptCachingConfig };
90
+ export { AnthropicAdapter, AnthropicAdapterParams, AnthropicPromptCachingConfig, FilterThinkingTextBuffer };
62
91
  //# sourceMappingURL=anthropic-adapter.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic-adapter.d.cts","names":[],"sources":["../../../../src/v1-deprecated/service-adapters/anthropic/anthropic-adapter.ts"],"mappings":";;;;;;UA8EiB,4BAAA;EAwMJ;;;EApMX,OAAA;EAiC4D;;;EA5B5D,KAAA;AAAA;AAAA,UAGe,sBAAA;EA6BP;;;;EAxBR,SAAA,GAAY,aAAA;;;;EAKZ,KAAA;EAyCoB;;;;EAnCpB,aAAA,GAAgB,4BAAA;EA2KV;;;;EArKN,cAAA;AAAA;AAAA,cAGW,gBAAA,YAA4B,qBAAA;EAChC,KAAA;EACA,QAAA;EAAA,QACC,aAAA;EAAA,QACA,cAAA;EAAA,QAEA,UAAA;EAAA,IACG,SAAA,CAAA,GAAa,aAAA;EAAA,IAGb,IAAA,CAAA;cAIC,MAAA,GAAS,sBAAA;EAYrB,gBAAA,CAAA,GAAoB,aAAA;EAAA,QAYZ,eAAA;;;;UAYA,sBAAA;;;;UAkCA,4BAAA;EAAA,QAwCA,8BAAA;EAsCF,OAAA,CACJ,OAAA,EAAS,mCAAA,GACR,OAAA,CAAQ,oCAAA;AAAA"}
1
+ {"version":3,"file":"anthropic-adapter.d.cts","names":[],"sources":["../../../../src/v1-deprecated/service-adapters/anthropic/anthropic-adapter.ts"],"mappings":";;;;;;UA8EiB,4BAAA;EAwMJ;;;EApMX,OAAA;EAiC4D;;;EA5B5D,KAAA;AAAA;AAAA,UAGe,sBAAA;EA6BP;;;;EAxBR,SAAA,GAAY,aAAA;;;;EAKZ,KAAA;EAyCoB;;;;EAnCpB,aAAA,GAAgB,4BAAA;EA2KV;;;;EArKN,cAAA;AAAA;AAAA,cAGW,gBAAA,YAA4B,qBAAA;EAChC,KAAA;EACA,QAAA;EAAA,QACC,aAAA;EAAA,QACA,cAAA;EAAA,QAEA,UAAA;EAAA,IACG,SAAA,CAAA,GAAa,aAAA;EAAA,IAGb,IAAA,CAAA;cAIC,MAAA,GAAS,sBAAA;EAYrB,gBAAA,CAAA,GAAoB,aAAA;EAAA,QAYZ,eAAA;EAwdA;;;EAAA,QA5cA,sBAAA;;;;UAkCA,4BAAA;EAAA,QAwCA,8BAAA;EAsCF,OAAA,CACJ,OAAA,EAAS,mCAAA,GACR,OAAA,CAAQ,oCAAA;AAAA;;;;;;;;;;;;;cA2RA,wBAAA;EAAA,QACH,MAAA;;;;;UAKA,QAAA;EAER,WAAA,CAAY,IAAA;;;;;;EAoCZ,KAAA,CAAA;EAcA,KAAA,CAAA;EAAA,QAKQ,OAAA;AAAA"}
@@ -58,6 +58,35 @@ declare class AnthropicAdapter implements CopilotServiceAdapter {
58
58
  private shouldGenerateFallbackResponse;
59
59
  process(request: CopilotRuntimeChatCompletionRequest): Promise<CopilotRuntimeChatCompletionResponse>;
60
60
  }
61
+ /**
62
+ * Strips a `<thinking>…</thinking>` block that opens a streamed text content
63
+ * block, passing everything else through unchanged.
64
+ *
65
+ * Only the START of a content block can be a thinking tag. Text is held back
66
+ * while the block's opening characters could still turn into `<thinking>`;
67
+ * the moment they diverge, everything held back is emitted in one piece and
68
+ * the detector disarms for the rest of the block, so a literal `<thinking>`
69
+ * mentioned later in the answer is never treated as a tag. `flush()` releases
70
+ * whatever is still held back when the content block ends (a block that is
71
+ * just `<`, for example).
72
+ */
73
+ declare class FilterThinkingTextBuffer {
74
+ private buffer;
75
+ /**
76
+ * True once the block's start is known to be, or not to be, a thinking tag;
77
+ * from then on chunks pass straight through.
78
+ */
79
+ private resolved;
80
+ onTextChunk(text: string): string;
81
+ /**
82
+ * Text still held back when the content block ends. A partial tag prefix
83
+ * (`<`, `<thin`) is real output and comes back; an unterminated thinking
84
+ * block stays hidden.
85
+ */
86
+ flush(): string;
87
+ reset(): void;
88
+ private release;
89
+ }
61
90
  //#endregion
62
- export { AnthropicAdapter, AnthropicAdapterParams, AnthropicPromptCachingConfig };
91
+ export { AnthropicAdapter, AnthropicAdapterParams, AnthropicPromptCachingConfig, FilterThinkingTextBuffer };
63
92
  //# sourceMappingURL=anthropic-adapter.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic-adapter.d.mts","names":[],"sources":["../../../../src/v1-deprecated/service-adapters/anthropic/anthropic-adapter.ts"],"mappings":";;;;;;;UA8EiB,4BAAA;EA+DK;;;EA3DpB,OAAA;EAiCuC;;;EA5BvC,KAAA;AAAA;AAAA,UAGe,sBAAA;EA4BP;;;;EAvBR,SAAA,GAAY,aAAA;EA8BD;;;EAzBX,KAAA;EAyCA;;;;EAnCA,aAAA,GAAgB,4BAAA;EAqIR;;;;EA/HR,cAAA;AAAA;AAAA,cAGW,gBAAA,YAA4B,qBAAA;EAChC,KAAA;EACA,QAAA;EAAA,QACC,aAAA;EAAA,QACA,cAAA;EAAA,QAEA,UAAA;EAAA,IACG,SAAA,CAAA,GAAa,aAAA;EAAA,IAGb,IAAA,CAAA;cAIC,MAAA,GAAS,sBAAA;EAYrB,gBAAA,CAAA,GAAoB,aAAA;EAAA,QAYZ,eAAA;;;;UAYA,sBAAA;;;;UAkCA,4BAAA;EAAA,QAwCA,8BAAA;EAsCF,OAAA,CACJ,OAAA,EAAS,mCAAA,GACR,OAAA,CAAQ,oCAAA;AAAA"}
1
+ {"version":3,"file":"anthropic-adapter.d.mts","names":[],"sources":["../../../../src/v1-deprecated/service-adapters/anthropic/anthropic-adapter.ts"],"mappings":";;;;;;;UA8EiB,4BAAA;EA+DK;;;EA3DpB,OAAA;EAiCuC;;;EA5BvC,KAAA;AAAA;AAAA,UAGe,sBAAA;EA4BP;;;;EAvBR,SAAA,GAAY,aAAA;EA8BD;;;EAzBX,KAAA;EAyCA;;;;EAnCA,aAAA,GAAgB,4BAAA;EAqIR;;;;EA/HR,cAAA;AAAA;AAAA,cAGW,gBAAA,YAA4B,qBAAA;EAChC,KAAA;EACA,QAAA;EAAA,QACC,aAAA;EAAA,QACA,cAAA;EAAA,QAEA,UAAA;EAAA,IACG,SAAA,CAAA,GAAa,aAAA;EAAA,IAGb,IAAA,CAAA;cAIC,MAAA,GAAS,sBAAA;EAYrB,gBAAA,CAAA,GAAoB,aAAA;EAAA,QAYZ,eAAA;EAmdR;;;EAAA,QAvcQ,sBAAA;;;;UAkCA,4BAAA;EAAA,QAwCA,8BAAA;EAsCF,OAAA,CACJ,OAAA,EAAS,mCAAA,GACR,OAAA,CAAQ,oCAAA;AAAA;;;;;;;;;;;;;cA2RA,wBAAA;EAAA,QACH,MAAA;;;;;UAKA,QAAA;EAER,WAAA,CAAY,IAAA;;;;;;EAoCZ,KAAA,CAAA;EAcA,KAAA,CAAA;EAAA,QAKQ,OAAA;AAAA"}
@@ -139,6 +139,17 @@ var AnthropicAdapter = class {
139
139
  let currentToolCallId = randomId();
140
140
  let filterThinkingTextBuffer = new FilterThinkingTextBuffer();
141
141
  let hasReceivedContent = false;
142
+ const emitText = (text) => {
143
+ if (text.length === 0) return;
144
+ if (!didOutputText) {
145
+ eventStream$.sendTextMessageStart({ messageId: currentMessageId });
146
+ didOutputText = true;
147
+ }
148
+ eventStream$.sendTextMessageContent({
149
+ messageId: currentMessageId,
150
+ content: text
151
+ });
152
+ };
142
153
  try {
143
154
  for await (const chunk of stream) if (chunk.type === "message_start") currentMessageId = chunk.message.id;
144
155
  else if (chunk.type === "content_block_start") {
@@ -163,24 +174,14 @@ var AnthropicAdapter = class {
163
174
  }
164
175
  } else if (chunk.type === "content_block_delta") {
165
176
  if (mode === null) continue;
166
- if (chunk.delta.type === "text_delta") {
167
- const text = filterThinkingTextBuffer.onTextChunk(chunk.delta.text);
168
- if (text.length > 0) {
169
- if (!didOutputText) {
170
- eventStream$.sendTextMessageStart({ messageId: currentMessageId });
171
- didOutputText = true;
172
- }
173
- eventStream$.sendTextMessageContent({
174
- messageId: currentMessageId,
175
- content: text
176
- });
177
- }
178
- } else if (chunk.delta.type === "input_json_delta") eventStream$.sendActionExecutionArgs({
177
+ if (chunk.delta.type === "text_delta") emitText(filterThinkingTextBuffer.onTextChunk(chunk.delta.text));
178
+ else if (chunk.delta.type === "input_json_delta") eventStream$.sendActionExecutionArgs({
179
179
  actionExecutionId: currentToolCallId,
180
180
  args: chunk.delta.partial_json
181
181
  });
182
182
  } else if (chunk.type === "content_block_stop") {
183
183
  if (mode === "message") {
184
+ emitText(filterThinkingTextBuffer.flush());
184
185
  if (didOutputText) eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
185
186
  } else if (mode === "function") eventStream$.sendActionExecutionEnd({ actionExecutionId: currentToolCallId });
186
187
  }
@@ -212,30 +213,62 @@ var AnthropicAdapter = class {
212
213
  };
213
214
  const THINKING_TAG = "<thinking>";
214
215
  const THINKING_TAG_END = "</thinking>";
216
+ /**
217
+ * Strips a `<thinking>…</thinking>` block that opens a streamed text content
218
+ * block, passing everything else through unchanged.
219
+ *
220
+ * Only the START of a content block can be a thinking tag. Text is held back
221
+ * while the block's opening characters could still turn into `<thinking>`;
222
+ * the moment they diverge, everything held back is emitted in one piece and
223
+ * the detector disarms for the rest of the block, so a literal `<thinking>`
224
+ * mentioned later in the answer is never treated as a tag. `flush()` releases
225
+ * whatever is still held back when the content block ends (a block that is
226
+ * just `<`, for example).
227
+ */
215
228
  var FilterThinkingTextBuffer = class {
216
229
  constructor() {
217
- this.didFilterThinkingTag = false;
218
230
  this.buffer = "";
231
+ this.resolved = false;
219
232
  }
220
233
  onTextChunk(text) {
234
+ if (this.resolved) return text;
221
235
  this.buffer += text;
222
- if (this.didFilterThinkingTag) return text;
223
- const potentialTag = this.buffer.slice(0, 10);
224
- if (THINKING_TAG.startsWith(potentialTag)) if (this.buffer.includes(THINKING_TAG_END)) {
225
- const end = this.buffer.indexOf(THINKING_TAG_END);
226
- const filteredText = this.buffer.slice(end + 11);
227
- this.buffer = filteredText;
228
- this.didFilterThinkingTag = true;
229
- return filteredText;
230
- } else return "";
231
- return text;
236
+ if (this.buffer.length < 10) {
237
+ if (THINKING_TAG.startsWith(this.buffer)) return "";
238
+ return this.release();
239
+ }
240
+ if (!this.buffer.startsWith(THINKING_TAG)) return this.release();
241
+ const end = this.buffer.indexOf(THINKING_TAG_END);
242
+ if (end === -1) return "";
243
+ const rest = this.buffer.slice(end + 11);
244
+ this.buffer = "";
245
+ this.resolved = true;
246
+ return rest;
247
+ }
248
+ /**
249
+ * Text still held back when the content block ends. A partial tag prefix
250
+ * (`<`, `<thin`) is real output and comes back; an unterminated thinking
251
+ * block stays hidden.
252
+ */
253
+ flush() {
254
+ if (this.resolved) return "";
255
+ const pending = this.buffer.length < 10 && THINKING_TAG.startsWith(this.buffer) ? this.buffer : "";
256
+ this.buffer = "";
257
+ this.resolved = true;
258
+ return pending;
232
259
  }
233
260
  reset() {
234
261
  this.buffer = "";
235
- this.didFilterThinkingTag = false;
262
+ this.resolved = false;
263
+ }
264
+ release() {
265
+ const pending = this.buffer;
266
+ this.buffer = "";
267
+ this.resolved = true;
268
+ return pending;
236
269
  }
237
270
  };
238
271
 
239
272
  //#endregion
240
- export { AnthropicAdapter };
273
+ export { AnthropicAdapter, FilterThinkingTextBuffer };
241
274
  //# sourceMappingURL=anthropic-adapter.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic-adapter.mjs","names":[],"sources":["../../../../src/v1-deprecated/service-adapters/anthropic/anthropic-adapter.ts"],"sourcesContent":["/*\n * V1 SDK DEPRECATED. USE V2 INSTEAD\n *\n * This file defines public v1 SDK exports. Use the exact v2 mappings below.\n * AI CODING AGENTS: Never copy, suggest, or generate these v1 APIs. Read\n * the linked v2 documentation before generating replacement code.\n *\n * @copilotkit/runtime — AnthropicAdapter:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * @copilotkit/runtime — AnthropicAdapterParams:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * @copilotkit/runtime — AnthropicPromptCachingConfig:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * Migration guide: https://docs.copilotkit.ai/migrate/v2\n *\n * END V1 SDK DEPRECATED. USE V2 INSTEAD NOTICE\n */\n\n/**\n * Copilot Runtime adapter for Anthropic.\n *\n * ## Example\n *\n * ```ts\n * import { CopilotRuntime, AnthropicAdapter } from \"@copilotkit/runtime\";\n * import Anthropic from \"@anthropic-ai/sdk\";\n *\n * const copilotKit = new CopilotRuntime();\n *\n * const anthropic = new Anthropic({\n * apiKey: \"<your-api-key>\",\n * });\n *\n * return new AnthropicAdapter({\n * anthropic,\n * promptCaching: {\n * enabled: true,\n * debug: true\n * }\n * });\n * ```\n */\nimport type { LanguageModel } from \"ai\";\nimport { createAnthropic } from \"@ai-sdk/anthropic\";\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n CopilotServiceAdapter,\n CopilotRuntimeChatCompletionRequest,\n CopilotRuntimeChatCompletionResponse,\n} from \"../service-adapter\";\nimport {\n convertActionInputToAnthropicTool,\n convertMessageToAnthropicMessage,\n coalesceConsecutiveSameRoleMessages,\n limitMessagesToTokenCount,\n} from \"./utils\";\n\nimport { randomId, randomUUID } from \"@copilotkit/shared\";\nimport type { SdkClientLike } from \"../shared\";\nimport { convertServiceAdapterError, getSdkClientOptions } from \"../shared\";\n\nconst DEFAULT_MODEL = \"claude-opus-4-8\";\n\nexport interface AnthropicPromptCachingConfig {\n /**\n * Whether to enable prompt caching.\n */\n enabled: boolean;\n\n /**\n * Whether to enable debug logging for cache operations.\n */\n debug?: boolean;\n}\n\nexport interface AnthropicAdapterParams {\n /**\n * An optional Anthropic instance to use. If not provided, a new instance will be\n * created.\n */\n anthropic?: SdkClientLike;\n\n /**\n * The model to use.\n */\n model?: string;\n\n /**\n * Configuration for prompt caching.\n * See: https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching\n */\n promptCaching?: AnthropicPromptCachingConfig;\n\n /**\n * Optional maximum input token limit. Overrides the default limit\n * used when trimming messages to fit the context window.\n */\n maxInputTokens?: number;\n}\n\nexport class AnthropicAdapter implements CopilotServiceAdapter {\n public model: string = DEFAULT_MODEL;\n public provider = \"anthropic\";\n private promptCaching: AnthropicPromptCachingConfig;\n private maxInputTokens?: number;\n\n private _anthropic: SdkClientLike;\n public get anthropic(): SdkClientLike {\n return this._anthropic;\n }\n public get name() {\n return \"AnthropicAdapter\";\n }\n\n constructor(params?: AnthropicAdapterParams) {\n if (params?.anthropic) {\n this._anthropic = params.anthropic;\n }\n // If no instance provided, we'll lazy-load in ensureAnthropic()\n if (params?.model) {\n this.model = params.model;\n }\n this.promptCaching = params?.promptCaching || { enabled: false };\n this.maxInputTokens = params?.maxInputTokens;\n }\n\n getLanguageModel(): LanguageModel {\n const anthropic = this.ensureAnthropic();\n const options = getSdkClientOptions(anthropic);\n const provider = createAnthropic({\n baseURL: anthropic.baseURL,\n apiKey: anthropic.apiKey,\n headers: options.defaultHeaders,\n fetch: options.fetch,\n });\n return provider(this.model);\n }\n\n private ensureAnthropic(): SdkClientLike {\n if (!this._anthropic) {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const Anthropic = require(\"@anthropic-ai/sdk\").default;\n this._anthropic = new Anthropic({});\n }\n return this._anthropic;\n }\n\n /**\n * Adds cache control to system prompt\n */\n private addSystemPromptCaching(\n system: string,\n debug: boolean = false,\n ):\n | string\n | Array<{\n type: \"text\";\n text: string;\n cache_control?: { type: \"ephemeral\" };\n }> {\n if (!this.promptCaching.enabled || !system) {\n return system;\n }\n\n const originalTextLength = system.length;\n\n if (debug) {\n console.log(\n `[ANTHROPIC CACHE DEBUG] Added cache control to system prompt (${originalTextLength} chars).`,\n );\n }\n\n return [\n {\n type: \"text\",\n text: system,\n cache_control: { type: \"ephemeral\" },\n },\n ];\n }\n\n /**\n * Adds cache control to the final message\n */\n private addIncrementalMessageCaching(\n messages: Anthropic.Messages.MessageParam[],\n debug: boolean = false,\n ): any[] {\n if (!this.promptCaching.enabled || messages.length === 0) {\n return messages;\n }\n\n const finalMessage = messages[messages.length - 1];\n const messageNumber = messages.length;\n\n if (\n Array.isArray(finalMessage.content) &&\n finalMessage.content.length > 0\n ) {\n const finalBlock = finalMessage.content[finalMessage.content.length - 1];\n\n const updatedMessages = [\n ...messages.slice(0, -1),\n {\n ...finalMessage,\n content: [\n ...finalMessage.content.slice(0, -1),\n { ...finalBlock, cache_control: { type: \"ephemeral\" } } as any,\n ],\n },\n ];\n\n if (debug) {\n console.log(\n `[ANTHROPIC CACHE DEBUG] Added cache control to final message (message ${messageNumber}).`,\n );\n }\n\n return updatedMessages;\n }\n\n return messages;\n }\n\n private shouldGenerateFallbackResponse(\n messages: Anthropic.Messages.MessageParam[],\n ): boolean {\n if (messages.length === 0) return false;\n\n const lastMessage = messages[messages.length - 1];\n\n // Check if the last message is a tool result\n const endsWithToolResult =\n lastMessage.role === \"user\" &&\n Array.isArray(lastMessage.content) &&\n lastMessage.content.some(\n (content: any) => content.type === \"tool_result\",\n );\n\n // Also check if we have a recent pattern of user message -> assistant tool use -> user tool result\n // This indicates a completed action that might not need a response\n if (messages.length >= 3 && endsWithToolResult) {\n const lastThree = messages.slice(-3);\n const hasRecentToolPattern =\n lastThree[0]?.role === \"user\" && // Initial user message\n lastThree[1]?.role === \"assistant\" && // Assistant tool use\n Array.isArray(lastThree[1].content) &&\n lastThree[1].content.some(\n (content: any) => content.type === \"tool_use\",\n ) &&\n lastThree[2]?.role === \"user\" && // Tool result\n Array.isArray(lastThree[2].content) &&\n lastThree[2].content.some(\n (content: any) => content.type === \"tool_result\",\n );\n\n return hasRecentToolPattern;\n }\n\n return endsWithToolResult;\n }\n\n async process(\n request: CopilotRuntimeChatCompletionRequest,\n ): Promise<CopilotRuntimeChatCompletionResponse> {\n const {\n threadId,\n model = this.model,\n messages: rawMessages,\n actions,\n eventSource,\n forwardedParameters,\n } = request;\n const tools = actions.map(convertActionInputToAnthropicTool);\n const knownActionNames = new Set(actions.map((a) => a.name));\n\n const messages = [...rawMessages];\n\n // get the instruction message\n const instructionsMessage = messages.shift();\n const instructions = instructionsMessage.isTextMessage()\n ? instructionsMessage.content\n : \"\";\n\n // ALLOWLIST APPROACH:\n // 1. First, identify all valid tool_use calls (from assistant)\n // 2. Then, only keep tool_result blocks that correspond to these valid tool_use IDs\n // 3. Discard any other tool_result blocks\n\n // Step 1: Extract valid tool_use IDs\n const validToolUseIds = new Set<string>();\n\n for (const message of messages) {\n if (message.isActionExecutionMessage()) {\n validToolUseIds.add(message.id);\n }\n }\n\n // Step 2: Map each message to an Anthropic message, eliminating invalid tool_results\n const processedToolResultIds = new Set<string>();\n const anthropicMessages = messages\n .map((message) => {\n // For tool results, only include if they match a valid tool_use ID AND haven't been processed\n if (message.isResultMessage()) {\n // Skip if there's no corresponding tool_use\n if (!validToolUseIds.has(message.actionExecutionId)) {\n return null; // Will be filtered out later\n }\n\n // Skip if we've already processed a result for this tool_use ID\n if (processedToolResultIds.has(message.actionExecutionId)) {\n return null; // Will be filtered out later\n }\n\n // Mark this tool result as processed\n processedToolResultIds.add(message.actionExecutionId);\n\n return {\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n content: message.result || \"Action completed successfully\",\n tool_use_id: message.actionExecutionId,\n },\n ],\n };\n }\n\n // For non-tool-result messages, convert normally\n return convertMessageToAnthropicMessage(message);\n })\n .filter(Boolean) // Remove nulls\n .filter((msg) => {\n // Filter out assistant messages with empty text content\n if (msg.role === \"assistant\" && Array.isArray(msg.content)) {\n const hasEmptyTextOnly =\n msg.content.length === 1 &&\n msg.content[0].type === \"text\" &&\n (!(msg.content[0] as any).text ||\n (msg.content[0] as any).text.trim() === \"\");\n\n // Keep messages that have tool_use or non-empty text\n return !hasEmptyTextOnly;\n }\n return true;\n }) as Anthropic.Messages.MessageParam[];\n\n // Coalesce consecutive same-role messages so the Anthropic API receives alternating turns.\n // A mixed text+tool_use response is stored as separate TextMessage / ActionExecutionMessage\n // objects; they must be merged into one assistant message before dispatch.\n const coalescedMessages =\n coalesceConsecutiveSameRoleMessages(anthropicMessages);\n\n // Apply token limits\n const limitedMessages = limitMessagesToTokenCount(\n coalescedMessages,\n tools,\n model,\n this.maxInputTokens,\n );\n\n // Apply prompt caching if enabled\n const cachedSystemPrompt = this.addSystemPromptCaching(\n instructions,\n this.promptCaching.debug,\n );\n const cachedMessages = this.addIncrementalMessageCaching(\n limitedMessages,\n this.promptCaching.debug,\n );\n\n // We'll check if we need a fallback response after seeing what Anthropic returns\n // Role alternation is now enforced by coalesceConsecutiveSameRoleMessages above.\n\n let toolChoice: any = forwardedParameters?.toolChoice;\n if (forwardedParameters?.toolChoice === \"function\") {\n toolChoice = {\n type: \"tool\",\n name: forwardedParameters.toolChoiceFunctionName,\n };\n }\n\n try {\n const createParams = {\n system: cachedSystemPrompt,\n model,\n messages: cachedMessages,\n max_tokens: forwardedParameters?.maxTokens || 4096,\n ...(forwardedParameters?.temperature\n ? { temperature: forwardedParameters.temperature }\n : {}),\n ...(tools.length > 0 && { tools }),\n ...(toolChoice && { tool_choice: toolChoice }),\n stream: true,\n };\n\n // The public surface is structural so consumers who skip the optional\n // peer can still compile (see SdkClientLike); the SDK type is only\n // reachable here, inside a function body, where it is never emitted.\n const anthropic = this.ensureAnthropic() as Anthropic;\n const stream = await anthropic.messages.create(createParams);\n\n eventSource.stream(async (eventStream$) => {\n let mode: \"function\" | \"message\" | null = null;\n let didOutputText = false;\n let currentMessageId = randomId();\n let currentToolCallId = randomId();\n let filterThinkingTextBuffer = new FilterThinkingTextBuffer();\n let hasReceivedContent = false;\n\n try {\n for await (const chunk of stream as AsyncIterable<any>) {\n if (chunk.type === \"message_start\") {\n currentMessageId = chunk.message.id;\n } else if (chunk.type === \"content_block_start\") {\n if (chunk.content_block.type === \"text\") {\n hasReceivedContent = true;\n didOutputText = false;\n filterThinkingTextBuffer.reset();\n mode = \"message\";\n } else if (chunk.content_block.type === \"tool_use\") {\n if (!knownActionNames.has(chunk.content_block.name)) {\n // Unknown tool - skip execution to prevent crashes\n mode = null;\n continue;\n }\n hasReceivedContent = true;\n currentToolCallId = chunk.content_block.id;\n eventStream$.sendActionExecutionStart({\n actionExecutionId: currentToolCallId,\n actionName: chunk.content_block.name,\n parentMessageId: currentMessageId,\n });\n mode = \"function\";\n }\n } else if (chunk.type === \"content_block_delta\") {\n if (mode === null) {\n // Skip deltas for unknown/skipped content blocks\n continue;\n }\n if (chunk.delta.type === \"text_delta\") {\n const text = filterThinkingTextBuffer.onTextChunk(\n chunk.delta.text,\n );\n if (text.length > 0) {\n if (!didOutputText) {\n eventStream$.sendTextMessageStart({\n messageId: currentMessageId,\n });\n didOutputText = true;\n }\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content: text,\n });\n }\n } else if (chunk.delta.type === \"input_json_delta\") {\n eventStream$.sendActionExecutionArgs({\n actionExecutionId: currentToolCallId,\n args: chunk.delta.partial_json,\n });\n }\n } else if (chunk.type === \"content_block_stop\") {\n if (mode === \"message\") {\n if (didOutputText) {\n eventStream$.sendTextMessageEnd({\n messageId: currentMessageId,\n });\n }\n } else if (mode === \"function\") {\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: currentToolCallId,\n });\n }\n }\n }\n } catch (error) {\n throw convertServiceAdapterError(error, \"Anthropic\");\n }\n\n // Generate fallback response only if Anthropic produced no content\n if (\n !hasReceivedContent &&\n this.shouldGenerateFallbackResponse(cachedMessages)\n ) {\n // Extract the tool result content for a more contextual response\n let fallbackContent = \"Task completed successfully.\";\n const lastMessage = cachedMessages[cachedMessages.length - 1];\n if (\n lastMessage?.role === \"user\" &&\n Array.isArray(lastMessage.content)\n ) {\n const toolResult = lastMessage.content.find(\n (c: any) => c.type === \"tool_result\",\n );\n if (\n toolResult?.content &&\n toolResult.content !== \"Action completed successfully\"\n ) {\n fallbackContent = toolResult.content;\n }\n }\n\n currentMessageId = randomId();\n eventStream$.sendTextMessageStart({ messageId: currentMessageId });\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content: fallbackContent,\n });\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n }\n\n eventStream$.complete();\n });\n } catch (error) {\n throw convertServiceAdapterError(error, \"Anthropic\");\n }\n\n return {\n threadId: threadId || randomUUID(),\n };\n }\n}\n\nconst THINKING_TAG = \"<thinking>\";\nconst THINKING_TAG_END = \"</thinking>\";\n\nclass FilterThinkingTextBuffer {\n private buffer: string;\n private didFilterThinkingTag: boolean = false;\n\n constructor() {\n this.buffer = \"\";\n }\n\n onTextChunk(text: string): string {\n this.buffer += text;\n if (this.didFilterThinkingTag) {\n return text;\n }\n const potentialTag = this.buffer.slice(0, THINKING_TAG.length);\n if (THINKING_TAG.startsWith(potentialTag)) {\n if (this.buffer.includes(THINKING_TAG_END)) {\n const end = this.buffer.indexOf(THINKING_TAG_END);\n const filteredText = this.buffer.slice(end + THINKING_TAG_END.length);\n this.buffer = filteredText;\n this.didFilterThinkingTag = true;\n return filteredText;\n } else {\n return \"\";\n }\n }\n return text;\n }\n\n reset() {\n this.buffer = \"\";\n this.didFilterThinkingTag = false;\n }\n}\n"],"mappings":";;;;;;;;;AA4EA,MAAM,gBAAgB;AAuCtB,IAAa,mBAAb,MAA+D;CAO7D,IAAW,YAA2B;AACpC,SAAO,KAAK;;CAEd,IAAW,OAAO;AAChB,SAAO;;CAGT,YAAY,QAAiC;eAbtB;kBACL;AAahB,MAAI,QAAQ,UACV,MAAK,aAAa,OAAO;AAG3B,MAAI,QAAQ,MACV,MAAK,QAAQ,OAAO;AAEtB,OAAK,gBAAgB,QAAQ,iBAAiB,EAAE,SAAS,OAAO;AAChE,OAAK,iBAAiB,QAAQ;;CAGhC,mBAAkC;EAChC,MAAM,YAAY,KAAK,iBAAiB;EACxC,MAAM,UAAU,oBAAoB,UAAU;AAO9C,SANiB,gBAAgB;GAC/B,SAAS,UAAU;GACnB,QAAQ,UAAU;GAClB,SAAS,QAAQ;GACjB,OAAO,QAAQ;GAChB,CAAC,CACc,KAAK,MAAM;;CAG7B,AAAQ,kBAAiC;AACvC,MAAI,CAAC,KAAK,YAAY;GAEpB,MAAM,sBAAoB,oBAAoB,CAAC;AAC/C,QAAK,aAAa,IAAI,UAAU,EAAE,CAAC;;AAErC,SAAO,KAAK;;;;;CAMd,AAAQ,uBACN,QACA,QAAiB,OAOZ;AACL,MAAI,CAAC,KAAK,cAAc,WAAW,CAAC,OAClC,QAAO;EAGT,MAAM,qBAAqB,OAAO;AAElC,MAAI,MACF,SAAQ,IACN,iEAAiE,mBAAmB,UACrF;AAGH,SAAO,CACL;GACE,MAAM;GACN,MAAM;GACN,eAAe,EAAE,MAAM,aAAa;GACrC,CACF;;;;;CAMH,AAAQ,6BACN,UACA,QAAiB,OACV;AACP,MAAI,CAAC,KAAK,cAAc,WAAW,SAAS,WAAW,EACrD,QAAO;EAGT,MAAM,eAAe,SAAS,SAAS,SAAS;EAChD,MAAM,gBAAgB,SAAS;AAE/B,MACE,MAAM,QAAQ,aAAa,QAAQ,IACnC,aAAa,QAAQ,SAAS,GAC9B;GACA,MAAM,aAAa,aAAa,QAAQ,aAAa,QAAQ,SAAS;GAEtE,MAAM,kBAAkB,CACtB,GAAG,SAAS,MAAM,GAAG,GAAG,EACxB;IACE,GAAG;IACH,SAAS,CACP,GAAG,aAAa,QAAQ,MAAM,GAAG,GAAG,EACpC;KAAE,GAAG;KAAY,eAAe,EAAE,MAAM,aAAa;KAAE,CACxD;IACF,CACF;AAED,OAAI,MACF,SAAQ,IACN,yEAAyE,cAAc,IACxF;AAGH,UAAO;;AAGT,SAAO;;CAGT,AAAQ,+BACN,UACS;AACT,MAAI,SAAS,WAAW,EAAG,QAAO;EAElC,MAAM,cAAc,SAAS,SAAS,SAAS;EAG/C,MAAM,qBACJ,YAAY,SAAS,UACrB,MAAM,QAAQ,YAAY,QAAQ,IAClC,YAAY,QAAQ,MACjB,YAAiB,QAAQ,SAAS,cACpC;AAIH,MAAI,SAAS,UAAU,KAAK,oBAAoB;GAC9C,MAAM,YAAY,SAAS,MAAM,GAAG;AAcpC,UAZE,UAAU,IAAI,SAAS,UACvB,UAAU,IAAI,SAAS,eACvB,MAAM,QAAQ,UAAU,GAAG,QAAQ,IACnC,UAAU,GAAG,QAAQ,MAClB,YAAiB,QAAQ,SAAS,WACpC,IACD,UAAU,IAAI,SAAS,UACvB,MAAM,QAAQ,UAAU,GAAG,QAAQ,IACnC,UAAU,GAAG,QAAQ,MAClB,YAAiB,QAAQ,SAAS,cACpC;;AAKL,SAAO;;CAGT,MAAM,QACJ,SAC+C;EAC/C,MAAM,EACJ,UACA,QAAQ,KAAK,OACb,UAAU,aACV,SACA,aACA,wBACE;EACJ,MAAM,QAAQ,QAAQ,IAAI,kCAAkC;EAC5D,MAAM,mBAAmB,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAE,KAAK,CAAC;EAE5D,MAAM,WAAW,CAAC,GAAG,YAAY;EAGjC,MAAM,sBAAsB,SAAS,OAAO;EAC5C,MAAM,eAAe,oBAAoB,eAAe,GACpD,oBAAoB,UACpB;EAQJ,MAAM,kCAAkB,IAAI,KAAa;AAEzC,OAAK,MAAM,WAAW,SACpB,KAAI,QAAQ,0BAA0B,CACpC,iBAAgB,IAAI,QAAQ,GAAG;EAKnC,MAAM,yCAAyB,IAAI,KAAa;EAwDhD,MAAM,kBAAkB,0BAHtB,oCApDwB,SACvB,KAAK,YAAY;AAEhB,OAAI,QAAQ,iBAAiB,EAAE;AAE7B,QAAI,CAAC,gBAAgB,IAAI,QAAQ,kBAAkB,CACjD,QAAO;AAIT,QAAI,uBAAuB,IAAI,QAAQ,kBAAkB,CACvD,QAAO;AAIT,2BAAuB,IAAI,QAAQ,kBAAkB;AAErD,WAAO;KACL,MAAM;KACN,SAAS,CACP;MACE,MAAM;MACN,SAAS,QAAQ,UAAU;MAC3B,aAAa,QAAQ;MACtB,CACF;KACF;;AAIH,UAAO,iCAAiC,QAAQ;IAChD,CACD,OAAO,QAAQ,CACf,QAAQ,QAAQ;AAEf,OAAI,IAAI,SAAS,eAAe,MAAM,QAAQ,IAAI,QAAQ,CAQxD,QAAO,EANL,IAAI,QAAQ,WAAW,KACvB,IAAI,QAAQ,GAAG,SAAS,WACvB,CAAE,IAAI,QAAQ,GAAW,QACvB,IAAI,QAAQ,GAAW,KAAK,MAAM,KAAK;AAK9C,UAAO;IACP,CAMoD,EAKtD,OACA,OACA,KAAK,eACN;EAGD,MAAM,qBAAqB,KAAK,uBAC9B,cACA,KAAK,cAAc,MACpB;EACD,MAAM,iBAAiB,KAAK,6BAC1B,iBACA,KAAK,cAAc,MACpB;EAKD,IAAI,aAAkB,qBAAqB;AAC3C,MAAI,qBAAqB,eAAe,WACtC,cAAa;GACX,MAAM;GACN,MAAM,oBAAoB;GAC3B;AAGH,MAAI;GACF,MAAM,eAAe;IACnB,QAAQ;IACR;IACA,UAAU;IACV,YAAY,qBAAqB,aAAa;IAC9C,GAAI,qBAAqB,cACrB,EAAE,aAAa,oBAAoB,aAAa,GAChD,EAAE;IACN,GAAI,MAAM,SAAS,KAAK,EAAE,OAAO;IACjC,GAAI,cAAc,EAAE,aAAa,YAAY;IAC7C,QAAQ;IACT;GAMD,MAAM,SAAS,MADG,KAAK,iBAAiB,CACT,SAAS,OAAO,aAAa;AAE5D,eAAY,OAAO,OAAO,iBAAiB;IACzC,IAAI,OAAsC;IAC1C,IAAI,gBAAgB;IACpB,IAAI,mBAAmB,UAAU;IACjC,IAAI,oBAAoB,UAAU;IAClC,IAAI,2BAA2B,IAAI,0BAA0B;IAC7D,IAAI,qBAAqB;AAEzB,QAAI;AACF,gBAAW,MAAM,SAAS,OACxB,KAAI,MAAM,SAAS,gBACjB,oBAAmB,MAAM,QAAQ;cACxB,MAAM,SAAS,uBACxB;UAAI,MAAM,cAAc,SAAS,QAAQ;AACvC,4BAAqB;AACrB,uBAAgB;AAChB,gCAAyB,OAAO;AAChC,cAAO;iBACE,MAAM,cAAc,SAAS,YAAY;AAClD,WAAI,CAAC,iBAAiB,IAAI,MAAM,cAAc,KAAK,EAAE;AAEnD,eAAO;AACP;;AAEF,4BAAqB;AACrB,2BAAoB,MAAM,cAAc;AACxC,oBAAa,yBAAyB;QACpC,mBAAmB;QACnB,YAAY,MAAM,cAAc;QAChC,iBAAiB;QAClB,CAAC;AACF,cAAO;;gBAEA,MAAM,SAAS,uBAAuB;AAC/C,UAAI,SAAS,KAEX;AAEF,UAAI,MAAM,MAAM,SAAS,cAAc;OACrC,MAAM,OAAO,yBAAyB,YACpC,MAAM,MAAM,KACb;AACD,WAAI,KAAK,SAAS,GAAG;AACnB,YAAI,CAAC,eAAe;AAClB,sBAAa,qBAAqB,EAChC,WAAW,kBACZ,CAAC;AACF,yBAAgB;;AAElB,qBAAa,uBAAuB;SAClC,WAAW;SACX,SAAS;SACV,CAAC;;iBAEK,MAAM,MAAM,SAAS,mBAC9B,cAAa,wBAAwB;OACnC,mBAAmB;OACnB,MAAM,MAAM,MAAM;OACnB,CAAC;gBAEK,MAAM,SAAS,sBACxB;UAAI,SAAS,WACX;WAAI,cACF,cAAa,mBAAmB,EAC9B,WAAW,kBACZ,CAAC;iBAEK,SAAS,WAClB,cAAa,uBAAuB,EAClC,mBAAmB,mBACpB,CAAC;;aAID,OAAO;AACd,WAAM,2BAA2B,OAAO,YAAY;;AAItD,QACE,CAAC,sBACD,KAAK,+BAA+B,eAAe,EACnD;KAEA,IAAI,kBAAkB;KACtB,MAAM,cAAc,eAAe,eAAe,SAAS;AAC3D,SACE,aAAa,SAAS,UACtB,MAAM,QAAQ,YAAY,QAAQ,EAClC;MACA,MAAM,aAAa,YAAY,QAAQ,MACpC,MAAW,EAAE,SAAS,cACxB;AACD,UACE,YAAY,WACZ,WAAW,YAAY,gCAEvB,mBAAkB,WAAW;;AAIjC,wBAAmB,UAAU;AAC7B,kBAAa,qBAAqB,EAAE,WAAW,kBAAkB,CAAC;AAClE,kBAAa,uBAAuB;MAClC,WAAW;MACX,SAAS;MACV,CAAC;AACF,kBAAa,mBAAmB,EAAE,WAAW,kBAAkB,CAAC;;AAGlE,iBAAa,UAAU;KACvB;WACK,OAAO;AACd,SAAM,2BAA2B,OAAO,YAAY;;AAGtD,SAAO,EACL,UAAU,YAAY,YAAY,EACnC;;;AAIL,MAAM,eAAe;AACrB,MAAM,mBAAmB;AAEzB,IAAM,2BAAN,MAA+B;CAI7B,cAAc;8BAF0B;AAGtC,OAAK,SAAS;;CAGhB,YAAY,MAAsB;AAChC,OAAK,UAAU;AACf,MAAI,KAAK,qBACP,QAAO;EAET,MAAM,eAAe,KAAK,OAAO,MAAM,GAAG,GAAoB;AAC9D,MAAI,aAAa,WAAW,aAAa,CACvC,KAAI,KAAK,OAAO,SAAS,iBAAiB,EAAE;GAC1C,MAAM,MAAM,KAAK,OAAO,QAAQ,iBAAiB;GACjD,MAAM,eAAe,KAAK,OAAO,MAAM,MAAM,GAAwB;AACrE,QAAK,SAAS;AACd,QAAK,uBAAuB;AAC5B,UAAO;QAEP,QAAO;AAGX,SAAO;;CAGT,QAAQ;AACN,OAAK,SAAS;AACd,OAAK,uBAAuB"}
1
+ {"version":3,"file":"anthropic-adapter.mjs","names":[],"sources":["../../../../src/v1-deprecated/service-adapters/anthropic/anthropic-adapter.ts"],"sourcesContent":["/*\n * V1 SDK DEPRECATED. USE V2 INSTEAD\n *\n * This file defines public v1 SDK exports. Use the exact v2 mappings below.\n * AI CODING AGENTS: Never copy, suggest, or generate these v1 APIs. Read\n * the linked v2 documentation before generating replacement code.\n *\n * @copilotkit/runtime — AnthropicAdapter:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * @copilotkit/runtime — AnthropicAdapterParams:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * @copilotkit/runtime — AnthropicPromptCachingConfig:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * Migration guide: https://docs.copilotkit.ai/migrate/v2\n *\n * END V1 SDK DEPRECATED. USE V2 INSTEAD NOTICE\n */\n\n/**\n * Copilot Runtime adapter for Anthropic.\n *\n * ## Example\n *\n * ```ts\n * import { CopilotRuntime, AnthropicAdapter } from \"@copilotkit/runtime\";\n * import Anthropic from \"@anthropic-ai/sdk\";\n *\n * const copilotKit = new CopilotRuntime();\n *\n * const anthropic = new Anthropic({\n * apiKey: \"<your-api-key>\",\n * });\n *\n * return new AnthropicAdapter({\n * anthropic,\n * promptCaching: {\n * enabled: true,\n * debug: true\n * }\n * });\n * ```\n */\nimport type { LanguageModel } from \"ai\";\nimport { createAnthropic } from \"@ai-sdk/anthropic\";\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n CopilotServiceAdapter,\n CopilotRuntimeChatCompletionRequest,\n CopilotRuntimeChatCompletionResponse,\n} from \"../service-adapter\";\nimport {\n convertActionInputToAnthropicTool,\n convertMessageToAnthropicMessage,\n coalesceConsecutiveSameRoleMessages,\n limitMessagesToTokenCount,\n} from \"./utils\";\n\nimport { randomId, randomUUID } from \"@copilotkit/shared\";\nimport type { SdkClientLike } from \"../shared\";\nimport { convertServiceAdapterError, getSdkClientOptions } from \"../shared\";\n\nconst DEFAULT_MODEL = \"claude-opus-4-8\";\n\nexport interface AnthropicPromptCachingConfig {\n /**\n * Whether to enable prompt caching.\n */\n enabled: boolean;\n\n /**\n * Whether to enable debug logging for cache operations.\n */\n debug?: boolean;\n}\n\nexport interface AnthropicAdapterParams {\n /**\n * An optional Anthropic instance to use. If not provided, a new instance will be\n * created.\n */\n anthropic?: SdkClientLike;\n\n /**\n * The model to use.\n */\n model?: string;\n\n /**\n * Configuration for prompt caching.\n * See: https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching\n */\n promptCaching?: AnthropicPromptCachingConfig;\n\n /**\n * Optional maximum input token limit. Overrides the default limit\n * used when trimming messages to fit the context window.\n */\n maxInputTokens?: number;\n}\n\nexport class AnthropicAdapter implements CopilotServiceAdapter {\n public model: string = DEFAULT_MODEL;\n public provider = \"anthropic\";\n private promptCaching: AnthropicPromptCachingConfig;\n private maxInputTokens?: number;\n\n private _anthropic: SdkClientLike;\n public get anthropic(): SdkClientLike {\n return this._anthropic;\n }\n public get name() {\n return \"AnthropicAdapter\";\n }\n\n constructor(params?: AnthropicAdapterParams) {\n if (params?.anthropic) {\n this._anthropic = params.anthropic;\n }\n // If no instance provided, we'll lazy-load in ensureAnthropic()\n if (params?.model) {\n this.model = params.model;\n }\n this.promptCaching = params?.promptCaching || { enabled: false };\n this.maxInputTokens = params?.maxInputTokens;\n }\n\n getLanguageModel(): LanguageModel {\n const anthropic = this.ensureAnthropic();\n const options = getSdkClientOptions(anthropic);\n const provider = createAnthropic({\n baseURL: anthropic.baseURL,\n apiKey: anthropic.apiKey,\n headers: options.defaultHeaders,\n fetch: options.fetch,\n });\n return provider(this.model);\n }\n\n private ensureAnthropic(): SdkClientLike {\n if (!this._anthropic) {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const Anthropic = require(\"@anthropic-ai/sdk\").default;\n this._anthropic = new Anthropic({});\n }\n return this._anthropic;\n }\n\n /**\n * Adds cache control to system prompt\n */\n private addSystemPromptCaching(\n system: string,\n debug: boolean = false,\n ):\n | string\n | Array<{\n type: \"text\";\n text: string;\n cache_control?: { type: \"ephemeral\" };\n }> {\n if (!this.promptCaching.enabled || !system) {\n return system;\n }\n\n const originalTextLength = system.length;\n\n if (debug) {\n console.log(\n `[ANTHROPIC CACHE DEBUG] Added cache control to system prompt (${originalTextLength} chars).`,\n );\n }\n\n return [\n {\n type: \"text\",\n text: system,\n cache_control: { type: \"ephemeral\" },\n },\n ];\n }\n\n /**\n * Adds cache control to the final message\n */\n private addIncrementalMessageCaching(\n messages: Anthropic.Messages.MessageParam[],\n debug: boolean = false,\n ): any[] {\n if (!this.promptCaching.enabled || messages.length === 0) {\n return messages;\n }\n\n const finalMessage = messages[messages.length - 1];\n const messageNumber = messages.length;\n\n if (\n Array.isArray(finalMessage.content) &&\n finalMessage.content.length > 0\n ) {\n const finalBlock = finalMessage.content[finalMessage.content.length - 1];\n\n const updatedMessages = [\n ...messages.slice(0, -1),\n {\n ...finalMessage,\n content: [\n ...finalMessage.content.slice(0, -1),\n { ...finalBlock, cache_control: { type: \"ephemeral\" } } as any,\n ],\n },\n ];\n\n if (debug) {\n console.log(\n `[ANTHROPIC CACHE DEBUG] Added cache control to final message (message ${messageNumber}).`,\n );\n }\n\n return updatedMessages;\n }\n\n return messages;\n }\n\n private shouldGenerateFallbackResponse(\n messages: Anthropic.Messages.MessageParam[],\n ): boolean {\n if (messages.length === 0) return false;\n\n const lastMessage = messages[messages.length - 1];\n\n // Check if the last message is a tool result\n const endsWithToolResult =\n lastMessage.role === \"user\" &&\n Array.isArray(lastMessage.content) &&\n lastMessage.content.some(\n (content: any) => content.type === \"tool_result\",\n );\n\n // Also check if we have a recent pattern of user message -> assistant tool use -> user tool result\n // This indicates a completed action that might not need a response\n if (messages.length >= 3 && endsWithToolResult) {\n const lastThree = messages.slice(-3);\n const hasRecentToolPattern =\n lastThree[0]?.role === \"user\" && // Initial user message\n lastThree[1]?.role === \"assistant\" && // Assistant tool use\n Array.isArray(lastThree[1].content) &&\n lastThree[1].content.some(\n (content: any) => content.type === \"tool_use\",\n ) &&\n lastThree[2]?.role === \"user\" && // Tool result\n Array.isArray(lastThree[2].content) &&\n lastThree[2].content.some(\n (content: any) => content.type === \"tool_result\",\n );\n\n return hasRecentToolPattern;\n }\n\n return endsWithToolResult;\n }\n\n async process(\n request: CopilotRuntimeChatCompletionRequest,\n ): Promise<CopilotRuntimeChatCompletionResponse> {\n const {\n threadId,\n model = this.model,\n messages: rawMessages,\n actions,\n eventSource,\n forwardedParameters,\n } = request;\n const tools = actions.map(convertActionInputToAnthropicTool);\n const knownActionNames = new Set(actions.map((a) => a.name));\n\n const messages = [...rawMessages];\n\n // get the instruction message\n const instructionsMessage = messages.shift();\n const instructions = instructionsMessage.isTextMessage()\n ? instructionsMessage.content\n : \"\";\n\n // ALLOWLIST APPROACH:\n // 1. First, identify all valid tool_use calls (from assistant)\n // 2. Then, only keep tool_result blocks that correspond to these valid tool_use IDs\n // 3. Discard any other tool_result blocks\n\n // Step 1: Extract valid tool_use IDs\n const validToolUseIds = new Set<string>();\n\n for (const message of messages) {\n if (message.isActionExecutionMessage()) {\n validToolUseIds.add(message.id);\n }\n }\n\n // Step 2: Map each message to an Anthropic message, eliminating invalid tool_results\n const processedToolResultIds = new Set<string>();\n const anthropicMessages = messages\n .map((message) => {\n // For tool results, only include if they match a valid tool_use ID AND haven't been processed\n if (message.isResultMessage()) {\n // Skip if there's no corresponding tool_use\n if (!validToolUseIds.has(message.actionExecutionId)) {\n return null; // Will be filtered out later\n }\n\n // Skip if we've already processed a result for this tool_use ID\n if (processedToolResultIds.has(message.actionExecutionId)) {\n return null; // Will be filtered out later\n }\n\n // Mark this tool result as processed\n processedToolResultIds.add(message.actionExecutionId);\n\n return {\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n content: message.result || \"Action completed successfully\",\n tool_use_id: message.actionExecutionId,\n },\n ],\n };\n }\n\n // For non-tool-result messages, convert normally\n return convertMessageToAnthropicMessage(message);\n })\n .filter(Boolean) // Remove nulls\n .filter((msg) => {\n // Filter out assistant messages with empty text content\n if (msg.role === \"assistant\" && Array.isArray(msg.content)) {\n const hasEmptyTextOnly =\n msg.content.length === 1 &&\n msg.content[0].type === \"text\" &&\n (!(msg.content[0] as any).text ||\n (msg.content[0] as any).text.trim() === \"\");\n\n // Keep messages that have tool_use or non-empty text\n return !hasEmptyTextOnly;\n }\n return true;\n }) as Anthropic.Messages.MessageParam[];\n\n // Coalesce consecutive same-role messages so the Anthropic API receives alternating turns.\n // A mixed text+tool_use response is stored as separate TextMessage / ActionExecutionMessage\n // objects; they must be merged into one assistant message before dispatch.\n const coalescedMessages =\n coalesceConsecutiveSameRoleMessages(anthropicMessages);\n\n // Apply token limits\n const limitedMessages = limitMessagesToTokenCount(\n coalescedMessages,\n tools,\n model,\n this.maxInputTokens,\n );\n\n // Apply prompt caching if enabled\n const cachedSystemPrompt = this.addSystemPromptCaching(\n instructions,\n this.promptCaching.debug,\n );\n const cachedMessages = this.addIncrementalMessageCaching(\n limitedMessages,\n this.promptCaching.debug,\n );\n\n // We'll check if we need a fallback response after seeing what Anthropic returns\n // Role alternation is now enforced by coalesceConsecutiveSameRoleMessages above.\n\n let toolChoice: any = forwardedParameters?.toolChoice;\n if (forwardedParameters?.toolChoice === \"function\") {\n toolChoice = {\n type: \"tool\",\n name: forwardedParameters.toolChoiceFunctionName,\n };\n }\n\n try {\n const createParams = {\n system: cachedSystemPrompt,\n model,\n messages: cachedMessages,\n max_tokens: forwardedParameters?.maxTokens || 4096,\n ...(forwardedParameters?.temperature\n ? { temperature: forwardedParameters.temperature }\n : {}),\n ...(tools.length > 0 && { tools }),\n ...(toolChoice && { tool_choice: toolChoice }),\n stream: true,\n };\n\n // The public surface is structural so consumers who skip the optional\n // peer can still compile (see SdkClientLike); the SDK type is only\n // reachable here, inside a function body, where it is never emitted.\n const anthropic = this.ensureAnthropic() as Anthropic;\n const stream = await anthropic.messages.create(createParams);\n\n eventSource.stream(async (eventStream$) => {\n let mode: \"function\" | \"message\" | null = null;\n let didOutputText = false;\n let currentMessageId = randomId();\n let currentToolCallId = randomId();\n let filterThinkingTextBuffer = new FilterThinkingTextBuffer();\n let hasReceivedContent = false;\n\n const emitText = (text: string) => {\n if (text.length === 0) {\n return;\n }\n if (!didOutputText) {\n eventStream$.sendTextMessageStart({\n messageId: currentMessageId,\n });\n didOutputText = true;\n }\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content: text,\n });\n };\n\n try {\n for await (const chunk of stream as AsyncIterable<any>) {\n if (chunk.type === \"message_start\") {\n currentMessageId = chunk.message.id;\n } else if (chunk.type === \"content_block_start\") {\n if (chunk.content_block.type === \"text\") {\n hasReceivedContent = true;\n didOutputText = false;\n filterThinkingTextBuffer.reset();\n mode = \"message\";\n } else if (chunk.content_block.type === \"tool_use\") {\n if (!knownActionNames.has(chunk.content_block.name)) {\n // Unknown tool - skip execution to prevent crashes\n mode = null;\n continue;\n }\n hasReceivedContent = true;\n currentToolCallId = chunk.content_block.id;\n eventStream$.sendActionExecutionStart({\n actionExecutionId: currentToolCallId,\n actionName: chunk.content_block.name,\n parentMessageId: currentMessageId,\n });\n mode = \"function\";\n }\n } else if (chunk.type === \"content_block_delta\") {\n if (mode === null) {\n // Skip deltas for unknown/skipped content blocks\n continue;\n }\n if (chunk.delta.type === \"text_delta\") {\n emitText(\n filterThinkingTextBuffer.onTextChunk(chunk.delta.text),\n );\n } else if (chunk.delta.type === \"input_json_delta\") {\n eventStream$.sendActionExecutionArgs({\n actionExecutionId: currentToolCallId,\n args: chunk.delta.partial_json,\n });\n }\n } else if (chunk.type === \"content_block_stop\") {\n if (mode === \"message\") {\n // Text held back as a possible `<thinking>` prefix is real\n // output once the block ends without resolving it.\n emitText(filterThinkingTextBuffer.flush());\n if (didOutputText) {\n eventStream$.sendTextMessageEnd({\n messageId: currentMessageId,\n });\n }\n } else if (mode === \"function\") {\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: currentToolCallId,\n });\n }\n }\n }\n } catch (error) {\n throw convertServiceAdapterError(error, \"Anthropic\");\n }\n\n // Generate fallback response only if Anthropic produced no content\n if (\n !hasReceivedContent &&\n this.shouldGenerateFallbackResponse(cachedMessages)\n ) {\n // Extract the tool result content for a more contextual response\n let fallbackContent = \"Task completed successfully.\";\n const lastMessage = cachedMessages[cachedMessages.length - 1];\n if (\n lastMessage?.role === \"user\" &&\n Array.isArray(lastMessage.content)\n ) {\n const toolResult = lastMessage.content.find(\n (c: any) => c.type === \"tool_result\",\n );\n if (\n toolResult?.content &&\n toolResult.content !== \"Action completed successfully\"\n ) {\n fallbackContent = toolResult.content;\n }\n }\n\n currentMessageId = randomId();\n eventStream$.sendTextMessageStart({ messageId: currentMessageId });\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content: fallbackContent,\n });\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n }\n\n eventStream$.complete();\n });\n } catch (error) {\n throw convertServiceAdapterError(error, \"Anthropic\");\n }\n\n return {\n threadId: threadId || randomUUID(),\n };\n }\n}\n\nconst THINKING_TAG = \"<thinking>\";\nconst THINKING_TAG_END = \"</thinking>\";\n\n/**\n * Strips a `<thinking>…</thinking>` block that opens a streamed text content\n * block, passing everything else through unchanged.\n *\n * Only the START of a content block can be a thinking tag. Text is held back\n * while the block's opening characters could still turn into `<thinking>`;\n * the moment they diverge, everything held back is emitted in one piece and\n * the detector disarms for the rest of the block, so a literal `<thinking>`\n * mentioned later in the answer is never treated as a tag. `flush()` releases\n * whatever is still held back when the content block ends (a block that is\n * just `<`, for example).\n */\nexport class FilterThinkingTextBuffer {\n private buffer: string = \"\";\n /**\n * True once the block's start is known to be, or not to be, a thinking tag;\n * from then on chunks pass straight through.\n */\n private resolved: boolean = false;\n\n onTextChunk(text: string): string {\n if (this.resolved) {\n return text;\n }\n this.buffer += text;\n\n if (this.buffer.length < THINKING_TAG.length) {\n if (THINKING_TAG.startsWith(this.buffer)) {\n // Still a possible tag prefix — keep holding it back.\n return \"\";\n }\n return this.release();\n }\n\n if (!this.buffer.startsWith(THINKING_TAG)) {\n // Diverged from `<thinking>`: emit the whole held-back text, not just\n // this chunk, and stop looking.\n return this.release();\n }\n\n const end = this.buffer.indexOf(THINKING_TAG_END);\n if (end === -1) {\n // Inside the thinking block — swallow until it closes.\n return \"\";\n }\n const rest = this.buffer.slice(end + THINKING_TAG_END.length);\n this.buffer = \"\";\n this.resolved = true;\n return rest;\n }\n\n /**\n * Text still held back when the content block ends. A partial tag prefix\n * (`<`, `<thin`) is real output and comes back; an unterminated thinking\n * block stays hidden.\n */\n flush(): string {\n if (this.resolved) {\n return \"\";\n }\n const pending =\n this.buffer.length < THINKING_TAG.length &&\n THINKING_TAG.startsWith(this.buffer)\n ? this.buffer\n : \"\";\n this.buffer = \"\";\n this.resolved = true;\n return pending;\n }\n\n reset() {\n this.buffer = \"\";\n this.resolved = false;\n }\n\n private release(): string {\n const pending = this.buffer;\n this.buffer = \"\";\n this.resolved = true;\n return pending;\n }\n}\n"],"mappings":"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"}
@@ -1,15 +1,18 @@
1
1
  require("reflect-metadata");
2
2
  const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
3
+ let _ai_sdk_openai = require("@ai-sdk/openai");
3
4
  let _copilotkit_shared = require("@copilotkit/shared");
4
5
 
5
6
  //#region src/v1-deprecated/service-adapters/experimental/ollama/ollama-adapter.ts
6
7
  const DEFAULT_MODEL = "llama3:latest";
8
+ const DEFAULT_BASE_URL = "http://127.0.0.1:11434";
7
9
  var ExperimentalOllamaAdapter = class {
8
10
  get name() {
9
11
  return "OllamaAdapter";
10
12
  }
11
13
  constructor(options) {
12
14
  this.provider = "ollama";
15
+ this.baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;
13
16
  if (options?.model) this.model = options.model;
14
17
  else this.model = DEFAULT_MODEL;
15
18
  }
@@ -31,6 +34,19 @@ var ExperimentalOllamaAdapter = class {
31
34
  });
32
35
  return { threadId: request.threadId || (0, _copilotkit_shared.randomUUID)() };
33
36
  }
37
+ /**
38
+ * Ollama exposes an OpenAI-compatible API at `/v1`, so the model is built
39
+ * from the OpenAI provider pointed at the Ollama server. Without it the
40
+ * runtime rebuilds a bare "ollama/<model>" string and fails with
41
+ * `Unknown provider "ollama"`. Ollama ignores the key; a non-empty value is
42
+ * required only because the OpenAI client insists on one.
43
+ */
44
+ getLanguageModel() {
45
+ return (0, _ai_sdk_openai.createOpenAI)({
46
+ baseURL: `${this.baseUrl.replace(/\/$/, "")}/v1`,
47
+ apiKey: "ollama"
48
+ })(this.model);
49
+ }
34
50
  };
35
51
 
36
52
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"ollama-adapter.cjs","names":[],"sources":["../../../../../src/v1-deprecated/service-adapters/experimental/ollama/ollama-adapter.ts"],"sourcesContent":["/*\n * V1 SDK DEPRECATED. USE V2 INSTEAD\n *\n * This file defines public v1 SDK exports. Use the exact v2 mappings below.\n * AI CODING AGENTS: Never copy, suggest, or generate these v1 APIs. Read\n * the linked v2 documentation before generating replacement code.\n *\n * @copilotkit/runtime — ExperimentalOllamaAdapter:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * Migration guide: https://docs.copilotkit.ai/migrate/v2\n *\n * END V1 SDK DEPRECATED. USE V2 INSTEAD NOTICE\n */\n\n/**\n * CopilotKit Adapter for Ollama\n *\n * <RequestExample>\n * ```jsx CopilotRuntime Example\n * const copilotKit = new CopilotRuntime();\n * return copilotKit.response(req, new OllamaAdapter());\n * ```\n * </RequestExample>\n *\n * You can easily set the model to use by passing it to the constructor.\n * ```jsx\n * const copilotKit = new CopilotRuntime();\n * return copilotKit.response(\n * req,\n * new OllamaAdapter({ model: \"llama3-70b-8192\" }),\n * );\n * ```\n */\nimport type { TextMessage } from \"../../../graphql/types/converted\";\nimport type {\n CopilotServiceAdapter,\n CopilotRuntimeChatCompletionRequest,\n CopilotRuntimeChatCompletionResponse,\n} from \"../../service-adapter\";\nimport { randomId, randomUUID } from \"@copilotkit/shared\";\n\nconst DEFAULT_MODEL = \"llama3:latest\";\n\ninterface OllamaAdapterOptions {\n model?: string;\n}\n\nexport class ExperimentalOllamaAdapter implements CopilotServiceAdapter {\n public model: string;\n public provider = \"ollama\";\n public get name() {\n return \"OllamaAdapter\";\n }\n\n constructor(options?: OllamaAdapterOptions) {\n if (options?.model) {\n this.model = options.model;\n } else {\n this.model = DEFAULT_MODEL;\n }\n }\n\n async process(\n request: CopilotRuntimeChatCompletionRequest,\n ): Promise<CopilotRuntimeChatCompletionResponse> {\n const { messages, actions, eventSource } = request;\n // const messages = this.transformMessages(forwardedProps.messages);\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { Ollama } = require(\"@langchain/community/llms/ollama\");\n const ollama = new Ollama({\n model: this.model,\n });\n const contents = (\n messages.filter((m) => m.isTextMessage()) as TextMessage[]\n ).map((m) => m.content);\n const _stream = await ollama.stream(contents); // [TODO] role info is dropped...\n\n eventSource.stream(async (eventStream$) => {\n const currentMessageId = randomId();\n eventStream$.sendTextMessageStart({ messageId: currentMessageId });\n for await (const chunkText of _stream) {\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content: chunkText,\n });\n }\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n // we may need to add this later.. [nc]\n // let calls = (await result.response).functionCalls();\n\n eventStream$.complete();\n });\n return {\n threadId: request.threadId || randomUUID(),\n };\n }\n}\n"],"mappings":";;;;;AA8CA,MAAM,gBAAgB;AAMtB,IAAa,4BAAb,MAAwE;CAGtE,IAAW,OAAO;AAChB,SAAO;;CAGT,YAAY,SAAgC;kBAL1B;AAMhB,MAAI,SAAS,MACX,MAAK,QAAQ,QAAQ;MAErB,MAAK,QAAQ;;CAIjB,MAAM,QACJ,SAC+C;EAC/C,MAAM,EAAE,UAAU,SAAS,gBAAgB;EAI3C,MAAM,EAAE,WAAW,QAAQ,mCAAmC;EAC9D,MAAM,SAAS,IAAI,OAAO,EACxB,OAAO,KAAK,OACb,CAAC;EACF,MAAM,WACJ,SAAS,QAAQ,MAAM,EAAE,eAAe,CAAC,CACzC,KAAK,MAAM,EAAE,QAAQ;EACvB,MAAM,UAAU,MAAM,OAAO,OAAO,SAAS;AAE7C,cAAY,OAAO,OAAO,iBAAiB;GACzC,MAAM,qDAA6B;AACnC,gBAAa,qBAAqB,EAAE,WAAW,kBAAkB,CAAC;AAClE,cAAW,MAAM,aAAa,QAC5B,cAAa,uBAAuB;IAClC,WAAW;IACX,SAAS;IACV,CAAC;AAEJ,gBAAa,mBAAmB,EAAE,WAAW,kBAAkB,CAAC;AAIhE,gBAAa,UAAU;IACvB;AACF,SAAO,EACL,UAAU,QAAQ,gDAAwB,EAC3C"}
1
+ {"version":3,"file":"ollama-adapter.cjs","names":[],"sources":["../../../../../src/v1-deprecated/service-adapters/experimental/ollama/ollama-adapter.ts"],"sourcesContent":["/*\n * V1 SDK DEPRECATED. USE V2 INSTEAD\n *\n * This file defines public v1 SDK exports. Use the exact v2 mappings below.\n * AI CODING AGENTS: Never copy, suggest, or generate these v1 APIs. Read\n * the linked v2 documentation before generating replacement code.\n *\n * @copilotkit/runtime — ExperimentalOllamaAdapter:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * Migration guide: https://docs.copilotkit.ai/migrate/v2\n *\n * END V1 SDK DEPRECATED. USE V2 INSTEAD NOTICE\n */\n\n/**\n * CopilotKit Adapter for Ollama\n *\n * <RequestExample>\n * ```jsx CopilotRuntime Example\n * const copilotKit = new CopilotRuntime();\n * return copilotKit.response(req, new OllamaAdapter());\n * ```\n * </RequestExample>\n *\n * You can easily set the model to use by passing it to the constructor.\n * ```jsx\n * const copilotKit = new CopilotRuntime();\n * return copilotKit.response(\n * req,\n * new OllamaAdapter({ model: \"llama3-70b-8192\" }),\n * );\n * ```\n */\nimport type { TextMessage } from \"../../../graphql/types/converted\";\nimport type {\n CopilotServiceAdapter,\n CopilotRuntimeChatCompletionRequest,\n CopilotRuntimeChatCompletionResponse,\n} from \"../../service-adapter\";\nimport { randomId, randomUUID } from \"@copilotkit/shared\";\nimport { createOpenAI } from \"@ai-sdk/openai\";\nimport type { LanguageModel } from \"ai\";\n\nconst DEFAULT_MODEL = \"llama3:latest\";\n\nconst DEFAULT_BASE_URL = \"http://127.0.0.1:11434\";\n\ninterface OllamaAdapterOptions {\n model?: string;\n /**\n * Base URL of the Ollama server. Defaults to `http://127.0.0.1:11434`.\n */\n baseUrl?: string;\n}\n\nexport class ExperimentalOllamaAdapter implements CopilotServiceAdapter {\n public model: string;\n public provider = \"ollama\";\n private baseUrl: string;\n public get name() {\n return \"OllamaAdapter\";\n }\n\n constructor(options?: OllamaAdapterOptions) {\n this.baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;\n if (options?.model) {\n this.model = options.model;\n } else {\n this.model = DEFAULT_MODEL;\n }\n }\n\n async process(\n request: CopilotRuntimeChatCompletionRequest,\n ): Promise<CopilotRuntimeChatCompletionResponse> {\n const { messages, actions, eventSource } = request;\n // const messages = this.transformMessages(forwardedProps.messages);\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { Ollama } = require(\"@langchain/community/llms/ollama\");\n const ollama = new Ollama({\n model: this.model,\n });\n const contents = (\n messages.filter((m) => m.isTextMessage()) as TextMessage[]\n ).map((m) => m.content);\n const _stream = await ollama.stream(contents); // [TODO] role info is dropped...\n\n eventSource.stream(async (eventStream$) => {\n const currentMessageId = randomId();\n eventStream$.sendTextMessageStart({ messageId: currentMessageId });\n for await (const chunkText of _stream) {\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content: chunkText,\n });\n }\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n // we may need to add this later.. [nc]\n // let calls = (await result.response).functionCalls();\n\n eventStream$.complete();\n });\n return {\n threadId: request.threadId || randomUUID(),\n };\n }\n\n /**\n * Ollama exposes an OpenAI-compatible API at `/v1`, so the model is built\n * from the OpenAI provider pointed at the Ollama server. Without it the\n * runtime rebuilds a bare \"ollama/<model>\" string and fails with\n * `Unknown provider \"ollama\"`. Ollama ignores the key; a non-empty value is\n * required only because the OpenAI client insists on one.\n */\n getLanguageModel(): LanguageModel {\n const provider = createOpenAI({\n baseURL: `${this.baseUrl.replace(/\\/$/, \"\")}/v1`,\n apiKey: \"ollama\",\n });\n return provider(this.model);\n }\n}\n"],"mappings":";;;;;;AAgDA,MAAM,gBAAgB;AAEtB,MAAM,mBAAmB;AAUzB,IAAa,4BAAb,MAAwE;CAItE,IAAW,OAAO;AAChB,SAAO;;CAGT,YAAY,SAAgC;kBAN1B;AAOhB,OAAK,UAAU,SAAS,WAAW;AACnC,MAAI,SAAS,MACX,MAAK,QAAQ,QAAQ;MAErB,MAAK,QAAQ;;CAIjB,MAAM,QACJ,SAC+C;EAC/C,MAAM,EAAE,UAAU,SAAS,gBAAgB;EAI3C,MAAM,EAAE,WAAW,QAAQ,mCAAmC;EAC9D,MAAM,SAAS,IAAI,OAAO,EACxB,OAAO,KAAK,OACb,CAAC;EACF,MAAM,WACJ,SAAS,QAAQ,MAAM,EAAE,eAAe,CAAC,CACzC,KAAK,MAAM,EAAE,QAAQ;EACvB,MAAM,UAAU,MAAM,OAAO,OAAO,SAAS;AAE7C,cAAY,OAAO,OAAO,iBAAiB;GACzC,MAAM,qDAA6B;AACnC,gBAAa,qBAAqB,EAAE,WAAW,kBAAkB,CAAC;AAClE,cAAW,MAAM,aAAa,QAC5B,cAAa,uBAAuB;IAClC,WAAW;IACX,SAAS;IACV,CAAC;AAEJ,gBAAa,mBAAmB,EAAE,WAAW,kBAAkB,CAAC;AAIhE,gBAAa,UAAU;IACvB;AACF,SAAO,EACL,UAAU,QAAQ,gDAAwB,EAC3C;;;;;;;;;CAUH,mBAAkC;AAKhC,0CAJ8B;GAC5B,SAAS,GAAG,KAAK,QAAQ,QAAQ,OAAO,GAAG,CAAC;GAC5C,QAAQ;GACT,CAAC,CACc,KAAK,MAAM"}
@@ -1,16 +1,30 @@
1
1
 
2
2
  import { CopilotRuntimeChatCompletionRequest, CopilotRuntimeChatCompletionResponse, CopilotServiceAdapter } from "../../service-adapter.cjs";
3
+ import { LanguageModel } from "ai";
3
4
 
4
5
  //#region src/v1-deprecated/service-adapters/experimental/ollama/ollama-adapter.d.ts
5
6
  interface OllamaAdapterOptions {
6
7
  model?: string;
8
+ /**
9
+ * Base URL of the Ollama server. Defaults to `http://127.0.0.1:11434`.
10
+ */
11
+ baseUrl?: string;
7
12
  }
8
13
  declare class ExperimentalOllamaAdapter implements CopilotServiceAdapter {
9
14
  model: string;
10
15
  provider: string;
16
+ private baseUrl;
11
17
  get name(): string;
12
18
  constructor(options?: OllamaAdapterOptions);
13
19
  process(request: CopilotRuntimeChatCompletionRequest): Promise<CopilotRuntimeChatCompletionResponse>;
20
+ /**
21
+ * Ollama exposes an OpenAI-compatible API at `/v1`, so the model is built
22
+ * from the OpenAI provider pointed at the Ollama server. Without it the
23
+ * runtime rebuilds a bare "ollama/<model>" string and fails with
24
+ * `Unknown provider "ollama"`. Ollama ignores the key; a non-empty value is
25
+ * required only because the OpenAI client insists on one.
26
+ */
27
+ getLanguageModel(): LanguageModel;
14
28
  }
15
29
  //#endregion
16
30
  export { ExperimentalOllamaAdapter };
@@ -1 +1 @@
1
- {"version":3,"file":"ollama-adapter.d.cts","names":[],"sources":["../../../../../src/v1-deprecated/service-adapters/experimental/ollama/ollama-adapter.ts"],"mappings":";;;;UAgDU,oBAAA;EACR,KAAA;AAAA;AAAA,cAGW,yBAAA,YAAqC,qBAAA;EACzC,KAAA;EACA,QAAA;EAAA,IACI,IAAA,CAAA;cAIC,OAAA,GAAU,oBAAA;EAQhB,OAAA,CACJ,OAAA,EAAS,mCAAA,GACR,OAAA,CAAQ,oCAAA;AAAA"}
1
+ {"version":3,"file":"ollama-adapter.d.cts","names":[],"sources":["../../../../../src/v1-deprecated/service-adapters/experimental/ollama/ollama-adapter.ts"],"mappings":";;;;;UAoDU,oBAAA;EACR,KAAA;EADQ;;;EAKR,OAAA;AAAA;AAAA,cAGW,yBAAA,YAAqC,qBAAA;EACzC,KAAA;EACA,QAAA;EAAA,QACC,OAAA;EAAA,IACG,IAAA,CAAA;cAIC,OAAA,GAAU,oBAAA;EAShB,OAAA,CACJ,OAAA,EAAS,mCAAA,GACR,OAAA,CAAQ,oCAAA;EAyCS;;;;;;;EAApB,gBAAA,CAAA,GAAoB,aAAA;AAAA"}
@@ -1,16 +1,30 @@
1
1
 
2
2
  import { CopilotRuntimeChatCompletionRequest, CopilotRuntimeChatCompletionResponse, CopilotServiceAdapter } from "../../service-adapter.mjs";
3
+ import { LanguageModel } from "ai";
3
4
 
4
5
  //#region src/v1-deprecated/service-adapters/experimental/ollama/ollama-adapter.d.ts
5
6
  interface OllamaAdapterOptions {
6
7
  model?: string;
8
+ /**
9
+ * Base URL of the Ollama server. Defaults to `http://127.0.0.1:11434`.
10
+ */
11
+ baseUrl?: string;
7
12
  }
8
13
  declare class ExperimentalOllamaAdapter implements CopilotServiceAdapter {
9
14
  model: string;
10
15
  provider: string;
16
+ private baseUrl;
11
17
  get name(): string;
12
18
  constructor(options?: OllamaAdapterOptions);
13
19
  process(request: CopilotRuntimeChatCompletionRequest): Promise<CopilotRuntimeChatCompletionResponse>;
20
+ /**
21
+ * Ollama exposes an OpenAI-compatible API at `/v1`, so the model is built
22
+ * from the OpenAI provider pointed at the Ollama server. Without it the
23
+ * runtime rebuilds a bare "ollama/<model>" string and fails with
24
+ * `Unknown provider "ollama"`. Ollama ignores the key; a non-empty value is
25
+ * required only because the OpenAI client insists on one.
26
+ */
27
+ getLanguageModel(): LanguageModel;
14
28
  }
15
29
  //#endregion
16
30
  export { ExperimentalOllamaAdapter };
@@ -1 +1 @@
1
- {"version":3,"file":"ollama-adapter.d.mts","names":[],"sources":["../../../../../src/v1-deprecated/service-adapters/experimental/ollama/ollama-adapter.ts"],"mappings":";;;;UAgDU,oBAAA;EACR,KAAA;AAAA;AAAA,cAGW,yBAAA,YAAqC,qBAAA;EACzC,KAAA;EACA,QAAA;EAAA,IACI,IAAA,CAAA;cAIC,OAAA,GAAU,oBAAA;EAQhB,OAAA,CACJ,OAAA,EAAS,mCAAA,GACR,OAAA,CAAQ,oCAAA;AAAA"}
1
+ {"version":3,"file":"ollama-adapter.d.mts","names":[],"sources":["../../../../../src/v1-deprecated/service-adapters/experimental/ollama/ollama-adapter.ts"],"mappings":";;;;;UAoDU,oBAAA;EACR,KAAA;EADQ;;;EAKR,OAAA;AAAA;AAAA,cAGW,yBAAA,YAAqC,qBAAA;EACzC,KAAA;EACA,QAAA;EAAA,QACC,OAAA;EAAA,IACG,IAAA,CAAA;cAIC,OAAA,GAAU,oBAAA;EAShB,OAAA,CACJ,OAAA,EAAS,mCAAA,GACR,OAAA,CAAQ,oCAAA;EAyCS;;;;;;;EAApB,gBAAA,CAAA,GAAoB,aAAA;AAAA"}
@@ -1,15 +1,18 @@
1
1
  import "reflect-metadata";
2
2
  import { __require } from "../../../_virtual/_rolldown/runtime.mjs";
3
+ import { createOpenAI } from "@ai-sdk/openai";
3
4
  import { randomId, randomUUID } from "@copilotkit/shared";
4
5
 
5
6
  //#region src/v1-deprecated/service-adapters/experimental/ollama/ollama-adapter.ts
6
7
  const DEFAULT_MODEL = "llama3:latest";
8
+ const DEFAULT_BASE_URL = "http://127.0.0.1:11434";
7
9
  var ExperimentalOllamaAdapter = class {
8
10
  get name() {
9
11
  return "OllamaAdapter";
10
12
  }
11
13
  constructor(options) {
12
14
  this.provider = "ollama";
15
+ this.baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;
13
16
  if (options?.model) this.model = options.model;
14
17
  else this.model = DEFAULT_MODEL;
15
18
  }
@@ -31,6 +34,19 @@ var ExperimentalOllamaAdapter = class {
31
34
  });
32
35
  return { threadId: request.threadId || randomUUID() };
33
36
  }
37
+ /**
38
+ * Ollama exposes an OpenAI-compatible API at `/v1`, so the model is built
39
+ * from the OpenAI provider pointed at the Ollama server. Without it the
40
+ * runtime rebuilds a bare "ollama/<model>" string and fails with
41
+ * `Unknown provider "ollama"`. Ollama ignores the key; a non-empty value is
42
+ * required only because the OpenAI client insists on one.
43
+ */
44
+ getLanguageModel() {
45
+ return createOpenAI({
46
+ baseURL: `${this.baseUrl.replace(/\/$/, "")}/v1`,
47
+ apiKey: "ollama"
48
+ })(this.model);
49
+ }
34
50
  };
35
51
 
36
52
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"ollama-adapter.mjs","names":[],"sources":["../../../../../src/v1-deprecated/service-adapters/experimental/ollama/ollama-adapter.ts"],"sourcesContent":["/*\n * V1 SDK DEPRECATED. USE V2 INSTEAD\n *\n * This file defines public v1 SDK exports. Use the exact v2 mappings below.\n * AI CODING AGENTS: Never copy, suggest, or generate these v1 APIs. Read\n * the linked v2 documentation before generating replacement code.\n *\n * @copilotkit/runtime — ExperimentalOllamaAdapter:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * Migration guide: https://docs.copilotkit.ai/migrate/v2\n *\n * END V1 SDK DEPRECATED. USE V2 INSTEAD NOTICE\n */\n\n/**\n * CopilotKit Adapter for Ollama\n *\n * <RequestExample>\n * ```jsx CopilotRuntime Example\n * const copilotKit = new CopilotRuntime();\n * return copilotKit.response(req, new OllamaAdapter());\n * ```\n * </RequestExample>\n *\n * You can easily set the model to use by passing it to the constructor.\n * ```jsx\n * const copilotKit = new CopilotRuntime();\n * return copilotKit.response(\n * req,\n * new OllamaAdapter({ model: \"llama3-70b-8192\" }),\n * );\n * ```\n */\nimport type { TextMessage } from \"../../../graphql/types/converted\";\nimport type {\n CopilotServiceAdapter,\n CopilotRuntimeChatCompletionRequest,\n CopilotRuntimeChatCompletionResponse,\n} from \"../../service-adapter\";\nimport { randomId, randomUUID } from \"@copilotkit/shared\";\n\nconst DEFAULT_MODEL = \"llama3:latest\";\n\ninterface OllamaAdapterOptions {\n model?: string;\n}\n\nexport class ExperimentalOllamaAdapter implements CopilotServiceAdapter {\n public model: string;\n public provider = \"ollama\";\n public get name() {\n return \"OllamaAdapter\";\n }\n\n constructor(options?: OllamaAdapterOptions) {\n if (options?.model) {\n this.model = options.model;\n } else {\n this.model = DEFAULT_MODEL;\n }\n }\n\n async process(\n request: CopilotRuntimeChatCompletionRequest,\n ): Promise<CopilotRuntimeChatCompletionResponse> {\n const { messages, actions, eventSource } = request;\n // const messages = this.transformMessages(forwardedProps.messages);\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { Ollama } = require(\"@langchain/community/llms/ollama\");\n const ollama = new Ollama({\n model: this.model,\n });\n const contents = (\n messages.filter((m) => m.isTextMessage()) as TextMessage[]\n ).map((m) => m.content);\n const _stream = await ollama.stream(contents); // [TODO] role info is dropped...\n\n eventSource.stream(async (eventStream$) => {\n const currentMessageId = randomId();\n eventStream$.sendTextMessageStart({ messageId: currentMessageId });\n for await (const chunkText of _stream) {\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content: chunkText,\n });\n }\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n // we may need to add this later.. [nc]\n // let calls = (await result.response).functionCalls();\n\n eventStream$.complete();\n });\n return {\n threadId: request.threadId || randomUUID(),\n };\n }\n}\n"],"mappings":";;;;;AA8CA,MAAM,gBAAgB;AAMtB,IAAa,4BAAb,MAAwE;CAGtE,IAAW,OAAO;AAChB,SAAO;;CAGT,YAAY,SAAgC;kBAL1B;AAMhB,MAAI,SAAS,MACX,MAAK,QAAQ,QAAQ;MAErB,MAAK,QAAQ;;CAIjB,MAAM,QACJ,SAC+C;EAC/C,MAAM,EAAE,UAAU,SAAS,gBAAgB;EAI3C,MAAM,EAAE,qBAAmB,mCAAmC;EAC9D,MAAM,SAAS,IAAI,OAAO,EACxB,OAAO,KAAK,OACb,CAAC;EACF,MAAM,WACJ,SAAS,QAAQ,MAAM,EAAE,eAAe,CAAC,CACzC,KAAK,MAAM,EAAE,QAAQ;EACvB,MAAM,UAAU,MAAM,OAAO,OAAO,SAAS;AAE7C,cAAY,OAAO,OAAO,iBAAiB;GACzC,MAAM,mBAAmB,UAAU;AACnC,gBAAa,qBAAqB,EAAE,WAAW,kBAAkB,CAAC;AAClE,cAAW,MAAM,aAAa,QAC5B,cAAa,uBAAuB;IAClC,WAAW;IACX,SAAS;IACV,CAAC;AAEJ,gBAAa,mBAAmB,EAAE,WAAW,kBAAkB,CAAC;AAIhE,gBAAa,UAAU;IACvB;AACF,SAAO,EACL,UAAU,QAAQ,YAAY,YAAY,EAC3C"}
1
+ {"version":3,"file":"ollama-adapter.mjs","names":[],"sources":["../../../../../src/v1-deprecated/service-adapters/experimental/ollama/ollama-adapter.ts"],"sourcesContent":["/*\n * V1 SDK DEPRECATED. USE V2 INSTEAD\n *\n * This file defines public v1 SDK exports. Use the exact v2 mappings below.\n * AI CODING AGENTS: Never copy, suggest, or generate these v1 APIs. Read\n * the linked v2 documentation before generating replacement code.\n *\n * @copilotkit/runtime — ExperimentalOllamaAdapter:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * Migration guide: https://docs.copilotkit.ai/migrate/v2\n *\n * END V1 SDK DEPRECATED. USE V2 INSTEAD NOTICE\n */\n\n/**\n * CopilotKit Adapter for Ollama\n *\n * <RequestExample>\n * ```jsx CopilotRuntime Example\n * const copilotKit = new CopilotRuntime();\n * return copilotKit.response(req, new OllamaAdapter());\n * ```\n * </RequestExample>\n *\n * You can easily set the model to use by passing it to the constructor.\n * ```jsx\n * const copilotKit = new CopilotRuntime();\n * return copilotKit.response(\n * req,\n * new OllamaAdapter({ model: \"llama3-70b-8192\" }),\n * );\n * ```\n */\nimport type { TextMessage } from \"../../../graphql/types/converted\";\nimport type {\n CopilotServiceAdapter,\n CopilotRuntimeChatCompletionRequest,\n CopilotRuntimeChatCompletionResponse,\n} from \"../../service-adapter\";\nimport { randomId, randomUUID } from \"@copilotkit/shared\";\nimport { createOpenAI } from \"@ai-sdk/openai\";\nimport type { LanguageModel } from \"ai\";\n\nconst DEFAULT_MODEL = \"llama3:latest\";\n\nconst DEFAULT_BASE_URL = \"http://127.0.0.1:11434\";\n\ninterface OllamaAdapterOptions {\n model?: string;\n /**\n * Base URL of the Ollama server. Defaults to `http://127.0.0.1:11434`.\n */\n baseUrl?: string;\n}\n\nexport class ExperimentalOllamaAdapter implements CopilotServiceAdapter {\n public model: string;\n public provider = \"ollama\";\n private baseUrl: string;\n public get name() {\n return \"OllamaAdapter\";\n }\n\n constructor(options?: OllamaAdapterOptions) {\n this.baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;\n if (options?.model) {\n this.model = options.model;\n } else {\n this.model = DEFAULT_MODEL;\n }\n }\n\n async process(\n request: CopilotRuntimeChatCompletionRequest,\n ): Promise<CopilotRuntimeChatCompletionResponse> {\n const { messages, actions, eventSource } = request;\n // const messages = this.transformMessages(forwardedProps.messages);\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { Ollama } = require(\"@langchain/community/llms/ollama\");\n const ollama = new Ollama({\n model: this.model,\n });\n const contents = (\n messages.filter((m) => m.isTextMessage()) as TextMessage[]\n ).map((m) => m.content);\n const _stream = await ollama.stream(contents); // [TODO] role info is dropped...\n\n eventSource.stream(async (eventStream$) => {\n const currentMessageId = randomId();\n eventStream$.sendTextMessageStart({ messageId: currentMessageId });\n for await (const chunkText of _stream) {\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content: chunkText,\n });\n }\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n // we may need to add this later.. [nc]\n // let calls = (await result.response).functionCalls();\n\n eventStream$.complete();\n });\n return {\n threadId: request.threadId || randomUUID(),\n };\n }\n\n /**\n * Ollama exposes an OpenAI-compatible API at `/v1`, so the model is built\n * from the OpenAI provider pointed at the Ollama server. Without it the\n * runtime rebuilds a bare \"ollama/<model>\" string and fails with\n * `Unknown provider \"ollama\"`. Ollama ignores the key; a non-empty value is\n * required only because the OpenAI client insists on one.\n */\n getLanguageModel(): LanguageModel {\n const provider = createOpenAI({\n baseURL: `${this.baseUrl.replace(/\\/$/, \"\")}/v1`,\n apiKey: \"ollama\",\n });\n return provider(this.model);\n }\n}\n"],"mappings":";;;;;;AAgDA,MAAM,gBAAgB;AAEtB,MAAM,mBAAmB;AAUzB,IAAa,4BAAb,MAAwE;CAItE,IAAW,OAAO;AAChB,SAAO;;CAGT,YAAY,SAAgC;kBAN1B;AAOhB,OAAK,UAAU,SAAS,WAAW;AACnC,MAAI,SAAS,MACX,MAAK,QAAQ,QAAQ;MAErB,MAAK,QAAQ;;CAIjB,MAAM,QACJ,SAC+C;EAC/C,MAAM,EAAE,UAAU,SAAS,gBAAgB;EAI3C,MAAM,EAAE,qBAAmB,mCAAmC;EAC9D,MAAM,SAAS,IAAI,OAAO,EACxB,OAAO,KAAK,OACb,CAAC;EACF,MAAM,WACJ,SAAS,QAAQ,MAAM,EAAE,eAAe,CAAC,CACzC,KAAK,MAAM,EAAE,QAAQ;EACvB,MAAM,UAAU,MAAM,OAAO,OAAO,SAAS;AAE7C,cAAY,OAAO,OAAO,iBAAiB;GACzC,MAAM,mBAAmB,UAAU;AACnC,gBAAa,qBAAqB,EAAE,WAAW,kBAAkB,CAAC;AAClE,cAAW,MAAM,aAAa,QAC5B,cAAa,uBAAuB;IAClC,WAAW;IACX,SAAS;IACV,CAAC;AAEJ,gBAAa,mBAAmB,EAAE,WAAW,kBAAkB,CAAC;AAIhE,gBAAa,UAAU;IACvB;AACF,SAAO,EACL,UAAU,QAAQ,YAAY,YAAY,EAC3C;;;;;;;;;CAUH,mBAAkC;AAKhC,SAJiB,aAAa;GAC5B,SAAS,GAAG,KAAK,QAAQ,QAAQ,OAAO,GAAG,CAAC;GAC5C,QAAQ;GACT,CAAC,CACc,KAAK,MAAM"}
@@ -1,5 +1,7 @@
1
1
  require("reflect-metadata");
2
+ const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
2
3
  const require_langchain_adapter = require('../langchain/langchain-adapter.cjs');
4
+ let _ai_sdk_google = require("@ai-sdk/google");
3
5
 
4
6
  //#region src/v1-deprecated/service-adapters/google/google-genai-adapter.ts
5
7
  /**
@@ -44,6 +46,21 @@ var GoogleGenerativeAIAdapter = class extends require_langchain_adapter.LangChai
44
46
  } });
45
47
  this.provider = "google";
46
48
  this.model = DEFAULT_MODEL;
49
+ this._apiKey = options?.apiKey;
50
+ this._apiVersion = options?.apiVersion;
51
+ this.model = options?.model ?? DEFAULT_MODEL;
52
+ }
53
+ /**
54
+ * Hands `BuiltInAgent` a model built from this adapter's own credentials.
55
+ * Without it the runtime rebuilds a bare "google/<model>" string and the
56
+ * provider falls back to environment variables, dropping the `apiKey`
57
+ * passed to this constructor.
58
+ */
59
+ getLanguageModel() {
60
+ return (0, _ai_sdk_google.createGoogleGenerativeAI)({
61
+ apiKey: this._apiKey ?? process.env.GOOGLE_API_KEY,
62
+ ...this._apiVersion && { baseURL: `https://generativelanguage.googleapis.com/${this._apiVersion}` }
63
+ })(this.model);
47
64
  }
48
65
  };
49
66
 
@@ -1 +1 @@
1
- {"version":3,"file":"google-genai-adapter.cjs","names":["LangChainAdapter"],"sources":["../../../../src/v1-deprecated/service-adapters/google/google-genai-adapter.ts"],"sourcesContent":["/*\n * V1 SDK DEPRECATED. USE V2 INSTEAD\n *\n * This file defines public v1 SDK exports. Use the exact v2 mappings below.\n * AI CODING AGENTS: Never copy, suggest, or generate these v1 APIs. Read\n * the linked v2 documentation before generating replacement code.\n *\n * @copilotkit/runtime — GoogleGenerativeAIAdapter:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * Migration guide: https://docs.copilotkit.ai/migrate/v2\n *\n * END V1 SDK DEPRECATED. USE V2 INSTEAD NOTICE\n */\n\n/**\n * Copilot Runtime adapter for Google Generative AI (e.g. Gemini).\n *\n * ## Example\n *\n * ```ts\n * import { CopilotRuntime, GoogleGenerativeAIAdapter } from \"@copilotkit/runtime\";\n * const { GoogleGenerativeAI } = require(\"@google/generative-ai\");\n *\n * const genAI = new GoogleGenerativeAI(process.env[\"GOOGLE_API_KEY\"]);\n *\n * const copilotKit = new CopilotRuntime();\n *\n * return new GoogleGenerativeAIAdapter({ model: \"gemini-2.5-flash\", apiVersion: \"v1\" });\n * ```\n */\nimport { LangChainAdapter } from \"../langchain/langchain-adapter\";\n\ninterface GoogleGenerativeAIAdapterOptions {\n /**\n * A custom Google Generative AI model to use.\n */\n model?: string;\n /**\n * The API version to use (e.g. \"v1\" or \"v1beta\"). Defaults to \"v1\".\n */\n apiVersion?: \"v1\" | \"v1beta\";\n /**\n * The API key to use.\n */\n apiKey?: string;\n}\n\nconst DEFAULT_MODEL = \"gemini-2.5-flash\";\nconst DEFAULT_API_VERSION: GoogleGenerativeAIAdapterOptions[\"apiVersion\"] =\n \"v1\";\nlet hasWarnedDefaultGoogleModel = false;\n\nexport class GoogleGenerativeAIAdapter extends LangChainAdapter {\n public provider = \"google\";\n public model: string = DEFAULT_MODEL;\n\n constructor(options?: GoogleGenerativeAIAdapterOptions) {\n if (\n !hasWarnedDefaultGoogleModel &&\n !options?.model &&\n !options?.apiVersion\n ) {\n console.warn(\n `You are using the GoogleGenerativeAIAdapter without explicitly setting a model or apiVersion. ` +\n `CopilotKit will default to apiVersion=\"v1\" and model=\"${DEFAULT_MODEL}\". ` +\n `To silence this warning, pass model and apiVersion when constructing the adapter.`,\n );\n hasWarnedDefaultGoogleModel = true;\n }\n\n super({\n chainFn: async ({ messages, tools, threadId }) => {\n // Lazy require for optional peer dependencies\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { ChatGoogle } = require(\"@langchain/google-gauth\");\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { AIMessage } = require(\"@langchain/core/messages\");\n\n // Filter out empty assistant messages to prevent Gemini validation errors\n // Gemini specifically rejects conversations containing AIMessages with empty content\n const filteredMessages = messages.filter((message) => {\n // Keep all non-AI messages (HumanMessage, SystemMessage, ToolMessage, etc.)\n if (!(message instanceof AIMessage)) {\n return true;\n }\n\n // For AIMessages, only keep those with non-empty content\n // Also keep AIMessages with tool_calls even if content is empty\n const aiMsg = message as any;\n return (\n (aiMsg.content && String(aiMsg.content).trim().length > 0) ||\n (aiMsg.tool_calls && aiMsg.tool_calls.length > 0)\n );\n });\n\n this.model = options?.model ?? DEFAULT_MODEL;\n const model = new ChatGoogle({\n apiKey: options?.apiKey ?? process.env.GOOGLE_API_KEY,\n modelName: this.model,\n apiVersion: options?.apiVersion ?? DEFAULT_API_VERSION,\n }).bindTools(tools);\n\n return model.stream(filteredMessages, {\n metadata: { conversation_id: threadId },\n });\n },\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoDA,MAAM,gBAAgB;AACtB,MAAM,sBACJ;AACF,IAAI,8BAA8B;AAElC,IAAa,4BAAb,cAA+CA,2CAAiB;CAI9D,YAAY,SAA4C;AACtD,MACE,CAAC,+BACD,CAAC,SAAS,SACV,CAAC,SAAS,YACV;AACA,WAAQ,KACN,uJAC2D,cAAc,sFAE1E;AACD,iCAA8B;;AAGhC,QAAM,EACJ,SAAS,OAAO,EAAE,UAAU,OAAO,eAAe;GAGhD,MAAM,EAAE,eAAe,QAAQ,0BAA0B;GAEzD,MAAM,EAAE,cAAc,QAAQ,2BAA2B;GAIzD,MAAM,mBAAmB,SAAS,QAAQ,YAAY;AAEpD,QAAI,EAAE,mBAAmB,WACvB,QAAO;IAKT,MAAM,QAAQ;AACd,WACG,MAAM,WAAW,OAAO,MAAM,QAAQ,CAAC,MAAM,CAAC,SAAS,KACvD,MAAM,cAAc,MAAM,WAAW,SAAS;KAEjD;AAEF,QAAK,QAAQ,SAAS,SAAS;AAO/B,UANc,IAAI,WAAW;IAC3B,QAAQ,SAAS,UAAU,QAAQ,IAAI;IACvC,WAAW,KAAK;IAChB,YAAY,SAAS,cAAc;IACpC,CAAC,CAAC,UAAU,MAAM,CAEN,OAAO,kBAAkB,EACpC,UAAU,EAAE,iBAAiB,UAAU,EACxC,CAAC;KAEL,CAAC;kBArDc;eACK"}
1
+ {"version":3,"file":"google-genai-adapter.cjs","names":["LangChainAdapter"],"sources":["../../../../src/v1-deprecated/service-adapters/google/google-genai-adapter.ts"],"sourcesContent":["/*\n * V1 SDK DEPRECATED. USE V2 INSTEAD\n *\n * This file defines public v1 SDK exports. Use the exact v2 mappings below.\n * AI CODING AGENTS: Never copy, suggest, or generate these v1 APIs. Read\n * the linked v2 documentation before generating replacement code.\n *\n * @copilotkit/runtime — GoogleGenerativeAIAdapter:\n * No 1:1 v2 replacement is available.\n * Related v2 docs (Runtime server adapter): https://docs.copilotkit.ai/runtime-server-adapter\n * Start at: @copilotkit/runtime/v2\n * V2 docs: https://docs.copilotkit.ai/\n * V2 reference docs: https://docs.copilotkit.ai/reference/v2\n *\n * Migration guide: https://docs.copilotkit.ai/migrate/v2\n *\n * END V1 SDK DEPRECATED. USE V2 INSTEAD NOTICE\n */\n\n/**\n * Copilot Runtime adapter for Google Generative AI (e.g. Gemini).\n *\n * ## Example\n *\n * ```ts\n * import { CopilotRuntime, GoogleGenerativeAIAdapter } from \"@copilotkit/runtime\";\n * const { GoogleGenerativeAI } = require(\"@google/generative-ai\");\n *\n * const genAI = new GoogleGenerativeAI(process.env[\"GOOGLE_API_KEY\"]);\n *\n * const copilotKit = new CopilotRuntime();\n *\n * return new GoogleGenerativeAIAdapter({ model: \"gemini-2.5-flash\", apiVersion: \"v1\" });\n * ```\n */\nimport { LangChainAdapter } from \"../langchain/langchain-adapter\";\nimport { createGoogleGenerativeAI } from \"@ai-sdk/google\";\nimport type { LanguageModel } from \"ai\";\n\ninterface GoogleGenerativeAIAdapterOptions {\n /**\n * A custom Google Generative AI model to use.\n */\n model?: string;\n /**\n * The API version to use (e.g. \"v1\" or \"v1beta\"). Defaults to \"v1\".\n */\n apiVersion?: \"v1\" | \"v1beta\";\n /**\n * The API key to use.\n */\n apiKey?: string;\n}\n\nconst DEFAULT_MODEL = \"gemini-2.5-flash\";\nconst DEFAULT_API_VERSION: GoogleGenerativeAIAdapterOptions[\"apiVersion\"] =\n \"v1\";\nlet hasWarnedDefaultGoogleModel = false;\n\nexport class GoogleGenerativeAIAdapter extends LangChainAdapter {\n public provider = \"google\";\n private _apiKey?: string;\n private _apiVersion?: GoogleGenerativeAIAdapterOptions[\"apiVersion\"];\n public model: string = DEFAULT_MODEL;\n\n constructor(options?: GoogleGenerativeAIAdapterOptions) {\n if (\n !hasWarnedDefaultGoogleModel &&\n !options?.model &&\n !options?.apiVersion\n ) {\n console.warn(\n `You are using the GoogleGenerativeAIAdapter without explicitly setting a model or apiVersion. ` +\n `CopilotKit will default to apiVersion=\"v1\" and model=\"${DEFAULT_MODEL}\". ` +\n `To silence this warning, pass model and apiVersion when constructing the adapter.`,\n );\n hasWarnedDefaultGoogleModel = true;\n }\n\n super({\n chainFn: async ({ messages, tools, threadId }) => {\n // Lazy require for optional peer dependencies\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { ChatGoogle } = require(\"@langchain/google-gauth\");\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { AIMessage } = require(\"@langchain/core/messages\");\n\n // Filter out empty assistant messages to prevent Gemini validation errors\n // Gemini specifically rejects conversations containing AIMessages with empty content\n const filteredMessages = messages.filter((message) => {\n // Keep all non-AI messages (HumanMessage, SystemMessage, ToolMessage, etc.)\n if (!(message instanceof AIMessage)) {\n return true;\n }\n\n // For AIMessages, only keep those with non-empty content\n // Also keep AIMessages with tool_calls even if content is empty\n const aiMsg = message as any;\n return (\n (aiMsg.content && String(aiMsg.content).trim().length > 0) ||\n (aiMsg.tool_calls && aiMsg.tool_calls.length > 0)\n );\n });\n\n this.model = options?.model ?? DEFAULT_MODEL;\n const model = new ChatGoogle({\n apiKey: options?.apiKey ?? process.env.GOOGLE_API_KEY,\n modelName: this.model,\n apiVersion: options?.apiVersion ?? DEFAULT_API_VERSION,\n }).bindTools(tools);\n\n return model.stream(filteredMessages, {\n metadata: { conversation_id: threadId },\n });\n },\n });\n\n // `this.model` is otherwise only assigned inside the chain closure, which\n // does not run until a request arrives — so `getLanguageModel()` would\n // report the default model instead of the configured one.\n this._apiKey = options?.apiKey;\n this._apiVersion = options?.apiVersion;\n this.model = options?.model ?? DEFAULT_MODEL;\n }\n\n /**\n * Hands `BuiltInAgent` a model built from this adapter's own credentials.\n * Without it the runtime rebuilds a bare \"google/<model>\" string and the\n * provider falls back to environment variables, dropping the `apiKey`\n * passed to this constructor.\n */\n getLanguageModel(): LanguageModel {\n // `createGoogleGenerativeAI` has no `apiVersion` option, so the version is\n // carried on the base URL. Only when the caller asked for one: the\n // provider's own default is v1beta, and that has been the live default\n // ever since this method started routing around `process()`. Forcing the\n // adapter's documented \"v1\" here would strand models v1 does not serve.\n const provider = createGoogleGenerativeAI({\n apiKey: this._apiKey ?? process.env.GOOGLE_API_KEY,\n ...(this._apiVersion && {\n baseURL: `https://generativelanguage.googleapis.com/${this._apiVersion}`,\n }),\n });\n return provider(this.model);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAsDA,MAAM,gBAAgB;AACtB,MAAM,sBACJ;AACF,IAAI,8BAA8B;AAElC,IAAa,4BAAb,cAA+CA,2CAAiB;CAM9D,YAAY,SAA4C;AACtD,MACE,CAAC,+BACD,CAAC,SAAS,SACV,CAAC,SAAS,YACV;AACA,WAAQ,KACN,uJAC2D,cAAc,sFAE1E;AACD,iCAA8B;;AAGhC,QAAM,EACJ,SAAS,OAAO,EAAE,UAAU,OAAO,eAAe;GAGhD,MAAM,EAAE,eAAe,QAAQ,0BAA0B;GAEzD,MAAM,EAAE,cAAc,QAAQ,2BAA2B;GAIzD,MAAM,mBAAmB,SAAS,QAAQ,YAAY;AAEpD,QAAI,EAAE,mBAAmB,WACvB,QAAO;IAKT,MAAM,QAAQ;AACd,WACG,MAAM,WAAW,OAAO,MAAM,QAAQ,CAAC,MAAM,CAAC,SAAS,KACvD,MAAM,cAAc,MAAM,WAAW,SAAS;KAEjD;AAEF,QAAK,QAAQ,SAAS,SAAS;AAO/B,UANc,IAAI,WAAW;IAC3B,QAAQ,SAAS,UAAU,QAAQ,IAAI;IACvC,WAAW,KAAK;IAChB,YAAY,SAAS,cAAc;IACpC,CAAC,CAAC,UAAU,MAAM,CAEN,OAAO,kBAAkB,EACpC,UAAU,EAAE,iBAAiB,UAAU,EACxC,CAAC;KAEL,CAAC;kBAvDc;eAGK;AAyDrB,OAAK,UAAU,SAAS;AACxB,OAAK,cAAc,SAAS;AAC5B,OAAK,QAAQ,SAAS,SAAS;;;;;;;;CASjC,mBAAkC;AAYhC,sDAN0C;GACxC,QAAQ,KAAK,WAAW,QAAQ,IAAI;GACpC,GAAI,KAAK,eAAe,EACtB,SAAS,6CAA6C,KAAK,eAC5D;GACF,CAAC,CACc,KAAK,MAAM"}