@agent-native/dispatch 0.15.24 → 0.15.25

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.
Files changed (46) hide show
  1. package/dist/actions/get-agent-thread-debug.d.ts +7 -1
  2. package/dist/actions/get-agent-thread-debug.js +16 -3
  3. package/dist/actions/get-agent-thread-debug.js.map +1 -1
  4. package/dist/actions/list-curated-workspace-templates.js +1 -1
  5. package/dist/actions/list-curated-workspace-templates.js.map +1 -1
  6. package/dist/actions/provider-api-register.d.ts +11 -11
  7. package/dist/actions/remix-workspace-template.js +5 -5
  8. package/dist/actions/remix-workspace-template.js.map +1 -1
  9. package/dist/actions/search-agent-threads.js +1 -1
  10. package/dist/actions/search-agent-threads.js.map +1 -1
  11. package/dist/actions/start-workspace-app-creation.js +1 -1
  12. package/dist/actions/start-workspace-app-creation.js.map +1 -1
  13. package/dist/components/create-app-popover.js +2 -2
  14. package/dist/components/create-app-popover.js.map +1 -1
  15. package/dist/components/workspace-template-card.js +4 -4
  16. package/dist/components/workspace-template-card.js.map +1 -1
  17. package/dist/routes/pages/thread-debug.d.ts.map +1 -1
  18. package/dist/routes/pages/thread-debug.js +25 -11
  19. package/dist/routes/pages/thread-debug.js.map +1 -1
  20. package/dist/server/lib/app-creation-store.js +2 -2
  21. package/dist/server/lib/app-creation-store.js.map +1 -1
  22. package/dist/server/lib/curated-workspace-templates.d.ts +1 -1
  23. package/dist/server/lib/curated-workspace-templates.js +2 -2
  24. package/dist/server/lib/curated-workspace-templates.js.map +1 -1
  25. package/dist/server/lib/thread-debug-store.d.ts +7 -1
  26. package/dist/server/lib/thread-debug-store.d.ts.map +1 -1
  27. package/dist/server/lib/thread-debug-store.js +43 -5
  28. package/dist/server/lib/thread-debug-store.js.map +1 -1
  29. package/dist/server/plugins/integrations.js +1 -1
  30. package/dist/server/plugins/integrations.js.map +1 -1
  31. package/package.json +2 -2
  32. package/src/actions/get-agent-thread-debug.ts +30 -15
  33. package/src/actions/list-curated-workspace-templates.ts +1 -1
  34. package/src/actions/remix-workspace-template.spec.ts +2 -2
  35. package/src/actions/remix-workspace-template.ts +5 -5
  36. package/src/actions/search-agent-threads.ts +1 -1
  37. package/src/actions/start-workspace-app-creation.ts +1 -1
  38. package/src/components/create-app-popover.tsx +2 -2
  39. package/src/components/workspace-template-card.spec.tsx +4 -4
  40. package/src/components/workspace-template-card.tsx +4 -4
  41. package/src/routes/pages/thread-debug.tsx +34 -14
  42. package/src/server/lib/app-creation-store.ts +2 -2
  43. package/src/server/lib/curated-workspace-templates.ts +2 -2
  44. package/src/server/lib/thread-debug-store.spec.ts +82 -0
  45. package/src/server/lib/thread-debug-store.ts +62 -6
  46. package/src/server/plugins/integrations.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-template-card.js","sourceRoot":"","sources":["../../src/components/workspace-template-card.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionMutation } from \"@agent-native/core/client/hooks\";\nimport {\n IconArrowUpRight,\n IconCircleCheck,\n IconCopy,\n IconExternalLink,\n IconFileText,\n IconPlugConnected,\n} from \"@tabler/icons-react\";\nimport { useEffect, useMemo, useState, type ReactNode } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { cn } from \"../lib/utils\";\nimport { Alert, AlertDescription } from \"./ui/alert\";\nimport { Badge } from \"./ui/badge\";\nimport { Button } from \"./ui/button\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"./ui/card\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"./ui/dialog\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\nimport { Spinner } from \"./ui/spinner\";\n\nexport interface CuratedWorkspaceTemplate {\n id?: string | null;\n templateId?: string | null;\n appId?: string | null;\n name: string;\n description?: string | null;\n source?: string | null;\n sourceDescription?: string | null;\n integrationSetup?: string | null;\n setupNote?: string | null;\n installed?: boolean | null;\n installedAppId?: string | null;\n liveUrl?: string | null;\n productUrl?: string | null;\n}\n\nexport type CuratedWorkspaceTemplatesResult =\n | CuratedWorkspaceTemplate[]\n | {\n templates: CuratedWorkspaceTemplate[];\n };\n\nexport interface WorkspaceTemplateLabels {\n appId: string;\n appIdDescription: string;\n cancel: string;\n integrationSetup: string;\n installed: string;\n remix: string;\n remixing: string;\n remixSuccess: string;\n remixError: string;\n appIdRequired: string;\n source: string;\n viewLiveApp: string;\n}\n\nconst DEFAULT_LABELS: WorkspaceTemplateLabels = {\n appId: \"App ID\",\n appIdDescription: \"Choose the URL-safe id for the new workspace app.\",\n cancel: \"Cancel\",\n integrationSetup: \"Integration setup\",\n installed: \"Installed\",\n remix: \"Remix into workspace\",\n remixing: \"Remixing…\",\n remixSuccess: \"Template remixed into your workspace.\",\n remixError: \"Could not remix this template\",\n appIdRequired: \"App ID is required.\",\n source: \"Source\",\n viewLiveApp: \"View the live app\",\n};\n\nexport interface WorkspaceTemplateCardProps {\n template: CuratedWorkspaceTemplate;\n defaultAppId?: string;\n labels?: Partial<WorkspaceTemplateLabels>;\n className?: string;\n onRemixSuccess?: (\n result: unknown,\n template: CuratedWorkspaceTemplate,\n ) => void;\n}\n\nfunction slugifyAppId(value: string): string {\n return (\n value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 48) || \"new-app\"\n );\n}\n\nfunction templateIdFor(template: CuratedWorkspaceTemplate): string {\n return template.templateId || template.id || template.appId || template.name;\n}\n\nfunction defaultAppIdFor(\n template: CuratedWorkspaceTemplate,\n defaultAppId?: string,\n): string {\n if (defaultAppId) return slugifyAppId(defaultAppId);\n const sourceId = slugifyAppId(template.appId || template.name);\n return `${sourceId}-remix`;\n}\n\nfunction stringifyError(error: unknown): string {\n if (error instanceof Error && error.message) return error.message;\n if (typeof error === \"string\") return error;\n return \"Unknown error\";\n}\n\nfunction mergeLabels(\n labels?: Partial<WorkspaceTemplateLabels>,\n): WorkspaceTemplateLabels {\n return { ...DEFAULT_LABELS, ...labels };\n}\n\nexport function WorkspaceTemplateCard({\n template,\n defaultAppId,\n labels: labelOverrides,\n className,\n onRemixSuccess,\n}: WorkspaceTemplateCardProps) {\n const labels = useMemo(() => mergeLabels(labelOverrides), [labelOverrides]);\n const [open, setOpen] = useState(false);\n const [appId, setAppId] = useState(() =>\n defaultAppIdFor(template, defaultAppId),\n );\n const isInstalled = Boolean(template.installed || template.installedAppId);\n const liveUrl = template.liveUrl || template.productUrl;\n const setupNote = template.integrationSetup || template.setupNote;\n const remix = useActionMutation(\"remix-workspace-template\", {\n onSuccess: (result) => {\n const mode = (result as { mode?: string } | null)?.mode;\n const message = (result as { message?: string } | null)?.message;\n if (mode === \"builder\") {\n toast.success(labels.remixSuccess);\n } else if (mode === \"builder-unavailable\") {\n toast.error(message || labels.remixError);\n } else if (mode === \"coming-soon\") {\n toast.info(message || labels.remixSuccess);\n } else {\n toast.success(labels.remixSuccess);\n }\n setOpen(false);\n onRemixSuccess?.(result, template);\n },\n onError: (error) =>\n toast.error(`${labels.remixError}: ${stringifyError(error)}`),\n });\n\n useEffect(() => {\n if (open) {\n setAppId(defaultAppIdFor(template, defaultAppId));\n }\n }, [defaultAppId, open, template]);\n\n function submitRemix() {\n const trimmedAppId = appId.trim();\n if (!trimmedAppId) {\n toast.error(labels.appIdRequired);\n return;\n }\n\n remix.mutate({\n templateId: templateIdFor(template),\n appId: trimmedAppId,\n });\n }\n\n return (\n <Card\n className={cn(\n \"flex h-full flex-col bg-card/40 shadow-none transition-[background-color] hover:bg-accent/15\",\n className,\n )}\n >\n <CardHeader className=\"gap-2 p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2.5\">\n <span className=\"mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-md bg-muted/40 text-muted-foreground\">\n <IconFileText size={16} />\n </span>\n <div className=\"min-w-0\">\n <CardTitle className=\"truncate text-sm font-semibold\">\n {template.name}\n </CardTitle>\n {template.source || template.sourceDescription ? (\n <CardDescription className=\"mt-1 truncate text-xs\">\n <span className=\"font-medium text-foreground/70\">\n {labels.source}:\n </span>{\" \"}\n {template.sourceDescription || template.source}\n </CardDescription>\n ) : null}\n </div>\n </div>\n {isInstalled ? (\n <Badge\n variant=\"outline\"\n className=\"shrink-0 gap-1 border-primary/30 bg-primary/5 text-primary\"\n >\n <IconCircleCheck size={13} />\n {labels.installed}\n </Badge>\n ) : null}\n </div>\n </CardHeader>\n\n <CardContent className=\"flex flex-1 flex-col gap-3 p-4 pt-0\">\n {template.description ? (\n <p className=\"line-clamp-3 text-[13px] leading-5 text-muted-foreground\">\n {template.description}\n </p>\n ) : null}\n\n {setupNote ? (\n <Alert className=\"border-border/60 bg-muted/25 px-3 py-2 [&>svg]:left-3 [&>svg]:top-2.5\">\n <IconPlugConnected size={15} />\n <AlertDescription className=\"text-xs leading-5\">\n <span className=\"font-medium text-foreground/80\">\n {labels.integrationSetup}:\n </span>{\" \"}\n {setupNote}\n </AlertDescription>\n </Alert>\n ) : null}\n </CardContent>\n\n <CardFooter className=\"flex flex-wrap justify-between gap-2 p-4 pt-0\">\n {liveUrl ? (\n <Button variant=\"link\" size=\"sm\" className=\"h-8 px-0\" asChild>\n <a href={liveUrl} target=\"_blank\" rel=\"noreferrer\">\n {labels.viewLiveApp}\n <IconExternalLink />\n </a>\n </Button>\n ) : (\n <span />\n )}\n\n <Dialog\n open={open}\n onOpenChange={(nextOpen) => {\n if (!remix.isPending) setOpen(nextOpen);\n }}\n >\n <DialogTrigger asChild>\n <Button type=\"button\" size=\"sm\">\n <IconCopy />\n {labels.remix}\n </Button>\n </DialogTrigger>\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle>{template.name}</DialogTitle>\n <DialogDescription>{labels.appIdDescription}</DialogDescription>\n </DialogHeader>\n <form\n className=\"flex flex-col gap-4\"\n onSubmit={(event) => {\n event.preventDefault();\n submitRemix();\n }}\n >\n <div className=\"flex flex-col gap-2\">\n <Label\n htmlFor={`workspace-template-app-id-${templateIdFor(template)}`}\n >\n {labels.appId}\n </Label>\n <Input\n id={`workspace-template-app-id-${templateIdFor(template)}`}\n value={appId}\n autoComplete=\"off\"\n onChange={(event) => setAppId(event.target.value)}\n disabled={remix.isPending}\n />\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setOpen(false)}\n disabled={remix.isPending}\n >\n {labels.cancel}\n </Button>\n <Button type=\"submit\" disabled={remix.isPending}>\n {remix.isPending ? <Spinner /> : <IconArrowUpRight />}\n {remix.isPending ? labels.remixing : labels.remix}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n </CardFooter>\n </Card>\n );\n}\n\nexport interface WorkspaceTemplatesSectionProps {\n templates: CuratedWorkspaceTemplatesResult;\n title?: ReactNode;\n defaultAppId?: string;\n labels?: Partial<WorkspaceTemplateLabels>;\n className?: string;\n cardClassName?: string;\n onRemixSuccess?: (\n result: unknown,\n template: CuratedWorkspaceTemplate,\n ) => void;\n}\n\nfunction getTemplateItems(\n result: CuratedWorkspaceTemplatesResult,\n): CuratedWorkspaceTemplate[] {\n return Array.isArray(result) ? result : result.templates;\n}\n\nexport function WorkspaceTemplatesSection({\n templates: result,\n title,\n defaultAppId,\n labels,\n className,\n cardClassName,\n onRemixSuccess,\n}: WorkspaceTemplatesSectionProps) {\n const templates = getTemplateItems(result);\n\n if (templates.length === 0) return null;\n\n return (\n <section className={cn(\"flex flex-col gap-3\", className)}>\n {title ? <div className=\"text-sm font-semibold\">{title}</div> : null}\n <div className=\"grid gap-3 md:grid-cols-2\">\n {templates.map((template) => (\n <WorkspaceTemplateCard\n key={templateIdFor(template)}\n template={template}\n defaultAppId={defaultAppId}\n labels={labels}\n className={cardClassName}\n onRemixSuccess={onRemixSuccess}\n />\n ))}\n </div>\n </section>\n );\n}\n"]}
1
+ {"version":3,"file":"workspace-template-card.js","sourceRoot":"","sources":["../../src/components/workspace-template-card.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useActionMutation } from \"@agent-native/core/client/hooks\";\nimport {\n IconArrowUpRight,\n IconCircleCheck,\n IconCopy,\n IconExternalLink,\n IconFileText,\n IconPlugConnected,\n} from \"@tabler/icons-react\";\nimport { useEffect, useMemo, useState, type ReactNode } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { cn } from \"../lib/utils\";\nimport { Alert, AlertDescription } from \"./ui/alert\";\nimport { Badge } from \"./ui/badge\";\nimport { Button } from \"./ui/button\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle,\n} from \"./ui/card\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"./ui/dialog\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\nimport { Spinner } from \"./ui/spinner\";\n\nexport interface CuratedWorkspaceTemplate {\n id?: string | null;\n templateId?: string | null;\n appId?: string | null;\n name: string;\n description?: string | null;\n source?: string | null;\n sourceDescription?: string | null;\n integrationSetup?: string | null;\n setupNote?: string | null;\n installed?: boolean | null;\n installedAppId?: string | null;\n liveUrl?: string | null;\n productUrl?: string | null;\n}\n\nexport type CuratedWorkspaceTemplatesResult =\n | CuratedWorkspaceTemplate[]\n | {\n templates: CuratedWorkspaceTemplate[];\n };\n\nexport interface WorkspaceTemplateLabels {\n appId: string;\n appIdDescription: string;\n cancel: string;\n integrationSetup: string;\n installed: string;\n remix: string;\n remixing: string;\n remixSuccess: string;\n remixError: string;\n appIdRequired: string;\n source: string;\n viewLiveApp: string;\n}\n\nconst DEFAULT_LABELS: WorkspaceTemplateLabels = {\n appId: \"App ID\",\n appIdDescription: \"Choose the URL-safe id for the new workspace app.\",\n cancel: \"Cancel\",\n integrationSetup: \"Integration setup\",\n installed: \"Installed\",\n remix: \"Create from template\",\n remixing: \"Creating app…\",\n remixSuccess: \"Template app creation started.\",\n remixError: \"Could not create an app from this template\",\n appIdRequired: \"App ID is required.\",\n source: \"Source\",\n viewLiveApp: \"View the live app\",\n};\n\nexport interface WorkspaceTemplateCardProps {\n template: CuratedWorkspaceTemplate;\n defaultAppId?: string;\n labels?: Partial<WorkspaceTemplateLabels>;\n className?: string;\n onRemixSuccess?: (\n result: unknown,\n template: CuratedWorkspaceTemplate,\n ) => void;\n}\n\nfunction slugifyAppId(value: string): string {\n return (\n value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 48) || \"new-app\"\n );\n}\n\nfunction templateIdFor(template: CuratedWorkspaceTemplate): string {\n return template.templateId || template.id || template.appId || template.name;\n}\n\nfunction defaultAppIdFor(\n template: CuratedWorkspaceTemplate,\n defaultAppId?: string,\n): string {\n if (defaultAppId) return slugifyAppId(defaultAppId);\n const sourceId = slugifyAppId(template.appId || template.name);\n return `${sourceId}-remix`;\n}\n\nfunction stringifyError(error: unknown): string {\n if (error instanceof Error && error.message) return error.message;\n if (typeof error === \"string\") return error;\n return \"Unknown error\";\n}\n\nfunction mergeLabels(\n labels?: Partial<WorkspaceTemplateLabels>,\n): WorkspaceTemplateLabels {\n return { ...DEFAULT_LABELS, ...labels };\n}\n\nexport function WorkspaceTemplateCard({\n template,\n defaultAppId,\n labels: labelOverrides,\n className,\n onRemixSuccess,\n}: WorkspaceTemplateCardProps) {\n const labels = useMemo(() => mergeLabels(labelOverrides), [labelOverrides]);\n const [open, setOpen] = useState(false);\n const [appId, setAppId] = useState(() =>\n defaultAppIdFor(template, defaultAppId),\n );\n const isInstalled = Boolean(template.installed || template.installedAppId);\n const liveUrl = template.liveUrl || template.productUrl;\n const setupNote = template.integrationSetup || template.setupNote;\n const remix = useActionMutation(\"remix-workspace-template\", {\n onSuccess: (result) => {\n const mode = (result as { mode?: string } | null)?.mode;\n const message = (result as { message?: string } | null)?.message;\n if (mode === \"builder\") {\n toast.success(labels.remixSuccess);\n } else if (mode === \"builder-unavailable\") {\n toast.error(message || labels.remixError);\n } else if (mode === \"coming-soon\") {\n toast.info(message || labels.remixSuccess);\n } else {\n toast.success(labels.remixSuccess);\n }\n setOpen(false);\n onRemixSuccess?.(result, template);\n },\n onError: (error) =>\n toast.error(`${labels.remixError}: ${stringifyError(error)}`),\n });\n\n useEffect(() => {\n if (open) {\n setAppId(defaultAppIdFor(template, defaultAppId));\n }\n }, [defaultAppId, open, template]);\n\n function submitRemix() {\n const trimmedAppId = appId.trim();\n if (!trimmedAppId) {\n toast.error(labels.appIdRequired);\n return;\n }\n\n remix.mutate({\n templateId: templateIdFor(template),\n appId: trimmedAppId,\n });\n }\n\n return (\n <Card\n className={cn(\n \"flex h-full flex-col bg-card/40 shadow-none transition-[background-color] hover:bg-accent/15\",\n className,\n )}\n >\n <CardHeader className=\"gap-2 p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex min-w-0 items-start gap-2.5\">\n <span className=\"mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-md bg-muted/40 text-muted-foreground\">\n <IconFileText size={16} />\n </span>\n <div className=\"min-w-0\">\n <CardTitle className=\"truncate text-sm font-semibold\">\n {template.name}\n </CardTitle>\n {template.source || template.sourceDescription ? (\n <CardDescription className=\"mt-1 truncate text-xs\">\n <span className=\"font-medium text-foreground/70\">\n {labels.source}:\n </span>{\" \"}\n {template.sourceDescription || template.source}\n </CardDescription>\n ) : null}\n </div>\n </div>\n {isInstalled ? (\n <Badge\n variant=\"outline\"\n className=\"shrink-0 gap-1 border-primary/30 bg-primary/5 text-primary\"\n >\n <IconCircleCheck size={13} />\n {labels.installed}\n </Badge>\n ) : null}\n </div>\n </CardHeader>\n\n <CardContent className=\"flex flex-1 flex-col gap-3 p-4 pt-0\">\n {template.description ? (\n <p className=\"line-clamp-3 text-[13px] leading-5 text-muted-foreground\">\n {template.description}\n </p>\n ) : null}\n\n {setupNote ? (\n <Alert className=\"border-border/60 bg-muted/25 px-3 py-2 [&>svg]:left-3 [&>svg]:top-2.5\">\n <IconPlugConnected size={15} />\n <AlertDescription className=\"text-xs leading-5\">\n <span className=\"font-medium text-foreground/80\">\n {labels.integrationSetup}:\n </span>{\" \"}\n {setupNote}\n </AlertDescription>\n </Alert>\n ) : null}\n </CardContent>\n\n <CardFooter className=\"flex flex-wrap justify-between gap-2 p-4 pt-0\">\n {liveUrl ? (\n <Button variant=\"link\" size=\"sm\" className=\"h-8 px-0\" asChild>\n <a href={liveUrl} target=\"_blank\" rel=\"noreferrer\">\n {labels.viewLiveApp}\n <IconExternalLink />\n </a>\n </Button>\n ) : (\n <span />\n )}\n\n <Dialog\n open={open}\n onOpenChange={(nextOpen) => {\n if (!remix.isPending) setOpen(nextOpen);\n }}\n >\n <DialogTrigger asChild>\n <Button type=\"button\" size=\"sm\">\n <IconCopy />\n {labels.remix}\n </Button>\n </DialogTrigger>\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle>{template.name}</DialogTitle>\n <DialogDescription>{labels.appIdDescription}</DialogDescription>\n </DialogHeader>\n <form\n className=\"flex flex-col gap-4\"\n onSubmit={(event) => {\n event.preventDefault();\n submitRemix();\n }}\n >\n <div className=\"flex flex-col gap-2\">\n <Label\n htmlFor={`workspace-template-app-id-${templateIdFor(template)}`}\n >\n {labels.appId}\n </Label>\n <Input\n id={`workspace-template-app-id-${templateIdFor(template)}`}\n value={appId}\n autoComplete=\"off\"\n onChange={(event) => setAppId(event.target.value)}\n disabled={remix.isPending}\n />\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setOpen(false)}\n disabled={remix.isPending}\n >\n {labels.cancel}\n </Button>\n <Button type=\"submit\" disabled={remix.isPending}>\n {remix.isPending ? <Spinner /> : <IconArrowUpRight />}\n {remix.isPending ? labels.remixing : labels.remix}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n </CardFooter>\n </Card>\n );\n}\n\nexport interface WorkspaceTemplatesSectionProps {\n templates: CuratedWorkspaceTemplatesResult;\n title?: ReactNode;\n defaultAppId?: string;\n labels?: Partial<WorkspaceTemplateLabels>;\n className?: string;\n cardClassName?: string;\n onRemixSuccess?: (\n result: unknown,\n template: CuratedWorkspaceTemplate,\n ) => void;\n}\n\nfunction getTemplateItems(\n result: CuratedWorkspaceTemplatesResult,\n): CuratedWorkspaceTemplate[] {\n return Array.isArray(result) ? result : result.templates;\n}\n\nexport function WorkspaceTemplatesSection({\n templates: result,\n title,\n defaultAppId,\n labels,\n className,\n cardClassName,\n onRemixSuccess,\n}: WorkspaceTemplatesSectionProps) {\n const templates = getTemplateItems(result);\n\n if (templates.length === 0) return null;\n\n return (\n <section className={cn(\"flex flex-col gap-3\", className)}>\n {title ? <div className=\"text-sm font-semibold\">{title}</div> : null}\n <div className=\"grid gap-3 md:grid-cols-2\">\n {templates.map((template) => (\n <WorkspaceTemplateCard\n key={templateIdFor(template)}\n template={template}\n defaultAppId={defaultAppId}\n labels={labels}\n className={cardClassName}\n onRemixSuccess={onRemixSuccess}\n />\n ))}\n </div>\n </section>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"thread-debug.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/thread-debug.tsx"],"names":[],"mappings":"AAgCA,wBAAgB,IAAI;;IAEnB;AAgYD,MAAM,CAAC,OAAO,UAAU,gBAAgB,oDA2RvC"}
1
+ {"version":3,"file":"thread-debug.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/thread-debug.tsx"],"names":[],"mappings":"AAgCA,wBAAgB,IAAI;;IAEnB;AAiYD,MAAM,CAAC,OAAO,UAAU,gBAAgB,oDA8SvC"}
@@ -99,7 +99,7 @@ export default function ThreadDebugRoute() {
99
99
  const [sourceId, setSourceId] = useState(initialSourceId);
100
100
  const [query, setQuery] = useState(initialQuery);
101
101
  const [ownerEmail, setOwnerEmail] = useState(initialOwnerEmail);
102
- const [threadId, setThreadId] = useState("");
102
+ const [lookupId, setLookupId] = useState("");
103
103
  const [submittedSearch, setSubmittedSearch] = useState({
104
104
  sourceId: initialSourceId,
105
105
  query: initialQuery,
@@ -119,14 +119,16 @@ export default function ThreadDebugRoute() {
119
119
  const searchThreads = searchData?.threads ?? [];
120
120
  const detailParams = useMemo(() => ({
121
121
  sourceId: selected?.sourceId ?? "current",
122
- threadId: selected?.threadId ?? "",
122
+ ...(selected?.lookupKind === "run"
123
+ ? { runId: selected.lookupId }
124
+ : { threadId: selected?.lookupId ?? "" }),
123
125
  ownerEmail: selected?.ownerEmail,
124
126
  maxRuns: 20,
125
127
  maxEvents: 800,
126
128
  maxTraceSpans: 600,
127
129
  }), [selected]);
128
130
  const { data: detail, isLoading: detailLoading, error: detailError, refetch: refetchDetail, } = useActionQuery("get-agent-thread-debug", detailParams, {
129
- enabled: Boolean(selected?.threadId),
131
+ enabled: Boolean(selected?.lookupId),
130
132
  });
131
133
  const selectedSource = sources.find((source) => source.id === sourceId);
132
134
  useEffect(() => {
@@ -142,27 +144,39 @@ export default function ThreadDebugRoute() {
142
144
  sourceId,
143
145
  query,
144
146
  ownerEmail: ownerEmail.trim() || undefined,
145
- threadId: selected?.threadId ?? (threadId.trim() || undefined),
147
+ threadId: selected?.lookupKind === "thread"
148
+ ? selected.lookupId
149
+ : !selected && lookupId.trim() && !lookupId.startsWith("run-")
150
+ ? lookupId.trim()
151
+ : undefined,
152
+ runId: selected?.lookupKind === "run"
153
+ ? selected.lookupId
154
+ : !selected && lookupId.trim() && lookupId.startsWith("run-")
155
+ ? lookupId.trim()
156
+ : undefined,
146
157
  }),
147
158
  }).catch(() => { });
148
- }, [ownerEmail, query, selected?.threadId, sourceId, threadId]);
159
+ }, [ownerEmail, query, selected, sourceId, lookupId]);
149
160
  return (_jsx(DispatchShell, { title: "Thread Debug", description: "Inspect persisted agent chat threads, run events, and AI internals.", children: _jsxs("div", { className: "space-y-4", children: [sourcesQuery.isError ? (_jsx(ActionQueryError, { error: sourcesQuery.error, onRetry: () => void sourcesQuery.refetch() })) : null, _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: sourceId, onValueChange: setSourceId, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Source" }) }), _jsxs(SelectContent, { children: [sources.map((source) => (_jsx(SelectItem, { value: source.id, children: source.label }, source.id))), sources.length === 0 ? (_jsx(SelectItem, { value: "current", children: "Current Dispatch DB" })) : null] })] }), _jsx(Input, { value: query, onChange: (event) => setQuery(event.target.value), placeholder: "Search title, preview, messages, tools" }), _jsx(Input, { value: ownerEmail, onChange: (event) => setOwnerEmail(event.target.value), placeholder: "Owner email" }), _jsxs(Button, { type: "button", onClick: () => setSubmittedSearch({
150
161
  sourceId,
151
162
  query: query.trim(),
152
163
  ownerEmail: ownerEmail.trim(),
153
- }), children: [_jsx(IconSearch, { size: 16 }), "Search"] })] }), _jsxs("div", { className: "mt-3 grid gap-3 lg:grid-cols-[1fr_auto]", children: [_jsx(Input, { value: threadId, onChange: (event) => setThreadId(event.target.value), placeholder: "Paste thread ID", className: "font-mono" }), _jsxs(Button, { type: "button", variant: "outline", onClick: () => {
154
- const trimmed = threadId.trim();
164
+ }), children: [_jsx(IconSearch, { size: 16 }), "Search"] })] }), _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: "Paste thread or request/run ID", className: "font-mono" }), _jsxs(Button, { type: "button", variant: "outline", onClick: () => {
165
+ const trimmed = lookupId.trim();
155
166
  if (!trimmed)
156
167
  return;
157
168
  setSelected({
158
169
  sourceId,
159
- threadId: trimmed,
170
+ lookupId: trimmed,
171
+ lookupKind: trimmed.startsWith("run-") ? "run" : "thread",
160
172
  ownerEmail: ownerEmail.trim() || undefined,
161
173
  });
162
- }, children: [_jsx(IconFileSearch, { size: 16 }), "Inspect"] })] }), _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 ? "admin scope" : "own scope"] })) : 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: "Threads" }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [searchData?.count ?? 0, " results \u00B7", " ", searchData?.access?.scope ?? "current scope"] })] }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => refetchSearch(), "aria-label": "Refresh threads", children: _jsx(IconRefresh, { size: 16 }) })] }), _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 h-5 w-5" }), "No threads found."] })) : null, searchThreads.map((result) => (_jsx(ResultCard, { result: result, selected: selected?.threadId === result.id, onSelect: () => setSelected({
174
+ }, children: [_jsx(IconFileSearch, { size: 16 }), "Inspect"] })] }), _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 ? "admin scope" : "own scope"] })) : 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: "Threads" }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [searchData?.count ?? 0, " results \u00B7", " ", searchData?.access?.scope ?? "current scope"] })] }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => refetchSearch(), "aria-label": "Refresh threads", children: _jsx(IconRefresh, { size: 16 }) })] }), _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 h-5 w-5" }), "No threads found."] })) : null, searchThreads.map((result) => (_jsx(ResultCard, { result: result, selected: selected?.lookupKind === "thread" &&
175
+ selected.lookupId === result.id, onSelect: () => setSelected({
163
176
  sourceId: submittedSearch.sourceId,
164
- threadId: result.id,
177
+ lookupId: result.id,
178
+ lookupKind: "thread",
165
179
  ownerEmail: submittedSearch.ownerEmail || undefined,
166
- }) }, result.id)))] })] }), _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 h-5 w-5" }), "Select or inspect a thread."] }))] })] })] }) }));
180
+ }) }, result.id)))] })] }), _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 h-5 w-5" }), "Select or inspect a thread or request/run ID."] }))] })] })] }) }));
167
181
  }
168
182
  //# sourceMappingURL=thread-debug.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"thread-debug.js","sourceRoot":"","sources":["../../../src/routes/pages/thread-debug.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EACL,YAAY,EACZ,cAAc,EACd,WAAW,EACX,UAAU,GACX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EACL,MAAM,EACN,aAAa,EACb,UAAU,EACV,aAAa,EACb,WAAW,GACZ,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EACL,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAErC,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC;AAChD,CAAC;AAqED,SAAS,UAAU,CAAC,KAAyC;IAC3D,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAChD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5E,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC;AAC/B,CAAC;AAED,SAAS,IAAI,CAAC,KAAc;IAC1B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAU;IAC5B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IACxD,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,gBAAgB,KAAK,CAAC,IAAI,EAAE,CAAC;IACrE,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;QAAE,OAAO,eAAe,KAAK,CAAC,IAAI,EAAE,CAAC;IACnE,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACzC,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,WAAW,KAAK,CAAC,SAAS,IAAI,OAAO,EAAE,CAAC;IAC3E,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,YAAY,CAAC,OAAsB;IAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC;IACvC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;AAChF,CAAC;AAED,SAAS,SAAS,CAAC,OAAsB;IACvC,OAAO,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,WAAW,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,QAAQ,CAAC,EAChB,KAAK,EACL,SAAS,GAIV;IACC,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,uGAAuG,EACvG,iCAAiC,EACjC,SAAS,CACV,YAEA,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAC5C,CACP,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,EAAE,MAAM,EAAiC;IAC5D,OAAO,CACL,KAAC,KAAK,IAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,YACrD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,GACnC,CACT,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,EAClB,MAAM,EACN,QAAQ,EACR,QAAQ,GAKT;IACC,OAAO,CACL,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,QAAQ,EACjB,SAAS,EAAE,EAAE,CACX,gEAAgE,EAChE,QAAQ;YACN,CAAC,CAAC,4BAA4B;YAC9B,CAAC,CAAC,sDAAsD,CAC3D,aAED,eAAK,SAAS,EAAC,wCAAwC,aACrD,eAAK,SAAS,EAAC,SAAS,aACtB,cAAK,SAAS,EAAC,8CAA8C,YAC1D,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,EAAE,GACxC,EACN,cAAK,SAAS,EAAC,2DAA2D,YACvE,MAAM,CAAC,EAAE,GACN,IACF,EACN,KAAC,KAAK,IAAC,OAAO,EAAC,SAAS,EAAC,SAAS,EAAC,UAAU,YAC1C,MAAM,CAAC,YAAY,GACd,IACJ,EACN,cAAK,SAAS,EAAC,iEAAiE,YAC7E,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,IAAI,YAAY,GAC7C,EACN,eAAK,SAAS,EAAC,gFAAgF,aAC7F,eAAM,SAAS,EAAC,UAAU,YAAE,MAAM,CAAC,UAAU,GAAQ,EACrD,eAAM,SAAS,EAAC,UAAU,YAAE,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,GAAQ,IAC5D,IACC,CACV,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,EAAE,OAAO,EAA8B;IAC3D,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IACjC,OAAO,CACL,eAAK,SAAS,EAAC,oBAAoB,aACjC,eAAK,SAAS,EAAC,sEAAsE,aACnF,eAAK,SAAS,EAAC,iCAAiC,aAC9C,KAAC,KAAK,IACJ,OAAO,EAAE,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,YAE9D,OAAO,CAAC,IAAI,GACP,EACR,eAAM,SAAS,EAAC,8CAA8C,YAC3D,YAAY,CAAC,OAAO,CAAC,GACjB,IACH,EACN,eAAK,SAAS,EAAC,2DAA2D,aACvE,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAChC,MAAC,KAAK,IAAC,OAAO,EAAC,SAAS,aAAE,OAAO,CAAC,WAAW,CAAC,MAAM,cAAe,CACpE,CAAC,CAAC,CAAC,IAAI,EACR,yBAAO,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,GAAQ,IACxC,IACF,EACN,eAAK,SAAS,EAAC,qBAAqB,aACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CACd,cAAK,SAAS,EAAC,yEAAyE,YACrF,OAAO,CAAC,IAAI,GACT,CACP,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,+BAA+B,gCAAsB,CACrE,EACA,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAClB,cAAK,SAAS,EAAC,WAAW,YACvB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAC1B,mBAEE,SAAS,EAAC,yCAAyC,aAEnD,kBAAS,SAAS,EAAC,oDAAoD,YACpE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,IAAI,WAAW,GAClC,EACV,KAAC,QAAQ,IAAC,KAAK,EAAE,IAAI,EAAE,SAAS,EAAC,eAAe,GAAG,KAN9C,GAAG,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,KAAK,SAAS,KAAK,EAAE,CAO3C,CACX,CAAC,GACE,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,IACF,CACP,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,EAAE,MAAM,EAAmC;IAC/D,MAAM,SAAS,GAAG,OAAO,CACvB,GAAG,EAAE,CAAC,CAAC;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC,EACF,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAC,oBAAoB,aACjC,eAAK,SAAS,EAAC,oBAAoB,aACjC,eAAK,SAAS,EAAC,kDAAkD,aAC/D,eAAK,SAAS,EAAC,SAAS,aACtB,cAAK,SAAS,EAAC,kDAAkD,YAC9D,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,GAC7D,EACN,cAAK,SAAS,EAAC,uDAAuD,YACnE,MAAM,CAAC,MAAM,CAAC,EAAE,GACb,IACF,EACN,eAAK,SAAS,EAAC,mCAAmC,aAChD,MAAC,KAAK,IAAC,OAAO,EAAC,WAAW,aAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,iBAAkB,EACpE,MAAC,KAAK,IAAC,OAAO,EAAC,WAAW,aAAE,MAAM,CAAC,IAAI,CAAC,MAAM,aAAc,EAC5D,KAAC,KAAK,IAAC,OAAO,EAAC,SAAS,YAAE,MAAM,CAAC,MAAM,CAAC,KAAK,GAAS,IAClD,IACF,EACN,eAAK,SAAS,EAAC,8DAA8D,aAC3E,eAAK,SAAS,EAAC,UAAU,wBAAS,MAAM,CAAC,MAAM,CAAC,UAAU,IAAO,EACjE,uCAAe,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,IAAO,EACzD,uCAAe,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,IAAO,IACrD,IACF,EAEN,MAAC,IAAI,IAAC,YAAY,EAAC,YAAY,EAAC,SAAS,EAAC,KAAK,aAC7C,MAAC,QAAQ,eACP,KAAC,WAAW,IAAC,KAAK,EAAC,YAAY,2BAAyB,EACxD,KAAC,WAAW,IAAC,KAAK,EAAC,MAAM,qBAAmB,EAC5C,KAAC,WAAW,IAAC,KAAK,EAAC,WAAW,0BAAwB,EACtD,KAAC,WAAW,IAAC,KAAK,EAAC,KAAK,oBAAkB,IACjC,EAEX,KAAC,WAAW,IAAC,KAAK,EAAC,YAAY,EAAC,SAAS,EAAC,gBAAgB,YACvD,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC5B,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAC/B,KAAC,YAAY,IAEX,OAAO,EAAE,OAAO,IADX,OAAO,CAAC,EAAE,IAAI,WAAW,OAAO,CAAC,KAAK,EAAE,CAE7C,CACH,CAAC,CACH,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,qFAAqF,uCAE9F,CACP,GACW,EAEd,KAAC,WAAW,IAAC,KAAK,EAAC,MAAM,EAAC,SAAS,EAAC,gBAAgB,YACjD,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACxB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACvB,mBAAsB,SAAS,EAAC,oBAAoB,aAClD,kBAAS,SAAS,EAAC,0BAA0B,YAC3C,eAAK,SAAS,EAAC,0CAA0C,aACvD,KAAC,KAAK,IAAC,OAAO,EAAC,SAAS,YAAE,GAAG,CAAC,MAAM,GAAS,EAC7C,eAAM,SAAS,EAAC,mCAAmC,YAChD,GAAG,CAAC,EAAE,GACF,EACP,eAAM,SAAS,EAAC,+BAA+B,YAC5C,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,GACrB,IACH,GACE,EACV,eAAK,SAAS,EAAC,8BAA8B,aAC1C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACzB,mBAEE,SAAS,EAAC,yCAAyC,aAEnD,mBAAS,SAAS,EAAC,oDAAoD,kBACnE,KAAK,CAAC,GAAG,OAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,IAC7B,EACV,KAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS,EAAC,eAAe,GAAG,KANrD,GAAG,GAAG,CAAC,EAAE,IAAI,KAAK,CAAC,GAAG,EAAE,CAOrB,CACX,CAAC,EACD,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACzB,cAAK,SAAS,EAAC,+BAA+B,wCAExC,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,KA7BM,GAAG,CAAC,EAAE,CA8BV,CACX,CAAC,CACH,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,qFAAqF,kCAE9F,CACP,GACW,EAEd,KAAC,WAAW,IAAC,KAAK,EAAC,WAAW,EAAC,SAAS,EAAC,gBAAgB,YACvD,eAAK,SAAS,EAAC,2BAA2B,aACxC,0BACE,cAAK,SAAS,EAAC,0CAA0C,2BAEnD,EACN,KAAC,QAAQ,IACP,KAAK,EACH,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;gDACzB,CAAC,CAAC,MAAM,CAAC,SAAS;gDAClB,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,GAE1B,IACE,EACN,0BACE,cAAK,SAAS,EAAC,0CAA0C,gCAEnD,EACN,KAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,GAAI,IACxC,EACN,0BACE,cAAK,SAAS,EAAC,0CAA0C,4BAEnD,EACN,KAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,GAAI,IACpC,EACN,0BACE,cAAK,SAAS,EAAC,0CAA0C,mCAEnD,EACN,KAAC,QAAQ,IACP,KAAK,EAAE;gDACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;gDACzB,YAAY,EAAE,MAAM,CAAC,YAAY;gDACjC,KAAK,EAAE,MAAM,CAAC,KAAK;gDACnB,WAAW,EAAE,MAAM,CAAC,WAAW;6CAChC,GACD,IACE,IACF,GACM,EAEd,MAAC,WAAW,IAAC,KAAK,EAAC,KAAK,EAAC,SAAS,EAAC,gBAAgB,aACjD,KAAC,QAAQ,IAAC,KAAK,EAAE,SAAS,GAAI,EAC9B,KAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,CAAC,aAAa,GAAI,IAC7B,IACT,IACH,CACP,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB;IACtC,MAAM,CAAC,iBAAiB,CAAC,GAAG,eAAe,EAAE,CAAC;IAC9C,MAAM,eAAe,GAAG,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC;IACrE,MAAM,YAAY,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IAC1D,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;IACpE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC;IAC1D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IACjD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAChE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC7C,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC;QACrD,QAAQ,EAAE,eAAe;QACzB,KAAK,EAAE,YAAY;QACnB,UAAU,EAAE,iBAAiB;KAC9B,CAAC,CAAC;IACH,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAI9B,IAAI,CAAC,CAAC;IAEhB,MAAM,YAAY,GAAG,cAAc,CAUhC,2BAA2B,EAAE,EAAE,CAAC,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,YAAY,CAAC;IAEtE,MAAM,OAAO,GAAwB,WAAW,EAAE,OAAO,IAAI,EAAE,CAAC;IAChE,MAAM,YAAY,GAAG,OAAO,CAC1B,GAAG,EAAE,CAAC,CAAC;QACL,QAAQ,EAAE,eAAe,CAAC,QAAQ;QAClC,KAAK,EAAE,eAAe,CAAC,KAAK,IAAI,SAAS;QACzC,UAAU,EAAE,eAAe,CAAC,UAAU,IAAI,SAAS;QACnD,KAAK,EAAE,EAAE;KACV,CAAC,EACF,CAAC,eAAe,CAAC,CAClB,CAAC;IACF,MAAM,EACJ,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,aAAa,GACvB,GAAG,cAAc,CAKf,sBAAsB,EAAE,YAAY,CAAC,CAAC;IACzC,MAAM,aAAa,GAAyB,UAAU,EAAE,OAAO,IAAI,EAAE,CAAC;IAEtE,MAAM,YAAY,GAAG,OAAO,CAC1B,GAAG,EAAE,CAAC,CAAC;QACL,QAAQ,EAAE,QAAQ,EAAE,QAAQ,IAAI,SAAS;QACzC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE;QAClC,UAAU,EAAE,QAAQ,EAAE,UAAU;QAChC,OAAO,EAAE,EAAE;QACX,SAAS,EAAE,GAAG;QACd,aAAa,EAAE,GAAG;KACnB,CAAC,EACF,CAAC,QAAQ,CAAC,CACX,CAAC;IACF,MAAM,EACJ,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,aAAa,GACvB,GAAG,cAAc,CAChB,wBAAwB,EACxB,YAAY,EACZ;QACE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC;KACrC,CACF,CAAC;IAEF,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;IAExE,SAAS,CAAC,GAAG,EAAE;QACb,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;gBACnB,IAAI,EAAE,cAAc;gBACpB,IAAI,EACF,OAAO,MAAM,KAAK,WAAW;oBAC3B,CAAC,CAAC,eAAe;oBACjB,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ;gBAC9B,QAAQ;gBACR,KAAK;gBACL,UAAU,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,SAAS;gBAC1C,QAAQ,EAAE,QAAQ,EAAE,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;aAC/D,CAAC;SACH,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACrB,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEhE,OAAO,CACL,KAAC,aAAa,IACZ,KAAK,EAAC,cAAc,EACpB,WAAW,EAAC,qEAAqE,YAEjF,eAAK,SAAS,EAAC,WAAW,aACvB,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CACtB,KAAC,gBAAgB,IACf,KAAK,EAAE,YAAY,CAAC,KAAK,EACzB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,YAAY,CAAC,OAAO,EAAE,GAC1C,CACH,CAAC,CAAC,CAAC,IAAI,EACR,mBAAS,SAAS,EAAC,wBAAwB,aACzC,eAAK,SAAS,EAAC,gDAAgD,aAC7D,MAAC,MAAM,IAAC,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,aACjD,KAAC,aAAa,cACZ,KAAC,WAAW,IAAC,WAAW,EAAC,QAAQ,GAAG,GACtB,EAChB,MAAC,aAAa,eACX,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CACvB,KAAC,UAAU,IAAiB,KAAK,EAAE,MAAM,CAAC,EAAE,YACzC,MAAM,CAAC,KAAK,IADE,MAAM,CAAC,EAAE,CAEb,CACd,CAAC,EACD,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACtB,KAAC,UAAU,IAAC,KAAK,EAAC,SAAS,oCAAiC,CAC7D,CAAC,CAAC,CAAC,IAAI,IACM,IACT,EACT,KAAC,KAAK,IACJ,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EACjD,WAAW,EAAC,wCAAwC,GACpD,EACF,KAAC,KAAK,IACJ,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EACtD,WAAW,EAAC,aAAa,GACzB,EACF,MAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CACZ,kBAAkB,CAAC;wCACjB,QAAQ;wCACR,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE;wCACnB,UAAU,EAAE,UAAU,CAAC,IAAI,EAAE;qCAC9B,CAAC,aAGJ,KAAC,UAAU,IAAC,IAAI,EAAE,EAAE,GAAI,cAEjB,IACL,EAEN,eAAK,SAAS,EAAC,yCAAyC,aACtD,KAAC,KAAK,IACJ,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EACpD,WAAW,EAAC,iBAAiB,EAC7B,SAAS,EAAC,WAAW,GACrB,EACF,MAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,SAAS,EACjB,OAAO,EAAE,GAAG,EAAE;wCACZ,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;wCAChC,IAAI,CAAC,OAAO;4CAAE,OAAO;wCACrB,WAAW,CAAC;4CACV,QAAQ;4CACR,QAAQ,EAAE,OAAO;4CACjB,UAAU,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,SAAS;yCAC3C,CAAC,CAAC;oCACL,CAAC,aAED,KAAC,cAAc,IAAC,IAAI,EAAE,EAAE,GAAI,eAErB,IACL,EAEN,eAAK,SAAS,EAAC,sEAAsE,aAClF,cAAc,CAAC,CAAC,CAAC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,EACzD,cAAc,CAAC,CAAC,CAAC,KAAC,WAAW,IAAC,MAAM,EAAE,cAAc,GAAI,CAAC,CAAC,CAAC,IAAI,EAC/D,cAAc,EAAE,cAAc,CAAC,CAAC,CAAC,CAChC,KAAC,KAAK,IAAC,OAAO,EAAC,SAAS,EAAC,SAAS,EAAC,WAAW,YAC3C,cAAc,CAAC,cAAc,GACxB,CACT,CAAC,CAAC,CAAC,IAAI,EACP,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CACrB,2BACG,WAAW,CAAC,MAAM,CAAC,WAAW,aAAI,GAAG,EACrC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,IAC1D,CACR,CAAC,CAAC,CAAC,IAAI,IACJ,IACE,EAET,WAAW,CAAC,CAAC,CAAC,CACb,KAAC,gBAAgB,IACf,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,aAAa,EAAE,GACnC,CACH,CAAC,CAAC,CAAC,IAAI,EAER,eAAK,SAAS,EAAC,qCAAqC,aAClD,mBAAS,SAAS,EAAC,kCAAkC,aACnD,eAAK,SAAS,EAAC,sDAAsD,aACnE,0BACE,cAAK,SAAS,EAAC,uCAAuC,wBAEhD,EACN,eAAK,SAAS,EAAC,+BAA+B,aAC3C,UAAU,EAAE,KAAK,IAAI,CAAC,qBAAY,GAAG,EACrC,UAAU,EAAE,MAAM,EAAE,KAAK,IAAI,eAAe,IACzC,IACF,EACN,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,MAAM,EACX,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE,gBACnB,iBAAiB,YAE5B,KAAC,WAAW,IAAC,IAAI,EAAE,EAAE,GAAI,GAClB,IACL,EACN,eAAK,SAAS,EAAC,2CAA2C,aACvD,aAAa,CAAC,CAAC,CAAC,CACf,8BACE,KAAC,QAAQ,IAAC,SAAS,EAAC,wBAAwB,GAAG,EAC/C,KAAC,QAAQ,IAAC,SAAS,EAAC,wBAAwB,GAAG,EAC/C,KAAC,QAAQ,IAAC,SAAS,EAAC,wBAAwB,GAAG,IAC9C,CACJ,CAAC,CAAC,CAAC,IAAI,EACP,CAAC,aAAa,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAC9C,eAAK,SAAS,EAAC,mIAAmI,aAChJ,KAAC,YAAY,IAAC,SAAS,EAAC,cAAc,GAAG,yBAErC,CACP,CAAC,CAAC,CAAC,IAAI,EACP,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC7B,KAAC,UAAU,IAET,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAAE,QAAQ,KAAK,MAAM,CAAC,EAAE,EAC1C,QAAQ,EAAE,GAAG,EAAE,CACb,WAAW,CAAC;gDACV,QAAQ,EAAE,eAAe,CAAC,QAAQ;gDAClC,QAAQ,EAAE,MAAM,CAAC,EAAE;gDACnB,UAAU,EAAE,eAAe,CAAC,UAAU,IAAI,SAAS;6CACpD,CAAC,IARC,MAAM,CAAC,EAAE,CAUd,CACH,CAAC,IACE,IACE,EAEV,mBAAS,SAAS,EAAC,SAAS,aACzB,WAAW,CAAC,CAAC,CAAC,CACb,KAAC,gBAAgB,IACf,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,aAAa,EAAE,GACnC,CACH,CAAC,CAAC,CAAC,IAAI,EACP,aAAa,CAAC,CAAC,CAAC,CACf,eAAK,SAAS,EAAC,wBAAwB,aACrC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,eAAe,GAAG,EACtC,KAAC,QAAQ,IAAC,SAAS,EAAC,uBAAuB,GAAG,IAC1C,CACP,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CACX,KAAC,YAAY,IAAC,MAAM,EAAE,MAAM,GAAI,CACjC,CAAC,CAAC,CAAC,CACF,eAAK,SAAS,EAAC,gJAAgJ,aAC7J,KAAC,cAAc,IAAC,SAAS,EAAC,cAAc,GAAG,mCAEvC,CACP,IACO,IACN,IACF,GACQ,CACjB,CAAC;AACJ,CAAC","sourcesContent":["import { agentNativePath } from \"@agent-native/core/client/api-path\";\nimport { useActionQuery } from \"@agent-native/core/client/hooks\";\nimport {\n IconDatabase,\n IconFileSearch,\n IconRefresh,\n IconSearch,\n} from \"@tabler/icons-react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useSearchParams } from \"react-router\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport { Input } from \"../../components/ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../components/ui/select\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from \"../../components/ui/tabs\";\nimport { cn } from \"../../lib/utils\";\n\nexport function meta() {\n return [{ title: \"Thread Debug — Dispatch\" }];\n}\n\ninterface ThreadDebugSource {\n id: string;\n label: string;\n kind: \"current\" | \"env\" | \"configured\";\n current: boolean;\n connected: boolean;\n databaseUrlEnv: string | null;\n databaseAuthTokenEnv: string | null;\n canInspectAll: boolean;\n}\n\ninterface ThreadSearchResult {\n id: string;\n ownerEmail: string;\n title: string;\n preview: string;\n messageCount: number;\n createdAt: number;\n updatedAt: number;\n snippet: string;\n}\n\ninterface ThreadMessage {\n index: number;\n id: string | null;\n role: string;\n createdAt: string | number | null;\n status: unknown;\n text: string;\n contentParts: any[];\n attachments: any[];\n metadata: unknown;\n}\n\ninterface ThreadRun {\n id: string;\n status: string;\n abortReason: string | null;\n startedAt: number;\n completedAt: number | null;\n heartbeatAt: number | null;\n events: Array<{ seq: number; event: any; rawEventData: string }>;\n}\n\ninterface ThreadDebugResponse {\n source: {\n id: string;\n label: string;\n kind: string;\n databaseUrlEnv: string | null;\n };\n access: { viewerEmail: string; scope: string; canInspectAll: boolean };\n thread: ThreadSearchResult;\n messages: ThreadMessage[];\n debug: any;\n debugRuns: any[];\n queuedMessages: any[];\n threadData: any;\n rawThreadData: string;\n runs: ThreadRun[];\n traces: { summaries: any[]; spans: any[] };\n feedback: any[];\n satisfaction: any[];\n evals: any[];\n checkpoints: any[];\n}\n\nfunction formatDate(value: number | string | null | undefined): string {\n if (value == null || value === \"\") return \"n/a\";\n const numeric = Number(value);\n const date = Number.isFinite(numeric) ? new Date(numeric) : new Date(value);\n if (Number.isNaN(date.getTime())) return \"n/a\";\n return date.toLocaleString();\n}\n\nfunction json(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n\nfunction eventLabel(event: any): string {\n if (!event || typeof event !== \"object\") return \"event\";\n if (event.type === \"tool_start\") return `tool_start · ${event.tool}`;\n if (event.type === \"tool_done\") return `tool_done · ${event.tool}`;\n if (event.type === \"text\") return \"text\";\n if (event.type === \"error\") return `error · ${event.errorCode ?? \"agent\"}`;\n return String(event.type ?? \"event\");\n}\n\nfunction messageTitle(message: ThreadMessage): string {\n const role = message.role || \"unknown\";\n return `${role.charAt(0).toUpperCase()}${role.slice(1)} ${message.index + 1}`;\n}\n\nfunction toolParts(message: ThreadMessage): any[] {\n return message.contentParts.filter((part) => part?.type === \"tool-call\");\n}\n\nfunction RawBlock({\n value,\n className,\n}: {\n value: unknown;\n className?: string;\n}) {\n return (\n <pre\n className={cn(\n \"max-h-[520px] overflow-auto rounded-lg border bg-muted/30 p-3 text-xs leading-relaxed text-foreground\",\n \"whitespace-pre-wrap break-words\",\n className,\n )}\n >\n {typeof value === \"string\" ? value : json(value)}\n </pre>\n );\n}\n\nfunction SourceBadge({ source }: { source: ThreadDebugSource }) {\n return (\n <Badge variant={source.current ? \"default\" : \"secondary\"}>\n {source.current ? \"current\" : source.kind}\n </Badge>\n );\n}\n\nfunction ResultCard({\n result,\n selected,\n onSelect,\n}: {\n result: ThreadSearchResult;\n selected: boolean;\n onSelect: () => void;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onSelect}\n className={cn(\n \"w-full rounded-lg border px-3 py-3 text-left transition-colors\",\n selected\n ? \"border-foreground bg-muted\"\n : \"bg-card hover:border-foreground/30 hover:bg-muted/40\",\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium text-foreground\">\n {result.title || result.preview || result.id}\n </div>\n <div className=\"mt-1 truncate font-mono text-[11px] text-muted-foreground\">\n {result.id}\n </div>\n </div>\n <Badge variant=\"outline\" className=\"shrink-0\">\n {result.messageCount}\n </Badge>\n </div>\n <div className=\"mt-2 line-clamp-3 text-xs leading-relaxed text-muted-foreground\">\n {result.snippet || result.preview || \"No preview\"}\n </div>\n <div className=\"mt-2 flex items-center justify-between gap-3 text-[11px] text-muted-foreground\">\n <span className=\"truncate\">{result.ownerEmail}</span>\n <span className=\"shrink-0\">{formatDate(result.updatedAt)}</span>\n </div>\n </button>\n );\n}\n\nfunction MessageBlock({ message }: { message: ThreadMessage }) {\n const tools = toolParts(message);\n return (\n <div className=\"rounded-lg bg-card\">\n <div className=\"flex flex-wrap items-center justify-between gap-2 border-b px-3 py-2\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <Badge\n variant={message.role === \"assistant\" ? \"default\" : \"secondary\"}\n >\n {message.role}\n </Badge>\n <span className=\"truncate text-sm font-medium text-foreground\">\n {messageTitle(message)}\n </span>\n </div>\n <div className=\"flex items-center gap-2 text-[11px] text-muted-foreground\">\n {message.attachments.length > 0 ? (\n <Badge variant=\"outline\">{message.attachments.length} files</Badge>\n ) : null}\n <span>{formatDate(message.createdAt)}</span>\n </div>\n </div>\n <div className=\"space-y-3 px-3 py-3\">\n {message.text ? (\n <div className=\"whitespace-pre-wrap break-words text-sm leading-relaxed text-foreground\">\n {message.text}\n </div>\n ) : (\n <div className=\"text-sm text-muted-foreground\">No text content</div>\n )}\n {tools.length > 0 ? (\n <div className=\"space-y-2\">\n {tools.map((tool, index) => (\n <details\n key={`${message.id ?? message.index}-tool-${index}`}\n className=\"rounded-md border bg-muted/30 px-3 py-2\"\n >\n <summary className=\"cursor-pointer text-xs font-medium text-foreground\">\n {tool.toolName ?? tool.name ?? \"tool-call\"}\n </summary>\n <RawBlock value={tool} className=\"mt-2 max-h-72\" />\n </details>\n ))}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction ThreadDetail({ detail }: { detail: ThreadDebugResponse }) {\n const rawBundle = useMemo(\n () => ({\n thread: detail.thread,\n debug: detail.debug,\n debugRuns: detail.debugRuns,\n queuedMessages: detail.queuedMessages,\n threadData: detail.threadData,\n runs: detail.runs,\n traces: detail.traces,\n feedback: detail.feedback,\n satisfaction: detail.satisfaction,\n evals: detail.evals,\n checkpoints: detail.checkpoints,\n }),\n [detail],\n );\n\n return (\n <div className=\"rounded-lg bg-card\">\n <div className=\"border-b px-4 py-3\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"truncate text-base font-semibold text-foreground\">\n {detail.thread.title || detail.thread.preview || detail.thread.id}\n </div>\n <div className=\"mt-1 truncate font-mono text-xs text-muted-foreground\">\n {detail.thread.id}\n </div>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"secondary\">{detail.messages.length} messages</Badge>\n <Badge variant=\"secondary\">{detail.runs.length} runs</Badge>\n <Badge variant=\"outline\">{detail.source.label}</Badge>\n </div>\n </div>\n <div className=\"mt-3 grid gap-2 text-xs text-muted-foreground sm:grid-cols-3\">\n <div className=\"truncate\">Owner: {detail.thread.ownerEmail}</div>\n <div>Created: {formatDate(detail.thread.createdAt)}</div>\n <div>Updated: {formatDate(detail.thread.updatedAt)}</div>\n </div>\n </div>\n\n <Tabs defaultValue=\"transcript\" className=\"p-4\">\n <TabsList>\n <TabsTrigger value=\"transcript\">Transcript</TabsTrigger>\n <TabsTrigger value=\"runs\">Runs</TabsTrigger>\n <TabsTrigger value=\"internals\">Internals</TabsTrigger>\n <TabsTrigger value=\"raw\">Raw</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"transcript\" className=\"mt-4 space-y-3\">\n {detail.messages.length > 0 ? (\n detail.messages.map((message) => (\n <MessageBlock\n key={message.id ?? `message-${message.index}`}\n message={message}\n />\n ))\n ) : (\n <div className=\"rounded-lg border border-dashed px-4 py-8 text-center text-sm text-muted-foreground\">\n No persisted messages.\n </div>\n )}\n </TabsContent>\n\n <TabsContent value=\"runs\" className=\"mt-4 space-y-3\">\n {detail.runs.length > 0 ? (\n detail.runs.map((run) => (\n <details key={run.id} className=\"rounded-lg bg-card\">\n <summary className=\"cursor-pointer px-4 py-3\">\n <div className=\"inline-flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\">{run.status}</Badge>\n <span className=\"font-mono text-xs text-foreground\">\n {run.id}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {formatDate(run.startedAt)}\n </span>\n </div>\n </summary>\n <div className=\"space-y-2 border-t px-4 py-3\">\n {run.events.map((event) => (\n <details\n key={`${run.id}-${event.seq}`}\n className=\"rounded-md border bg-muted/30 px-3 py-2\"\n >\n <summary className=\"cursor-pointer text-xs font-medium text-foreground\">\n #{event.seq} {eventLabel(event.event)}\n </summary>\n <RawBlock value={event.event} className=\"mt-2 max-h-72\" />\n </details>\n ))}\n {run.events.length === 0 ? (\n <div className=\"text-sm text-muted-foreground\">\n No retained run events.\n </div>\n ) : null}\n </div>\n </details>\n ))\n ) : (\n <div className=\"rounded-lg border border-dashed px-4 py-8 text-center text-sm text-muted-foreground\">\n No retained runs.\n </div>\n )}\n </TabsContent>\n\n <TabsContent value=\"internals\" className=\"mt-4 space-y-4\">\n <div className=\"grid gap-4 lg:grid-cols-2\">\n <div>\n <div className=\"mb-2 text-sm font-medium text-foreground\">\n Debug Runs\n </div>\n <RawBlock\n value={\n detail.debugRuns.length > 0\n ? detail.debugRuns\n : (detail.debug ?? {})\n }\n />\n </div>\n <div>\n <div className=\"mb-2 text-sm font-medium text-foreground\">\n Trace Summaries\n </div>\n <RawBlock value={detail.traces.summaries} />\n </div>\n <div>\n <div className=\"mb-2 text-sm font-medium text-foreground\">\n Trace Spans\n </div>\n <RawBlock value={detail.traces.spans} />\n </div>\n <div>\n <div className=\"mb-2 text-sm font-medium text-foreground\">\n Feedback And Evals\n </div>\n <RawBlock\n value={{\n feedback: detail.feedback,\n satisfaction: detail.satisfaction,\n evals: detail.evals,\n checkpoints: detail.checkpoints,\n }}\n />\n </div>\n </div>\n </TabsContent>\n\n <TabsContent value=\"raw\" className=\"mt-4 space-y-4\">\n <RawBlock value={rawBundle} />\n <RawBlock value={detail.rawThreadData} />\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n\nexport default function ThreadDebugRoute() {\n const [routeSearchParams] = useSearchParams();\n const initialSourceId = routeSearchParams.get(\"source\") || \"current\";\n const initialQuery = routeSearchParams.get(\"query\") || \"\";\n const initialOwnerEmail = routeSearchParams.get(\"ownerEmail\") || \"\";\n const [sourceId, setSourceId] = useState(initialSourceId);\n const [query, setQuery] = useState(initialQuery);\n const [ownerEmail, setOwnerEmail] = useState(initialOwnerEmail);\n const [threadId, setThreadId] = useState(\"\");\n const [submittedSearch, setSubmittedSearch] = useState({\n sourceId: initialSourceId,\n query: initialQuery,\n ownerEmail: initialOwnerEmail,\n });\n const [selected, setSelected] = useState<{\n sourceId: string;\n threadId: string;\n ownerEmail?: string;\n } | null>(null);\n\n const sourcesQuery = useActionQuery<{\n access: {\n viewerEmail: string;\n orgId: string | null;\n role: string | null;\n envAdmin: boolean;\n canInspectAll: boolean;\n memberCount: number;\n };\n sources: ThreadDebugSource[];\n }>(\"list-agent-thread-sources\", {});\n const { data: sourcesData, isLoading: sourcesLoading } = sourcesQuery;\n\n const sources: ThreadDebugSource[] = sourcesData?.sources ?? [];\n const searchParams = useMemo(\n () => ({\n sourceId: submittedSearch.sourceId,\n query: submittedSearch.query || undefined,\n ownerEmail: submittedSearch.ownerEmail || undefined,\n limit: 25,\n }),\n [submittedSearch],\n );\n const {\n data: searchData,\n isLoading: searchLoading,\n error: searchError,\n refetch: refetchSearch,\n } = useActionQuery<{\n count: number;\n threads: ThreadSearchResult[];\n access: { scope: string; canInspectAll: boolean };\n source: { id: string; label: string };\n }>(\"search-agent-threads\", searchParams);\n const searchThreads: ThreadSearchResult[] = searchData?.threads ?? [];\n\n const detailParams = useMemo(\n () => ({\n sourceId: selected?.sourceId ?? \"current\",\n threadId: selected?.threadId ?? \"\",\n ownerEmail: selected?.ownerEmail,\n maxRuns: 20,\n maxEvents: 800,\n maxTraceSpans: 600,\n }),\n [selected],\n );\n const {\n data: detail,\n isLoading: detailLoading,\n error: detailError,\n refetch: refetchDetail,\n } = useActionQuery<ThreadDebugResponse>(\n \"get-agent-thread-debug\",\n detailParams,\n {\n enabled: Boolean(selected?.threadId),\n },\n );\n\n const selectedSource = sources.find((source) => source.id === sourceId);\n\n useEffect(() => {\n fetch(agentNativePath(\"/_agent-native/application-state/navigation\"), {\n method: \"PUT\",\n keepalive: true,\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n view: \"thread-debug\",\n path:\n typeof window === \"undefined\"\n ? \"/thread-debug\"\n : window.location.pathname,\n sourceId,\n query,\n ownerEmail: ownerEmail.trim() || undefined,\n threadId: selected?.threadId ?? (threadId.trim() || undefined),\n }),\n }).catch(() => {});\n }, [ownerEmail, query, selected?.threadId, sourceId, threadId]);\n\n return (\n <DispatchShell\n title=\"Thread Debug\"\n description=\"Inspect persisted agent chat threads, run events, and AI internals.\"\n >\n <div className=\"space-y-4\">\n {sourcesQuery.isError ? (\n <ActionQueryError\n error={sourcesQuery.error}\n onRetry={() => void sourcesQuery.refetch()}\n />\n ) : null}\n <section className=\"rounded-lg bg-card p-4\">\n <div className=\"grid gap-3 lg:grid-cols-[220px_1fr_260px_auto]\">\n <Select value={sourceId} onValueChange={setSourceId}>\n <SelectTrigger>\n <SelectValue placeholder=\"Source\" />\n </SelectTrigger>\n <SelectContent>\n {sources.map((source) => (\n <SelectItem key={source.id} value={source.id}>\n {source.label}\n </SelectItem>\n ))}\n {sources.length === 0 ? (\n <SelectItem value=\"current\">Current Dispatch DB</SelectItem>\n ) : null}\n </SelectContent>\n </Select>\n <Input\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n placeholder=\"Search title, preview, messages, tools\"\n />\n <Input\n value={ownerEmail}\n onChange={(event) => setOwnerEmail(event.target.value)}\n placeholder=\"Owner email\"\n />\n <Button\n type=\"button\"\n onClick={() =>\n setSubmittedSearch({\n sourceId,\n query: query.trim(),\n ownerEmail: ownerEmail.trim(),\n })\n }\n >\n <IconSearch size={16} />\n Search\n </Button>\n </div>\n\n <div className=\"mt-3 grid gap-3 lg:grid-cols-[1fr_auto]\">\n <Input\n value={threadId}\n onChange={(event) => setThreadId(event.target.value)}\n placeholder=\"Paste thread ID\"\n className=\"font-mono\"\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => {\n const trimmed = threadId.trim();\n if (!trimmed) return;\n setSelected({\n sourceId,\n threadId: trimmed,\n ownerEmail: ownerEmail.trim() || undefined,\n });\n }}\n >\n <IconFileSearch size={16} />\n Inspect\n </Button>\n </div>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-2 text-xs text-muted-foreground\">\n {sourcesLoading ? <Skeleton className=\"h-5 w-32\" /> : null}\n {selectedSource ? <SourceBadge source={selectedSource} /> : null}\n {selectedSource?.databaseUrlEnv ? (\n <Badge variant=\"outline\" className=\"font-mono\">\n {selectedSource.databaseUrlEnv}\n </Badge>\n ) : null}\n {sourcesData?.access ? (\n <span>\n {sourcesData.access.viewerEmail} ·{\" \"}\n {sourcesData.access.canInspectAll ? \"admin scope\" : \"own scope\"}\n </span>\n ) : null}\n </div>\n </section>\n\n {searchError ? (\n <ActionQueryError\n error={searchError}\n onRetry={() => void refetchSearch()}\n />\n ) : null}\n\n <div className=\"grid gap-4 xl:grid-cols-[380px_1fr]\">\n <section className=\"min-h-[520px] rounded-lg bg-card\">\n <div className=\"flex items-center justify-between border-b px-4 py-3\">\n <div>\n <div className=\"text-sm font-semibold text-foreground\">\n Threads\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {searchData?.count ?? 0} results ·{\" \"}\n {searchData?.access?.scope ?? \"current scope\"}\n </div>\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => refetchSearch()}\n aria-label=\"Refresh threads\"\n >\n <IconRefresh size={16} />\n </Button>\n </div>\n <div className=\"max-h-[760px] space-y-2 overflow-auto p-3\">\n {searchLoading ? (\n <>\n <Skeleton className=\"h-28 w-full rounded-lg\" />\n <Skeleton className=\"h-28 w-full rounded-lg\" />\n <Skeleton className=\"h-28 w-full rounded-lg\" />\n </>\n ) : null}\n {!searchLoading && searchThreads.length === 0 ? (\n <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\">\n <IconDatabase className=\"mb-2 h-5 w-5\" />\n No threads found.\n </div>\n ) : null}\n {searchThreads.map((result) => (\n <ResultCard\n key={result.id}\n result={result}\n selected={selected?.threadId === result.id}\n onSelect={() =>\n setSelected({\n sourceId: submittedSearch.sourceId,\n threadId: result.id,\n ownerEmail: submittedSearch.ownerEmail || undefined,\n })\n }\n />\n ))}\n </div>\n </section>\n\n <section className=\"min-w-0\">\n {detailError ? (\n <ActionQueryError\n error={detailError}\n onRetry={() => void refetchDetail()}\n />\n ) : null}\n {detailLoading ? (\n <div className=\"rounded-lg bg-card p-4\">\n <Skeleton className=\"h-6 w-72\" />\n <Skeleton className=\"mt-3 h-4 w-96\" />\n <Skeleton className=\"mt-6 h-[520px] w-full\" />\n </div>\n ) : detail ? (\n <ThreadDetail detail={detail} />\n ) : (\n <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\">\n <IconFileSearch className=\"mb-2 h-5 w-5\" />\n Select or inspect a thread.\n </div>\n )}\n </section>\n </div>\n </div>\n </DispatchShell>\n );\n}\n"]}
1
+ {"version":3,"file":"thread-debug.js","sourceRoot":"","sources":["../../../src/routes/pages/thread-debug.tsx"],"names":[],"mappings":"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","sourcesContent":["import { agentNativePath } from \"@agent-native/core/client/api-path\";\nimport { useActionQuery } from \"@agent-native/core/client/hooks\";\nimport {\n IconDatabase,\n IconFileSearch,\n IconRefresh,\n IconSearch,\n} from \"@tabler/icons-react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useSearchParams } from \"react-router\";\n\nimport { ActionQueryError } from \"../../components/action-query-error\";\nimport { DispatchShell } from \"../../components/dispatch-shell\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport { Input } from \"../../components/ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../components/ui/select\";\nimport { Skeleton } from \"../../components/ui/skeleton\";\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from \"../../components/ui/tabs\";\nimport { cn } from \"../../lib/utils\";\n\nexport function meta() {\n return [{ title: \"Thread Debug — Dispatch\" }];\n}\n\ninterface ThreadDebugSource {\n id: string;\n label: string;\n kind: \"current\" | \"env\" | \"configured\";\n current: boolean;\n connected: boolean;\n databaseUrlEnv: string | null;\n databaseAuthTokenEnv: string | null;\n canInspectAll: boolean;\n}\n\ninterface ThreadSearchResult {\n id: string;\n ownerEmail: string;\n title: string;\n preview: string;\n messageCount: number;\n createdAt: number;\n updatedAt: number;\n snippet: string;\n}\n\ninterface ThreadMessage {\n index: number;\n id: string | null;\n role: string;\n createdAt: string | number | null;\n status: unknown;\n text: string;\n contentParts: any[];\n attachments: any[];\n metadata: unknown;\n}\n\ninterface ThreadRun {\n id: string;\n status: string;\n abortReason: string | null;\n startedAt: number;\n completedAt: number | null;\n heartbeatAt: number | null;\n events: Array<{ seq: number; event: any; rawEventData: string }>;\n}\n\ninterface ThreadDebugResponse {\n source: {\n id: string;\n label: string;\n kind: string;\n databaseUrlEnv: string | null;\n };\n access: { viewerEmail: string; scope: string; canInspectAll: boolean };\n thread: ThreadSearchResult;\n lookup?: { requestedId: string; threadId: string; runId: string | null };\n messages: ThreadMessage[];\n debug: any;\n debugRuns: any[];\n queuedMessages: any[];\n threadData: any;\n rawThreadData: string;\n runs: ThreadRun[];\n traces: { summaries: any[]; spans: any[] };\n feedback: any[];\n satisfaction: any[];\n evals: any[];\n checkpoints: any[];\n}\n\nfunction formatDate(value: number | string | null | undefined): string {\n if (value == null || value === \"\") return \"n/a\";\n const numeric = Number(value);\n const date = Number.isFinite(numeric) ? new Date(numeric) : new Date(value);\n if (Number.isNaN(date.getTime())) return \"n/a\";\n return date.toLocaleString();\n}\n\nfunction json(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n\nfunction eventLabel(event: any): string {\n if (!event || typeof event !== \"object\") return \"event\";\n if (event.type === \"tool_start\") return `tool_start · ${event.tool}`;\n if (event.type === \"tool_done\") return `tool_done · ${event.tool}`;\n if (event.type === \"text\") return \"text\";\n if (event.type === \"error\") return `error · ${event.errorCode ?? \"agent\"}`;\n return String(event.type ?? \"event\");\n}\n\nfunction messageTitle(message: ThreadMessage): string {\n const role = message.role || \"unknown\";\n return `${role.charAt(0).toUpperCase()}${role.slice(1)} ${message.index + 1}`;\n}\n\nfunction toolParts(message: ThreadMessage): any[] {\n return message.contentParts.filter((part) => part?.type === \"tool-call\");\n}\n\nfunction RawBlock({\n value,\n className,\n}: {\n value: unknown;\n className?: string;\n}) {\n return (\n <pre\n className={cn(\n \"max-h-[520px] overflow-auto rounded-lg border bg-muted/30 p-3 text-xs leading-relaxed text-foreground\",\n \"whitespace-pre-wrap break-words\",\n className,\n )}\n >\n {typeof value === \"string\" ? value : json(value)}\n </pre>\n );\n}\n\nfunction SourceBadge({ source }: { source: ThreadDebugSource }) {\n return (\n <Badge variant={source.current ? \"default\" : \"secondary\"}>\n {source.current ? \"current\" : source.kind}\n </Badge>\n );\n}\n\nfunction ResultCard({\n result,\n selected,\n onSelect,\n}: {\n result: ThreadSearchResult;\n selected: boolean;\n onSelect: () => void;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onSelect}\n className={cn(\n \"w-full rounded-lg border px-3 py-3 text-left transition-colors\",\n selected\n ? \"border-foreground bg-muted\"\n : \"bg-card hover:border-foreground/30 hover:bg-muted/40\",\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium text-foreground\">\n {result.title || result.preview || result.id}\n </div>\n <div className=\"mt-1 truncate font-mono text-[11px] text-muted-foreground\">\n {result.id}\n </div>\n </div>\n <Badge variant=\"outline\" className=\"shrink-0\">\n {result.messageCount}\n </Badge>\n </div>\n <div className=\"mt-2 line-clamp-3 text-xs leading-relaxed text-muted-foreground\">\n {result.snippet || result.preview || \"No preview\"}\n </div>\n <div className=\"mt-2 flex items-center justify-between gap-3 text-[11px] text-muted-foreground\">\n <span className=\"truncate\">{result.ownerEmail}</span>\n <span className=\"shrink-0\">{formatDate(result.updatedAt)}</span>\n </div>\n </button>\n );\n}\n\nfunction MessageBlock({ message }: { message: ThreadMessage }) {\n const tools = toolParts(message);\n return (\n <div className=\"rounded-lg bg-card\">\n <div className=\"flex flex-wrap items-center justify-between gap-2 border-b px-3 py-2\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <Badge\n variant={message.role === \"assistant\" ? \"default\" : \"secondary\"}\n >\n {message.role}\n </Badge>\n <span className=\"truncate text-sm font-medium text-foreground\">\n {messageTitle(message)}\n </span>\n </div>\n <div className=\"flex items-center gap-2 text-[11px] text-muted-foreground\">\n {message.attachments.length > 0 ? (\n <Badge variant=\"outline\">{message.attachments.length} files</Badge>\n ) : null}\n <span>{formatDate(message.createdAt)}</span>\n </div>\n </div>\n <div className=\"space-y-3 px-3 py-3\">\n {message.text ? (\n <div className=\"whitespace-pre-wrap break-words text-sm leading-relaxed text-foreground\">\n {message.text}\n </div>\n ) : (\n <div className=\"text-sm text-muted-foreground\">No text content</div>\n )}\n {tools.length > 0 ? (\n <div className=\"space-y-2\">\n {tools.map((tool, index) => (\n <details\n key={`${message.id ?? message.index}-tool-${index}`}\n className=\"rounded-md border bg-muted/30 px-3 py-2\"\n >\n <summary className=\"cursor-pointer text-xs font-medium text-foreground\">\n {tool.toolName ?? tool.name ?? \"tool-call\"}\n </summary>\n <RawBlock value={tool} className=\"mt-2 max-h-72\" />\n </details>\n ))}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction ThreadDetail({ detail }: { detail: ThreadDebugResponse }) {\n const rawBundle = useMemo(\n () => ({\n thread: detail.thread,\n debug: detail.debug,\n debugRuns: detail.debugRuns,\n queuedMessages: detail.queuedMessages,\n threadData: detail.threadData,\n runs: detail.runs,\n traces: detail.traces,\n feedback: detail.feedback,\n satisfaction: detail.satisfaction,\n evals: detail.evals,\n checkpoints: detail.checkpoints,\n }),\n [detail],\n );\n\n return (\n <div className=\"rounded-lg bg-card\">\n <div className=\"border-b px-4 py-3\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"truncate text-base font-semibold text-foreground\">\n {detail.thread.title || detail.thread.preview || detail.thread.id}\n </div>\n <div className=\"mt-1 truncate font-mono text-xs text-muted-foreground\">\n {detail.thread.id}\n </div>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"secondary\">{detail.messages.length} messages</Badge>\n <Badge variant=\"secondary\">{detail.runs.length} runs</Badge>\n <Badge variant=\"outline\">{detail.source.label}</Badge>\n </div>\n </div>\n <div className=\"mt-3 grid gap-2 text-xs text-muted-foreground sm:grid-cols-3\">\n <div className=\"truncate\">Owner: {detail.thread.ownerEmail}</div>\n <div>Created: {formatDate(detail.thread.createdAt)}</div>\n <div>Updated: {formatDate(detail.thread.updatedAt)}</div>\n </div>\n </div>\n\n <Tabs defaultValue=\"transcript\" className=\"p-4\">\n <TabsList>\n <TabsTrigger value=\"transcript\">Transcript</TabsTrigger>\n <TabsTrigger value=\"runs\">Runs</TabsTrigger>\n <TabsTrigger value=\"internals\">Internals</TabsTrigger>\n <TabsTrigger value=\"raw\">Raw</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"transcript\" className=\"mt-4 space-y-3\">\n {detail.messages.length > 0 ? (\n detail.messages.map((message) => (\n <MessageBlock\n key={message.id ?? `message-${message.index}`}\n message={message}\n />\n ))\n ) : (\n <div className=\"rounded-lg border border-dashed px-4 py-8 text-center text-sm text-muted-foreground\">\n No persisted messages.\n </div>\n )}\n </TabsContent>\n\n <TabsContent value=\"runs\" className=\"mt-4 space-y-3\">\n {detail.runs.length > 0 ? (\n detail.runs.map((run) => (\n <details key={run.id} className=\"rounded-lg bg-card\">\n <summary className=\"cursor-pointer px-4 py-3\">\n <div className=\"inline-flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\">{run.status}</Badge>\n <span className=\"font-mono text-xs text-foreground\">\n {run.id}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {formatDate(run.startedAt)}\n </span>\n </div>\n </summary>\n <div className=\"space-y-2 border-t px-4 py-3\">\n {run.events.map((event) => (\n <details\n key={`${run.id}-${event.seq}`}\n className=\"rounded-md border bg-muted/30 px-3 py-2\"\n >\n <summary className=\"cursor-pointer text-xs font-medium text-foreground\">\n #{event.seq} {eventLabel(event.event)}\n </summary>\n <RawBlock value={event.event} className=\"mt-2 max-h-72\" />\n </details>\n ))}\n {run.events.length === 0 ? (\n <div className=\"text-sm text-muted-foreground\">\n No retained run events.\n </div>\n ) : null}\n </div>\n </details>\n ))\n ) : (\n <div className=\"rounded-lg border border-dashed px-4 py-8 text-center text-sm text-muted-foreground\">\n No retained runs.\n </div>\n )}\n </TabsContent>\n\n <TabsContent value=\"internals\" className=\"mt-4 space-y-4\">\n <div className=\"grid gap-4 lg:grid-cols-2\">\n <div>\n <div className=\"mb-2 text-sm font-medium text-foreground\">\n Debug Runs\n </div>\n <RawBlock\n value={\n detail.debugRuns.length > 0\n ? detail.debugRuns\n : (detail.debug ?? {})\n }\n />\n </div>\n <div>\n <div className=\"mb-2 text-sm font-medium text-foreground\">\n Trace Summaries\n </div>\n <RawBlock value={detail.traces.summaries} />\n </div>\n <div>\n <div className=\"mb-2 text-sm font-medium text-foreground\">\n Trace Spans\n </div>\n <RawBlock value={detail.traces.spans} />\n </div>\n <div>\n <div className=\"mb-2 text-sm font-medium text-foreground\">\n Feedback And Evals\n </div>\n <RawBlock\n value={{\n feedback: detail.feedback,\n satisfaction: detail.satisfaction,\n evals: detail.evals,\n checkpoints: detail.checkpoints,\n }}\n />\n </div>\n </div>\n </TabsContent>\n\n <TabsContent value=\"raw\" className=\"mt-4 space-y-4\">\n <RawBlock value={rawBundle} />\n <RawBlock value={detail.rawThreadData} />\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n\nexport default function ThreadDebugRoute() {\n const [routeSearchParams] = useSearchParams();\n const initialSourceId = routeSearchParams.get(\"source\") || \"current\";\n const initialQuery = routeSearchParams.get(\"query\") || \"\";\n const initialOwnerEmail = routeSearchParams.get(\"ownerEmail\") || \"\";\n const [sourceId, setSourceId] = useState(initialSourceId);\n const [query, setQuery] = useState(initialQuery);\n const [ownerEmail, setOwnerEmail] = useState(initialOwnerEmail);\n const [lookupId, setLookupId] = useState(\"\");\n const [submittedSearch, setSubmittedSearch] = useState({\n sourceId: initialSourceId,\n query: initialQuery,\n ownerEmail: initialOwnerEmail,\n });\n const [selected, setSelected] = useState<{\n sourceId: string;\n lookupId: string;\n lookupKind: \"thread\" | \"run\";\n ownerEmail?: string;\n } | null>(null);\n\n const sourcesQuery = useActionQuery<{\n access: {\n viewerEmail: string;\n orgId: string | null;\n role: string | null;\n envAdmin: boolean;\n canInspectAll: boolean;\n memberCount: number;\n };\n sources: ThreadDebugSource[];\n }>(\"list-agent-thread-sources\", {});\n const { data: sourcesData, isLoading: sourcesLoading } = sourcesQuery;\n\n const sources: ThreadDebugSource[] = sourcesData?.sources ?? [];\n const searchParams = useMemo(\n () => ({\n sourceId: submittedSearch.sourceId,\n query: submittedSearch.query || undefined,\n ownerEmail: submittedSearch.ownerEmail || undefined,\n limit: 25,\n }),\n [submittedSearch],\n );\n const {\n data: searchData,\n isLoading: searchLoading,\n error: searchError,\n refetch: refetchSearch,\n } = useActionQuery<{\n count: number;\n threads: ThreadSearchResult[];\n access: { scope: string; canInspectAll: boolean };\n source: { id: string; label: string };\n }>(\"search-agent-threads\", searchParams);\n const searchThreads: ThreadSearchResult[] = searchData?.threads ?? [];\n\n const detailParams = useMemo(\n () => ({\n sourceId: selected?.sourceId ?? \"current\",\n ...(selected?.lookupKind === \"run\"\n ? { runId: selected.lookupId }\n : { threadId: selected?.lookupId ?? \"\" }),\n ownerEmail: selected?.ownerEmail,\n maxRuns: 20,\n maxEvents: 800,\n maxTraceSpans: 600,\n }),\n [selected],\n );\n const {\n data: detail,\n isLoading: detailLoading,\n error: detailError,\n refetch: refetchDetail,\n } = useActionQuery<ThreadDebugResponse>(\n \"get-agent-thread-debug\",\n detailParams,\n {\n enabled: Boolean(selected?.lookupId),\n },\n );\n\n const selectedSource = sources.find((source) => source.id === sourceId);\n\n useEffect(() => {\n fetch(agentNativePath(\"/_agent-native/application-state/navigation\"), {\n method: \"PUT\",\n keepalive: true,\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n view: \"thread-debug\",\n path:\n typeof window === \"undefined\"\n ? \"/thread-debug\"\n : window.location.pathname,\n sourceId,\n query,\n ownerEmail: ownerEmail.trim() || undefined,\n threadId:\n selected?.lookupKind === \"thread\"\n ? selected.lookupId\n : !selected && lookupId.trim() && !lookupId.startsWith(\"run-\")\n ? lookupId.trim()\n : undefined,\n runId:\n selected?.lookupKind === \"run\"\n ? selected.lookupId\n : !selected && lookupId.trim() && lookupId.startsWith(\"run-\")\n ? lookupId.trim()\n : undefined,\n }),\n }).catch(() => {});\n }, [ownerEmail, query, selected, sourceId, lookupId]);\n\n return (\n <DispatchShell\n title=\"Thread Debug\"\n description=\"Inspect persisted agent chat threads, run events, and AI internals.\"\n >\n <div className=\"space-y-4\">\n {sourcesQuery.isError ? (\n <ActionQueryError\n error={sourcesQuery.error}\n onRetry={() => void sourcesQuery.refetch()}\n />\n ) : null}\n <section className=\"rounded-lg bg-card p-4\">\n <div className=\"grid gap-3 lg:grid-cols-[220px_1fr_260px_auto]\">\n <Select value={sourceId} onValueChange={setSourceId}>\n <SelectTrigger>\n <SelectValue placeholder=\"Source\" />\n </SelectTrigger>\n <SelectContent>\n {sources.map((source) => (\n <SelectItem key={source.id} value={source.id}>\n {source.label}\n </SelectItem>\n ))}\n {sources.length === 0 ? (\n <SelectItem value=\"current\">Current Dispatch DB</SelectItem>\n ) : null}\n </SelectContent>\n </Select>\n <Input\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n placeholder=\"Search title, preview, messages, tools\"\n />\n <Input\n value={ownerEmail}\n onChange={(event) => setOwnerEmail(event.target.value)}\n placeholder=\"Owner email\"\n />\n <Button\n type=\"button\"\n onClick={() =>\n setSubmittedSearch({\n sourceId,\n query: query.trim(),\n ownerEmail: ownerEmail.trim(),\n })\n }\n >\n <IconSearch size={16} />\n Search\n </Button>\n </div>\n\n <div className=\"mt-3 grid gap-3 lg:grid-cols-[1fr_auto]\">\n <Input\n value={lookupId}\n onChange={(event) => setLookupId(event.target.value)}\n placeholder=\"Paste thread or request/run ID\"\n className=\"font-mono\"\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => {\n const trimmed = lookupId.trim();\n if (!trimmed) return;\n setSelected({\n sourceId,\n lookupId: trimmed,\n lookupKind: trimmed.startsWith(\"run-\") ? \"run\" : \"thread\",\n ownerEmail: ownerEmail.trim() || undefined,\n });\n }}\n >\n <IconFileSearch size={16} />\n Inspect\n </Button>\n </div>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-2 text-xs text-muted-foreground\">\n {sourcesLoading ? <Skeleton className=\"h-5 w-32\" /> : null}\n {selectedSource ? <SourceBadge source={selectedSource} /> : null}\n {selectedSource?.databaseUrlEnv ? (\n <Badge variant=\"outline\" className=\"font-mono\">\n {selectedSource.databaseUrlEnv}\n </Badge>\n ) : null}\n {sourcesData?.access ? (\n <span>\n {sourcesData.access.viewerEmail} ·{\" \"}\n {sourcesData.access.canInspectAll ? \"admin scope\" : \"own scope\"}\n </span>\n ) : null}\n </div>\n </section>\n\n {searchError ? (\n <ActionQueryError\n error={searchError}\n onRetry={() => void refetchSearch()}\n />\n ) : null}\n\n <div className=\"grid gap-4 xl:grid-cols-[380px_1fr]\">\n <section className=\"min-h-[520px] rounded-lg bg-card\">\n <div className=\"flex items-center justify-between border-b px-4 py-3\">\n <div>\n <div className=\"text-sm font-semibold text-foreground\">\n Threads\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {searchData?.count ?? 0} results ·{\" \"}\n {searchData?.access?.scope ?? \"current scope\"}\n </div>\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => refetchSearch()}\n aria-label=\"Refresh threads\"\n >\n <IconRefresh size={16} />\n </Button>\n </div>\n <div className=\"max-h-[760px] space-y-2 overflow-auto p-3\">\n {searchLoading ? (\n <>\n <Skeleton className=\"h-28 w-full rounded-lg\" />\n <Skeleton className=\"h-28 w-full rounded-lg\" />\n <Skeleton className=\"h-28 w-full rounded-lg\" />\n </>\n ) : null}\n {!searchLoading && searchThreads.length === 0 ? (\n <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\">\n <IconDatabase className=\"mb-2 h-5 w-5\" />\n No threads found.\n </div>\n ) : null}\n {searchThreads.map((result) => (\n <ResultCard\n key={result.id}\n result={result}\n selected={\n selected?.lookupKind === \"thread\" &&\n selected.lookupId === result.id\n }\n onSelect={() =>\n setSelected({\n sourceId: submittedSearch.sourceId,\n lookupId: result.id,\n lookupKind: \"thread\",\n ownerEmail: submittedSearch.ownerEmail || undefined,\n })\n }\n />\n ))}\n </div>\n </section>\n\n <section className=\"min-w-0\">\n {detailError ? (\n <ActionQueryError\n error={detailError}\n onRetry={() => void refetchDetail()}\n />\n ) : null}\n {detailLoading ? (\n <div className=\"rounded-lg bg-card p-4\">\n <Skeleton className=\"h-6 w-72\" />\n <Skeleton className=\"mt-3 h-4 w-96\" />\n <Skeleton className=\"mt-6 h-[520px] w-full\" />\n </div>\n ) : detail ? (\n <ThreadDetail detail={detail} />\n ) : (\n <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\">\n <IconFileSearch className=\"mb-2 h-5 w-5\" />\n Select or inspect a thread or request/run ID.\n </div>\n )}\n </section>\n </div>\n </div>\n </DispatchShell>\n );\n}\n"]}
@@ -1373,8 +1373,8 @@ function buildWorkspaceAppPrompt(input) {
1373
1373
  `Use the workspace app layout: create it under apps/${appId}, mount it at /${appId}, keep it on the shared workspace database/hosting model, and avoid table-name collisions by namespacing any new domain tables to the app.`,
1374
1374
  `Important routing rule: from outside the app, link to /${appId}; inside apps/${appId}, React Router routes are app-local. Use <Link to="/review"> and navigate("/review"), not "/${appId}/review"; APP_BASE_PATH supplies the mounted prefix, and hardcoding it causes doubled URLs like /${appId}/${appId}/review.`,
1375
1375
  "Existing first-party apps are neighbors, not implementation details for this app. If the user prompt mentions Mail, Calendar, Analytics, Dispatch, or other templates, treat them as existing hosted/connected apps that this app can link to or call through A2A/default connected agents. For example, Mail, Calendar, and Analytics already exist at https://mail.agent-native.com, https://calendar.agent-native.com, and https://analytics.agent-native.com.",
1376
- `Do not clone first-party templates, create wrapper apps, or scaffold child apps/routes for Mail, Calendar, Analytics, etc. inside apps/${appId} just so this app can access them. If the request is a cross-app dashboard or overview, build only the new dashboard/overview app and delegate to the existing apps for domain work.`,
1377
- "Only create another first-party app copy when the user explicitly asks for a customized fork/copy of that app; otherwise keep using the hosted/shared app so improvements to the base template keep flowing to users.",
1376
+ `Do not create wrapper apps or scaffold child apps/routes for Mail, Calendar, Analytics, etc. inside apps/${appId} just so this app can access them. If the request is a cross-app dashboard or overview, build only the new dashboard/overview app and delegate to the existing apps for domain work.`,
1377
+ "Only create another first-party app when the user explicitly asks for a customized app from that template; otherwise keep using the hosted/shared app so improvements to the base app keep flowing to users.",
1378
1378
  selectedKeys.length
1379
1379
  ? `Dispatch will create pending vault requests for the selected keys for appId "${appId}" after this app creation request is accepted. Do not grant or sync vault keys directly from the app-creation branch.`
1380
1380
  : "Do not grant or request any Dispatch vault keys unless the user asks later.",