@copilotkit/runtime 1.77.2 → 1.78.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.
- package/README.md +16 -0
- package/dist/agent/index.cjs +84 -14
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +4 -3
- package/dist/agent/index.d.cts.map +1 -1
- package/dist/agent/index.d.mts +4 -3
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs +84 -14
- package/dist/agent/index.mjs.map +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/service-adapters/google/google-genai-adapter.cjs +2 -2
- package/dist/service-adapters/google/google-genai-adapter.cjs.map +1 -1
- package/dist/service-adapters/google/google-genai-adapter.mjs +2 -2
- package/dist/service-adapters/google/google-genai-adapter.mjs.map +1 -1
- package/dist/v2/runtime/core/package-info.cjs +1 -1
- package/dist/v2/runtime/core/package-info.mjs +1 -1
- package/dist/v2/runtime/intelligence-platform/client.cjs +37 -7
- package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.mjs +37 -7
- package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
- package/dist/v2/runtime/runner/intelligence.cjs +1 -1
- package/dist/v2/runtime/runner/intelligence.cjs.map +1 -1
- package/dist/v2/runtime/runner/intelligence.d.cts.map +1 -1
- package/dist/v2/runtime/runner/intelligence.d.mts.map +1 -1
- package/dist/v2/runtime/runner/intelligence.mjs +1 -1
- package/dist/v2/runtime/runner/intelligence.mjs.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -192,3 +192,19 @@ See [Skill delivery](https://docs.copilotkit.ai/intelligence/learned-skills) for
|
|
|
192
192
|
Explicit `containers` accepts 1–50 unique container IDs and sends one batch request for all sources that need a refresh. This also applies to a list with one entry.
|
|
193
193
|
The server must support `POST /api/v1/learning/skills/batch` before you use this configuration. The SDK does not fall back to separate requests.
|
|
194
194
|
Legacy `containerId` configuration keeps its existing single-container request. Both interfaces use the same authentication configuration.
|
|
195
|
+
|
|
196
|
+
## Intelligence runner reconnects
|
|
197
|
+
|
|
198
|
+
`IntelligenceAgentRunner` retains unacknowledged events and retries them with the
|
|
199
|
+
same IDs after reconnect. An unexpected normal WebSocket close (`1000`) also
|
|
200
|
+
reconnects while the run remains active. Intentional cleanup does not reconnect.
|
|
201
|
+
|
|
202
|
+
Recovery also depends on the Intelligence gateway's reconnect grace period.
|
|
203
|
+
The current gateway defaults to 15 seconds and stores pending disconnects in
|
|
204
|
+
Redis so another gateway replica can finish cleanup. The gateway controls this
|
|
205
|
+
period; the runner does not negotiate it. A gateway with no reconnect grace can
|
|
206
|
+
record `RUNNER_CONNECTION_DROPPED` before the runner reconnects.
|
|
207
|
+
|
|
208
|
+
This recovers a lost WebSocket while the agent runtime remains alive. It does
|
|
209
|
+
not restart an agent after its runtime process exits. The existing 60-second
|
|
210
|
+
event acknowledgment deadline still applies.
|
package/dist/agent/index.cjs
CHANGED
|
@@ -86,20 +86,88 @@ function toolResultOutput(content) {
|
|
|
86
86
|
}] : [], ...media]
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Split a model string into provider and model id. The provider is the text
|
|
91
|
+
* before the FIRST ":" or "/"; everything after it is the model id, unchanged.
|
|
92
|
+
* So "openai:meta-llama/llama-3.3-70b" keeps the slash in its model id, and
|
|
93
|
+
* "openai/ft:gpt-4o-mini:org::id" keeps its colons. Empty strings mean the
|
|
94
|
+
* part is missing.
|
|
95
|
+
*/
|
|
96
|
+
function parseModelSpec(spec) {
|
|
97
|
+
const trimmed = spec.trim();
|
|
98
|
+
const separator = trimmed.search(/[:/]/);
|
|
99
|
+
if (separator === -1) return {
|
|
100
|
+
provider: trimmed.toLowerCase(),
|
|
101
|
+
model: ""
|
|
102
|
+
};
|
|
103
|
+
return {
|
|
104
|
+
provider: trimmed.slice(0, separator).toLowerCase(),
|
|
105
|
+
model: trimmed.slice(separator + 1).trim()
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Whether an `OPENAI_BASE_URL` should get Chat Completions instead of the
|
|
110
|
+
* Responses API. OpenAI's own hosts (including `*.api.openai.com`, such as the
|
|
111
|
+
* EU data-residency host) and Azure serve `/responses`, so they keep it, as
|
|
112
|
+
* does an unset value. Any other host gets `/chat/completions`, which is what
|
|
113
|
+
* most OpenAI-compatible servers implement. The host rule is
|
|
114
|
+
* `classifyModelHost`, the same one telemetry uses.
|
|
115
|
+
*
|
|
116
|
+
* A value `new URL` throws on keeps the Responses route; the request will
|
|
117
|
+
* fail on that base URL either way. A schemeless value such as
|
|
118
|
+
* `localhost:11434/v1` does not throw (it parses with scheme `localhost:` and
|
|
119
|
+
* an empty host), so it classifies as `other` and gets Chat Completions.
|
|
120
|
+
*/
|
|
121
|
+
function usesChatCompletions(baseURL) {
|
|
122
|
+
const trimmed = baseURL?.trim();
|
|
123
|
+
if (!trimmed) return false;
|
|
124
|
+
try {
|
|
125
|
+
new URL(trimmed);
|
|
126
|
+
} catch {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
const host = (0, _copilotkit_shared.classifyModelHost)(trimmed, "openai");
|
|
130
|
+
return host !== "openai" && host !== "azure";
|
|
131
|
+
}
|
|
132
|
+
/** Whether the Chat Completions notice below was already logged. */
|
|
133
|
+
let loggedChatCompletionsRoute = false;
|
|
134
|
+
/**
|
|
135
|
+
* Which OpenAI API an `openai/...` model string targets.
|
|
136
|
+
*
|
|
137
|
+
* `COPILOTKIT_OPENAI_API` (`responses` or `chat`) wins when set, so a proxy in
|
|
138
|
+
* front of OpenAI can keep the Responses API, and an OpenAI host can use Chat
|
|
139
|
+
* Completions. Unset or blank, `usesChatCompletions` decides from
|
|
140
|
+
* `OPENAI_BASE_URL`.
|
|
141
|
+
*
|
|
142
|
+
* When that rule picks Chat Completions, this logs once per process. Through a
|
|
143
|
+
* proxy, Chat Completions drops Responses-only features (such as reasoning
|
|
144
|
+
* summaries) without an error, and the notice names the way back.
|
|
145
|
+
*/
|
|
146
|
+
function openAIApiFor(baseURL) {
|
|
147
|
+
const raw = process.env.COPILOTKIT_OPENAI_API;
|
|
148
|
+
const override = raw?.trim().toLowerCase();
|
|
149
|
+
if (override === "responses" || override === "chat") return override;
|
|
150
|
+
if (override) throw new Error(`Invalid COPILOTKIT_OPENAI_API "${raw}". Use "responses" or "chat", or leave it unset.`);
|
|
151
|
+
if (!usesChatCompletions(baseURL)) return "responses";
|
|
152
|
+
if (!loggedChatCompletionsRoute) {
|
|
153
|
+
loggedChatCompletionsRoute = true;
|
|
154
|
+
console.info("[CopilotKit] OPENAI_BASE_URL is not an OpenAI or Azure host, so \"openai/...\" models use the Chat Completions API. To use the Responses API instead, set COPILOTKIT_OPENAI_API=responses.");
|
|
155
|
+
}
|
|
156
|
+
return "chat";
|
|
157
|
+
}
|
|
89
158
|
function resolveModel(spec, apiKey) {
|
|
90
159
|
if (typeof spec !== "string") return spec;
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (!rawProvider) throw new Error(`Invalid model string "${spec}". Use "openai/gpt-5", "anthropic/claude-sonnet-4.5", or "google/gemini-2.5-pro".`);
|
|
95
|
-
const provider = rawProvider.toLowerCase();
|
|
96
|
-
const model = rest.join(":").trim();
|
|
97
|
-
if (!model) throw new Error(`Invalid model string "${spec}". Use "openai/gpt-5", "anthropic/claude-sonnet-4.5", or "google/gemini-2.5-pro".`);
|
|
160
|
+
const { provider, model } = parseModelSpec(spec);
|
|
161
|
+
if (!provider) throw new Error(`Invalid model string "${spec}". Use "openai/gpt-5", "anthropic/claude-sonnet-4.5", or "google/gemini-3.8-flash".`);
|
|
162
|
+
if (!model) throw new Error(`Invalid model string "${spec}". Use "openai/gpt-5", "anthropic/claude-sonnet-4.5", or "google/gemini-3.8-flash".`);
|
|
98
163
|
switch (provider) {
|
|
99
|
-
case "openai":
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
164
|
+
case "openai": {
|
|
165
|
+
const openai = (0, _ai_sdk_openai.createOpenAI)({
|
|
166
|
+
apiKey: apiKey || process.env.OPENAI_API_KEY,
|
|
167
|
+
baseURL: process.env.OPENAI_BASE_URL
|
|
168
|
+
});
|
|
169
|
+
return openAIApiFor(process.env.OPENAI_BASE_URL) === "chat" ? openai.chat(model) : openai(model);
|
|
170
|
+
}
|
|
103
171
|
case "anthropic": return (0, _ai_sdk_anthropic.createAnthropic)({
|
|
104
172
|
apiKey: apiKey || process.env.ANTHROPIC_API_KEY,
|
|
105
173
|
baseURL: process.env.ANTHROPIC_BASE_URL
|
|
@@ -124,8 +192,9 @@ function resolveModel(spec, apiKey) {
|
|
|
124
192
|
*
|
|
125
193
|
* `resolveModel` above is the only place this runtime builds a provider, so it
|
|
126
194
|
* is the only place that knows the endpoint. Once built, the endpoint is gone:
|
|
127
|
-
* an AI SDK model
|
|
128
|
-
*
|
|
195
|
+
* an AI SDK model's `provider` names only the wire API (`"openai.responses"`
|
|
196
|
+
* on OpenAI and Azure, `"openai.chat"` on any other host), so it cannot tell
|
|
197
|
+
* OpenRouter from a laptop, and its base URL survives
|
|
129
198
|
* only inside a closure that the public `LanguageModelV3` type does not
|
|
130
199
|
* expose. Azure's own migration guide tells customers to use that same OpenAI
|
|
131
200
|
* client, so the case we are blindest to is the common one.
|
|
@@ -140,7 +209,8 @@ function resolveModel(spec, apiKey) {
|
|
|
140
209
|
*/
|
|
141
210
|
function classifyModelSpec(spec) {
|
|
142
211
|
if (typeof spec !== "string") return "unknown";
|
|
143
|
-
|
|
212
|
+
const { provider } = parseModelSpec(spec);
|
|
213
|
+
switch (provider) {
|
|
144
214
|
case "openai": return (0, _copilotkit_shared.classifyModelHost)(process.env.OPENAI_BASE_URL, "openai");
|
|
145
215
|
case "anthropic": return (0, _copilotkit_shared.classifyModelHost)(process.env.ANTHROPIC_BASE_URL, "anthropic");
|
|
146
216
|
case "google":
|