@copilotkitnext/react 1.54.0-next.9 → 1.54.1-next.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/dist/hooks/index.cjs +1 -0
- package/dist/hooks/index.d.cts +2 -1
- package/dist/hooks/index.d.mts +2 -1
- package/dist/hooks/index.mjs +1 -0
- package/dist/hooks/use-agent.cjs +4 -2
- package/dist/hooks/use-agent.cjs.map +1 -1
- package/dist/hooks/use-agent.mjs +4 -2
- package/dist/hooks/use-agent.mjs.map +1 -1
- package/dist/hooks/use-threads.cjs +106 -0
- package/dist/hooks/use-threads.cjs.map +1 -0
- package/dist/hooks/use-threads.d.cts +114 -0
- package/dist/hooks/use-threads.d.cts.map +1 -0
- package/dist/hooks/use-threads.d.mts +114 -0
- package/dist/hooks/use-threads.d.mts.map +1 -0
- package/dist/hooks/use-threads.mjs +105 -0
- package/dist/hooks/use-threads.mjs.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +2 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +2 -1
- package/dist/index.umd.js +107 -2
- package/dist/index.umd.js.map +1 -1
- package/package.json +8 -7
package/dist/hooks/index.cjs
CHANGED
|
@@ -11,3 +11,4 @@ const require_use_agent_context = require('./use-agent-context.cjs');
|
|
|
11
11
|
const require_use_suggestions = require('./use-suggestions.cjs');
|
|
12
12
|
const require_use_configure_suggestions = require('./use-configure-suggestions.cjs');
|
|
13
13
|
const require_use_interrupt = require('./use-interrupt.cjs');
|
|
14
|
+
const require_use_threads = require('./use-threads.cjs');
|
package/dist/hooks/index.d.cts
CHANGED
|
@@ -10,4 +10,5 @@ import { UseAgentUpdate, useAgent } from "./use-agent.cjs";
|
|
|
10
10
|
import { AgentContextInput, JsonSerializable, useAgentContext } from "./use-agent-context.cjs";
|
|
11
11
|
import { useSuggestions } from "./use-suggestions.cjs";
|
|
12
12
|
import { useConfigureSuggestions } from "./use-configure-suggestions.cjs";
|
|
13
|
-
import { UseInterruptConfig, useInterrupt } from "./use-interrupt.cjs";
|
|
13
|
+
import { UseInterruptConfig, useInterrupt } from "./use-interrupt.cjs";
|
|
14
|
+
import { Thread, UseThreadsInput, UseThreadsResult, useThreads } from "./use-threads.cjs";
|
package/dist/hooks/index.d.mts
CHANGED
|
@@ -10,4 +10,5 @@ import { UseAgentUpdate, useAgent } from "./use-agent.mjs";
|
|
|
10
10
|
import { AgentContextInput, JsonSerializable, useAgentContext } from "./use-agent-context.mjs";
|
|
11
11
|
import { useSuggestions } from "./use-suggestions.mjs";
|
|
12
12
|
import { useConfigureSuggestions } from "./use-configure-suggestions.mjs";
|
|
13
|
-
import { UseInterruptConfig, useInterrupt } from "./use-interrupt.mjs";
|
|
13
|
+
import { UseInterruptConfig, useInterrupt } from "./use-interrupt.mjs";
|
|
14
|
+
import { Thread, UseThreadsInput, UseThreadsResult, useThreads } from "./use-threads.mjs";
|
package/dist/hooks/index.mjs
CHANGED
|
@@ -11,5 +11,6 @@ import { useAgentContext } from "./use-agent-context.mjs";
|
|
|
11
11
|
import { useSuggestions } from "./use-suggestions.mjs";
|
|
12
12
|
import { useConfigureSuggestions } from "./use-configure-suggestions.mjs";
|
|
13
13
|
import { useInterrupt } from "./use-interrupt.mjs";
|
|
14
|
+
import { useThreads } from "./use-threads.mjs";
|
|
14
15
|
|
|
15
16
|
export { };
|
package/dist/hooks/use-agent.cjs
CHANGED
|
@@ -39,7 +39,8 @@ function useAgent({ agentId, updates } = {}) {
|
|
|
39
39
|
const provisional = new _copilotkitnext_core.ProxiedCopilotRuntimeAgent({
|
|
40
40
|
runtimeUrl: copilotkit.runtimeUrl,
|
|
41
41
|
agentId,
|
|
42
|
-
transport: copilotkit.runtimeTransport
|
|
42
|
+
transport: copilotkit.runtimeTransport,
|
|
43
|
+
runtimeMode: "pending"
|
|
43
44
|
});
|
|
44
45
|
provisional.headers = { ...copilotkit.headers };
|
|
45
46
|
provisionalAgentCache.current.set(agentId, provisional);
|
|
@@ -49,7 +50,8 @@ function useAgent({ agentId, updates } = {}) {
|
|
|
49
50
|
const provisional = new _copilotkitnext_core.ProxiedCopilotRuntimeAgent({
|
|
50
51
|
runtimeUrl: copilotkit.runtimeUrl,
|
|
51
52
|
agentId,
|
|
52
|
-
transport: copilotkit.runtimeTransport
|
|
53
|
+
transport: copilotkit.runtimeTransport,
|
|
54
|
+
runtimeMode: "pending"
|
|
53
55
|
});
|
|
54
56
|
provisional.headers = { ...copilotkit.headers };
|
|
55
57
|
return provisional;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-agent.cjs","names":["DEFAULT_AGENT_ID","useCopilotKit","CopilotKitCoreRuntimeConnectionStatus","ProxiedCopilotRuntimeAgent"],"sources":["../../src/hooks/use-agent.tsx"],"sourcesContent":["import { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useMemo, useEffect, useReducer, useRef } from \"react\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkitnext/shared\";\nimport { AbstractAgent } from \"@ag-ui/client\";\nimport {\n ProxiedCopilotRuntimeAgent,\n CopilotKitCoreRuntimeConnectionStatus,\n} from \"@copilotkitnext/core\";\n\nexport enum UseAgentUpdate {\n OnMessagesChanged = \"OnMessagesChanged\",\n OnStateChanged = \"OnStateChanged\",\n OnRunStatusChanged = \"OnRunStatusChanged\",\n}\n\nconst ALL_UPDATES: UseAgentUpdate[] = [\n UseAgentUpdate.OnMessagesChanged,\n UseAgentUpdate.OnStateChanged,\n UseAgentUpdate.OnRunStatusChanged,\n];\n\nexport interface UseAgentProps {\n agentId?: string;\n updates?: UseAgentUpdate[];\n}\n\nexport function useAgent({ agentId, updates }: UseAgentProps = {}) {\n agentId ??= DEFAULT_AGENT_ID;\n\n const { copilotkit } = useCopilotKit();\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n const updateFlags = useMemo(\n () => updates ?? ALL_UPDATES,\n [JSON.stringify(updates)],\n );\n\n // Cache provisional agents to avoid creating new references on every render\n // while the runtime is still connecting. A new reference would cascade into\n // CopilotChat's connectAgent effect, causing unnecessary HTTP calls.\n const provisionalAgentCache = useRef<Map<string, ProxiedCopilotRuntimeAgent>>(\n new Map(),\n );\n\n const agent: AbstractAgent = useMemo(() => {\n const existing = copilotkit.getAgent(agentId);\n if (existing) {\n // Real agent found — clear any cached provisional for this ID\n provisionalAgentCache.current.delete(agentId);\n return existing;\n }\n\n const isRuntimeConfigured = copilotkit.runtimeUrl !== undefined;\n const status = copilotkit.runtimeConnectionStatus;\n\n // While runtime is not yet synced, return a provisional runtime agent\n if (\n isRuntimeConfigured &&\n (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected ||\n status === CopilotKitCoreRuntimeConnectionStatus.Connecting)\n ) {\n // Return cached provisional if available (keeps reference stable)\n const cached = provisionalAgentCache.current.get(agentId);\n if (cached) {\n // Update headers on the cached agent in case they changed\n cached.headers = { ...copilotkit.headers };\n return cached;\n }\n\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n });\n // Apply current headers so runs/connects inherit them\n provisional.headers = { ...copilotkit.headers };\n provisionalAgentCache.current.set(agentId, provisional);\n return provisional;\n }\n\n // Runtime is in Error state — return a provisional agent instead of throwing.\n // The error has already been emitted through the subscriber system\n // (RUNTIME_INFO_FETCH_FAILED). Throwing here would crash the React tree;\n // returning a provisional agent lets onError handlers fire while keeping\n // the app alive.\n if (\n isRuntimeConfigured &&\n status === CopilotKitCoreRuntimeConnectionStatus.Error\n ) {\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n });\n provisional.headers = { ...copilotkit.headers };\n return provisional;\n }\n\n // No runtime configured and agent doesn't exist — this is a configuration error.\n const knownAgents = Object.keys(copilotkit.agents ?? {});\n const runtimePart = isRuntimeConfigured\n ? `runtimeUrl=${copilotkit.runtimeUrl}`\n : \"no runtimeUrl\";\n throw new Error(\n `useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` +\n (knownAgents.length\n ? `Known agents: [${knownAgents.join(\", \")}]`\n : \"No agents registered.\") +\n \" Verify your runtime /info and/or agents__unsafe_dev_only.\",\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n agentId,\n copilotkit.agents,\n copilotkit.runtimeConnectionStatus,\n copilotkit.runtimeUrl,\n copilotkit.runtimeTransport,\n JSON.stringify(copilotkit.headers),\n ]);\n\n useEffect(() => {\n if (updateFlags.length === 0) {\n return;\n }\n\n const handlers: Parameters<AbstractAgent[\"subscribe\"]>[0] = {};\n\n if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {\n // Content stripping for immutableContent renderers is handled by CopilotKitCoreReact\n handlers.onMessagesChanged = () => {\n forceUpdate();\n };\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) {\n handlers.onStateChanged = forceUpdate;\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {\n handlers.onRunInitialized = forceUpdate;\n handlers.onRunFinalized = forceUpdate;\n handlers.onRunFailed = forceUpdate;\n }\n\n const subscription = agent.subscribe(handlers);\n return () => subscription.unsubscribe();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, forceUpdate, JSON.stringify(updateFlags)]);\n\n return {\n agent,\n };\n}\n"],"mappings":";;;;;;;AASA,IAAY,0DAAL;AACL;AACA;AACA;;;AAGF,MAAM,cAAgC;CACpC,eAAe;CACf,eAAe;CACf,eAAe;CAChB;AAOD,SAAgB,SAAS,EAAE,SAAS,YAA2B,EAAE,EAAE;AACjE,aAAYA;CAEZ,MAAM,EAAE,eAAeC,0CAAe;CACtC,MAAM,GAAG,sCAA2B,MAAM,IAAI,GAAG,EAAE;CAEnD,MAAM,uCACE,WAAW,aACjB,CAAC,KAAK,UAAU,QAAQ,CAAC,CAC1B;CAKD,MAAM,0DACJ,IAAI,KAAK,CACV;CAED,MAAM,iCAAqC;EACzC,MAAM,WAAW,WAAW,SAAS,QAAQ;AAC7C,MAAI,UAAU;AAEZ,yBAAsB,QAAQ,OAAO,QAAQ;AAC7C,UAAO;;EAGT,MAAM,sBAAsB,WAAW,eAAe;EACtD,MAAM,SAAS,WAAW;AAG1B,MACE,wBACC,WAAWC,2DAAsC,gBAChD,WAAWA,2DAAsC,aACnD;GAEA,MAAM,SAAS,sBAAsB,QAAQ,IAAI,QAAQ;AACzD,OAAI,QAAQ;AAEV,WAAO,UAAU,EAAE,GAAG,WAAW,SAAS;AAC1C,WAAO;;GAGT,MAAM,cAAc,IAAIC,gDAA2B;IACjD,YAAY,WAAW;IACvB;IACA,WAAW,WAAW;
|
|
1
|
+
{"version":3,"file":"use-agent.cjs","names":["DEFAULT_AGENT_ID","useCopilotKit","CopilotKitCoreRuntimeConnectionStatus","ProxiedCopilotRuntimeAgent"],"sources":["../../src/hooks/use-agent.tsx"],"sourcesContent":["import { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useMemo, useEffect, useReducer, useRef } from \"react\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkitnext/shared\";\nimport { AbstractAgent } from \"@ag-ui/client\";\nimport {\n ProxiedCopilotRuntimeAgent,\n CopilotKitCoreRuntimeConnectionStatus,\n} from \"@copilotkitnext/core\";\n\nexport enum UseAgentUpdate {\n OnMessagesChanged = \"OnMessagesChanged\",\n OnStateChanged = \"OnStateChanged\",\n OnRunStatusChanged = \"OnRunStatusChanged\",\n}\n\nconst ALL_UPDATES: UseAgentUpdate[] = [\n UseAgentUpdate.OnMessagesChanged,\n UseAgentUpdate.OnStateChanged,\n UseAgentUpdate.OnRunStatusChanged,\n];\n\nexport interface UseAgentProps {\n agentId?: string;\n updates?: UseAgentUpdate[];\n}\n\nexport function useAgent({ agentId, updates }: UseAgentProps = {}) {\n agentId ??= DEFAULT_AGENT_ID;\n\n const { copilotkit } = useCopilotKit();\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n const updateFlags = useMemo(\n () => updates ?? ALL_UPDATES,\n [JSON.stringify(updates)],\n );\n\n // Cache provisional agents to avoid creating new references on every render\n // while the runtime is still connecting. A new reference would cascade into\n // CopilotChat's connectAgent effect, causing unnecessary HTTP calls.\n const provisionalAgentCache = useRef<Map<string, ProxiedCopilotRuntimeAgent>>(\n new Map(),\n );\n\n const agent: AbstractAgent = useMemo(() => {\n const existing = copilotkit.getAgent(agentId);\n if (existing) {\n // Real agent found — clear any cached provisional for this ID\n provisionalAgentCache.current.delete(agentId);\n return existing;\n }\n\n const isRuntimeConfigured = copilotkit.runtimeUrl !== undefined;\n const status = copilotkit.runtimeConnectionStatus;\n\n // While runtime is not yet synced, return a provisional runtime agent\n if (\n isRuntimeConfigured &&\n (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected ||\n status === CopilotKitCoreRuntimeConnectionStatus.Connecting)\n ) {\n // Return cached provisional if available (keeps reference stable)\n const cached = provisionalAgentCache.current.get(agentId);\n if (cached) {\n // Update headers on the cached agent in case they changed\n cached.headers = { ...copilotkit.headers };\n return cached;\n }\n\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n runtimeMode: \"pending\",\n });\n // Apply current headers so runs/connects inherit them\n provisional.headers = { ...copilotkit.headers };\n provisionalAgentCache.current.set(agentId, provisional);\n return provisional;\n }\n\n // Runtime is in Error state — return a provisional agent instead of throwing.\n // The error has already been emitted through the subscriber system\n // (RUNTIME_INFO_FETCH_FAILED). Throwing here would crash the React tree;\n // returning a provisional agent lets onError handlers fire while keeping\n // the app alive.\n if (\n isRuntimeConfigured &&\n status === CopilotKitCoreRuntimeConnectionStatus.Error\n ) {\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n runtimeMode: \"pending\",\n });\n provisional.headers = { ...copilotkit.headers };\n return provisional;\n }\n\n // No runtime configured and agent doesn't exist — this is a configuration error.\n const knownAgents = Object.keys(copilotkit.agents ?? {});\n const runtimePart = isRuntimeConfigured\n ? `runtimeUrl=${copilotkit.runtimeUrl}`\n : \"no runtimeUrl\";\n throw new Error(\n `useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` +\n (knownAgents.length\n ? `Known agents: [${knownAgents.join(\", \")}]`\n : \"No agents registered.\") +\n \" Verify your runtime /info and/or agents__unsafe_dev_only.\",\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n agentId,\n copilotkit.agents,\n copilotkit.runtimeConnectionStatus,\n copilotkit.runtimeUrl,\n copilotkit.runtimeTransport,\n JSON.stringify(copilotkit.headers),\n ]);\n\n useEffect(() => {\n if (updateFlags.length === 0) {\n return;\n }\n\n const handlers: Parameters<AbstractAgent[\"subscribe\"]>[0] = {};\n\n if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {\n // Content stripping for immutableContent renderers is handled by CopilotKitCoreReact\n handlers.onMessagesChanged = () => {\n forceUpdate();\n };\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) {\n handlers.onStateChanged = forceUpdate;\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {\n handlers.onRunInitialized = forceUpdate;\n handlers.onRunFinalized = forceUpdate;\n handlers.onRunFailed = forceUpdate;\n }\n\n const subscription = agent.subscribe(handlers);\n return () => subscription.unsubscribe();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, forceUpdate, JSON.stringify(updateFlags)]);\n\n return {\n agent,\n };\n}\n"],"mappings":";;;;;;;AASA,IAAY,0DAAL;AACL;AACA;AACA;;;AAGF,MAAM,cAAgC;CACpC,eAAe;CACf,eAAe;CACf,eAAe;CAChB;AAOD,SAAgB,SAAS,EAAE,SAAS,YAA2B,EAAE,EAAE;AACjE,aAAYA;CAEZ,MAAM,EAAE,eAAeC,0CAAe;CACtC,MAAM,GAAG,sCAA2B,MAAM,IAAI,GAAG,EAAE;CAEnD,MAAM,uCACE,WAAW,aACjB,CAAC,KAAK,UAAU,QAAQ,CAAC,CAC1B;CAKD,MAAM,0DACJ,IAAI,KAAK,CACV;CAED,MAAM,iCAAqC;EACzC,MAAM,WAAW,WAAW,SAAS,QAAQ;AAC7C,MAAI,UAAU;AAEZ,yBAAsB,QAAQ,OAAO,QAAQ;AAC7C,UAAO;;EAGT,MAAM,sBAAsB,WAAW,eAAe;EACtD,MAAM,SAAS,WAAW;AAG1B,MACE,wBACC,WAAWC,2DAAsC,gBAChD,WAAWA,2DAAsC,aACnD;GAEA,MAAM,SAAS,sBAAsB,QAAQ,IAAI,QAAQ;AACzD,OAAI,QAAQ;AAEV,WAAO,UAAU,EAAE,GAAG,WAAW,SAAS;AAC1C,WAAO;;GAGT,MAAM,cAAc,IAAIC,gDAA2B;IACjD,YAAY,WAAW;IACvB;IACA,WAAW,WAAW;IACtB,aAAa;IACd,CAAC;AAEF,eAAY,UAAU,EAAE,GAAG,WAAW,SAAS;AAC/C,yBAAsB,QAAQ,IAAI,SAAS,YAAY;AACvD,UAAO;;AAQT,MACE,uBACA,WAAWD,2DAAsC,OACjD;GACA,MAAM,cAAc,IAAIC,gDAA2B;IACjD,YAAY,WAAW;IACvB;IACA,WAAW,WAAW;IACtB,aAAa;IACd,CAAC;AACF,eAAY,UAAU,EAAE,GAAG,WAAW,SAAS;AAC/C,UAAO;;EAIT,MAAM,cAAc,OAAO,KAAK,WAAW,UAAU,EAAE,CAAC;EACxD,MAAM,cAAc,sBAChB,cAAc,WAAW,eACzB;AACJ,QAAM,IAAI,MACR,oBAAoB,QAAQ,kCAAkC,YAAY,QACvE,YAAY,SACT,kBAAkB,YAAY,KAAK,KAAK,CAAC,KACzC,2BACJ,6DACH;IAEA;EACD;EACA,WAAW;EACX,WAAW;EACX,WAAW;EACX,WAAW;EACX,KAAK,UAAU,WAAW,QAAQ;EACnC,CAAC;AAEF,4BAAgB;AACd,MAAI,YAAY,WAAW,EACzB;EAGF,MAAM,WAAsD,EAAE;AAE9D,MAAI,YAAY,SAAS,eAAe,kBAAkB,CAExD,UAAS,0BAA0B;AACjC,gBAAa;;AAIjB,MAAI,YAAY,SAAS,eAAe,eAAe,CACrD,UAAS,iBAAiB;AAG5B,MAAI,YAAY,SAAS,eAAe,mBAAmB,EAAE;AAC3D,YAAS,mBAAmB;AAC5B,YAAS,iBAAiB;AAC1B,YAAS,cAAc;;EAGzB,MAAM,eAAe,MAAM,UAAU,SAAS;AAC9C,eAAa,aAAa,aAAa;IAEtC;EAAC;EAAO;EAAa,KAAK,UAAU,YAAY;EAAC,CAAC;AAErD,QAAO,EACL,OACD"}
|
package/dist/hooks/use-agent.mjs
CHANGED
|
@@ -38,7 +38,8 @@ function useAgent({ agentId, updates } = {}) {
|
|
|
38
38
|
const provisional = new ProxiedCopilotRuntimeAgent({
|
|
39
39
|
runtimeUrl: copilotkit.runtimeUrl,
|
|
40
40
|
agentId,
|
|
41
|
-
transport: copilotkit.runtimeTransport
|
|
41
|
+
transport: copilotkit.runtimeTransport,
|
|
42
|
+
runtimeMode: "pending"
|
|
42
43
|
});
|
|
43
44
|
provisional.headers = { ...copilotkit.headers };
|
|
44
45
|
provisionalAgentCache.current.set(agentId, provisional);
|
|
@@ -48,7 +49,8 @@ function useAgent({ agentId, updates } = {}) {
|
|
|
48
49
|
const provisional = new ProxiedCopilotRuntimeAgent({
|
|
49
50
|
runtimeUrl: copilotkit.runtimeUrl,
|
|
50
51
|
agentId,
|
|
51
|
-
transport: copilotkit.runtimeTransport
|
|
52
|
+
transport: copilotkit.runtimeTransport,
|
|
53
|
+
runtimeMode: "pending"
|
|
52
54
|
});
|
|
53
55
|
provisional.headers = { ...copilotkit.headers };
|
|
54
56
|
return provisional;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-agent.mjs","names":[],"sources":["../../src/hooks/use-agent.tsx"],"sourcesContent":["import { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useMemo, useEffect, useReducer, useRef } from \"react\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkitnext/shared\";\nimport { AbstractAgent } from \"@ag-ui/client\";\nimport {\n ProxiedCopilotRuntimeAgent,\n CopilotKitCoreRuntimeConnectionStatus,\n} from \"@copilotkitnext/core\";\n\nexport enum UseAgentUpdate {\n OnMessagesChanged = \"OnMessagesChanged\",\n OnStateChanged = \"OnStateChanged\",\n OnRunStatusChanged = \"OnRunStatusChanged\",\n}\n\nconst ALL_UPDATES: UseAgentUpdate[] = [\n UseAgentUpdate.OnMessagesChanged,\n UseAgentUpdate.OnStateChanged,\n UseAgentUpdate.OnRunStatusChanged,\n];\n\nexport interface UseAgentProps {\n agentId?: string;\n updates?: UseAgentUpdate[];\n}\n\nexport function useAgent({ agentId, updates }: UseAgentProps = {}) {\n agentId ??= DEFAULT_AGENT_ID;\n\n const { copilotkit } = useCopilotKit();\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n const updateFlags = useMemo(\n () => updates ?? ALL_UPDATES,\n [JSON.stringify(updates)],\n );\n\n // Cache provisional agents to avoid creating new references on every render\n // while the runtime is still connecting. A new reference would cascade into\n // CopilotChat's connectAgent effect, causing unnecessary HTTP calls.\n const provisionalAgentCache = useRef<Map<string, ProxiedCopilotRuntimeAgent>>(\n new Map(),\n );\n\n const agent: AbstractAgent = useMemo(() => {\n const existing = copilotkit.getAgent(agentId);\n if (existing) {\n // Real agent found — clear any cached provisional for this ID\n provisionalAgentCache.current.delete(agentId);\n return existing;\n }\n\n const isRuntimeConfigured = copilotkit.runtimeUrl !== undefined;\n const status = copilotkit.runtimeConnectionStatus;\n\n // While runtime is not yet synced, return a provisional runtime agent\n if (\n isRuntimeConfigured &&\n (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected ||\n status === CopilotKitCoreRuntimeConnectionStatus.Connecting)\n ) {\n // Return cached provisional if available (keeps reference stable)\n const cached = provisionalAgentCache.current.get(agentId);\n if (cached) {\n // Update headers on the cached agent in case they changed\n cached.headers = { ...copilotkit.headers };\n return cached;\n }\n\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n });\n // Apply current headers so runs/connects inherit them\n provisional.headers = { ...copilotkit.headers };\n provisionalAgentCache.current.set(agentId, provisional);\n return provisional;\n }\n\n // Runtime is in Error state — return a provisional agent instead of throwing.\n // The error has already been emitted through the subscriber system\n // (RUNTIME_INFO_FETCH_FAILED). Throwing here would crash the React tree;\n // returning a provisional agent lets onError handlers fire while keeping\n // the app alive.\n if (\n isRuntimeConfigured &&\n status === CopilotKitCoreRuntimeConnectionStatus.Error\n ) {\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n });\n provisional.headers = { ...copilotkit.headers };\n return provisional;\n }\n\n // No runtime configured and agent doesn't exist — this is a configuration error.\n const knownAgents = Object.keys(copilotkit.agents ?? {});\n const runtimePart = isRuntimeConfigured\n ? `runtimeUrl=${copilotkit.runtimeUrl}`\n : \"no runtimeUrl\";\n throw new Error(\n `useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` +\n (knownAgents.length\n ? `Known agents: [${knownAgents.join(\", \")}]`\n : \"No agents registered.\") +\n \" Verify your runtime /info and/or agents__unsafe_dev_only.\",\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n agentId,\n copilotkit.agents,\n copilotkit.runtimeConnectionStatus,\n copilotkit.runtimeUrl,\n copilotkit.runtimeTransport,\n JSON.stringify(copilotkit.headers),\n ]);\n\n useEffect(() => {\n if (updateFlags.length === 0) {\n return;\n }\n\n const handlers: Parameters<AbstractAgent[\"subscribe\"]>[0] = {};\n\n if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {\n // Content stripping for immutableContent renderers is handled by CopilotKitCoreReact\n handlers.onMessagesChanged = () => {\n forceUpdate();\n };\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) {\n handlers.onStateChanged = forceUpdate;\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {\n handlers.onRunInitialized = forceUpdate;\n handlers.onRunFinalized = forceUpdate;\n handlers.onRunFailed = forceUpdate;\n }\n\n const subscription = agent.subscribe(handlers);\n return () => subscription.unsubscribe();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, forceUpdate, JSON.stringify(updateFlags)]);\n\n return {\n agent,\n };\n}\n"],"mappings":";;;;;;AASA,IAAY,0DAAL;AACL;AACA;AACA;;;AAGF,MAAM,cAAgC;CACpC,eAAe;CACf,eAAe;CACf,eAAe;CAChB;AAOD,SAAgB,SAAS,EAAE,SAAS,YAA2B,EAAE,EAAE;AACjE,aAAY;CAEZ,MAAM,EAAE,eAAe,eAAe;CACtC,MAAM,GAAG,eAAe,YAAY,MAAM,IAAI,GAAG,EAAE;CAEnD,MAAM,cAAc,cACZ,WAAW,aACjB,CAAC,KAAK,UAAU,QAAQ,CAAC,CAC1B;CAKD,MAAM,wBAAwB,uBAC5B,IAAI,KAAK,CACV;CAED,MAAM,QAAuB,cAAc;EACzC,MAAM,WAAW,WAAW,SAAS,QAAQ;AAC7C,MAAI,UAAU;AAEZ,yBAAsB,QAAQ,OAAO,QAAQ;AAC7C,UAAO;;EAGT,MAAM,sBAAsB,WAAW,eAAe;EACtD,MAAM,SAAS,WAAW;AAG1B,MACE,wBACC,WAAW,sCAAsC,gBAChD,WAAW,sCAAsC,aACnD;GAEA,MAAM,SAAS,sBAAsB,QAAQ,IAAI,QAAQ;AACzD,OAAI,QAAQ;AAEV,WAAO,UAAU,EAAE,GAAG,WAAW,SAAS;AAC1C,WAAO;;GAGT,MAAM,cAAc,IAAI,2BAA2B;IACjD,YAAY,WAAW;IACvB;IACA,WAAW,WAAW;
|
|
1
|
+
{"version":3,"file":"use-agent.mjs","names":[],"sources":["../../src/hooks/use-agent.tsx"],"sourcesContent":["import { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useMemo, useEffect, useReducer, useRef } from \"react\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkitnext/shared\";\nimport { AbstractAgent } from \"@ag-ui/client\";\nimport {\n ProxiedCopilotRuntimeAgent,\n CopilotKitCoreRuntimeConnectionStatus,\n} from \"@copilotkitnext/core\";\n\nexport enum UseAgentUpdate {\n OnMessagesChanged = \"OnMessagesChanged\",\n OnStateChanged = \"OnStateChanged\",\n OnRunStatusChanged = \"OnRunStatusChanged\",\n}\n\nconst ALL_UPDATES: UseAgentUpdate[] = [\n UseAgentUpdate.OnMessagesChanged,\n UseAgentUpdate.OnStateChanged,\n UseAgentUpdate.OnRunStatusChanged,\n];\n\nexport interface UseAgentProps {\n agentId?: string;\n updates?: UseAgentUpdate[];\n}\n\nexport function useAgent({ agentId, updates }: UseAgentProps = {}) {\n agentId ??= DEFAULT_AGENT_ID;\n\n const { copilotkit } = useCopilotKit();\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n const updateFlags = useMemo(\n () => updates ?? ALL_UPDATES,\n [JSON.stringify(updates)],\n );\n\n // Cache provisional agents to avoid creating new references on every render\n // while the runtime is still connecting. A new reference would cascade into\n // CopilotChat's connectAgent effect, causing unnecessary HTTP calls.\n const provisionalAgentCache = useRef<Map<string, ProxiedCopilotRuntimeAgent>>(\n new Map(),\n );\n\n const agent: AbstractAgent = useMemo(() => {\n const existing = copilotkit.getAgent(agentId);\n if (existing) {\n // Real agent found — clear any cached provisional for this ID\n provisionalAgentCache.current.delete(agentId);\n return existing;\n }\n\n const isRuntimeConfigured = copilotkit.runtimeUrl !== undefined;\n const status = copilotkit.runtimeConnectionStatus;\n\n // While runtime is not yet synced, return a provisional runtime agent\n if (\n isRuntimeConfigured &&\n (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected ||\n status === CopilotKitCoreRuntimeConnectionStatus.Connecting)\n ) {\n // Return cached provisional if available (keeps reference stable)\n const cached = provisionalAgentCache.current.get(agentId);\n if (cached) {\n // Update headers on the cached agent in case they changed\n cached.headers = { ...copilotkit.headers };\n return cached;\n }\n\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n runtimeMode: \"pending\",\n });\n // Apply current headers so runs/connects inherit them\n provisional.headers = { ...copilotkit.headers };\n provisionalAgentCache.current.set(agentId, provisional);\n return provisional;\n }\n\n // Runtime is in Error state — return a provisional agent instead of throwing.\n // The error has already been emitted through the subscriber system\n // (RUNTIME_INFO_FETCH_FAILED). Throwing here would crash the React tree;\n // returning a provisional agent lets onError handlers fire while keeping\n // the app alive.\n if (\n isRuntimeConfigured &&\n status === CopilotKitCoreRuntimeConnectionStatus.Error\n ) {\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n runtimeMode: \"pending\",\n });\n provisional.headers = { ...copilotkit.headers };\n return provisional;\n }\n\n // No runtime configured and agent doesn't exist — this is a configuration error.\n const knownAgents = Object.keys(copilotkit.agents ?? {});\n const runtimePart = isRuntimeConfigured\n ? `runtimeUrl=${copilotkit.runtimeUrl}`\n : \"no runtimeUrl\";\n throw new Error(\n `useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` +\n (knownAgents.length\n ? `Known agents: [${knownAgents.join(\", \")}]`\n : \"No agents registered.\") +\n \" Verify your runtime /info and/or agents__unsafe_dev_only.\",\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n agentId,\n copilotkit.agents,\n copilotkit.runtimeConnectionStatus,\n copilotkit.runtimeUrl,\n copilotkit.runtimeTransport,\n JSON.stringify(copilotkit.headers),\n ]);\n\n useEffect(() => {\n if (updateFlags.length === 0) {\n return;\n }\n\n const handlers: Parameters<AbstractAgent[\"subscribe\"]>[0] = {};\n\n if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {\n // Content stripping for immutableContent renderers is handled by CopilotKitCoreReact\n handlers.onMessagesChanged = () => {\n forceUpdate();\n };\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) {\n handlers.onStateChanged = forceUpdate;\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {\n handlers.onRunInitialized = forceUpdate;\n handlers.onRunFinalized = forceUpdate;\n handlers.onRunFailed = forceUpdate;\n }\n\n const subscription = agent.subscribe(handlers);\n return () => subscription.unsubscribe();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, forceUpdate, JSON.stringify(updateFlags)]);\n\n return {\n agent,\n };\n}\n"],"mappings":";;;;;;AASA,IAAY,0DAAL;AACL;AACA;AACA;;;AAGF,MAAM,cAAgC;CACpC,eAAe;CACf,eAAe;CACf,eAAe;CAChB;AAOD,SAAgB,SAAS,EAAE,SAAS,YAA2B,EAAE,EAAE;AACjE,aAAY;CAEZ,MAAM,EAAE,eAAe,eAAe;CACtC,MAAM,GAAG,eAAe,YAAY,MAAM,IAAI,GAAG,EAAE;CAEnD,MAAM,cAAc,cACZ,WAAW,aACjB,CAAC,KAAK,UAAU,QAAQ,CAAC,CAC1B;CAKD,MAAM,wBAAwB,uBAC5B,IAAI,KAAK,CACV;CAED,MAAM,QAAuB,cAAc;EACzC,MAAM,WAAW,WAAW,SAAS,QAAQ;AAC7C,MAAI,UAAU;AAEZ,yBAAsB,QAAQ,OAAO,QAAQ;AAC7C,UAAO;;EAGT,MAAM,sBAAsB,WAAW,eAAe;EACtD,MAAM,SAAS,WAAW;AAG1B,MACE,wBACC,WAAW,sCAAsC,gBAChD,WAAW,sCAAsC,aACnD;GAEA,MAAM,SAAS,sBAAsB,QAAQ,IAAI,QAAQ;AACzD,OAAI,QAAQ;AAEV,WAAO,UAAU,EAAE,GAAG,WAAW,SAAS;AAC1C,WAAO;;GAGT,MAAM,cAAc,IAAI,2BAA2B;IACjD,YAAY,WAAW;IACvB;IACA,WAAW,WAAW;IACtB,aAAa;IACd,CAAC;AAEF,eAAY,UAAU,EAAE,GAAG,WAAW,SAAS;AAC/C,yBAAsB,QAAQ,IAAI,SAAS,YAAY;AACvD,UAAO;;AAQT,MACE,uBACA,WAAW,sCAAsC,OACjD;GACA,MAAM,cAAc,IAAI,2BAA2B;IACjD,YAAY,WAAW;IACvB;IACA,WAAW,WAAW;IACtB,aAAa;IACd,CAAC;AACF,eAAY,UAAU,EAAE,GAAG,WAAW,SAAS;AAC/C,UAAO;;EAIT,MAAM,cAAc,OAAO,KAAK,WAAW,UAAU,EAAE,CAAC;EACxD,MAAM,cAAc,sBAChB,cAAc,WAAW,eACzB;AACJ,QAAM,IAAI,MACR,oBAAoB,QAAQ,kCAAkC,YAAY,QACvE,YAAY,SACT,kBAAkB,YAAY,KAAK,KAAK,CAAC,KACzC,2BACJ,6DACH;IAEA;EACD;EACA,WAAW;EACX,WAAW;EACX,WAAW;EACX,WAAW;EACX,KAAK,UAAU,WAAW,QAAQ;EACnC,CAAC;AAEF,iBAAgB;AACd,MAAI,YAAY,WAAW,EACzB;EAGF,MAAM,WAAsD,EAAE;AAE9D,MAAI,YAAY,SAAS,eAAe,kBAAkB,CAExD,UAAS,0BAA0B;AACjC,gBAAa;;AAIjB,MAAI,YAAY,SAAS,eAAe,eAAe,CACrD,UAAS,iBAAiB;AAG5B,MAAI,YAAY,SAAS,eAAe,mBAAmB,EAAE;AAC3D,YAAS,mBAAmB;AAC5B,YAAS,iBAAiB;AAC1B,YAAS,cAAc;;EAGzB,MAAM,eAAe,MAAM,UAAU,SAAS;AAC9C,eAAa,aAAa,aAAa;IAEtC;EAAC;EAAO;EAAa,KAAK,UAAU,YAAY;EAAC,CAAC;AAErD,QAAO,EACL,OACD"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
2
|
+
const require_CopilotKitProvider = require('../providers/CopilotKitProvider.cjs');
|
|
3
|
+
let react = require("react");
|
|
4
|
+
let _copilotkitnext_core = require("@copilotkitnext/core");
|
|
5
|
+
|
|
6
|
+
//#region src/hooks/use-threads.tsx
|
|
7
|
+
function useThreadStoreSelector(store, selector) {
|
|
8
|
+
return (0, react.useSyncExternalStore)((0, react.useCallback)((onStoreChange) => {
|
|
9
|
+
const subscription = store.select(selector).subscribe(onStoreChange);
|
|
10
|
+
return () => subscription.unsubscribe();
|
|
11
|
+
}, [store, selector]), () => selector(store.getState()));
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* React hook for listing and managing Intelligence platform threads.
|
|
15
|
+
*
|
|
16
|
+
* On mount the hook fetches the thread list for the given `userId`/`agentId`
|
|
17
|
+
* pair. When the Intelligence platform exposes a WebSocket URL, it also opens
|
|
18
|
+
* a realtime subscription so the `threads` array stays current without
|
|
19
|
+
* polling — thread creates, renames, archives, and deletes from any client
|
|
20
|
+
* are reflected immediately.
|
|
21
|
+
*
|
|
22
|
+
* Mutation methods (`renameThread`, `archiveThread`, `deleteThread`) return
|
|
23
|
+
* promises that resolve once the platform confirms the operation and reject
|
|
24
|
+
* with an `Error` on failure.
|
|
25
|
+
*
|
|
26
|
+
* @param input - User and agent identifiers that scope the thread list.
|
|
27
|
+
* @returns Thread list state and stable mutation callbacks.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* import { useThreads } from "@copilotkitnext/react";
|
|
32
|
+
*
|
|
33
|
+
* function ThreadList() {
|
|
34
|
+
* const { threads, isLoading, renameThread, deleteThread } = useThreads({
|
|
35
|
+
* userId: "user-1",
|
|
36
|
+
* agentId: "agent-1",
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* if (isLoading) return <p>Loading…</p>;
|
|
40
|
+
*
|
|
41
|
+
* return (
|
|
42
|
+
* <ul>
|
|
43
|
+
* {threads.map((t) => (
|
|
44
|
+
* <li key={t.id}>
|
|
45
|
+
* {t.name ?? "Untitled"}
|
|
46
|
+
* <button onClick={() => renameThread(t.id, "New name")}>Rename</button>
|
|
47
|
+
* <button onClick={() => deleteThread(t.id)}>Delete</button>
|
|
48
|
+
* </li>
|
|
49
|
+
* ))}
|
|
50
|
+
* </ul>
|
|
51
|
+
* );
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
function useThreads({ userId, agentId }) {
|
|
56
|
+
const { copilotkit } = require_CopilotKitProvider.useCopilotKit();
|
|
57
|
+
const [store] = (0, react.useState)(() => (0, _copilotkitnext_core.ɵcreateThreadStore)({ fetch: globalThis.fetch }));
|
|
58
|
+
const threads = useThreadStoreSelector(store, _copilotkitnext_core.ɵselectThreads);
|
|
59
|
+
const storeIsLoading = useThreadStoreSelector(store, _copilotkitnext_core.ɵselectThreadsIsLoading);
|
|
60
|
+
const storeError = useThreadStoreSelector(store, _copilotkitnext_core.ɵselectThreadsError);
|
|
61
|
+
const headersKey = (0, react.useMemo)(() => {
|
|
62
|
+
return JSON.stringify(Object.entries(copilotkit.headers ?? {}).sort(([left], [right]) => left.localeCompare(right)));
|
|
63
|
+
}, [copilotkit.headers]);
|
|
64
|
+
const runtimeError = (0, react.useMemo)(() => {
|
|
65
|
+
if (copilotkit.runtimeUrl) return null;
|
|
66
|
+
return /* @__PURE__ */ new Error("Runtime URL is not configured");
|
|
67
|
+
}, [copilotkit.runtimeUrl]);
|
|
68
|
+
const isLoading = runtimeError ? false : storeIsLoading;
|
|
69
|
+
const error = runtimeError ?? storeError;
|
|
70
|
+
(0, react.useEffect)(() => {
|
|
71
|
+
store.start();
|
|
72
|
+
return () => {
|
|
73
|
+
store.stop();
|
|
74
|
+
};
|
|
75
|
+
}, [store]);
|
|
76
|
+
(0, react.useEffect)(() => {
|
|
77
|
+
const context = copilotkit.runtimeUrl ? {
|
|
78
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
79
|
+
headers: { ...copilotkit.headers },
|
|
80
|
+
wsUrl: copilotkit.intelligence?.wsUrl,
|
|
81
|
+
userId,
|
|
82
|
+
agentId
|
|
83
|
+
} : null;
|
|
84
|
+
store.setContext(context);
|
|
85
|
+
}, [
|
|
86
|
+
store,
|
|
87
|
+
copilotkit.runtimeUrl,
|
|
88
|
+
headersKey,
|
|
89
|
+
copilotkit.intelligence?.wsUrl,
|
|
90
|
+
userId,
|
|
91
|
+
agentId,
|
|
92
|
+
copilotkit.headers
|
|
93
|
+
]);
|
|
94
|
+
return {
|
|
95
|
+
threads,
|
|
96
|
+
isLoading,
|
|
97
|
+
error,
|
|
98
|
+
renameThread: (0, react.useCallback)((threadId, name) => store.renameThread(threadId, name), [store]),
|
|
99
|
+
archiveThread: (0, react.useCallback)((threadId) => store.archiveThread(threadId), [store]),
|
|
100
|
+
deleteThread: (0, react.useCallback)((threadId) => store.deleteThread(threadId), [store])
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
//#endregion
|
|
105
|
+
exports.useThreads = useThreads;
|
|
106
|
+
//# sourceMappingURL=use-threads.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-threads.cjs","names":["useCopilotKit","ɵselectThreads","ɵselectThreadsIsLoading","ɵselectThreadsError"],"sources":["../../src/hooks/use-threads.tsx"],"sourcesContent":["import { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport {\n ɵcreateThreadStore,\n ɵselectThreads,\n ɵselectThreadsError,\n ɵselectThreadsIsLoading,\n type ɵThread as CoreThread,\n type ɵThreadRuntimeContext,\n type ɵThreadStore,\n} from \"@copilotkitnext/core\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useState,\n useSyncExternalStore,\n} from \"react\";\n\n/**\n * A conversation thread managed by the Intelligence platform.\n *\n * Each thread has a unique `id`, an optional human-readable `name`, and\n * timestamp fields tracking creation and update times.\n */\nexport interface Thread extends CoreThread {}\n\n/**\n * Configuration for the {@link useThreads} hook.\n *\n * Both fields are required — they scope the thread list and all mutations\n * to a specific user/agent pair on the Intelligence platform.\n */\nexport interface UseThreadsInput {\n /** The ID of the current user. Thread queries and mutations are scoped to this user. */\n userId: string;\n /** The ID of the agent whose threads to list and manage. */\n agentId: string;\n}\n\n/**\n * Return value of the {@link useThreads} hook.\n *\n * The `threads` array is kept in sync with the platform via a realtime\n * WebSocket subscription (when available) and is sorted most-recently-updated\n * first. Mutations reject with an `Error` if the platform request fails.\n */\nexport interface UseThreadsResult {\n /**\n * All non-archived threads for the current user/agent pair, sorted by\n * most recently updated first. Updated in realtime when the platform\n * pushes metadata events.\n */\n threads: Thread[];\n /**\n * `true` while the initial thread list is being fetched from the platform.\n * Subsequent realtime updates do not re-enter the loading state.\n */\n isLoading: boolean;\n /**\n * The most recent error from fetching threads or executing a mutation,\n * or `null` when there is no error. Reset to `null` on the next\n * successful fetch.\n */\n error: Error | null;\n /**\n * Rename a thread on the platform.\n * Resolves when the server confirms the update; rejects on failure.\n */\n renameThread: (threadId: string, name: string) => Promise<void>;\n /**\n * Archive a thread on the platform.\n * Archived threads are excluded from subsequent list results.\n * Resolves when the server confirms the update; rejects on failure.\n */\n archiveThread: (threadId: string) => Promise<void>;\n /**\n * Permanently delete a thread from the platform.\n * This is irreversible. Resolves when the server confirms deletion;\n * rejects on failure.\n */\n deleteThread: (threadId: string) => Promise<void>;\n}\n\nfunction useThreadStoreSelector<T>(\n store: ɵThreadStore,\n selector: (state: ReturnType<ɵThreadStore[\"getState\"]>) => T,\n): T {\n return useSyncExternalStore(\n useCallback(\n (onStoreChange) => {\n const subscription = store.select(selector).subscribe(onStoreChange);\n return () => subscription.unsubscribe();\n },\n [store, selector],\n ),\n () => selector(store.getState()),\n );\n}\n\n/**\n * React hook for listing and managing Intelligence platform threads.\n *\n * On mount the hook fetches the thread list for the given `userId`/`agentId`\n * pair. When the Intelligence platform exposes a WebSocket URL, it also opens\n * a realtime subscription so the `threads` array stays current without\n * polling — thread creates, renames, archives, and deletes from any client\n * are reflected immediately.\n *\n * Mutation methods (`renameThread`, `archiveThread`, `deleteThread`) return\n * promises that resolve once the platform confirms the operation and reject\n * with an `Error` on failure.\n *\n * @param input - User and agent identifiers that scope the thread list.\n * @returns Thread list state and stable mutation callbacks.\n *\n * @example\n * ```tsx\n * import { useThreads } from \"@copilotkitnext/react\";\n *\n * function ThreadList() {\n * const { threads, isLoading, renameThread, deleteThread } = useThreads({\n * userId: \"user-1\",\n * agentId: \"agent-1\",\n * });\n *\n * if (isLoading) return <p>Loading…</p>;\n *\n * return (\n * <ul>\n * {threads.map((t) => (\n * <li key={t.id}>\n * {t.name ?? \"Untitled\"}\n * <button onClick={() => renameThread(t.id, \"New name\")}>Rename</button>\n * <button onClick={() => deleteThread(t.id)}>Delete</button>\n * </li>\n * ))}\n * </ul>\n * );\n * }\n * ```\n */\nexport function useThreads({\n userId,\n agentId,\n}: UseThreadsInput): UseThreadsResult {\n const { copilotkit } = useCopilotKit();\n\n const [store] = useState(() =>\n ɵcreateThreadStore({\n fetch: globalThis.fetch,\n }),\n );\n\n const threads = useThreadStoreSelector(store, ɵselectThreads);\n const storeIsLoading = useThreadStoreSelector(store, ɵselectThreadsIsLoading);\n const storeError = useThreadStoreSelector(store, ɵselectThreadsError);\n const headersKey = useMemo(() => {\n return JSON.stringify(\n Object.entries(copilotkit.headers ?? {}).sort(([left], [right]) =>\n left.localeCompare(right),\n ),\n );\n }, [copilotkit.headers]);\n const runtimeError = useMemo(() => {\n if (copilotkit.runtimeUrl) {\n return null;\n }\n\n return new Error(\"Runtime URL is not configured\");\n }, [copilotkit.runtimeUrl]);\n const isLoading = runtimeError ? false : storeIsLoading;\n const error = runtimeError ?? storeError;\n\n useEffect(() => {\n store.start();\n return () => {\n store.stop();\n };\n }, [store]);\n\n useEffect(() => {\n const context: ɵThreadRuntimeContext | null = copilotkit.runtimeUrl\n ? {\n runtimeUrl: copilotkit.runtimeUrl,\n headers: { ...copilotkit.headers },\n wsUrl: copilotkit.intelligence?.wsUrl,\n userId,\n agentId,\n }\n : null;\n\n store.setContext(context);\n }, [\n store,\n copilotkit.runtimeUrl,\n headersKey,\n copilotkit.intelligence?.wsUrl,\n userId,\n agentId,\n copilotkit.headers,\n ]);\n\n const renameThread = useCallback(\n (threadId: string, name: string) => store.renameThread(threadId, name),\n [store],\n );\n\n const archiveThread = useCallback(\n (threadId: string) => store.archiveThread(threadId),\n [store],\n );\n\n const deleteThread = useCallback(\n (threadId: string) => store.deleteThread(threadId),\n [store],\n );\n\n return {\n threads,\n isLoading,\n error,\n renameThread,\n archiveThread,\n deleteThread,\n };\n}\n"],"mappings":";;;;;;AAmFA,SAAS,uBACP,OACA,UACG;AACH,gEAEK,kBAAkB;EACjB,MAAM,eAAe,MAAM,OAAO,SAAS,CAAC,UAAU,cAAc;AACpE,eAAa,aAAa,aAAa;IAEzC,CAAC,OAAO,SAAS,CAClB,QACK,SAAS,MAAM,UAAU,CAAC,CACjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CH,SAAgB,WAAW,EACzB,QACA,WACoC;CACpC,MAAM,EAAE,eAAeA,0CAAe;CAEtC,MAAM,CAAC,gFACc,EACjB,OAAO,WAAW,OACnB,CAAC,CACH;CAED,MAAM,UAAU,uBAAuB,OAAOC,oCAAe;CAC7D,MAAM,iBAAiB,uBAAuB,OAAOC,6CAAwB;CAC7E,MAAM,aAAa,uBAAuB,OAAOC,yCAAoB;CACrE,MAAM,sCAA2B;AAC/B,SAAO,KAAK,UACV,OAAO,QAAQ,WAAW,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,WACtD,KAAK,cAAc,MAAM,CAC1B,CACF;IACA,CAAC,WAAW,QAAQ,CAAC;CACxB,MAAM,wCAA6B;AACjC,MAAI,WAAW,WACb,QAAO;AAGT,yBAAO,IAAI,MAAM,gCAAgC;IAChD,CAAC,WAAW,WAAW,CAAC;CAC3B,MAAM,YAAY,eAAe,QAAQ;CACzC,MAAM,QAAQ,gBAAgB;AAE9B,4BAAgB;AACd,QAAM,OAAO;AACb,eAAa;AACX,SAAM,MAAM;;IAEb,CAAC,MAAM,CAAC;AAEX,4BAAgB;EACd,MAAM,UAAwC,WAAW,aACrD;GACE,YAAY,WAAW;GACvB,SAAS,EAAE,GAAG,WAAW,SAAS;GAClC,OAAO,WAAW,cAAc;GAChC;GACA;GACD,GACD;AAEJ,QAAM,WAAW,QAAQ;IACxB;EACD;EACA,WAAW;EACX;EACA,WAAW,cAAc;EACzB;EACA;EACA,WAAW;EACZ,CAAC;AAiBF,QAAO;EACL;EACA;EACA;EACA,sCAlBC,UAAkB,SAAiB,MAAM,aAAa,UAAU,KAAK,EACtE,CAAC,MAAM,CACR;EAiBC,uCAdC,aAAqB,MAAM,cAAc,SAAS,EACnD,CAAC,MAAM,CACR;EAaC,sCAVC,aAAqB,MAAM,aAAa,SAAS,EAClD,CAAC,MAAM,CACR;EASA"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { ɵThread } from "@copilotkitnext/core";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/use-threads.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* A conversation thread managed by the Intelligence platform.
|
|
6
|
+
*
|
|
7
|
+
* Each thread has a unique `id`, an optional human-readable `name`, and
|
|
8
|
+
* timestamp fields tracking creation and update times.
|
|
9
|
+
*/
|
|
10
|
+
interface Thread extends ɵThread {}
|
|
11
|
+
/**
|
|
12
|
+
* Configuration for the {@link useThreads} hook.
|
|
13
|
+
*
|
|
14
|
+
* Both fields are required — they scope the thread list and all mutations
|
|
15
|
+
* to a specific user/agent pair on the Intelligence platform.
|
|
16
|
+
*/
|
|
17
|
+
interface UseThreadsInput {
|
|
18
|
+
/** The ID of the current user. Thread queries and mutations are scoped to this user. */
|
|
19
|
+
userId: string;
|
|
20
|
+
/** The ID of the agent whose threads to list and manage. */
|
|
21
|
+
agentId: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Return value of the {@link useThreads} hook.
|
|
25
|
+
*
|
|
26
|
+
* The `threads` array is kept in sync with the platform via a realtime
|
|
27
|
+
* WebSocket subscription (when available) and is sorted most-recently-updated
|
|
28
|
+
* first. Mutations reject with an `Error` if the platform request fails.
|
|
29
|
+
*/
|
|
30
|
+
interface UseThreadsResult {
|
|
31
|
+
/**
|
|
32
|
+
* All non-archived threads for the current user/agent pair, sorted by
|
|
33
|
+
* most recently updated first. Updated in realtime when the platform
|
|
34
|
+
* pushes metadata events.
|
|
35
|
+
*/
|
|
36
|
+
threads: Thread[];
|
|
37
|
+
/**
|
|
38
|
+
* `true` while the initial thread list is being fetched from the platform.
|
|
39
|
+
* Subsequent realtime updates do not re-enter the loading state.
|
|
40
|
+
*/
|
|
41
|
+
isLoading: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* The most recent error from fetching threads or executing a mutation,
|
|
44
|
+
* or `null` when there is no error. Reset to `null` on the next
|
|
45
|
+
* successful fetch.
|
|
46
|
+
*/
|
|
47
|
+
error: Error | null;
|
|
48
|
+
/**
|
|
49
|
+
* Rename a thread on the platform.
|
|
50
|
+
* Resolves when the server confirms the update; rejects on failure.
|
|
51
|
+
*/
|
|
52
|
+
renameThread: (threadId: string, name: string) => Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Archive a thread on the platform.
|
|
55
|
+
* Archived threads are excluded from subsequent list results.
|
|
56
|
+
* Resolves when the server confirms the update; rejects on failure.
|
|
57
|
+
*/
|
|
58
|
+
archiveThread: (threadId: string) => Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Permanently delete a thread from the platform.
|
|
61
|
+
* This is irreversible. Resolves when the server confirms deletion;
|
|
62
|
+
* rejects on failure.
|
|
63
|
+
*/
|
|
64
|
+
deleteThread: (threadId: string) => Promise<void>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* React hook for listing and managing Intelligence platform threads.
|
|
68
|
+
*
|
|
69
|
+
* On mount the hook fetches the thread list for the given `userId`/`agentId`
|
|
70
|
+
* pair. When the Intelligence platform exposes a WebSocket URL, it also opens
|
|
71
|
+
* a realtime subscription so the `threads` array stays current without
|
|
72
|
+
* polling — thread creates, renames, archives, and deletes from any client
|
|
73
|
+
* are reflected immediately.
|
|
74
|
+
*
|
|
75
|
+
* Mutation methods (`renameThread`, `archiveThread`, `deleteThread`) return
|
|
76
|
+
* promises that resolve once the platform confirms the operation and reject
|
|
77
|
+
* with an `Error` on failure.
|
|
78
|
+
*
|
|
79
|
+
* @param input - User and agent identifiers that scope the thread list.
|
|
80
|
+
* @returns Thread list state and stable mutation callbacks.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```tsx
|
|
84
|
+
* import { useThreads } from "@copilotkitnext/react";
|
|
85
|
+
*
|
|
86
|
+
* function ThreadList() {
|
|
87
|
+
* const { threads, isLoading, renameThread, deleteThread } = useThreads({
|
|
88
|
+
* userId: "user-1",
|
|
89
|
+
* agentId: "agent-1",
|
|
90
|
+
* });
|
|
91
|
+
*
|
|
92
|
+
* if (isLoading) return <p>Loading…</p>;
|
|
93
|
+
*
|
|
94
|
+
* return (
|
|
95
|
+
* <ul>
|
|
96
|
+
* {threads.map((t) => (
|
|
97
|
+
* <li key={t.id}>
|
|
98
|
+
* {t.name ?? "Untitled"}
|
|
99
|
+
* <button onClick={() => renameThread(t.id, "New name")}>Rename</button>
|
|
100
|
+
* <button onClick={() => deleteThread(t.id)}>Delete</button>
|
|
101
|
+
* </li>
|
|
102
|
+
* ))}
|
|
103
|
+
* </ul>
|
|
104
|
+
* );
|
|
105
|
+
* }
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
declare function useThreads({
|
|
109
|
+
userId,
|
|
110
|
+
agentId
|
|
111
|
+
}: UseThreadsInput): UseThreadsResult;
|
|
112
|
+
//#endregion
|
|
113
|
+
export { Thread, UseThreadsInput, UseThreadsResult, useThreads };
|
|
114
|
+
//# sourceMappingURL=use-threads.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-threads.d.cts","names":[],"sources":["../../src/hooks/use-threads.tsx"],"mappings":";;;;;AAwBA;;;;UAAiB,MAAA,SAAe,OAAA;;;;;AAsBhC;;UAdiB,eAAA;EAoBN;EAlBT,MAAA;EAkCkD;EAhClD,OAAA;AAAA;;;;;;;;UAUe,gBAAA;EAsBA;;;;;EAhBf,OAAA,EAAS,MAAA;EA4BT;;;;EAvBA,SAAA;EAoFc;;;;;EA9Ed,KAAA,EAAO,KAAA;EAiFY;;;;EA5EnB,YAAA,GAAe,QAAA,UAAkB,IAAA,aAAiB,OAAA;EA2ElD;;;;;EArEA,aAAA,GAAgB,QAAA,aAAqB,OAAA;;;;;;EAMrC,YAAA,GAAe,QAAA,aAAqB,OAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6DtB,UAAA,CAAA;EACd,MAAA;EACA;AAAA,GACC,eAAA,GAAkB,gBAAA"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { ɵThread } from "@copilotkitnext/core";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/use-threads.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* A conversation thread managed by the Intelligence platform.
|
|
6
|
+
*
|
|
7
|
+
* Each thread has a unique `id`, an optional human-readable `name`, and
|
|
8
|
+
* timestamp fields tracking creation and update times.
|
|
9
|
+
*/
|
|
10
|
+
interface Thread extends ɵThread {}
|
|
11
|
+
/**
|
|
12
|
+
* Configuration for the {@link useThreads} hook.
|
|
13
|
+
*
|
|
14
|
+
* Both fields are required — they scope the thread list and all mutations
|
|
15
|
+
* to a specific user/agent pair on the Intelligence platform.
|
|
16
|
+
*/
|
|
17
|
+
interface UseThreadsInput {
|
|
18
|
+
/** The ID of the current user. Thread queries and mutations are scoped to this user. */
|
|
19
|
+
userId: string;
|
|
20
|
+
/** The ID of the agent whose threads to list and manage. */
|
|
21
|
+
agentId: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Return value of the {@link useThreads} hook.
|
|
25
|
+
*
|
|
26
|
+
* The `threads` array is kept in sync with the platform via a realtime
|
|
27
|
+
* WebSocket subscription (when available) and is sorted most-recently-updated
|
|
28
|
+
* first. Mutations reject with an `Error` if the platform request fails.
|
|
29
|
+
*/
|
|
30
|
+
interface UseThreadsResult {
|
|
31
|
+
/**
|
|
32
|
+
* All non-archived threads for the current user/agent pair, sorted by
|
|
33
|
+
* most recently updated first. Updated in realtime when the platform
|
|
34
|
+
* pushes metadata events.
|
|
35
|
+
*/
|
|
36
|
+
threads: Thread[];
|
|
37
|
+
/**
|
|
38
|
+
* `true` while the initial thread list is being fetched from the platform.
|
|
39
|
+
* Subsequent realtime updates do not re-enter the loading state.
|
|
40
|
+
*/
|
|
41
|
+
isLoading: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* The most recent error from fetching threads or executing a mutation,
|
|
44
|
+
* or `null` when there is no error. Reset to `null` on the next
|
|
45
|
+
* successful fetch.
|
|
46
|
+
*/
|
|
47
|
+
error: Error | null;
|
|
48
|
+
/**
|
|
49
|
+
* Rename a thread on the platform.
|
|
50
|
+
* Resolves when the server confirms the update; rejects on failure.
|
|
51
|
+
*/
|
|
52
|
+
renameThread: (threadId: string, name: string) => Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Archive a thread on the platform.
|
|
55
|
+
* Archived threads are excluded from subsequent list results.
|
|
56
|
+
* Resolves when the server confirms the update; rejects on failure.
|
|
57
|
+
*/
|
|
58
|
+
archiveThread: (threadId: string) => Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Permanently delete a thread from the platform.
|
|
61
|
+
* This is irreversible. Resolves when the server confirms deletion;
|
|
62
|
+
* rejects on failure.
|
|
63
|
+
*/
|
|
64
|
+
deleteThread: (threadId: string) => Promise<void>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* React hook for listing and managing Intelligence platform threads.
|
|
68
|
+
*
|
|
69
|
+
* On mount the hook fetches the thread list for the given `userId`/`agentId`
|
|
70
|
+
* pair. When the Intelligence platform exposes a WebSocket URL, it also opens
|
|
71
|
+
* a realtime subscription so the `threads` array stays current without
|
|
72
|
+
* polling — thread creates, renames, archives, and deletes from any client
|
|
73
|
+
* are reflected immediately.
|
|
74
|
+
*
|
|
75
|
+
* Mutation methods (`renameThread`, `archiveThread`, `deleteThread`) return
|
|
76
|
+
* promises that resolve once the platform confirms the operation and reject
|
|
77
|
+
* with an `Error` on failure.
|
|
78
|
+
*
|
|
79
|
+
* @param input - User and agent identifiers that scope the thread list.
|
|
80
|
+
* @returns Thread list state and stable mutation callbacks.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```tsx
|
|
84
|
+
* import { useThreads } from "@copilotkitnext/react";
|
|
85
|
+
*
|
|
86
|
+
* function ThreadList() {
|
|
87
|
+
* const { threads, isLoading, renameThread, deleteThread } = useThreads({
|
|
88
|
+
* userId: "user-1",
|
|
89
|
+
* agentId: "agent-1",
|
|
90
|
+
* });
|
|
91
|
+
*
|
|
92
|
+
* if (isLoading) return <p>Loading…</p>;
|
|
93
|
+
*
|
|
94
|
+
* return (
|
|
95
|
+
* <ul>
|
|
96
|
+
* {threads.map((t) => (
|
|
97
|
+
* <li key={t.id}>
|
|
98
|
+
* {t.name ?? "Untitled"}
|
|
99
|
+
* <button onClick={() => renameThread(t.id, "New name")}>Rename</button>
|
|
100
|
+
* <button onClick={() => deleteThread(t.id)}>Delete</button>
|
|
101
|
+
* </li>
|
|
102
|
+
* ))}
|
|
103
|
+
* </ul>
|
|
104
|
+
* );
|
|
105
|
+
* }
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
declare function useThreads({
|
|
109
|
+
userId,
|
|
110
|
+
agentId
|
|
111
|
+
}: UseThreadsInput): UseThreadsResult;
|
|
112
|
+
//#endregion
|
|
113
|
+
export { Thread, UseThreadsInput, UseThreadsResult, useThreads };
|
|
114
|
+
//# sourceMappingURL=use-threads.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-threads.d.mts","names":[],"sources":["../../src/hooks/use-threads.tsx"],"mappings":";;;;;AAwBA;;;;UAAiB,MAAA,SAAe,OAAA;;;;;AAsBhC;;UAdiB,eAAA;EAoBN;EAlBT,MAAA;EAkCkD;EAhClD,OAAA;AAAA;;;;;;;;UAUe,gBAAA;EAsBA;;;;;EAhBf,OAAA,EAAS,MAAA;EA4BT;;;;EAvBA,SAAA;EAoFc;;;;;EA9Ed,KAAA,EAAO,KAAA;EAiFY;;;;EA5EnB,YAAA,GAAe,QAAA,UAAkB,IAAA,aAAiB,OAAA;EA2ElD;;;;;EArEA,aAAA,GAAgB,QAAA,aAAqB,OAAA;;;;;;EAMrC,YAAA,GAAe,QAAA,aAAqB,OAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6DtB,UAAA,CAAA;EACd,MAAA;EACA;AAAA,GACC,eAAA,GAAkB,gBAAA"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { useCopilotKit } from "../providers/CopilotKitProvider.mjs";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useState, useSyncExternalStore } from "react";
|
|
3
|
+
import { ɵcreateThreadStore, ɵselectThreads, ɵselectThreadsError, ɵselectThreadsIsLoading } from "@copilotkitnext/core";
|
|
4
|
+
|
|
5
|
+
//#region src/hooks/use-threads.tsx
|
|
6
|
+
function useThreadStoreSelector(store, selector) {
|
|
7
|
+
return useSyncExternalStore(useCallback((onStoreChange) => {
|
|
8
|
+
const subscription = store.select(selector).subscribe(onStoreChange);
|
|
9
|
+
return () => subscription.unsubscribe();
|
|
10
|
+
}, [store, selector]), () => selector(store.getState()));
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* React hook for listing and managing Intelligence platform threads.
|
|
14
|
+
*
|
|
15
|
+
* On mount the hook fetches the thread list for the given `userId`/`agentId`
|
|
16
|
+
* pair. When the Intelligence platform exposes a WebSocket URL, it also opens
|
|
17
|
+
* a realtime subscription so the `threads` array stays current without
|
|
18
|
+
* polling — thread creates, renames, archives, and deletes from any client
|
|
19
|
+
* are reflected immediately.
|
|
20
|
+
*
|
|
21
|
+
* Mutation methods (`renameThread`, `archiveThread`, `deleteThread`) return
|
|
22
|
+
* promises that resolve once the platform confirms the operation and reject
|
|
23
|
+
* with an `Error` on failure.
|
|
24
|
+
*
|
|
25
|
+
* @param input - User and agent identifiers that scope the thread list.
|
|
26
|
+
* @returns Thread list state and stable mutation callbacks.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* import { useThreads } from "@copilotkitnext/react";
|
|
31
|
+
*
|
|
32
|
+
* function ThreadList() {
|
|
33
|
+
* const { threads, isLoading, renameThread, deleteThread } = useThreads({
|
|
34
|
+
* userId: "user-1",
|
|
35
|
+
* agentId: "agent-1",
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* if (isLoading) return <p>Loading…</p>;
|
|
39
|
+
*
|
|
40
|
+
* return (
|
|
41
|
+
* <ul>
|
|
42
|
+
* {threads.map((t) => (
|
|
43
|
+
* <li key={t.id}>
|
|
44
|
+
* {t.name ?? "Untitled"}
|
|
45
|
+
* <button onClick={() => renameThread(t.id, "New name")}>Rename</button>
|
|
46
|
+
* <button onClick={() => deleteThread(t.id)}>Delete</button>
|
|
47
|
+
* </li>
|
|
48
|
+
* ))}
|
|
49
|
+
* </ul>
|
|
50
|
+
* );
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
function useThreads({ userId, agentId }) {
|
|
55
|
+
const { copilotkit } = useCopilotKit();
|
|
56
|
+
const [store] = useState(() => ɵcreateThreadStore({ fetch: globalThis.fetch }));
|
|
57
|
+
const threads = useThreadStoreSelector(store, ɵselectThreads);
|
|
58
|
+
const storeIsLoading = useThreadStoreSelector(store, ɵselectThreadsIsLoading);
|
|
59
|
+
const storeError = useThreadStoreSelector(store, ɵselectThreadsError);
|
|
60
|
+
const headersKey = useMemo(() => {
|
|
61
|
+
return JSON.stringify(Object.entries(copilotkit.headers ?? {}).sort(([left], [right]) => left.localeCompare(right)));
|
|
62
|
+
}, [copilotkit.headers]);
|
|
63
|
+
const runtimeError = useMemo(() => {
|
|
64
|
+
if (copilotkit.runtimeUrl) return null;
|
|
65
|
+
return /* @__PURE__ */ new Error("Runtime URL is not configured");
|
|
66
|
+
}, [copilotkit.runtimeUrl]);
|
|
67
|
+
const isLoading = runtimeError ? false : storeIsLoading;
|
|
68
|
+
const error = runtimeError ?? storeError;
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
store.start();
|
|
71
|
+
return () => {
|
|
72
|
+
store.stop();
|
|
73
|
+
};
|
|
74
|
+
}, [store]);
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
const context = copilotkit.runtimeUrl ? {
|
|
77
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
78
|
+
headers: { ...copilotkit.headers },
|
|
79
|
+
wsUrl: copilotkit.intelligence?.wsUrl,
|
|
80
|
+
userId,
|
|
81
|
+
agentId
|
|
82
|
+
} : null;
|
|
83
|
+
store.setContext(context);
|
|
84
|
+
}, [
|
|
85
|
+
store,
|
|
86
|
+
copilotkit.runtimeUrl,
|
|
87
|
+
headersKey,
|
|
88
|
+
copilotkit.intelligence?.wsUrl,
|
|
89
|
+
userId,
|
|
90
|
+
agentId,
|
|
91
|
+
copilotkit.headers
|
|
92
|
+
]);
|
|
93
|
+
return {
|
|
94
|
+
threads,
|
|
95
|
+
isLoading,
|
|
96
|
+
error,
|
|
97
|
+
renameThread: useCallback((threadId, name) => store.renameThread(threadId, name), [store]),
|
|
98
|
+
archiveThread: useCallback((threadId) => store.archiveThread(threadId), [store]),
|
|
99
|
+
deleteThread: useCallback((threadId) => store.deleteThread(threadId), [store])
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
//#endregion
|
|
104
|
+
export { useThreads };
|
|
105
|
+
//# sourceMappingURL=use-threads.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-threads.mjs","names":[],"sources":["../../src/hooks/use-threads.tsx"],"sourcesContent":["import { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport {\n ɵcreateThreadStore,\n ɵselectThreads,\n ɵselectThreadsError,\n ɵselectThreadsIsLoading,\n type ɵThread as CoreThread,\n type ɵThreadRuntimeContext,\n type ɵThreadStore,\n} from \"@copilotkitnext/core\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useState,\n useSyncExternalStore,\n} from \"react\";\n\n/**\n * A conversation thread managed by the Intelligence platform.\n *\n * Each thread has a unique `id`, an optional human-readable `name`, and\n * timestamp fields tracking creation and update times.\n */\nexport interface Thread extends CoreThread {}\n\n/**\n * Configuration for the {@link useThreads} hook.\n *\n * Both fields are required — they scope the thread list and all mutations\n * to a specific user/agent pair on the Intelligence platform.\n */\nexport interface UseThreadsInput {\n /** The ID of the current user. Thread queries and mutations are scoped to this user. */\n userId: string;\n /** The ID of the agent whose threads to list and manage. */\n agentId: string;\n}\n\n/**\n * Return value of the {@link useThreads} hook.\n *\n * The `threads` array is kept in sync with the platform via a realtime\n * WebSocket subscription (when available) and is sorted most-recently-updated\n * first. Mutations reject with an `Error` if the platform request fails.\n */\nexport interface UseThreadsResult {\n /**\n * All non-archived threads for the current user/agent pair, sorted by\n * most recently updated first. Updated in realtime when the platform\n * pushes metadata events.\n */\n threads: Thread[];\n /**\n * `true` while the initial thread list is being fetched from the platform.\n * Subsequent realtime updates do not re-enter the loading state.\n */\n isLoading: boolean;\n /**\n * The most recent error from fetching threads or executing a mutation,\n * or `null` when there is no error. Reset to `null` on the next\n * successful fetch.\n */\n error: Error | null;\n /**\n * Rename a thread on the platform.\n * Resolves when the server confirms the update; rejects on failure.\n */\n renameThread: (threadId: string, name: string) => Promise<void>;\n /**\n * Archive a thread on the platform.\n * Archived threads are excluded from subsequent list results.\n * Resolves when the server confirms the update; rejects on failure.\n */\n archiveThread: (threadId: string) => Promise<void>;\n /**\n * Permanently delete a thread from the platform.\n * This is irreversible. Resolves when the server confirms deletion;\n * rejects on failure.\n */\n deleteThread: (threadId: string) => Promise<void>;\n}\n\nfunction useThreadStoreSelector<T>(\n store: ɵThreadStore,\n selector: (state: ReturnType<ɵThreadStore[\"getState\"]>) => T,\n): T {\n return useSyncExternalStore(\n useCallback(\n (onStoreChange) => {\n const subscription = store.select(selector).subscribe(onStoreChange);\n return () => subscription.unsubscribe();\n },\n [store, selector],\n ),\n () => selector(store.getState()),\n );\n}\n\n/**\n * React hook for listing and managing Intelligence platform threads.\n *\n * On mount the hook fetches the thread list for the given `userId`/`agentId`\n * pair. When the Intelligence platform exposes a WebSocket URL, it also opens\n * a realtime subscription so the `threads` array stays current without\n * polling — thread creates, renames, archives, and deletes from any client\n * are reflected immediately.\n *\n * Mutation methods (`renameThread`, `archiveThread`, `deleteThread`) return\n * promises that resolve once the platform confirms the operation and reject\n * with an `Error` on failure.\n *\n * @param input - User and agent identifiers that scope the thread list.\n * @returns Thread list state and stable mutation callbacks.\n *\n * @example\n * ```tsx\n * import { useThreads } from \"@copilotkitnext/react\";\n *\n * function ThreadList() {\n * const { threads, isLoading, renameThread, deleteThread } = useThreads({\n * userId: \"user-1\",\n * agentId: \"agent-1\",\n * });\n *\n * if (isLoading) return <p>Loading…</p>;\n *\n * return (\n * <ul>\n * {threads.map((t) => (\n * <li key={t.id}>\n * {t.name ?? \"Untitled\"}\n * <button onClick={() => renameThread(t.id, \"New name\")}>Rename</button>\n * <button onClick={() => deleteThread(t.id)}>Delete</button>\n * </li>\n * ))}\n * </ul>\n * );\n * }\n * ```\n */\nexport function useThreads({\n userId,\n agentId,\n}: UseThreadsInput): UseThreadsResult {\n const { copilotkit } = useCopilotKit();\n\n const [store] = useState(() =>\n ɵcreateThreadStore({\n fetch: globalThis.fetch,\n }),\n );\n\n const threads = useThreadStoreSelector(store, ɵselectThreads);\n const storeIsLoading = useThreadStoreSelector(store, ɵselectThreadsIsLoading);\n const storeError = useThreadStoreSelector(store, ɵselectThreadsError);\n const headersKey = useMemo(() => {\n return JSON.stringify(\n Object.entries(copilotkit.headers ?? {}).sort(([left], [right]) =>\n left.localeCompare(right),\n ),\n );\n }, [copilotkit.headers]);\n const runtimeError = useMemo(() => {\n if (copilotkit.runtimeUrl) {\n return null;\n }\n\n return new Error(\"Runtime URL is not configured\");\n }, [copilotkit.runtimeUrl]);\n const isLoading = runtimeError ? false : storeIsLoading;\n const error = runtimeError ?? storeError;\n\n useEffect(() => {\n store.start();\n return () => {\n store.stop();\n };\n }, [store]);\n\n useEffect(() => {\n const context: ɵThreadRuntimeContext | null = copilotkit.runtimeUrl\n ? {\n runtimeUrl: copilotkit.runtimeUrl,\n headers: { ...copilotkit.headers },\n wsUrl: copilotkit.intelligence?.wsUrl,\n userId,\n agentId,\n }\n : null;\n\n store.setContext(context);\n }, [\n store,\n copilotkit.runtimeUrl,\n headersKey,\n copilotkit.intelligence?.wsUrl,\n userId,\n agentId,\n copilotkit.headers,\n ]);\n\n const renameThread = useCallback(\n (threadId: string, name: string) => store.renameThread(threadId, name),\n [store],\n );\n\n const archiveThread = useCallback(\n (threadId: string) => store.archiveThread(threadId),\n [store],\n );\n\n const deleteThread = useCallback(\n (threadId: string) => store.deleteThread(threadId),\n [store],\n );\n\n return {\n threads,\n isLoading,\n error,\n renameThread,\n archiveThread,\n deleteThread,\n };\n}\n"],"mappings":";;;;;AAmFA,SAAS,uBACP,OACA,UACG;AACH,QAAO,qBACL,aACG,kBAAkB;EACjB,MAAM,eAAe,MAAM,OAAO,SAAS,CAAC,UAAU,cAAc;AACpE,eAAa,aAAa,aAAa;IAEzC,CAAC,OAAO,SAAS,CAClB,QACK,SAAS,MAAM,UAAU,CAAC,CACjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CH,SAAgB,WAAW,EACzB,QACA,WACoC;CACpC,MAAM,EAAE,eAAe,eAAe;CAEtC,MAAM,CAAC,SAAS,eACd,mBAAmB,EACjB,OAAO,WAAW,OACnB,CAAC,CACH;CAED,MAAM,UAAU,uBAAuB,OAAO,eAAe;CAC7D,MAAM,iBAAiB,uBAAuB,OAAO,wBAAwB;CAC7E,MAAM,aAAa,uBAAuB,OAAO,oBAAoB;CACrE,MAAM,aAAa,cAAc;AAC/B,SAAO,KAAK,UACV,OAAO,QAAQ,WAAW,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,WACtD,KAAK,cAAc,MAAM,CAC1B,CACF;IACA,CAAC,WAAW,QAAQ,CAAC;CACxB,MAAM,eAAe,cAAc;AACjC,MAAI,WAAW,WACb,QAAO;AAGT,yBAAO,IAAI,MAAM,gCAAgC;IAChD,CAAC,WAAW,WAAW,CAAC;CAC3B,MAAM,YAAY,eAAe,QAAQ;CACzC,MAAM,QAAQ,gBAAgB;AAE9B,iBAAgB;AACd,QAAM,OAAO;AACb,eAAa;AACX,SAAM,MAAM;;IAEb,CAAC,MAAM,CAAC;AAEX,iBAAgB;EACd,MAAM,UAAwC,WAAW,aACrD;GACE,YAAY,WAAW;GACvB,SAAS,EAAE,GAAG,WAAW,SAAS;GAClC,OAAO,WAAW,cAAc;GAChC;GACA;GACD,GACD;AAEJ,QAAM,WAAW,QAAQ;IACxB;EACD;EACA,WAAW;EACX;EACA,WAAW,cAAc;EACzB;EACA;EACA,WAAW;EACZ,CAAC;AAiBF,QAAO;EACL;EACA;EACA;EACA,cAnBmB,aAClB,UAAkB,SAAiB,MAAM,aAAa,UAAU,KAAK,EACtE,CAAC,MAAM,CACR;EAiBC,eAfoB,aACnB,aAAqB,MAAM,cAAc,SAAS,EACnD,CAAC,MAAM,CACR;EAaC,cAXmB,aAClB,aAAqB,MAAM,aAAa,SAAS,EAClD,CAAC,MAAM,CACR;EASA"}
|
package/dist/index.cjs
CHANGED
|
@@ -24,6 +24,7 @@ const require_use_agent_context = require('./hooks/use-agent-context.cjs');
|
|
|
24
24
|
const require_use_suggestions = require('./hooks/use-suggestions.cjs');
|
|
25
25
|
const require_use_configure_suggestions = require('./hooks/use-configure-suggestions.cjs');
|
|
26
26
|
const require_use_interrupt = require('./hooks/use-interrupt.cjs');
|
|
27
|
+
const require_use_threads = require('./hooks/use-threads.cjs');
|
|
27
28
|
require('./hooks/index.cjs');
|
|
28
29
|
const require_CopilotChatToolCallsView = require('./components/chat/CopilotChatToolCallsView.cjs');
|
|
29
30
|
const require_CopilotChatAssistantMessage = require('./components/chat/CopilotChatAssistantMessage.cjs');
|
|
@@ -110,6 +111,7 @@ exports.useRenderCustomMessages = require_use_render_custom_messages.useRenderCu
|
|
|
110
111
|
exports.useRenderTool = require_use_render_tool.useRenderTool;
|
|
111
112
|
exports.useRenderToolCall = require_use_render_tool_call.useRenderToolCall;
|
|
112
113
|
exports.useSuggestions = require_use_suggestions.useSuggestions;
|
|
114
|
+
exports.useThreads = require_use_threads.useThreads;
|
|
113
115
|
var _ag_ui_client = require("@ag-ui/client");
|
|
114
116
|
Object.keys(_ag_ui_client).forEach(function (k) {
|
|
115
117
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|