Revert "feat(integrations): add Intelligence threads to langgraph-fastapi"

This commit is contained in:
Mike Ryan
2026-06-03 18:28:56 -07:00
committed by GitHub
parent 11e18e378a
commit 1e1aadbad8
13 changed files with 14 additions and 22046 deletions
+4 -1
View File
@@ -151,7 +151,10 @@
"src/app/api/copilotkit/**",
"docker/Dockerfile.agent",
"docker-compose.test.yml",
"scripts/**"
"scripts/**",
"src/components/threads-drawer/**",
"src/app/page.tsx",
"next.config.ts"
],
"packageJsonOverrides": {
"scripts.dev:agent": "cd agent && uv run main.py",
@@ -1,8 +1 @@
AGENT_URL=http://localhost:8000
OPENAI_API_KEY=
# --- CopilotKit Intelligence (optional; set COPILOTKIT_LICENSE_TOKEN to enable Threads — server + UI) ---
# COPILOTKIT_LICENSE_TOKEN=
# INTELLIGENCE_API_URL=http://localhost:4201
# INTELLIGENCE_GATEWAY_WS_URL=ws://localhost:4401
# INTELLIGENCE_API_KEY= # local dev: see examples/integrations/_intelligence/.env.intelligence for the seed value
@@ -3,19 +3,6 @@ import type { NextConfig } from "next";
const nextConfig: NextConfig = {
output: "standalone",
serverExternalPackages: ["@copilotkit/runtime"],
env: {
// The public Threads UI flag is DERIVED from the server-side license token.
// Set COPILOTKIT_LICENSE_TOKEN (only) to enable Threads — do not set this flag
// directly. NOTE: NEXT_PUBLIC_* resolves at BUILD time while the runtime reads
// the token per-request, so the UI gate and runtime agree only when the token is
// present at build time (the standard `next dev` / host-build flow). For a
// standalone/Docker image built without the token and injected at runtime, set
// COPILOTKIT_LICENSE_TOKEN at build time too (or gate the UI at runtime) so the
// baked flag reflects it.
NEXT_PUBLIC_COPILOTKIT_THREADS_ENABLED: process.env.COPILOTKIT_LICENSE_TOKEN
? "true"
: "false",
},
typescript: {
// Docker route override uses HttpAgent which has a type mismatch with CopilotRuntime
ignoreBuildErrors: true,
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,5 @@
import {
CopilotRuntime,
CopilotKitIntelligence,
createCopilotEndpoint,
InMemoryAgentRunner,
} from "@copilotkit/runtime/v2";
@@ -19,22 +18,7 @@ const defaultAgent = new LangGraphHttpAgent({
const runtime = new CopilotRuntime({
agents: { default: defaultAgent },
// --- copilotkit:intelligence (remove this block to opt out) ---
...(process.env.COPILOTKIT_LICENSE_TOKEN
? {
intelligence: new CopilotKitIntelligence({
apiKey: process.env.INTELLIGENCE_API_KEY ?? "",
apiUrl: process.env.INTELLIGENCE_API_URL ?? "http://localhost:4201",
wsUrl:
process.env.INTELLIGENCE_GATEWAY_WS_URL ?? "ws://localhost:4401",
}),
// Demo stub — replace with your real auth-derived user identity before any
// multi-user deployment, or all users share one thread history.
identifyUser: () => ({ id: "demo-user", name: "Demo User" }),
licenseToken: process.env.COPILOTKIT_LICENSE_TOKEN,
}
: { runner: new InMemoryAgentRunner() }),
// --- /copilotkit:intelligence ---
runner: new InMemoryAgentRunner(),
openGenerativeUI: true,
a2ui: {
injectA2UITool: false,
@@ -57,5 +41,3 @@ const app = createCopilotEndpoint({
export const GET = handle(app);
export const POST = handle(app);
export const PATCH = handle(app);
export const DELETE = handle(app);
@@ -1,57 +1,24 @@
"use client";
import { useState } from "react";
import { ExampleLayout } from "@/components/example-layout";
import { ExampleCanvas } from "@/components/example-canvas";
import { ThreadsDrawer } from "@/components/threads-drawer";
import { ThreadsPanelGate } from "@/components/threads-drawer/locked-state";
import { useGenerativeUIExamples, useExampleSuggestions } from "@/hooks";
import {
CopilotChat,
CopilotChatConfigurationProvider,
} from "@copilotkit/react-core/v2";
import styles from "@/components/threads-drawer/threads-drawer.module.css";
import { CopilotChat } from "@copilotkit/react-core/v2";
export default function HomePage() {
useGenerativeUIExamples();
useExampleSuggestions();
const [threadId, setThreadId] = useState<string | undefined>(undefined);
return (
<div className={styles.layout}>
<ThreadsPanelGate>
<ThreadsDrawer
agentId="default"
threadId={threadId}
onThreadChange={setThreadId}
<ExampleLayout
chatContent={
<CopilotChat
attachments={{ enabled: true }}
input={{ disclaimer: () => null, className: "pb-6" }}
/>
</ThreadsPanelGate>
<div className={styles.mainPanel}>
{/*
Wrap both the chat and the canvas in one CopilotChatConfigurationProvider
so they share the active threadId. `useAgent()` falls back to the
provider's threadId when called without an explicit one, which makes
the canvas read from the same per-thread agent clone that the chat's
/connect replay populates. Without this wrapper, the canvas resolves
to the registry agent and never receives STATE_SNAPSHOT events on
thread resume.
*/}
<CopilotChatConfigurationProvider agentId="default" threadId={threadId}>
<ExampleLayout
chatContent={
<CopilotChat
attachments={{ enabled: true }}
input={{ disclaimer: () => null, className: "pb-6" }}
/>
}
appContent={<ExampleCanvas />}
/>
</CopilotChatConfigurationProvider>
</div>
</div>
}
appContent={<ExampleCanvas />}
/>
);
}
@@ -1,53 +0,0 @@
# Threads Drawer — Theming Contract
The threads-drawer is a BASE component. It is fully driven by CSS variables and
contains no hardcoded colors, shadows, or surface radii. To theme it for an
example, (re)define the tokens below on any ancestor (e.g. `:root`, `body`, or a
wrapper element) — **never edit the drawer files**.
The drawer first consumes the shared design-system tokens (`--card`,
`--border`, `--radius`, …) that `ui/card.tsx` and `ui/button.tsx` also consume.
For a handful of drawer-specific visuals (scrim, shadows, delete-hover tint) it
exposes dedicated `--threads-*` tokens, each with a fallback to a shared token or
the original literal — so defining nothing reproduces the default look exactly.
## Shared design-system tokens consumed
| Token | Controls |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--background` | Tooltip text color (`color: var(--background)` on the dark tooltip body) |
| `--foreground` | Drawer/dialog title + body text, active segment text, tooltip surface bg |
| `--card` | Drawer surface bg (via `--threads-drawer-bg`), active segment bg, empty/dialog/load-more bg |
| `--border` | Drawer + header + filter + dialog borders, thread accent (idle), selected-row inset ring, secondary-button hover bg, tooltip border |
| `--radius` | Drawer/dialog/button/segment/thread/empty-card radii; tooltip radius derives from it |
| `--primary` | New-thread button bg, primary dialog button bg, selected thread accent |
| `--primary-foreground` | New-thread button text, primary dialog button text |
| `--secondary` | Icon-button + thread-row + load-more hover bg, segment track, archived badge bg, secondary dialog button bg, loading skeleton bars, thread-enter start bg |
| `--secondary-foreground` | (locked-state) inline code text |
| `--muted-foreground` | Icon-button idle color, segment idle text, meta text, placeholder/archived titles, empty/dialog description, load-more text, collapsed-rail icon |
| `--accent` | Selected thread-row bg |
| `--ring` | Focus-visible outline on buttons, thread items, segments, dialog buttons |
| `--destructive` | Delete-button icon color + delete-hover text |
| `--destructive-foreground` | Destructive dialog button text |
| `--font-body` | Header, segments, tooltip, empty card, and dialog typography |
(locked-state additionally uses `--secondary`, `--muted-foreground`, `--border`,
`--radius`, `--secondary-foreground`, and the `ui/card` + `ui/button` tokens via
those components.)
## Drawer-specific tokens (with fallbacks)
| Token | Controls | Fallback |
| --------------------------------- | ----------------------------------------- | --------------------------------------------------------- |
| `--threads-drawer-bg` | Drawer surface background | `var(--card)` |
| `--threads-drawer-border` | Drawer right border color | `var(--border)` |
| `--threads-drawer-shadow` | Open-drawer drop shadow | `4px 0 20px rgb(0 0 0 / 0.04)` |
| `--threads-segment-active-shadow` | Active filter-segment shadow | `0 1px 2px rgb(0 0 0 / 0.06)` |
| `--threads-delete-hover-bg` | Delete-button hover/focus background tint | `color-mix(in srgb, var(--destructive) 10%, transparent)` |
| `--threads-overlay-bg` | Confirm-dialog overlay scrim | `rgb(0 0 0 / 0.5)` |
| `--threads-dialog-shadow` | Confirm-dialog drop shadow | `0 20px 50px rgb(0 0 0 / 0.25)` |
| `--threads-tooltip-radius` | Action-button tooltip corner radius | `calc(var(--radius) - 0.45rem)` (= `0.3rem` at default) |
All fallbacks resolve to the original hardcoded values in the north-star, so an
example that defines none of the `--threads-*` tokens renders pixel-identical to
the pre-tokenization drawer.
@@ -1,4 +0,0 @@
"use client";
export { default as ThreadsDrawer } from "./threads-drawer";
export type { ThreadsDrawerProps } from "./threads-drawer";
@@ -1,91 +0,0 @@
"use client";
import * as React from "react";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import styles from "./threads-drawer.module.css";
export function ThreadsPanelGate({ children }: { children: React.ReactNode }) {
// The Threads drawer reads a client-only external store (useThreads /
// useSyncExternalStore) with no server snapshot, so it must not render during
// SSR/prerender — Next would fail to prerender "/". Defer to client mount.
const [mounted, setMounted] = React.useState(false);
React.useEffect(() => setMounted(true), []);
if (process.env.NEXT_PUBLIC_COPILOTKIT_THREADS_ENABLED === "true") {
if (!mounted) {
// SSR / first-paint placeholder: matches the open drawer's footprint +
// surface (and collapses to nothing on mobile) so the panel doesn't flash
// a bare-background column or shift the content when the drawer mounts.
return <div className={styles.drawerPlaceholder} aria-hidden />;
}
return <>{children}</>;
}
return (
<div className="flex w-80 shrink-0 flex-col items-center justify-center p-4 bg-[var(--threads-drawer-bg,var(--card))] border-r border-[var(--threads-drawer-border,var(--border))] max-lg:hidden">
<Card className="w-full">
<CardHeader>
<div className="mb-2 flex h-10 w-10 items-center justify-center rounded-full bg-[var(--secondary)]">
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="text-[var(--muted-foreground)]"
aria-hidden="true"
>
<rect width="18" height="11" x="3" y="11" rx="2" ry="2" />
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
</svg>
</div>
<CardTitle>Threads</CardTitle>
<CardDescription>
Threads is a licensed CopilotKit Intelligence feature. Unlock
persistent conversation history, multi-session context, and thread
management across your application.
</CardDescription>
</CardHeader>
<CardContent>
<p className="text-sm text-[var(--muted-foreground)]">
To enable Threads, add a CopilotKit Intelligence license to your
project with:
</p>
</CardContent>
<CardFooter className="flex-col items-start gap-3">
<div className="w-full rounded-[var(--radius)] border border-[var(--border)] bg-[var(--secondary)] px-3 py-2">
<code className="text-xs whitespace-nowrap text-[var(--secondary-foreground)]">
copilotkit add-intelligence
</code>
</div>
<Button
variant="default"
size="sm"
className="w-full"
onClick={() =>
window.open(
"https://docs.copilotkit.ai/intelligence",
"_blank",
"noopener,noreferrer",
)
}
>
Learn more
</Button>
</CardFooter>
</Card>
</div>
);
}
@@ -1,738 +0,0 @@
.layout {
display: grid;
grid-template-columns: auto minmax(0, 1fr);
min-height: 100vh;
min-height: 100svh;
height: 100dvh;
width: 100%;
overflow: hidden;
}
.drawer {
position: relative;
display: flex;
min-height: 100vh;
min-height: 100svh;
height: 100dvh;
background: var(--threads-drawer-bg, var(--card));
border-right: 1px solid var(--threads-drawer-border, var(--border));
transition:
width 180ms ease,
box-shadow 180ms ease;
}
.drawerOpen {
width: 18rem;
box-shadow: var(--threads-drawer-shadow, 4px 0 20px rgb(0 0 0 / 0.04));
}
.drawerClosed {
width: 3.5rem;
}
/* First-paint placeholder (rendered by ThreadsPanelGate before the client-only
drawer mounts). Matches the open drawer's footprint + surface so there's no
bare-background column flash and no content shift on mount. On mobile the
real drawer floats (no grid footprint), so the placeholder reserves nothing. */
.drawerPlaceholder {
width: 18rem;
flex-shrink: 0;
min-height: 100vh;
min-height: 100svh;
height: 100dvh;
background: var(--threads-drawer-bg, var(--card));
border-right: 1px solid var(--threads-drawer-border, var(--border));
}
.drawerSurface {
display: flex;
flex: 1;
height: 100%;
flex-direction: column;
overflow: hidden;
}
.drawerHeader {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.75rem;
padding: 1rem 1rem 0.75rem;
border-bottom: 1px solid var(--border);
}
.drawerHeaderMain {
display: flex;
min-width: 0;
flex-direction: column;
gap: 0.25rem;
font-family: var(--font-body);
}
.drawerTitle {
margin: 0;
font-size: 0.95rem;
font-weight: 700;
letter-spacing: -0.02em;
color: var(--foreground);
}
.headerActions {
display: flex;
align-items: center;
gap: 0.5rem;
}
.iconButton {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
border: 0;
border-radius: var(--radius);
color: var(--muted-foreground);
background: transparent;
transition:
background-color 140ms ease,
color 140ms ease;
cursor: pointer;
}
.iconButton:hover,
.iconButton:focus-visible {
background: var(--secondary);
color: var(--foreground);
}
.iconButton:focus-visible,
.threadItem:focus-visible,
.newThreadButton:focus-visible {
outline: 2px solid var(--ring);
outline-offset: 2px;
}
.newThreadButton {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.4rem;
min-height: 2.25rem;
padding: 0.5rem 0.75rem;
border: 0;
border-radius: var(--radius);
background: var(--primary);
color: var(--primary-foreground);
font-size: 0.8rem;
font-weight: 600;
cursor: pointer;
transition:
opacity 140ms ease,
transform 140ms ease;
}
.newThreadButton:hover {
opacity: 0.9;
}
.filterBar {
display: flex;
align-items: center;
padding: 0.5rem 1rem;
border-bottom: 1px solid var(--border);
}
.segmented {
display: inline-flex;
width: 100%;
padding: 0.2rem;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--secondary);
gap: 0.15rem;
}
.segmentedOption {
flex: 1;
min-height: 1.75rem;
padding: 0.3rem 0.75rem;
border: 0;
border-radius: calc(var(--radius) - 0.15rem);
background: transparent;
font-family: var(--font-body);
font-size: 0.75rem;
font-weight: 500;
color: var(--muted-foreground);
cursor: pointer;
transition:
background-color 140ms ease,
color 140ms ease,
box-shadow 140ms ease;
}
.segmentedOption:hover {
color: var(--foreground);
}
.segmentedOption:focus-visible {
outline: 2px solid var(--ring);
outline-offset: 2px;
}
.segmentedOptionActive {
background: var(--card);
color: var(--foreground);
box-shadow: var(--threads-segment-active-shadow, 0 1px 2px rgb(0 0 0 / 0.06));
}
.drawerContent {
display: flex;
flex: 1;
min-height: 0;
flex-direction: column;
overflow: hidden;
}
.threadList {
display: flex;
flex: 1;
min-height: 0;
flex-direction: column;
gap: 0.25rem;
overflow-y: auto;
/* Reserve scrollbar space so the list doesn't shift horizontally
when the scrollbar appears during the thread-enter animation. */
scrollbar-gutter: stable;
padding: 0.75rem 0.5rem;
}
.threadRow {
position: relative;
}
.threadItem {
display: flex;
width: 100%;
align-items: center;
gap: 0.5rem;
padding: 0.6rem 0.65rem;
border: 0;
border-radius: var(--radius);
background: transparent;
color: inherit;
text-align: left;
cursor: pointer;
transition:
background-color 140ms ease,
box-shadow 140ms ease,
padding-right 140ms ease;
}
.threadItem:hover,
.threadItem:focus-visible {
background: var(--secondary);
}
.threadRow:hover .threadItem,
.threadRow:focus-within .threadItem {
padding-right: 3.5rem;
}
.threadItemSelected {
background: var(--accent);
box-shadow: inset 0 0 0 1px var(--border);
}
.threadItemAnimatingIn {
animation: threadItemEnter 420ms cubic-bezier(0.16, 1, 0.3, 1);
}
.threadAccent {
flex: none;
width: 0.35rem;
height: 1.75rem;
border-radius: 999px;
background: var(--border);
transition: background 140ms ease;
}
.threadItemSelected .threadAccent {
background: var(--primary);
}
.threadBody {
display: flex;
min-width: 0;
flex: 1;
flex-direction: column;
gap: 0.15rem;
}
.threadTitle {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 0.82rem;
font-weight: 600;
color: var(--foreground);
}
.threadTitlePlaceholder {
color: var(--muted-foreground);
font-weight: 500;
}
.threadTitleAnimated {
display: inline-block;
animation: generatedTitleReveal 360ms cubic-bezier(0.22, 1, 0.36, 1);
transform-origin: left center;
}
.threadMeta {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 0.7rem;
color: var(--muted-foreground);
}
.threadItemArchived .threadTitle {
color: var(--muted-foreground);
font-weight: 500;
}
.threadItemArchived .threadAccent {
opacity: 0.5;
}
.archivedBadge {
display: inline-block;
margin-left: 0.35rem;
padding: 0.05rem 0.35rem;
border-radius: 999px;
background: var(--secondary);
font-size: 0.6rem;
font-weight: 600;
color: var(--muted-foreground);
vertical-align: middle;
}
.loadMoreButton {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
min-height: 2rem;
margin-top: 0.25rem;
padding: 0.4rem;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--card);
font-size: 0.78rem;
font-weight: 600;
color: var(--muted-foreground);
cursor: pointer;
transition:
background-color 140ms ease,
color 140ms ease;
}
.loadMoreButton:hover:not(:disabled) {
background: var(--secondary);
color: var(--foreground);
}
.loadMoreButton:disabled {
opacity: 0.6;
cursor: default;
}
.threadActions {
position: absolute;
right: 0.4rem;
top: 50%;
display: flex;
align-items: center;
gap: 0.15rem;
transform: translateY(-50%) scale(0.96);
opacity: 0;
pointer-events: none;
transition:
opacity 140ms ease,
transform 140ms ease;
}
.threadRow:hover .threadActions,
.threadRow:focus-within .threadActions {
opacity: 1;
pointer-events: auto;
transform: translateY(-50%) scale(1);
}
.threadActionButton {
width: 1.75rem;
height: 1.75rem;
}
.tooltip {
position: relative;
}
.tooltip::after {
content: attr(data-tooltip);
position: absolute;
top: calc(100% + 0.3rem);
left: 50%;
transform: translateX(-50%) translateY(-2px);
padding: 0.2rem 0.45rem;
border-radius: var(--threads-tooltip-radius, calc(var(--radius) - 0.45rem));
border: 1px solid var(--border);
background: var(--foreground);
color: var(--background);
font-family: var(--font-body);
font-size: 0.7rem;
font-weight: 500;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition:
opacity 110ms ease 200ms,
transform 110ms ease 200ms;
z-index: 20;
}
.tooltip:hover::after,
.tooltip:focus-visible::after {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
.deleteButton {
color: var(--destructive);
}
.deleteButton:hover,
.deleteButton:focus-visible {
background: var(
--threads-delete-hover-bg,
color-mix(in srgb, var(--destructive) 10%, transparent)
);
color: var(--destructive);
}
.loadingList {
display: flex;
flex-direction: column;
gap: 0.35rem;
padding: 0.2rem 0;
}
.loadingRow {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.6rem 0.65rem;
border-radius: var(--radius);
}
.loadingAccent {
flex: none;
width: 0.35rem;
height: 1.75rem;
border-radius: 999px;
background: var(--secondary);
animation: threadsDrawerPulse 1.4s ease-in-out infinite;
}
.loadingBody {
display: flex;
flex: 1;
flex-direction: column;
gap: 0.4rem;
}
.loadingTitleBar {
height: 0.6rem;
width: 60%;
border-radius: 999px;
background: var(--secondary);
animation: threadsDrawerPulse 1.4s ease-in-out infinite;
}
.loadingMetaBar {
height: 0.45rem;
width: 35%;
border-radius: 999px;
background: var(--secondary);
animation: threadsDrawerPulse 1.4s ease-in-out infinite;
animation-delay: 140ms;
}
@keyframes threadsDrawerPulse {
0%,
100% {
opacity: 0.45;
}
50% {
opacity: 0.9;
}
}
.emptyState {
display: flex;
flex: 1;
align-items: center;
justify-content: center;
padding: 1.5rem;
}
.emptyCard {
display: flex;
max-width: 13rem;
flex-direction: column;
align-items: flex-start;
gap: 0.5rem;
padding: 0.75rem;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--card);
font-family: var(--font-body);
}
.emptyTitle {
margin: 0;
font-size: 0.85rem;
font-weight: 700;
color: var(--foreground);
}
.emptyMessage {
margin: 0;
font-size: 0.78rem;
line-height: 1.4;
color: var(--muted-foreground);
}
.collapsedRail {
display: flex;
width: 100%;
flex-direction: column;
align-items: center;
gap: 0.75rem;
padding: 1rem 0.5rem;
}
.mainPanel {
min-width: 0;
min-height: 100vh;
min-height: 100svh;
height: 100dvh;
overflow: auto;
}
.dialogOverlay {
position: fixed;
inset: 0;
z-index: 200;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
background: var(--threads-overlay-bg, rgb(0 0 0 / 0.5));
backdrop-filter: blur(2px);
animation: dialogOverlayEnter 140ms ease-out;
}
.dialog {
width: 100%;
max-width: 22rem;
padding: 1.1rem 1.1rem 1rem;
border: 1px solid var(--border);
border-radius: calc(var(--radius) + 0.25rem);
background: var(--card);
color: var(--foreground);
box-shadow: var(--threads-dialog-shadow, 0 20px 50px rgb(0 0 0 / 0.25));
font-family: var(--font-body);
animation: dialogEnter 160ms cubic-bezier(0.22, 1, 0.36, 1);
}
.dialogTitle {
margin: 0 0 0.35rem;
font-size: 0.95rem;
font-weight: 700;
letter-spacing: -0.01em;
color: var(--foreground);
}
.dialogDescription {
margin: 0 0 1rem;
font-size: 0.82rem;
line-height: 1.5;
color: var(--muted-foreground);
}
.dialogActions {
display: flex;
justify-content: flex-end;
gap: 0.5rem;
}
.dialogButton {
min-height: 2.25rem;
padding: 0.5rem 0.95rem;
border: 0;
border-radius: var(--radius);
font-family: var(--font-body);
font-size: 0.8rem;
font-weight: 600;
cursor: pointer;
transition:
background-color 140ms ease,
color 140ms ease,
opacity 140ms ease;
}
.dialogButton:focus-visible {
outline: 2px solid var(--ring);
outline-offset: 2px;
}
.dialogButtonSecondary {
background: var(--secondary);
color: var(--foreground);
}
.dialogButtonSecondary:hover {
background: var(--border);
}
.dialogButtonPrimary {
background: var(--primary);
color: var(--primary-foreground);
}
.dialogButtonPrimary:hover {
opacity: 0.9;
}
.dialogButtonDestructive {
background: var(--destructive);
color: var(--destructive-foreground);
}
.dialogButtonDestructive:hover {
opacity: 0.9;
}
@keyframes dialogOverlayEnter {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes dialogEnter {
from {
opacity: 0;
transform: translateY(6px) scale(0.98);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
@keyframes threadItemEnter {
0% {
opacity: 0;
transform: translateX(-10px);
background: var(--secondary);
}
100% {
opacity: 1;
transform: translateX(0);
background: transparent;
}
}
@keyframes generatedTitleReveal {
0% {
opacity: 0;
filter: blur(6px);
transform: translateY(4px);
}
100% {
opacity: 1;
filter: blur(0);
transform: translateY(0);
}
}
/* Tablet + phone: the threads panel goes off-canvas so the content and the
(full-screen) chat get the whole width instead of squeezing into a column. */
@media (max-width: 1024px) {
.layout {
position: relative;
isolation: isolate;
grid-template-columns: minmax(0, 1fr);
}
/* The mounted drawer floats on mobile, so the first-paint placeholder must
reserve no column (otherwise content shifts left when the drawer mounts). */
.drawerPlaceholder {
display: none;
}
/* Collapsed: a small floating launcher pinned top-left, above the full-screen
mobile chat (z-index 1200) so threads stay reachable over it. */
.drawer.drawerClosed {
position: fixed;
top: 0.5rem;
left: 0.5rem;
width: auto;
height: auto;
/* Override the base drawer's full-viewport height + chrome so the closed
state shrinks to a small floating launcher. */
min-height: 0;
border-right: 0;
background: transparent;
z-index: 1300;
}
.drawerClosed .collapsedRail {
flex-direction: row;
width: auto;
height: auto;
gap: 0.125rem;
padding: 0.1875rem;
overflow: visible;
border-radius: 999px;
background: var(--threads-drawer-bg, var(--card));
border: 1px solid var(--threads-drawer-border, var(--border));
box-shadow: 0 8px 24px rgb(0 0 0 / 0.16);
}
/* Trim the launcher's icon buttons so the pill's height lines up with the
top-right Chat/App toggle instead of towering over it. */
.drawerClosed .collapsedRail .iconButton {
width: 1.75rem;
height: 1.75rem;
}
/* Open: full-height off-canvas panel from the left, above the chat. */
.drawer.drawerOpen {
position: fixed;
inset: 0 auto 0 0;
z-index: 1300;
width: min(20rem, 92vw);
box-shadow: 0 20px 50px rgb(0 0 0 / 0.25);
}
.mainPanel {
grid-column: 1;
position: relative;
z-index: 1;
}
}
@@ -1,586 +0,0 @@
"use client";
import {
Archive,
ArchiveRestore,
ChevronLeft,
ChevronRight,
Plus,
Trash2,
} from "lucide-react";
import { useCallback, useEffect, useId, useRef, useState } from "react";
import { createPortal } from "react-dom";
import { useThreads } from "@copilotkit/react-core/v2";
import styles from "./threads-drawer.module.css";
export interface ThreadsDrawerProps {
agentId: string;
threadId: string | undefined;
onThreadChange: (threadId: string | undefined) => void;
}
interface DrawerThread {
id: string;
name: string | null;
updatedAt: string;
archived: boolean;
lastRunAt?: string;
}
const THREAD_ENTRY_ANIMATION_MS = 420;
const TITLE_ANIMATION_MS = 360;
const UNTITLED_THREAD_LABEL = "New thread";
const RUNTIME_BASE_PATH = "/api/copilotkit";
function formatThreadTimestamp(updatedAt: string): string {
const timestamp = new Date(updatedAt);
if (Number.isNaN(timestamp.getTime())) return "Updated recently";
return new Intl.DateTimeFormat("en-US", {
dateStyle: "medium",
timeStyle: "short",
}).format(timestamp);
}
function cx(...classNames: Array<string | false | undefined>): string {
return classNames.filter(Boolean).join(" ");
}
export default function ThreadsDrawer({
agentId,
threadId,
onThreadChange,
}: ThreadsDrawerProps) {
const [showArchived, setShowArchived] = useState(false);
// Start collapsed on narrow screens (tablet + phone) so the panel — which
// becomes an off-canvas overlay below 1024px — doesn't cover the content +
// chat on load. The drawer is client-mounted, so reading window here is safe
// and won't cause a hydration mismatch.
const [isOpen, setIsOpen] = useState(
() => typeof window === "undefined" || window.innerWidth > 1024,
);
const [pendingDelete, setPendingDelete] = useState<{
id: string;
title: string;
} | null>(null);
const deleteTriggerRef = useRef<HTMLElement | null>(null);
const {
threads,
archiveThread,
deleteThread,
error,
isLoading,
hasMoreThreads,
isFetchingMoreThreads,
fetchMoreThreads,
} = useThreads({
agentId,
includeArchived: showArchived,
limit: 20,
});
const restoreThread = useCallback(
async (id: string) => {
const response = await fetch(
`${RUNTIME_BASE_PATH}/threads/${encodeURIComponent(id)}`,
{
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ agentId, archived: false }),
},
);
if (!response.ok) {
throw new Error(
`Restore failed: ${response.status} ${response.statusText}`,
);
}
},
[agentId],
);
const hasMountedRef = useRef(false);
const hasLoadedOnceRef = useRef(false);
const stableThreadsRef = useRef<DrawerThread[]>(threads);
const previousThreadIdsRef = useRef<Set<string>>(new Set());
const previousNamesRef = useRef<Map<string, string | null>>(new Map());
const entryTimeoutsRef = useRef<Map<string, number>>(new Map());
const titleTimeoutsRef = useRef<Map<string, number>>(new Map());
if (!isLoading) {
hasLoadedOnceRef.current = true;
stableThreadsRef.current = threads;
}
const displayThreads: DrawerThread[] =
isLoading && hasLoadedOnceRef.current ? stableThreadsRef.current : threads;
const [enteringThreadIds, setEnteringThreadIds] = useState<
Record<string, true>
>({});
const [revealedTitleIds, setRevealedTitleIds] = useState<
Record<string, true>
>({});
useEffect(() => {
return () => {
for (const timeoutId of entryTimeoutsRef.current.values()) {
window.clearTimeout(timeoutId);
}
for (const timeoutId of titleTimeoutsRef.current.values()) {
window.clearTimeout(timeoutId);
}
};
}, []);
useEffect(() => {
// Skip diffing while the store is refetching (e.g. after a filter change
// clears the list). Otherwise every thread would be treated as newly
// added once the new page lands.
if (isLoading) return;
const nextThreadIds = new Set(threads.map((t) => t.id));
if (!hasMountedRef.current) {
hasMountedRef.current = true;
previousThreadIdsRef.current = nextThreadIds;
previousNamesRef.current = new Map(threads.map((t) => [t.id, t.name]));
return;
}
const addedThreadIds = threads
.filter((t) => !previousThreadIdsRef.current.has(t.id))
.map((t) => t.id);
if (addedThreadIds.length > 0) {
setEnteringThreadIds((current) => {
const next = { ...current };
for (const id of addedThreadIds) {
next[id] = true;
const existing = entryTimeoutsRef.current.get(id);
if (existing !== undefined) window.clearTimeout(existing);
const tid = window.setTimeout(() => {
setEnteringThreadIds((s) => {
const updated = { ...s };
delete updated[id];
return updated;
});
entryTimeoutsRef.current.delete(id);
}, THREAD_ENTRY_ANIMATION_MS);
entryTimeoutsRef.current.set(id, tid);
}
return next;
});
}
const renamedThreadIds = threads
.filter((t) => {
// Only reveal when an already-tracked thread's name transitions from
// null → named. Threads appearing for the first time (e.g. on a
// filter switch) already have their final name and should not trigger
// the title reveal animation — that would layer a blur/translateY
// onto the row's enter animation and produce a visible jitter.
if (!previousNamesRef.current.has(t.id)) return false;
const prev = previousNamesRef.current.get(t.id) ?? null;
return prev === null && t.name !== null;
})
.map((t) => t.id);
if (renamedThreadIds.length > 0) {
setRevealedTitleIds((current) => {
const next = { ...current };
for (const id of renamedThreadIds) {
next[id] = true;
const existing = titleTimeoutsRef.current.get(id);
if (existing !== undefined) window.clearTimeout(existing);
const tid = window.setTimeout(() => {
setRevealedTitleIds((s) => {
const updated = { ...s };
delete updated[id];
return updated;
});
titleTimeoutsRef.current.delete(id);
}, TITLE_ANIMATION_MS);
titleTimeoutsRef.current.set(id, tid);
}
return next;
});
}
previousThreadIdsRef.current = nextThreadIds;
previousNamesRef.current = new Map(threads.map((t) => [t.id, t.name]));
}, [threads, isLoading]);
const isInitialLoading = isLoading && !hasLoadedOnceRef.current;
if (error) {
console.error("Unable to load threads", error);
}
if (!isOpen) {
return (
<aside
aria-label="Threads drawer"
className={cx(styles.drawer, styles.drawerClosed)}
>
<div className={styles.collapsedRail}>
{/* Native title here (not the styled ::after): the collapsed rail
sits at the viewport's left edge where a centered tooltip clips. */}
<button
aria-label="Open threads drawer"
title="Expand"
className={styles.iconButton}
type="button"
onClick={() => setIsOpen(true)}
>
<ChevronRight size={18} />
</button>
<button
aria-label="Create thread"
title="New thread"
className={styles.iconButton}
type="button"
onClick={() => onThreadChange(crypto.randomUUID())}
>
<Plus size={18} />
</button>
</div>
</aside>
);
}
const closeDeleteDialog = () => {
setPendingDelete(null);
const trigger = deleteTriggerRef.current;
deleteTriggerRef.current = null;
trigger?.focus?.();
};
return (
<>
<aside
aria-label="Threads drawer"
className={cx(styles.drawer, styles.drawerOpen)}
>
<div className={styles.drawerSurface}>
<div className={styles.drawerHeader}>
<div className={styles.drawerHeaderMain}>
<h2 className={styles.drawerTitle}>Threads</h2>
</div>
<div className={styles.headerActions}>
<button
aria-label="Create thread"
className={styles.newThreadButton}
type="button"
onClick={() => onThreadChange(crypto.randomUUID())}
>
<Plus size={14} />
<span>New thread</span>
</button>
<button
aria-label="Collapse threads drawer"
className={styles.iconButton}
type="button"
onClick={() => setIsOpen(false)}
>
<ChevronLeft size={18} />
</button>
</div>
</div>
<div className={styles.filterBar}>
<div
aria-label="Thread filter"
className={styles.segmented}
role="tablist"
>
<button
aria-selected={!showArchived}
className={cx(
styles.segmentedOption,
!showArchived && styles.segmentedOptionActive,
)}
role="tab"
type="button"
onClick={() => setShowArchived(false)}
>
Active
</button>
<button
aria-selected={showArchived}
className={cx(
styles.segmentedOption,
showArchived && styles.segmentedOptionActive,
)}
role="tab"
type="button"
onClick={() => setShowArchived(true)}
>
All
</button>
</div>
</div>
<div className={styles.drawerContent}>
{error ? (
<div className={styles.emptyState}>
<div className={styles.emptyCard}>
<p className={styles.emptyTitle}>
Couldn&rsquo;t load threads
</p>
<p className={styles.emptyMessage}>
The thread list failed to load. Try reloading the page.
</p>
<button
className={styles.loadMoreButton}
type="button"
onClick={() => window.location.reload()}
>
Reload
</button>
</div>
</div>
) : isInitialLoading ? (
<div
aria-busy="true"
aria-label="Loading threads"
className={styles.loadingList}
role="status"
>
{Array.from({ length: 4 }).map((_, i) => (
<div key={i} className={styles.loadingRow}>
<span className={styles.loadingAccent} />
<span className={styles.loadingBody}>
<span className={styles.loadingTitleBar} />
<span className={styles.loadingMetaBar} />
</span>
</div>
))}
</div>
) : displayThreads.length === 0 ? (
<div className={styles.emptyState}>
<div className={styles.emptyCard}>
<p className={styles.emptyTitle}>No threads yet</p>
<p className={styles.emptyMessage}>
Create a thread to start a fresh conversation.
</p>
</div>
</div>
) : (
<div className={styles.threadList}>
{displayThreads.map((thread) => {
const hasTitle = thread.name !== null;
const title = thread.name ?? UNTITLED_THREAD_LABEL;
return (
<div key={thread.id} className={styles.threadRow}>
<button
aria-current={
threadId === thread.id ? "page" : undefined
}
className={cx(
styles.threadItem,
threadId === thread.id && styles.threadItemSelected,
enteringThreadIds[thread.id] &&
styles.threadItemAnimatingIn,
thread.archived && styles.threadItemArchived,
)}
type="button"
onClick={() => onThreadChange(thread.id)}
>
<span aria-hidden className={styles.threadAccent} />
<span className={styles.threadBody}>
<span
className={cx(
styles.threadTitle,
!hasTitle && styles.threadTitlePlaceholder,
revealedTitleIds[thread.id] &&
styles.threadTitleAnimated,
)}
>
{title}
{thread.archived && (
<span className={styles.archivedBadge}>
Archived
</span>
)}
</span>
<span className={styles.threadMeta}>
{formatThreadTimestamp(
thread.lastRunAt ?? thread.updatedAt,
)}
</span>
</span>
</button>
<div className={styles.threadActions}>
{thread.archived ? (
<button
aria-label={`Restore ${title}`}
className={cx(
styles.iconButton,
styles.threadActionButton,
styles.tooltip,
)}
data-tooltip="Restore thread"
type="button"
onClick={() => {
restoreThread(thread.id).catch((err: unknown) => {
console.error("Unable to restore thread", err);
});
}}
>
<ArchiveRestore size={14} />
</button>
) : (
<button
aria-label={`Archive ${title}`}
className={cx(
styles.iconButton,
styles.threadActionButton,
styles.tooltip,
)}
data-tooltip="Archive thread"
type="button"
onClick={() => {
if (threadId === thread.id)
onThreadChange(undefined);
archiveThread(thread.id).catch((err: unknown) => {
console.error("Unable to archive thread", err);
});
}}
>
<Archive size={14} />
</button>
)}
<button
aria-label={`Delete ${title}`}
className={cx(
styles.iconButton,
styles.threadActionButton,
styles.deleteButton,
styles.tooltip,
)}
data-tooltip="Delete thread"
type="button"
onClick={(e) => {
deleteTriggerRef.current = e.currentTarget;
setPendingDelete({ id: thread.id, title });
}}
>
<Trash2 size={14} />
</button>
</div>
</div>
);
})}
{hasMoreThreads && (
<button
className={styles.loadMoreButton}
disabled={isFetchingMoreThreads}
type="button"
onClick={fetchMoreThreads}
>
{isFetchingMoreThreads ? "Loading\u2026" : "Load more"}
</button>
)}
</div>
)}
</div>
</div>
</aside>
{pendingDelete && (
<ConfirmDialog
confirmLabel="Delete"
description={`Delete "${pendingDelete.title}"? This cannot be undone.`}
destructive
title="Delete thread"
onCancel={closeDeleteDialog}
onConfirm={() => {
const { id } = pendingDelete;
closeDeleteDialog();
if (threadId === id) onThreadChange(undefined);
deleteThread(id).catch((err: unknown) => {
console.error("Unable to delete thread", err);
});
}}
/>
)}
</>
);
}
interface ConfirmDialogProps {
title: string;
description: string;
confirmLabel: string;
cancelLabel?: string;
destructive?: boolean;
onConfirm: () => void;
onCancel: () => void;
}
function ConfirmDialog({
title,
description,
confirmLabel,
cancelLabel = "Cancel",
destructive = false,
onConfirm,
onCancel,
}: ConfirmDialogProps) {
const titleId = useId();
const descId = useId();
useEffect(() => {
const onKey = (e: KeyboardEvent) => {
if (e.key === "Escape") onCancel();
};
window.addEventListener("keydown", onKey);
return () => window.removeEventListener("keydown", onKey);
}, [onCancel]);
if (typeof document === "undefined") return null;
return createPortal(
<div
className={styles.dialogOverlay}
role="presentation"
onClick={onCancel}
>
<div
aria-describedby={descId}
aria-labelledby={titleId}
aria-modal="true"
className={styles.dialog}
role="dialog"
onClick={(e) => e.stopPropagation()}
>
<h3 className={styles.dialogTitle} id={titleId}>
{title}
</h3>
<p className={styles.dialogDescription} id={descId}>
{description}
</p>
<div className={styles.dialogActions}>
<button
autoFocus
className={cx(styles.dialogButton, styles.dialogButtonSecondary)}
type="button"
onClick={onCancel}
>
{cancelLabel}
</button>
<button
className={cx(
styles.dialogButton,
destructive
? styles.dialogButtonDestructive
: styles.dialogButtonPrimary,
)}
type="button"
onClick={onConfirm}
>
{confirmLabel}
</button>
</div>
</div>
</div>,
document.body,
);
}
-991
View File
@@ -1,991 +0,0 @@
{
"name": "agent",
"version": "0.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "agent",
"version": "0.0.1",
"license": "ISC",
"dependencies": {
"@copilotkit/sdk-js": "1.56.5",
"@langchain/core": "1.1.44",
"@langchain/langgraph": "1.3.0",
"@langchain/openai": "1.4.4",
"langchain": "1.3.4"
},
"devDependencies": {
"@types/html-to-text": "^9.0.4",
"@types/node": "^22.9.0",
"typescript": "^5.6.3"
}
},
"node_modules/@ag-ui/client": {
"version": "0.0.55",
"resolved": "https://registry.npmjs.org/@ag-ui/client/-/client-0.0.55.tgz",
"integrity": "sha512-cyTY0S1UK3ynFCtLh6XPkxECQiYL6XvFcAei5FD4yYzln5agSCZ3cAmdD86mwE4UbS5teS3Nci8Q5tEAjrRRgA==",
"peer": true,
"dependencies": {
"@ag-ui/core": "0.0.55",
"@ag-ui/encoder": "0.0.55",
"@ag-ui/proto": "0.0.55",
"@types/uuid": "^10.0.0",
"compare-versions": "^6.1.1",
"fast-json-patch": "^3.1.1",
"rxjs": "7.8.1",
"untruncate-json": "^0.0.1",
"uuid": "^11.1.0",
"zod": "^3.22.4"
}
},
"node_modules/@ag-ui/core": {
"version": "0.0.55",
"resolved": "https://registry.npmjs.org/@ag-ui/core/-/core-0.0.55.tgz",
"integrity": "sha512-Pj7Ke0NsCxbCFgI3xK5YE56LaMRxnXnyeDUgDFTYxeF6KZDcSf5E0x2gB6/37w6bE0hcn/LRNPFd8Es18eIEzA==",
"peer": true,
"dependencies": {
"zod": "^3.22.4"
}
},
"node_modules/@ag-ui/encoder": {
"version": "0.0.55",
"resolved": "https://registry.npmjs.org/@ag-ui/encoder/-/encoder-0.0.55.tgz",
"integrity": "sha512-co4RB8kCatQ/+sBOR+nmNMzuKKWynHD73U/MTn9yG8rdznG51KuAPlQAwTP03VChFgO5GfNqEAzcGf5dR6jyMg==",
"peer": true,
"dependencies": {
"@ag-ui/core": "0.0.55",
"@ag-ui/proto": "0.0.55"
}
},
"node_modules/@ag-ui/langgraph": {
"version": "0.0.31",
"resolved": "https://registry.npmjs.org/@ag-ui/langgraph/-/langgraph-0.0.31.tgz",
"integrity": "sha512-mK24pfQZiV5SlnDLhTka+873gw7QQOAWXqqDSnwkuyoQQQFX7KC8xZR+4Da2dWqyVhbhNPx+amE16X7twS1wcg==",
"dependencies": {
"@langchain/core": "^1.1.40",
"@langchain/langgraph-sdk": "^1.8.8",
"langchain": ">=1.2.0",
"partial-json": "^0.1.7",
"rxjs": "7.8.1"
},
"peerDependencies": {
"@ag-ui/client": ">=0.0.42",
"@ag-ui/core": ">=0.0.42"
}
},
"node_modules/@ag-ui/proto": {
"version": "0.0.55",
"resolved": "https://registry.npmjs.org/@ag-ui/proto/-/proto-0.0.55.tgz",
"integrity": "sha512-DNavmWA/dL3u4mpB+g/NPzF7XrYLjVFgmS8CnSOsenrmO64XVoR5RrbQghzaKvP9VNkhvdFI9tllpItfE3Pryw==",
"peer": true,
"dependencies": {
"@ag-ui/core": "0.0.55",
"@bufbuild/protobuf": "^2.2.5",
"@protobuf-ts/protoc": "^2.11.1"
}
},
"node_modules/@bufbuild/protobuf": {
"version": "2.12.0",
"resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.12.0.tgz",
"integrity": "sha512-B/XlCaFIP8LOwzo+bz5uFzATYokcwCKQcghqnlfwSmM5eX/qTkvDBnDPs+gXtX/RyjxJ4DRikECcPJbyALA8FA==",
"license": "(Apache-2.0 AND BSD-3-Clause)"
},
"node_modules/@cfworker/json-schema": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@cfworker/json-schema/-/json-schema-4.1.1.tgz",
"integrity": "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==",
"license": "MIT"
},
"node_modules/@copilotkit/license-verifier": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@copilotkit/license-verifier/-/license-verifier-0.2.0.tgz",
"integrity": "sha512-hliCifqy5a65YTozgRckuQmvBEQlt4L2PhbpSDY6fb/TKqPHyNDJgItRSnOpxOVDqvEfHEbUUqw3NaD88ZtdJA=="
},
"node_modules/@copilotkit/sdk-js": {
"version": "1.56.5",
"resolved": "https://registry.npmjs.org/@copilotkit/sdk-js/-/sdk-js-1.56.5.tgz",
"integrity": "sha512-v4jZdZaiRVH+xtJYBSjltiTWih6JKgG0Gk2ospxxrHLDKEGcwvm+GtQIpwf0Arb5nqFa5OnxV62EPC70IXRAdg==",
"license": "MIT",
"dependencies": {
"@ag-ui/langgraph": "0.0.31",
"@copilotkit/shared": "1.56.5"
},
"peerDependencies": {
"@langchain/core": ">=0.4.0 <2.0.0",
"@langchain/langgraph": ">=0.4.0 <2.0.0",
"langchain": ">=1.0.0",
"typescript": "^5.2.3",
"zod": "^3.23.3 || ^3.24.0 || ^3.25.0"
}
},
"node_modules/@copilotkit/shared": {
"version": "1.56.5",
"resolved": "https://registry.npmjs.org/@copilotkit/shared/-/shared-1.56.5.tgz",
"integrity": "sha512-jK2iEa+jRgWYXOw/v09RaU9txX5wNAYIrGl/SO405uzbC5mi0cYgXhJ3PC+VjNM7rlH//LRqa0+ELJO0UBwfPA==",
"license": "MIT",
"dependencies": {
"@ag-ui/client": "0.0.53",
"@copilotkit/license-verifier": "0.2.0",
"@segment/analytics-node": "^2.1.2",
"@standard-schema/spec": "^1.0.0",
"chalk": "4.1.2",
"graphql": "^16.8.1",
"partial-json": "^0.1.7",
"uuid": "^11.1.0",
"zod": "^3.23.3",
"zod-to-json-schema": "^3.23.5"
},
"peerDependencies": {
"@ag-ui/core": ">=0.0.48"
}
},
"node_modules/@copilotkit/shared/node_modules/@ag-ui/client": {
"version": "0.0.53",
"resolved": "https://registry.npmjs.org/@ag-ui/client/-/client-0.0.53.tgz",
"integrity": "sha512-Mkup36KUp0KXy9v89QtAOWDUoh8H1s1Vgl4zvQv9HqXuAK1TkbtpXJHpbgZJXIxTqd54KT6yCurmC2UkOP7FDQ==",
"dependencies": {
"@ag-ui/core": "0.0.53",
"@ag-ui/encoder": "0.0.53",
"@ag-ui/proto": "0.0.53",
"@types/uuid": "^10.0.0",
"compare-versions": "^6.1.1",
"fast-json-patch": "^3.1.1",
"rxjs": "7.8.1",
"untruncate-json": "^0.0.1",
"uuid": "^11.1.0",
"zod": "^3.22.4"
}
},
"node_modules/@copilotkit/shared/node_modules/@ag-ui/client/node_modules/@ag-ui/core": {
"version": "0.0.53",
"resolved": "https://registry.npmjs.org/@ag-ui/core/-/core-0.0.53.tgz",
"integrity": "sha512-11UocR7fFdMWw503bWCX2IOK15vbWfxT11Mn9xOiPBVO/UVcn57ywGrlLL4UaBlPgmUTvuzr2yYR2ElSqiN2wQ==",
"dependencies": {
"zod": "^3.22.4"
}
},
"node_modules/@copilotkit/shared/node_modules/@ag-ui/encoder": {
"version": "0.0.53",
"resolved": "https://registry.npmjs.org/@ag-ui/encoder/-/encoder-0.0.53.tgz",
"integrity": "sha512-bAOcfVdm6U4H6G6tW+DZfwPEQm1w/snVBTwaFn9nJcEMW69M7/HZuwvEc/7Zo0rK1jRL32N/j60PwTAeky19fw==",
"dependencies": {
"@ag-ui/core": "0.0.53",
"@ag-ui/proto": "0.0.53"
}
},
"node_modules/@copilotkit/shared/node_modules/@ag-ui/encoder/node_modules/@ag-ui/core": {
"version": "0.0.53",
"resolved": "https://registry.npmjs.org/@ag-ui/core/-/core-0.0.53.tgz",
"integrity": "sha512-11UocR7fFdMWw503bWCX2IOK15vbWfxT11Mn9xOiPBVO/UVcn57ywGrlLL4UaBlPgmUTvuzr2yYR2ElSqiN2wQ==",
"dependencies": {
"zod": "^3.22.4"
}
},
"node_modules/@copilotkit/shared/node_modules/@ag-ui/proto": {
"version": "0.0.53",
"resolved": "https://registry.npmjs.org/@ag-ui/proto/-/proto-0.0.53.tgz",
"integrity": "sha512-swjz22xWT8YUZt5OhmUwkARDQdwt8XM1hmGZbQrhRnNPXKwrKJX9ELlbnQ4iFUQIKkMWpphzE3vA3yNKs2bbKw==",
"dependencies": {
"@ag-ui/core": "0.0.53",
"@bufbuild/protobuf": "^2.2.5",
"@protobuf-ts/protoc": "^2.11.1"
}
},
"node_modules/@copilotkit/shared/node_modules/@ag-ui/proto/node_modules/@ag-ui/core": {
"version": "0.0.53",
"resolved": "https://registry.npmjs.org/@ag-ui/core/-/core-0.0.53.tgz",
"integrity": "sha512-11UocR7fFdMWw503bWCX2IOK15vbWfxT11Mn9xOiPBVO/UVcn57ywGrlLL4UaBlPgmUTvuzr2yYR2ElSqiN2wQ==",
"dependencies": {
"zod": "^3.22.4"
}
},
"node_modules/@langchain/core": {
"version": "1.1.44",
"resolved": "https://registry.npmjs.org/@langchain/core/-/core-1.1.44.tgz",
"integrity": "sha512-RePW1IjGCHr9ua2vcby3aE8mOOz3EnwDZxMEGbNDT91kf14eqkJqxDXvaZFviGdcN9DTrxM5RPQNAHmwSm4tbg==",
"license": "MIT",
"dependencies": {
"@cfworker/json-schema": "^4.0.2",
"@standard-schema/spec": "^1.1.0",
"ansi-styles": "^5.0.0",
"camelcase": "6",
"decamelize": "1.2.0",
"js-tiktoken": "^1.0.12",
"langsmith": ">=0.5.0 <1.0.0",
"mustache": "^4.2.0",
"p-queue": "^6.6.2",
"zod": "^3.25.76 || ^4"
},
"engines": {
"node": ">=20"
}
},
"node_modules/@langchain/langgraph": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@langchain/langgraph/-/langgraph-1.3.0.tgz",
"integrity": "sha512-QvhTjiyqFPz81A+y6LHs223w6DTjv5+882DT4mup72bd72rRhNjTYo5fhes5um0swnKArvY/arc7KeFInfHHWw==",
"license": "MIT",
"dependencies": {
"@langchain/langgraph-checkpoint": "^1.0.2",
"@langchain/langgraph-sdk": "~1.9.0",
"@langchain/protocol": "^0.0.15",
"@standard-schema/spec": "1.1.0",
"uuid": "^10.0.0"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@langchain/core": "^1.1.44",
"zod": "^3.25.32 || ^4.2.0",
"zod-to-json-schema": "^3.x"
},
"peerDependenciesMeta": {
"zod-to-json-schema": {
"optional": true
}
}
},
"node_modules/@langchain/langgraph-checkpoint": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@langchain/langgraph-checkpoint/-/langgraph-checkpoint-1.0.4.tgz",
"integrity": "sha512-1y5MgZ0gXXrtmoy56e3kaBChI3GwFPIKl27xkrHwN+VE/3iUsyr9gO3Jtp7kdKAe6diZGbcas5bdC/r0yUwTZA==",
"license": "MIT",
"dependencies": {
"uuid": "^14.0.0"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@langchain/core": "^1.1.44"
}
},
"node_modules/@langchain/langgraph-checkpoint/node_modules/uuid": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz",
"integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist-node/bin/uuid"
}
},
"node_modules/@langchain/langgraph-sdk": {
"version": "1.9.13",
"resolved": "https://registry.npmjs.org/@langchain/langgraph-sdk/-/langgraph-sdk-1.9.13.tgz",
"integrity": "sha512-c3yq7kfGncMxJT9YCua5KGytTQbEyZhhjt6y3wSFHvuhNXGTJV5kBctK6jh1xFrWKwjFcdqRtVBE8pqz1GiSrA==",
"license": "MIT",
"dependencies": {
"@langchain/protocol": "^0.0.16",
"@types/json-schema": "^7.0.15",
"p-queue": "^9.0.1",
"p-retry": "^7.1.1",
"uuid": "^14.0.0"
},
"peerDependencies": {
"@langchain/core": "^1.1.44",
"react": "^18 || ^19",
"react-dom": "^18 || ^19",
"svelte": "^4.0.0 || ^5.0.0",
"vue": "^3.0.0"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"react-dom": {
"optional": true
},
"svelte": {
"optional": true
},
"vue": {
"optional": true
}
}
},
"node_modules/@langchain/langgraph-sdk/node_modules/@langchain/protocol": {
"version": "0.0.16",
"resolved": "https://registry.npmjs.org/@langchain/protocol/-/protocol-0.0.16.tgz",
"integrity": "sha512-ws+J7MaHyhO5dG7f0vdyHQiUn9hoCnki0f3crJPa4MCTGzcRC39jYSCghyrGtBPYQnZbUQiGyRVpW3z3M8IpJg==",
"license": "MIT"
},
"node_modules/@langchain/langgraph-sdk/node_modules/eventemitter3": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz",
"integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
"license": "MIT"
},
"node_modules/@langchain/langgraph-sdk/node_modules/p-queue": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/p-queue/-/p-queue-9.3.0.tgz",
"integrity": "sha512-7NED7xhQ74Ngp4JP/2e0VZHp7vSWfJfqeiR92jPgxsz6m0Se4P03YoTKa9dDXyZ3r6P616gUXttrB6nnHYKang==",
"license": "MIT",
"dependencies": {
"eventemitter3": "^5.0.4",
"p-timeout": "^7.0.0"
},
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@langchain/langgraph-sdk/node_modules/p-timeout": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-7.0.1.tgz",
"integrity": "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==",
"license": "MIT",
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@langchain/langgraph-sdk/node_modules/uuid": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz",
"integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist-node/bin/uuid"
}
},
"node_modules/@langchain/langgraph/node_modules/uuid": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
"deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/@langchain/openai": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/@langchain/openai/-/openai-1.4.4.tgz",
"integrity": "sha512-mRr/X5rvlwPj6cSXPxbL+CtOqYANO1/+CQ3Z+5t48kWnrlgPYOazmA+UAWvqQOuwJ6LaYn3SFrt43rR4lte/Ow==",
"license": "MIT",
"dependencies": {
"js-tiktoken": "^1.0.12",
"openai": "^6.32.0",
"zod": "^3.25.76 || ^4"
},
"engines": {
"node": ">=20"
},
"peerDependencies": {
"@langchain/core": "^1.1.39"
}
},
"node_modules/@langchain/protocol": {
"version": "0.0.15",
"resolved": "https://registry.npmjs.org/@langchain/protocol/-/protocol-0.0.15.tgz",
"integrity": "sha512-MllvbpMjqHevUm+v94M422mH7XKN+wGCvJRBVROTWBotEDOATYB4Ktk2UheYP859y9o2LlhtPek5t1T9eyfAbQ==",
"license": "MIT"
},
"node_modules/@lukeed/csprng": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz",
"integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/@lukeed/uuid": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@lukeed/uuid/-/uuid-2.0.1.tgz",
"integrity": "sha512-qC72D4+CDdjGqJvkFMMEAtancHUQ7/d/tAiHf64z8MopFDmcrtbcJuerDtFceuAfQJ2pDSfCKCtbqoGBNnwg0w==",
"license": "MIT",
"dependencies": {
"@lukeed/csprng": "^1.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@protobuf-ts/protoc": {
"version": "2.11.1",
"resolved": "https://registry.npmjs.org/@protobuf-ts/protoc/-/protoc-2.11.1.tgz",
"integrity": "sha512-mUZJaV0daGO6HUX90o/atzQ6A7bbN2RSuHtdwo8SSF2Qoe3zHwa4IHyCN1evftTeHfLmdz+45qo47sL+5P8nyg==",
"license": "Apache-2.0",
"bin": {
"protoc": "protoc.js"
}
},
"node_modules/@segment/analytics-core": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/@segment/analytics-core/-/analytics-core-1.8.2.tgz",
"integrity": "sha512-5FDy6l8chpzUfJcNlIcyqYQq4+JTUynlVoCeCUuVz+l+6W0PXg+ljKp34R4yLVCcY5VVZohuW+HH0VLWdwYVAg==",
"license": "MIT",
"dependencies": {
"@lukeed/uuid": "^2.0.0",
"@segment/analytics-generic-utils": "1.2.0",
"dset": "^3.1.4",
"tslib": "^2.4.1"
}
},
"node_modules/@segment/analytics-generic-utils": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@segment/analytics-generic-utils/-/analytics-generic-utils-1.2.0.tgz",
"integrity": "sha512-DfnW6mW3YQOLlDQQdR89k4EqfHb0g/3XvBXkovH1FstUN93eL1kfW9CsDcVQyH3bAC5ZsFyjA/o/1Q2j0QeoWw==",
"license": "MIT",
"dependencies": {
"tslib": "^2.4.1"
}
},
"node_modules/@segment/analytics-node": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@segment/analytics-node/-/analytics-node-2.3.0.tgz",
"integrity": "sha512-fOXLL8uY0uAWw/sTLmezze80hj8YGgXXlAfvSS6TUmivk4D/SP0C0sxnbpFdkUzWg2zT64qWIZj26afEtSnxUA==",
"license": "MIT",
"dependencies": {
"@lukeed/uuid": "^2.0.0",
"@segment/analytics-core": "1.8.2",
"@segment/analytics-generic-utils": "1.2.0",
"buffer": "^6.0.3",
"jose": "^5.1.0",
"node-fetch": "^2.6.7",
"tslib": "^2.4.1"
},
"engines": {
"node": ">=20"
}
},
"node_modules/@standard-schema/spec": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
"integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
"license": "MIT"
},
"node_modules/@types/html-to-text": {
"version": "9.0.4",
"resolved": "https://registry.npmjs.org/@types/html-to-text/-/html-to-text-9.0.4.tgz",
"integrity": "sha512-pUY3cKH/Nm2yYrEmDlPR1mR7yszjGx4DrwPjQ702C4/D5CwHuZTgZdIdwPkRbcuhs7BAh2L5rg3CL5cbRiGTCQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.19.19",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz",
"integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
}
},
"node_modules/@types/uuid": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
"integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
"license": "MIT"
},
"node_modules/ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"node_modules/camelcase": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/chalk/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/compare-versions": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz",
"integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==",
"license": "MIT"
},
"node_modules/decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/dset": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz",
"integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==",
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
"license": "MIT"
},
"node_modules/fast-json-patch": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz",
"integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==",
"license": "MIT"
},
"node_modules/graphql": {
"version": "16.14.1",
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.14.1.tgz",
"integrity": "sha512-cQOsSMS/IrDz82PVyRDvf/Q1F/bRbBVjJlh+xYOkI1qw2bWRvWGiWc+m2O0d6l4Bt1fyY+8kzJ8JFWGJqNeDBg==",
"license": "MIT",
"engines": {
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
}
},
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "BSD-3-Clause"
},
"node_modules/is-network-error": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.2.tgz",
"integrity": "sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==",
"license": "MIT",
"engines": {
"node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/jose": {
"version": "5.10.0",
"resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz",
"integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/js-tiktoken": {
"version": "1.0.21",
"resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.21.tgz",
"integrity": "sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==",
"license": "MIT",
"dependencies": {
"base64-js": "^1.5.1"
}
},
"node_modules/langchain": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/langchain/-/langchain-1.3.4.tgz",
"integrity": "sha512-umrD+ZC6vr0Q0U1lC5PoIMMQqgnP+7QhaIdAXCeZiSX2GPVBiVR7Ed2ZR+3MPvz1yWrRtIm17wPaovkND+wOXg==",
"license": "MIT",
"dependencies": {
"@langchain/langgraph": "^1.2.9",
"@langchain/langgraph-checkpoint": "^1.0.1",
"langsmith": ">=0.5.0 <1.0.0",
"uuid": "^11.1.0",
"zod": "^3.25.76 || ^4"
},
"engines": {
"node": ">=20"
},
"peerDependencies": {
"@langchain/core": "^1.1.41"
}
},
"node_modules/langsmith": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.7.3.tgz",
"integrity": "sha512-Gg+IeRGoF1/aStu80aEnIXJCu+N6+4NoV4tAVFS51ZPRBsRa2KG0LkS7K7/ryZ/yES7O9xdqah5QuuWMIeMjQw==",
"license": "MIT",
"dependencies": {
"p-queue": "6.6.2"
},
"peerDependencies": {
"@opentelemetry/api": "*",
"@opentelemetry/exporter-trace-otlp-proto": "*",
"@opentelemetry/sdk-trace-base": "*",
"openai": "*",
"ws": ">=7"
},
"peerDependenciesMeta": {
"@opentelemetry/api": {
"optional": true
},
"@opentelemetry/exporter-trace-otlp-proto": {
"optional": true
},
"@opentelemetry/sdk-trace-base": {
"optional": true
},
"openai": {
"optional": true
},
"ws": {
"optional": true
}
}
},
"node_modules/mustache": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
"integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
"license": "MIT",
"bin": {
"mustache": "bin/mustache"
}
},
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/openai": {
"version": "6.41.0",
"resolved": "https://registry.npmjs.org/openai/-/openai-6.41.0.tgz",
"integrity": "sha512-IGWPopZq6Rjoynjfb3NSLf/z2MTw7UiOsm9TAjPGAjUESH7Uq41Trg4QWehBEn58p74i+m7uoRPV2vXcpPXhyA==",
"license": "Apache-2.0",
"peerDependencies": {
"ws": "^8.18.0",
"zod": "^3.25 || ^4.0"
},
"peerDependenciesMeta": {
"ws": {
"optional": true
},
"zod": {
"optional": true
}
}
},
"node_modules/p-finally": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
"integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/p-queue": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz",
"integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==",
"license": "MIT",
"dependencies": {
"eventemitter3": "^4.0.4",
"p-timeout": "^3.2.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-retry": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-7.1.1.tgz",
"integrity": "sha512-J5ApzjyRkkf601HpEeykoiCvzHQjWxPAHhyjFcEUP2SWq0+35NKh8TLhpLw+Dkq5TZBFvUM6UigdE9hIVYTl5w==",
"license": "MIT",
"dependencies": {
"is-network-error": "^1.1.0"
},
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-timeout": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz",
"integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==",
"license": "MIT",
"dependencies": {
"p-finally": "^1.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/partial-json": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/partial-json/-/partial-json-0.1.7.tgz",
"integrity": "sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==",
"license": "MIT"
},
"node_modules/rxjs": {
"version": "7.8.1",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
"integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"license": "MIT"
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
"node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true,
"license": "MIT"
},
"node_modules/untruncate-json": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/untruncate-json/-/untruncate-json-0.0.1.tgz",
"integrity": "sha512-4W9enDK4X1y1s2S/Rz7ysw6kDuMS3VmRjMFg7GZrNO+98OSe+x5Lh7PKYoVjy3lW/1wmhs6HW0lusnQRHgMarA==",
"license": "MIT"
},
"node_modules/uuid": {
"version": "11.1.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz",
"integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist/esm/bin/uuid"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"license": "BSD-2-Clause"
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"license": "MIT",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/zod": {
"version": "3.25.76",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/zod-to-json-schema": {
"version": "3.25.2",
"resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz",
"integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==",
"license": "ISC",
"peerDependencies": {
"zod": "^3.25.28 || ^4"
}
}
}
}
@@ -8,7 +8,6 @@ const integrationsDir = path.join(repoRoot, "examples", "integrations");
const migratedIntegrations = [
"crewai-flows",
"llamaindex",
"langgraph-fastapi",
"pydantic-ai",
"mcp-apps",
"agent-spec",