@copilotkit/react-core 1.64.1 → 1.64.2-canary.1785346263

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.
@@ -293,7 +293,10 @@ const ALL_UPDATES = [
293
293
  UseAgentUpdate.OnStateChanged,
294
294
  UseAgentUpdate.OnRunStatusChanged
295
295
  ];
296
- function useAgent({ agentId, updates, throttleMs } = {}) {
296
+ function useAgent({ agentId, threadId, runtimeAgentId, updates, throttleMs } = {}) {
297
+ if (threadId != null && runtimeAgentId == null) throw new Error(`useAgent: \`threadId\` requires \`runtimeAgentId\`. A threadId is written onto a single agent, but an agent resolved by agentId alone is shared, so scoping a thread to it would clobber other useAgent callers. Pass a distinct local \`agentId\` and the runtime agent to route to, e.g. useAgent({ agentId: "chat-1", runtimeAgentId: "${agentId ?? "default"}", threadId }).`);
298
+ if (runtimeAgentId != null && threadId == null) throw new Error(`useAgent: \`runtimeAgentId\` requires \`threadId\`. A proxied agent exists to scope a thread to a private instance; without a threadId it behaves like the shared agent while adding a registration and a local agentId to keep unique. Either pass the thread, e.g. useAgent({ agentId: "${agentId ?? "chat-1"}", runtimeAgentId: "${runtimeAgentId}", threadId }), or bind to the agent directly with useAgent({ agentId: "${runtimeAgentId}" }).`);
299
+ if (runtimeAgentId != null && agentId == null) throw new Error(`useAgent: \`runtimeAgentId\` requires an explicit \`agentId\`. The proxied agent is registered under \`agentId\`, and the usual fallbacks (chat configuration, then "${_copilotkit_shared.DEFAULT_AGENT_ID}") name agents that already exist — registering over one throws or shadows it. Pick a local id for this hook, e.g. useAgent({ agentId: "chat-1", runtimeAgentId: "${runtimeAgentId}", threadId }).`);
297
300
  const chatConfig = useCopilotChatConfiguration();
298
301
  const resolvedAgentId = agentId ?? chatConfig?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
299
302
  const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
@@ -301,7 +304,58 @@ function useAgent({ agentId, updates, throttleMs } = {}) {
301
304
  const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
302
305
  const updateFlags = (0, react.useMemo)(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
303
306
  const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
307
+ const [registeredProxyAgent, setRegisteredProxyAgent] = (0, react.useState)(null);
308
+ (0, react.useEffect)(() => {
309
+ if (runtimeAgentId == null) {
310
+ setRegisteredProxyAgent(null);
311
+ return;
312
+ }
313
+ const { agent: proxy, unregister } = copilotkit.registerProxiedAgent({
314
+ agentId: resolvedAgentId,
315
+ runtimeAgentId
316
+ });
317
+ provisionalAgentCache.current.delete(resolvedAgentId);
318
+ setRegisteredProxyAgent(proxy);
319
+ return () => {
320
+ unregister();
321
+ setRegisteredProxyAgent(null);
322
+ };
323
+ }, [
324
+ copilotkit,
325
+ resolvedAgentId,
326
+ runtimeAgentId
327
+ ]);
304
328
  const { agent, isReady } = (0, react.useMemo)(() => {
329
+ if (runtimeAgentId != null) {
330
+ if (registeredProxyAgent) {
331
+ provisionalAgentCache.current.delete(resolvedAgentId);
332
+ return {
333
+ agent: registeredProxyAgent,
334
+ isReady: true
335
+ };
336
+ }
337
+ const cached = provisionalAgentCache.current.get(resolvedAgentId);
338
+ if (cached) {
339
+ copilotkit.applyHeadersToAgent(cached);
340
+ return {
341
+ agent: cached,
342
+ isReady: false
343
+ };
344
+ }
345
+ const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
346
+ runtimeUrl: copilotkit.runtimeUrl,
347
+ agentId: resolvedAgentId,
348
+ runtimeAgentId,
349
+ transport: copilotkit.runtimeTransport,
350
+ runtimeMode: "pending"
351
+ });
352
+ copilotkit.applyHeadersToAgent(provisional);
353
+ provisionalAgentCache.current.set(resolvedAgentId, provisional);
354
+ return {
355
+ agent: provisional,
356
+ isReady: false
357
+ };
358
+ }
305
359
  const existing = copilotkit.getAgent(resolvedAgentId);
306
360
  if (existing) {
307
361
  provisionalAgentCache.current.delete(resolvedAgentId);
@@ -357,6 +411,8 @@ function useAgent({ agentId, updates, throttleMs } = {}) {
357
411
  throw new Error(`useAgent: Agent '${resolvedAgentId}' not found after runtime sync (${runtimePart}). ` + (knownAgents.length ? `Known agents: [${knownAgents.join(", ")}]` : "No agents registered.") + " Verify your runtime /info and/or agents__unsafe_dev_only.");
358
412
  }, [
359
413
  resolvedAgentId,
414
+ runtimeAgentId,
415
+ registeredProxyAgent,
360
416
  copilotkit.agents,
361
417
  copilotkit.runtimeConnectionStatus,
362
418
  copilotkit.runtimeUrl,
@@ -409,14 +465,11 @@ function useAgent({ agentId, updates, throttleMs } = {}) {
409
465
  ]);
410
466
  const configThreadId = chatConfig?.threadId;
411
467
  const configHasExplicitThreadId = chatConfig?.hasExplicitThreadId;
468
+ const resolvedThreadId = threadId ?? (configHasExplicitThreadId ? configThreadId : void 0);
412
469
  (0, react.useEffect)(() => {
413
- if (!configHasExplicitThreadId || !configThreadId) return;
414
- agent.threadId = configThreadId;
415
- }, [
416
- agent,
417
- configThreadId,
418
- configHasExplicitThreadId
419
- ]);
470
+ if (!resolvedThreadId) return;
471
+ agent.threadId = resolvedThreadId;
472
+ }, [agent, resolvedThreadId]);
420
473
  return {
421
474
  agent,
422
475
  isReady