@loopstack/loopstack-studio 0.33.0 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/EnvironmentEmbedRoot.js +17 -25
- package/dist/components/layout/StudioSidebar.js +34 -34
- package/dist/components/messages/CompletionMessagePaper.js +25 -29
- package/dist/events/api-client-events.js +13 -1
- package/dist/events/index.js +1 -0
- package/dist/features/code-explorer/components/FileTabsBarBase.js +1 -1
- package/dist/features/code-explorer/index.js +0 -3
- package/dist/features/dashboard/AppLauncher.js +111 -64
- package/dist/features/debug/components/WorkflowFlowViewer.js +2 -1
- package/dist/features/debug/components/workflow-flow/WorkflowGraph.js +2 -1
- package/dist/features/documents/DocumentRenderer.js +42 -42
- package/dist/features/documents/components/DocumentList.js +1 -1
- package/dist/features/documents/document-details/DocumentDetails.js +0 -5
- package/dist/features/documents/renderers/DocumentFormRenderer.js +13 -12
- package/dist/features/documents/renderers/LinkMessageRenderer.js +2 -1
- package/dist/features/documents/renderers/useDocumentTransition.js +3 -2
- package/dist/features/feature-registry/FeatureRegistryProvider.js +17 -18
- package/dist/features/feature-registry/available-features.js +3 -2
- package/dist/features/feature-registry/index.js +1 -1
- package/dist/features/file-explorer/components/FileExplorerPanel.js +64 -43
- package/dist/features/file-explorer/components/FileTabsBar.js +1 -1
- package/dist/features/file-explorer/components/FileTree.js +1 -1
- package/dist/features/file-explorer/file-explorer-feature.js +15 -7
- package/dist/features/file-explorer/hooks/useFileExplorer.js +41 -34
- package/dist/features/file-explorer/index.js +1 -1
- package/dist/features/file-explorer/providers/FileExplorerProvider.js +91 -89
- package/dist/features/git/components/WorkbenchGitPanel.js +7 -10
- package/dist/features/git/hooks/useGit.js +55 -57
- package/dist/features/health/LocalHealthCheck.js +46 -47
- package/dist/features/oauth/OAuthPromptRenderer.js +6 -5
- package/dist/features/runs/Runs.js +3 -2
- package/dist/features/secrets/components/WorkbenchSecretsPanel.js +1 -1
- package/dist/features/secrets/renderers/SecretInputRenderer.js +3 -2
- package/dist/features/workbench/Workbench.js +16 -16
- package/dist/features/workbench/WorkflowItem.js +5 -8
- package/dist/features/workbench/components/NewRunDialog.js +173 -171
- package/dist/features/workbench/components/PreviewEmptyState.js +1 -1
- package/dist/features/workbench/components/WorkbenchIconSidebar.js +1 -1
- package/dist/features/workbench/components/WorkbenchRunsPanel.js +2 -1
- package/dist/features/workbench/components/WorkbenchSidebarShell.js +3 -3
- package/dist/features/workbench/components/WorkflowForms.js +1 -1
- package/dist/features/workbench/components/WorkflowHistoryItem.js +2 -1
- package/dist/features/workbench/components/buttons/WorkflowButtons.js +8 -14
- package/dist/features/workbench/hooks/useLlmStreamingDocuments.js +65 -132
- package/dist/features/workbench/hooks/useWorkflowData.js +8 -6
- package/dist/features/workbench/index.js +1 -1
- package/dist/features/workspaces/Workspaces.js +5 -3
- package/dist/features/workspaces/components/CreateWorkspace.js +7 -5
- package/dist/features/workspaces/components/ExecutionTimeline.js +69 -65
- package/dist/features/workspaces/components/WorkflowRunForm.js +6 -4
- package/dist/features/workspaces/components/WorkspaceHomePage.js +1 -1
- package/dist/hooks/index.js +5 -5
- package/dist/hooks/useAuth.js +14 -53
- package/dist/hooks/useConfig.js +13 -37
- package/dist/hooks/useDocuments.js +5 -30
- package/dist/hooks/useEnvironments.js +34 -24
- package/dist/hooks/useProcessor.js +2 -31
- package/dist/hooks/useSecrets.js +71 -53
- package/dist/hooks/useWorkflows.js +43 -172
- package/dist/hooks/useWorkspaces.js +24 -130
- package/dist/index.d.ts +137 -481
- package/dist/index.js +15 -17
- package/dist/loopstack-studio.css +1 -1
- package/dist/packages/client/dist/client.js +35 -0
- package/dist/packages/client/dist/http.js +47 -0
- package/dist/packages/client/dist/index.js +15 -0
- package/dist/packages/client/dist/queries/query-keys.js +94 -0
- package/dist/packages/client/dist/queries/query-options.js +97 -0
- package/dist/packages/client/dist/resources/auth.js +10 -0
- package/dist/packages/client/dist/resources/config.js +11 -0
- package/dist/packages/client/dist/resources/dashboard.js +4 -0
- package/dist/packages/client/dist/resources/documents.js +7 -0
- package/dist/packages/client/dist/resources/processor.js +7 -0
- package/dist/packages/client/dist/resources/workflows.js +13 -0
- package/dist/packages/client/dist/resources/workspaces.js +12 -0
- package/dist/packages/client/dist/stream/invalidations.js +20 -0
- package/dist/packages/client/dist/stream/llm-reducer.js +65 -0
- package/dist/packages/client/dist/stream/sse-parser.js +40 -0
- package/dist/packages/client/dist/stream/stream.js +147 -0
- package/dist/packages/contracts/dist/events/client-message-base.schema.js +6 -0
- package/dist/packages/contracts/dist/events/client-message.schema.js +24 -0
- package/dist/packages/contracts/dist/events/index.js +6 -0
- package/dist/packages/contracts/dist/events/llm-events.schema.js +44 -0
- package/dist/packages/contracts/dist/events/stream-events.schema.js +4 -0
- package/dist/packages/contracts/dist/events/workflow-events.schema.js +20 -0
- package/dist/packages/contracts/dist/events/workspace-events.schema.js +5 -0
- package/dist/packages/contracts/dist/types/types/ui-message.type.js +39 -0
- package/dist/packages/react/dist/hooks/mutations.js +175 -0
- package/dist/packages/react/dist/hooks/queries.js +139 -0
- package/dist/packages/react/dist/hooks/use-live-invalidation.js +39 -0
- package/dist/packages/react/dist/hooks/use-llm-stream.js +18 -0
- package/dist/packages/react/dist/index.js +5 -0
- package/dist/packages/react/dist/provider.js +15 -0
- package/dist/pages/DashboardPage.js +2 -1
- package/dist/pages/DebugWorkflowDetailsPage.js +2 -1
- package/dist/pages/DebugWorkflowsPage.js +2 -1
- package/dist/pages/EmbedWorkbenchPage.js +50 -43
- package/dist/pages/PreviewWorkbenchPage.js +60 -59
- package/dist/pages/StudioLandingPage.js +1 -1
- package/dist/pages/WorkbenchPage.js +53 -47
- package/dist/pages/WorkflowDebugPage.js +3 -2
- package/dist/pages/WorkspacePage.js +42 -27
- package/dist/pages/WorkspaceRunsPage.js +36 -27
- package/dist/providers/LoopstackClientProvider.js +31 -0
- package/dist/services/createApiClient.js +9 -3
- package/dist/services/index.js +0 -1
- package/dist/services/reporting-fetch.js +13 -0
- package/package.json +4 -3
- package/dist/api/auth.js +0 -10
- package/dist/api/client.js +0 -13
- package/dist/api/config.js +0 -11
- package/dist/api/dashboard.js +0 -4
- package/dist/api/documents.js +0 -7
- package/dist/api/environments.js +0 -8
- package/dist/api/index.js +0 -28
- package/dist/api/processor.js +0 -7
- package/dist/api/secrets.js +0 -16
- package/dist/api/workflows.js +0 -15
- package/dist/api/workspaces.js +0 -12
- package/dist/events/sse-client-events.js +0 -13
- package/dist/features/code-explorer/CodeExplorer.js +0 -6
- package/dist/features/code-explorer/components/CodeExplorerTree.js +0 -6
- package/dist/features/code-explorer/components/FileTabsBar.js +0 -4
- package/dist/features/code-explorer/providers/CodeExplorerProvider.js +0 -5
- package/dist/features/file-explorer/api/files.js +0 -7
- package/dist/features/git/api/git.js +0 -9
- package/dist/hooks/query-keys.js +0 -145
- package/dist/hooks/useApi.js +0 -15
- package/dist/hooks/useFiles.js +0 -3
- package/dist/node_modules/lodash/_Symbol.js +0 -7
- package/dist/node_modules/lodash/_baseGetTag.js +0 -13
- package/dist/node_modules/lodash/_baseTrim.js +0 -11
- package/dist/node_modules/lodash/_freeGlobal.js +0 -6
- package/dist/node_modules/lodash/_getRawTag.js +0 -17
- package/dist/node_modules/lodash/_objectToString.js +0 -10
- package/dist/node_modules/lodash/_root.js +0 -8
- package/dist/node_modules/lodash/_trimmedEndIndex.js +0 -11
- package/dist/node_modules/lodash/debounce.js +0 -53
- package/dist/node_modules/lodash/isObject.js +0 -10
- package/dist/node_modules/lodash/isObjectLike.js +0 -9
- package/dist/node_modules/lodash/isSymbol.js +0 -12
- package/dist/node_modules/lodash/now.js +0 -10
- package/dist/node_modules/lodash/toNumber.js +0 -22
- package/dist/providers/InvalidationEventsProvider.js +0 -41
- package/dist/providers/SseProvider.js +0 -37
- package/dist/services/eventEmitter.js +0 -12
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { createHttpClient } from "./http.js";
|
|
2
|
+
import { createQueries } from "./queries/query-options.js";
|
|
3
|
+
import { createAuthResource } from "./resources/auth.js";
|
|
4
|
+
import { createConfigResource } from "./resources/config.js";
|
|
5
|
+
import { createDashboardResource } from "./resources/dashboard.js";
|
|
6
|
+
import { createDocumentsResource } from "./resources/documents.js";
|
|
7
|
+
import { createProcessorResource } from "./resources/processor.js";
|
|
8
|
+
import { createWorkflowsResource } from "./resources/workflows.js";
|
|
9
|
+
import { createWorkspacesResource } from "./resources/workspaces.js";
|
|
10
|
+
import { LoopstackStream } from "./stream/stream.js";
|
|
11
|
+
function createClient(u) {
|
|
12
|
+
let d = u.envKey ?? u.url, f = createHttpClient(u), p = createWorkflowsResource(f), m = createDocumentsResource(f), h = createProcessorResource(f), g = createWorkspacesResource(f), _ = createConfigResource(f), v = createDashboardResource(f), y = createAuthResource(f);
|
|
13
|
+
return {
|
|
14
|
+
envKey: d,
|
|
15
|
+
http: f,
|
|
16
|
+
workflows: p,
|
|
17
|
+
documents: m,
|
|
18
|
+
processor: h,
|
|
19
|
+
workspaces: g,
|
|
20
|
+
config: _,
|
|
21
|
+
dashboard: v,
|
|
22
|
+
auth: y,
|
|
23
|
+
queries: createQueries({
|
|
24
|
+
envKey: d,
|
|
25
|
+
workflows: p,
|
|
26
|
+
documents: m,
|
|
27
|
+
workspaces: g,
|
|
28
|
+
config: _,
|
|
29
|
+
dashboard: v,
|
|
30
|
+
auth: y
|
|
31
|
+
}),
|
|
32
|
+
stream: new LoopstackStream(u)
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export { createClient };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
var LoopstackApiError = class extends Error {
|
|
2
|
+
status;
|
|
3
|
+
body;
|
|
4
|
+
constructor(e, n, r) {
|
|
5
|
+
super(r), this.status = e, this.body = n, this.name = "LoopstackApiError";
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
function extractErrorMessage(e, n) {
|
|
9
|
+
if (e && typeof e == "object" && "message" in e) {
|
|
10
|
+
let n = e.message;
|
|
11
|
+
if (Array.isArray(n)) return n.join("; ");
|
|
12
|
+
if (typeof n == "string") return n;
|
|
13
|
+
}
|
|
14
|
+
return `Request failed with status ${n}`;
|
|
15
|
+
}
|
|
16
|
+
function createHttpClient(r) {
|
|
17
|
+
let i = r.fetch ?? fetch, a = r.url.replace(/\/+$/, "");
|
|
18
|
+
async function o(o, s, c = {}) {
|
|
19
|
+
let l = new URL(a + s);
|
|
20
|
+
for (let [e, n] of Object.entries(c.query ?? {})) n !== void 0 && l.searchParams.set(e, typeof n == "object" ? JSON.stringify(n) : String(n));
|
|
21
|
+
let u = { Accept: "application/json" };
|
|
22
|
+
c.body !== void 0 && (u["Content-Type"] = "application/json"), r.token && (u.Authorization = `Bearer ${r.token}`);
|
|
23
|
+
let d = await i(l, {
|
|
24
|
+
method: o,
|
|
25
|
+
headers: u,
|
|
26
|
+
credentials: r.credentials ?? "include",
|
|
27
|
+
body: c.body === void 0 ? void 0 : JSON.stringify(c.body)
|
|
28
|
+
}), f = await d.text(), p = f ? safeJsonParse(f) : void 0;
|
|
29
|
+
if (!d.ok) throw new LoopstackApiError(d.status, p ?? f, extractErrorMessage(p, d.status));
|
|
30
|
+
return p;
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
get: (e, n) => o("GET", e, { query: n }),
|
|
34
|
+
post: (e, n) => o("POST", e, { body: n }),
|
|
35
|
+
put: (e, n) => o("PUT", e, { body: n }),
|
|
36
|
+
patch: (e, n) => o("PATCH", e, { body: n }),
|
|
37
|
+
delete: (e, n) => o("DELETE", e, { body: n })
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function safeJsonParse(e) {
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(e);
|
|
43
|
+
} catch {
|
|
44
|
+
return e;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export { LoopstackApiError, createHttpClient };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { LoopstackApiError, createHttpClient } from "./http.js";
|
|
2
|
+
import { queryKeys } from "./queries/query-keys.js";
|
|
3
|
+
import { createQueries } from "./queries/query-options.js";
|
|
4
|
+
import { createAuthResource } from "./resources/auth.js";
|
|
5
|
+
import { createConfigResource } from "./resources/config.js";
|
|
6
|
+
import { createDashboardResource } from "./resources/dashboard.js";
|
|
7
|
+
import { createDocumentsResource } from "./resources/documents.js";
|
|
8
|
+
import { createProcessorResource } from "./resources/processor.js";
|
|
9
|
+
import { createWorkflowsResource } from "./resources/workflows.js";
|
|
10
|
+
import { createWorkspacesResource } from "./resources/workspaces.js";
|
|
11
|
+
import { createSseParser } from "./stream/sse-parser.js";
|
|
12
|
+
import { LoopstackStream } from "./stream/stream.js";
|
|
13
|
+
import { createClient } from "./client.js";
|
|
14
|
+
import { resolveInvalidations } from "./stream/invalidations.js";
|
|
15
|
+
import { reduceLlmStream } from "./stream/llm-reducer.js";
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const queryKeys = {
|
|
2
|
+
workflow: (e, t) => [
|
|
3
|
+
"workflow",
|
|
4
|
+
e,
|
|
5
|
+
t
|
|
6
|
+
],
|
|
7
|
+
workflowStatus: (e, t) => [
|
|
8
|
+
"workflowStatus",
|
|
9
|
+
e,
|
|
10
|
+
t
|
|
11
|
+
],
|
|
12
|
+
workflows: (e) => ["workflows", e],
|
|
13
|
+
workflowList: (e, t = {}) => [
|
|
14
|
+
"workflows",
|
|
15
|
+
e,
|
|
16
|
+
"list",
|
|
17
|
+
t
|
|
18
|
+
],
|
|
19
|
+
childWorkflows: (e, t) => [
|
|
20
|
+
"childWorkflows",
|
|
21
|
+
e,
|
|
22
|
+
t
|
|
23
|
+
],
|
|
24
|
+
workflowCheckpoints: (e, t) => [
|
|
25
|
+
"workflow",
|
|
26
|
+
e,
|
|
27
|
+
t,
|
|
28
|
+
"checkpoints"
|
|
29
|
+
],
|
|
30
|
+
workspace: (e, t) => [
|
|
31
|
+
"workspace",
|
|
32
|
+
e,
|
|
33
|
+
t
|
|
34
|
+
],
|
|
35
|
+
workspaces: (e) => ["workspaces", e],
|
|
36
|
+
workspaceList: (e, t = {}) => [
|
|
37
|
+
"workspaces",
|
|
38
|
+
e,
|
|
39
|
+
"list",
|
|
40
|
+
t
|
|
41
|
+
],
|
|
42
|
+
me: (e) => ["me", e],
|
|
43
|
+
workerHealth: (e) => ["workerHealth", e],
|
|
44
|
+
apps: (e) => ["apps", e],
|
|
45
|
+
workflowConfig: (e, t) => [
|
|
46
|
+
"workflowConfig",
|
|
47
|
+
e,
|
|
48
|
+
t
|
|
49
|
+
],
|
|
50
|
+
workflowSource: (e, t) => [
|
|
51
|
+
"workflowSource",
|
|
52
|
+
e,
|
|
53
|
+
t
|
|
54
|
+
],
|
|
55
|
+
toolConfigs: (e) => ["toolConfigs", e],
|
|
56
|
+
toolConfig: (e, t) => [
|
|
57
|
+
"toolConfig",
|
|
58
|
+
e,
|
|
59
|
+
t
|
|
60
|
+
],
|
|
61
|
+
availableEnvironments: (e) => ["availableEnvironments", e],
|
|
62
|
+
dashboardStats: (e) => ["dashboardStats", e],
|
|
63
|
+
document: (e, t) => [
|
|
64
|
+
"document",
|
|
65
|
+
e,
|
|
66
|
+
t
|
|
67
|
+
],
|
|
68
|
+
documents: (e, t) => [
|
|
69
|
+
"documents",
|
|
70
|
+
e,
|
|
71
|
+
t
|
|
72
|
+
],
|
|
73
|
+
secrets: (e, t) => [
|
|
74
|
+
"secrets",
|
|
75
|
+
e,
|
|
76
|
+
t
|
|
77
|
+
],
|
|
78
|
+
gitStatus: (e, t) => [
|
|
79
|
+
"gitStatus",
|
|
80
|
+
e,
|
|
81
|
+
t
|
|
82
|
+
],
|
|
83
|
+
gitLog: (e, t) => [
|
|
84
|
+
"gitLog",
|
|
85
|
+
e,
|
|
86
|
+
t
|
|
87
|
+
],
|
|
88
|
+
gitRemote: (e, t) => [
|
|
89
|
+
"gitRemote",
|
|
90
|
+
e,
|
|
91
|
+
t
|
|
92
|
+
]
|
|
93
|
+
};
|
|
94
|
+
export { queryKeys };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { SortOrder } from "../../../contracts/dist/enums/sort-order.enum.js";
|
|
2
|
+
import "../../../contracts/dist/enums/index.js";
|
|
3
|
+
import { queryKeys } from "./query-keys.js";
|
|
4
|
+
function createQueries({ envKey: n, workflows: r, documents: i, workspaces: a, config: o, dashboard: s, auth: c }) {
|
|
5
|
+
return {
|
|
6
|
+
workflow: (e) => ({
|
|
7
|
+
queryKey: queryKeys.workflow(n, e),
|
|
8
|
+
queryFn: () => r.get(e)
|
|
9
|
+
}),
|
|
10
|
+
workflowStatus: (e) => ({
|
|
11
|
+
queryKey: queryKeys.workflowStatus(n, e),
|
|
12
|
+
queryFn: () => r.status(e)
|
|
13
|
+
}),
|
|
14
|
+
workflowList: (e = {}) => ({
|
|
15
|
+
queryKey: queryKeys.workflowList(n, e),
|
|
16
|
+
queryFn: () => r.list(e)
|
|
17
|
+
}),
|
|
18
|
+
childWorkflows: (i) => ({
|
|
19
|
+
queryKey: queryKeys.childWorkflows(n, i),
|
|
20
|
+
queryFn: () => r.list({
|
|
21
|
+
filter: { parentId: i },
|
|
22
|
+
sortBy: [{
|
|
23
|
+
field: "createdAt",
|
|
24
|
+
order: SortOrder.ASC
|
|
25
|
+
}],
|
|
26
|
+
page: 0,
|
|
27
|
+
limit: 100
|
|
28
|
+
})
|
|
29
|
+
}),
|
|
30
|
+
workflowCheckpoints: (e) => ({
|
|
31
|
+
queryKey: queryKeys.workflowCheckpoints(n, e),
|
|
32
|
+
queryFn: () => r.checkpoints(e)
|
|
33
|
+
}),
|
|
34
|
+
document: (e) => ({
|
|
35
|
+
queryKey: queryKeys.document(n, e),
|
|
36
|
+
queryFn: () => i.get(e)
|
|
37
|
+
}),
|
|
38
|
+
documents: (r) => ({
|
|
39
|
+
queryKey: queryKeys.documents(n, r),
|
|
40
|
+
queryFn: () => i.list({
|
|
41
|
+
filter: {
|
|
42
|
+
workflowId: r,
|
|
43
|
+
isInvalidated: !1
|
|
44
|
+
},
|
|
45
|
+
sortBy: [{
|
|
46
|
+
field: "index",
|
|
47
|
+
order: SortOrder.ASC
|
|
48
|
+
}]
|
|
49
|
+
})
|
|
50
|
+
}),
|
|
51
|
+
workspace: (e) => ({
|
|
52
|
+
queryKey: queryKeys.workspace(n, e),
|
|
53
|
+
queryFn: () => a.get(e)
|
|
54
|
+
}),
|
|
55
|
+
workspaceList: (e = {}) => ({
|
|
56
|
+
queryKey: queryKeys.workspaceList(n, e),
|
|
57
|
+
queryFn: () => a.list(e)
|
|
58
|
+
}),
|
|
59
|
+
apps: () => ({
|
|
60
|
+
queryKey: queryKeys.apps(n),
|
|
61
|
+
queryFn: () => o.apps()
|
|
62
|
+
}),
|
|
63
|
+
workflowConfig: (e) => ({
|
|
64
|
+
queryKey: queryKeys.workflowConfig(n, e),
|
|
65
|
+
queryFn: () => o.workflowConfig(e)
|
|
66
|
+
}),
|
|
67
|
+
workflowSource: (e) => ({
|
|
68
|
+
queryKey: queryKeys.workflowSource(n, e),
|
|
69
|
+
queryFn: () => o.workflowSource(e)
|
|
70
|
+
}),
|
|
71
|
+
toolConfigs: () => ({
|
|
72
|
+
queryKey: queryKeys.toolConfigs(n),
|
|
73
|
+
queryFn: () => o.tools()
|
|
74
|
+
}),
|
|
75
|
+
toolConfig: (e) => ({
|
|
76
|
+
queryKey: queryKeys.toolConfig(n, e),
|
|
77
|
+
queryFn: () => o.tool(e)
|
|
78
|
+
}),
|
|
79
|
+
availableEnvironments: () => ({
|
|
80
|
+
queryKey: queryKeys.availableEnvironments(n),
|
|
81
|
+
queryFn: () => o.availableEnvironments()
|
|
82
|
+
}),
|
|
83
|
+
dashboardStats: () => ({
|
|
84
|
+
queryKey: queryKeys.dashboardStats(n),
|
|
85
|
+
queryFn: () => s.stats()
|
|
86
|
+
}),
|
|
87
|
+
me: () => ({
|
|
88
|
+
queryKey: queryKeys.me(n),
|
|
89
|
+
queryFn: () => c.me()
|
|
90
|
+
}),
|
|
91
|
+
workerHealth: () => ({
|
|
92
|
+
queryKey: queryKeys.workerHealth(n),
|
|
93
|
+
queryFn: () => c.workerHealth()
|
|
94
|
+
})
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export { createQueries };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
function createAuthResource(e) {
|
|
2
|
+
return {
|
|
3
|
+
me: () => e.get("/api/v1/auth/me"),
|
|
4
|
+
workerHealth: () => e.get("/api/v1/auth/worker/health"),
|
|
5
|
+
hubLogin: (t) => e.post("/api/v1/auth/oauth/hub", t),
|
|
6
|
+
refresh: () => e.post("/api/v1/auth/refresh"),
|
|
7
|
+
logout: () => e.post("/api/v1/auth/logout")
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export { createAuthResource };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
function createConfigResource(e) {
|
|
2
|
+
return {
|
|
3
|
+
apps: () => e.get("/api/v1/config/apps"),
|
|
4
|
+
workflowConfig: (t) => e.get(`/api/v1/config/workflows/${encodeURIComponent(t)}`),
|
|
5
|
+
workflowSource: (t) => e.get(`/api/v1/config/workflows/${encodeURIComponent(t)}/source`),
|
|
6
|
+
tools: () => e.get("/api/v1/config/tools"),
|
|
7
|
+
tool: (t) => e.get(`/api/v1/config/tools/${encodeURIComponent(t)}`),
|
|
8
|
+
availableEnvironments: () => e.get("/api/v1/config/environments")
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export { createConfigResource };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
function createWorkflowsResource(e) {
|
|
2
|
+
return {
|
|
3
|
+
get: (t) => e.get(`/api/v1/workflows/${t}`),
|
|
4
|
+
status: (t) => e.get(`/api/v1/workflows/${t}/status`),
|
|
5
|
+
list: (t = {}) => e.get("/api/v1/workflows", t),
|
|
6
|
+
create: (t) => e.post("/api/v1/workflows", t),
|
|
7
|
+
update: (t, n) => e.put(`/api/v1/workflows/${t}`, n),
|
|
8
|
+
delete: (t) => e.delete(`/api/v1/workflows/id/${t}`),
|
|
9
|
+
batchDelete: (t) => e.delete("/api/v1/workflows/batch", { ids: t }),
|
|
10
|
+
checkpoints: (t) => e.get(`/api/v1/workflows/${t}/checkpoints`)
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export { createWorkflowsResource };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
function createWorkspacesResource(e) {
|
|
2
|
+
return {
|
|
3
|
+
get: (t) => e.get(`/api/v1/workspaces/${t}`),
|
|
4
|
+
list: (t = {}) => e.get("/api/v1/workspaces", t),
|
|
5
|
+
create: (t) => e.post("/api/v1/workspaces", t),
|
|
6
|
+
update: (t, n) => e.put(`/api/v1/workspaces/${t}`, n),
|
|
7
|
+
setFavourite: (t, n) => e.patch(`/api/v1/workspaces/${t}/favourite`, { isFavourite: n }),
|
|
8
|
+
delete: (t) => e.delete(`/api/v1/workspaces/id/${t}`),
|
|
9
|
+
batchDelete: (t) => e.delete("/api/v1/workspaces/batch", { ids: t })
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export { createWorkspacesResource };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { queryKeys } from "../queries/query-keys.js";
|
|
2
|
+
function resolveInvalidations(t, n) {
|
|
3
|
+
switch (t.type) {
|
|
4
|
+
case "workflow.created": return t.parentId ? [queryKeys.childWorkflows(n, t.parentId)] : [];
|
|
5
|
+
case "workflow.updated": {
|
|
6
|
+
let r = [queryKeys.workflow(n, t.id), queryKeys.workflowStatus(n, t.id)];
|
|
7
|
+
return t.parentId && r.push(queryKeys.childWorkflows(n, t.parentId)), r;
|
|
8
|
+
}
|
|
9
|
+
case "document.created": return [queryKeys.documents(n, t.workflowId)];
|
|
10
|
+
case "secret.upserted":
|
|
11
|
+
case "secret.deleted": return [queryKeys.secrets(n, t.workspaceId)];
|
|
12
|
+
case "git.updated": return [
|
|
13
|
+
queryKeys.gitStatus(n, t.workspaceId),
|
|
14
|
+
queryKeys.gitLog(n, t.workspaceId),
|
|
15
|
+
queryKeys.gitRemote(n, t.workspaceId)
|
|
16
|
+
];
|
|
17
|
+
default: return [];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export { resolveInvalidations };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
function emptyMessageState(e) {
|
|
2
|
+
return {
|
|
3
|
+
messageId: e.messageId,
|
|
4
|
+
workflowId: e.workflowId,
|
|
5
|
+
text: "",
|
|
6
|
+
thinking: "",
|
|
7
|
+
toolCalls: [],
|
|
8
|
+
completed: !1
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function reduceLlmStream(t, n) {
|
|
12
|
+
let r = t[n.messageId] ?? emptyMessageState(n);
|
|
13
|
+
switch (n.type) {
|
|
14
|
+
case "llm.response.start": return {
|
|
15
|
+
...t,
|
|
16
|
+
[n.messageId]: {
|
|
17
|
+
...r,
|
|
18
|
+
completed: !1,
|
|
19
|
+
error: void 0
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
case "llm.response.text_delta": return {
|
|
23
|
+
...t,
|
|
24
|
+
[n.messageId]: {
|
|
25
|
+
...r,
|
|
26
|
+
text: r.text + n.delta
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
case "llm.response.thinking_delta": return {
|
|
30
|
+
...t,
|
|
31
|
+
[n.messageId]: {
|
|
32
|
+
...r,
|
|
33
|
+
thinking: r.thinking + n.delta
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
case "llm.response.tool_call": return {
|
|
37
|
+
...t,
|
|
38
|
+
[n.messageId]: {
|
|
39
|
+
...r,
|
|
40
|
+
toolCalls: [...r.toolCalls, {
|
|
41
|
+
id: n.id,
|
|
42
|
+
name: n.name,
|
|
43
|
+
args: n.args
|
|
44
|
+
}]
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
case "llm.response.done": return {
|
|
48
|
+
...t,
|
|
49
|
+
[n.messageId]: {
|
|
50
|
+
...r,
|
|
51
|
+
completed: !0,
|
|
52
|
+
message: n.message
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
case "llm.response.error": return {
|
|
56
|
+
...t,
|
|
57
|
+
[n.messageId]: {
|
|
58
|
+
...r,
|
|
59
|
+
completed: !0,
|
|
60
|
+
error: n.error
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export { reduceLlmStream };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
function createSseParser(e) {
|
|
2
|
+
let t = "", n = [], r, i;
|
|
3
|
+
function a() {
|
|
4
|
+
(n.length > 0 || r !== void 0 || i !== void 0) && e({
|
|
5
|
+
id: i,
|
|
6
|
+
event: r,
|
|
7
|
+
data: n.join("\n")
|
|
8
|
+
}), n = [], r = void 0, i = void 0;
|
|
9
|
+
}
|
|
10
|
+
function o(e) {
|
|
11
|
+
if (e === "") {
|
|
12
|
+
a();
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (e.startsWith(":")) return;
|
|
16
|
+
let t = e.indexOf(":"), o = t === -1 ? e : e.slice(0, t), s = t === -1 ? "" : e.slice(t + 1);
|
|
17
|
+
switch (s.startsWith(" ") && (s = s.slice(1)), o) {
|
|
18
|
+
case "data":
|
|
19
|
+
n.push(s);
|
|
20
|
+
break;
|
|
21
|
+
case "event":
|
|
22
|
+
r = s;
|
|
23
|
+
break;
|
|
24
|
+
case "id":
|
|
25
|
+
s.includes("\0") || (i = s);
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return { feed(e) {
|
|
30
|
+
t += e;
|
|
31
|
+
let n;
|
|
32
|
+
for (; (n = t.search(/\r\n|\n|\r/)) !== -1;) {
|
|
33
|
+
let e = t[n] === "\r";
|
|
34
|
+
if (e && n === t.length - 1) return;
|
|
35
|
+
let r = t.slice(0, n);
|
|
36
|
+
t = t.slice(n + (e && t[n + 1] === "\n" ? 2 : 1)), o(r);
|
|
37
|
+
}
|
|
38
|
+
} };
|
|
39
|
+
}
|
|
40
|
+
export { createSseParser };
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { LoopstackApiError } from "../http.js";
|
|
2
|
+
import { ClientMessageSchema } from "../../../contracts/dist/events/client-message.schema.js";
|
|
3
|
+
import "../../../contracts/dist/events/index.js";
|
|
4
|
+
import { createSseParser } from "./sse-parser.js";
|
|
5
|
+
var INITIAL_RETRY_DELAY_MS = 500;
|
|
6
|
+
function matchesWorkflow(e, t) {
|
|
7
|
+
return !t || e.type === "stream.reset" ? !0 : "workflowId" in e ? e.workflowId === t : !0;
|
|
8
|
+
}
|
|
9
|
+
var LoopstackStream = class {
|
|
10
|
+
config;
|
|
11
|
+
handlers = /* @__PURE__ */ new Map();
|
|
12
|
+
anyHandlers = /* @__PURE__ */ new Set();
|
|
13
|
+
statusHandlers = /* @__PURE__ */ new Set();
|
|
14
|
+
subscriberCount = 0;
|
|
15
|
+
abortController;
|
|
16
|
+
watchdog;
|
|
17
|
+
running = !1;
|
|
18
|
+
closed = !1;
|
|
19
|
+
currentStatus = "idle";
|
|
20
|
+
lastEventId;
|
|
21
|
+
constructor(e) {
|
|
22
|
+
this.config = e, this.lastEventId = e.lastEventId;
|
|
23
|
+
}
|
|
24
|
+
get status() {
|
|
25
|
+
return this.currentStatus;
|
|
26
|
+
}
|
|
27
|
+
on(e, t) {
|
|
28
|
+
this.handlers.has(e) || this.handlers.set(e, /* @__PURE__ */ new Set()), this.handlers.get(e).add(t), this.retain();
|
|
29
|
+
let n = !0;
|
|
30
|
+
return () => {
|
|
31
|
+
n && (n = !1, this.handlers.get(e)?.delete(t), this.release());
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
onAny(e) {
|
|
35
|
+
this.anyHandlers.add(e), this.retain();
|
|
36
|
+
let t = !0;
|
|
37
|
+
return () => {
|
|
38
|
+
t && (t = !1, this.anyHandlers.delete(e), this.release());
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
onStatus(e) {
|
|
42
|
+
return this.statusHandlers.add(e), () => this.statusHandlers.delete(e);
|
|
43
|
+
}
|
|
44
|
+
events(e = {}) {
|
|
45
|
+
let t = [], n, r = !1, a = this.onAny((r) => {
|
|
46
|
+
"userId" in r && matchesWorkflow(r, e.workflowId) && (t.push(r), n?.());
|
|
47
|
+
}), o = {
|
|
48
|
+
[Symbol.asyncIterator]: () => o,
|
|
49
|
+
next: async () => {
|
|
50
|
+
for (; t.length === 0 && !r;) await new Promise((e) => n = e), n = void 0;
|
|
51
|
+
return t.length === 0 ? {
|
|
52
|
+
done: !0,
|
|
53
|
+
value: void 0
|
|
54
|
+
} : {
|
|
55
|
+
done: !1,
|
|
56
|
+
value: t.shift()
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
return: async () => (r = !0, a(), n?.(), {
|
|
60
|
+
done: !0,
|
|
61
|
+
value: void 0
|
|
62
|
+
})
|
|
63
|
+
};
|
|
64
|
+
return o;
|
|
65
|
+
}
|
|
66
|
+
close() {
|
|
67
|
+
this.closed = !0, this.handlers.clear(), this.anyHandlers.clear(), this.subscriberCount = 0, this.abortController?.abort(), this.clearWatchdog(), this.setStatus("closed");
|
|
68
|
+
}
|
|
69
|
+
retain() {
|
|
70
|
+
this.subscriberCount++, this.subscriberCount === 1 && !this.running && !this.closed && this.runLoop();
|
|
71
|
+
}
|
|
72
|
+
release() {
|
|
73
|
+
this.subscriberCount = Math.max(0, this.subscriberCount - 1), this.subscriberCount === 0 && this.abortController?.abort();
|
|
74
|
+
}
|
|
75
|
+
setStatus(e) {
|
|
76
|
+
if (this.currentStatus !== e) {
|
|
77
|
+
this.currentStatus = e;
|
|
78
|
+
for (let t of this.statusHandlers) t(e);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
buildUrl() {
|
|
82
|
+
let e = new URL(`${this.config.url.replace(/\/+$/, "")}/api/v1/sse/stream`);
|
|
83
|
+
return this.config.workflowId && e.searchParams.set("workflowId", this.config.workflowId), e;
|
|
84
|
+
}
|
|
85
|
+
async runLoop() {
|
|
86
|
+
this.running = !0;
|
|
87
|
+
let t = this.config.fetch ?? fetch, i = 0;
|
|
88
|
+
for (; !this.closed && this.subscriberCount > 0;) {
|
|
89
|
+
this.abortController = new AbortController();
|
|
90
|
+
let { signal: a } = this.abortController;
|
|
91
|
+
try {
|
|
92
|
+
this.setStatus("connecting");
|
|
93
|
+
let r = { Accept: "text/event-stream" };
|
|
94
|
+
this.config.token && (r.Authorization = `Bearer ${this.config.token}`), this.lastEventId !== void 0 && (r["Last-Event-ID"] = this.lastEventId);
|
|
95
|
+
let o = await t(this.buildUrl(), {
|
|
96
|
+
headers: r,
|
|
97
|
+
credentials: this.config.credentials ?? "include",
|
|
98
|
+
signal: a
|
|
99
|
+
});
|
|
100
|
+
if (!o.ok || !o.body) throw new LoopstackApiError(o.status, void 0, `Event stream failed with status ${o.status}`);
|
|
101
|
+
this.setStatus("open"), i = 0, this.resetWatchdog();
|
|
102
|
+
let s = createSseParser((e) => {
|
|
103
|
+
this.resetWatchdog(), e.id !== void 0 && e.id !== "" && (this.lastEventId = e.id), e.event !== "ping" && e.data && this.dispatch(e.data);
|
|
104
|
+
}), c = o.body.getReader(), l = new TextDecoder();
|
|
105
|
+
for (;;) {
|
|
106
|
+
let { done: e, value: t } = await c.read();
|
|
107
|
+
if (e) break;
|
|
108
|
+
s.feed(l.decode(t, { stream: !0 }));
|
|
109
|
+
}
|
|
110
|
+
} catch {}
|
|
111
|
+
if (this.clearWatchdog(), this.currentStatus === "open" && this.setStatus("connecting"), this.closed || this.subscriberCount === 0) break;
|
|
112
|
+
i++;
|
|
113
|
+
let o = Math.min(this.config.maxRetryDelayMs ?? 1e4, INITIAL_RETRY_DELAY_MS * 2 ** (i - 1)) * (.8 + Math.random() * .4);
|
|
114
|
+
await new Promise((e) => setTimeout(e, o));
|
|
115
|
+
}
|
|
116
|
+
this.running = !1, this.setStatus(this.closed ? "closed" : "idle");
|
|
117
|
+
}
|
|
118
|
+
dispatch(e) {
|
|
119
|
+
let n;
|
|
120
|
+
try {
|
|
121
|
+
n = JSON.parse(e);
|
|
122
|
+
} catch {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
let r = ClientMessageSchema.safeParse(n);
|
|
126
|
+
if (r.success) {
|
|
127
|
+
let e = r.data;
|
|
128
|
+
for (let t of this.handlers.get(e.type) ?? []) t(e);
|
|
129
|
+
for (let t of this.anyHandlers) t(e);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
let i = n && typeof n == "object" && "type" in n && typeof n.type == "string" ? n.type : "unknown";
|
|
133
|
+
for (let e of this.anyHandlers) e({
|
|
134
|
+
type: i,
|
|
135
|
+
raw: n
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
resetWatchdog() {
|
|
139
|
+
this.clearWatchdog(), this.watchdog = setTimeout(() => {
|
|
140
|
+
this.abortController?.abort();
|
|
141
|
+
}, this.config.heartbeatTimeoutMs ?? 6e4), this.watchdog.unref?.();
|
|
142
|
+
}
|
|
143
|
+
clearWatchdog() {
|
|
144
|
+
this.watchdog !== void 0 && clearTimeout(this.watchdog), this.watchdog = void 0;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
export { LoopstackStream };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { DocumentCreatedEventSchema, WorkflowCreatedEventSchema, WorkflowUpdatedEventSchema } from "./workflow-events.schema.js";
|
|
2
|
+
import { GitUpdatedEventSchema, SecretDeletedEventSchema, SecretUpsertedEventSchema } from "./workspace-events.schema.js";
|
|
3
|
+
import { LlmResponseDoneEventSchema, LlmResponseErrorEventSchema, LlmResponseStartEventSchema, LlmResponseTextDeltaEventSchema, LlmResponseThinkingDeltaEventSchema, LlmResponseToolCallEventSchema } from "./llm-events.schema.js";
|
|
4
|
+
import { StreamResetEventSchema } from "./stream-events.schema.js";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
const ClientMessageSchema = z.discriminatedUnion("type", [
|
|
7
|
+
WorkflowCreatedEventSchema,
|
|
8
|
+
WorkflowUpdatedEventSchema,
|
|
9
|
+
DocumentCreatedEventSchema,
|
|
10
|
+
SecretUpsertedEventSchema,
|
|
11
|
+
SecretDeletedEventSchema,
|
|
12
|
+
GitUpdatedEventSchema,
|
|
13
|
+
LlmResponseStartEventSchema,
|
|
14
|
+
LlmResponseTextDeltaEventSchema,
|
|
15
|
+
LlmResponseThinkingDeltaEventSchema,
|
|
16
|
+
LlmResponseToolCallEventSchema,
|
|
17
|
+
LlmResponseDoneEventSchema,
|
|
18
|
+
LlmResponseErrorEventSchema,
|
|
19
|
+
StreamResetEventSchema
|
|
20
|
+
]);
|
|
21
|
+
function isLlmResponseEvent(e) {
|
|
22
|
+
return e.type.startsWith("llm.response.");
|
|
23
|
+
}
|
|
24
|
+
export { ClientMessageSchema, isLlmResponseEvent };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ClientMessageBaseSchema } from "./client-message-base.schema.js";
|
|
2
|
+
import { DocumentCreatedEventSchema, WorkflowCreatedEventSchema, WorkflowUpdatedEventSchema } from "./workflow-events.schema.js";
|
|
3
|
+
import { GitUpdatedEventSchema, SecretDeletedEventSchema, SecretUpsertedEventSchema } from "./workspace-events.schema.js";
|
|
4
|
+
import { LlmNormalizedMessageSchema, LlmResponseDoneEventSchema, LlmResponseErrorEventSchema, LlmResponseStartEventSchema, LlmResponseTextDeltaEventSchema, LlmResponseThinkingDeltaEventSchema, LlmResponseToolCallEventSchema } from "./llm-events.schema.js";
|
|
5
|
+
import { StreamResetEventSchema } from "./stream-events.schema.js";
|
|
6
|
+
import { ClientMessageSchema, isLlmResponseEvent } from "./client-message.schema.js";
|