larkup 0.4.12 → 0.4.14
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/.next/standalone/apps/web/.next/BUILD_ID +1 -0
- package/.next/standalone/apps/web/.next/app-path-routes-manifest.json +94 -0
- package/.next/standalone/apps/web/.next/build-manifest.json +20 -0
- package/.next/standalone/apps/web/.next/diagnostics/build-diagnostics.json +6 -0
- package/.next/standalone/apps/web/.next/diagnostics/framework.json +1 -0
- package/.next/standalone/apps/web/.next/lock +0 -0
- package/.next/standalone/apps/web/.next/package.json +1 -0
- package/.next/standalone/apps/web/.next/prerender-manifest.json +241 -0
- package/.next/standalone/apps/web/.next/react-loadable-manifest.json +31 -0
- package/.next/standalone/apps/web/.next/required-server-files.json +399 -0
- package/.next/standalone/apps/web/.next/routes-manifest.json +644 -0
- package/.next/standalone/apps/web/.next/server/app/_global-error/page.js +31 -0
- package/.next/standalone/apps/web/.next/server/app/_global-error/page.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/_global-error.html +1 -0
- package/.next/standalone/apps/web/.next/server/app/_global-error.meta +35 -0
- package/.next/standalone/apps/web/.next/server/app/_global-error.rsc +15 -0
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +15 -0
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +21 -0
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
- package/.next/standalone/apps/web/.next/server/app/_not-found/page.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/_not-found.html +1 -0
- package/.next/standalone/apps/web/.next/server/app/_not-found.meta +35 -0
- package/.next/standalone/apps/web/.next/server/app/_not-found.rsc +26 -0
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_full.segment.rsc +26 -0
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +32 -0
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -0
- package/.next/standalone/apps/web/.next/server/app/add/page.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/add/page.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/add/page_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/add.html +1 -0
- package/.next/standalone/apps/web/.next/server/app/add.meta +34 -0
- package/.next/standalone/apps/web/.next/server/app/add.rsc +27 -0
- package/.next/standalone/apps/web/.next/server/app/add.segments/_full.segment.rsc +27 -0
- package/.next/standalone/apps/web/.next/server/app/add.segments/_tree.segment.rsc +2 -0
- package/.next/standalone/apps/web/.next/server/app/add.segments/add/__PAGE__.segment.rsc +33 -0
- package/.next/standalone/apps/web/.next/server/app/api/analytics/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/analytics/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/analytics/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/chat/feedback/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/chat/feedback/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/chat/feedback/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/chat/route.js +111 -0
- package/.next/standalone/apps/web/.next/server/app/api/chat/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/chat/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/chat/status/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/chat/status/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/chat/status/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/test/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/test/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/test/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/test-embedding/route.js +10 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/test-embedding/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/test-embedding/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/test-llm/route.js +10 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/test-llm/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/test-llm/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/test-provider/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/test-provider/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/test-provider/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/verify/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/verify/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/config/verify/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/[channelId]/oauth/callback/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/[channelId]/oauth/callback/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/[channelId]/oauth/callback/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/[channelId]/oauth/start/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/[channelId]/oauth/start/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/[channelId]/oauth/start/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/[channelId]/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/[channelId]/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/[channelId]/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/tunnel/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/tunnel/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/connections/tunnel/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/demo/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/demo/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/demo/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/deploy/ssh/route.js +5 -0
- package/.next/standalone/apps/web/.next/server/app/api/deploy/ssh/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/deploy/ssh/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/deploy/verify/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/deploy/verify/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/deploy/verify/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/describe-image/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/describe-image/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/describe-image/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/edit/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/edit/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/edit/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/export/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/export/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/export/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/extract-text/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/extract-text/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/extract-text/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/parse/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/parse/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/parse/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/restore/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/restore/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/doc-editor/restore/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/document/sign/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/document/sign/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/document/sign/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/documents/move/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/documents/move/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/documents/move/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/documents/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/documents/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/documents/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/files/remote/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/files/remote/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/files/remote/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/firecrawl/local/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/firecrawl/local/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/firecrawl/local/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/gpu-activity/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/gpu-activity/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/gpu-activity/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/groups/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/groups/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/groups/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/index/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/index/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/index/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/[integration]/callback/route.js +4 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/[integration]/callback/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/[integration]/callback/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/[integration]/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/[integration]/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/[integration]/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/notion/callback/route.js +19 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/notion/callback/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/notion/callback/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/notion/route.js +11 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/notion/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/notion/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/integrations/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/jobs/[id]/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/jobs/[id]/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/jobs/[id]/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/jobs/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/jobs/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/jobs/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/marketplace/[toolId]/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/marketplace/[toolId]/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/marketplace/[toolId]/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/marketplace/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/marketplace/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/marketplace/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/mcp/[connectionId]/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/mcp/[connectionId]/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/mcp/[connectionId]/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/mcp/[connectionId]/test/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/mcp/[connectionId]/test/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/mcp/[connectionId]/test/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/mcp/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/mcp/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/[id]/frame/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/[id]/frame/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/[id]/frame/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/[id]/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/[id]/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/[id]/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/inspect/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/inspect/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/inspect/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/jobs/[id]/approval/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/jobs/[id]/approval/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/jobs/[id]/approval/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/jobs/[id]/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/jobs/[id]/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/jobs/[id]/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/process/route.js +2 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/process/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/process/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/stream/route.js +5 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/stream/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/media/stream/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/models/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/models/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/models/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/parse-file/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/parse-file/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/parse-file/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/pdf-page/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/pdf-page/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/pdf-page/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/projects/deployments/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/projects/deployments/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/projects/deployments/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/projects/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/projects/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/projects/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/projects/runtime/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/projects/runtime/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/projects/runtime/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/proxy/verify/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/proxy/verify/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/proxy/verify/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/sandbox/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/sandbox/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/sandbox/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/sandbox/verify/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/sandbox/verify/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/sandbox/verify/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/bing/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/bing/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/bing/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/brave/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/brave/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/brave/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/exa/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/exa/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/exa/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/google/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/google/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/google/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/tavily/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/tavily/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/tavily/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/verify/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/verify/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/search/verify/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/system/cache/route.js +2 -0
- package/.next/standalone/apps/web/.next/server/app/api/system/cache/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/system/cache/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tabular/query/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tabular/query/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tabular/query/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tabular/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tabular/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tabular/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/host/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/host/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/host/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/runtime/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/runtime/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/runtime/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/usage/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/usage/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/usage/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/usage-request/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/usage-request/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/usage-request/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/verify/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/verify/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/[toolId]/verify/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/video-intelligence/connection/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/video-intelligence/connection/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/video-intelligence/connection/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/video-intelligence/usage/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/video-intelligence/usage/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/video-intelligence/usage/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/video-intelligence/usage-request/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/video-intelligence/usage-request/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/tools/video-intelligence/usage-request/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/upload-file/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/upload-file/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/upload-file/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/uploads/[...slug]/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/uploads/[...slug]/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/uploads/[...slug]/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/vector-stores/install/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/vector-stores/install/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/vector-stores/install/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/vector-stores/status/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/vector-stores/status/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/api/vector-stores/status/route_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/chat/[id]/page.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/chat/[id]/page.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/chat/[id]/page_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/chat/page.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/chat/page.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/chat/page_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/chat.html +1 -0
- package/.next/standalone/apps/web/.next/server/app/chat.meta +34 -0
- package/.next/standalone/apps/web/.next/server/app/chat.rsc +28 -0
- package/.next/standalone/apps/web/.next/server/app/chat.segments/_full.segment.rsc +28 -0
- package/.next/standalone/apps/web/.next/server/app/chat.segments/_tree.segment.rsc +3 -0
- package/.next/standalone/apps/web/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +34 -0
- package/.next/standalone/apps/web/.next/server/app/data/page.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/data/page.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/data/page_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/data.html +1 -0
- package/.next/standalone/apps/web/.next/server/app/data.meta +34 -0
- package/.next/standalone/apps/web/.next/server/app/data.rsc +27 -0
- package/.next/standalone/apps/web/.next/server/app/data.segments/_full.segment.rsc +27 -0
- package/.next/standalone/apps/web/.next/server/app/data.segments/_tree.segment.rsc +2 -0
- package/.next/standalone/apps/web/.next/server/app/data.segments/data/__PAGE__.segment.rsc +33 -0
- package/.next/standalone/apps/web/.next/server/app/favicon.ico/route.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/favicon.ico/route.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/favicon.ico.body +0 -0
- package/.next/standalone/apps/web/.next/server/app/favicon.ico.meta +1 -0
- package/.next/standalone/apps/web/.next/server/app/index.html +1 -0
- package/.next/standalone/apps/web/.next/server/app/index.meta +29 -0
- package/.next/standalone/apps/web/.next/server/app/index.rsc +25 -0
- package/.next/standalone/apps/web/.next/server/app/index.segments/__PAGE__.segment.rsc +30 -0
- package/.next/standalone/apps/web/.next/server/app/index.segments/_full.segment.rsc +25 -0
- package/.next/standalone/apps/web/.next/server/app/index.segments/_tree.segment.rsc +2 -0
- package/.next/standalone/apps/web/.next/server/app/page.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/page.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/page_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/settings/page.js +216 -0
- package/.next/standalone/apps/web/.next/server/app/settings/page.js.nft.json +1 -0
- package/.next/standalone/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/app/settings.html +1 -0
- package/.next/standalone/apps/web/.next/server/app/settings.meta +34 -0
- package/.next/standalone/apps/web/.next/server/app/settings.rsc +30 -0
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_full.segment.rsc +30 -0
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_tree.segment.rsc +2 -0
- package/.next/standalone/apps/web/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +36 -0
- package/.next/standalone/apps/web/.next/server/app-paths-manifest.json +94 -0
- package/.next/standalone/apps/web/.next/server/chunks/101.js +24 -0
- package/.next/standalone/apps/web/.next/server/chunks/1149.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/1309.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/1389.js +5 -0
- package/.next/standalone/apps/web/.next/server/chunks/1479.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/1602.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/1778.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/1810.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/1953.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/1999.js +6 -0
- package/.next/standalone/apps/web/.next/server/chunks/2097.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/2129.js +47 -0
- package/.next/standalone/apps/web/.next/server/chunks/2411.js +193 -0
- package/.next/standalone/apps/web/.next/server/chunks/2500.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/2552.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/2595.js +45 -0
- package/.next/standalone/apps/web/.next/server/chunks/2883.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/2918.js +212 -0
- package/.next/standalone/apps/web/.next/server/chunks/309.js +2 -0
- package/.next/standalone/apps/web/.next/server/chunks/3122.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/3257.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/3287.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/3304.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/340.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/3545.js +6 -0
- package/.next/standalone/apps/web/.next/server/chunks/3577.js +27 -0
- package/.next/standalone/apps/web/.next/server/chunks/3609.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/364.js +36 -0
- package/.next/standalone/apps/web/.next/server/chunks/3642.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/365.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/4292.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/4327.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/4375.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/4441.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/4915.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/5072.js +47 -0
- package/.next/standalone/apps/web/.next/server/chunks/5078.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/5523.js +10 -0
- package/.next/standalone/apps/web/.next/server/chunks/5701.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/5760.js +11 -0
- package/.next/standalone/apps/web/.next/server/chunks/5770.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/588.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/5884.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/5937.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/5995.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/600.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/6014.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/6066.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/6149.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/6199.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/620.js +78 -0
- package/.next/standalone/apps/web/.next/server/chunks/6207.js +14 -0
- package/.next/standalone/apps/web/.next/server/chunks/63.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/6457.js +2 -0
- package/.next/standalone/apps/web/.next/server/chunks/6479.js +35 -0
- package/.next/standalone/apps/web/.next/server/chunks/657.js +84 -0
- package/.next/standalone/apps/web/.next/server/chunks/6573.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/6814.js +18 -0
- package/.next/standalone/apps/web/.next/server/chunks/6909.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/7010.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/7289.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/7324.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/741.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/7448.js +165 -0
- package/.next/standalone/apps/web/.next/server/chunks/7459.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/7613.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/7945.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/7974.js +20 -0
- package/.next/standalone/apps/web/.next/server/chunks/8005.js +41 -0
- package/.next/standalone/apps/web/.next/server/chunks/8052.js +55 -0
- package/.next/standalone/apps/web/.next/server/chunks/8169.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/8299.js +2 -0
- package/.next/standalone/apps/web/.next/server/chunks/8358.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/843.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/8437.js +12 -0
- package/.next/standalone/apps/web/.next/server/chunks/8840.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/8952.js +1859 -0
- package/.next/standalone/apps/web/.next/server/chunks/9016.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/9028.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/9077.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/915.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/9248.js +256 -0
- package/.next/standalone/apps/web/.next/server/chunks/9301.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/9319.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/9439.js +24 -0
- package/.next/standalone/apps/web/.next/server/chunks/9480.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/9579.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/9768.js +4 -0
- package/.next/standalone/apps/web/.next/server/chunks/9837.js +121 -0
- package/.next/standalone/apps/web/.next/server/chunks/9851.js +1 -0
- package/.next/standalone/apps/web/.next/server/chunks/static/media/pdf.worker.min.63b810cd.mjs +6 -0
- package/.next/standalone/apps/web/.next/server/functions-config-manifest.json +82 -0
- package/.next/standalone/apps/web/.next/server/middleware-build-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/middleware-manifest.json +6 -0
- package/.next/standalone/apps/web/.next/server/middleware-react-loadable-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/next-font-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/next-font-manifest.json +1 -0
- package/.next/standalone/apps/web/.next/server/pages/404.html +1 -0
- package/.next/standalone/apps/web/.next/server/pages/500.html +1 -0
- package/.next/standalone/apps/web/.next/server/pages-manifest.json +4 -0
- package/.next/standalone/apps/web/.next/server/prefetch-hints.json +95 -0
- package/.next/standalone/apps/web/.next/server/server-reference-manifest.js +1 -0
- package/.next/standalone/apps/web/.next/server/server-reference-manifest.json +1 -0
- package/.next/standalone/apps/web/.next/server/webpack-runtime.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/0ed6b8a9-7f39ffa51cd4d7d3.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/1788-3ec11e3d6d6986e9.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/1986-2eb6c09f2f556e84.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/2038-1dc8a3028545edab.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/217c94bb-b2b832568a17950f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/227-7f3dac471f0eb3b0.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/2634.803b324122bd1d49.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/2928-8a2d9ed34f45623a.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/3182.74de4aadefc6e951.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/3259.41d1a9e21c751dca.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/3853-f4d7f7a9e7afd752.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/4112ad79.b782044759df4bc8.js +45 -0
- package/.next/standalone/apps/web/.next/static/chunks/4765-48a3b66331719b80.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/4975-4de53a9574e52468.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/5833-f7b1cb2153cd52ab.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/6462-9d67b69d990b1234.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/6837-67b91a5109edf8a8.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/6880.4300fd5c0fd7f17a.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/6904-f77e06e821ecae13.js +52 -0
- package/.next/standalone/apps/web/.next/static/chunks/7534-8b910687515b8403.js +6 -0
- package/.next/standalone/apps/web/.next/static/chunks/7857.ce5356f660fb54a1.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/8226-c6f5131375b6df6a.js +3 -0
- package/.next/standalone/apps/web/.next/static/chunks/9734-c7b94c9bf40c9b2e.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/9779-5dc3db110e05c070.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/9987-45c7dfa599210f7e.js +78 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/_global-error/page-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/_not-found/page-7007da1b6a809c3d.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/add/page-d423813ec2556ef0.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/analytics/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/chat/feedback/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/chat/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/chat/status/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/config/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/config/test/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/config/test-embedding/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/config/test-llm/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/config/test-provider/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/config/verify/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/connections/[channelId]/oauth/callback/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/connections/[channelId]/oauth/start/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/connections/[channelId]/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/connections/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/connections/tunnel/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/demo/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/deploy/ssh/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/deploy/verify/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/describe-image/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/doc-editor/edit/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/doc-editor/export/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/doc-editor/extract-text/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/doc-editor/parse/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/doc-editor/restore/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/document/sign/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/documents/move/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/documents/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/files/remote/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/firecrawl/local/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/gpu-activity/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/groups/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/index/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/integrations/[integration]/callback/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/integrations/[integration]/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/integrations/notion/callback/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/integrations/notion/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/integrations/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/jobs/[id]/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/jobs/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/marketplace/[toolId]/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/marketplace/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/mcp/[connectionId]/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/mcp/[connectionId]/test/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/mcp/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/media/[id]/frame/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/media/[id]/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/media/inspect/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/media/jobs/[id]/approval/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/media/jobs/[id]/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/media/process/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/media/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/media/stream/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/models/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/parse-file/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/pdf-page/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/projects/deployments/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/projects/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/projects/runtime/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/proxy/verify/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/sandbox/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/sandbox/verify/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/search/bing/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/search/brave/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/search/exa/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/search/google/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/search/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/search/tavily/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/search/verify/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/system/cache/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/tabular/query/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/tabular/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/tools/[toolId]/host/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/tools/[toolId]/runtime/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/tools/[toolId]/usage/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/tools/[toolId]/usage-request/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/tools/[toolId]/verify/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/tools/video-intelligence/connection/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/tools/video-intelligence/usage/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/tools/video-intelligence/usage-request/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/upload-file/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/uploads/[...slug]/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/vector-stores/install/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/api/vector-stores/status/route-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/chat/[id]/page-579d3515fee9f89a.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/chat/page-bec03ef7408245b1.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/data/page-02e56e093071379d.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/layout-4b8ce98cb78f7113.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/page-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/settings/page-485ea820c1111580.js +214 -0
- package/.next/standalone/apps/web/.next/static/chunks/app/template-6c3f1e7c9216df6c.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/ca017448-ac5fddb4e8d1ca39.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/db534642-baa98c214832026c.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/framework-ae648e3ae9d64766.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/main-25c6b3b10ba0a4a3.js +5 -0
- package/.next/standalone/apps/web/.next/static/chunks/main-app-ecde5d6ff9b76409.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/next/dist/client/components/builtin/app-error-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/next/dist/client/components/builtin/forbidden-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/next/dist/client/components/builtin/global-error-ab826e81c411f616.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/next/dist/client/components/builtin/not-found-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/next/dist/client/components/builtin/unauthorized-0d4f12c4c9cbf85f.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/webpack-8c15908ca85a5a46.js +1 -0
- package/.next/standalone/apps/web/.next/static/css/063aaab22a52e4b4.css +1 -0
- package/.next/standalone/apps/web/.next/static/css/a2d2ae3b76e6a5b6.css +1 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_AMS-Regular.1608a09b.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_AMS-Regular.4aafdb68.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_AMS-Regular.a79f1c31.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Caligraphic-Bold.b6770918.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Caligraphic-Bold.cce5b8ec.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Caligraphic-Bold.ec17d132.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Caligraphic-Regular.07ef19e7.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Caligraphic-Regular.55fac258.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Caligraphic-Regular.dad44a7f.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Fraktur-Bold.9f256b85.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Fraktur-Bold.b18f59e1.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Fraktur-Bold.d42a5579.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Fraktur-Regular.7c187121.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Fraktur-Regular.d3c882a6.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Fraktur-Regular.ed38e79f.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Main-Bold.b74a1a8b.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Main-Bold.c3fb5ac2.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Main-Bold.d181c465.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Main-BoldItalic.6f2bb1df.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Main-BoldItalic.70d8b0a5.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Main-BoldItalic.e3f82f9d.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Main-Italic.47373d1e.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Main-Italic.8916142b.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Main-Italic.9024d815.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Main-Regular.0462f03b.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Main-Regular.7f51fe03.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Main-Regular.b7f8fe9b.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Math-BoldItalic.572d331f.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Math-BoldItalic.a879cf83.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Math-BoldItalic.f1035d8d.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Math-Italic.5295ba48.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Math-Italic.939bc644.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Math-Italic.f28c23ac.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_SansSerif-Bold.8c5b5494.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_SansSerif-Bold.94e1e8dc.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_SansSerif-Bold.bf59d231.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_SansSerif-Italic.3b1e59b3.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_SansSerif-Italic.7c9bc82b.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_SansSerif-Italic.b4c20c84.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_SansSerif-Regular.74048478.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_SansSerif-Regular.ba21ed5f.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_SansSerif-Regular.d4d7ba48.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Script-Regular.03e9641d.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Script-Regular.07505710.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Script-Regular.fe9cbbe1.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Size1-Regular.e1e279cb.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Size1-Regular.eae34984.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Size1-Regular.fabc004a.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Size2-Regular.57727022.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Size2-Regular.5916a24f.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Size2-Regular.d6b476ec.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Size3-Regular.9acaf01c.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Size3-Regular.a144ef58.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Size3-Regular.b4230e7e.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Size4-Regular.10d95fd3.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Size4-Regular.7a996c9d.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Size4-Regular.fbccdabe.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Typewriter-Regular.6258592b.woff +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Typewriter-Regular.a8709e36.woff2 +0 -0
- package/.next/standalone/apps/web/.next/static/media/KaTeX_Typewriter-Regular.d97aaf4a.ttf +0 -0
- package/.next/standalone/apps/web/.next/static/media/pdf.worker.min.b6d469c6.mjs +6 -0
- package/.next/standalone/apps/web/.next/static/omDbbCzcQ9kxlZ8Gz0yln/_buildManifest.js +1 -0
- package/.next/standalone/apps/web/.next/static/omDbbCzcQ9kxlZ8Gz0yln/_ssgManifest.js +1 -0
- package/.next/standalone/apps/web/.next/types/cache-life.d.ts +146 -0
- package/.next/standalone/apps/web/.next/types/root-params.d.ts +3 -0
- package/.next/standalone/apps/web/.next/types/routes.d.ts +161 -0
- package/.next/standalone/apps/web/.next/types/validator.ts +862 -0
- package/.next/standalone/apps/web/AGENTS.md +9 -0
- package/.next/standalone/apps/web/CLAUDE.md +1 -0
- package/.next/standalone/apps/web/app/api/groups/route.test.ts +86 -0
- package/.next/standalone/apps/web/app/api/index/route.test.ts +55 -0
- package/.next/standalone/apps/web/app/api/marketplace/[toolId]/route.test.ts +83 -0
- package/.next/standalone/apps/web/app/api/marketplace/route.test.ts +117 -0
- package/.next/standalone/apps/web/app/api/tools/[toolId]/verify/route.test.ts +66 -0
- package/.next/standalone/apps/web/app/favicon.ico +0 -0
- package/.next/standalone/apps/web/app/globals.css +406 -0
- package/.next/standalone/apps/web/app/themes.css +234 -0
- package/.next/standalone/apps/web/bin/larkup.js +528 -0
- package/.next/standalone/apps/web/components/alerts/generic-alert.tsx +76 -0
- package/.next/standalone/apps/web/components/analytics/analytics-dashboard.tsx +517 -0
- package/.next/standalone/apps/web/components/chat/canvas/doc-editor-provider.tsx +331 -0
- package/.next/standalone/apps/web/components/chat/canvas/document-canvas.tsx +98 -0
- package/.next/standalone/apps/web/components/chat/canvas/document-field.tsx +167 -0
- package/.next/standalone/apps/web/components/chat/canvas/document-viewer.tsx +446 -0
- package/.next/standalone/apps/web/components/chat/canvas/file-attachment-button.tsx +88 -0
- package/.next/standalone/apps/web/components/chat/canvas/file-chip.tsx +147 -0
- package/.next/standalone/apps/web/components/chat/message-actions.tsx +96 -0
- package/.next/standalone/apps/web/components/chat/message-item.tsx +1404 -0
- package/.next/standalone/apps/web/components/chat/message-queue.tsx +86 -0
- package/.next/standalone/apps/web/components/chat/reasoning.tsx +182 -0
- package/.next/standalone/apps/web/components/chat/tools/chat-card.tsx +97 -0
- package/.next/standalone/apps/web/components/chat/tools/chat-chart.tsx +554 -0
- package/.next/standalone/apps/web/components/chat/tools/chat-citations.tsx +152 -0
- package/.next/standalone/apps/web/components/chat/tools/chat-data-table.tsx +377 -0
- package/.next/standalone/apps/web/components/chat/tools/chat-file-export.tsx +49 -0
- package/.next/standalone/apps/web/components/chat/tools/chat-grid.tsx +99 -0
- package/.next/standalone/apps/web/components/chat/tools/chat-media-preview.tsx +465 -0
- package/.next/standalone/apps/web/components/chat/tools/chat-metrics.tsx +76 -0
- package/.next/standalone/apps/web/components/chat/tools/chat-sandbox-result.tsx +130 -0
- package/.next/standalone/apps/web/components/chat/tools/chat-signature-request.tsx +809 -0
- package/.next/standalone/apps/web/components/chat/tools/chat-tabs.tsx +59 -0
- package/.next/standalone/apps/web/components/chat/tools/corpus-data-result.tsx +194 -0
- package/.next/standalone/apps/web/components/chat/tools/knowledge-base-result.tsx +345 -0
- package/.next/standalone/apps/web/components/chat/tools/visual-placement-modal.tsx +314 -0
- package/.next/standalone/apps/web/components/chat/tools/visualization-tabs.tsx +37 -0
- package/.next/standalone/apps/web/components/configure/custom-model-modal.tsx +214 -0
- package/.next/standalone/apps/web/components/configure/store-fields.tsx +129 -0
- package/.next/standalone/apps/web/components/data/corpus-panel.tsx +1124 -0
- package/.next/standalone/apps/web/components/data/data-entry-mode-switch.tsx +53 -0
- package/.next/standalone/apps/web/components/data/data-primary-action.ts +6 -0
- package/.next/standalone/apps/web/components/data/groups-panel.tsx +526 -0
- package/.next/standalone/apps/web/components/data/integration-resources-panel.tsx +281 -0
- package/.next/standalone/apps/web/components/data/integrations-panel.tsx +397 -0
- package/.next/standalone/apps/web/components/data/jobs-panel.tsx +487 -0
- package/.next/standalone/apps/web/components/data/jobs-tracking-button.tsx +221 -0
- package/.next/standalone/apps/web/components/data/live-media-progress.tsx +79 -0
- package/.next/standalone/apps/web/components/data/media-indexing-jobs-panel.tsx +190 -0
- package/.next/standalone/apps/web/components/data/media-panel.tsx +2883 -0
- package/.next/standalone/apps/web/components/data/notion-panel.tsx +405 -0
- package/.next/standalone/apps/web/components/data/paste-panel.tsx +100 -0
- package/.next/standalone/apps/web/components/data/scrape-panel.tsx +1275 -0
- package/.next/standalone/apps/web/components/data/tabular-preview.tsx +205 -0
- package/.next/standalone/apps/web/components/data/tool-indexing-dialog.tsx +210 -0
- package/.next/standalone/apps/web/components/data/upload-panel.tsx +1306 -0
- package/.next/standalone/apps/web/components/data/web-crawler-status.tsx +131 -0
- package/.next/standalone/apps/web/components/index/index-action-dialog.tsx +545 -0
- package/.next/standalone/apps/web/components/index/index-workspace.tsx +406 -0
- package/.next/standalone/apps/web/components/onboarding/welcome-screen.tsx +596 -0
- package/.next/standalone/apps/web/components/projects/delete-project-dialog.tsx +63 -0
- package/.next/standalone/apps/web/components/projects/project-form-dialog.tsx +97 -0
- package/.next/standalone/apps/web/components/projects/project-switcher.tsx +136 -0
- package/.next/standalone/apps/web/components/settings/general/agent-customization-section.tsx +619 -0
- package/.next/standalone/apps/web/components/settings/general/cache-management-card.tsx +176 -0
- package/.next/standalone/apps/web/components/settings/general/general-section.tsx +333 -0
- package/.next/standalone/apps/web/components/settings/general/mcp-connections-section.tsx +893 -0
- package/.next/standalone/apps/web/components/settings/general/model-combobox.tsx +235 -0
- package/.next/standalone/apps/web/components/settings/general/models-section.tsx +918 -0
- package/.next/standalone/apps/web/components/settings/general/sandbox-section.tsx +382 -0
- package/.next/standalone/apps/web/components/settings/general/search-scraping-section.tsx +749 -0
- package/.next/standalone/apps/web/components/settings/general/storage-indexing-section.tsx +389 -0
- package/.next/standalone/apps/web/components/settings/hub/marketplace-section.tsx +574 -0
- package/.next/standalone/apps/web/components/settings/hub/marketplace-tools-settings.tsx +1247 -0
- package/.next/standalone/apps/web/components/settings/runtime/connections-tab.tsx +1045 -0
- package/.next/standalone/apps/web/components/settings/runtime/deploy/index.ts +4 -0
- package/.next/standalone/apps/web/components/settings/runtime/deploy/project-deploy-button.tsx +245 -0
- package/.next/standalone/apps/web/components/settings/runtime/deploy/project-deploy-view.tsx +1592 -0
- package/.next/standalone/apps/web/components/settings/runtime/deploy/use-vps-deploy.ts +114 -0
- package/.next/standalone/apps/web/components/settings/runtime/deploy/vps-terminal-dialog.tsx +391 -0
- package/.next/standalone/apps/web/components/settings/runtime/playground-tab.tsx +359 -0
- package/.next/standalone/apps/web/components/settings/runtime/runtime-section.tsx +1001 -0
- package/.next/standalone/apps/web/components/settings/runtime/widget-snippets.ts +15 -0
- package/.next/standalone/apps/web/components/settings/runtime/widget-tab.tsx +426 -0
- package/.next/standalone/apps/web/components/settings/settings-layout.tsx +123 -0
- package/.next/standalone/apps/web/components/sidebar.tsx +208 -0
- package/.next/standalone/apps/web/components/topnav.tsx +92 -0
- package/.next/standalone/apps/web/components/ui/alert-dialog.tsx +187 -0
- package/.next/standalone/apps/web/components/ui/alert.tsx +76 -0
- package/.next/standalone/apps/web/components/ui/badge.tsx +52 -0
- package/.next/standalone/apps/web/components/ui/button.tsx +58 -0
- package/.next/standalone/apps/web/components/ui/card.tsx +92 -0
- package/.next/standalone/apps/web/components/ui/checkbox.tsx +28 -0
- package/.next/standalone/apps/web/components/ui/collapsible.tsx +21 -0
- package/.next/standalone/apps/web/components/ui/command.tsx +181 -0
- package/.next/standalone/apps/web/components/ui/dialog.tsx +138 -0
- package/.next/standalone/apps/web/components/ui/dropdown-menu.tsx +267 -0
- package/.next/standalone/apps/web/components/ui/input-group.tsx +146 -0
- package/.next/standalone/apps/web/components/ui/input.tsx +20 -0
- package/.next/standalone/apps/web/components/ui/label.tsx +20 -0
- package/.next/standalone/apps/web/components/ui/line-tabs.tsx +59 -0
- package/.next/standalone/apps/web/components/ui/popover.tsx +77 -0
- package/.next/standalone/apps/web/components/ui/progress.tsx +83 -0
- package/.next/standalone/apps/web/components/ui/provider-icon.tsx +165 -0
- package/.next/standalone/apps/web/components/ui/scroll-area.tsx +55 -0
- package/.next/standalone/apps/web/components/ui/select.tsx +231 -0
- package/.next/standalone/apps/web/components/ui/separator.tsx +25 -0
- package/.next/standalone/apps/web/components/ui/sheet.tsx +125 -0
- package/.next/standalone/apps/web/components/ui/skeleton.tsx +14 -0
- package/.next/standalone/apps/web/components/ui/slider.tsx +52 -0
- package/.next/standalone/apps/web/components/ui/switch.tsx +32 -0
- package/.next/standalone/apps/web/components/ui/table.tsx +116 -0
- package/.next/standalone/apps/web/components/ui/tabs.tsx +77 -0
- package/.next/standalone/apps/web/components/ui/textarea.tsx +18 -0
- package/.next/standalone/apps/web/components/ui/tooltip.tsx +54 -0
- package/.next/standalone/apps/web/components.json +21 -0
- package/.next/standalone/apps/web/hooks/use-channel-oauth.ts +42 -0
- package/.next/standalone/apps/web/hooks/use-copy-to-clipboard.ts +25 -0
- package/.next/standalone/apps/web/hooks/use-integration-auth.ts +37 -0
- package/.next/standalone/apps/web/hooks/use-live-media-progress.ts +71 -0
- package/.next/standalone/apps/web/hooks/use-notion-auth.ts +63 -0
- package/.next/standalone/apps/web/lib/browser-cache.test.ts +32 -0
- package/.next/standalone/apps/web/lib/browser-cache.ts +17 -0
- package/.next/standalone/apps/web/lib/cache-size.test.ts +15 -0
- package/.next/standalone/apps/web/lib/cache-size.ts +11 -0
- package/.next/standalone/apps/web/lib/chat/assistant-source-scope.test.ts +43 -0
- package/.next/standalone/apps/web/lib/chat/chart-config.test.ts +144 -0
- package/.next/standalone/apps/web/lib/chat/chat-media-preview.test.ts +31 -0
- package/.next/standalone/apps/web/lib/chat/conversation-memory.test.ts +390 -0
- package/.next/standalone/apps/web/lib/chat/data-export.test.ts +224 -0
- package/.next/standalone/apps/web/lib/chat/live-tool-progress.test.ts +76 -0
- package/.next/standalone/apps/web/lib/chat/live-tool-progress.ts +69 -0
- package/.next/standalone/apps/web/lib/chat/media-retrieval-routing.test.ts +42 -0
- package/.next/standalone/apps/web/lib/chat/media-source-routing.test.ts +118 -0
- package/.next/standalone/apps/web/lib/chat/message-feedback.test.ts +102 -0
- package/.next/standalone/apps/web/lib/chat/message-input.test.ts +30 -0
- package/.next/standalone/apps/web/lib/chat/retrieval-ranking.test.ts +62 -0
- package/.next/standalone/apps/web/lib/chat/retrieval-routing.test.ts +80 -0
- package/.next/standalone/apps/web/lib/chat/tabular-dataset-routing.test.ts +83 -0
- package/.next/standalone/apps/web/lib/chat/tabular-query-plan.test.ts +148 -0
- package/.next/standalone/apps/web/lib/chat/tabular-routing.test.ts +109 -0
- package/.next/standalone/apps/web/lib/chat/tabular-sandbox-files.test.ts +100 -0
- package/.next/standalone/apps/web/lib/chat/tabular-visualization.test.ts +89 -0
- package/.next/standalone/apps/web/lib/chat/tool-call-repair.test.ts +64 -0
- package/.next/standalone/apps/web/lib/chat/tool-context.test.ts +978 -0
- package/.next/standalone/apps/web/lib/chat/tool-output.test.ts +23 -0
- package/.next/standalone/apps/web/lib/chat/tool-output.ts +14 -0
- package/.next/standalone/apps/web/lib/chat/tool-registry.test.ts +19 -0
- package/.next/standalone/apps/web/lib/chat/video-rag-routing.test.ts +158 -0
- package/.next/standalone/apps/web/lib/chat/visual-routing.test.ts +140 -0
- package/.next/standalone/apps/web/lib/chat-supporting-clip.test.ts +16 -0
- package/.next/standalone/apps/web/lib/chat-supporting-clip.ts +16 -0
- package/.next/standalone/apps/web/lib/constants/stores.ts +12 -0
- package/.next/standalone/apps/web/lib/constants/tools.test.ts +26 -0
- package/.next/standalone/apps/web/lib/constants/tools.ts +178 -0
- package/.next/standalone/apps/web/lib/error-formatter.ts +30 -0
- package/.next/standalone/apps/web/lib/jobs-client.ts +25 -0
- package/.next/standalone/apps/web/lib/marketplace/tool-runtime-config.test.ts +217 -0
- package/.next/standalone/apps/web/lib/media/knowledge.test.ts +36 -0
- package/.next/standalone/apps/web/lib/media/pdf-inspection.test.ts +63 -0
- package/.next/standalone/apps/web/lib/media/pdf.ts +57 -0
- package/.next/standalone/apps/web/lib/media/progress.test.ts +208 -0
- package/.next/standalone/apps/web/lib/media/progress.ts +209 -0
- package/.next/standalone/apps/web/lib/media/source-identity.test.ts +33 -0
- package/.next/standalone/apps/web/lib/media/source-selection.test.ts +36 -0
- package/.next/standalone/apps/web/lib/media/source-selection.ts +47 -0
- package/.next/standalone/apps/web/lib/media/source-utils.test.ts +231 -0
- package/.next/standalone/apps/web/lib/media/tool-indexing-estimate.test.ts +28 -0
- package/.next/standalone/apps/web/lib/media/tool-indexing-estimate.ts +39 -0
- package/.next/standalone/apps/web/lib/media/video/quick-look.test.ts +81 -0
- package/.next/standalone/apps/web/lib/media/video-intelligence-adapter.test.ts +739 -0
- package/.next/standalone/apps/web/lib/media/video-intelligence-capacity.test.ts +104 -0
- package/.next/standalone/apps/web/lib/media/video-runtime-scope.test.ts +43 -0
- package/.next/standalone/apps/web/lib/release-metadata.test.ts +118 -0
- package/.next/standalone/apps/web/lib/remote-files.test.ts +53 -0
- package/.next/standalone/apps/web/lib/system-cache.test.ts +173 -0
- package/.next/standalone/apps/web/lib/utils.ts +6 -0
- package/.next/standalone/apps/web/next-env.d.ts +7 -0
- package/.next/standalone/apps/web/next.config.mjs +82 -0
- package/.next/standalone/apps/web/package.json +96 -0
- package/.next/standalone/apps/web/parse_log.mjs +67 -0
- package/.next/standalone/apps/web/postcss.config.mjs +8 -0
- package/.next/standalone/apps/web/public/docker.png +0 -0
- package/.next/standalone/apps/web/public/favicon.ico +0 -0
- package/.next/standalone/apps/web/public/github.svg +3 -0
- package/.next/standalone/apps/web/public/hetzner.svg +1 -0
- package/.next/standalone/apps/web/public/icons/Confluence.png +0 -0
- package/.next/standalone/apps/web/public/icons/Instagram.png +0 -0
- package/.next/standalone/apps/web/public/icons/Northflank.png +0 -0
- package/.next/standalone/apps/web/public/icons/Salesforce.png +0 -0
- package/.next/standalone/apps/web/public/icons/agentskills.png +0 -0
- package/.next/standalone/apps/web/public/icons/airtable.png +0 -0
- package/.next/standalone/apps/web/public/icons/asana.png +0 -0
- package/.next/standalone/apps/web/public/icons/ashby.png +0 -0
- package/.next/standalone/apps/web/public/icons/audio.png +0 -0
- package/.next/standalone/apps/web/public/icons/aws-kendra.png +0 -0
- package/.next/standalone/apps/web/public/icons/aws.svg +38 -0
- package/.next/standalone/apps/web/public/icons/azure-ai-search.png +0 -0
- package/.next/standalone/apps/web/public/icons/azure.svg +1 -0
- package/.next/standalone/apps/web/public/icons/bigquery.png +0 -0
- package/.next/standalone/apps/web/public/icons/bing.png +0 -0
- package/.next/standalone/apps/web/public/icons/bitbucket.png +0 -0
- package/.next/standalone/apps/web/public/icons/brave.png +0 -0
- package/.next/standalone/apps/web/public/icons/browserbase.png +0 -0
- package/.next/standalone/apps/web/public/icons/calendly.png +0 -0
- package/.next/standalone/apps/web/public/icons/chroma.png +0 -0
- package/.next/standalone/apps/web/public/icons/cloudflare.png +0 -0
- package/.next/standalone/apps/web/public/icons/cohere.svg +30 -0
- package/.next/standalone/apps/web/public/icons/databricks.png +0 -0
- package/.next/standalone/apps/web/public/icons/daytonaio.png +0 -0
- package/.next/standalone/apps/web/public/icons/daytonaio2.png +0 -0
- package/.next/standalone/apps/web/public/icons/deepgram.png +0 -0
- package/.next/standalone/apps/web/public/icons/deepl.png +0 -0
- package/.next/standalone/apps/web/public/icons/digital-ocean.webp +0 -0
- package/.next/standalone/apps/web/public/icons/discord.png +0 -0
- package/.next/standalone/apps/web/public/icons/e2b-2.png +0 -0
- package/.next/standalone/apps/web/public/icons/e2b.png +0 -0
- package/.next/standalone/apps/web/public/icons/elevenlabs.png +0 -0
- package/.next/standalone/apps/web/public/icons/email.png +0 -0
- package/.next/standalone/apps/web/public/icons/exa.png +0 -0
- package/.next/standalone/apps/web/public/icons/excel.png +0 -0
- package/.next/standalone/apps/web/public/icons/fal.png +0 -0
- package/.next/standalone/apps/web/public/icons/firecrawl.png +0 -0
- package/.next/standalone/apps/web/public/icons/firecrawl2.png +0 -0
- package/.next/standalone/apps/web/public/icons/flyio.jpeg +0 -0
- package/.next/standalone/apps/web/public/icons/gcp.svg +1 -0
- package/.next/standalone/apps/web/public/icons/gemini.svg +1 -0
- package/.next/standalone/apps/web/public/icons/gmail.png +0 -0
- package/.next/standalone/apps/web/public/icons/google-analytics.png +0 -0
- package/.next/standalone/apps/web/public/icons/google-calender.png +0 -0
- package/.next/standalone/apps/web/public/icons/google-docs.png +0 -0
- package/.next/standalone/apps/web/public/icons/google-drive.png +0 -0
- package/.next/standalone/apps/web/public/icons/google-maps.png +0 -0
- package/.next/standalone/apps/web/public/icons/google-meet.png +0 -0
- package/.next/standalone/apps/web/public/icons/google-sheets.png +0 -0
- package/.next/standalone/apps/web/public/icons/google-slides.png +0 -0
- package/.next/standalone/apps/web/public/icons/google-tasks.png +0 -0
- package/.next/standalone/apps/web/public/icons/google.png +0 -0
- package/.next/standalone/apps/web/public/icons/grok.png +0 -0
- package/.next/standalone/apps/web/public/icons/hubspot.png +0 -0
- package/.next/standalone/apps/web/public/icons/image.png +0 -0
- package/.next/standalone/apps/web/public/icons/jina.svg +1 -0
- package/.next/standalone/apps/web/public/icons/jira.png +0 -0
- package/.next/standalone/apps/web/public/icons/lancedb2.png +0 -0
- package/.next/standalone/apps/web/public/icons/linear.png +0 -0
- package/.next/standalone/apps/web/public/icons/linux.png +0 -0
- package/.next/standalone/apps/web/public/icons/looker.png +0 -0
- package/.next/standalone/apps/web/public/icons/luma.png +0 -0
- package/.next/standalone/apps/web/public/icons/mac.png +0 -0
- package/.next/standalone/apps/web/public/icons/markdown.png +0 -0
- package/.next/standalone/apps/web/public/icons/mcp.png +0 -0
- package/.next/standalone/apps/web/public/icons/mcp.svg +1 -0
- package/.next/standalone/apps/web/public/icons/messenger.svg +1 -0
- package/.next/standalone/apps/web/public/icons/microsoft-intra.png +0 -0
- package/.next/standalone/apps/web/public/icons/microsoft-onenote.png +0 -0
- package/.next/standalone/apps/web/public/icons/microsoft-planner.png +0 -0
- package/.next/standalone/apps/web/public/icons/microsoft-teams.png +0 -0
- package/.next/standalone/apps/web/public/icons/miro.png +0 -0
- package/.next/standalone/apps/web/public/icons/mistral.svg +469 -0
- package/.next/standalone/apps/web/public/icons/modal.png +0 -0
- package/.next/standalone/apps/web/public/icons/ngrok.png +0 -0
- package/.next/standalone/apps/web/public/icons/nomic.png +0 -0
- package/.next/standalone/apps/web/public/icons/onedrive.png +0 -0
- package/.next/standalone/apps/web/public/icons/openai.svg +1 -0
- package/.next/standalone/apps/web/public/icons/outlook-calendar.png +0 -0
- package/.next/standalone/apps/web/public/icons/outlook-email.png +0 -0
- package/.next/standalone/apps/web/public/icons/outlook.png +0 -0
- package/.next/standalone/apps/web/public/icons/pdf.png +0 -0
- package/.next/standalone/apps/web/public/icons/personio.png +0 -0
- package/.next/standalone/apps/web/public/icons/pgvector2.png +0 -0
- package/.next/standalone/apps/web/public/icons/phone.png +0 -0
- package/.next/standalone/apps/web/public/icons/pinecone.png +0 -0
- package/.next/standalone/apps/web/public/icons/pipedrive.png +0 -0
- package/.next/standalone/apps/web/public/icons/power-pi.png +0 -0
- package/.next/standalone/apps/web/public/icons/pylon.png +0 -0
- package/.next/standalone/apps/web/public/icons/python.png +0 -0
- package/.next/standalone/apps/web/public/icons/qdrant.svg +35 -0
- package/.next/standalone/apps/web/public/icons/revai.png +0 -0
- package/.next/standalone/apps/web/public/icons/revai.svg +1 -0
- package/.next/standalone/apps/web/public/icons/sap.png +0 -0
- package/.next/standalone/apps/web/public/icons/serpapi.svg +34 -0
- package/.next/standalone/apps/web/public/icons/serper.png +0 -0
- package/.next/standalone/apps/web/public/icons/servicenow.png +0 -0
- package/.next/standalone/apps/web/public/icons/sharepoint.png +0 -0
- package/.next/standalone/apps/web/public/icons/slack.png +0 -0
- package/.next/standalone/apps/web/public/icons/snowflake.png +0 -0
- package/.next/standalone/apps/web/public/icons/statistia.png +0 -0
- package/.next/standalone/apps/web/public/icons/stripe.png +0 -0
- package/.next/standalone/apps/web/public/icons/supabase.png +0 -0
- package/.next/standalone/apps/web/public/icons/tableau.png +0 -0
- package/.next/standalone/apps/web/public/icons/tavily.png +0 -0
- package/.next/standalone/apps/web/public/icons/telegram.png +0 -0
- package/.next/standalone/apps/web/public/icons/typescript.png +0 -0
- package/.next/standalone/apps/web/public/icons/vercel copy.svg +1 -0
- package/.next/standalone/apps/web/public/icons/vercel.svg +1 -0
- package/.next/standalone/apps/web/public/icons/vertex-ai.png +0 -0
- package/.next/standalone/apps/web/public/icons/video.png +0 -0
- package/.next/standalone/apps/web/public/icons/voyage-light.png +0 -0
- package/.next/standalone/apps/web/public/icons/weaviate.webp +0 -0
- package/.next/standalone/apps/web/public/icons/webcontainers.svg +11 -0
- package/.next/standalone/apps/web/public/icons/webhook.png +0 -0
- package/.next/standalone/apps/web/public/icons/whatsapp copy.png +0 -0
- package/.next/standalone/apps/web/public/icons/whatsapp.png +0 -0
- package/.next/standalone/apps/web/public/icons/windows.png +0 -0
- package/.next/standalone/apps/web/public/icons/word.png +0 -0
- package/.next/standalone/apps/web/public/icons/zendesk.png +0 -0
- package/.next/standalone/apps/web/public/icons/zoom.png +0 -0
- package/.next/standalone/apps/web/public/logo-light.png +0 -0
- package/.next/standalone/apps/web/public/logo-light2.png +0 -0
- package/.next/standalone/apps/web/public/logo.png +0 -0
- package/.next/standalone/apps/web/public/logo9.png +0 -0
- package/.next/standalone/apps/web/public/notion-white.png +0 -0
- package/.next/standalone/apps/web/public/notion.png +0 -0
- package/.next/standalone/apps/web/public/vercel.svg +1 -0
- package/.next/standalone/apps/web/scripts/prepare-standalone.mjs +153 -0
- package/.next/standalone/apps/web/server.js +44 -0
- package/.next/standalone/apps/web/store/chat-store.ts +19 -0
- package/.next/standalone/apps/web/store/connections-store.ts +276 -0
- package/.next/standalone/apps/web/store/deploy-store.ts +90 -0
- package/.next/standalone/apps/web/store/scrape-store.ts +76 -0
- package/.next/standalone/apps/web/tsconfig.json +41 -0
- package/.next/standalone/apps/web/verify-models.mjs +133 -0
- package/.next/standalone/apps/web/vitest.config.ts +15 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1859 @@
|
|
|
1
|
+
"use strict";exports.id=8952,exports.ids=[6066,8952],exports.modules={8952:(a,b,c)=>{c.d(b,{Re:()=>K,UD:()=>I,dd:()=>s,gG:()=>J,rq:()=>D});var d=c(73024),e=c(76760),f=c.n(e),g=c(31421),h=c(57975),i=c(17089),j=c(52249),k=c(26043),l=c(25098);let m=(0,h.promisify)(g.exec);async function n(a){try{let{stdout:b}=await m(`lsof -ti tcp:${a}`);for(let a of b.split("\n").map(a=>a.trim()).filter(Boolean))try{process.kill(Number(a),9)}catch{}await new Promise(a=>setTimeout(a,300))}catch{}}async function o(){let a=await (0,k._d)();return a?.port??8080}function p(a){return{running:!1,port:a,endpoint:`http://localhost:${a}`}}async function q(a){let b=a?await (0,k.requireProjectDataDir)():await (0,k.getProjectDataDir)();return b?f().join(b,"generated-server"):null}async function r(a){let b=a?await (0,k.requireProjectDataDir)():await (0,k.getProjectDataDir)();return b?f().join(b,"server-local.json"):null}async function s(){let a=await o(),b=await r(!1);if(!b)return p(a);try{let c=await d.promises.readFile(b,"utf8");return{...p(a),...JSON.parse(c),port:a}}catch{return p(a)}}async function t(a){let b=await r(!0);return b&&await d.promises.writeFile(b,JSON.stringify(a,null,2),"utf8"),a}function u(a){if(!a)return!1;try{return process.kill(a,0),!0}catch{return!1}}let v=/^(?:@[-a-z0-9~][-_a-z0-9~]*\/)?[-a-z0-9~][-_a-z0-9~]*$/i,w=/^[-a-z0-9]+$/i;async function x(a,b=!1){if("assistant"!==a.runtimeProfile)return[];try{let c=await d.promises.readFile(f().join((0,k.zd)(),"tools","installed.json"),"utf8"),e=JSON.parse(c),g=new Set(a.enabledTools??[]);return(e.tools??[]).filter(a=>"string"==typeof a.id&&"string"==typeof a.packageName&&"string"==typeof a.version&&v.test(a.packageName)&&(0===g.size||g.has(a.id))).map(a=>({id:a.id,packageName:a.packageName,version:function(a,b=!1){return b&&"local"===a.source&&"string"==typeof a.id&&w.test(a.id)?`file:./marketplace-tools/${a.id}`:!b&&"local"===a.source&&"string"==typeof a.resolvedPath&&f().isAbsolute(a.resolvedPath)?`file:${a.resolvedPath}`:a.version}(a,b),config:a.config??{},source:a.source,resolvedPath:a.resolvedPath}))}catch{return[]}}async function y(a){try{let b=JSON.parse(await d.promises.readFile(f().join(process.cwd(),"node_modules",...a.split("/"),"package.json"),"utf8"));return"string"==typeof b.version?b.version:void 0}catch{return}}async function z(a){for(let b of["dependencies","optionalDependencies","peerDependencies"]){let c=a[b];if(c)for(let[a,b]of Object.entries(c)){if(!b.startsWith("workspace:"))continue;let d=await y(a);if(!d)throw Error(`Could not resolve a publishable version for workspace dependency ${a}.`);let e=b.slice(10);c[a]="*"===e||"^"===e||"~"===e?`${"*"===e?"^":e}${d}`:e}}}async function A(a,b,c,e){let g=f().join(a,b);for(let i of(await d.promises.readdir(g,{withFileTypes:!0}))){let g=f().join(b,i.name);if(i.isDirectory())await A(a,g,c,e);else if(i.isFile()){var h;let b=f().posix.join(c,...g.split(f().sep));e.push((h=await d.promises.readFile(f().join(a,g)),/\.(?:[cm]?js|json|d\.ts)$/i.test(b)?{path:b,contents:h.toString("utf8"),language:"javascript"}:{path:b,contents:h.toString("base64"),language:"text",encoding:"base64"}))}}}async function B(a){if("local"!==a.source||"string"!=typeof a.id||!w.test(a.id)||"string"!=typeof a.packageName||"string"!=typeof a.resolvedPath||!f().isAbsolute(a.resolvedPath))return[];let b=await d.promises.realpath(a.resolvedPath),c=JSON.parse(await d.promises.readFile(f().join(b,"package.json"),"utf8"));if(c.name!==a.packageName)throw Error(`Could not bundle Marketplace tool ${a.id}: package metadata does not match.`);await d.promises.access(f().join(b,"dist")),await z(c),delete c.devDependencies;let e=f().posix.join("marketplace-tools",a.id),g=[{path:f().posix.join(e,"package.json"),contents:JSON.stringify(c,null,2)+"\n",language:"json"}];return await A(b,"dist",e,g),g}async function C(a){return Promise.all((a.skills??[]).map(async a=>{if(!1===a.enabled||"remote"!==a.source||!a.url||a.content)return a;try{let b=new URL(a.url);if("https:"!==b.protocol)return a;let c=await fetch(b,{signal:AbortSignal.timeout(5e3)});if(!c.ok)return a;let d=(await c.text()).slice(0,12e3);return d?{...a,content:d}:a}catch{return a}}))}async function D(a,b={}){if("assistant"!==a.runtimeProfile)return{config:a,env:{},pluginFiles:[]};let[c,d,e]=await Promise.all([C(a),(0,l.fy)(),x(a,b.portable)]),f=b.portable?(await Promise.all(e.map(a=>B(a)))).flat():[],g=new Map((a.agentPlugins??[]).filter(b=>"string"==typeof b.id&&"string"==typeof b.packageName&&(0===(a.enabledTools??[]).length||(a.enabledTools??[]).includes(b.id))).map(a=>({...a,config:{}})).map(a=>[a.id,a]));for(let a of e)g.set(a.id,{...g.get(a.id),...a});let h=[...g.values()],i=b.mcpConnectionIds?new Set(b.mcpConnectionIds):null,j=i?d.filter(a=>i.has(a.id)):d,k=a.defaultSandboxProvider||"local";return{config:{...a,skills:c,agentPlugins:h.map(({id:a,name:b,packageName:c,version:d})=>({id:a,name:b,packageName:c,version:d}))},env:{LARKUP_MCP_CONNECTIONS:JSON.stringify(j),LARKUP_SANDBOX_BACKEND:k,LARKUP_SANDBOX_CREDENTIALS:JSON.stringify(a.sandboxProviderConfigs?.[k]??{}),LARKUP_AGENT_PLUGIN_MODULES:JSON.stringify(h.map(({id:a,name:b,packageName:c,config:d})=>({id:a,name:b,packageName:c,config:d})))},pluginFiles:f}}async function E(a){let b=(0,i.N)(a),c=await q(!0);if(!c)throw Error("No active Project to emit to.");for(let a of(await d.promises.mkdir(c,{recursive:!0}),b.files)){let b=f().join(c,a.path);await d.promises.mkdir(f().dirname(b),{recursive:!0}),"base64"===a.encoding?await d.promises.writeFile(b,Buffer.from(a.contents,"base64")):await d.promises.writeFile(b,a.contents,"utf8")}return c}async function F(a){let b=f().join(process.cwd(),"packages","sandbox");try{await d.promises.access(f().join(b,"package.json")),await d.promises.access(f().join(b,"dist","index.js"));let c=f().join(a,"package.json"),e=JSON.parse(await d.promises.readFile(c,"utf8"));if(!e.dependencies?.["@larkup/sandbox"])return;e.dependencies["@larkup/sandbox"]=`file:${b}`,await d.promises.writeFile(c,JSON.stringify(e,null,2)+"\n","utf8")}catch{}}async function G(a){try{return(await fetch(`${a}/health`,{signal:AbortSignal.timeout(3e3)})).ok}catch{return!1}}async function H(a){let b=f().join(a,".npm-cache");await d.promises.rm(b,{recursive:!0,force:!0}).catch(()=>{});try{await m("npm install --omit=dev --no-audit --no-fund",{cwd:a,timeout:24e4,env:{...process.env,HOME:process.env.HOME||a,npm_config_cache:b}})}finally{await d.promises.rm(b,{recursive:!0,force:!0}).catch(()=>{})}}async function I(a,b){let c,e=await o(),h=`http://localhost:${e}`,i=await s();if(i.pid&&u(i.pid))try{process.kill(i.pid,9)}catch{}await n(e);let k=await D(a),l=k.config,m=await E(l);await F(m);try{await H(m)}catch(b){let a=b instanceof Error?b.message:"npm install failed";return t({...p(e),lastError:a})}let q=l.storeConfig.dbPath||"./.larkup/lancedb",r=f().isAbsolute(q)?q:f().join(process.cwd(),q),v=f().join(m,"server.log");await d.promises.writeFile(v,"","utf8");let w=await d.promises.open(v,"a"),x=(0,g.spawn)("node",["server.mjs"],{cwd:m,detached:!0,stdio:["ignore",w.fd,w.fd],env:{...process.env,PORT:String(e),TOP_K:String(l.topK),SERVER_API_KEY:b||"",EMBEDDING_API_KEY:l.embeddingApiKey||process.env.EMBEDDING_API_KEY||process.env.OPENAI_API_KEY||"",CHAT_API_KEY:l.chatApiKey||l.customChatModels?.find(a=>a.modelName===l.chatModelId?.replace(/^custom:/,""))?.apiKey||process.env.CHAT_API_KEY||process.env.OPENAI_API_KEY||"",CHAT_MODEL:process.env.CHAT_MODEL||(0,j.oK)(l),CHAT_BASE_URL:l.customChatModels?.find(a=>a.modelName===l.chatModelId?.replace(/^custom:/,""))?.baseUrl||process.env.CHAT_BASE_URL||"",OPENAI_API_KEY:l.embeddingApiKey||l.chatApiKey||process.env.OPENAI_API_KEY||"",ANTHROPIC_API_KEY:l.chatApiKey||l.embeddingApiKey||process.env.ANTHROPIC_API_KEY||"",COHERE_API_KEY:l.embeddingApiKey||l.chatApiKey||process.env.COHERE_API_KEY||"",GOOGLE_GENERATIVE_AI_API_KEY:l.embeddingApiKey||l.chatApiKey||process.env.GOOGLE_GENERATIVE_AI_API_KEY||"",PINECONE_API_KEY:l.storeConfig.apiKey||"",PINECONE_INDEX:l.storeConfig.indexName||"",PINECONE_NAMESPACE:l.storeConfig.namespace||"",PINECONE_SPARSE_MODEL:l.storeConfig.sparseModel||"",PINECONE_SPARSE_INDEX:l.storeConfig.sparseIndexName||"",LANCEDB_MODE:l.storeConfig.mode||"local",LANCEDB_PATH:r,LANCEDB_URI:l.storeConfig.uri||"",LANCEDB_API_KEY:l.storeConfig.apiKey||"",LANCEDB_S3_URI:l.storeConfig.s3Uri||"",AWS_ENDPOINT:l.storeConfig.s3Endpoint||"",AWS_REGION:l.storeConfig.s3Region||"",AWS_ACCESS_KEY_ID:l.storeConfig.s3AccessKeyId||"",AWS_SECRET_ACCESS_KEY:l.storeConfig.s3SecretAccessKey||"",LANCEDB_TABLE:l.storeConfig.tableName||"documents",...k.env}});x.unref(),await w.close();let y=await L(h,2e4);if(!y){c="The AI server failed to start within the expected time limit. Please try restarting.";try{let a=(await d.promises.readFile(v,"utf8")).trim();if(a){let b=a.split("\n").slice(-20).join("\n");c=`The AI server failed to start. Error details:
|
|
2
|
+
${b}`}}catch(a){}}return t({running:y,pid:x.pid,port:e,endpoint:h,generatedAt:new Date().toISOString(),startedAt:new Date().toISOString(),lastError:c})}async function J(){let a=await s(),b=a.port||8080;if(a.pid&&u(a.pid))try{process.kill(a.pid,9)}catch{}return await n(b),t({...a,running:!1,pid:void 0,startedAt:void 0})}async function K(){let a=await s();if(!a.startedAt)return a;let b=u(a.pid)&&await G(a.endpoint);return b!==a.running?t({...a,running:b}):a}async function L(a,b){let c=Date.now()+b;for(;Date.now()<c;){if(await G(a))return!0;await new Promise(a=>setTimeout(a,1500))}return!1}},17089:(a,b,c)=>{c.d(b,{N:()=>g});var d=c(22462),e=c(46066),f=c(52249);function g(a){var b;let g,h,i,j,k,l,m,n,o,p,q,r=(0,d.jX)(a.vectorStore);(0,e.getEmbeddingModel)(a.embeddingModelId);let s="lancedb"===a.vectorStore&&(a.storeConfig.mode??"local")==="local",t={ai:f.Pm,cheerio:"^1.0.0",...r.serverDependencies};if("assistant"===a.runtimeProfile)for(let b of(t.zod="^4.4.3",t["@ai-sdk/mcp"]="2.0.26",t["@larkup/sandbox"]="^0.1.2",a.agentPlugins??[]))b.version&&/^(?:@[-a-z0-9~][-_a-z0-9~]*\/)?[-a-z0-9~][-_a-z0-9~]*$/i.test(b.packageName)&&(t[b.packageName]=b.version);a.embeddingModelId.startsWith("custom:")?t["@ai-sdk/openai-compatible"]=f.sZ["@ai-sdk/openai-compatible"]:"deepseek"===a.embeddingProvider?t["@ai-sdk/deepseek"]=f.sZ["@ai-sdk/deepseek"]:"google"===a.embeddingProvider?t["@ai-sdk/google"]=f.sZ["@ai-sdk/google"]:"cohere"===a.embeddingProvider?t["@ai-sdk/cohere"]=f.sZ["@ai-sdk/cohere"]:"mistral"===a.embeddingProvider?t["@ai-sdk/mistral"]=f.sZ["@ai-sdk/mistral"]:"vercel_ai_gateway"===a.embeddingProvider?t["@ai-sdk/gateway"]=f.sZ["@ai-sdk/gateway"]:(a.embeddingProvider,t["@ai-sdk/openai"]=f.sZ["@ai-sdk/openai"]);let u=(0,f.yo)(a),v=(0,f.oK)(a,u);(0,f.II)(t,u);let w=[{key:"EMBEDDING_API_KEY",required:!0,help:"API key used to embed incoming queries."},{key:"PORT",required:!1,help:"Port to listen on (default 8080)."},{key:"SERVER_API_KEYS",required:!1,help:"Scoped API keys. Format: 'scope:key,scope:key,...' where scope is retrieval, ingest, or admin. Example: 'retrieval:rk_abc,ingest:ik_def,admin:ak_ghi'. A single key without scope prefix is treated as admin for backward compatibility."},{key:"TOP_K",required:!1,help:`Default number of documents to retrieve (default ${a.topK}).`},{key:"CHAT_API_KEY",required:!0,help:"API key used by the streaming /chat endpoint."},{key:"CHAT_MODEL",required:!1,help:`Chat model override (default ${v}).`}];"custom"===u&&w.push({key:"CHAT_BASE_URL",required:!0,help:"OpenAI-compatible base URL used by the chat endpoint."}),"assistant"===a.runtimeProfile&&w.push({key:"LARKUP_MCP_CONNECTIONS",required:!1,help:"JSON array of enabled MCP connection records. Configure this as a deployment secret; local runs receive it from Agent Customization automatically."},{key:"LARKUP_SANDBOX_BACKEND",required:!1,help:"Sandbox backend for the Agent executeAnalysis tool (default local)."},{key:"LARKUP_SANDBOX_CREDENTIALS",required:!1,help:"JSON sandbox credentials for LARKUP_SANDBOX_BACKEND. Configure this as a deployment secret."},{key:"LARKUP_AGENT_PLUGIN_MODULES",required:!1,help:"JSON array of installed plugin modules that implement the Larkup Agent tool factory contract."}),"pinecone"===a.vectorStore?w.push({key:"PINECONE_API_KEY",required:!0,help:"Pinecone API key."},{key:"PINECONE_INDEX",required:!0,help:"Pinecone index name to query."},{key:"PINECONE_NAMESPACE",required:!1,help:"Pinecone namespace (default 'default')."},{key:"PINECONE_SPARSE_MODEL",required:!1,help:"Pinecone sparse model (for hybrid search)."},{key:"PINECONE_SPARSE_INDEX",required:!1,help:"Pinecone sparse index name (for hybrid search)."}):w.push({key:"LANCEDB_MODE",required:!1,help:"'local' (on-disk), 's3' (S3-compatible), or 'cloud' (default 'local')."},{key:"LANCEDB_PATH",required:!1,help:"On-disk path to the LanceDB tables (local mode)."},{key:"LANCEDB_TABLE",required:!1,help:"Table name holding the embedded chunks (default 'documents')."},{key:"LANCEDB_S3_URI",required:!1,help:"S3-compatible LanceDB URI (e.g. s3://bucket/prefix)."},{key:"AWS_ENDPOINT",required:!1,help:"S3-compatible endpoint (required for Cloudflare R2)."},{key:"AWS_REGION",required:!1,help:"S3 region (use auto for Cloudflare R2)."},{key:"AWS_ACCESS_KEY_ID",required:!1,help:"S3-compatible access key ID."},{key:"AWS_SECRET_ACCESS_KEY",required:!1,help:"S3-compatible secret access key."},{key:"LANCEDB_URI",required:!1,help:"LanceDB Cloud database URI (cloud mode)."},{key:"LANCEDB_API_KEY",required:!1,help:"LanceDB Cloud API key (cloud mode)."});let x={projectName:a.projectName,files:[],dependencies:t,envVars:w},y={name:a.projectName,version:"1.0.0",private:!0,type:"module",description:`Larkup ${"assistant"===a.runtimeProfile?"Agent":"Knowledge"} Server (${r.label})`,scripts:{start:"node --env-file=.env server.mjs",demo:"node demo.mjs"},dependencies:t,engines:{node:">=20"}},z=x.envVars.map(b=>{let c="";if("EMBEDDING_API_KEY"===b.key&&(c=a.embeddingApiKey||""),"CHAT_API_KEY"===b.key){let b=a.chatModelId?.replace(/^custom:/,"")||"",d=a.customChatModels?.find(a=>a.modelName===b)?.apiKey;c=a.chatApiKey||d||a.embeddingApiKey||""}if("CHAT_MODEL"===b.key&&(c=v),"CHAT_BASE_URL"===b.key){let b=a.chatModelId?.replace(/^custom:/,"")||"";c=a.customChatModels?.find(a=>a.modelName===b)?.baseUrl||""}return"PINECONE_API_KEY"===b.key&&(c=a.storeConfig.apiKey||""),"PINECONE_INDEX"===b.key&&(c=a.storeConfig.indexName||""),"PINECONE_NAMESPACE"===b.key&&(c=a.storeConfig.namespace||""),"LANCEDB_MODE"===b.key&&(c=a.storeConfig.mode||"local"),"LANCEDB_URI"===b.key&&(c=a.storeConfig.uri||""),"LANCEDB_API_KEY"===b.key&&(c=a.storeConfig.apiKey||""),"LANCEDB_S3_URI"===b.key&&(c=a.storeConfig.s3Uri||""),"AWS_ENDPOINT"===b.key&&(c=a.storeConfig.s3Endpoint||""),"AWS_REGION"===b.key&&(c=a.storeConfig.s3Region||""),"AWS_ACCESS_KEY_ID"===b.key&&(c=a.storeConfig.s3AccessKeyId||""),"AWS_SECRET_ACCESS_KEY"===b.key&&(c=a.storeConfig.s3SecretAccessKey||""),`${b.key}=${c}`}).join("\n"),A=[{path:"package.json",contents:JSON.stringify(y,null,2)+"\n"},{path:"server.mjs",contents:(g="assistant"===a.runtimeProfile,h=["searchKnowledgeBase","getIndexedData"].filter(b=>0===(a.enabledTools??[]).length||a.enabledTools?.includes(b)).map(a=>"searchKnowledgeBase"===a?{id:a,name:"Search Knowledge Base",description:"Search indexed Larkup knowledge-base content."}:{id:a,name:"Get Indexed Data",description:"List indexed knowledge-base documents."}),`import { createServer } from "node:http"
|
|
3
|
+
import { embedQuery } from "./embed.mjs"
|
|
4
|
+
import * as store from "./store.mjs"
|
|
5
|
+
import { getChatModelCatalog } from "./models.mjs"
|
|
6
|
+
${g?'import { widgetScript } from "./widget.mjs"':""}
|
|
7
|
+
import { handleChat${g?", handleAgentChat, handleOpenAIChatCompletions, listAgentCapabilities, listAgentTools, getAgentRuntimeConfiguration, getAgentSandboxStatus":""} } from "./chat.mjs"
|
|
8
|
+
import fs from "node:fs"
|
|
9
|
+
import path from "node:path"
|
|
10
|
+
import * as cheerio from "cheerio"
|
|
11
|
+
|
|
12
|
+
const PORT = process.env.PORT || 8080
|
|
13
|
+
const DEFAULT_TOP_K = Number(process.env.TOP_K || ${a.topK})
|
|
14
|
+
const SERVER_PROFILE = ${JSON.stringify(g?"agent":"knowledge")}
|
|
15
|
+
const AGENT_TOOLS = ${JSON.stringify(h)}
|
|
16
|
+
|
|
17
|
+
/* Scoped API-key authentication. */
|
|
18
|
+
// SERVER_API_KEYS format: "scope:key,scope:key,..."
|
|
19
|
+
// Scopes: retrieval (query/chat), ingest (documents/scrape/media), admin (everything)
|
|
20
|
+
// Backward compat: SERVER_API_KEY without scope prefix = admin
|
|
21
|
+
const KEY_MAP = new Map()
|
|
22
|
+
const rawKeys = process.env.SERVER_API_KEYS || process.env.SERVER_API_KEY || ""
|
|
23
|
+
if (rawKeys) {
|
|
24
|
+
for (const entry of rawKeys.split(",").map(s => s.trim()).filter(Boolean)) {
|
|
25
|
+
const colonIdx = entry.indexOf(":")
|
|
26
|
+
if (colonIdx > 0) {
|
|
27
|
+
KEY_MAP.set(entry.slice(colonIdx + 1), entry.slice(0, colonIdx))
|
|
28
|
+
} else {
|
|
29
|
+
// Legacy single key without scope = admin
|
|
30
|
+
KEY_MAP.set(entry, "admin")
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const AUTH_ENABLED = KEY_MAP.size > 0
|
|
35
|
+
console.log('[${a.projectName}] Auth:', AUTH_ENABLED ? \`\${KEY_MAP.size} scoped key(s) configured\` : 'DISABLED (open access)')
|
|
36
|
+
|
|
37
|
+
// Endpoint-to-scope access table per ADR-004
|
|
38
|
+
const SCOPE_TABLE = {
|
|
39
|
+
retrieval: new Set(["/query", "/chat", "/models", "/agent", "/v1/chat/completions"]),
|
|
40
|
+
ingest: new Set(["/query", "/chat", "/models", "/agent", "/v1/chat/completions", "/documents", "/scrape", "/media"]),
|
|
41
|
+
admin: null, // admin = all endpoints
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function resolveScope(token) {
|
|
45
|
+
return KEY_MAP.get(token) || null
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function scopeAllows(scope, pathname) {
|
|
49
|
+
if (!scope) return false
|
|
50
|
+
if (scope === "admin") return true
|
|
51
|
+
if (pathname === "/agent/configuration" || pathname === "/agent/sandbox") return false
|
|
52
|
+
const allowed = SCOPE_TABLE[scope]
|
|
53
|
+
if (!allowed) return false
|
|
54
|
+
// Check if the pathname starts with any allowed prefix
|
|
55
|
+
for (const p of allowed) {
|
|
56
|
+
if (pathname === p || pathname.startsWith(p + "/")) return true
|
|
57
|
+
}
|
|
58
|
+
return false
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function send(res, status, body) {
|
|
62
|
+
const json = JSON.stringify(body)
|
|
63
|
+
res.writeHead(status, {
|
|
64
|
+
"Content-Type": "application/json",
|
|
65
|
+
"Access-Control-Allow-Origin": "*",
|
|
66
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
67
|
+
"Access-Control-Allow-Methods": "GET,POST,PUT,DELETE,OPTIONS",
|
|
68
|
+
})
|
|
69
|
+
res.end(json)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function readBody(req) {
|
|
73
|
+
const chunks = []
|
|
74
|
+
for await (const c of req) chunks.push(c)
|
|
75
|
+
if (chunks.length === 0) return {}
|
|
76
|
+
try {
|
|
77
|
+
return JSON.parse(Buffer.concat(chunks).toString("utf8"))
|
|
78
|
+
} catch {
|
|
79
|
+
return {}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const handler = async (req, res) => {
|
|
84
|
+
if (req.method === "OPTIONS") return send(res, 204, {})
|
|
85
|
+
|
|
86
|
+
const url = new URL(req.url, \`http://\${req.headers.host}\`)
|
|
87
|
+
|
|
88
|
+
if (req.method === "GET" && url.pathname === "/favicon.ico") {
|
|
89
|
+
try {
|
|
90
|
+
const filepath = path.join(process.cwd(), "public", "favicon.ico")
|
|
91
|
+
if (fs.existsSync(filepath)) {
|
|
92
|
+
res.writeHead(200, { "Content-Type": "image/x-icon" })
|
|
93
|
+
return res.end(fs.readFileSync(filepath))
|
|
94
|
+
}
|
|
95
|
+
const rootFilepath = path.join(process.cwd(), "favicon.ico")
|
|
96
|
+
if (fs.existsSync(rootFilepath)) {
|
|
97
|
+
res.writeHead(200, { "Content-Type": "image/x-icon" })
|
|
98
|
+
return res.end(fs.readFileSync(rootFilepath))
|
|
99
|
+
}
|
|
100
|
+
} catch {}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Public endpoints: no auth required
|
|
104
|
+
const isPublic = url.pathname === "/" || url.pathname === "/health" || url.pathname === "/readiness" || url.pathname === "/openapi.json" || url.pathname === "/reference"${g?' || url.pathname === "/widget.js"':""}
|
|
105
|
+
|
|
106
|
+
if (AUTH_ENABLED && !isPublic) {
|
|
107
|
+
const auth = req.headers.authorization
|
|
108
|
+
if (!auth) {
|
|
109
|
+
return send(res, 401, { error: "Missing Authorization header. Use 'Authorization: Bearer <key>'." })
|
|
110
|
+
}
|
|
111
|
+
const token = auth.replace(/^Bearer\\s+/i, "").trim()
|
|
112
|
+
const scope = resolveScope(token)
|
|
113
|
+
if (!scope) {
|
|
114
|
+
return send(res, 401, { error: "Invalid API key." })
|
|
115
|
+
}
|
|
116
|
+
if (!scopeAllows(scope, url.pathname)) {
|
|
117
|
+
return send(res, 403, { error: \`Insufficient permissions. Your '\${scope}' key cannot access \${url.pathname}.\` })
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (req.method === "GET" && url.pathname === "/health") {
|
|
122
|
+
return send(res, 200, { ok: true, service: ${JSON.stringify(a.projectName)}, type: SERVER_PROFILE === "agent" ? "agent-server" : "knowledge-server", profile: SERVER_PROFILE })
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (req.method === "OPTIONS") {
|
|
126
|
+
res.writeHead(204, {
|
|
127
|
+
"Access-Control-Allow-Origin": "*",
|
|
128
|
+
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
|
|
129
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
130
|
+
"Access-Control-Max-Age": "86400",
|
|
131
|
+
})
|
|
132
|
+
return res.end()
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
${g?` if (req.method === "GET" && url.pathname === "/widget.js") {
|
|
136
|
+
res.writeHead(200, {
|
|
137
|
+
"Content-Type": "application/javascript; charset=utf-8",
|
|
138
|
+
"Cache-Control": "public, max-age=3600",
|
|
139
|
+
"Access-Control-Allow-Origin": "*",
|
|
140
|
+
"X-Content-Type-Options": "nosniff",
|
|
141
|
+
})
|
|
142
|
+
return res.end(widgetScript)
|
|
143
|
+
}
|
|
144
|
+
`:""}
|
|
145
|
+
|
|
146
|
+
if (req.method === "GET" && url.pathname === "/readiness") {
|
|
147
|
+
try {
|
|
148
|
+
const t = await store.list({ page: 1, limit: 1 })
|
|
149
|
+
return send(res, 200, { ready: true, vectorStore: "connected", documents: t.total ?? 0 })
|
|
150
|
+
} catch (err) {
|
|
151
|
+
return send(res, 503, { ready: false, vectorStore: "error", error: String(err?.message || err) })
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (req.method === "GET" && url.pathname === "/models") {
|
|
156
|
+
return send(res, 200, await getChatModelCatalog(url.searchParams.get("provider") || undefined))
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (req.method === "GET" && url.pathname === "/") {
|
|
160
|
+
res.writeHead(302, { Location: "/reference", "Cache-Control": "no-store" })
|
|
161
|
+
return res.end()
|
|
162
|
+
|
|
163
|
+
res.writeHead(200, { "Content-Type": "text/html" })
|
|
164
|
+
return res.end(\`<!DOCTYPE html>
|
|
165
|
+
<html lang="en">
|
|
166
|
+
<head>
|
|
167
|
+
<meta charset="utf-8" />
|
|
168
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
169
|
+
<title>\${${JSON.stringify(a.projectName)}} — Larkup Server</title>
|
|
170
|
+
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
|
|
171
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
172
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
173
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
174
|
+
<style>
|
|
175
|
+
*{margin:0;padding:0;box-sizing:border-box}
|
|
176
|
+
body{font-family:'Inter',system-ui,sans-serif;min-height:100vh;display:flex;align-items:center;justify-content:center;background:#F2EDE8;color:#18181b;overflow:hidden;position:relative}
|
|
177
|
+
body::after{content:'';position:fixed;inset:0;pointer-events:none;z-index:0;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.28 0 0 0 0 0.23 0 0 0 0 0.16 0 0 0 0.55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");background-size:512px 512px;background-repeat:repeat;opacity:0.79;mix-blend-mode:overlay}
|
|
178
|
+
.bg-mesh{position:fixed;inset:0;z-index:0;background-image:radial-gradient(ellipse 55% 45% at 8% 4%,rgba(0,0,0,0.12),transparent 70%),radial-gradient(ellipse 45% 40% at 94% 92%,rgba(220,160,120,0.15),transparent 65%),radial-gradient(ellipse 70% 55% at 50% 50%,rgba(0,0,0,0.05),transparent 80%)}
|
|
179
|
+
.container{position:relative;z-index:1;text-align:center;max-width:800px;padding:2rem;}
|
|
180
|
+
.badge{display:inline-flex;align-items:center;gap:6px;padding:6px 16px;border-radius:100px;font-size:0.75rem;font-weight:500;color:#000;background:rgba(255,255,255,0.8);border:1px solid rgba(0,0,0,0.1);margin-bottom:2rem;backdrop-filter:blur(4px);transition:colors .2s}
|
|
181
|
+
.badge:hover{background:#fff}
|
|
182
|
+
.badge .dot{width:6px;height:6px;border-radius:50%;background:#10b981;box-shadow:0 0 6px rgba(16,185,129,.4);animation:pulse 2s ease-in-out infinite}
|
|
183
|
+
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.4}}
|
|
184
|
+
h1{font-size:3.5rem;font-weight:500;letter-spacing:-0.02em;color:#000;margin-bottom:1.5rem;line-height:1.05;}
|
|
185
|
+
.subtitle{font-size:1.125rem;color:#52525b;line-height:1.6;margin-bottom:3rem;max-width:600px;margin-left:auto;margin-right:auto;}
|
|
186
|
+
.actions{display:flex;flex-wrap:wrap;gap:1rem;justify-content:center}
|
|
187
|
+
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:0.75rem 1.5rem;font-size:0.875rem;font-weight:500;text-decoration:none;transition:all .2s ease;cursor:pointer;border:none;}
|
|
188
|
+
.btn-primary{background:#000000;color:#fff;box-shadow:0 2px 12px rgba(0,0,0,.15)}
|
|
189
|
+
.btn-primary:hover{transform:translateY(-1px);box-shadow:0 4px 20px rgba(0,0,0,.25)}
|
|
190
|
+
.btn-outline{background:transparent;color:#000;border:1px solid rgba(0,0,0,.12);}
|
|
191
|
+
.btn-outline:hover{background:rgba(255,255,255,0.5);border-color:rgba(0,0,0,.2);transform:translateY(-1px);}
|
|
192
|
+
.footer{margin-top:4rem;font-size:.875rem;color:#71717a}
|
|
193
|
+
.footer a{color:#000;text-decoration:underline;text-underline-offset:2px;}
|
|
194
|
+
.footer a:hover{color:#333;}
|
|
195
|
+
.icon{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
|
|
196
|
+
@media (max-width: 640px){ h1{font-size:2.5rem;} }
|
|
197
|
+
</style>
|
|
198
|
+
</head>
|
|
199
|
+
<body>
|
|
200
|
+
<div class="bg-mesh"></div>
|
|
201
|
+
<div class="container">
|
|
202
|
+
<div class="badge"><span class="dot"></span> Server Online</div>
|
|
203
|
+
<h1>\${${JSON.stringify(a.projectName)}}</h1>
|
|
204
|
+
<p class="subtitle">Your Larkup Server is ready.<br/>Powered by <strong style="color:#df9c20">Larkup</strong></p>
|
|
205
|
+
<div class="actions">
|
|
206
|
+
<a href="/reference" class="btn btn-primary">
|
|
207
|
+
<svg class="icon" viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>
|
|
208
|
+
API Reference
|
|
209
|
+
</a>
|
|
210
|
+
<a href="https://github.com/Larkup-AI/larkup" target="_blank" rel="noopener" class="btn btn-outline">
|
|
211
|
+
<svg class="icon" viewBox="0 0 24 24"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
|
212
|
+
Larkup Team
|
|
213
|
+
</a>
|
|
214
|
+
<a href="mailto:contact@larkup.de" class="btn btn-outline">
|
|
215
|
+
<svg class="icon" viewBox="0 0 24 24"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
|
|
216
|
+
Contact
|
|
217
|
+
</a>
|
|
218
|
+
</div>
|
|
219
|
+
<div class="footer">Built with <a href="https://github.com/Larkup-AI/larkup/buddy-rag" target="_blank" rel="noopener">larkup</a> \xb7 v1.0</div>
|
|
220
|
+
</div>
|
|
221
|
+
</body>
|
|
222
|
+
</html>\`)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (req.method === "POST" && url.pathname === "/query") {
|
|
226
|
+
try {
|
|
227
|
+
const { query: q, topK } = await readBody(req)
|
|
228
|
+
if (!q || typeof q !== "string") {
|
|
229
|
+
return send(res, 400, { error: "Body must include a 'query' string." })
|
|
230
|
+
}
|
|
231
|
+
const vector = await embedQuery(q)
|
|
232
|
+
const hits = await store.query(vector, Number(topK) || DEFAULT_TOP_K)
|
|
233
|
+
return send(res, 200, { query: q, hits })
|
|
234
|
+
} catch (err) {
|
|
235
|
+
return send(res, 500, { error: String(err?.message || err) })
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
${g?` if (req.method === "GET" && url.pathname === "/agent") {
|
|
240
|
+
return send(res, 200, {
|
|
241
|
+
name: ${JSON.stringify(a.projectName)},
|
|
242
|
+
agentId: ${JSON.stringify(a.projectName)},
|
|
243
|
+
profile: "agent",
|
|
244
|
+
tools: await listAgentTools(),
|
|
245
|
+
})
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (req.method === "GET" && url.pathname === "/agent/tools") {
|
|
249
|
+
return send(res, 200, { tools: await listAgentTools() })
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (req.method === "GET" && url.pathname === "/agent/capabilities") {
|
|
253
|
+
return send(res, 200, { capabilities: await listAgentCapabilities() })
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (req.method === "GET" && url.pathname === "/agent/configuration") {
|
|
257
|
+
return send(res, 200, getAgentRuntimeConfiguration())
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (req.method === "GET" && url.pathname === "/agent/sandbox") {
|
|
261
|
+
return send(res, 200, await getAgentSandboxStatus())
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (req.method === "POST" && (url.pathname === "/chat" || url.pathname === "/agent/chat")) {
|
|
265
|
+
return handleAgentChat(req, res)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (req.method === "POST" && url.pathname === "/v1/chat/completions") {
|
|
269
|
+
return handleOpenAIChatCompletions(req, res)
|
|
270
|
+
}
|
|
271
|
+
`:` if (req.method === "POST" && url.pathname === "/chat") {
|
|
272
|
+
return handleChat(req, res)
|
|
273
|
+
}
|
|
274
|
+
`}
|
|
275
|
+
|
|
276
|
+
if (req.method === "GET" && url.pathname === "/documents") {
|
|
277
|
+
try {
|
|
278
|
+
const page = Math.max(1, parseInt(url.searchParams.get("page") || "1", 10) || 1)
|
|
279
|
+
const limit = Math.min(100, Math.max(1, parseInt(url.searchParams.get("limit") || "20", 10) || 20))
|
|
280
|
+
const result = await store.list({ page, limit })
|
|
281
|
+
return send(res, 200, result)
|
|
282
|
+
} catch (err) {
|
|
283
|
+
return send(res, 500, { error: String(err?.message || err) })
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (req.method === "GET" && url.pathname.match(/^\\/documents\\/[^/]+$/) && !url.pathname.endsWith("/documents")) {
|
|
288
|
+
try {
|
|
289
|
+
const id = url.pathname.split("/").pop()
|
|
290
|
+
const doc = await store.get(id)
|
|
291
|
+
if (!doc) return send(res, 404, { error: "Document not found" })
|
|
292
|
+
return send(res, 200, doc)
|
|
293
|
+
} catch (err) {
|
|
294
|
+
return send(res, 500, { error: String(err?.message || err) })
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (req.method === "POST" && url.pathname === "/documents") {
|
|
299
|
+
try {
|
|
300
|
+
const doc = await readBody(req)
|
|
301
|
+
if (!doc.text) return send(res, 400, { error: "Missing text" })
|
|
302
|
+
const vector = await embedQuery(doc.text)
|
|
303
|
+
const id = doc.id || Math.random().toString(36).slice(2)
|
|
304
|
+
await store.add([{ id, vector, text: doc.text, title: doc.title || "Untitled", url: doc.url || "", documentId: doc.documentId || id }])
|
|
305
|
+
return send(res, 200, { success: true, id })
|
|
306
|
+
} catch (err) {
|
|
307
|
+
console.error("[POST /documents] Error:", err)
|
|
308
|
+
return send(res, 500, { error: String(err?.message || err) })
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (req.method === "PUT" && url.pathname.startsWith("/documents/")) {
|
|
313
|
+
try {
|
|
314
|
+
const id = url.pathname.split("/").pop()
|
|
315
|
+
const doc = await readBody(req)
|
|
316
|
+
if (!doc.text) return send(res, 400, { error: "Missing text" })
|
|
317
|
+
const vector = await embedQuery(doc.text)
|
|
318
|
+
await store.update(id, { id, vector, text: doc.text, title: doc.title || "Untitled", url: doc.url, documentId: doc.documentId || id })
|
|
319
|
+
return send(res, 200, { success: true })
|
|
320
|
+
} catch (err) {
|
|
321
|
+
return send(res, 500, { error: String(err?.message || err) })
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (req.method === "DELETE" && url.pathname.startsWith("/documents/")) {
|
|
326
|
+
try {
|
|
327
|
+
const id = url.pathname.split("/").pop()
|
|
328
|
+
await store.remove(id)
|
|
329
|
+
return send(res, 200, { success: true })
|
|
330
|
+
} catch (err) {
|
|
331
|
+
return send(res, 500, { error: String(err?.message || err) })
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (req.method === "POST" && url.pathname === "/scrape") {
|
|
336
|
+
try {
|
|
337
|
+
const { url: targetUrl } = await readBody(req)
|
|
338
|
+
if (!targetUrl || typeof targetUrl !== "string") {
|
|
339
|
+
return send(res, 400, { error: "Body must include a 'url' string." })
|
|
340
|
+
}
|
|
341
|
+
const fetchRes = await fetch(targetUrl)
|
|
342
|
+
if (!fetchRes.ok) return send(res, 502, { error: \`Failed to fetch \${targetUrl}: \${fetchRes.status}\` })
|
|
343
|
+
const html = await fetchRes.text()
|
|
344
|
+
const $ = cheerio.load(html)
|
|
345
|
+
$("script, style, nav, footer, header, iframe, noscript").remove()
|
|
346
|
+
const rawText = $("body").text().replace(/\\s+/g, " ").trim()
|
|
347
|
+
if (!rawText) return send(res, 422, { error: "No text content extracted from URL." })
|
|
348
|
+
|
|
349
|
+
const title = $("title").text().trim() || new URL(targetUrl).hostname
|
|
350
|
+
const CHUNK_SIZE = 1000
|
|
351
|
+
const chunks = []
|
|
352
|
+
for (let i = 0; i < rawText.length; i += CHUNK_SIZE) {
|
|
353
|
+
chunks.push(rawText.slice(i, i + CHUNK_SIZE))
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const documentId = Math.random().toString(36).slice(2)
|
|
357
|
+
for (const [idx, chunk] of chunks.entries()) {
|
|
358
|
+
const id = \`\${documentId}-\${idx}\`
|
|
359
|
+
const vector = await embedQuery(chunk)
|
|
360
|
+
await store.add([{ id, vector, text: chunk, title: \`\${title} (part \${idx + 1})\`, url: targetUrl || "", documentId }])
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
return send(res, 200, { success: true, documentId, chunks: chunks.length })
|
|
364
|
+
} catch (err) {
|
|
365
|
+
return send(res, 500, { error: String(err?.message || err) })
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (req.method === "GET" && url.pathname === "/corpus/summary") {
|
|
370
|
+
try {
|
|
371
|
+
const all = await store.list({ page: 1, limit: 100000 })
|
|
372
|
+
const docs = all.documents || []
|
|
373
|
+
const bySource = {}
|
|
374
|
+
const byStatus = {}
|
|
375
|
+
let totalChars = 0
|
|
376
|
+
for (const d of docs) {
|
|
377
|
+
const src = d.source || "unknown"
|
|
378
|
+
bySource[src] = (bySource[src] || 0) + 1
|
|
379
|
+
const st = d.status || "indexed"
|
|
380
|
+
byStatus[st] = (byStatus[st] || 0) + 1
|
|
381
|
+
totalChars += (d.text || "").length
|
|
382
|
+
}
|
|
383
|
+
return send(res, 200, {
|
|
384
|
+
totalDocuments: all.total,
|
|
385
|
+
bySource,
|
|
386
|
+
byStatus,
|
|
387
|
+
totalCharacters: totalChars
|
|
388
|
+
})
|
|
389
|
+
} catch (err) {
|
|
390
|
+
return send(res, 500, { error: String(err?.message || err) })
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (req.method === "POST" && url.pathname === "/corpus") {
|
|
395
|
+
try {
|
|
396
|
+
const { filter, limit: reqLimit, offset: reqOffset, includeContent } = await readBody(req)
|
|
397
|
+
const pageSize = Math.min(Math.max(reqLimit || 200, 1), 1000)
|
|
398
|
+
const page = Math.max(1, Math.floor((reqOffset || 0) / pageSize) + 1)
|
|
399
|
+
const result = await store.list({ page, limit: pageSize })
|
|
400
|
+
let docs = result.documents || []
|
|
401
|
+
|
|
402
|
+
// Apply optional filters
|
|
403
|
+
if (filter) {
|
|
404
|
+
if (filter.source) docs = docs.filter(d => d.source === filter.source)
|
|
405
|
+
if (filter.titleContains) {
|
|
406
|
+
const needle = filter.titleContains.toLowerCase()
|
|
407
|
+
docs = docs.filter(d => (d.title || "").toLowerCase().includes(needle))
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const mapped = docs.map(d => {
|
|
412
|
+
const entry = { id: d.id, title: d.title, url: d.url, documentId: d.documentId, charCount: (d.text || "").length }
|
|
413
|
+
if (includeContent) entry.content = (d.text || "").slice(0, 2000)
|
|
414
|
+
return entry
|
|
415
|
+
})
|
|
416
|
+
return send(res, 200, { documents: mapped, total: result.total, page, limit: pageSize })
|
|
417
|
+
} catch (err) {
|
|
418
|
+
return send(res, 500, { error: String(err?.message || err) })
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if (req.method === "POST" && url.pathname === "/corpus/export") {
|
|
423
|
+
try {
|
|
424
|
+
const { format } = await readBody(req)
|
|
425
|
+
const all = await store.list({ page: 1, limit: 100000 })
|
|
426
|
+
const docs = all.documents || []
|
|
427
|
+
|
|
428
|
+
if (format === "jsonl") {
|
|
429
|
+
const lines = docs.map(d => JSON.stringify({
|
|
430
|
+
id: d.id, title: d.title, url: d.url || "",
|
|
431
|
+
documentId: d.documentId, text: (d.text || "").slice(0, 1000)
|
|
432
|
+
}))
|
|
433
|
+
res.writeHead(200, { "Content-Type": "application/x-ndjson", "Access-Control-Allow-Origin": "*" })
|
|
434
|
+
return res.end(lines.join("\\n"))
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Default: CSV
|
|
438
|
+
const header = "id,title,url,documentId,charCount,content"
|
|
439
|
+
const csvEscape = (v) => {
|
|
440
|
+
const s = String(v || "")
|
|
441
|
+
return s.includes(",") || s.includes('"') || s.includes("\\n") ? '"' + s.replace(/"/g, '""') + '"' : s
|
|
442
|
+
}
|
|
443
|
+
const rows = docs.map(d => [
|
|
444
|
+
d.id, d.title, d.url || "", d.documentId,
|
|
445
|
+
(d.text || "").length,
|
|
446
|
+
(d.text || "").slice(0, 1000).replace(/\\n/g, " ")
|
|
447
|
+
].map(csvEscape).join(","))
|
|
448
|
+
res.writeHead(200, { "Content-Type": "text/csv", "Access-Control-Allow-Origin": "*" })
|
|
449
|
+
return res.end([header, ...rows].join("\\n"))
|
|
450
|
+
} catch (err) {
|
|
451
|
+
return send(res, 500, { error: String(err?.message || err) })
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (req.method === "GET" && url.pathname === "/openapi.json") {
|
|
456
|
+
return send(res, 200, {
|
|
457
|
+
openapi: "3.1.0",
|
|
458
|
+
info: {
|
|
459
|
+
title: SERVER_PROFILE === "agent" ? "Larkup Agent Server" : "Larkup Knowledge Server",
|
|
460
|
+
version: "1.0.0",
|
|
461
|
+
description: SERVER_PROFILE === "agent"
|
|
462
|
+
? "Knowledge-base operations plus an AI SDK-compatible Agent API."
|
|
463
|
+
: "Knowledge-base retrieval and content-management API.",
|
|
464
|
+
},
|
|
465
|
+
security: [{ bearerAuth: [] }],
|
|
466
|
+
tags: [
|
|
467
|
+
{ name: "Knowledge", description: "Knowledge base retrieval and management." },
|
|
468
|
+
...(SERVER_PROFILE === "agent"
|
|
469
|
+
? [{ name: "Agent", description: "Agent chat streaming and loaded tools." }]
|
|
470
|
+
: []),
|
|
471
|
+
],
|
|
472
|
+
paths: {
|
|
473
|
+
"/query": {
|
|
474
|
+
post: {
|
|
475
|
+
summary: "Query the RAG knowledge base",
|
|
476
|
+
tags: ["Knowledge"],
|
|
477
|
+
security: [{ bearerAuth: [] }],
|
|
478
|
+
requestBody: {
|
|
479
|
+
content: { "application/json": { schema: { type: "object", properties: { query: { type: "string" }, topK: { type: "number" } } } } }
|
|
480
|
+
},
|
|
481
|
+
responses: { "200": { description: "Successful response" } }
|
|
482
|
+
}
|
|
483
|
+
},
|
|
484
|
+
"/chat": {
|
|
485
|
+
post: {
|
|
486
|
+
summary: SERVER_PROFILE === "agent" ? "Stream an Agent chat response" : "Stream a retrieval-grounded chat response",
|
|
487
|
+
tags: [SERVER_PROFILE === "agent" ? "Agent" : "Knowledge"],
|
|
488
|
+
security: [{ bearerAuth: [] }],
|
|
489
|
+
requestBody: {
|
|
490
|
+
required: true,
|
|
491
|
+
content: {
|
|
492
|
+
"application/json": {
|
|
493
|
+
schema: {
|
|
494
|
+
type: "object",
|
|
495
|
+
required: ["messages"],
|
|
496
|
+
properties: {
|
|
497
|
+
messages: {
|
|
498
|
+
type: "array",
|
|
499
|
+
items: {
|
|
500
|
+
type: "object",
|
|
501
|
+
required: ["role", "content"],
|
|
502
|
+
properties: {
|
|
503
|
+
role: { type: "string", enum: ["user", "assistant", "system"] },
|
|
504
|
+
content: { type: "string" }
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
},
|
|
508
|
+
topK: { type: "integer", minimum: 1 },
|
|
509
|
+
provider: { type: "string", description: "Configured chat runtime provider. Optional; must match this deployment." },
|
|
510
|
+
modelId: { type: "string", description: "Model ID to use for this request. Gateway runtimes accept any listed Gateway language model; direct providers accept their own model IDs." }
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
},
|
|
516
|
+
responses: {
|
|
517
|
+
"200": {
|
|
518
|
+
description: SERVER_PROFILE === "agent"
|
|
519
|
+
? "AI SDK UI message stream"
|
|
520
|
+
: "Server-sent events containing text-delta and done events",
|
|
521
|
+
content: { "text/event-stream": {} }
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
"/documents": {
|
|
527
|
+
get: {
|
|
528
|
+
summary: "List documents (paginated)",
|
|
529
|
+
tags: ["Knowledge"],
|
|
530
|
+
security: [{ bearerAuth: [] }],
|
|
531
|
+
parameters: [
|
|
532
|
+
{ name: "page", in: "query", required: false, schema: { type: "integer", default: 1, minimum: 1 }, description: "Page number (1-indexed)" },
|
|
533
|
+
{ name: "limit", in: "query", required: false, schema: { type: "integer", default: 20, minimum: 1, maximum: 100 }, description: "Items per page" }
|
|
534
|
+
],
|
|
535
|
+
responses: {
|
|
536
|
+
"200": {
|
|
537
|
+
description: "Paginated list of documents",
|
|
538
|
+
content: {
|
|
539
|
+
"application/json": {
|
|
540
|
+
schema: {
|
|
541
|
+
type: "object",
|
|
542
|
+
properties: {
|
|
543
|
+
documents: { type: "array", items: { type: "object" } },
|
|
544
|
+
total: { type: "integer", description: "Total number of documents" },
|
|
545
|
+
page: { type: "integer", description: "Current page" },
|
|
546
|
+
limit: { type: "integer", description: "Items per page" },
|
|
547
|
+
totalPages: { type: "integer", description: "Total number of pages" }
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
},
|
|
555
|
+
post: {
|
|
556
|
+
summary: "Add a new document",
|
|
557
|
+
tags: ["Knowledge"],
|
|
558
|
+
security: [{ bearerAuth: [] }],
|
|
559
|
+
requestBody: {
|
|
560
|
+
content: { "application/json": { schema: { type: "object", properties: { text: { type: "string" }, title: { type: "string" }, url: { type: "string" }, documentId: { type: "string" } } } } }
|
|
561
|
+
},
|
|
562
|
+
responses: { "200": { description: "Successful response" } }
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
"/documents/{id}": {
|
|
566
|
+
get: {
|
|
567
|
+
summary: "Get a single document by ID",
|
|
568
|
+
tags: ["Knowledge"],
|
|
569
|
+
security: [{ bearerAuth: [] }],
|
|
570
|
+
parameters: [{ name: "id", in: "path", required: true, schema: { type: "string" } }],
|
|
571
|
+
responses: {
|
|
572
|
+
"200": { description: "Document object" },
|
|
573
|
+
"404": { description: "Document not found" }
|
|
574
|
+
}
|
|
575
|
+
},
|
|
576
|
+
put: {
|
|
577
|
+
summary: "Update a document",
|
|
578
|
+
tags: ["Knowledge"],
|
|
579
|
+
security: [{ bearerAuth: [] }],
|
|
580
|
+
parameters: [{ name: "id", in: "path", required: true, schema: { type: "string" } }],
|
|
581
|
+
requestBody: {
|
|
582
|
+
content: { "application/json": { schema: { type: "object", properties: { text: { type: "string" }, title: { type: "string" }, url: { type: "string" }, documentId: { type: "string" } } } } }
|
|
583
|
+
},
|
|
584
|
+
responses: { "200": { description: "Successful response" } }
|
|
585
|
+
},
|
|
586
|
+
delete: {
|
|
587
|
+
summary: "Delete a document",
|
|
588
|
+
tags: ["Knowledge"],
|
|
589
|
+
security: [{ bearerAuth: [] }],
|
|
590
|
+
parameters: [{ name: "id", in: "path", required: true, schema: { type: "string" } }],
|
|
591
|
+
responses: { "200": { description: "Successful response" } }
|
|
592
|
+
}
|
|
593
|
+
},
|
|
594
|
+
"/scrape": {
|
|
595
|
+
post: {
|
|
596
|
+
summary: "Scrape a URL and ingest into the corpus",
|
|
597
|
+
tags: ["Knowledge"],
|
|
598
|
+
security: [{ bearerAuth: [] }],
|
|
599
|
+
requestBody: {
|
|
600
|
+
content: { "application/json": { schema: { type: "object", required: ["url"], properties: { url: { type: "string", description: "URL to scrape" } } } } }
|
|
601
|
+
},
|
|
602
|
+
responses: {
|
|
603
|
+
"200": { description: "Scrape successful", content: { "application/json": { schema: { type: "object", properties: { success: { type: "boolean" }, documentId: { type: "string" }, chunks: { type: "integer" } } } } } },
|
|
604
|
+
"502": { description: "Failed to fetch the target URL" }
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
},
|
|
608
|
+
"/health": {
|
|
609
|
+
get: {
|
|
610
|
+
summary: "Health check",
|
|
611
|
+
tags: ["Knowledge"],
|
|
612
|
+
responses: { "200": { description: "OK" } }
|
|
613
|
+
}
|
|
614
|
+
},
|
|
615
|
+
"/models": {
|
|
616
|
+
get: {
|
|
617
|
+
summary: "List chat providers and models available to this runtime",
|
|
618
|
+
tags: ["Knowledge"],
|
|
619
|
+
security: [{ bearerAuth: [] }],
|
|
620
|
+
parameters: [{ name: "provider", in: "query", required: false, schema: { type: "string" }, description: "Filter Gateway models by provider." }],
|
|
621
|
+
responses: { "200": { description: "Chat provider and model catalog" } }
|
|
622
|
+
}
|
|
623
|
+
},
|
|
624
|
+
"/readiness": {
|
|
625
|
+
get: {
|
|
626
|
+
summary: "Check knowledge-store readiness",
|
|
627
|
+
tags: ["Knowledge"],
|
|
628
|
+
responses: { "200": { description: "Knowledge store is connected" }, "503": { description: "Knowledge store is unavailable" } }
|
|
629
|
+
}
|
|
630
|
+
},
|
|
631
|
+
"/corpus/summary": {
|
|
632
|
+
get: {
|
|
633
|
+
summary: "Get corpus summary statistics",
|
|
634
|
+
tags: ["Knowledge"],
|
|
635
|
+
security: [{ bearerAuth: [] }],
|
|
636
|
+
responses: {
|
|
637
|
+
"200": {
|
|
638
|
+
description: "Corpus summary with counts by source and status",
|
|
639
|
+
content: {
|
|
640
|
+
"application/json": {
|
|
641
|
+
schema: {
|
|
642
|
+
type: "object",
|
|
643
|
+
properties: {
|
|
644
|
+
totalDocuments: { type: "integer" },
|
|
645
|
+
bySource: { type: "object" },
|
|
646
|
+
byStatus: { type: "object" },
|
|
647
|
+
totalCharacters: { type: "integer" }
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
},
|
|
656
|
+
"/corpus": {
|
|
657
|
+
post: {
|
|
658
|
+
summary: "Get corpus documents with optional filtering",
|
|
659
|
+
tags: ["Knowledge"],
|
|
660
|
+
security: [{ bearerAuth: [] }],
|
|
661
|
+
requestBody: {
|
|
662
|
+
content: { "application/json": { schema: { type: "object", properties: {
|
|
663
|
+
filter: { type: "object", properties: { source: { type: "string" }, titleContains: { type: "string" } } },
|
|
664
|
+
limit: { type: "integer", default: 200 },
|
|
665
|
+
offset: { type: "integer", default: 0 },
|
|
666
|
+
includeContent: { type: "boolean", default: false }
|
|
667
|
+
} } } }
|
|
668
|
+
},
|
|
669
|
+
responses: { "200": { description: "Paginated list of corpus documents" } }
|
|
670
|
+
}
|
|
671
|
+
},
|
|
672
|
+
"/corpus/export": {
|
|
673
|
+
post: {
|
|
674
|
+
summary: "Export full corpus as CSV or JSONL",
|
|
675
|
+
tags: ["Knowledge"],
|
|
676
|
+
security: [{ bearerAuth: [] }],
|
|
677
|
+
requestBody: {
|
|
678
|
+
content: { "application/json": { schema: { type: "object", properties: { format: { type: "string", enum: ["csv", "jsonl"], default: "csv" } } } } }
|
|
679
|
+
},
|
|
680
|
+
responses: { "200": { description: "Corpus data in requested format" } }
|
|
681
|
+
}
|
|
682
|
+
},
|
|
683
|
+
...(SERVER_PROFILE === "agent" ? {
|
|
684
|
+
"/agent": {
|
|
685
|
+
get: {
|
|
686
|
+
summary: "Get Agent Runtime information",
|
|
687
|
+
tags: ["Agent"],
|
|
688
|
+
security: [{ bearerAuth: [] }],
|
|
689
|
+
responses: { "200": { description: "Agent name, profile, and loaded tools" } },
|
|
690
|
+
},
|
|
691
|
+
},
|
|
692
|
+
"/agent/tools": {
|
|
693
|
+
get: {
|
|
694
|
+
summary: "List tools loaded by the Agent",
|
|
695
|
+
tags: ["Agent"],
|
|
696
|
+
security: [{ bearerAuth: [] }],
|
|
697
|
+
responses: { "200": { description: "Available Agent tool manifests" } },
|
|
698
|
+
},
|
|
699
|
+
},
|
|
700
|
+
"/agent/capabilities": {
|
|
701
|
+
get: {
|
|
702
|
+
summary: "List grouped Agent capabilities",
|
|
703
|
+
tags: ["Agent"],
|
|
704
|
+
security: [{ bearerAuth: [] }],
|
|
705
|
+
responses: { "200": { description: "Built-in, skills, sandbox, MCP, and plugin capability groups" } },
|
|
706
|
+
},
|
|
707
|
+
},
|
|
708
|
+
"/agent/configuration": {
|
|
709
|
+
get: {
|
|
710
|
+
summary: "Get saved Agent prompt and skills",
|
|
711
|
+
tags: ["Agent"],
|
|
712
|
+
security: [{ bearerAuth: [] }],
|
|
713
|
+
responses: { "200": { description: "Saved system prompt and enabled skill metadata; requires an admin key when auth is configured" } },
|
|
714
|
+
},
|
|
715
|
+
"/agent/sandbox": {
|
|
716
|
+
get: {
|
|
717
|
+
summary: "Check the configured Agent sandbox environment",
|
|
718
|
+
responses: { "200": { description: "Sanitized sandbox health status" } },
|
|
719
|
+
},
|
|
720
|
+
},
|
|
721
|
+
},
|
|
722
|
+
"/agent/chat": {
|
|
723
|
+
post: {
|
|
724
|
+
summary: "Stream an Agent response using the AI SDK UI message protocol",
|
|
725
|
+
tags: ["Agent"],
|
|
726
|
+
security: [{ bearerAuth: [] }],
|
|
727
|
+
requestBody: {
|
|
728
|
+
required: true,
|
|
729
|
+
content: {
|
|
730
|
+
"application/json": {
|
|
731
|
+
schema: {
|
|
732
|
+
type: "object",
|
|
733
|
+
required: ["messages"],
|
|
734
|
+
properties: { messages: { type: "array", items: { type: "object" } } },
|
|
735
|
+
},
|
|
736
|
+
},
|
|
737
|
+
},
|
|
738
|
+
},
|
|
739
|
+
responses: { "200": { description: "AI SDK UI message stream", content: { "text/event-stream": {} } } },
|
|
740
|
+
},
|
|
741
|
+
},
|
|
742
|
+
"/v1/chat/completions": {
|
|
743
|
+
post: {
|
|
744
|
+
summary: "OpenAI-compatible Agent chat completions",
|
|
745
|
+
tags: ["Agent"],
|
|
746
|
+
security: [{ bearerAuth: [] }],
|
|
747
|
+
requestBody: {
|
|
748
|
+
required: true,
|
|
749
|
+
content: {
|
|
750
|
+
"application/json": {
|
|
751
|
+
schema: {
|
|
752
|
+
type: "object",
|
|
753
|
+
required: ["messages"],
|
|
754
|
+
properties: {
|
|
755
|
+
model: { type: "string" },
|
|
756
|
+
stream: { type: "boolean", default: true },
|
|
757
|
+
messages: { type: "array", items: { type: "object" } },
|
|
758
|
+
},
|
|
759
|
+
},
|
|
760
|
+
},
|
|
761
|
+
},
|
|
762
|
+
},
|
|
763
|
+
responses: { "200": { description: "OpenAI chat completion or SSE completion stream" } },
|
|
764
|
+
},
|
|
765
|
+
},
|
|
766
|
+
} : {})
|
|
767
|
+
},
|
|
768
|
+
components: {
|
|
769
|
+
securitySchemes: {
|
|
770
|
+
bearerAuth: {
|
|
771
|
+
type: "http",
|
|
772
|
+
scheme: "bearer"
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
})
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
if (req.method === "GET" && url.pathname === "/reference") {
|
|
780
|
+
const defaultToken = process.env.SERVER_API_KEY || ""
|
|
781
|
+
res.writeHead(200, { "Content-Type": "text/html" })
|
|
782
|
+
return res.end(\`
|
|
783
|
+
<!DOCTYPE html>
|
|
784
|
+
<html>
|
|
785
|
+
<head>
|
|
786
|
+
<title>API Reference</title>
|
|
787
|
+
<meta charset="utf-8" />
|
|
788
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
789
|
+
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
|
|
790
|
+
<style>
|
|
791
|
+
:root {
|
|
792
|
+
--scalar-color-1: #000000;
|
|
793
|
+
--scalar-color-2: #333333;
|
|
794
|
+
--scalar-color-3: #666666;
|
|
795
|
+
--scalar-color-accent: #000000;
|
|
796
|
+
--scalar-background-1: #ffffff;
|
|
797
|
+
--scalar-background-2: #fafafa;
|
|
798
|
+
--scalar-background-3: #f5f5f5;
|
|
799
|
+
--scalar-background-accent: #f0f0f0;
|
|
800
|
+
}
|
|
801
|
+
.dark-mode {
|
|
802
|
+
--scalar-color-1: #ffffff;
|
|
803
|
+
--scalar-color-2: #cccccc;
|
|
804
|
+
--scalar-color-3: #999999;
|
|
805
|
+
--scalar-color-accent: #ffffff;
|
|
806
|
+
--scalar-background-1: #000000;
|
|
807
|
+
--scalar-background-2: #111111;
|
|
808
|
+
--scalar-background-3: #222222;
|
|
809
|
+
--scalar-background-accent: #333333;
|
|
810
|
+
}
|
|
811
|
+
</style>
|
|
812
|
+
</head>
|
|
813
|
+
<body>
|
|
814
|
+
<script id="api-reference" data-url="/openapi.json"></script>
|
|
815
|
+
<script>
|
|
816
|
+
const configuration = {
|
|
817
|
+
"theme": "default",
|
|
818
|
+
"hideClientButton": false,
|
|
819
|
+
"showSidebar": true,
|
|
820
|
+
"showDeveloperTools": "localhost",
|
|
821
|
+
"showToolbar": "localhost",
|
|
822
|
+
"operationTitleSource": "summary",
|
|
823
|
+
"persistAuth": true,
|
|
824
|
+
"telemetry": true,
|
|
825
|
+
"externalUrls": {
|
|
826
|
+
"dashboardUrl": "https://dashboard.scalar.com",
|
|
827
|
+
"registryUrl": "https://registry.scalar.com",
|
|
828
|
+
"proxyUrl": "https://proxy.scalar.com",
|
|
829
|
+
"apiBaseUrl": "https://api.scalar.com"
|
|
830
|
+
},
|
|
831
|
+
"default": false,
|
|
832
|
+
"layout": "modern",
|
|
833
|
+
"isEditable": false,
|
|
834
|
+
"isLoading": false,
|
|
835
|
+
"hideModels": false,
|
|
836
|
+
"documentDownloadType": "both",
|
|
837
|
+
"hideTestRequestButton": false,
|
|
838
|
+
"hideSearch": false,
|
|
839
|
+
"showOperationId": false,
|
|
840
|
+
"hideDarkModeToggle": false,
|
|
841
|
+
"withDefaultFonts": true,
|
|
842
|
+
"defaultOpenFirstTag": true,
|
|
843
|
+
"defaultOpenAllTags": false,
|
|
844
|
+
"expandAllModelSections": false,
|
|
845
|
+
"expandAllResponses": false,
|
|
846
|
+
"orderSchemaPropertiesBy": "alpha",
|
|
847
|
+
"orderRequiredPropertiesFirst": true,
|
|
848
|
+
"_integration": "html",
|
|
849
|
+
"modelsSectionLabel": "Models",
|
|
850
|
+
"slug": "api-1",
|
|
851
|
+
"title": "API #1",
|
|
852
|
+
"authentication": {
|
|
853
|
+
"preferredSecurityScheme": "bearerAuth",
|
|
854
|
+
"http": {
|
|
855
|
+
"basic": { "username": "", "password": "" },
|
|
856
|
+
"bearer": { "token": "\${defaultToken}" }
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
document.getElementById('api-reference').dataset.configuration = JSON.stringify(configuration);
|
|
861
|
+
</script>
|
|
862
|
+
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
|
|
863
|
+
</body>
|
|
864
|
+
</html>
|
|
865
|
+
\`)
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
return send(res, 404, { error: "Not found" })
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
const IS_SERVERLESS = !!process.env.VERCEL || !!process.env.AWS_LAMBDA_FUNCTION_NAME
|
|
872
|
+
|
|
873
|
+
if (!IS_SERVERLESS) {
|
|
874
|
+
const server = createServer(handler)
|
|
875
|
+
server.listen(PORT, () => {
|
|
876
|
+
console.log(\`Server listening on port \${PORT}\`)
|
|
877
|
+
})
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
export default handler;
|
|
881
|
+
`)},{path:"chat.mjs",contents:(0,f.iE)(a)},{path:"models.mjs",contents:(i=(0,f.yo)(a),j=(0,f.oK)(a,i),`const CHAT_PROVIDER = ${JSON.stringify(i)};
|
|
882
|
+
const CHAT_MODEL = process.env.CHAT_MODEL || ${JSON.stringify(j)};
|
|
883
|
+
const GATEWAY_MODELS_URL = "https://ai-gateway.vercel.sh/v1/models";
|
|
884
|
+
const CACHE_TTL_MS = 15 * 60 * 1000;
|
|
885
|
+
let cachedCatalog = null;
|
|
886
|
+
|
|
887
|
+
function vendorFromModelId(id) {
|
|
888
|
+
return typeof id === "string" && id.includes("/") ? id.split("/", 1)[0] : CHAT_PROVIDER;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
function configuredFallback() {
|
|
892
|
+
const provider = vendorFromModelId(CHAT_MODEL);
|
|
893
|
+
return {
|
|
894
|
+
configuredProvider: CHAT_PROVIDER,
|
|
895
|
+
configuredModelId: CHAT_MODEL,
|
|
896
|
+
providers: [{ id: provider, name: provider, modelCount: 1 }],
|
|
897
|
+
models: [{ id: CHAT_MODEL, name: CHAT_MODEL, provider }],
|
|
898
|
+
source: "configured",
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
function normalizeGatewayModels(payload) {
|
|
903
|
+
const raw = Array.isArray(payload) ? payload : Array.isArray(payload?.data) ? payload.data : [];
|
|
904
|
+
return raw
|
|
905
|
+
.filter((item) => item && (item.type === "language" || item.type === "chat" || !item.type))
|
|
906
|
+
.map((item) => ({
|
|
907
|
+
id: item.id,
|
|
908
|
+
name: item.name || item.id,
|
|
909
|
+
provider: item.owned_by || item.provider || vendorFromModelId(item.id),
|
|
910
|
+
contextWindow: item.context_window || item.contextWindow,
|
|
911
|
+
maxTokens: item.max_tokens || item.maxTokens,
|
|
912
|
+
tags: Array.isArray(item.tags) ? item.tags : undefined,
|
|
913
|
+
description: item.description,
|
|
914
|
+
}))
|
|
915
|
+
.filter((item) => typeof item.id === "string" && item.id.length > 0);
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
export async function getChatModelCatalog(requestedProvider) {
|
|
919
|
+
if (CHAT_PROVIDER !== "vercel_ai_gateway") {
|
|
920
|
+
const fallback = configuredFallback();
|
|
921
|
+
if (requestedProvider && requestedProvider !== CHAT_PROVIDER && requestedProvider !== fallback.models[0].provider) {
|
|
922
|
+
return { ...fallback, providers: [], models: [] };
|
|
923
|
+
}
|
|
924
|
+
return fallback;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
if (!cachedCatalog || Date.now() - cachedCatalog.at > CACHE_TTL_MS) {
|
|
928
|
+
try {
|
|
929
|
+
const response = await fetch(GATEWAY_MODELS_URL, { signal: AbortSignal.timeout(5000) });
|
|
930
|
+
if (!response.ok) throw new Error("Gateway model catalog returned " + response.status);
|
|
931
|
+
const models = normalizeGatewayModels(await response.json());
|
|
932
|
+
if (models.length === 0) throw new Error("Gateway model catalog was empty");
|
|
933
|
+
cachedCatalog = { at: Date.now(), models };
|
|
934
|
+
} catch (error) {
|
|
935
|
+
console.warn("[models] Could not refresh AI Gateway catalog:", error instanceof Error ? error.message : String(error));
|
|
936
|
+
return configuredFallback();
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
const models = requestedProvider
|
|
941
|
+
? cachedCatalog.models.filter((item) => item.provider === requestedProvider)
|
|
942
|
+
: cachedCatalog.models;
|
|
943
|
+
const counts = new Map();
|
|
944
|
+
for (const item of models) counts.set(item.provider, (counts.get(item.provider) || 0) + 1);
|
|
945
|
+
return {
|
|
946
|
+
configuredProvider: CHAT_PROVIDER,
|
|
947
|
+
configuredModelId: CHAT_MODEL,
|
|
948
|
+
providers: [...counts.entries()]
|
|
949
|
+
.map(([id, modelCount]) => ({ id, name: id, modelCount }))
|
|
950
|
+
.sort((a, b) => a.name.localeCompare(b.name)),
|
|
951
|
+
models,
|
|
952
|
+
source: "vercel-ai-gateway",
|
|
953
|
+
};
|
|
954
|
+
}`)},..."assistant"===a.runtimeProfile?[{path:"widget.mjs",contents:(k={title:a.widget?.title||"Ask us anything",welcomeMessage:a.widget?.welcomeMessage||"Hi! How can I help?",placeholder:a.widget?.placeholder||"Type a message…",primaryColor:a.widget?.primaryColor||"#111827",position:a.widget?.position||"bottom-right",darkMode:!!a.widget?.darkMode,logoUrl:a.widget?.logoUrl||""},l=`(() => {
|
|
955
|
+
const defaults = ${JSON.stringify(k)};
|
|
956
|
+
const script = document.currentScript || document.querySelector('script[data-larkup-widget]') || document.querySelector('script[src*="/widget.js"]');
|
|
957
|
+
const data = script?.dataset || {};
|
|
958
|
+
const host = String(data.host || new URL(script?.src || location.href, location.href).origin).replace(/\\/+$/, '');
|
|
959
|
+
const config = { ...defaults, title: data.title || defaults.title, welcomeMessage: data.welcomeMessage || defaults.welcomeMessage, placeholder: data.placeholder || defaults.placeholder, primaryColor: data.primaryColor || defaults.primaryColor, position: data.position || defaults.position, darkMode: data.theme ? data.theme === 'dark' : defaults.darkMode, logoUrl: data.logoUrl || defaults.logoUrl };
|
|
960
|
+
const mount = document.createElement('div'); mount.dataset.larkupWidget = ''; if (data.class) mount.className = data.class; document.body.appendChild(mount);
|
|
961
|
+
const root = mount.attachShadow({ mode: 'open' });
|
|
962
|
+
root.innerHTML = '<style>:host{all:initial}*{box-sizing:border-box}.w{--a:' + config.primaryColor + ';position:fixed;bottom:20px;z-index:2147483000;font:14px/1.45 ui-sans-serif,system-ui;color:#17191e}.right{right:20px}.left{left:20px}.p{width:min(390px,calc(100vw - 32px));height:min(620px,calc(100vh - 110px));display:none;flex-direction:column;overflow:hidden;background:#fff;border:1px solid #e1e3e8;border-radius:18px;box-shadow:0 20px 60px #11182738}.open .p{display:flex}.dark .p{background:#17191e;border-color:#343946;color:#f4f4f5;box-shadow:0 20px 60px #0009}.h{display:flex;gap:10px;align-items:center;padding:15px 16px;border-bottom:1px solid #e1e3e8}.dark .h{border-color:#343946}.d{width:9px;height:9px;border-radius:99px;background:var(--a)}strong{flex:1}.x,.b,.s{border:0;cursor:pointer}.x{background:transparent;color:inherit;font-size:20px}.m{flex:1;overflow:auto;display:flex;flex-direction:column;gap:10px;padding:16px}.a,.u,.empty{max-width:86%;padding:10px 12px;border-radius:14px;white-space:pre-wrap;overflow-wrap:anywhere}.a,.empty{align-self:flex-start;background:#f3f4f6}.dark .a,.dark .empty{background:#292d36}.u{align-self:flex-end;background:var(--a);color:#fff;border-bottom-right-radius:4px}.f{display:flex;gap:8px;padding:12px;border-top:1px solid #e1e3e8}.dark .f{border-color:#343946}textarea{flex:1;min-height:42px;resize:none;border:1px solid #d8dbe2;border-radius:12px;padding:10px;background:transparent;color:inherit;font:inherit}.s{width:42px;border-radius:12px;background:var(--a);color:#fff}.b{display:flex;align-items:center;justify-content:center;margin:12px 0 0 auto;width:56px;height:56px;border-radius:99px;background:var(--a);color:#fff;font-size:22px;box-shadow:0 10px 25px #11182740}.left .b{margin-left:0}.err{color:#dc2626}.dark .err{color:#fca5a5}.cb{background:#1e1e1e;color:#d4d4d4;border-radius:8px;overflow:hidden;margin:8px 0;font-family:monospace;font-size:13px;white-space:normal}.cb-h{display:flex;justify-content:space-between;background:#2d2d2d;padding:4px 8px;font-size:11px;color:#a0a0a0}.cb-h button{background:none;border:none;color:inherit;cursor:pointer;padding:0}.cb pre{margin:0;padding:8px;overflow-x:auto;white-space:pre}code{font-family:monospace;background:#0002;padding:2px 4px;border-radius:4px}a{color:var(--a)}@keyframes pulse{0%,100%{opacity:.5}50%{opacity:1}}</style><div class="w ' + (config.position === 'bottom-left' ? 'left' : 'right') + (config.darkMode ? ' dark' : '') + '"><section class="p" role="dialog"><header class="h"><i class="d"></i><strong></strong><button class="x" aria-label="Close chat">\xd7</button></header><main class="m"><div class="empty"></div></main><form class="f"><textarea rows="1"></textarea><button class="s" aria-label="Send">↑</button></form></section><button class="b" aria-label="Open chat"></button></div>';
|
|
963
|
+
const shell = root.querySelector('.w'), panel = root.querySelector('.p'), button = root.querySelector('.b'), close = root.querySelector('.x'), list = root.querySelector('.m'), empty = root.querySelector('.empty'), input = root.querySelector('textarea'), form = root.querySelector('form');
|
|
964
|
+
root.querySelector('strong').textContent = config.title; empty.textContent = config.welcomeMessage; input.placeholder = config.placeholder;
|
|
965
|
+
const iconNormal = config.logoUrl ? '<img src="' + config.logoUrl + '" style="width:28px;height:28px;border-radius:99px;object-fit:cover">' : '◌';
|
|
966
|
+
button.innerHTML = iconNormal;
|
|
967
|
+
const toggle = (open) => { shell.classList.toggle('open', open); button.innerHTML = open ? '\xd7' : iconNormal; }; button.onclick = () => toggle(!shell.classList.contains('open')); close.onclick = () => toggle(false);
|
|
968
|
+
const add = (name, text) => { const el = document.createElement('div'); el.className = name; el.innerHTML = text; list.appendChild(el); list.scrollTop = list.scrollHeight; return el; };
|
|
969
|
+
const text = (line) => { try { if (line.startsWith('0:')) { const value = JSON.parse(line.slice(2)); return typeof value === 'string' ? value : ''; } if (!line.startsWith('data:')) return ''; const value = JSON.parse(line.slice(5)); return value?.type === 'text-delta' ? (value.delta || value.text || '') : ''; } catch { return ''; } };
|
|
970
|
+
const parseMD = (str) => { return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\\\`\\\`\\\`(\\w*)\\n([\\s\\S]*?)\\\`\\\`\\\`/g, '<div class="cb"><div class="cb-h"><span>$1</span><button type="button" onclick="navigator.clipboard.writeText(this.parentElement.nextElementSibling.textContent);this.textContent=\\'Copied!\\';setTimeout(()=>this.textContent=\\'Copy\\',2000)">Copy</button></div><pre><code>$2</code></pre></div>').replace(/\\\`([^\`]+)\\\`/g, '<code>$1</code>').replace(/\\*\\*([^*]+)\\*\\*/g, '<strong>$1</strong>').replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href="$2" target="_blank">$1</a>'); };
|
|
971
|
+
input.onkeydown = (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); form.requestSubmit(); } };
|
|
972
|
+
form.onsubmit = async (event) => { event.preventDefault(); const question = input.value.trim(); if (!question) return; empty.remove(); add('u', parseMD(question)); input.value = ''; const answer = add('a', '<span style="animation:pulse 1s infinite">Thinking...</span>'); try { const response = await fetch(host + '/chat', { method: 'POST', headers: { 'Content-Type': 'application/json', ...(data.apiKey ? { Authorization: 'Bearer ' + data.apiKey } : {}) }, body: JSON.stringify({ messages: [{ role: 'user', content: question }] }) }); if (!response.ok) throw new Error((await response.json().catch(() => ({}))).error || 'Could not reach the assistant.'); const reader = response.body?.getReader(), decoder = new TextDecoder(); if (!reader) return; let buffer = ''; let fullText = ''; while (true) { const chunk = await reader.read(); buffer += decoder.decode(chunk.value || new Uint8Array(), { stream: !chunk.done }); const lines = buffer.split(/\\r?\\n/); buffer = lines.pop() || ''; for (const line of lines) { const t = text(line); if (t) { fullText += t; answer.innerHTML = parseMD(fullText); list.scrollTop = list.scrollHeight; } } if (chunk.done) break; } const t = text(buffer); if (t) { fullText += t; answer.innerHTML = parseMD(fullText); list.scrollTop = list.scrollHeight; } } catch (error) { answer.classList.add('err'); answer.textContent = error instanceof Error ? error.message : 'Could not reach the assistant.'; } };
|
|
973
|
+
window.LarkupWidget = { destroy: () => mount.remove() };
|
|
974
|
+
})();`,`export const widgetScript = ${JSON.stringify(l)};
|
|
975
|
+
`)}]:[],{path:"embed.mjs",contents:function(a){let b=`import { embed } from "ai"
|
|
976
|
+
`,c="";if(a.embeddingModelId.startsWith("custom:")){let d=a.embeddingModelId.slice(7),e=(a.customEmbeddings??[]).find(a=>a.modelName===d);b+=`import { createOpenAICompatible } from "@ai-sdk/openai-compatible"
|
|
977
|
+
`,c=`const provider = createOpenAICompatible({
|
|
978
|
+
name: "custom_provider",
|
|
979
|
+
baseURL: process.env.EMBEDDING_BASE_URL || ${JSON.stringify(e?.baseUrl||"")},
|
|
980
|
+
apiKey: process.env.EMBEDDING_API_KEY
|
|
981
|
+
})
|
|
982
|
+
const MODEL = provider.embeddingModel(process.env.EMBEDDING_MODEL || ${JSON.stringify(e?.modelName||"")})`}else"deepseek"===a.embeddingProvider?(b+=`import { createDeepSeek } from "@ai-sdk/deepseek"
|
|
983
|
+
`,c=`const provider = createDeepSeek({
|
|
984
|
+
apiKey: process.env.EMBEDDING_API_KEY
|
|
985
|
+
})
|
|
986
|
+
const MODEL = provider.embeddingModel(process.env.EMBEDDING_MODEL || ${JSON.stringify(a.embeddingModelId)})`):"google"===a.embeddingProvider?(b+=`import { createGoogleGenerativeAI } from "@ai-sdk/google"
|
|
987
|
+
`,c=`const provider = createGoogleGenerativeAI({
|
|
988
|
+
apiKey: process.env.EMBEDDING_API_KEY
|
|
989
|
+
})
|
|
990
|
+
const MODEL = provider.textEmbeddingModel(process.env.EMBEDDING_MODEL || ${JSON.stringify(a.embeddingModelId)})`):"cohere"===a.embeddingProvider?(b+=`import { createCohere } from "@ai-sdk/cohere"
|
|
991
|
+
`,c=`const provider = createCohere({
|
|
992
|
+
apiKey: process.env.EMBEDDING_API_KEY
|
|
993
|
+
})
|
|
994
|
+
const MODEL = provider.embedding(process.env.EMBEDDING_MODEL || ${JSON.stringify(a.embeddingModelId)})`):"mistral"===a.embeddingProvider?(b+=`import { createMistral } from "@ai-sdk/mistral"
|
|
995
|
+
`,c=`const provider = createMistral({
|
|
996
|
+
apiKey: process.env.EMBEDDING_API_KEY
|
|
997
|
+
})
|
|
998
|
+
const MODEL = provider.embedding(process.env.EMBEDDING_MODEL || ${JSON.stringify(a.embeddingModelId)})`):"vercel_ai_gateway"===a.embeddingProvider?(b+=`import { createGateway } from "@ai-sdk/gateway"
|
|
999
|
+
`,c=`const gateway = createGateway({
|
|
1000
|
+
apiKey: process.env.EMBEDDING_API_KEY
|
|
1001
|
+
})
|
|
1002
|
+
const MODEL = gateway.embedding(process.env.EMBEDDING_MODEL || ${JSON.stringify(a.embeddingModelId)})`):(b+=`import { createOpenAI } from "@ai-sdk/openai"
|
|
1003
|
+
`,c=`const provider = createOpenAI({
|
|
1004
|
+
apiKey: process.env.EMBEDDING_API_KEY
|
|
1005
|
+
})
|
|
1006
|
+
const modelName = process.env.EMBEDDING_MODEL || ${JSON.stringify(a.embeddingModelId)};
|
|
1007
|
+
const MODEL = provider.embedding(modelName.includes("/") ? modelName.split("/")[1] : modelName)`);return`${b}
|
|
1008
|
+
${c}
|
|
1009
|
+
|
|
1010
|
+
export async function embedQuery(text) {
|
|
1011
|
+
const { embedding } = await embed({ model: MODEL, value: text })
|
|
1012
|
+
return embedding
|
|
1013
|
+
}
|
|
1014
|
+
`}(a)},{path:"store.mjs",contents:"pinecone"===a.vectorStore?`import { Pinecone } from "@pinecone-database/pinecone"
|
|
1015
|
+
|
|
1016
|
+
const API_KEY = process.env.PINECONE_API_KEY || ""
|
|
1017
|
+
const INDEX = process.env.PINECONE_INDEX || ""
|
|
1018
|
+
const NAMESPACE = process.env.PINECONE_NAMESPACE || "default"
|
|
1019
|
+
|
|
1020
|
+
if (!API_KEY) throw new Error("PINECONE_API_KEY is required.")
|
|
1021
|
+
if (!INDEX) throw new Error("PINECONE_INDEX is required.")
|
|
1022
|
+
|
|
1023
|
+
const pc = new Pinecone({ apiKey: API_KEY })
|
|
1024
|
+
const ns = pc.index(INDEX).namespace(NAMESPACE)
|
|
1025
|
+
|
|
1026
|
+
export async function query(vector, topK) {
|
|
1027
|
+
const res = await ns.query({ vector, topK, includeMetadata: true })
|
|
1028
|
+
return (res.matches ?? []).map((m) => {
|
|
1029
|
+
const meta = m.metadata ?? {}
|
|
1030
|
+
return {
|
|
1031
|
+
id: m.id,
|
|
1032
|
+
score: m.score ?? 0,
|
|
1033
|
+
text: meta.text ?? "",
|
|
1034
|
+
title: meta.title ?? "Untitled",
|
|
1035
|
+
url: meta.url || undefined,
|
|
1036
|
+
documentId: meta.documentId ?? "",
|
|
1037
|
+
metadata: meta,
|
|
1038
|
+
}
|
|
1039
|
+
})
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
export async function list({ page = 1, limit = 20 } = {}) {
|
|
1043
|
+
// Collect all IDs via Pinecone's cursor-based pagination
|
|
1044
|
+
const allIds = []
|
|
1045
|
+
let paginationToken = undefined
|
|
1046
|
+
do {
|
|
1047
|
+
const res = await ns.listPaginated({ limit: 100, paginationToken })
|
|
1048
|
+
if (res.vectors) allIds.push(...res.vectors.map(v => v.id))
|
|
1049
|
+
paginationToken = res.pagination?.next
|
|
1050
|
+
} while (paginationToken)
|
|
1051
|
+
|
|
1052
|
+
const total = allIds.length
|
|
1053
|
+
const start = (page - 1) * limit
|
|
1054
|
+
const pageIds = allIds.slice(start, start + limit)
|
|
1055
|
+
|
|
1056
|
+
if (pageIds.length === 0) {
|
|
1057
|
+
return { documents: [], total, page, limit, totalPages: Math.ceil(total / limit) }
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
const fetched = await ns.fetch(pageIds)
|
|
1061
|
+
const documents = Object.values(fetched.records).map(r => {
|
|
1062
|
+
const meta = r.metadata ?? {}
|
|
1063
|
+
return {
|
|
1064
|
+
id: r.id,
|
|
1065
|
+
text: meta.text ?? "",
|
|
1066
|
+
title: meta.title ?? "Untitled",
|
|
1067
|
+
url: meta.url || undefined,
|
|
1068
|
+
documentId: meta.documentId ?? "",
|
|
1069
|
+
}
|
|
1070
|
+
})
|
|
1071
|
+
return { documents, total, page, limit, totalPages: Math.ceil(total / limit) }
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
export async function get(id) {
|
|
1075
|
+
const fetched = await ns.fetch([id])
|
|
1076
|
+
const r = fetched.records[id]
|
|
1077
|
+
if (!r) return null;
|
|
1078
|
+
const meta = r.metadata ?? {}
|
|
1079
|
+
return {
|
|
1080
|
+
id: r.id,
|
|
1081
|
+
text: meta.text ?? "",
|
|
1082
|
+
title: meta.title ?? "Untitled",
|
|
1083
|
+
url: meta.url || undefined,
|
|
1084
|
+
documentId: meta.documentId ?? "",
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
export async function add(docs) {
|
|
1089
|
+
const vectors = docs.map(d => ({
|
|
1090
|
+
id: d.id,
|
|
1091
|
+
values: d.vector,
|
|
1092
|
+
metadata: {
|
|
1093
|
+
...(d.metadata ?? {}),
|
|
1094
|
+
text: d.text,
|
|
1095
|
+
title: d.title,
|
|
1096
|
+
url: d.url || "",
|
|
1097
|
+
documentId: d.documentId,
|
|
1098
|
+
}
|
|
1099
|
+
}))
|
|
1100
|
+
await ns.upsert(vectors)
|
|
1101
|
+
return { success: true }
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
export async function remove(id) {
|
|
1105
|
+
await ns.deleteOne(id)
|
|
1106
|
+
return { success: true }
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
export async function update(id, doc) {
|
|
1110
|
+
await ns.update({
|
|
1111
|
+
id,
|
|
1112
|
+
values: doc.vector,
|
|
1113
|
+
setMetadata: {
|
|
1114
|
+
...(doc.metadata ?? {}),
|
|
1115
|
+
text: doc.text,
|
|
1116
|
+
title: doc.title,
|
|
1117
|
+
url: doc.url || "",
|
|
1118
|
+
documentId: doc.documentId,
|
|
1119
|
+
}
|
|
1120
|
+
})
|
|
1121
|
+
return { success: true }
|
|
1122
|
+
}
|
|
1123
|
+
`:`import * as lancedb from "@lancedb/lancedb"
|
|
1124
|
+
import path from "node:path"
|
|
1125
|
+
|
|
1126
|
+
const MODE = process.env.LANCEDB_MODE || "local"
|
|
1127
|
+
const IS_SERVERLESS = !!process.env.VERCEL || !!process.env.AWS_LAMBDA_FUNCTION_NAME
|
|
1128
|
+
const DEFAULT_DB_PATH = IS_SERVERLESS ? "/tmp/lancedb" : "./.larkup/lancedb"
|
|
1129
|
+
const DB_PATH = process.env.LANCEDB_PATH || DEFAULT_DB_PATH
|
|
1130
|
+
const URI = process.env.LANCEDB_URI || ""
|
|
1131
|
+
const API_KEY = process.env.LANCEDB_API_KEY || ""
|
|
1132
|
+
const S3_URI = process.env.LANCEDB_S3_URI || ""
|
|
1133
|
+
const TABLE = process.env.LANCEDB_TABLE || "documents"
|
|
1134
|
+
|
|
1135
|
+
if (IS_SERVERLESS && MODE === "local") {
|
|
1136
|
+
console.warn("[LanceDB] Running on serverless — using /tmp/lancedb. Data will NOT persist between invocations. Use S3-compatible storage or LanceDB Cloud for production.")
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
let _conn = null
|
|
1140
|
+
let _table = null
|
|
1141
|
+
|
|
1142
|
+
async function getConn() {
|
|
1143
|
+
if (_conn) return _conn
|
|
1144
|
+
if (MODE === "cloud") {
|
|
1145
|
+
if (!URI || !API_KEY) {
|
|
1146
|
+
throw new Error("LanceDB Cloud needs LANCEDB_URI and LANCEDB_API_KEY.")
|
|
1147
|
+
}
|
|
1148
|
+
_conn = await lancedb.connect(URI, { apiKey: API_KEY })
|
|
1149
|
+
} else if (MODE === "s3") {
|
|
1150
|
+
if (!S3_URI) {
|
|
1151
|
+
throw new Error("S3-compatible LanceDB needs LANCEDB_S3_URI.")
|
|
1152
|
+
}
|
|
1153
|
+
_conn = await lancedb.connect(S3_URI)
|
|
1154
|
+
} else {
|
|
1155
|
+
const abs = path.isAbsolute(DB_PATH) ? DB_PATH : path.join(process.cwd(), DB_PATH)
|
|
1156
|
+
_conn = await lancedb.connect(abs)
|
|
1157
|
+
}
|
|
1158
|
+
return _conn
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
async function getTable() {
|
|
1162
|
+
if (_table) return _table
|
|
1163
|
+
const conn = await getConn()
|
|
1164
|
+
const names = await conn.tableNames()
|
|
1165
|
+
if (names.includes(TABLE)) {
|
|
1166
|
+
_table = await conn.openTable(TABLE)
|
|
1167
|
+
return _table
|
|
1168
|
+
}
|
|
1169
|
+
return null
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
export async function query(vector, topK) {
|
|
1173
|
+
const t = await getTable()
|
|
1174
|
+
if (!t) return []
|
|
1175
|
+
const rows = await t.search(vector).limit(topK).toArray()
|
|
1176
|
+
return rows.map((row) => ({
|
|
1177
|
+
id: row.id,
|
|
1178
|
+
score: typeof row._distance === "number" ? 1 / (1 + row._distance) : 0,
|
|
1179
|
+
text: row.text,
|
|
1180
|
+
title: row.title,
|
|
1181
|
+
url: row.url || undefined,
|
|
1182
|
+
documentId: row.documentId,
|
|
1183
|
+
metadata: typeof row.metadata === "string" ? JSON.parse(row.metadata) : row.metadata,
|
|
1184
|
+
}))
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
export async function list({ page = 1, limit = 20 } = {}) {
|
|
1188
|
+
const t = await getTable()
|
|
1189
|
+
if (!t) return { documents: [], total: 0, page, limit, totalPages: 0 }
|
|
1190
|
+
const allRows = await t.query().select(["id", "text", "title", "url", "documentId"]).toArray()
|
|
1191
|
+
const total = allRows.length
|
|
1192
|
+
const start = (page - 1) * limit
|
|
1193
|
+
const pageRows = allRows.slice(start, start + limit)
|
|
1194
|
+
return {
|
|
1195
|
+
documents: pageRows.map((row) => ({
|
|
1196
|
+
id: row.id,
|
|
1197
|
+
text: row.text,
|
|
1198
|
+
title: row.title,
|
|
1199
|
+
url: row.url || undefined,
|
|
1200
|
+
documentId: row.documentId,
|
|
1201
|
+
})),
|
|
1202
|
+
total,
|
|
1203
|
+
page,
|
|
1204
|
+
limit,
|
|
1205
|
+
totalPages: Math.ceil(total / limit),
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
export async function get(id) {
|
|
1210
|
+
const t = await getTable()
|
|
1211
|
+
if (!t) return null
|
|
1212
|
+
const rows = await t.query().filter(\`id = '\${id}'\`).limit(1).toArray()
|
|
1213
|
+
if (!rows.length) return null;
|
|
1214
|
+
const row = rows[0];
|
|
1215
|
+
return { id: row.id, text: row.text, title: row.title, url: row.url || undefined, documentId: row.documentId }
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
export async function add(docs) {
|
|
1219
|
+
if (docs.length === 0) return { success: true }
|
|
1220
|
+
let t = await getTable()
|
|
1221
|
+
if (t) {
|
|
1222
|
+
await t.add(docs)
|
|
1223
|
+
} else {
|
|
1224
|
+
const conn = await getConn()
|
|
1225
|
+
const names = await conn.tableNames()
|
|
1226
|
+
if (names.includes(TABLE)) {
|
|
1227
|
+
t = await conn.openTable(TABLE)
|
|
1228
|
+
_table = t
|
|
1229
|
+
await t.add(docs)
|
|
1230
|
+
} else {
|
|
1231
|
+
t = await conn.createTable(TABLE, docs)
|
|
1232
|
+
_table = t
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
return { success: true }
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
export async function remove(id) {
|
|
1239
|
+
const t = await getTable()
|
|
1240
|
+
if (!t) return { success: true }
|
|
1241
|
+
await t.delete(\`id = '\${id}'\`)
|
|
1242
|
+
return { success: true }
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
export async function update(id, doc) {
|
|
1246
|
+
let t = await getTable()
|
|
1247
|
+
if (!t) {
|
|
1248
|
+
const conn = await getConn()
|
|
1249
|
+
t = await conn.createTable(TABLE, [doc])
|
|
1250
|
+
_table = t
|
|
1251
|
+
return { success: true }
|
|
1252
|
+
}
|
|
1253
|
+
await t.delete(\`id = '\${id}'\`)
|
|
1254
|
+
await t.add([doc])
|
|
1255
|
+
return { success: true }
|
|
1256
|
+
}`},{path:"demo.mjs",contents:`const BASE = process.env.RAG_SERVER_URL || "http://localhost:8080"
|
|
1257
|
+
|
|
1258
|
+
const question = process.argv.slice(2).join(" ") || "What is this corpus about?"
|
|
1259
|
+
|
|
1260
|
+
const res = await fetch(\`\${BASE}/query\`, {
|
|
1261
|
+
method: "POST",
|
|
1262
|
+
headers: { "Content-Type": "application/json" },
|
|
1263
|
+
body: JSON.stringify({ query: question }),
|
|
1264
|
+
})
|
|
1265
|
+
|
|
1266
|
+
const data = await res.json()
|
|
1267
|
+
if (!res.ok) {
|
|
1268
|
+
console.error("Error:", data.error)
|
|
1269
|
+
process.exit(1)
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
console.log(\`\\nQuery: \${data.query}\\n\`)
|
|
1273
|
+
for (const [i, hit] of data.hits.entries()) {
|
|
1274
|
+
console.log(\`#\${i + 1} [\${hit.score.toFixed(3)}] \${hit.title}\`)
|
|
1275
|
+
if (hit.url) console.log(\` \${hit.url}\`)
|
|
1276
|
+
console.log(\` \${hit.text.slice(0, 160).replace(/\\n/g, " ")}...\\n\`)
|
|
1277
|
+
}
|
|
1278
|
+
`},{path:"Dockerfile",contents:`FROM node:22-slim
|
|
1279
|
+
|
|
1280
|
+
WORKDIR /app
|
|
1281
|
+
|
|
1282
|
+
COPY package.json ./
|
|
1283
|
+
RUN npm install --omit=dev
|
|
1284
|
+
|
|
1285
|
+
COPY . .
|
|
1286
|
+
|
|
1287
|
+
ENV PORT=8080
|
|
1288
|
+
EXPOSE 8080
|
|
1289
|
+
|
|
1290
|
+
CMD ["node", "server.mjs"]
|
|
1291
|
+
`},{path:".dockerignore",contents:`node_modules
|
|
1292
|
+
npm-debug.log
|
|
1293
|
+
.env
|
|
1294
|
+
.git
|
|
1295
|
+
.DS_Store
|
|
1296
|
+
`},{path:"docker-compose.yml",contents:(b=a.projectName,m=s?` volumes:
|
|
1297
|
+
- larkup_data:/app/.larkup
|
|
1298
|
+
`:"",n=s?`
|
|
1299
|
+
volumes:
|
|
1300
|
+
larkup_data:
|
|
1301
|
+
driver: local
|
|
1302
|
+
`:"",`services:
|
|
1303
|
+
${b}:
|
|
1304
|
+
build: .
|
|
1305
|
+
container_name: ${b}
|
|
1306
|
+
restart: unless-stopped
|
|
1307
|
+
ports:
|
|
1308
|
+
- "8080:8080"
|
|
1309
|
+
env_file:
|
|
1310
|
+
- .env
|
|
1311
|
+
healthcheck:
|
|
1312
|
+
test: ["CMD", "node", "-e", "fetch('http://localhost:8080/health').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
|
|
1313
|
+
interval: 30s
|
|
1314
|
+
timeout: 10s
|
|
1315
|
+
retries: 3
|
|
1316
|
+
start_period: 15s
|
|
1317
|
+
${m}${n}`)},{path:"vercel.json",contents:`{
|
|
1318
|
+
"$schema": "https://openapi.vercel.sh/vercel.json",
|
|
1319
|
+
"builds": [{ "src": "server.mjs", "use": "@vercel/node" }],
|
|
1320
|
+
"routes": [
|
|
1321
|
+
{ "handle": "filesystem" },
|
|
1322
|
+
{ "src": "/(.*)", "dest": "server.mjs" }
|
|
1323
|
+
]
|
|
1324
|
+
}
|
|
1325
|
+
`},{path:".env.example",contents:x.envVars.map(a=>`# ${a.help}${a.required?"":" (optional)"}
|
|
1326
|
+
${a.key}=`).join("\n")},{path:".env",contents:z},{path:".gitignore",contents:"node_modules\n.env\n.DS_Store\n"},{path:"README.md",contents:(o=(0,d.jX)(a.vectorStore),p="assistant"===a.runtimeProfile,q=Object.entries(x.dependencies).map(([a,b])=>`- \`${a}@${b}\``).join("\n"),`# ${a.projectName}
|
|
1327
|
+
|
|
1328
|
+
A Larkup **${p?"Agent Server":"Knowledge Server"}** — ${p?"AI SDK-compatible agent plus RAG knowledge base.":"lightweight RAG retrieval API."}
|
|
1329
|
+
|
|
1330
|
+
- **Vector store:** ${o.label}
|
|
1331
|
+
- **Embedding model:** ${a.embeddingModelId}
|
|
1332
|
+
- **Index type:** ${a.indexType}
|
|
1333
|
+
- **Default top-k:** ${a.topK}
|
|
1334
|
+
|
|
1335
|
+
## Dependencies
|
|
1336
|
+
${q}
|
|
1337
|
+
|
|
1338
|
+
## Run locally
|
|
1339
|
+
\`\`\`bash
|
|
1340
|
+
npm install
|
|
1341
|
+
cp .env.example .env
|
|
1342
|
+
node server.mjs
|
|
1343
|
+
\`\`\`
|
|
1344
|
+
|
|
1345
|
+
Then query it:
|
|
1346
|
+
\`\`\`bash
|
|
1347
|
+
node demo.mjs "your question here"
|
|
1348
|
+
# or
|
|
1349
|
+
curl -X POST http://localhost:8080/query \\
|
|
1350
|
+
-H "Content-Type: application/json" \\
|
|
1351
|
+
-H "Authorization: Bearer <your-retrieval-key>" \\
|
|
1352
|
+
-d '{"query":"your question","topK":${a.topK}}'
|
|
1353
|
+
\`\`\`
|
|
1354
|
+
|
|
1355
|
+
## Authentication
|
|
1356
|
+
|
|
1357
|
+
Set \`SERVER_API_KEYS\` with scoped keys:
|
|
1358
|
+
\`\`\`bash
|
|
1359
|
+
SERVER_API_KEYS=retrieval:rk_your_key,ingest:ik_your_key,admin:ak_your_key
|
|
1360
|
+
\`\`\`
|
|
1361
|
+
|
|
1362
|
+
| Scope | Can do |
|
|
1363
|
+
|-------|--------|
|
|
1364
|
+
| \`retrieval\` | Query, chat |
|
|
1365
|
+
| \`ingest\` | Query, chat, add/update/delete documents, scrape, media |
|
|
1366
|
+
| \`admin\` | Everything including corpus export |
|
|
1367
|
+
|
|
1368
|
+
A single key without a scope prefix is treated as \`admin\` for backward compatibility.
|
|
1369
|
+
|
|
1370
|
+
## Deploy
|
|
1371
|
+
|
|
1372
|
+
### Docker / VPS
|
|
1373
|
+
\`\`\`bash
|
|
1374
|
+
docker compose up -d --build
|
|
1375
|
+
\`\`\`
|
|
1376
|
+
|
|
1377
|
+
Data persists in a Docker named volume (\`larkup_data\`).
|
|
1378
|
+
|
|
1379
|
+
### Vercel
|
|
1380
|
+
\`\`\`bash
|
|
1381
|
+
vercel deploy
|
|
1382
|
+
\`\`\`
|
|
1383
|
+
|
|
1384
|
+
> **Important:** Vercel uses ephemeral storage. You must configure S3-compatible
|
|
1385
|
+
> (\`LANCEDB_MODE=s3\`) or LanceDB Cloud (\`LANCEDB_MODE=cloud\`) storage for
|
|
1386
|
+
> production. Local LanceDB data will not persist between invocations.
|
|
1387
|
+
|
|
1388
|
+
## API
|
|
1389
|
+
- \`GET /health\` → \`{ ok: true, type: "knowledge-server" }\`
|
|
1390
|
+
- \`GET /readiness\` → \`{ ready: true, vectorStore: "connected" }\`
|
|
1391
|
+
- \`GET /reference\` → Scalar API docs UI
|
|
1392
|
+
- \`GET /models\` → available chat providers and models
|
|
1393
|
+
- \`POST /query\` → \`{ query, hits: [...] }\` (retrieval scope)
|
|
1394
|
+
- \`POST /chat\` → ${p?"AI SDK UI message stream (retrieval scope)":"SSE stream (retrieval scope)"}
|
|
1395
|
+
${p?"- `GET /agent` → Agent Runtime details\n- `GET /agent/tools` → loaded Agent tools\n- `GET /agent/capabilities` → grouped Agent capabilities\n- `GET /agent/configuration` → saved prompt and skills (admin scope)\n- `GET /agent/sandbox` → sandbox provider and readiness (admin scope)\n- `POST /agent/chat` → AI SDK UI message stream\n- `POST /v1/chat/completions` → OpenAI-compatible Agent chat\n":""}
|
|
1396
|
+
- \`GET /documents\` → list documents (ingest scope)
|
|
1397
|
+
- \`GET /documents/:id\` → get a document (ingest scope)
|
|
1398
|
+
- \`POST /documents\` → add a document (ingest scope)
|
|
1399
|
+
- \`PUT /documents/:id\` → update a document (ingest scope)
|
|
1400
|
+
- \`DELETE /documents/:id\` → delete a document (ingest scope)
|
|
1401
|
+
- \`POST /scrape\` → scrape and ingest URL (ingest scope)
|
|
1402
|
+
- \`GET /corpus/summary\` → corpus stats (admin scope)
|
|
1403
|
+
- \`POST /corpus\` → corpus documents (admin scope)
|
|
1404
|
+
- \`POST /corpus/export\` → export as CSV/JSONL (admin scope)
|
|
1405
|
+
`)}].map(a=>{var b;return{...a,language:(b=a.path).endsWith(".json")?"json":b.endsWith(".mjs")||b.endsWith(".js")?"javascript":b.endsWith(".md")?"markdown":b.endsWith("Dockerfile")?"dockerfile":b.endsWith(".yml")||b.endsWith(".yaml")?"yaml":"text"}});try{let a=c(73024),b=c(76760),d=b.resolve(process.cwd(),"public/favicon.ico");if(a.existsSync(d))A.push({path:"public/favicon.ico",contents:a.readFileSync(d).toString("base64"),language:"ico",encoding:"base64"});else{let c=b.resolve(process.cwd(),"apps/web/public/favicon.ico");a.existsSync(c)&&A.push({path:"public/favicon.ico",contents:a.readFileSync(c).toString("base64"),language:"ico",encoding:"base64"})}}catch(a){}return x.files=A,x}},22462:(a,b,c)=>{c.d(b,{KB:()=>f,jX:()=>e});let d={lancedb:{id:"lancedb",label:"LanceDB",description:"Embedded vector database for local development, LanceDB Cloud, or persistent S3-compatible storage such as Cloudflare R2.",runtime:"both",installStatus:"installed",docsUrl:"https://lancedb.github.io/lancedb/",serverDependencies:{"@lancedb/lancedb":"^0.30.0"},fields:[{key:"mode",label:"Mode",type:"select",required:!0,defaultValue:"local",help:"Use a local disk, LanceDB Cloud, or an S3-compatible bucket for persistent serverless deployments.",options:[{label:"Local (on-disk)",value:"local"},{label:"S3-compatible (Vercel / R2 / S3)",value:"s3"},{label:"Cloud",value:"cloud"}]},{key:"dbPath",label:"Database path",type:"path",required:!0,defaultValue:"./.larkup/lancedb",placeholder:"./.larkup/lancedb",help:"Directory where the LanceDB tables are stored.",showWhen:{key:"mode",equals:["local"]}},{key:"s3Uri",label:"Database URI",type:"text",required:!0,placeholder:"s3://my-bucket/larkup/my-server",help:"A dedicated, private bucket prefix for LanceDB table files. This is persistent across Vercel invocations.",showWhen:{key:"mode",equals:["s3"]}},{key:"s3Endpoint",label:"S3 endpoint",type:"text",required:!1,placeholder:"https://<account-id>.r2.cloudflarestorage.com",help:"Required for Cloudflare R2 and other S3-compatible providers. Leave blank for AWS S3.",showWhen:{key:"mode",equals:["s3"]}},{key:"s3Region",label:"Region",type:"text",required:!0,defaultValue:"auto",placeholder:"auto",help:"Use “auto” for Cloudflare R2, or your bucket region for AWS S3.",showWhen:{key:"mode",equals:["s3"]}},{key:"s3AccessKeyId",label:"Access key ID",type:"password",required:!0,secret:!0,help:"Use an object read/write credential restricted to this bucket.",showWhen:{key:"mode",equals:["s3"]}},{key:"s3SecretAccessKey",label:"Secret access key",type:"password",required:!0,secret:!0,help:"Stored as a deployment environment variable; never expose it in the browser.",showWhen:{key:"mode",equals:["s3"]}},{key:"uri",label:"Cloud URI",type:"text",required:!0,placeholder:"db://my-database",help:"Your LanceDB Cloud database URI.",showWhen:{key:"mode",equals:["cloud"]}},{key:"apiKey",label:"API key",type:"password",required:!0,secret:!0,placeholder:"sk_...",help:"LanceDB Cloud API key. Stored as an env var in the generated server.",showWhen:{key:"mode",equals:["cloud"]}},{key:"tableName",label:"Table name",type:"text",required:!0,defaultValue:"documents",help:"The table that holds your embedded chunks."}]},pinecone:{id:"pinecone",label:"Pinecone",description:"Fully-managed cloud vector database. Cloud-only — requires an API key and an existing index.",runtime:"cloud",installStatus:"installed",docsUrl:"https://docs.pinecone.io/",serverDependencies:{"@pinecone-database/pinecone":"^6.0.0"},fields:[{key:"apiKey",label:"API key",type:"password",required:!0,secret:!0,placeholder:"pcsk_...",help:"Pinecone API key. Stored as an env var in the generated server."},{key:"indexName",label:"Index name",type:"text",required:!0,placeholder:"rag-index",help:"Name of the Pinecone index to upsert into / query. For hybrid/lexical mode this index must use the 'dotproduct' metric."},{key:"namespace",label:"Namespace",type:"text",required:!1,placeholder:"default",help:"Optional namespace to isolate this dataset within the index."},{key:"sparseModel",label:"Sparse model",type:"text",required:!0,defaultValue:"pinecone-sparse-english-v0",help:"Pinecone-hosted sparse model used to generate keyword vectors via the Inference API. Both dense and sparse vectors are stored in the same index.",showWhenIndexType:["lexical","hybrid"]}]},weaviate:{id:"weaviate",label:"Weaviate",description:"Open-source AI-native vector database with built-in hybrid search, BM25, and multi-tenancy.",runtime:"both",installStatus:"coming-soon",docsUrl:"https://weaviate.io/developers/weaviate",serverDependencies:{weaviate:"^3.0.0"},fields:[{key:"host",label:"Host URL",type:"text",required:!0,placeholder:"https://my-cluster.weaviate.network",help:"Weaviate Cloud URL or self-hosted host address."},{key:"apiKey",label:"API key",type:"password",required:!1,secret:!0,placeholder:"weaviate-api-key",help:"Weaviate Cloud API key (optional for self-hosted)."},{key:"className",label:"Collection name",type:"text",required:!0,defaultValue:"Documents",help:"The Weaviate collection (class) that holds your embedded chunks."}]},qdrant:{id:"qdrant",label:"Qdrant",description:"High-performance vector search engine with rich filtering, built for production-scale RAG.",runtime:"both",installStatus:"coming-soon",docsUrl:"https://qdrant.tech/documentation/",serverDependencies:{"@qdrant/js-client-rest":"^1.9.0"},fields:[{key:"url",label:"Host URL",type:"text",required:!0,placeholder:"http://localhost:6333",help:"Qdrant server URL (local or Qdrant Cloud endpoint)."},{key:"apiKey",label:"API key",type:"password",required:!1,secret:!0,placeholder:"qdrant-api-key",help:"Qdrant Cloud API key (leave blank for local)."},{key:"collectionName",label:"Collection name",type:"text",required:!0,defaultValue:"documents",help:"Qdrant collection to upsert into and query."}]},chroma:{id:"chroma",label:"Chroma",description:"Open-source, developer-friendly embedding database. Great for rapid local prototyping.",runtime:"both",installStatus:"installable",docsUrl:"https://docs.trychroma.com/",serverDependencies:{chromadb:"^1.9.0"},fields:[{key:"mode",label:"Mode",type:"select",required:!0,defaultValue:"server",help:"Server connects to a self-hosted Chroma instance. Cloud connects to Chroma Cloud.",options:[{label:"Server (Self-hosted)",value:"server"},{label:"Cloud (Chroma Cloud)",value:"cloud"}]},{key:"host",label:"Server URL",type:"text",required:!0,placeholder:"http://localhost:8000",defaultValue:"http://localhost:8000",help:"Chroma server URL (local Docker or remote).",showWhen:{key:"mode",equals:["server"]}},{key:"authToken",label:"Auth Token",type:"password",required:!1,secret:!0,placeholder:"chroma-token",help:"Optional static auth token for Chroma server.",showWhen:{key:"mode",equals:["server"]}},{key:"apiKey",label:"API Key",type:"password",required:!0,secret:!0,placeholder:"sk_...",help:"Chroma Cloud API Key.",showWhen:{key:"mode",equals:["cloud"]}},{key:"tenant",label:"Tenant",type:"text",required:!0,defaultValue:"default_tenant",help:"Tenant name for Chroma Cloud.",showWhen:{key:"mode",equals:["cloud"]}},{key:"database",label:"Database",type:"text",required:!0,defaultValue:"default_database",help:"Database name for Chroma Cloud.",showWhen:{key:"mode",equals:["cloud"]}},{key:"collectionName",label:"Collection name",type:"text",required:!0,defaultValue:"documents",help:"Chroma collection to store and retrieve embeddings."}]},pgvector:{id:"pgvector",label:"pgvector",description:"PostgreSQL extension for vector similarity search. Self-host vectors alongside your relational data.",runtime:"both",installStatus:"coming-soon",docsUrl:"https://github.com/pgvector/pgvector",serverDependencies:{pg:"^8.11.0",pgvector:"^0.2.0"},fields:[{key:"connectionString",label:"Connection string",type:"password",required:!0,secret:!0,placeholder:"postgresql://user:pass@localhost:5432/db",help:"Full PostgreSQL connection string."},{key:"tableName",label:"Table name",type:"text",required:!0,defaultValue:"embeddings",help:"The table used to store vector embeddings. Created automatically if absent."}]},supabase:{id:"supabase",label:"Supabase",description:"Postgres-backed vector store via the pgvector extension with Supabase's managed infrastructure.",runtime:"cloud",installStatus:"coming-soon",docsUrl:"https://supabase.com/docs/guides/ai",serverDependencies:{"@supabase/supabase-js":"^2.43.0"},fields:[{key:"url",label:"Project URL",type:"text",required:!0,placeholder:"https://xyz.supabase.co",help:"Your Supabase project URL."},{key:"serviceKey",label:"Service role key",type:"password",required:!0,secret:!0,placeholder:"eyJhbGci...",help:"Supabase service_role key (not the anon key). Stored as an env var."},{key:"tableName",label:"Table name",type:"text",required:!0,defaultValue:"documents",help:"Supabase table with a vector column for embeddings."}]}};function e(a){return d[a]}function f(a,b,c){let d={};for(let e of a.fields.filter(a=>{if(a.showWhen){let c=b[a.showWhen.key]??"";if(!a.showWhen.equals.includes(c))return!1}return!a.showWhenIndexType||!c||!!a.showWhenIndexType.includes(c)}))e.required&&!b[e.key]?.trim()&&(d[e.key]=`${e.label} is required`);return d}Object.values(d)},25098:(a,b,c)=>{c.d(b,{GX:()=>B,JH:()=>F,Nh:()=>z,fy:()=>y,me:()=>w,od:()=>A,uT:()=>E});var d=c(77598),e=c(73024),f=c(76760),g=c.n(f),h=c(77459),i=c(26043);let j="__larkup_secret_set__",k=/^(authorization|proxy-authorization|cookie|set-cookie)$/i,l=/(token|secret|api[-_]?key|password|credential)/i,m=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;function n(a){return g().join(a,"mcp-connections.json")}async function o(){let a=await (0,i.getProjectDataDir)();if(!a)return[];try{let b=JSON.parse(await e.promises.readFile(n(a),"utf8"));return Array.isArray(b)?b.filter(p).map(a=>({...a,transport:"sse"===a.transport?"sse":"http",connectionType:"proxy"===a.connectionType?"proxy":"direct",proxyAuthHeader:a.proxyAuthHeader??"Authorization"})):[]}catch{return[]}}function p(a){return!!a&&"object"==typeof a&&"string"==typeof a.id&&"string"==typeof a.name&&"string"==typeof a.url&&(void 0===a.transport||"http"===a.transport||"sse"===a.transport)&&(void 0===a.connectionType||"direct"===a.connectionType||"proxy"===a.connectionType)&&(void 0===a.proxyUrl||"string"==typeof a.proxyUrl)&&(void 0===a.proxyAuthToken||"string"==typeof a.proxyAuthToken)&&(void 0===a.proxyAuthHeader||"string"==typeof a.proxyAuthHeader)&&!!a.headers&&"object"==typeof a.headers&&"boolean"==typeof a.enabled&&"boolean"==typeof a.enabledForLocalChat&&"string"==typeof a.createdAt&&"string"==typeof a.updatedAt}async function q(a){let b=await (0,i.requireProjectDataDir)();await e.promises.writeFile(n(b),JSON.stringify(a,null,2),"utf8")}function r(a){let b;if("string"!=typeof a||!a.trim())throw Error("MCP URL is required.");try{b=new URL(a.trim())}catch{throw Error("MCP URL must be a valid HTTP(S) URL.")}if(!["http:","https:"].includes(b.protocol)||b.username||b.password)throw Error("MCP URL must be an HTTP(S) URL without embedded credentials.");return b.toString()}function s(a,b){if("string"!=typeof a||!m.test(a.trim()))throw Error(`${b} must be a valid HTTP header name.`);return a.trim()}function t({connectionType:a,proxyUrl:b,proxyAuthHeader:c}){if("proxy"===a){if(void 0===b)throw Error("Proxy URL is required for proxy MCP connections.");r(b),s(c??"Authorization","Proxy auth header")}}function u(a){return{...a,proxyAuthToken:a.proxyAuthToken?j:a.proxyAuthToken,headers:Object.fromEntries(Object.entries(a.headers).map(([a,b])=>[a,(k.test(a)||l.test(a))&&b?j:b]))}}function v(a,b){let c=Object.fromEntries(Object.entries(void 0===b.headers?a.headers:function(a){if(void 0===a)return{};if(!a||"object"!=typeof a||Array.isArray(a))throw Error("MCP headers must be an object.");let b={};for(let[c,d]of Object.entries(a)){if(!m.test(c))throw Error(`Invalid MCP header name: ${c}`);if("string"!=typeof d)throw Error(`MCP header "${c}" must be text.`);if(/[\r\n]/.test(d))throw Error(`MCP header "${c}" cannot contain a newline.`);b[c]=d}return b}(b.headers)).map(([b,c])=>{if(c!==j)return[b,c];let d=Object.entries(a.headers).find(([a])=>a.toLowerCase()===b.toLowerCase())?.[1];return[b,d??""]})),d=void 0===b.connectionType?a.connectionType:function(a){if(void 0===a||"direct"===a)return"direct";if("proxy"===a)return"proxy";throw Error("MCP connection type must be Direct or Proxy.")}(b.connectionType),e=void 0===b.proxyUrl?a.proxyUrl:function(a){if("string"!=typeof a||a.trim())return r(a)}(b.proxyUrl),f=void 0===b.proxyAuthHeader?a.proxyAuthHeader??"Authorization":s(b.proxyAuthHeader,"Proxy auth header"),g=void 0===b.proxyAuthToken?a.proxyAuthToken:function(a){if(void 0!==a){if("string"!=typeof a)throw Error("Proxy auth token must be text.");if(/[\r\n]/.test(a))throw Error("Proxy auth token cannot contain a newline.");return a}}(b.proxyAuthToken),h=g===j?a.proxyAuthToken:g;return t({connectionType:d,proxyUrl:e,proxyAuthHeader:f}),{...a,name:void 0===b.name?a.name:"string"==typeof b.name&&b.name.trim()?b.name.trim().slice(0,120):(()=>{throw Error("MCP name is required.")})(),url:void 0===b.url?a.url:r(b.url),transport:void 0===b.transport?a.transport:function(a){if(void 0===a||"http"===a)return"http";if("sse"===a)return"sse";throw Error("MCP transport must be Streamable HTTP or SSE.")}(b.transport),connectionType:d,proxyUrl:e,proxyAuthToken:h,proxyAuthHeader:f,headers:c,enabled:void 0===b.enabled?a.enabled:!!b.enabled,enabledForLocalChat:void 0===b.enabledForLocalChat?a.enabledForLocalChat:!!b.enabledForLocalChat,updatedAt:new Date().toISOString()}}async function w(){return(await o()).map(u)}async function x(a){return(await o()).find(b=>b.id===a)??null}async function y(){return(await o()).filter(a=>a.enabled)}async function z(a){let b=new Date().toISOString(),c=v({id:(0,d.randomUUID)(),name:"",url:"",transport:"http",connectionType:"direct",proxyAuthHeader:"Authorization",headers:{},enabled:!0,enabledForLocalChat:!1,createdAt:b,updatedAt:b},a),e=await o();return e.push(c),await q(e),u(c)}async function A(a,b){let c=await o(),d=c.findIndex(b=>b.id===a);if(-1===d)return null;let e=v(c[d],b);return c[d]=e,await q(c),u(e)}async function B(a){let b=await o(),c=b.filter(b=>b.id!==a);return c.length!==b.length&&(await q(c),!0)}function C(a){if("proxy"!==a.connectionType)return{type:a.transport,url:a.url,headers:a.headers};t(a);let b=a.proxyAuthHeader??"Authorization",c=a.proxyAuthToken?{...Object.fromEntries(Object.entries(a.headers).filter(([a])=>a.toLowerCase()!==b.toLowerCase())),[b]:a.proxyAuthToken}:a.headers;return{type:a.transport,url:a.proxyUrl,headers:c}}async function D(a){let b=await (0,h.MT)({transport:C(a)});try{let c=await b.tools();return{tools:Object.fromEntries(Object.entries(c).map(([b,c])=>[`mcp_${a.id.replace(/-/g,"").slice(0,10)}_${b}`,c])),close:()=>b.close()}}catch(a){throw await b.close(),a}}async function E(a={}){let b=a.connectionIds?new Set(a.connectionIds):null,c=(await o()).filter(c=>c.enabled&&(a.forLocalChat?c.enabledForLocalChat:b?.has(c.id))),d=[],e={},f=[],g=[];for(let a of c)try{let b=await D(a);d.push(b),Object.assign(e,b.tools),f.push(a.id)}catch(b){g.push({connectionId:a.id,message:b instanceof Error?b.message:String(b)})}return{tools:e,connectedIds:f,failures:g,close:async()=>{await Promise.allSettled(d.map(a=>a.close()))}}}async function F(a){let b=await x(a);if(!b)throw Error("MCP connection not found.");let c=await (0,h.MT)({transport:C(b)});try{return{toolCount:Object.keys(await c.tools()).length}}finally{await c.close()}}},46066:(a,b,c)=>{c.d(b,{EMBEDDING_DIMENSIONS:()=>d,Wg:()=>e,eq:()=>f,getEmbeddingModel:()=>h,vx:()=>g});let d={"openai/text-embedding-3-small":{dimensions:1536,maxInputTokens:8191},"openai/text-embedding-3-large":{dimensions:3072,maxInputTokens:8191},"openai/text-embedding-ada-002":{dimensions:1536,maxInputTokens:8191},"google/gemini-embedding-2":{dimensions:3072,maxInputTokens:8192},"google/gemini-embedding-001":{dimensions:3072,maxInputTokens:2048},"cohere/embed-english-v3.0":{dimensions:1024,maxInputTokens:512},"cohere/embed-multilingual-v3.0":{dimensions:1024,maxInputTokens:512},"voyage/voyage-3":{dimensions:1024,maxInputTokens:32e3},"voyage/voyage-3-lite":{dimensions:512,maxInputTokens:32e3},"voyage/voyage-code-3":{dimensions:1024,maxInputTokens:32e3},"mistral/mistral-embed":{dimensions:1024,maxInputTokens:8192},"jina/jina-embeddings-v3":{dimensions:1024,maxInputTokens:8192},"jina/jina-clip-v2":{dimensions:1024,maxInputTokens:8192},"nomic/nomic-embed-text-v1.5":{dimensions:768,maxInputTokens:8192}};function e(a){let b=d[a.id],c=a.id.split("/")[0]||a.owned_by;return{id:a.id,label:a.name||a.id.split("/").slice(1).join("/"),provider:c,dimensions:b?.dimensions??a.context_window??768,maxInputTokens:b?.maxInputTokens??a.max_tokens??2048,description:a.description||""}}function f(a,b){return"vercel_ai_gateway"===b?a:a.filter(a=>a.provider?.toLowerCase()===b.toLowerCase())}let g=[{id:"openai/text-embedding-3-small",label:"text-embedding-3-small",provider:"openai",dimensions:1536,maxInputTokens:8191,description:"Fast, cheap, strong general-purpose default."},{id:"openai/text-embedding-3-large",label:"text-embedding-3-large",provider:"openai",dimensions:3072,maxInputTokens:8191,description:"Highest quality OpenAI embeddings, larger vectors."},{id:"openai/text-embedding-ada-002",label:"text-embedding-ada-002",provider:"openai",dimensions:1536,maxInputTokens:8191,description:"Legacy model — kept for backward compatibility."},{id:"google/gemini-embedding-2",label:"gemini-embedding-2",provider:"google",dimensions:3072,maxInputTokens:8192,description:"Current Gemini embedding model with multilingual retrieval support."},{id:"google/gemini-embedding-001",label:"gemini-embedding-001",provider:"google",dimensions:3072,maxInputTokens:2048,description:"Gemini embedding 001."},{id:"cohere/embed-english-v3.0",label:"embed-english-v3.0",provider:"cohere",dimensions:1024,maxInputTokens:512,description:"Tuned for retrieval; great for English-heavy corpora."},{id:"cohere/embed-multilingual-v3.0",label:"embed-multilingual-v3.0",provider:"cohere",dimensions:1024,maxInputTokens:512,description:"100+ language multilingual retrieval embeddings."},{id:"voyage/voyage-3",label:"voyage-3",provider:"voyage",dimensions:1024,maxInputTokens:32e3,description:"Voyage's best general-purpose retrieval model."},{id:"voyage/voyage-3-lite",label:"voyage-3-lite",provider:"voyage",dimensions:512,maxInputTokens:32e3,description:"Optimized for latency and cost with strong performance."},{id:"voyage/voyage-code-3",label:"voyage-code-3",provider:"voyage",dimensions:1024,maxInputTokens:32e3,description:"Specialized for code retrieval tasks."},{id:"mistral/mistral-embed",label:"mistral-embed",provider:"mistral",dimensions:1024,maxInputTokens:8192,description:"Mistral's efficient embedding model for retrieval."},{id:"jina/jina-embeddings-v3",label:"jina-embeddings-v3",provider:"jina",dimensions:1024,maxInputTokens:8192,description:"Multilingual, task-specific embeddings from Jina AI."},{id:"jina/jina-clip-v2",label:"jina-clip-v2",provider:"jina",dimensions:1024,maxInputTokens:8192,description:"Multimodal embeddings for text and images."},{id:"nomic/nomic-embed-text-v1.5",label:"nomic-embed-text-v1.5",provider:"nomic",dimensions:768,maxInputTokens:8192,description:"Open-source, highly capable text embeddings."}];function h(a){return g.find(b=>b.id===a)}},52249:(a,b,c)=>{c.d(b,{II:()=>i,Pm:()=>d,iE:()=>h,oK:()=>g,sZ:()=>e,yo:()=>f});let d="^7.0.54",e={"@ai-sdk/cohere":"^4.0.22","@ai-sdk/deepseek":"^3.0.23","@ai-sdk/gateway":"^4.0.42","@ai-sdk/google":"^4.0.35","@ai-sdk/mistral":"^4.0.24","@ai-sdk/openai":"^4.0.31","@ai-sdk/openai-compatible":"^3.0.24"};function f(a){if(a.chatProvider)return a.chatProvider;if(a.chatModelId?.startsWith("custom:"))return"custom";let b=a.chatModelId?.split("/",1)[0];return b&&["openai","google","cohere","mistral","deepseek"].includes(b)?b:a.embeddingProvider||"openai"}function g(a,b=f(a)){if(a.chatModelId)return a.chatModelId;if("custom"===b&&a.customChatModels?.[0])return`custom:${a.customChatModels[0].modelName}`;let c={openai:"openai/gpt-4o-mini",google:"google/gemini-3.6-flash",cohere:"cohere/command-r-plus",mistral:"mistral/mistral-large-latest",deepseek:"deepseek/deepseek-chat",vercel_ai_gateway:"openai/gpt-4o-mini"};return c[b]||c.openai}function h(a){let b="assistant"===a.runtimeProfile,c=f(a),d=g(a,c),e=d.startsWith("custom:")?d.slice(7):d,h=function(a,b=""){switch(a){case"google":return`import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
1406
|
+
const provider = createGoogleGenerativeAI({ apiKey: CHAT_API_KEY });
|
|
1407
|
+
function createConfiguredModel(modelId) {
|
|
1408
|
+
return provider(modelNameFor(modelId));
|
|
1409
|
+
}`;case"cohere":return`import { createCohere } from "@ai-sdk/cohere";
|
|
1410
|
+
const provider = createCohere({ apiKey: CHAT_API_KEY });
|
|
1411
|
+
function createConfiguredModel(modelId) {
|
|
1412
|
+
return provider(modelNameFor(modelId));
|
|
1413
|
+
}`;case"mistral":return`import { createMistral } from "@ai-sdk/mistral";
|
|
1414
|
+
const provider = createMistral({ apiKey: CHAT_API_KEY });
|
|
1415
|
+
function createConfiguredModel(modelId) {
|
|
1416
|
+
return provider(modelNameFor(modelId));
|
|
1417
|
+
}`;case"deepseek":return`import { createDeepSeek } from "@ai-sdk/deepseek";
|
|
1418
|
+
const provider = createDeepSeek({ apiKey: CHAT_API_KEY });
|
|
1419
|
+
function createConfiguredModel(modelId) {
|
|
1420
|
+
return provider(modelNameFor(modelId));
|
|
1421
|
+
}`;case"vercel_ai_gateway":return`import { createGateway } from "@ai-sdk/gateway";
|
|
1422
|
+
const provider = createGateway({ apiKey: CHAT_API_KEY });
|
|
1423
|
+
function createConfiguredModel(modelId) {
|
|
1424
|
+
return provider(modelId);
|
|
1425
|
+
}`;case"custom":return`import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
|
|
1426
|
+
const provider = createOpenAICompatible({
|
|
1427
|
+
name: "larkup-custom",
|
|
1428
|
+
baseURL: process.env.CHAT_BASE_URL || ${JSON.stringify(b)},
|
|
1429
|
+
apiKey: CHAT_API_KEY,
|
|
1430
|
+
});
|
|
1431
|
+
function createConfiguredModel(modelId) {
|
|
1432
|
+
return provider.chatModel(modelNameFor(modelId));
|
|
1433
|
+
}`;default:return`import { createOpenAI } from "@ai-sdk/openai";
|
|
1434
|
+
const provider = createOpenAI({ apiKey: CHAT_API_KEY });
|
|
1435
|
+
function createConfiguredModel(modelId) {
|
|
1436
|
+
return provider(modelNameFor(modelId));
|
|
1437
|
+
}`}}(c,(a.customChatModels??[]).find(a=>a.modelName===e)?.baseUrl),i=(a.skills??[]).filter(a=>!1!==a.enabled),j=[{id:"searchKnowledgeBase",name:"Semantic Search",description:"Search the RAG knowledge base for text."},{id:"queryTabularData",name:"Tabular Data Query",description:"Filter, group, and aggregate tabular data."},{id:"generateVisualization",name:"Generate Charts",description:"Create interactive charts from Assistant results."},{id:"executeAnalysis",name:"Python Sandbox",description:"Execute Python code for complex analysis."},{id:"getIndexedData",name:"Indexed Data",description:"List and filter source documents."},{id:"analyzeCorpusWithCode",name:"Corpus Analysis",description:"Run code against the full indexed corpus."},{id:"fillDocumentForm",name:"Form Filler",description:"Fill forms in the active document."}].filter(b=>0===(a.enabledTools??[]).length||a.enabledTools?.includes(b.id)),k=i.map(a=>{let b=a.content?.slice(0,12e3)??`Remote skill reference: ${a.url}`;return`## ${a.name}
|
|
1438
|
+
${a.description}
|
|
1439
|
+
${b??""}`}).join("\n\n"),l=a.systemPrompt||"You are a helpful assistant grounded in the supplied knowledge base.";return`import { streamText${b?", stepCountIs, tool":""} } from "ai";
|
|
1440
|
+
${b?'import { z } from "zod";\nimport { createMCPClient } from "@ai-sdk/mcp";\nimport { SandboxManager } from "@larkup/sandbox";\n':""}import { embedQuery } from "./embed.mjs";
|
|
1441
|
+
import { list as storeList, query as storeQuery } from "./store.mjs";
|
|
1442
|
+
|
|
1443
|
+
const CHAT_API_KEY = process.env.CHAT_API_KEY || process.env.OPENAI_API_KEY || "";
|
|
1444
|
+
const CHAT_PROVIDER = ${JSON.stringify(c)};
|
|
1445
|
+
const CHAT_MODEL = process.env.CHAT_MODEL || ${JSON.stringify(d)};
|
|
1446
|
+
function modelNameFor(modelId) {
|
|
1447
|
+
return modelId.startsWith("custom:")
|
|
1448
|
+
? modelId.slice("custom:".length)
|
|
1449
|
+
: modelId.includes("/")
|
|
1450
|
+
? modelId.split("/").slice(1).join("/")
|
|
1451
|
+
: modelId;
|
|
1452
|
+
}
|
|
1453
|
+
const DEFAULT_LARKUP_PROMPT = \`You are an advanced AI Agent powered by Larkup.
|
|
1454
|
+
Before answering any user query, you MUST aggressively utilize your available tools to gather the most accurate and up-to-date information. Do not rely solely on your pre-trained memory.
|
|
1455
|
+
1. Use your knowledge base tools to query local indexed data.
|
|
1456
|
+
2. Use your MCP (Model Context Protocol) tools to query connected external systems.
|
|
1457
|
+
3. Use your Sandbox tools if you need to compute or analyze data.
|
|
1458
|
+
4. Strictly follow any active Skill instructions provided below.
|
|
1459
|
+
5. When a chart is requested and generateVisualization is available, call it with exact returned rows. Never write chart JSON, ASCII art, or a Markdown table as a substitute.
|
|
1460
|
+
|
|
1461
|
+
Your primary directive is: Check Knowledge > Check MCP/Plugins > Follow Skills > Answer User.\`;
|
|
1462
|
+
|
|
1463
|
+
const CONFIGURED_SYSTEM_PROMPT = process.env.CHAT_SYSTEM_PROMPT || ${JSON.stringify(l)};
|
|
1464
|
+
const SYSTEM_PROMPT = DEFAULT_LARKUP_PROMPT + "\\n\\n--- USER CUSTOM INSTRUCTIONS ---\\n" + CONFIGURED_SYSTEM_PROMPT + ${JSON.stringify(k?`
|
|
1465
|
+
|
|
1466
|
+
--- AVAILABLE AGENT SKILLS ---
|
|
1467
|
+
${k}`:"")};
|
|
1468
|
+
const ENABLED_TOOLS = new Set(${JSON.stringify(a.enabledTools??[])});
|
|
1469
|
+
const CONFIGURED_BUILT_IN_TOOLS = ${JSON.stringify(j)};
|
|
1470
|
+
const isToolEnabled = (id) => ENABLED_TOOLS.size === 0 || ENABLED_TOOLS.has(id);
|
|
1471
|
+
|
|
1472
|
+
${b?`function parseRuntimeJson(name, fallback) {
|
|
1473
|
+
try {
|
|
1474
|
+
const value = process.env[name];
|
|
1475
|
+
return value ? JSON.parse(value) : fallback;
|
|
1476
|
+
} catch {
|
|
1477
|
+
return fallback;
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
const MCP_CONNECTIONS = parseRuntimeJson("LARKUP_MCP_CONNECTIONS", []);
|
|
1482
|
+
const PLUGIN_MODULES = parseRuntimeJson("LARKUP_AGENT_PLUGIN_MODULES", []);
|
|
1483
|
+
const SANDBOX_BACKEND = process.env.LARKUP_SANDBOX_BACKEND || "local";
|
|
1484
|
+
const SANDBOX_CREDENTIALS = parseRuntimeJson("LARKUP_SANDBOX_CREDENTIALS", {});
|
|
1485
|
+
`:""}
|
|
1486
|
+
|
|
1487
|
+
${h}
|
|
1488
|
+
const model = createConfiguredModel(CHAT_MODEL);
|
|
1489
|
+
|
|
1490
|
+
function textFromMessage(message) {
|
|
1491
|
+
if (typeof message?.content === "string") return message.content.trim();
|
|
1492
|
+
if (Array.isArray(message?.content)) {
|
|
1493
|
+
return message.content
|
|
1494
|
+
.filter((part) => part?.type === "text" && typeof part.text === "string")
|
|
1495
|
+
.map((part) => part.text)
|
|
1496
|
+
.join("\\n")
|
|
1497
|
+
.trim();
|
|
1498
|
+
}
|
|
1499
|
+
return "";
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
async function readBody(req) {
|
|
1503
|
+
const chunks = [];
|
|
1504
|
+
for await (const chunk of req) chunks.push(chunk);
|
|
1505
|
+
if (chunks.length === 0) return {};
|
|
1506
|
+
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
function sendError(res, status, error) {
|
|
1510
|
+
res.writeHead(status, { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" });
|
|
1511
|
+
res.end(JSON.stringify({ error }));
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
function normalizeMessages(body) {
|
|
1515
|
+
if (!Array.isArray(body.messages)) throw new Error("Body must include a messages array.");
|
|
1516
|
+
const messages = body.messages
|
|
1517
|
+
.filter((message) => ["user", "assistant", "system"].includes(message?.role))
|
|
1518
|
+
.map((message) => ({ role: message.role, content: textFromMessage(message) }))
|
|
1519
|
+
.filter((message) => message.content);
|
|
1520
|
+
if (![...messages].reverse().some((message) => message.role === "user")) {
|
|
1521
|
+
throw new Error("At least one user message is required.");
|
|
1522
|
+
}
|
|
1523
|
+
return messages;
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
function resolveRequestedChatModel(body) {
|
|
1527
|
+
const requestedProvider = typeof body.provider === "string" ? body.provider.trim() : "";
|
|
1528
|
+
const requestedModel = typeof body.modelId === "string"
|
|
1529
|
+
? body.modelId.trim()
|
|
1530
|
+
: typeof body.model === "string"
|
|
1531
|
+
? body.model.trim()
|
|
1532
|
+
: "";
|
|
1533
|
+
if (requestedProvider && requestedProvider !== CHAT_PROVIDER) {
|
|
1534
|
+
throw new Error("This runtime is configured for " + CHAT_PROVIDER + ". Set provider to that value or omit it.");
|
|
1535
|
+
}
|
|
1536
|
+
if (!requestedModel) return { id: CHAT_MODEL, model };
|
|
1537
|
+
if (CHAT_PROVIDER !== "vercel_ai_gateway") {
|
|
1538
|
+
const modelProvider = requestedModel.startsWith("custom:")
|
|
1539
|
+
? "custom"
|
|
1540
|
+
: requestedModel.includes("/")
|
|
1541
|
+
? requestedModel.split("/", 1)[0]
|
|
1542
|
+
: CHAT_PROVIDER;
|
|
1543
|
+
if (modelProvider !== CHAT_PROVIDER) {
|
|
1544
|
+
throw new Error("Model " + requestedModel + " is not available through the configured " + CHAT_PROVIDER + " provider.");
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
return { id: requestedModel, model: createConfiguredModel(requestedModel) };
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
${b?`function mcpTransport(connection) {
|
|
1551
|
+
const headers = { ...(connection.headers || {}) };
|
|
1552
|
+
if (connection.connectionType === "proxy") {
|
|
1553
|
+
if (connection.proxyAuthToken) headers[connection.proxyAuthHeader || "Authorization"] = connection.proxyAuthToken;
|
|
1554
|
+
return { type: connection.transport || "http", url: connection.proxyUrl, headers };
|
|
1555
|
+
}
|
|
1556
|
+
return { type: connection.transport || "http", url: connection.url, headers };
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
function mcpToolPrefix(connection) {
|
|
1560
|
+
return "mcp_" + String(connection.id || "remote").replace(/[^a-zA-Z0-9_]/g, "_") + "_";
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
async function buildAgentTools() {
|
|
1564
|
+
const tools = {};
|
|
1565
|
+
const descriptions = [];
|
|
1566
|
+
const closers = [];
|
|
1567
|
+
if (isToolEnabled("searchKnowledgeBase")) {
|
|
1568
|
+
tools.searchKnowledgeBase = tool({
|
|
1569
|
+
description: "Search the Larkup knowledge base for relevant source material.",
|
|
1570
|
+
inputSchema: z.object({ query: z.string(), topK: z.number().int().min(1).max(20).optional() }),
|
|
1571
|
+
execute: async ({ query, topK }) => storeQuery(await embedQuery(query), topK || Number(process.env.TOP_K || 5)),
|
|
1572
|
+
});
|
|
1573
|
+
descriptions.push({ id: "searchKnowledgeBase", name: "Search Knowledge Base", description: "Search indexed Larkup knowledge-base content.", source: "built-in" });
|
|
1574
|
+
}
|
|
1575
|
+
if (isToolEnabled("getIndexedData")) {
|
|
1576
|
+
tools.getIndexedData = tool({
|
|
1577
|
+
description: "List indexed knowledge-base documents when a user asks what data is available.",
|
|
1578
|
+
inputSchema: z.object({ page: z.number().int().min(1).optional(), limit: z.number().int().min(1).max(100).optional() }),
|
|
1579
|
+
execute: ({ page, limit }) => storeList({ page: page || 1, limit: limit || 20 }),
|
|
1580
|
+
});
|
|
1581
|
+
descriptions.push({ id: "getIndexedData", name: "Get Indexed Data", description: "List indexed knowledge-base documents.", source: "built-in" });
|
|
1582
|
+
}
|
|
1583
|
+
if (isToolEnabled("generateVisualization")) {
|
|
1584
|
+
tools.generateVisualization = tool({
|
|
1585
|
+
description: "Create an interactive chart from rows already returned by another tool. Call this tool instead of writing chart JSON or an ASCII chart. data must contain the exact rows to plot, and xAxisKey and every series dataKey must exactly match keys in those rows. Never use placeholder keys such as EMPTY, null, or undefined. Supply clear human-readable xAxisLabel and yAxisLabel values, including units when known.",
|
|
1586
|
+
inputSchema: z.object({
|
|
1587
|
+
chartType: z.enum(["bar", "area", "line", "pie", "scatter", "radar"]),
|
|
1588
|
+
title: z.string(),
|
|
1589
|
+
subtitle: z.string().optional(),
|
|
1590
|
+
data: z.array(z.looseObject({})),
|
|
1591
|
+
xAxisKey: z.string(),
|
|
1592
|
+
series: z.array(z.object({ dataKey: z.string(), label: z.string().optional(), color: z.string().optional() })),
|
|
1593
|
+
colors: z.array(z.string()).optional(),
|
|
1594
|
+
stacked: z.boolean().optional(),
|
|
1595
|
+
showLegend: z.boolean().optional(),
|
|
1596
|
+
xAxisLabel: z.string().optional(),
|
|
1597
|
+
yAxisLabel: z.string().optional(),
|
|
1598
|
+
}),
|
|
1599
|
+
execute: async (config) => config,
|
|
1600
|
+
});
|
|
1601
|
+
descriptions.push({ id: "generateVisualization", name: "Generate Charts", description: "Create interactive charts from returned rows.", source: "built-in" });
|
|
1602
|
+
}
|
|
1603
|
+
if (isToolEnabled("executeAnalysis") || isToolEnabled("analyzeCorpusWithCode")) {
|
|
1604
|
+
tools.executeAnalysis = tool({
|
|
1605
|
+
description: "Run Python, JavaScript, or TypeScript in the configured isolated sandbox.",
|
|
1606
|
+
inputSchema: z.object({ code: z.string(), language: z.enum(["python", "javascript", "typescript"]).default("python") }),
|
|
1607
|
+
execute: async ({ code, language }) => {
|
|
1608
|
+
const result = await new SandboxManager({ backend: SANDBOX_BACKEND, credentials: SANDBOX_CREDENTIALS }).execute({ code, language, timeout: 30_000 });
|
|
1609
|
+
return { stdout: result.stdout.slice(0, 5000), stderr: result.stderr.slice(0, 2000), exitCode: result.exitCode, executionTimeMs: result.executionTimeMs, artifacts: result.artifacts.map((artifact) => ({ name: artifact.name, mimeType: artifact.mimeType })) };
|
|
1610
|
+
},
|
|
1611
|
+
});
|
|
1612
|
+
descriptions.push({ id: "executeAnalysis", name: "Execute Analysis", description: "Run code in the configured sandbox.", source: "sandbox" });
|
|
1613
|
+
}
|
|
1614
|
+
for (const connection of Array.isArray(MCP_CONNECTIONS) ? MCP_CONNECTIONS : []) {
|
|
1615
|
+
if (!connection || connection.enabled === false || !connection.url) continue;
|
|
1616
|
+
try {
|
|
1617
|
+
const client = await createMCPClient({ transport: mcpTransport(connection) });
|
|
1618
|
+
const remoteTools = await client.tools();
|
|
1619
|
+
const prefix = mcpToolPrefix(connection);
|
|
1620
|
+
for (const [name, remoteTool] of Object.entries(remoteTools)) {
|
|
1621
|
+
const id = prefix + name;
|
|
1622
|
+
tools[id] = remoteTool;
|
|
1623
|
+
descriptions.push({ id, name, description: "MCP tool from " + (connection.name || connection.url), source: "mcp", connectionId: connection.id, connectionName: connection.name || connection.url });
|
|
1624
|
+
}
|
|
1625
|
+
closers.push(() => client.close());
|
|
1626
|
+
} catch (error) {
|
|
1627
|
+
console.warn("[agent] MCP connection unavailable:", connection.name || connection.id, error instanceof Error ? error.message : String(error));
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
for (const plugin of Array.isArray(PLUGIN_MODULES) ? PLUGIN_MODULES : []) {
|
|
1631
|
+
if (!plugin || !plugin.packageName) continue;
|
|
1632
|
+
try {
|
|
1633
|
+
const mod = await import(plugin.packageName);
|
|
1634
|
+
const factory = mod.default || mod.tool;
|
|
1635
|
+
const pluginTools = typeof factory === "function" ? await factory({ config: plugin.config || {}, sandbox: { backend: SANDBOX_BACKEND } }) : null;
|
|
1636
|
+
const pluginName = plugin.name || mod.TOOL_META?.name || plugin.id || plugin.packageName;
|
|
1637
|
+
if (!pluginTools || typeof pluginTools !== "object") {
|
|
1638
|
+
descriptions.push({ id: plugin.id || plugin.packageName, name: pluginName, description: "Configured Marketplace plugin without an Agent tool factory.", source: "plugin", pluginId: plugin.id, pluginName, availability: "configured" });
|
|
1639
|
+
continue;
|
|
1640
|
+
}
|
|
1641
|
+
for (const [name, pluginTool] of Object.entries(pluginTools)) {
|
|
1642
|
+
if (!pluginTool || typeof pluginTool !== "object") {
|
|
1643
|
+
console.warn("[agent] Plugin returned an invalid tool:", plugin.id || plugin.packageName, name);
|
|
1644
|
+
continue;
|
|
1645
|
+
}
|
|
1646
|
+
tools[name] = pluginTool;
|
|
1647
|
+
descriptions.push({ id: name, name, description: "Tool provided by plugin " + (plugin.id || plugin.packageName), source: "plugin", pluginId: plugin.id, pluginName });
|
|
1648
|
+
}
|
|
1649
|
+
} catch (error) {
|
|
1650
|
+
console.warn("[agent] Plugin unavailable:", plugin.id || plugin.packageName, error instanceof Error ? error.message : String(error));
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
return { tools, descriptions, close: async () => Promise.allSettled(closers.map((close) => close())) };
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
export async function listAgentTools() {
|
|
1657
|
+
const agentTools = await buildAgentTools();
|
|
1658
|
+
try {
|
|
1659
|
+
return agentTools.descriptions;
|
|
1660
|
+
} finally {
|
|
1661
|
+
await agentTools.close();
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
export async function listAgentCapabilities() {
|
|
1666
|
+
const agentTools = await buildAgentTools();
|
|
1667
|
+
try {
|
|
1668
|
+
const groups = new Map();
|
|
1669
|
+
for (const item of agentTools.descriptions) {
|
|
1670
|
+
const id = item.source === "mcp"
|
|
1671
|
+
? "mcp:" + item.connectionId
|
|
1672
|
+
: item.source === "plugin"
|
|
1673
|
+
? "plugin:" + item.pluginId
|
|
1674
|
+
: item.source || "built-in";
|
|
1675
|
+
const name = item.source === "mcp"
|
|
1676
|
+
? "MCP \xb7 " + (item.connectionName || item.connectionId)
|
|
1677
|
+
: item.source === "plugin"
|
|
1678
|
+
? "Plugin \xb7 " + (item.pluginName || item.pluginId)
|
|
1679
|
+
: item.source === "sandbox"
|
|
1680
|
+
? "Sandbox"
|
|
1681
|
+
: "Built-in tools";
|
|
1682
|
+
const group = groups.get(id) || {
|
|
1683
|
+
id,
|
|
1684
|
+
name,
|
|
1685
|
+
source: item.source || "built-in",
|
|
1686
|
+
connectionId: item.connectionId,
|
|
1687
|
+
pluginId: item.pluginId,
|
|
1688
|
+
tools: [],
|
|
1689
|
+
};
|
|
1690
|
+
group.tools.push(item);
|
|
1691
|
+
groups.set(id, group);
|
|
1692
|
+
}
|
|
1693
|
+
const builtIns = groups.get("built-in") || { id: "built-in", name: "Built-in tools", source: "built-in", tools: [] };
|
|
1694
|
+
const knownBuiltIns = new Set(builtIns.tools.map((item) => item.id));
|
|
1695
|
+
for (const tool of CONFIGURED_BUILT_IN_TOOLS) {
|
|
1696
|
+
if (!knownBuiltIns.has(tool.id)) {
|
|
1697
|
+
builtIns.tools.push({ ...tool, source: "built-in", availability: "configured" });
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
if (builtIns.tools.length) groups.set("built-in", builtIns);
|
|
1701
|
+
const configuredPluginIds = new Set(
|
|
1702
|
+
agentTools.descriptions.filter((item) => item.source === "plugin").map((item) => item.pluginId),
|
|
1703
|
+
);
|
|
1704
|
+
for (const plugin of Array.isArray(PLUGIN_MODULES) ? PLUGIN_MODULES : []) {
|
|
1705
|
+
if (!plugin?.packageName || configuredPluginIds.has(plugin.id)) continue;
|
|
1706
|
+
const pluginId = plugin.id || plugin.packageName;
|
|
1707
|
+
groups.set("plugin:" + pluginId, {
|
|
1708
|
+
id: "plugin:" + pluginId,
|
|
1709
|
+
name: "Plugin \xb7 " + (plugin.name || pluginId),
|
|
1710
|
+
source: "plugin",
|
|
1711
|
+
pluginId,
|
|
1712
|
+
tools: [{
|
|
1713
|
+
id: pluginId,
|
|
1714
|
+
name: plugin.name || pluginId,
|
|
1715
|
+
description: "Configured Marketplace plugin. Its executable tools could not be loaded by this runtime.",
|
|
1716
|
+
source: "plugin",
|
|
1717
|
+
pluginId,
|
|
1718
|
+
availability: "configured",
|
|
1719
|
+
}],
|
|
1720
|
+
});
|
|
1721
|
+
}
|
|
1722
|
+
const skills = ${JSON.stringify(i.map(a=>({id:a.id,name:a.name,description:a.description||"Agent skill instructions.",source:"skill",availability:"active",url:a.url})))};
|
|
1723
|
+
if (skills.length) groups.set("skills", { id: "skills", name: "Skills", source: "skill", tools: skills });
|
|
1724
|
+
return [...groups.values()];
|
|
1725
|
+
} finally {
|
|
1726
|
+
await agentTools.close();
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
export function getAgentRuntimeConfiguration() {
|
|
1731
|
+
return {
|
|
1732
|
+
systemPrompt: CONFIGURED_SYSTEM_PROMPT,
|
|
1733
|
+
enabledTools: CONFIGURED_BUILT_IN_TOOLS,
|
|
1734
|
+
sandbox: {
|
|
1735
|
+
provider: SANDBOX_BACKEND,
|
|
1736
|
+
configured: Object.keys(SANDBOX_CREDENTIALS).length > 0 || SANDBOX_BACKEND === "local" || SANDBOX_BACKEND === "docker",
|
|
1737
|
+
enabled: isToolEnabled("executeAnalysis") || isToolEnabled("analyzeCorpusWithCode"),
|
|
1738
|
+
},
|
|
1739
|
+
skills: ${JSON.stringify(i.map(a=>({id:a.id,name:a.name,description:a.description,url:a.url})))},
|
|
1740
|
+
};
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
export async function getAgentSandboxStatus() {
|
|
1744
|
+
try {
|
|
1745
|
+
const health = await new SandboxManager({ backend: SANDBOX_BACKEND, credentials: SANDBOX_CREDENTIALS }).healthCheck();
|
|
1746
|
+
return {
|
|
1747
|
+
provider: SANDBOX_BACKEND,
|
|
1748
|
+
configured: getAgentRuntimeConfiguration().sandbox.configured,
|
|
1749
|
+
status: health.status,
|
|
1750
|
+
message: health.error,
|
|
1751
|
+
};
|
|
1752
|
+
} catch (error) {
|
|
1753
|
+
return { provider: SANDBOX_BACKEND, configured: getAgentRuntimeConfiguration().sandbox.configured, status: "unavailable", message: error instanceof Error ? error.message : "Sandbox health check failed." };
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
`:""}
|
|
1757
|
+
async function createChatResult(body, agentMode) {
|
|
1758
|
+
const messages = normalizeMessages(body);
|
|
1759
|
+
const latestUser = [...messages].reverse().find((message) => message.role === "user");
|
|
1760
|
+
const vector = await embedQuery(latestUser.content);
|
|
1761
|
+
const requestedTopK = Number(body.topK) || Number(process.env.TOP_K || 5);
|
|
1762
|
+
const hits = await storeQuery(vector, Math.min(50, Math.max(1, requestedTopK)));
|
|
1763
|
+
const context = hits
|
|
1764
|
+
.map((hit, index) => \`[\${index + 1}] \${hit.title || "Untitled"}\\n\${hit.text}\`)
|
|
1765
|
+
.join("\\n\\n");
|
|
1766
|
+
const requestedSystem = messages
|
|
1767
|
+
.filter((message) => message.role === "system")
|
|
1768
|
+
.map((message) => message.content)
|
|
1769
|
+
.join("\\n\\n");
|
|
1770
|
+
const system = [
|
|
1771
|
+
SYSTEM_PROMPT,
|
|
1772
|
+
requestedSystem,
|
|
1773
|
+
context
|
|
1774
|
+
? \`Use the retrieved context below as the source of truth. Answer directly when it states the requested fact. Treat first- and second-person statements in a retrieved source as referring to the person asked about when the wording matches the user's question (for example, “you like mango and orange” answers “which fruit do I like?”). Do not describe the source as “the first document” or add uncertainty when the fact is stated plainly. Say the context does not answer only when no retrieved statement supports an answer.\\n\\n\${context}\`
|
|
1775
|
+
: "",
|
|
1776
|
+
].filter(Boolean).join("\\n\\n");
|
|
1777
|
+
const modelMessages = messages
|
|
1778
|
+
.filter((message) => message.role !== "system")
|
|
1779
|
+
.map((message) => ({ role: message.role, content: message.content }));
|
|
1780
|
+
const selected = resolveRequestedChatModel(body);
|
|
1781
|
+
const options = { model: selected.model, system, messages: modelMessages };
|
|
1782
|
+
const agentTools = agentMode ? await buildAgentTools() : null;
|
|
1783
|
+
const result = agentMode
|
|
1784
|
+
? streamText({ ...options, tools: agentTools.tools, stopWhen: stepCountIs(5) })
|
|
1785
|
+
: streamText(options);
|
|
1786
|
+
return { result, hits, modelId: selected.id, close: agentTools ? agentTools.close : async () => {} };
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
export async function handleChat(req, res) {
|
|
1790
|
+
try {
|
|
1791
|
+
const { result, hits } = await createChatResult(await readBody(req), false);
|
|
1792
|
+
res.writeHead(200, {
|
|
1793
|
+
"Content-Type": "text/event-stream",
|
|
1794
|
+
"Cache-Control": "no-cache, no-transform",
|
|
1795
|
+
Connection: "keep-alive",
|
|
1796
|
+
"Access-Control-Allow-Origin": "*",
|
|
1797
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
1798
|
+
});
|
|
1799
|
+
for await (const text of result.textStream) {
|
|
1800
|
+
res.write(\`event: message\\ndata: \${JSON.stringify({ type: "text-delta", text })}\\n\\n\`);
|
|
1801
|
+
}
|
|
1802
|
+
res.write(\`event: done\\ndata: \${JSON.stringify({ type: "done", hits })}\\n\\n\`);
|
|
1803
|
+
res.end();
|
|
1804
|
+
} catch (error) {
|
|
1805
|
+
sendError(res, 400, error instanceof Error ? error.message : String(error));
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
${b?`export async function handleAgentChat(req, res) {
|
|
1810
|
+
try {
|
|
1811
|
+
const { result, close } = await createChatResult(await readBody(req), true);
|
|
1812
|
+
await result.pipeUIMessageStreamToResponse(res, {
|
|
1813
|
+
sendReasoning: true,
|
|
1814
|
+
headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Content-Type, Authorization" },
|
|
1815
|
+
});
|
|
1816
|
+
await close();
|
|
1817
|
+
} catch (error) {
|
|
1818
|
+
sendError(res, 400, error instanceof Error ? error.message : String(error));
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
export async function handleOpenAIChatCompletions(req, res) {
|
|
1823
|
+
try {
|
|
1824
|
+
const body = await readBody(req);
|
|
1825
|
+
const { result, modelId, close } = await createChatResult(body, true);
|
|
1826
|
+
const id = \`chatcmpl_\${crypto.randomUUID().replaceAll("-", "")}\`;
|
|
1827
|
+
const created = Math.floor(Date.now() / 1000);
|
|
1828
|
+
const modelName = modelId;
|
|
1829
|
+
if (body.stream === false) {
|
|
1830
|
+
let content = "";
|
|
1831
|
+
for await (const text of result.textStream) content += text;
|
|
1832
|
+
res.writeHead(200, { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" });
|
|
1833
|
+
const response = res.end(JSON.stringify({
|
|
1834
|
+
id,
|
|
1835
|
+
object: "chat.completion",
|
|
1836
|
+
created,
|
|
1837
|
+
model: modelName,
|
|
1838
|
+
choices: [{ index: 0, message: { role: "assistant", content }, finish_reason: "stop" }],
|
|
1839
|
+
}));
|
|
1840
|
+
await close();
|
|
1841
|
+
return response;
|
|
1842
|
+
}
|
|
1843
|
+
res.writeHead(200, {
|
|
1844
|
+
"Content-Type": "text/event-stream",
|
|
1845
|
+
"Cache-Control": "no-cache, no-transform",
|
|
1846
|
+
Connection: "keep-alive",
|
|
1847
|
+
"Access-Control-Allow-Origin": "*",
|
|
1848
|
+
});
|
|
1849
|
+
for await (const text of result.textStream) {
|
|
1850
|
+
res.write(\`data: \${JSON.stringify({ id, object: "chat.completion.chunk", created, model: modelName, choices: [{ index: 0, delta: { content: text }, finish_reason: null }] })}\\n\\n\`);
|
|
1851
|
+
}
|
|
1852
|
+
res.write(\`data: \${JSON.stringify({ id, object: "chat.completion.chunk", created, model: modelName, choices: [{ index: 0, delta: {}, finish_reason: "stop" }] })}\\n\\n\`);
|
|
1853
|
+
res.end("data: [DONE]\\n\\n");
|
|
1854
|
+
await close();
|
|
1855
|
+
} catch (error) {
|
|
1856
|
+
sendError(res, 400, error instanceof Error ? error.message : String(error));
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
`:""}`}function i(a,b){let c={custom:"@ai-sdk/openai-compatible",google:"@ai-sdk/google",cohere:"@ai-sdk/cohere",mistral:"@ai-sdk/mistral",deepseek:"@ai-sdk/deepseek",vercel_ai_gateway:"@ai-sdk/gateway",openai:"@ai-sdk/openai"}[b||"openai"]||"@ai-sdk/openai";a[c]=e[c]}}};
|