@agent-native/dispatch 0.16.2 → 0.16.4
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/actions/get-agent-thread-debug.d.ts +9 -0
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +2 -0
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/list-agent-run-failures.d.ts +61 -0
- package/dist/actions/list-agent-run-failures.d.ts.map +1 -0
- package/dist/actions/list-agent-run-failures.js +38 -0
- package/dist/actions/list-agent-run-failures.js.map +1 -0
- package/dist/actions/provider-api-register.d.ts +12 -12
- package/dist/actions/upsert-destination.d.ts +12 -12
- package/dist/actions/view-screen.js +32 -5
- package/dist/actions/view-screen.js.map +1 -1
- package/dist/hooks/use-navigation-state.d.ts +6 -0
- package/dist/hooks/use-navigation-state.d.ts.map +1 -1
- package/dist/hooks/use-navigation-state.js +30 -0
- package/dist/hooks/use-navigation-state.js.map +1 -1
- package/dist/routes/pages/thread-debug.d.ts.map +1 -1
- package/dist/routes/pages/thread-debug.js +291 -77
- package/dist/routes/pages/thread-debug.js.map +1 -1
- package/dist/server/lib/thread-debug-store.d.ts +72 -0
- package/dist/server/lib/thread-debug-store.d.ts.map +1 -1
- package/dist/server/lib/thread-debug-store.js +215 -19
- package/dist/server/lib/thread-debug-store.js.map +1 -1
- package/dist/server/plugins/agent-chat.js +1 -0
- package/dist/server/plugins/agent-chat.js.map +1 -1
- package/package.json +3 -3
- package/src/actions/index.ts +2 -0
- package/src/actions/list-agent-run-failures.ts +44 -0
- package/src/actions/view-screen.spec.ts +91 -0
- package/src/actions/view-screen.ts +34 -4
- package/src/hooks/use-navigation-state.spec.ts +45 -0
- package/src/hooks/use-navigation-state.ts +28 -0
- package/src/routes/pages/thread-debug.spec.tsx +272 -0
- package/src/routes/pages/thread-debug.tsx +843 -224
- package/src/server/lib/thread-debug-store.spec.ts +292 -16
- package/src/server/lib/thread-debug-store.ts +318 -22
- package/src/server/plugins/agent-chat.spec.ts +30 -0
- package/src/server/plugins/agent-chat.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-navigation-state.js","sourceRoot":"","sources":["../../src/hooks/use-navigation-state.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isAgentChatHomeHandoffActive,\n markAgentChatHomeHandoff,\n} from \"@agent-native/core/client/agent-chat\";\nimport {\n agentNativePath,\n appBasePath,\n appPath,\n} from \"@agent-native/core/client/api-path\";\nimport { extensionIdFromPathname } from \"@agent-native/core/client/extensions\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect } from \"react\";\nimport { useLocation, useNavigate } from \"react-router\";\n\nimport type {\n DispatchExtensionConfig,\n DispatchNavItem,\n} from \"../components/index.js\";\n\nexport interface NavigationState {\n view: string;\n path?: string;\n extensionId?: string;\n extensionSlug?: string;\n dreamId?: string;\n sourceId?: string;\n query?: string;\n threadId?: string;\n}\n\nexport function useNavigationState(extensions?: DispatchExtensionConfig) {\n const location = useLocation();\n const navigate = useNavigate();\n const qc = useQueryClient();\n\n // Sync current route to application state\n useEffect(() => {\n const localPathname = routerPath(location.pathname);\n const state = buildDispatchNavigationState(\n localPathname,\n location.search,\n extensions,\n );\n\n fetch(agentNativePath(\"/_agent-native/application-state/navigation\"), {\n method: \"PUT\",\n keepalive: true,\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(state),\n }).catch(() => {});\n }, [extensions, location.pathname, location.search]);\n\n // Listen for navigate commands from agent\n const { data: navCommand } = useQuery({\n queryKey: [\"navigate-command\"],\n queryFn: async () => {\n const res = await fetch(\n agentNativePath(\"/_agent-native/application-state/navigate\"),\n );\n if (!res.ok) return null;\n const data = await res.json();\n if (data) {\n // Return with a timestamp to ensure uniqueness\n return { ...data, _ts: Date.now() };\n }\n return null;\n },\n structuralSharing: false,\n });\n\n useEffect(() => {\n if (!navCommand) return;\n // Delete the one-shot command AFTER reading it\n fetch(agentNativePath(\"/_agent-native/application-state/navigate\"), {\n method: \"DELETE\",\n headers: { \"X-Agent-Native-CSRF\": \"1\" },\n }).catch(() => {});\n const cmd = navCommand as NavigationState;\n\n // Navigate to a specific path or resolve view name to path\n const resolvedPath =\n cmd.path || resolvePath(cmd.view, extensions, cmd) || \"/overview\";\n const path =\n cmd.view === \"dreams\" && cmd.dreamId && !resolvedPath.includes(\"?\")\n ? `${resolvedPath}?dreamId=${encodeURIComponent(cmd.dreamId)}`\n : resolvedPath;\n const nextPath = routerPath(path);\n if (\n isChatPath(routerPath(location.pathname)) &&\n !isChatPath(pathnameFromPath(nextPath))\n ) {\n if (isAgentChatHomeHandoffActive(\"dispatch\")) {\n markAgentChatHomeHandoff(\"dispatch\");\n }\n }\n navigate(nextPath);\n qc.setQueryData([\"navigate-command\"], null);\n }, [extensions, location.pathname, navCommand, navigate, qc]);\n}\n\nfunction pathnameFromPath(path: string): string {\n return path.split(/[?#]/, 1)[0] || \"/\";\n}\n\nfunction isChatPath(pathname: string): boolean {\n return pathname === \"/chat\" || pathname.startsWith(\"/chat/\");\n}\n\nfunction threadIdFromPath(pathname: string): string | null {\n const match = pathname.match(/^\\/chat\\/([^/]+)/);\n if (!match) return null;\n try {\n const value = decodeURIComponent(match[1]).trim();\n return value || null;\n } catch {\n return null;\n }\n}\n\nexport function buildDispatchNavigationState(\n pathname: string,\n search = \"\",\n extensions?: DispatchExtensionConfig,\n): NavigationState {\n const state: NavigationState = {\n view: resolveView(pathname, extensions),\n path: appPath(pathname),\n };\n\n const threadId = threadIdFromPath(pathname);\n if (threadId) state.threadId = threadId;\n\n const extensionId = extensionIdFromPathname(pathname);\n if (extensionId) {\n state.view = \"extensions\";\n state.extensionId = extensionId;\n const slug = extensionSlugFromPathname(pathname);\n if (slug) state.extensionSlug = slug;\n return state;\n }\n\n if (state.view === \"dreams\") {\n const params = new URLSearchParams(search);\n const dreamId = params.get(\"dreamId\");\n const sourceId = params.get(\"sourceId\");\n const query = params.get(\"query\");\n if (dreamId) state.dreamId = dreamId;\n if (sourceId) state.sourceId = sourceId;\n if (query) state.query = query;\n }\n\n return state;\n}\n\nfunction routerPath(path: string): string {\n const basePath = appBasePath();\n if (!basePath) return path;\n let result = path;\n // Iteratively strip basename. A path that arrives doubly-prefixed\n // (e.g. \"/dispatch/dispatch/overview\", possibly from a stale link or a\n // prior bug) would otherwise get partially stripped here and then\n // re-prefixed by react-router's basename, restoring the bad URL.\n for (let i = 0; i < 4; i += 1) {\n if (result === basePath) return \"/\";\n if (!result.startsWith(`${basePath}/`)) break;\n result = result.slice(basePath.length) || \"/\";\n }\n return result;\n}\n\nfunction extensionItemMatchesPath(\n item: DispatchNavItem,\n pathname: string,\n): boolean {\n if (item.match) {\n try {\n if (item.match(pathname)) return true;\n } catch {\n return false;\n }\n }\n return pathname === item.to || pathname.startsWith(`${item.to}/`);\n}\n\nfunction resolveExtensionView(\n pathname: string,\n extensions?: DispatchExtensionConfig,\n): string | undefined {\n return extensions?.navItems?.find((item) =>\n extensionItemMatchesPath(item, pathname),\n )?.id;\n}\n\nfunction resolveExtensionPath(\n view: string | undefined,\n extensions?: DispatchExtensionConfig,\n): string | undefined {\n if (!view) return undefined;\n return extensions?.navItems?.find((item) => item.id === view)?.to;\n}\n\nfunction resolveView(\n pathname: string,\n extensions?: DispatchExtensionConfig,\n): string {\n const extensionView = resolveExtensionView(pathname, extensions);\n if (extensionView) return extensionView;\n if (pathname === \"/extensions\" || pathname.startsWith(\"/extensions/\")) {\n return \"extensions\";\n }\n if (pathname.startsWith(\"/browser-chat\")) return \"browser-chat\";\n if (pathname.startsWith(\"/chat\")) return \"chat\";\n if (pathname.startsWith(\"/apps\")) return \"apps\";\n if (pathname.startsWith(\"/metrics\")) return \"metrics\";\n if (pathname.startsWith(\"/new-app\")) return \"new-app\";\n if (pathname.startsWith(\"/vault\")) return \"vault\";\n if (pathname.startsWith(\"/integrations\")) return \"integrations\";\n if (pathname.startsWith(\"/workspace\")) return \"workspace\";\n if (pathname.startsWith(\"/agents\")) return \"agents\";\n if (pathname.startsWith(\"/messaging\")) return \"messaging\";\n if (pathname.startsWith(\"/destinations\")) return \"destinations\";\n if (pathname.startsWith(\"/identities\")) return \"identities\";\n if (pathname.startsWith(\"/approvals\")) return \"approvals\";\n if (pathname.startsWith(\"/automations\")) return \"automations\";\n if (pathname.startsWith(\"/audit\")) return \"audit\";\n if (pathname.startsWith(\"/dreams\")) return \"dreams\";\n if (pathname.startsWith(\"/thread-debug\")) return \"thread-debug\";\n if (pathname.startsWith(\"/team\")) return \"settings\";\n return \"overview\";\n}\n\nfunction resolvePath(\n view?: string,\n extensions?: DispatchExtensionConfig,\n command?: Pick<NavigationState, \"extensionId\" | \"threadId\">,\n): string | undefined {\n switch (view) {\n case \"chat\":\n case \"ask\":\n return command?.threadId && command.threadId.trim()\n ? `/chat/${encodeURIComponent(command.threadId.trim())}`\n : \"/chat\";\n case \"overview\":\n return \"/overview\";\n case \"apps\":\n return \"/apps\";\n case \"metrics\":\n case \"usage\":\n return \"/metrics\";\n case \"new-app\":\n case \"create-app\":\n return \"/new-app\";\n case \"vault\":\n case \"secrets\":\n return \"/vault\";\n case \"integrations\":\n return \"/integrations\";\n case \"workspace\":\n case \"resources\":\n return \"/workspace\";\n case \"agents\":\n return \"/agents\";\n case \"messaging\":\n return \"/messaging\";\n case \"destinations\":\n case \"routes\":\n return \"/destinations\";\n case \"identities\":\n return \"/identities\";\n case \"approvals\":\n return \"/approvals\";\n case \"automations\":\n case \"jobs\":\n return \"/automations\";\n case \"audit\":\n return \"/audit\";\n case \"dreams\":\n return \"/dreams\";\n case \"thread-debug\":\n case \"threads\":\n return \"/thread-debug\";\n case \"team\":\n return \"/settings#organization\";\n case \"extensions\":\n return command?.extensionId\n ? `/extensions/${encodeURIComponent(command.extensionId)}`\n : \"/extensions\";\n default:\n return resolveExtensionPath(view, extensions);\n }\n}\n\nfunction extensionSlugFromPathname(pathname: string): string | undefined {\n const match = pathname.match(/^\\/extensions\\/[^/]+\\/([^/?#]+)/);\n if (!match?.[1]) return undefined;\n try {\n return decodeURIComponent(match[1]);\n } catch {\n return match[1];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"use-navigation-state.js","sourceRoot":"","sources":["../../src/hooks/use-navigation-state.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,eAAe,EACf,WAAW,EACX,OAAO,GACR,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAwBxD,MAAM,UAAU,kBAAkB,CAAC,UAAoC;IACrE,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IAE5B,0CAA0C;IAC1C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,aAAa,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,4BAA4B,CACxC,aAAa,EACb,QAAQ,CAAC,MAAM,EACf,UAAU,CACX,CAAC;QAEF,KAAK,CAAC,eAAe,CAAC,6CAA6C,CAAC,EAAE;YACpE,MAAM,EAAE,KAAK;YACb,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;SAC5B,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACrB,CAAC,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAErD,0CAA0C;IAC1C,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC;QACpC,QAAQ,EAAE,CAAC,kBAAkB,CAAC;QAC9B,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,eAAe,CAAC,2CAA2C,CAAC,CAC7D,CAAC;YACF,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,IAAI,IAAI,EAAE,CAAC;gBACT,+CAA+C;gBAC/C,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YACtC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,iBAAiB,EAAE,KAAK;KACzB,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,UAAU;YAAE,OAAO;QACxB,+CAA+C;QAC/C,KAAK,CAAC,eAAe,CAAC,2CAA2C,CAAC,EAAE;YAClE,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,EAAE,qBAAqB,EAAE,GAAG,EAAE;SACxC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACnB,MAAM,GAAG,GAAG,UAA6B,CAAC;QAE1C,2DAA2D;QAC3D,MAAM,YAAY,GAChB,GAAG,CAAC,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,IAAI,WAAW,CAAC;QACpE,MAAM,IAAI,GACR,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC;YACjE,CAAC,CAAC,GAAG,YAAY,YAAY,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;YAC9D,CAAC,CAAC,YAAY,CAAC;QACnB,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAClC,IACE,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACzC,CAAC,UAAU,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,EACvC,CAAC;YACD,IAAI,4BAA4B,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC7C,wBAAwB,CAAC,UAAU,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QACD,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnB,EAAE,CAAC,YAAY,CAAC,CAAC,kBAAkB,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY;IACpC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;AACzC,CAAC;AAED,SAAS,UAAU,CAAC,QAAgB;IAClC,OAAO,QAAQ,KAAK,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAgB;IACxC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACjD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,OAAO,KAAK,IAAI,IAAI,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,QAAgB,EAChB,MAAM,GAAG,EAAE,EACX,UAAoC;IAEpC,MAAM,KAAK,GAAoB;QAC7B,IAAI,EAAE,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC;QACvC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC;KACxB,CAAC;IAEF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,QAAQ;QAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAExC,MAAM,WAAW,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACtD,IAAI,WAAW,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC;QAC1B,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;QAChC,MAAM,IAAI,GAAG,yBAAyB,CAAC,QAAQ,CAAC,CAAC;QACjD,IAAI,IAAI;YAAE,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;QACrC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,OAAO;YAAE,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;QACrC,IAAI,QAAQ;YAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACxC,IAAI,KAAK;YAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;IACjC,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,IAAI;YAAE,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC;QACvC,IAAI,QAAQ;YAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACxC,IAAI,eAAe;YAAE,KAAK,CAAC,eAAe,GAAG,eAAe,CAAC;QAC7D,IAAI,UAAU;YAAE,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;QAC9C,IAAI,MAAM;YAAE,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC;QACzC,IAAI,KAAK;YAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;QAC/B,IAAI,KAAK;YAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;QAC/B,IAAI,KAAK;YAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;QAC/B,IAAI,gBAAgB;YAAE,KAAK,CAAC,QAAQ,GAAG,gBAAgB,CAAC;IAC1D,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,kEAAkE;IAClE,uEAAuE;IACvE,kEAAkE;IAClE,iEAAiE;IACjE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,IAAI,MAAM,KAAK,QAAQ;YAAE,OAAO,GAAG,CAAC;QACpC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC;YAAE,MAAM;QAC9C,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;IAChD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,wBAAwB,CAC/B,IAAqB,EACrB,QAAgB;IAEhB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;gBAAE,OAAO,IAAI,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,KAAK,IAAI,CAAC,EAAE,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,oBAAoB,CAC3B,QAAgB,EAChB,UAAoC;IAEpC,OAAO,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACzC,wBAAwB,CAAC,IAAI,EAAE,QAAQ,CAAC,CACzC,EAAE,EAAE,CAAC;AACR,CAAC;AAED,SAAS,oBAAoB,CAC3B,IAAwB,EACxB,UAAoC;IAEpC,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,OAAO,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;AACpE,CAAC;AAED,SAAS,WAAW,CAClB,QAAgB,EAChB,UAAoC;IAEpC,MAAM,aAAa,GAAG,oBAAoB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACjE,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC;IACxC,IAAI,QAAQ,KAAK,aAAa,IAAI,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACtE,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,IAAI,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO,cAAc,CAAC;IAChE,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC;IAChD,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC;IAChD,IAAI,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,SAAS,CAAC;IACtD,IAAI,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,SAAS,CAAC;IACtD,IAAI,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,OAAO,CAAC;IAClD,IAAI,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO,cAAc,CAAC;IAChE,IAAI,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,WAAW,CAAC;IAC1D,IAAI,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,QAAQ,CAAC;IACpD,IAAI,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,WAAW,CAAC;IAC1D,IAAI,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO,cAAc,CAAC;IAChE,IAAI,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO,YAAY,CAAC;IAC5D,IAAI,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,WAAW,CAAC;IAC1D,IAAI,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC;QAAE,OAAO,aAAa,CAAC;IAC9D,IAAI,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,OAAO,CAAC;IAClD,IAAI,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,QAAQ,CAAC;IACpD,IAAI,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO,cAAc,CAAC;IAChE,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,UAAU,CAAC;IACpD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,WAAW,CAClB,IAAa,EACb,UAAoC,EACpC,OAA2D;IAE3D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM,CAAC;QACZ,KAAK,KAAK;YACR,OAAO,OAAO,EAAE,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;gBACjD,CAAC,CAAC,SAAS,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE;gBACxD,CAAC,CAAC,OAAO,CAAC;QACd,KAAK,UAAU;YACb,OAAO,WAAW,CAAC;QACrB,KAAK,MAAM;YACT,OAAO,OAAO,CAAC;QACjB,KAAK,SAAS,CAAC;QACf,KAAK,OAAO;YACV,OAAO,UAAU,CAAC;QACpB,KAAK,SAAS,CAAC;QACf,KAAK,YAAY;YACf,OAAO,UAAU,CAAC;QACpB,KAAK,OAAO,CAAC;QACb,KAAK,SAAS;YACZ,OAAO,QAAQ,CAAC;QAClB,KAAK,cAAc;YACjB,OAAO,eAAe,CAAC;QACzB,KAAK,WAAW,CAAC;QACjB,KAAK,WAAW;YACd,OAAO,YAAY,CAAC;QACtB,KAAK,QAAQ;YACX,OAAO,SAAS,CAAC;QACnB,KAAK,WAAW;YACd,OAAO,YAAY,CAAC;QACtB,KAAK,cAAc,CAAC;QACpB,KAAK,QAAQ;YACX,OAAO,eAAe,CAAC;QACzB,KAAK,YAAY;YACf,OAAO,aAAa,CAAC;QACvB,KAAK,WAAW;YACd,OAAO,YAAY,CAAC;QACtB,KAAK,aAAa,CAAC;QACnB,KAAK,MAAM;YACT,OAAO,cAAc,CAAC;QACxB,KAAK,OAAO;YACV,OAAO,QAAQ,CAAC;QAClB,KAAK,QAAQ;YACX,OAAO,SAAS,CAAC;QACnB,KAAK,cAAc,CAAC;QACpB,KAAK,SAAS;YACZ,OAAO,eAAe,CAAC;QACzB,KAAK,MAAM;YACT,OAAO,wBAAwB,CAAC;QAClC,KAAK,YAAY;YACf,OAAO,OAAO,EAAE,WAAW;gBACzB,CAAC,CAAC,eAAe,kBAAkB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;gBAC1D,CAAC,CAAC,aAAa,CAAC;QACpB;YACE,OAAO,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAClD,CAAC;AACH,CAAC;AAED,SAAS,yBAAyB,CAAC,QAAgB;IACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAChE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAClC,IAAI,CAAC;QACH,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC","sourcesContent":["import {\n isAgentChatHomeHandoffActive,\n markAgentChatHomeHandoff,\n} from \"@agent-native/core/client/agent-chat\";\nimport {\n agentNativePath,\n appBasePath,\n appPath,\n} from \"@agent-native/core/client/api-path\";\nimport { extensionIdFromPathname } from \"@agent-native/core/client/extensions\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect } from \"react\";\nimport { useLocation, useNavigate } from \"react-router\";\n\nimport type {\n DispatchExtensionConfig,\n DispatchNavItem,\n} from \"../components/index.js\";\n\nexport interface NavigationState {\n view: string;\n path?: string;\n extensionId?: string;\n extensionSlug?: string;\n dreamId?: string;\n threadDebugMode?: string;\n sourceId?: string;\n inspectSourceId?: string;\n ownerEmail?: string;\n failureStatus?: string;\n range?: string;\n query?: string;\n runId?: string;\n threadId?: string;\n}\n\nexport function useNavigationState(extensions?: DispatchExtensionConfig) {\n const location = useLocation();\n const navigate = useNavigate();\n const qc = useQueryClient();\n\n // Sync current route to application state\n useEffect(() => {\n const localPathname = routerPath(location.pathname);\n const state = buildDispatchNavigationState(\n localPathname,\n location.search,\n extensions,\n );\n\n fetch(agentNativePath(\"/_agent-native/application-state/navigation\"), {\n method: \"PUT\",\n keepalive: true,\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(state),\n }).catch(() => {});\n }, [extensions, location.pathname, location.search]);\n\n // Listen for navigate commands from agent\n const { data: navCommand } = useQuery({\n queryKey: [\"navigate-command\"],\n queryFn: async () => {\n const res = await fetch(\n agentNativePath(\"/_agent-native/application-state/navigate\"),\n );\n if (!res.ok) return null;\n const data = await res.json();\n if (data) {\n // Return with a timestamp to ensure uniqueness\n return { ...data, _ts: Date.now() };\n }\n return null;\n },\n structuralSharing: false,\n });\n\n useEffect(() => {\n if (!navCommand) return;\n // Delete the one-shot command AFTER reading it\n fetch(agentNativePath(\"/_agent-native/application-state/navigate\"), {\n method: \"DELETE\",\n headers: { \"X-Agent-Native-CSRF\": \"1\" },\n }).catch(() => {});\n const cmd = navCommand as NavigationState;\n\n // Navigate to a specific path or resolve view name to path\n const resolvedPath =\n cmd.path || resolvePath(cmd.view, extensions, cmd) || \"/overview\";\n const path =\n cmd.view === \"dreams\" && cmd.dreamId && !resolvedPath.includes(\"?\")\n ? `${resolvedPath}?dreamId=${encodeURIComponent(cmd.dreamId)}`\n : resolvedPath;\n const nextPath = routerPath(path);\n if (\n isChatPath(routerPath(location.pathname)) &&\n !isChatPath(pathnameFromPath(nextPath))\n ) {\n if (isAgentChatHomeHandoffActive(\"dispatch\")) {\n markAgentChatHomeHandoff(\"dispatch\");\n }\n }\n navigate(nextPath);\n qc.setQueryData([\"navigate-command\"], null);\n }, [extensions, location.pathname, navCommand, navigate, qc]);\n}\n\nfunction pathnameFromPath(path: string): string {\n return path.split(/[?#]/, 1)[0] || \"/\";\n}\n\nfunction isChatPath(pathname: string): boolean {\n return pathname === \"/chat\" || pathname.startsWith(\"/chat/\");\n}\n\nfunction threadIdFromPath(pathname: string): string | null {\n const match = pathname.match(/^\\/chat\\/([^/]+)/);\n if (!match) return null;\n try {\n const value = decodeURIComponent(match[1]).trim();\n return value || null;\n } catch {\n return null;\n }\n}\n\nexport function buildDispatchNavigationState(\n pathname: string,\n search = \"\",\n extensions?: DispatchExtensionConfig,\n): NavigationState {\n const state: NavigationState = {\n view: resolveView(pathname, extensions),\n path: appPath(pathname),\n };\n\n const threadId = threadIdFromPath(pathname);\n if (threadId) state.threadId = threadId;\n\n const extensionId = extensionIdFromPathname(pathname);\n if (extensionId) {\n state.view = \"extensions\";\n state.extensionId = extensionId;\n const slug = extensionSlugFromPathname(pathname);\n if (slug) state.extensionSlug = slug;\n return state;\n }\n\n if (state.view === \"dreams\") {\n const params = new URLSearchParams(search);\n const dreamId = params.get(\"dreamId\");\n const sourceId = params.get(\"sourceId\");\n const query = params.get(\"query\");\n if (dreamId) state.dreamId = dreamId;\n if (sourceId) state.sourceId = sourceId;\n if (query) state.query = query;\n }\n\n if (state.view === \"thread-debug\") {\n const params = new URLSearchParams(search);\n const mode = params.get(\"mode\");\n const sourceId = params.get(\"source\");\n const inspectSourceId = params.get(\"inspectSource\");\n const ownerEmail = params.get(\"owner\");\n const status = params.get(\"status\");\n const range = params.get(\"range\");\n const query = params.get(\"query\");\n const runId = params.get(\"runId\");\n const selectedThreadId = params.get(\"threadId\");\n if (mode) state.threadDebugMode = mode;\n if (sourceId) state.sourceId = sourceId;\n if (inspectSourceId) state.inspectSourceId = inspectSourceId;\n if (ownerEmail) state.ownerEmail = ownerEmail;\n if (status) state.failureStatus = status;\n if (range) state.range = range;\n if (query) state.query = query;\n if (runId) state.runId = runId;\n if (selectedThreadId) state.threadId = selectedThreadId;\n }\n\n return state;\n}\n\nfunction routerPath(path: string): string {\n const basePath = appBasePath();\n if (!basePath) return path;\n let result = path;\n // Iteratively strip basename. A path that arrives doubly-prefixed\n // (e.g. \"/dispatch/dispatch/overview\", possibly from a stale link or a\n // prior bug) would otherwise get partially stripped here and then\n // re-prefixed by react-router's basename, restoring the bad URL.\n for (let i = 0; i < 4; i += 1) {\n if (result === basePath) return \"/\";\n if (!result.startsWith(`${basePath}/`)) break;\n result = result.slice(basePath.length) || \"/\";\n }\n return result;\n}\n\nfunction extensionItemMatchesPath(\n item: DispatchNavItem,\n pathname: string,\n): boolean {\n if (item.match) {\n try {\n if (item.match(pathname)) return true;\n } catch {\n return false;\n }\n }\n return pathname === item.to || pathname.startsWith(`${item.to}/`);\n}\n\nfunction resolveExtensionView(\n pathname: string,\n extensions?: DispatchExtensionConfig,\n): string | undefined {\n return extensions?.navItems?.find((item) =>\n extensionItemMatchesPath(item, pathname),\n )?.id;\n}\n\nfunction resolveExtensionPath(\n view: string | undefined,\n extensions?: DispatchExtensionConfig,\n): string | undefined {\n if (!view) return undefined;\n return extensions?.navItems?.find((item) => item.id === view)?.to;\n}\n\nfunction resolveView(\n pathname: string,\n extensions?: DispatchExtensionConfig,\n): string {\n const extensionView = resolveExtensionView(pathname, extensions);\n if (extensionView) return extensionView;\n if (pathname === \"/extensions\" || pathname.startsWith(\"/extensions/\")) {\n return \"extensions\";\n }\n if (pathname.startsWith(\"/browser-chat\")) return \"browser-chat\";\n if (pathname.startsWith(\"/chat\")) return \"chat\";\n if (pathname.startsWith(\"/apps\")) return \"apps\";\n if (pathname.startsWith(\"/metrics\")) return \"metrics\";\n if (pathname.startsWith(\"/new-app\")) return \"new-app\";\n if (pathname.startsWith(\"/vault\")) return \"vault\";\n if (pathname.startsWith(\"/integrations\")) return \"integrations\";\n if (pathname.startsWith(\"/workspace\")) return \"workspace\";\n if (pathname.startsWith(\"/agents\")) return \"agents\";\n if (pathname.startsWith(\"/messaging\")) return \"messaging\";\n if (pathname.startsWith(\"/destinations\")) return \"destinations\";\n if (pathname.startsWith(\"/identities\")) return \"identities\";\n if (pathname.startsWith(\"/approvals\")) return \"approvals\";\n if (pathname.startsWith(\"/automations\")) return \"automations\";\n if (pathname.startsWith(\"/audit\")) return \"audit\";\n if (pathname.startsWith(\"/dreams\")) return \"dreams\";\n if (pathname.startsWith(\"/thread-debug\")) return \"thread-debug\";\n if (pathname.startsWith(\"/team\")) return \"settings\";\n return \"overview\";\n}\n\nfunction resolvePath(\n view?: string,\n extensions?: DispatchExtensionConfig,\n command?: Pick<NavigationState, \"extensionId\" | \"threadId\">,\n): string | undefined {\n switch (view) {\n case \"chat\":\n case \"ask\":\n return command?.threadId && command.threadId.trim()\n ? `/chat/${encodeURIComponent(command.threadId.trim())}`\n : \"/chat\";\n case \"overview\":\n return \"/overview\";\n case \"apps\":\n return \"/apps\";\n case \"metrics\":\n case \"usage\":\n return \"/metrics\";\n case \"new-app\":\n case \"create-app\":\n return \"/new-app\";\n case \"vault\":\n case \"secrets\":\n return \"/vault\";\n case \"integrations\":\n return \"/integrations\";\n case \"workspace\":\n case \"resources\":\n return \"/workspace\";\n case \"agents\":\n return \"/agents\";\n case \"messaging\":\n return \"/messaging\";\n case \"destinations\":\n case \"routes\":\n return \"/destinations\";\n case \"identities\":\n return \"/identities\";\n case \"approvals\":\n return \"/approvals\";\n case \"automations\":\n case \"jobs\":\n return \"/automations\";\n case \"audit\":\n return \"/audit\";\n case \"dreams\":\n return \"/dreams\";\n case \"thread-debug\":\n case \"threads\":\n return \"/thread-debug\";\n case \"team\":\n return \"/settings#organization\";\n case \"extensions\":\n return command?.extensionId\n ? `/extensions/${encodeURIComponent(command.extensionId)}`\n : \"/extensions\";\n default:\n return resolveExtensionPath(view, extensions);\n }\n}\n\nfunction extensionSlugFromPathname(pathname: string): string | undefined {\n const match = pathname.match(/^\\/extensions\\/[^/]+\\/([^/?#]+)/);\n if (!match?.[1]) return undefined;\n try {\n return decodeURIComponent(match[1]);\n } catch {\n return match[1];\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-debug.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/thread-debug.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"thread-debug.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/thread-debug.tsx"],"names":[],"mappings":"AAkCA,wBAAgB,IAAI;;IAEnB;AA6pBD,MAAM,CAAC,OAAO,UAAU,gBAAgB,oDA2nBvC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { agentNativePath } from "@agent-native/core/client/api-path";
|
|
3
2
|
import { useActionQuery } from "@agent-native/core/client/hooks";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { useT } from "@agent-native/core/client/i18n";
|
|
4
|
+
import { IconAlertTriangle, IconClock, IconDatabase, IconFileSearch, IconRefresh, IconSearch, } from "@tabler/icons-react";
|
|
5
|
+
import { useMemo, useState } from "react";
|
|
6
6
|
import { useSearchParams } from "react-router";
|
|
7
7
|
import { ActionQueryError } from "../../components/action-query-error.js";
|
|
8
8
|
import { DispatchShell } from "../../components/dispatch-shell.js";
|
|
@@ -16,6 +16,28 @@ import { cn } from "../../lib/utils.js";
|
|
|
16
16
|
export function meta() {
|
|
17
17
|
return [{ title: "Thread Debug — Dispatch" }];
|
|
18
18
|
}
|
|
19
|
+
const FAILURE_RANGE_HOURS = {
|
|
20
|
+
"24h": 24,
|
|
21
|
+
"7d": 7 * 24,
|
|
22
|
+
"30d": 30 * 24,
|
|
23
|
+
};
|
|
24
|
+
function parseMode(value) {
|
|
25
|
+
return value === "threads" ? "threads" : "failures";
|
|
26
|
+
}
|
|
27
|
+
function parseFailureStatus(value) {
|
|
28
|
+
return value === "errored" || value === "aborted" || value === "truncated"
|
|
29
|
+
? value
|
|
30
|
+
: "all";
|
|
31
|
+
}
|
|
32
|
+
function parseFailureRange(value) {
|
|
33
|
+
return value === "7d" || value === "30d" ? value : "24h";
|
|
34
|
+
}
|
|
35
|
+
function failureSourceId(failure) {
|
|
36
|
+
return failure.sourceId || failure.source?.id || "current";
|
|
37
|
+
}
|
|
38
|
+
function failureSourceLabel(failure) {
|
|
39
|
+
return (failure.sourceLabel || failure.source?.label || failureSourceId(failure));
|
|
40
|
+
}
|
|
19
41
|
function formatDate(value) {
|
|
20
42
|
if (value == null || value === "")
|
|
21
43
|
return "n/a";
|
|
@@ -25,6 +47,15 @@ function formatDate(value) {
|
|
|
25
47
|
return "n/a";
|
|
26
48
|
return date.toLocaleString();
|
|
27
49
|
}
|
|
50
|
+
function formatDuration(value) {
|
|
51
|
+
if (value == null || !Number.isFinite(value))
|
|
52
|
+
return "n/a";
|
|
53
|
+
if (value < 1_000)
|
|
54
|
+
return `${Math.round(value)}ms`;
|
|
55
|
+
if (value < 60_000)
|
|
56
|
+
return `${(value / 1_000).toFixed(1)}s`;
|
|
57
|
+
return `${(value / 60_000).toFixed(1)}m`;
|
|
58
|
+
}
|
|
28
59
|
function json(value) {
|
|
29
60
|
try {
|
|
30
61
|
return JSON.stringify(value, null, 2);
|
|
@@ -53,6 +84,23 @@ function messageTitle(message) {
|
|
|
53
84
|
function toolParts(message) {
|
|
54
85
|
return message.contentParts.filter((part) => part?.type === "tool-call");
|
|
55
86
|
}
|
|
87
|
+
function diagnosticStage(value) {
|
|
88
|
+
if (!value)
|
|
89
|
+
return null;
|
|
90
|
+
try {
|
|
91
|
+
const parsed = JSON.parse(value);
|
|
92
|
+
const stage = typeof parsed.stage === "string" && parsed.stage.trim()
|
|
93
|
+
? parsed.stage.trim()
|
|
94
|
+
: value;
|
|
95
|
+
const detail = typeof parsed.detail === "string" && parsed.detail.trim()
|
|
96
|
+
? parsed.detail.trim()
|
|
97
|
+
: "";
|
|
98
|
+
return detail ? `${stage}: ${detail}` : stage;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
56
104
|
function RawBlock({ value, className, }) {
|
|
57
105
|
return (_jsx("pre", { className: cn("max-h-[520px] overflow-auto rounded-lg border bg-muted/30 p-3 text-xs leading-relaxed text-foreground", "whitespace-pre-wrap break-words", className), children: typeof value === "string" ? value : json(value) }));
|
|
58
106
|
}
|
|
@@ -64,11 +112,39 @@ function ResultCard({ result, selected, onSelect, }) {
|
|
|
64
112
|
? "border-foreground bg-muted"
|
|
65
113
|
: "bg-card hover:border-foreground/30 hover:bg-muted/40"), children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm font-medium text-foreground", children: result.title || result.preview || result.id }), _jsx("div", { className: "mt-1 truncate font-mono text-[11px] text-muted-foreground", children: result.id })] }), _jsx(Badge, { variant: "outline", className: "shrink-0", children: result.messageCount })] }), _jsx("div", { className: "mt-2 line-clamp-3 text-xs leading-relaxed text-muted-foreground", children: result.snippet || result.preview || "No preview" }), _jsxs("div", { className: "mt-2 flex items-center justify-between gap-3 text-[11px] text-muted-foreground", children: [_jsx("span", { className: "truncate", children: result.ownerEmail }), _jsx("span", { className: "shrink-0", children: formatDate(result.updatedAt) })] })] }));
|
|
66
114
|
}
|
|
115
|
+
function FailureCard({ failure, selected, onSelect, }) {
|
|
116
|
+
const t = useT();
|
|
117
|
+
const summary = failure.errorCode ||
|
|
118
|
+
failure.terminalReason ||
|
|
119
|
+
failure.abortReason ||
|
|
120
|
+
failure.status;
|
|
121
|
+
const statusLabel = failure.status === "errored"
|
|
122
|
+
? t("dispatch.pages.threadDebugErrored", {
|
|
123
|
+
defaultValue: "Errored",
|
|
124
|
+
})
|
|
125
|
+
: failure.status === "aborted"
|
|
126
|
+
? t("dispatch.pages.threadDebugAborted", {
|
|
127
|
+
defaultValue: "Aborted",
|
|
128
|
+
})
|
|
129
|
+
: failure.status === "truncated"
|
|
130
|
+
? t("dispatch.pages.threadDebugTruncated", {
|
|
131
|
+
defaultValue: "Truncated",
|
|
132
|
+
})
|
|
133
|
+
: failure.status;
|
|
134
|
+
return (_jsxs("button", { type: "button", onClick: onSelect, className: cn("w-full rounded-lg border px-3 py-3 text-left transition-colors", selected
|
|
135
|
+
? "border-foreground bg-muted"
|
|
136
|
+
: "bg-card hover:border-foreground/30 hover:bg-muted/40"), children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm font-medium text-foreground", children: failure.threadTitle || failure.threadPreview || failure.threadId }), _jsx("div", { className: "mt-1 truncate font-mono text-[11px] text-muted-foreground", children: failure.id })] }), _jsx(Badge, { variant: "outline", className: "shrink-0", children: statusLabel })] }), _jsxs("div", { className: "mt-2 flex items-center gap-1.5 text-xs text-foreground", children: [_jsx(IconAlertTriangle, { className: "size-3.5 shrink-0 text-muted-foreground" }), _jsx("span", { className: "truncate", children: summary })] }), failure.errorDetail ? (_jsx("div", { className: "mt-1 line-clamp-2 text-xs leading-relaxed text-muted-foreground", children: failure.errorDetail })) : null, _jsxs("div", { className: "mt-2 flex items-center justify-between gap-3 text-[11px] text-muted-foreground", children: [_jsxs("span", { className: "truncate", children: [failureSourceLabel(failure), " \u00B7 ", failure.ownerEmail] }), _jsxs("span", { className: "inline-flex shrink-0 items-center gap-1", children: [_jsx(IconClock, { className: "size-3" }), formatDate(failure.completedAt ?? failure.startedAt), failure.durationMs == null
|
|
137
|
+
? null
|
|
138
|
+
: ` · ${formatDuration(failure.durationMs)}`] })] }), _jsx("span", { className: "sr-only", children: t("dispatch.pages.threadDebugInspectFailure", {
|
|
139
|
+
defaultValue: "Inspect failed run",
|
|
140
|
+
}) })] }));
|
|
141
|
+
}
|
|
67
142
|
function MessageBlock({ message }) {
|
|
68
143
|
const tools = toolParts(message);
|
|
69
144
|
return (_jsxs("div", { className: "rounded-lg bg-card", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2 border-b px-3 py-2", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(Badge, { variant: message.role === "assistant" ? "default" : "secondary", children: message.role }), _jsx("span", { className: "truncate text-sm font-medium text-foreground", children: messageTitle(message) })] }), _jsxs("div", { className: "flex items-center gap-2 text-[11px] text-muted-foreground", children: [message.attachments.length > 0 ? (_jsxs(Badge, { variant: "outline", children: [message.attachments.length, " files"] })) : null, _jsx("span", { children: formatDate(message.createdAt) })] })] }), _jsxs("div", { className: "space-y-3 px-3 py-3", children: [message.text ? (_jsx("div", { className: "whitespace-pre-wrap break-words text-sm leading-relaxed text-foreground", children: message.text })) : (_jsx("div", { className: "text-sm text-muted-foreground", children: "No text content" })), tools.length > 0 ? (_jsx("div", { className: "space-y-2", children: tools.map((tool, index) => (_jsxs("details", { className: "rounded-md border bg-muted/30 px-3 py-2", children: [_jsx("summary", { className: "cursor-pointer text-xs font-medium text-foreground", children: tool.toolName ?? tool.name ?? "tool-call" }), _jsx(RawBlock, { value: tool, className: "mt-2 max-h-72" })] }, `${message.id ?? message.index}-tool-${index}`))) })) : null] })] }));
|
|
70
145
|
}
|
|
71
146
|
function ThreadDetail({ detail }) {
|
|
147
|
+
const t = useT();
|
|
72
148
|
const rawBundle = useMemo(() => ({
|
|
73
149
|
thread: detail.thread,
|
|
74
150
|
debug: detail.debug,
|
|
@@ -82,7 +158,24 @@ function ThreadDetail({ detail }) {
|
|
|
82
158
|
evals: detail.evals,
|
|
83
159
|
checkpoints: detail.checkpoints,
|
|
84
160
|
}), [detail]);
|
|
85
|
-
return (_jsxs("div", { className: "rounded-lg bg-card", children: [_jsxs("div", { className: "border-b px-4 py-3", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-base font-semibold text-foreground", children: detail.thread.title || detail.thread.preview || detail.thread.id }), _jsx("div", { className: "mt-1 truncate font-mono text-xs text-muted-foreground", children: detail.thread.id })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs(Badge, { variant: "secondary", children: [detail.messages.length, " messages"] }), _jsxs(Badge, { variant: "secondary", children: [detail.runs.length, " runs"] }), _jsx(Badge, { variant: "outline", children: detail.source.label })] })] }), _jsxs("div", { className: "mt-3 grid gap-2 text-xs text-muted-foreground sm:grid-cols-3", children: [_jsxs("div", { className: "truncate", children: ["Owner: ", detail.thread.ownerEmail] }), _jsxs("div", { children: ["Created: ", formatDate(detail.thread.createdAt)] }), _jsxs("div", { children: ["Updated: ", formatDate(detail.thread.updatedAt)] })] })] }), _jsxs(Tabs, { defaultValue: "transcript", className: "p-4", children: [_jsxs(TabsList, { children: [_jsx(TabsTrigger, { value: "transcript", children: "Transcript" }), _jsx(TabsTrigger, { value: "runs", children: "Runs" }), _jsx(TabsTrigger, { value: "internals", children: "Internals" }), _jsx(TabsTrigger, { value: "raw", children: "Raw" })] }), _jsx(TabsContent, { value: "transcript", className: "mt-4 space-y-3", children: detail.messages.length > 0 ? (detail.messages.map((message) => (_jsx(MessageBlock, { message: message }, message.id ?? `message-${message.index}`)))) : (_jsx("div", { className: "rounded-lg border border-dashed px-4 py-8 text-center text-sm text-muted-foreground", children: "No persisted messages." })) }), _jsx(TabsContent, { value: "runs", className: "mt-4 space-y-3", children: detail.runs.length > 0 ? (detail.runs.map((run) => (_jsxs("details", { className: "rounded-lg bg-card", children: [_jsx("summary", { className: "cursor-pointer px-4 py-3", children: _jsxs("div", { className: "inline-flex flex-wrap items-center gap-2", children: [_jsx(Badge, { variant: "outline", children: run.status }), _jsx("span", { className: "font-mono text-xs text-foreground", children: run.id }),
|
|
161
|
+
return (_jsxs("div", { className: "rounded-lg bg-card", children: [_jsxs("div", { className: "border-b px-4 py-3", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-base font-semibold text-foreground", children: detail.thread.title || detail.thread.preview || detail.thread.id }), _jsx("div", { className: "mt-1 truncate font-mono text-xs text-muted-foreground", children: detail.thread.id })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs(Badge, { variant: "secondary", children: [detail.messages.length, " messages"] }), _jsxs(Badge, { variant: "secondary", children: [detail.runs.length, " runs"] }), _jsx(Badge, { variant: "outline", children: detail.source.label })] })] }), _jsxs("div", { className: "mt-3 grid gap-2 text-xs text-muted-foreground sm:grid-cols-3", children: [_jsxs("div", { className: "truncate", children: ["Owner: ", detail.thread.ownerEmail] }), _jsxs("div", { children: ["Created: ", formatDate(detail.thread.createdAt)] }), _jsxs("div", { children: ["Updated: ", formatDate(detail.thread.updatedAt)] })] })] }), _jsxs(Tabs, { defaultValue: "transcript", className: "p-4", children: [_jsxs(TabsList, { children: [_jsx(TabsTrigger, { value: "transcript", children: "Transcript" }), _jsx(TabsTrigger, { value: "runs", children: "Runs" }), _jsx(TabsTrigger, { value: "internals", children: "Internals" }), _jsx(TabsTrigger, { value: "raw", children: "Raw" })] }), _jsx(TabsContent, { value: "transcript", className: "mt-4 space-y-3", children: detail.messages.length > 0 ? (detail.messages.map((message) => (_jsx(MessageBlock, { message: message }, message.id ?? `message-${message.index}`)))) : (_jsx("div", { className: "rounded-lg border border-dashed px-4 py-8 text-center text-sm text-muted-foreground", children: "No persisted messages." })) }), _jsx(TabsContent, { value: "runs", className: "mt-4 space-y-3", children: detail.runs.length > 0 ? (detail.runs.map((run) => (_jsxs("details", { className: "rounded-lg bg-card", children: [_jsx("summary", { className: "cursor-pointer px-4 py-3", children: _jsxs("div", { className: "inline-flex flex-wrap items-center gap-2", children: [_jsx(Badge, { variant: "outline", children: run.status }), _jsx("span", { className: "font-mono text-xs text-foreground", children: run.id }), run.errorCode ? (_jsx("span", { className: "font-mono text-xs text-destructive", children: run.errorCode })) : null, _jsx("span", { className: "text-xs text-muted-foreground", children: formatDate(run.startedAt) })] }) }), _jsxs("div", { className: "space-y-3 border-t px-4 py-3", children: [_jsxs("div", { className: "grid gap-2 text-xs sm:grid-cols-2 xl:grid-cols-3", children: [_jsxs("div", { children: [_jsx("div", { className: "text-muted-foreground", children: t("dispatch.pages.threadDebugFailureCode", {
|
|
162
|
+
defaultValue: "Failure code",
|
|
163
|
+
}) }), _jsx("div", { className: "mt-0.5 break-words font-mono text-foreground", children: run.errorCode || "n/a" })] }), _jsxs("div", { children: [_jsx("div", { className: "text-muted-foreground", children: t("dispatch.pages.threadDebugTerminalReason", {
|
|
164
|
+
defaultValue: "Terminal reason",
|
|
165
|
+
}) }), _jsx("div", { className: "mt-0.5 break-words font-mono text-foreground", children: run.terminalReason || run.abortReason || "n/a" })] }), _jsxs("div", { children: [_jsx("div", { className: "text-muted-foreground", children: t("dispatch.pages.threadDebugDispatchMode", {
|
|
166
|
+
defaultValue: "Dispatch mode",
|
|
167
|
+
}) }), _jsx("div", { className: "mt-0.5 break-words font-mono text-foreground", children: run.dispatchMode || "foreground" })] }), _jsxs("div", { children: [_jsx("div", { className: "text-muted-foreground", children: t("dispatch.pages.threadDebugLastStage", {
|
|
168
|
+
defaultValue: "Last stage",
|
|
169
|
+
}) }), _jsx("div", { className: "mt-0.5 break-words font-mono text-foreground", children: diagnosticStage(run.workerStage) ||
|
|
170
|
+
diagnosticStage(run.diagStage) ||
|
|
171
|
+
"n/a" })] }), _jsxs("div", { children: [_jsx("div", { className: "text-muted-foreground", children: t("dispatch.pages.threadDebugDuration", {
|
|
172
|
+
defaultValue: "Duration",
|
|
173
|
+
}) }), _jsx("div", { className: "mt-0.5 text-foreground", children: formatDuration(run.durationMs ??
|
|
174
|
+
(run.completedAt == null
|
|
175
|
+
? null
|
|
176
|
+
: run.completedAt - run.startedAt)) })] }), _jsxs("div", { children: [_jsx("div", { className: "text-muted-foreground", children: t("dispatch.pages.threadDebugLastProgress", {
|
|
177
|
+
defaultValue: "Last progress",
|
|
178
|
+
}) }), _jsx("div", { className: "mt-0.5 text-foreground", children: formatDate(run.lastProgressAt ?? run.heartbeatAt) })] })] }), run.errorDetail ? (_jsx("div", { className: "rounded-md bg-destructive/10 px-3 py-2 text-xs leading-relaxed text-destructive", children: run.errorDetail })) : null, run.events.map((event) => (_jsxs("details", { className: "rounded-md border bg-muted/30 px-3 py-2", children: [_jsxs("summary", { className: "cursor-pointer text-xs font-medium text-foreground", children: ["#", event.seq, " ", eventLabel(event.event)] }), _jsx(RawBlock, { value: event.event, className: "mt-2 max-h-72" })] }, `${run.id}-${event.seq}`))), run.events.length === 0 ? (_jsx("div", { className: "text-sm text-muted-foreground", children: "No retained run events." })) : null] })] }, run.id)))) : (_jsx("div", { className: "rounded-lg border border-dashed px-4 py-8 text-center text-sm text-muted-foreground", children: "No retained runs." })) }), _jsx(TabsContent, { value: "internals", className: "mt-4 space-y-4", children: _jsxs("div", { className: "grid gap-4 lg:grid-cols-2", children: [_jsxs("div", { children: [_jsx("div", { className: "mb-2 text-sm font-medium text-foreground", children: "Debug Runs" }), _jsx(RawBlock, { value: detail.debugRuns.length > 0
|
|
86
179
|
? detail.debugRuns
|
|
87
180
|
: (detail.debug ?? {}) })] }), _jsxs("div", { children: [_jsx("div", { className: "mb-2 text-sm font-medium text-foreground", children: "Trace Summaries" }), _jsx(RawBlock, { value: detail.traces.summaries })] }), _jsxs("div", { children: [_jsx("div", { className: "mb-2 text-sm font-medium text-foreground", children: "Trace Spans" }), _jsx(RawBlock, { value: detail.traces.spans })] }), _jsxs("div", { children: [_jsx("div", { className: "mb-2 text-sm font-medium text-foreground", children: "Feedback And Evals" }), _jsx(RawBlock, { value: {
|
|
88
181
|
feedback: detail.feedback,
|
|
@@ -92,91 +185,212 @@ function ThreadDetail({ detail }) {
|
|
|
92
185
|
} })] })] }) }), _jsxs(TabsContent, { value: "raw", className: "mt-4 space-y-4", children: [_jsx(RawBlock, { value: rawBundle }), _jsx(RawBlock, { value: detail.rawThreadData })] })] })] }));
|
|
93
186
|
}
|
|
94
187
|
export default function ThreadDebugRoute() {
|
|
95
|
-
const
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
const
|
|
188
|
+
const t = useT();
|
|
189
|
+
const [routeSearchParams, setRouteSearchParams] = useSearchParams();
|
|
190
|
+
const mode = parseMode(routeSearchParams.get("mode"));
|
|
191
|
+
const sourceId = routeSearchParams.get("source") ||
|
|
192
|
+
(mode === "failures" ? "all" : "current");
|
|
193
|
+
const ownerEmail = routeSearchParams.get("owner") || "";
|
|
194
|
+
const query = routeSearchParams.get("query") || "";
|
|
195
|
+
const status = parseFailureStatus(routeSearchParams.get("status"));
|
|
196
|
+
const range = parseFailureRange(routeSearchParams.get("range"));
|
|
197
|
+
const runId = routeSearchParams.get("runId") || "";
|
|
198
|
+
const threadId = routeSearchParams.get("threadId") || "";
|
|
199
|
+
const inspectSourceId = routeSearchParams.get("inspectSource") || "";
|
|
102
200
|
const [lookupId, setLookupId] = useState("");
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
201
|
+
function updateRouteState(updates) {
|
|
202
|
+
const next = new URLSearchParams(routeSearchParams);
|
|
203
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
204
|
+
if (value == null || value === "")
|
|
205
|
+
next.delete(key);
|
|
206
|
+
else
|
|
207
|
+
next.set(key, value);
|
|
208
|
+
}
|
|
209
|
+
setRouteSearchParams(next, { replace: true });
|
|
210
|
+
}
|
|
109
211
|
const sourcesQuery = useActionQuery("list-agent-thread-sources", {});
|
|
110
212
|
const { data: sourcesData, isLoading: sourcesLoading } = sourcesQuery;
|
|
111
213
|
const sources = sourcesData?.sources ?? [];
|
|
214
|
+
const failureParams = useMemo(() => ({
|
|
215
|
+
sourceId,
|
|
216
|
+
ownerEmail: ownerEmail.trim() || undefined,
|
|
217
|
+
status,
|
|
218
|
+
lookbackHours: FAILURE_RANGE_HOURS[range],
|
|
219
|
+
limit: 25,
|
|
220
|
+
}), [ownerEmail, range, sourceId, status]);
|
|
221
|
+
const { data: failuresData, isLoading: failuresLoading, error: failuresError, refetch: refetchFailures, } = useActionQuery("list-agent-run-failures", failureParams, { enabled: mode === "failures" });
|
|
222
|
+
const failures = failuresData?.failures ?? [];
|
|
223
|
+
const unavailableFailureSources = (failuresData?.sources ?? []).filter((source) => source.status !== "ok");
|
|
224
|
+
const failureSourceStatusLabels = {
|
|
225
|
+
ok: "ok",
|
|
226
|
+
disconnected: t("dispatch.pages.threadDebugDisconnected", {
|
|
227
|
+
defaultValue: "disconnected",
|
|
228
|
+
}),
|
|
229
|
+
unsupported: t("dispatch.pages.threadDebugUnsupported", {
|
|
230
|
+
defaultValue: "unsupported",
|
|
231
|
+
}),
|
|
232
|
+
unavailable: t("dispatch.pages.threadDebugUnavailable", {
|
|
233
|
+
defaultValue: "unavailable",
|
|
234
|
+
}),
|
|
235
|
+
};
|
|
236
|
+
const threadSourceId = sourceId === "all" ? "current" : sourceId;
|
|
237
|
+
const detailSourceId = runId && inspectSourceId ? inspectSourceId : threadSourceId;
|
|
112
238
|
const searchParams = useMemo(() => ({
|
|
113
|
-
sourceId:
|
|
114
|
-
query:
|
|
115
|
-
ownerEmail:
|
|
239
|
+
sourceId: threadSourceId,
|
|
240
|
+
query: query.trim() || undefined,
|
|
241
|
+
ownerEmail: ownerEmail.trim() || undefined,
|
|
116
242
|
limit: 25,
|
|
117
|
-
}), [
|
|
118
|
-
const { data: searchData, isLoading: searchLoading, error: searchError, refetch: refetchSearch, } = useActionQuery("search-agent-threads", searchParams);
|
|
243
|
+
}), [ownerEmail, query, threadSourceId]);
|
|
244
|
+
const { data: searchData, isLoading: searchLoading, error: searchError, refetch: refetchSearch, } = useActionQuery("search-agent-threads", searchParams, { enabled: mode === "threads" });
|
|
119
245
|
const searchThreads = searchData?.threads ?? [];
|
|
120
246
|
const detailParams = useMemo(() => ({
|
|
121
|
-
sourceId:
|
|
122
|
-
...(
|
|
123
|
-
|
|
124
|
-
: { threadId: selected?.lookupId ?? "" }),
|
|
125
|
-
ownerEmail: selected?.ownerEmail,
|
|
247
|
+
sourceId: detailSourceId,
|
|
248
|
+
...(runId ? { runId } : { threadId }),
|
|
249
|
+
ownerEmail: ownerEmail.trim() || undefined,
|
|
126
250
|
maxRuns: 20,
|
|
127
251
|
maxEvents: 800,
|
|
128
252
|
maxTraceSpans: 600,
|
|
129
|
-
}), [
|
|
253
|
+
}), [detailSourceId, ownerEmail, runId, threadId]);
|
|
130
254
|
const { data: detail, isLoading: detailLoading, error: detailError, refetch: refetchDetail, } = useActionQuery("get-agent-thread-debug", detailParams, {
|
|
131
|
-
enabled: Boolean(
|
|
255
|
+
enabled: Boolean(runId || threadId),
|
|
132
256
|
});
|
|
133
|
-
const selectedSource = sources.find((source) => source.id ===
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
257
|
+
const selectedSource = sources.find((source) => source.id === threadSourceId);
|
|
258
|
+
const detailPane = (_jsxs("section", { className: "min-w-0", children: [detailError ? (_jsx(ActionQueryError, { error: detailError, onRetry: () => void refetchDetail() })) : null, detailLoading ? (_jsxs("div", { className: "rounded-lg bg-card p-4", children: [_jsx(Skeleton, { className: "h-6 w-72" }), _jsx(Skeleton, { className: "mt-3 h-4 w-96" }), _jsx(Skeleton, { className: "mt-6 h-[520px] w-full" })] })) : detail ? (_jsx(ThreadDetail, { detail: detail })) : (_jsxs("div", { className: "flex min-h-[520px] flex-col items-center justify-center rounded-lg border border-dashed bg-card px-4 text-center text-sm text-muted-foreground", children: [_jsx(IconFileSearch, { className: "mb-2 size-5" }), t("dispatch.pages.threadDebugSelectPrompt", {
|
|
259
|
+
defaultValue: "Select a failed run or thread to inspect.",
|
|
260
|
+
})] }))] }));
|
|
261
|
+
return (_jsx(DispatchShell, { title: t("dispatch.pages.threadDebugTitle", {
|
|
262
|
+
defaultValue: "Thread Debug",
|
|
263
|
+
}), description: t("dispatch.pages.threadDebugDescription", {
|
|
264
|
+
defaultValue: "Inspect failed agent runs, persisted threads, run events, and AI internals.",
|
|
265
|
+
}), children: _jsxs("div", { className: "space-y-4", children: [sourcesQuery.isError ? (_jsx(ActionQueryError, { error: sourcesQuery.error, onRetry: () => void sourcesQuery.refetch() })) : null, _jsxs(Tabs, { value: mode, onValueChange: (value) => {
|
|
266
|
+
const nextMode = parseMode(value);
|
|
267
|
+
updateRouteState({
|
|
268
|
+
mode: nextMode,
|
|
269
|
+
source: nextMode === "threads" && sourceId === "all"
|
|
270
|
+
? "current"
|
|
271
|
+
: sourceId,
|
|
272
|
+
runId: null,
|
|
273
|
+
threadId: null,
|
|
274
|
+
inspectSource: null,
|
|
275
|
+
});
|
|
276
|
+
}, children: [_jsxs(TabsList, { children: [_jsx(TabsTrigger, { value: "failures", children: t("dispatch.pages.threadDebugFailedRuns", {
|
|
277
|
+
defaultValue: "Failed runs",
|
|
278
|
+
}) }), _jsx(TabsTrigger, { value: "threads", children: t("dispatch.pages.threadDebugThreads", {
|
|
279
|
+
defaultValue: "Threads",
|
|
280
|
+
}) })] }), _jsxs(TabsContent, { value: "failures", className: "mt-4 space-y-4", children: [_jsxs("section", { className: "rounded-lg bg-card p-4", children: [_jsxs("div", { className: "grid gap-3 md:grid-cols-2 xl:grid-cols-[220px_1fr_180px_150px]", children: [_jsxs(Select, { value: sourceId, onValueChange: (value) => updateRouteState({
|
|
281
|
+
source: value,
|
|
282
|
+
runId: null,
|
|
283
|
+
threadId: null,
|
|
284
|
+
inspectSource: null,
|
|
285
|
+
}), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: t("dispatch.pages.threadDebugSource", {
|
|
286
|
+
defaultValue: "Source",
|
|
287
|
+
}) }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: t("dispatch.pages.threadDebugAllSources", {
|
|
288
|
+
defaultValue: "All sources",
|
|
289
|
+
}) }), sources.map((source) => (_jsx(SelectItem, { value: source.id, children: source.label }, source.id)))] })] }), _jsx(Input, { value: ownerEmail, onChange: (event) => updateRouteState({ owner: event.target.value }), placeholder: t("dispatch.pages.threadDebugOwner", {
|
|
290
|
+
defaultValue: "Owner email",
|
|
291
|
+
}) }), _jsxs(Select, { value: status, onValueChange: (value) => updateRouteState({
|
|
292
|
+
status: parseFailureStatus(value),
|
|
293
|
+
runId: null,
|
|
294
|
+
inspectSource: null,
|
|
295
|
+
}), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: t("dispatch.pages.threadDebugStatus", {
|
|
296
|
+
defaultValue: "Status",
|
|
297
|
+
}) }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: t("dispatch.pages.threadDebugAllStatuses", {
|
|
298
|
+
defaultValue: "All statuses",
|
|
299
|
+
}) }), _jsx(SelectItem, { value: "errored", children: t("dispatch.pages.threadDebugErrored", {
|
|
300
|
+
defaultValue: "Errored",
|
|
301
|
+
}) }), _jsx(SelectItem, { value: "aborted", children: t("dispatch.pages.threadDebugAborted", {
|
|
302
|
+
defaultValue: "Aborted",
|
|
303
|
+
}) }), _jsx(SelectItem, { value: "truncated", children: t("dispatch.pages.threadDebugTruncated", {
|
|
304
|
+
defaultValue: "Truncated",
|
|
305
|
+
}) })] })] }), _jsxs(Select, { value: range, onValueChange: (value) => updateRouteState({
|
|
306
|
+
range: parseFailureRange(value),
|
|
307
|
+
runId: null,
|
|
308
|
+
inspectSource: null,
|
|
309
|
+
}), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: t("dispatch.pages.threadDebugRange", {
|
|
310
|
+
defaultValue: "Time range",
|
|
311
|
+
}) }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "24h", children: t("dispatch.pages.threadDebugRange24h", {
|
|
312
|
+
defaultValue: "Last 24 hours",
|
|
313
|
+
}) }), _jsx(SelectItem, { value: "7d", children: t("dispatch.pages.threadDebugRange7d", {
|
|
314
|
+
defaultValue: "Last 7 days",
|
|
315
|
+
}) }), _jsx(SelectItem, { value: "30d", children: t("dispatch.pages.threadDebugRange30d", {
|
|
316
|
+
defaultValue: "Last 30 days",
|
|
317
|
+
}) })] })] })] }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2 text-xs text-muted-foreground", children: [_jsxs("span", { children: [failuresData?.count ?? failures.length, " ", t("dispatch.pages.threadDebugFailureResults", {
|
|
318
|
+
defaultValue: "failed runs",
|
|
319
|
+
})] }), _jsx("span", { children: "\u00B7" }), _jsx("span", { children: failuresData?.access?.scope ??
|
|
320
|
+
t("dispatch.pages.threadDebugCurrentScope", {
|
|
321
|
+
defaultValue: "current scope",
|
|
322
|
+
}) }), failuresData?.partial ? (_jsx(Badge, { variant: "outline", children: t("dispatch.pages.threadDebugPartialResults", {
|
|
323
|
+
defaultValue: "Partial results",
|
|
324
|
+
}) })) : null] }), unavailableFailureSources.length > 0 ? (_jsxs("div", { className: "mt-2 flex items-start gap-1.5 text-xs text-muted-foreground", children: [_jsx(IconAlertTriangle, { className: "mt-0.5 size-3.5 shrink-0" }), _jsxs("span", { children: [t("dispatch.pages.threadDebugUnavailableSources", {
|
|
325
|
+
defaultValue: "Unavailable sources:",
|
|
326
|
+
}), " ", unavailableFailureSources
|
|
327
|
+
.map(({ source, status: sourceStatus }) => `${source.label} (${failureSourceStatusLabels[sourceStatus]})`)
|
|
328
|
+
.join(", ")] })] })) : null] }), failuresError ? (_jsx(ActionQueryError, { error: failuresError, onRetry: () => void refetchFailures() })) : null, _jsxs("div", { className: "grid gap-4 xl:grid-cols-[380px_1fr]", children: [_jsxs("section", { className: "min-h-[520px] rounded-lg bg-card", children: [_jsxs("div", { className: "flex items-center justify-between border-b px-4 py-3", children: [_jsx("div", { className: "text-sm font-semibold text-foreground", children: t("dispatch.pages.threadDebugFailedRuns", {
|
|
329
|
+
defaultValue: "Failed runs",
|
|
330
|
+
}) }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => void refetchFailures(), "aria-label": t("dispatch.pages.threadDebugRefreshFailures", {
|
|
331
|
+
defaultValue: "Refresh failed runs",
|
|
332
|
+
}), children: _jsx(IconRefresh, { className: "size-4" }) })] }), _jsxs("div", { className: "max-h-[760px] space-y-2 overflow-auto p-3", children: [failuresLoading ? (_jsxs(_Fragment, { children: [_jsx(Skeleton, { className: "h-32 w-full rounded-lg" }), _jsx(Skeleton, { className: "h-32 w-full rounded-lg" }), _jsx(Skeleton, { className: "h-32 w-full rounded-lg" })] })) : null, !failuresLoading && failures.length === 0 ? (_jsxs("div", { className: "flex min-h-64 flex-col items-center justify-center rounded-lg border border-dashed px-4 text-center text-sm text-muted-foreground", children: [_jsx(IconDatabase, { className: "mb-2 size-5" }), t("dispatch.pages.threadDebugNoFailures", {
|
|
333
|
+
defaultValue: "No failed runs found.",
|
|
334
|
+
})] })) : null, failures.map((failure) => (_jsx(FailureCard, { failure: failure, selected: runId === failure.id &&
|
|
335
|
+
detailSourceId === failureSourceId(failure), onSelect: () => updateRouteState({
|
|
336
|
+
inspectSource: failureSourceId(failure),
|
|
337
|
+
runId: failure.id,
|
|
338
|
+
threadId: null,
|
|
339
|
+
}) }, `${failureSourceId(failure)}:${failure.id}`)))] })] }), detailPane] })] }), _jsxs(TabsContent, { value: "threads", className: "mt-4 space-y-4", children: [_jsxs("section", { className: "rounded-lg bg-card p-4", children: [_jsxs("div", { className: "grid gap-3 lg:grid-cols-[220px_1fr_260px_auto]", children: [_jsxs(Select, { value: threadSourceId, onValueChange: (value) => updateRouteState({
|
|
340
|
+
source: value,
|
|
341
|
+
runId: null,
|
|
342
|
+
threadId: null,
|
|
343
|
+
inspectSource: null,
|
|
344
|
+
}), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: t("dispatch.pages.threadDebugSource", {
|
|
345
|
+
defaultValue: "Source",
|
|
346
|
+
}) }) }), _jsxs(SelectContent, { children: [sources.map((source) => (_jsx(SelectItem, { value: source.id, children: source.label }, source.id))), sources.length === 0 ? (_jsx(SelectItem, { value: "current", children: t("dispatch.pages.threadDebugCurrentDatabase", {
|
|
347
|
+
defaultValue: "Current Dispatch DB",
|
|
348
|
+
}) })) : null] })] }), _jsx(Input, { value: query, onChange: (event) => updateRouteState({ query: event.target.value }), placeholder: t("dispatch.pages.threadDebugSearchPlaceholder", {
|
|
349
|
+
defaultValue: "Search title, preview, messages, tools",
|
|
350
|
+
}) }), _jsx(Input, { value: ownerEmail, onChange: (event) => updateRouteState({ owner: event.target.value }), placeholder: t("dispatch.pages.threadDebugOwner", {
|
|
351
|
+
defaultValue: "Owner email",
|
|
352
|
+
}) }), _jsxs(Button, { type: "button", onClick: () => void refetchSearch(), children: [_jsx(IconSearch, { className: "size-4" }), t("dispatch.pages.threadDebugSearch", {
|
|
353
|
+
defaultValue: "Search",
|
|
354
|
+
})] })] }), _jsxs("div", { className: "mt-3 grid gap-3 lg:grid-cols-[1fr_auto]", children: [_jsx(Input, { value: lookupId, onChange: (event) => setLookupId(event.target.value), placeholder: t("dispatch.pages.threadDebugLookupPlaceholder", {
|
|
355
|
+
defaultValue: "Paste thread or request/run ID",
|
|
356
|
+
}), className: "font-mono" }), _jsxs(Button, { type: "button", variant: "outline", onClick: () => {
|
|
357
|
+
const trimmed = lookupId.trim();
|
|
358
|
+
if (!trimmed)
|
|
359
|
+
return;
|
|
360
|
+
updateRouteState(trimmed.startsWith("run-")
|
|
361
|
+
? {
|
|
362
|
+
runId: trimmed,
|
|
363
|
+
threadId: null,
|
|
364
|
+
inspectSource: null,
|
|
365
|
+
}
|
|
366
|
+
: {
|
|
367
|
+
threadId: trimmed,
|
|
368
|
+
runId: null,
|
|
369
|
+
inspectSource: null,
|
|
370
|
+
});
|
|
371
|
+
}, children: [_jsx(IconFileSearch, { className: "size-4" }), t("dispatch.pages.threadDebugInspect", {
|
|
372
|
+
defaultValue: "Inspect",
|
|
373
|
+
})] })] }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2 text-xs text-muted-foreground", children: [sourcesLoading ? _jsx(Skeleton, { className: "h-5 w-32" }) : null, selectedSource ? (_jsx(SourceBadge, { source: selectedSource })) : null, selectedSource?.databaseUrlEnv ? (_jsx(Badge, { variant: "outline", className: "font-mono", children: selectedSource.databaseUrlEnv })) : null, sourcesData?.access ? (_jsxs("span", { children: [sourcesData.access.viewerEmail, " \u00B7", " ", sourcesData.access.canInspectAll
|
|
374
|
+
? t("dispatch.pages.threadDebugAdminScope", {
|
|
375
|
+
defaultValue: "admin scope",
|
|
376
|
+
})
|
|
377
|
+
: t("dispatch.pages.threadDebugOwnScope", {
|
|
378
|
+
defaultValue: "own scope",
|
|
379
|
+
})] })) : null] })] }), searchError ? (_jsx(ActionQueryError, { error: searchError, onRetry: () => void refetchSearch() })) : null, _jsxs("div", { className: "grid gap-4 xl:grid-cols-[380px_1fr]", children: [_jsxs("section", { className: "min-h-[520px] rounded-lg bg-card", children: [_jsxs("div", { className: "flex items-center justify-between border-b px-4 py-3", children: [_jsxs("div", { children: [_jsx("div", { className: "text-sm font-semibold text-foreground", children: t("dispatch.pages.threadDebugThreads", {
|
|
380
|
+
defaultValue: "Threads",
|
|
381
|
+
}) }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [searchData?.count ?? 0, " ", t("dispatch.pages.threadDebugResults", {
|
|
382
|
+
defaultValue: "results",
|
|
383
|
+
}), " ", "\u00B7", " ", searchData?.access?.scope ??
|
|
384
|
+
t("dispatch.pages.threadDebugCurrentScope", {
|
|
385
|
+
defaultValue: "current scope",
|
|
386
|
+
})] })] }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => void refetchSearch(), "aria-label": t("dispatch.pages.threadDebugRefreshThreads", {
|
|
387
|
+
defaultValue: "Refresh threads",
|
|
388
|
+
}), children: _jsx(IconRefresh, { className: "size-4" }) })] }), _jsxs("div", { className: "max-h-[760px] space-y-2 overflow-auto p-3", children: [searchLoading ? (_jsxs(_Fragment, { children: [_jsx(Skeleton, { className: "h-28 w-full rounded-lg" }), _jsx(Skeleton, { className: "h-28 w-full rounded-lg" }), _jsx(Skeleton, { className: "h-28 w-full rounded-lg" })] })) : null, !searchLoading && searchThreads.length === 0 ? (_jsxs("div", { className: "flex min-h-64 flex-col items-center justify-center rounded-lg border border-dashed px-4 text-center text-sm text-muted-foreground", children: [_jsx(IconDatabase, { className: "mb-2 size-5" }), t("dispatch.pages.threadDebugNoThreads", {
|
|
389
|
+
defaultValue: "No threads found.",
|
|
390
|
+
})] })) : null, searchThreads.map((result) => (_jsx(ResultCard, { result: result, selected: threadId === result.id, onSelect: () => updateRouteState({
|
|
391
|
+
threadId: result.id,
|
|
392
|
+
runId: null,
|
|
393
|
+
inspectSource: null,
|
|
394
|
+
}) }, result.id)))] })] }), detailPane] })] })] })] }) }));
|
|
181
395
|
}
|
|
182
396
|
//# sourceMappingURL=thread-debug.js.map
|