@beeuni/sdk 0.2.0 → 0.3.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/README.md +19 -10
- package/dist/beeuni.esm.min.js +37 -35
- package/dist/beeuni.global.js +37 -35
- package/dist/browser/cache/idb-sync-cache.js +15 -5
- package/dist/browser/session-sync/server-transcript-mirror.d.ts +7 -1
- package/dist/browser/session-sync/server-transcript-mirror.js +30 -24
- package/dist/browser/session-sync/session-sync-registry.d.ts +3 -1
- package/dist/browser/session-sync/session-sync-registry.js +48 -3
- package/dist/browser/stores/sync-store/keep-unchanged.d.ts +4 -0
- package/dist/browser/stores/sync-store/keep-unchanged.js +34 -0
- package/dist/browser/stores/sync-store.d.ts +1 -0
- package/dist/browser/stores/sync-store.js +72 -16
- package/dist/core/attachments/prompt-attachments.d.ts +4 -0
- package/dist/core/attachments/prompt-attachments.js +34 -0
- package/dist/core/capture/rules.d.ts +17 -0
- package/dist/core/capture/rules.js +27 -0
- package/dist/core/client/beeuni.d.ts +92 -5
- package/dist/core/client/beeuni.js +2 -0
- package/dist/core/client/capture.d.ts +105 -0
- package/dist/core/client/capture.js +48 -0
- package/dist/core/client/facade-identity.d.ts +1 -0
- package/dist/core/client/facade-identity.js +1 -0
- package/dist/core/client/project-access-resources.d.ts +3 -1
- package/dist/core/client/project-access-resources.js +1 -1
- package/dist/core/client/project-operations-admin.d.ts +4 -4
- package/dist/core/client/project-operations-review.d.ts +2 -3
- package/dist/core/client/project-operations-review.js +1 -0
- package/dist/core/client/project-operations-workspace.d.ts +4 -4
- package/dist/core/client/project-operations-workspace.js +1 -1
- package/dist/core/client/project-operations.d.ts +5 -4
- package/dist/core/client/session-context.d.ts +2 -0
- package/dist/core/client/session-handle.d.ts +13 -0
- package/dist/core/client/session-lifecycle-resources.d.ts +11 -0
- package/dist/core/client/session-lifecycle-resources.js +4 -0
- package/dist/core/client/session-lifecycle-security.d.ts +2 -0
- package/dist/core/client/session-lifecycle-security.js +1 -0
- package/dist/core/client/session-readiness.d.ts +2 -0
- package/dist/core/client/session-readiness.js +20 -1
- package/dist/core/http/api-client.d.ts +1 -0
- package/dist/core/http/api-client.js +1 -0
- package/dist/core/http/config.d.ts +2 -0
- package/dist/core/http/response-error.js +26 -11
- package/dist/core/http/transport.js +6 -1
- package/dist/core/models/composer-model.d.ts +14 -0
- package/dist/core/models/composer-model.js +21 -1
- package/dist/core/rest/platform-client/capture.d.ts +363 -0
- package/dist/core/rest/platform-client/capture.js +116 -0
- package/dist/core/rest/platform-client/index.d.ts +1 -0
- package/dist/core/rest/platform-client/index.js +1 -0
- package/dist/core/rest/platform-client/lifecycle.js +18 -12
- package/dist/core/rest/platform-client/shared.d.ts +5 -0
- package/dist/core/rest/platform-client/shared.js +18 -0
- package/dist/core/rest/projects-client/account-secret-resources.d.ts +2 -1
- package/dist/core/rest/projects-client/accounts.d.ts +34 -0
- package/dist/core/rest/projects-client/accounts.js +10 -0
- package/dist/core/rest/projects-client/admin-providers.d.ts +0 -61
- package/dist/core/rest/projects-client/admin-providers.js +0 -6
- package/dist/core/rest/projects-client/agent-config.d.ts +3 -0
- package/dist/core/rest/projects-client/apps-fleet.d.ts +5 -1
- package/dist/core/rest/projects-client/apps-fleet.js +2 -2
- package/dist/core/rest/projects-client/apps.d.ts +3 -0
- package/dist/core/rest/projects-client/change-requests.d.ts +2 -0
- package/dist/core/rest/projects-client/change-requests.js +2 -0
- package/dist/core/rest/projects-client/connectors.d.ts +7 -0
- package/dist/core/rest/projects-client/connectors.js +3 -0
- package/dist/core/rest/projects-client/files.d.ts +3 -0
- package/dist/core/rest/projects-client/files.js +4 -0
- package/dist/core/rest/projects-client/gateway.d.ts +5 -0
- package/dist/core/rest/projects-client/iam-actions.d.ts +76 -0
- package/dist/core/rest/projects-client/iam-actions.js +101 -0
- package/dist/core/rest/projects-client/iam.d.ts +1 -0
- package/dist/core/rest/projects-client/iam.js +1 -0
- package/dist/core/rest/projects-client/notifications.d.ts +1 -1
- package/dist/core/rest/projects-client/notifications.js +4 -0
- package/dist/core/rest/projects-client/projects.d.ts +3 -2
- package/dist/core/rest/projects-client/projects.js +2 -3
- package/dist/core/rest/projects-client/review-items.d.ts +2 -0
- package/dist/core/rest/projects-client/review-items.js +4 -0
- package/dist/core/rest/projects-client/review.d.ts +17 -3
- package/dist/core/rest/projects-client/review.js +11 -0
- package/dist/core/rest/projects-client/secrets.d.ts +3 -0
- package/dist/core/rest/projects-client/session-attachments.js +14 -1
- package/dist/core/rest/projects-client/sessions.d.ts +29 -2
- package/dist/core/rest/projects-client/sessions.js +34 -4
- package/dist/core/runtime/runtime-rest-client.js +1 -1
- package/dist/core/runtime/runtime-types.d.ts +1 -0
- package/dist/core/session/open-bundle.d.ts +4 -4
- package/dist/core/session/open-bundle.js +29 -46
- package/dist/core/session/turn-end-watch.d.ts +47 -0
- package/dist/core/session/turn-end-watch.js +141 -0
- package/dist/core/session-log/index.d.ts +4 -0
- package/dist/core/session-log/index.js +3 -0
- package/dist/core/session-log/tool-call.d.ts +7 -2
- package/dist/core/session-log/tool-call.js +25 -6
- package/dist/core/session-log/turns/blocks.d.ts +60 -0
- package/dist/core/session-log/turns/blocks.js +124 -0
- package/dist/core/session-log/turns/history.d.ts +32 -0
- package/dist/core/session-log/turns/history.js +99 -0
- package/dist/core/session-log/turns/index.d.ts +4 -0
- package/dist/core/session-log/turns/index.js +4 -0
- package/dist/core/session-log/turns/metrics.d.ts +21 -0
- package/dist/core/session-log/turns/metrics.js +29 -0
- package/dist/core/session-log/turns/turn.d.ts +55 -0
- package/dist/core/session-log/turns/turn.js +279 -0
- package/dist/core/session-log/turns/v1-parts.d.ts +8 -0
- package/dist/core/session-log/turns/v1-parts.js +43 -0
- package/dist/core/session-log/v1-view.d.ts +5 -2
- package/dist/core/session-log/v1-view.js +86 -22
- package/dist/core/session-log/v1.js +10 -3
- package/dist/core/session-sync/saved-transcript.d.ts +15 -1
- package/dist/core/session-sync/saved-transcript.js +55 -0
- package/dist/core/session-sync/session-sync-controller.js +3 -0
- package/dist/core/stream/event-stream.js +3 -3
- package/dist/core/turns/classify.js +4 -2
- package/dist/core/turns/edit-blocks.d.ts +1 -0
- package/dist/core/turns/edit-blocks.js +15 -0
- package/dist/core/turns/segments/burst-summary.d.ts +1 -0
- package/dist/core/turns/segments/burst-summary.js +24 -0
- package/dist/core/turns/segments/group-steps.d.ts +4 -3
- package/dist/core/turns/segments/group-steps.js +9 -6
- package/dist/core/turns/segments/narration.d.ts +5 -4
- package/dist/core/turns/segments/narration.js +12 -3
- package/dist/core/turns/segments/session-activity-groups.d.ts +2 -1
- package/dist/core/turns/segments/session-activity-groups.js +3 -1
- package/dist/core/turns/segments/step-label.d.ts +2 -1
- package/dist/core/turns/segments/step-label.js +3 -1
- package/dist/core/turns/segments/working-turn.d.ts +4 -2
- package/dist/core/turns/segments/working-turn.js +9 -8
- package/dist/core/turns/tool-kind.d.ts +1 -1
- package/dist/core/turns/tool-kind.js +3 -2
- package/dist/core/turns/tool-registry.js +1 -0
- package/dist/core/turns/tools/tool-meta.d.ts +1 -1
- package/dist/core/turns/tools/tool-meta.js +3 -2
- package/dist/core/turns/view-model.js +1 -13
- package/dist/genui/catalog.d.ts +28 -0
- package/dist/genui/catalog.js +396 -0
- package/dist/genui/expansion.d.ts +3 -0
- package/dist/genui/expansion.js +295 -0
- package/dist/genui/fence-entry.d.ts +2 -0
- package/dist/genui/fence-entry.js +1 -0
- package/dist/genui/fence.d.ts +21 -0
- package/dist/genui/fence.js +138 -0
- package/dist/genui/index.d.ts +6 -0
- package/dist/genui/index.js +6 -0
- package/dist/genui/markdown.d.ts +12 -0
- package/dist/genui/markdown.js +104 -0
- package/dist/genui/parse.d.ts +6 -0
- package/dist/genui/parse.js +75 -0
- package/dist/genui/prompt.d.ts +2 -0
- package/dist/genui/prompt.js +206 -0
- package/dist/genui/react/default-components.d.ts +2 -0
- package/dist/genui/react/default-components.js +72 -0
- package/dist/genui/react/default-components.test.d.ts +1 -0
- package/dist/genui/react/default-components.test.js +94 -0
- package/dist/genui/react/genui-block-disabled.test.d.ts +1 -0
- package/dist/genui/react/genui-block-disabled.test.js +50 -0
- package/dist/genui/react/genui-block.d.ts +28 -0
- package/dist/genui/react/genui-block.js +91 -0
- package/dist/genui/react/genui-block.test.d.ts +1 -0
- package/dist/genui/react/genui-block.test.js +205 -0
- package/dist/genui/react/index.d.ts +2 -0
- package/dist/genui/react/index.js +2 -0
- package/dist/genui/share.d.ts +5 -0
- package/dist/genui/share.js +30 -0
- package/dist/genui/test-fixtures.d.ts +2 -0
- package/dist/genui/test-fixtures.js +16 -0
- package/dist/genui/types.d.ts +29 -0
- package/dist/genui/types.js +1 -0
- package/dist/genui/urls.d.ts +1 -0
- package/dist/genui/urls.js +18 -0
- package/dist/genui/validate.d.ts +9 -0
- package/dist/genui/validate.js +116 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/internal/connector-catalog.d.ts +1 -0
- package/dist/platform/ui.d.ts +8 -2
- package/dist/platform/ui.js +19 -4
- package/dist/react/chat/use-chat-turns.d.ts +1 -1
- package/dist/react/human-presence.d.ts +9 -0
- package/dist/react/human-presence.js +12 -0
- package/dist/react/index.d.ts +4 -0
- package/dist/react/index.js +4 -0
- package/dist/react/opencode.d.ts +1 -1
- package/dist/react/opencode.js +1 -1
- package/dist/react/query-contracts.d.ts +6 -0
- package/dist/react/query-contracts.js +6 -0
- package/dist/react/query-keys.d.ts +17 -1
- package/dist/react/query-keys.js +24 -1
- package/dist/react/reset-identity-state.js +2 -0
- package/dist/react/session-cache-write.d.ts +1 -0
- package/dist/react/session-cache-write.js +20 -0
- package/dist/react/session-transcript-subscription.js +1 -1
- package/dist/react/sign-in-with-beeuni.d.ts +5 -5
- package/dist/react/turn-end-handoff.d.ts +13 -0
- package/dist/react/turn-end-handoff.js +101 -0
- package/dist/react/use-admin-providers.d.ts +0 -3
- package/dist/react/use-admin-providers.js +1 -11
- package/dist/react/use-capture.d.ts +47 -0
- package/dist/react/use-capture.js +173 -0
- package/dist/react/use-feature-flag.js +1 -0
- package/dist/react/use-opencode-events/handle-interaction-event.js +8 -3
- package/dist/react/use-opencode-events/handle-session-event.js +13 -8
- package/dist/react/use-opencode-events/handler-context.d.ts +1 -0
- package/dist/react/use-opencode-events/helpers.d.ts +1 -0
- package/dist/react/use-opencode-events/helpers.js +11 -1
- package/dist/react/use-opencode-local.d.ts +5 -1
- package/dist/react/use-opencode-local.js +15 -2
- package/dist/react/use-opencode-sessions/commands.d.ts +11 -1
- package/dist/react/use-opencode-sessions/commands.js +21 -1
- package/dist/react/use-opencode-sessions/permissions.js +28 -1
- package/dist/react/use-project-sessions.d.ts +1 -1
- package/dist/react/use-project-sessions.js +6 -5
- package/dist/react/use-prompt-attachments.js +1 -0
- package/dist/react/use-review-summary.d.ts +13 -0
- package/dist/react/use-review-summary.js +32 -0
- package/dist/react/use-runtime-reconnect.js +2 -2
- package/dist/react/use-session-list-state.d.ts +6 -0
- package/dist/react/use-session-list-state.js +33 -0
- package/dist/react/use-session-log.d.ts +3 -2
- package/dist/react/use-session-log.js +26 -17
- package/dist/react/use-session-messages.d.ts +2 -1
- package/dist/react/use-session-messages.js +15 -14
- package/dist/react/use-session-stream.js +12 -1
- package/dist/react/use-session-sync.d.ts +2 -2
- package/dist/react/use-session-sync.js +10 -8
- package/dist/react/use-session-transcript-history.js +2 -12
- package/dist/react/use-session-working.d.ts +2 -0
- package/dist/react/use-session-working.js +10 -0
- package/dist/react/use-session.d.ts +6 -0
- package/dist/react/use-session.js +87 -7
- package/package.json +49 -3
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
|
+
import { getSessionTurn } from '../core/rest/projects-client/sessions.js';
|
|
5
|
+
import { openSessionStream, sessionStreamConnected } from '../core/session/control-stream.js';
|
|
6
|
+
import { createTurnEndWatch, } from '../core/session/turn-end-watch.js';
|
|
7
|
+
import { unwrapError } from '../core/turns/errors.js';
|
|
8
|
+
import { hasNotifySink, notifySessionError, notifyTaskComplete } from '../platform/ui.js';
|
|
9
|
+
import { registerIdentityReset } from './identity-reset-registry.js';
|
|
10
|
+
import { findCachedProjectSession } from './session-cache-write.js';
|
|
11
|
+
import { realRuntimeTitle } from './use-opencode-events/helpers.js';
|
|
12
|
+
import { runtimeKeys } from './use-opencode-sessions/index.js';
|
|
13
|
+
let watch = null;
|
|
14
|
+
let overrides = null;
|
|
15
|
+
function announce(...[handoff, outcome, watchedSinceMs]) {
|
|
16
|
+
const title = handoff.title?.();
|
|
17
|
+
if (outcome.kind === 'completed') {
|
|
18
|
+
notifyTaskComplete(handoff.sessionId, title, { watchedSinceMs, projectId: handoff.projectId });
|
|
19
|
+
}
|
|
20
|
+
else if (outcome.kind === 'failed') {
|
|
21
|
+
notifySessionError(handoff.sessionId, unwrapError(outcome.error), title, {
|
|
22
|
+
projectId: handoff.projectId,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function subscribeTurnFrames(projectId, sessionId, onRead) {
|
|
27
|
+
const handle = openSessionStream({
|
|
28
|
+
projectId,
|
|
29
|
+
sessionId,
|
|
30
|
+
onControl: (frame) => {
|
|
31
|
+
if (frame.type !== 'beeuni.control.turn')
|
|
32
|
+
return;
|
|
33
|
+
const payload = frame.payload;
|
|
34
|
+
if (!payload?.known || !Array.isArray(payload.turns))
|
|
35
|
+
return;
|
|
36
|
+
onRead({
|
|
37
|
+
turns: payload.turns,
|
|
38
|
+
...(payload.last_ended ? { last_ended: payload.last_ended } : {}),
|
|
39
|
+
...(payload.recent_failures ? { recent_failures: payload.recent_failures } : {}),
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
return () => handle.close();
|
|
44
|
+
}
|
|
45
|
+
function turnEndWatch() {
|
|
46
|
+
watch ??= createTurnEndWatch({
|
|
47
|
+
readTurn: (projectId, sessionId) => getSessionTurn(projectId, sessionId, { showErrors: false }),
|
|
48
|
+
subscribe: subscribeTurnFrames,
|
|
49
|
+
pushLive: sessionStreamConnected,
|
|
50
|
+
onEnded: announce,
|
|
51
|
+
...overrides,
|
|
52
|
+
});
|
|
53
|
+
return watch;
|
|
54
|
+
}
|
|
55
|
+
registerIdentityReset(() => watch?.releaseAll());
|
|
56
|
+
export function resetTurnEndHandoffForTests(deps) {
|
|
57
|
+
overrides = deps ?? null;
|
|
58
|
+
watch = null;
|
|
59
|
+
}
|
|
60
|
+
export function turnEndHandoffWatching() {
|
|
61
|
+
return watch?.watching() ?? [];
|
|
62
|
+
}
|
|
63
|
+
function sessionTitle(queryClient, projectId, sessionId, runtimeSessionId) {
|
|
64
|
+
const row = findCachedProjectSession(queryClient, projectId, (session) => session.session_id === sessionId);
|
|
65
|
+
const named = row?.custom_name || row?.name;
|
|
66
|
+
if (named)
|
|
67
|
+
return named;
|
|
68
|
+
if (!runtimeSessionId)
|
|
69
|
+
return undefined;
|
|
70
|
+
const runtime = queryClient.getQueryData(runtimeKeys.runtimeSession(runtimeSessionId)) ??
|
|
71
|
+
queryClient.getQueryData(runtimeKeys.sessions())?.find((s) => s.id === runtimeSessionId);
|
|
72
|
+
return realRuntimeTitle(runtime?.title) ?? undefined;
|
|
73
|
+
}
|
|
74
|
+
export function useTurnEndHandoff(input) {
|
|
75
|
+
const queryClient = useQueryClient();
|
|
76
|
+
const latest = useRef(input);
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
latest.current = input;
|
|
79
|
+
});
|
|
80
|
+
const { enabled, projectId, sessionId } = input;
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (!enabled || !projectId || !sessionId)
|
|
83
|
+
return;
|
|
84
|
+
watch?.release(projectId, sessionId);
|
|
85
|
+
return () => {
|
|
86
|
+
const last = latest.current;
|
|
87
|
+
if (!last.working || last.projectId !== projectId || last.sessionId !== sessionId)
|
|
88
|
+
return;
|
|
89
|
+
if (!hasNotifySink())
|
|
90
|
+
return;
|
|
91
|
+
const runtimeSessionId = last.runtimeSessionId;
|
|
92
|
+
turnEndWatch().watch({
|
|
93
|
+
projectId,
|
|
94
|
+
sessionId,
|
|
95
|
+
openTurnToken: last.openTurnToken,
|
|
96
|
+
lastEndedToken: last.lastEndedToken,
|
|
97
|
+
title: () => sessionTitle(queryClient, projectId, sessionId, runtimeSessionId),
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
}, [enabled, projectId, sessionId, queryClient]);
|
|
101
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type AdminBootModePolicy } from '../core/rest/projects-client/admin-providers.js';
|
|
2
1
|
export declare function useAdminProviderDistribution(): import("@tanstack/react-query").UseQueryResult<import("../internal/platform-admin.js").AdminProviderDistribution, Error>;
|
|
3
2
|
export declare function useAdminProviderSandboxes(): import("@tanstack/react-query").UseQueryResult<import("../internal/platform-admin.js").AdminProviderSandboxesResponse, Error>;
|
|
4
3
|
export declare function useAdminProviderAnalytics(days: number, enabled: boolean): import("@tanstack/react-query").UseQueryResult<import("../internal/platform-admin.js").AdminProviderAnalytics, Error>;
|
|
@@ -16,5 +15,3 @@ export interface AdminProviderMigrationVariables {
|
|
|
16
15
|
export declare function useSetAdminProviderDistribution(options?: AdminProviderMutationOptions): import("@tanstack/react-query").UseMutationResult<unknown, Error, Record<string, number>, unknown>;
|
|
17
16
|
export declare function useMigrateAdminSandboxProvider(options?: AdminProviderMutationOptions): import("@tanstack/react-query").UseMutationResult<unknown, Error, AdminProviderMigrationVariables, unknown>;
|
|
18
17
|
export declare function useSetAdminProviderFallback(options?: AdminProviderMutationOptions): import("@tanstack/react-query").UseMutationResult<unknown, Error, boolean, unknown>;
|
|
19
|
-
export declare function useAdminBootModes(): import("@tanstack/react-query").UseQueryResult<import("../internal/platform-admin.js").AdminBootModes, Error>;
|
|
20
|
-
export declare function useSetAdminBootModes(options?: AdminProviderMutationOptions): import("@tanstack/react-query").UseMutationResult<import("../internal/platform-admin.js").AdminBootModes, Error, AdminBootModePolicy, unknown>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
2
|
-
import { getAdminProviderDistribution, listAdminSandboxes, getAdminProviderAnalytics, getAdminProviderFallback, setAdminProviderDistribution, migrateAdminSandboxProvider, setAdminProviderFallback
|
|
2
|
+
import { getAdminProviderDistribution, listAdminSandboxes, getAdminProviderAnalytics, getAdminProviderFallback, setAdminProviderDistribution, migrateAdminSandboxProvider, setAdminProviderFallback } from '../core/rest/projects-client/admin-providers.js';
|
|
3
3
|
export function useAdminProviderDistribution() {
|
|
4
4
|
return useQuery({ queryKey: ['admin', 'provider-distribution'], queryFn: () => getAdminProviderDistribution() });
|
|
5
5
|
}
|
|
@@ -33,13 +33,3 @@ export function useSetAdminProviderFallback(options = {}) {
|
|
|
33
33
|
void qc.invalidateQueries({ queryKey: ['admin', 'provider-fallback'] });
|
|
34
34
|
} });
|
|
35
35
|
}
|
|
36
|
-
export function useAdminBootModes() {
|
|
37
|
-
return useQuery({ queryKey: ['admin', 'boot-modes'], queryFn: () => getAdminBootModes(), refetchInterval: 30_000 });
|
|
38
|
-
}
|
|
39
|
-
export function useSetAdminBootModes(options = {}) {
|
|
40
|
-
const qc = useQueryClient();
|
|
41
|
-
return useMutation({ mutationFn: (policy) => setAdminBootModes(policy), onError: options.onError, onSuccess: (data) => {
|
|
42
|
-
options.onSuccess?.();
|
|
43
|
-
qc.setQueryData(['admin', 'boot-modes'], data);
|
|
44
|
-
} });
|
|
45
|
-
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type CaptureEnrollmentStatus, type CaptureEnrollmentTokenInput, type CaptureDaysQuery, type CapturePolicy, type CaptureSearchQuery, type CaptureWindowQuery } from '../core/rest/platform-client/capture.js';
|
|
2
|
+
export declare function useCaptureDeviceGrant(userCode: string | null | undefined): import("@tanstack/react-query").UseQueryResult<import("../index.js").CaptureDeviceGrantDetail, Error>;
|
|
3
|
+
export declare function useApproveCaptureDevice(): import("@tanstack/react-query").UseMutationResult<import("../index.js").CaptureDeviceGrant, Error, {
|
|
4
|
+
userCode: string;
|
|
5
|
+
accountId?: string;
|
|
6
|
+
}, unknown>;
|
|
7
|
+
export declare function useDenyCaptureDevice(): import("@tanstack/react-query").UseMutationResult<import("../index.js").CaptureDeviceGrant, Error, string, unknown>;
|
|
8
|
+
type AccountId = string | null | undefined;
|
|
9
|
+
export declare function useCaptureDevices(accountId: AccountId, opts?: {
|
|
10
|
+
scope?: 'mine' | 'account';
|
|
11
|
+
userId?: string;
|
|
12
|
+
}): import("@tanstack/react-query").UseQueryResult<{
|
|
13
|
+
devices: import("../index.js").CaptureDevice[];
|
|
14
|
+
health: import("../index.js").CaptureHealthSummary;
|
|
15
|
+
}, Error>;
|
|
16
|
+
export declare function useRevokeCaptureDevice(accountId: AccountId): import("@tanstack/react-query").UseMutationResult<import("../index.js").CaptureDevice, Error, string, unknown>;
|
|
17
|
+
export declare function useCaptureDays(accountId: AccountId, query?: CaptureDaysQuery): import("@tanstack/react-query").UseQueryResult<import("../index.js").CaptureDays, Error>;
|
|
18
|
+
export declare function useCaptureTimeline(accountId: AccountId, query: CaptureWindowQuery | null): import("@tanstack/react-query").UseQueryResult<import("../index.js").CaptureTimeline, Error>;
|
|
19
|
+
export declare function useCaptureTimelineItems(accountId: AccountId, query: CaptureWindowQuery | null): import("@tanstack/react-query").UseQueryResult<import("../index.js").CaptureTimelineItems, Error>;
|
|
20
|
+
export declare function useCaptureSearch(accountId: AccountId, query: CaptureSearchQuery | null): import("@tanstack/react-query").UseQueryResult<import("../index.js").CaptureSearchResult, Error>;
|
|
21
|
+
export declare function useCaptureChunkMedia(accountId: AccountId, chunkId: string | null | undefined, opts?: {
|
|
22
|
+
userId?: string;
|
|
23
|
+
}): import("@tanstack/react-query").UseQueryResult<import("../index.js").CaptureChunkMedia, Error>;
|
|
24
|
+
export declare function useCaptureEnrollmentTokens(accountId: AccountId): import("@tanstack/react-query").UseQueryResult<{
|
|
25
|
+
tokens: import("../index.js").CaptureEnrollmentToken[];
|
|
26
|
+
}, Error>;
|
|
27
|
+
export declare function useCreateCaptureEnrollmentToken(accountId: AccountId): import("@tanstack/react-query").UseMutationResult<import("../index.js").CaptureEnrollmentTokenSecret, Error, CaptureEnrollmentTokenInput, unknown>;
|
|
28
|
+
export declare function useRevokeCaptureEnrollmentToken(accountId: AccountId): import("@tanstack/react-query").UseMutationResult<import("../index.js").CaptureEnrollmentToken, Error, string, unknown>;
|
|
29
|
+
export declare function useCaptureEnrollments(accountId: AccountId, opts?: {
|
|
30
|
+
status?: CaptureEnrollmentStatus;
|
|
31
|
+
}): import("@tanstack/react-query").UseQueryResult<{
|
|
32
|
+
enrollments: import("../index.js").CaptureEnrollment[];
|
|
33
|
+
}, Error>;
|
|
34
|
+
export declare function useApproveCaptureEnrollment(accountId: AccountId): import("@tanstack/react-query").UseMutationResult<import("../index.js").CaptureEnrollment, Error, {
|
|
35
|
+
enrollmentId: string;
|
|
36
|
+
userId?: string | null;
|
|
37
|
+
}, unknown>;
|
|
38
|
+
export declare function useDenyCaptureEnrollment(accountId: AccountId): import("@tanstack/react-query").UseMutationResult<import("../index.js").CaptureEnrollment, Error, string, unknown>;
|
|
39
|
+
export declare function useLinkCaptureDevice(accountId: AccountId): import("@tanstack/react-query").UseMutationResult<import("../index.js").CaptureDevice, Error, {
|
|
40
|
+
deviceId: string;
|
|
41
|
+
userId: string | null;
|
|
42
|
+
}, unknown>;
|
|
43
|
+
export declare function useCapturePolicy(accountId: AccountId): import("@tanstack/react-query").UseQueryResult<import("../index.js").CapturePolicyRecord, Error>;
|
|
44
|
+
export declare function useSetCapturePolicy(accountId: AccountId): import("@tanstack/react-query").UseMutationResult<import("../index.js").CapturePolicyRecord, Error, CapturePolicy, unknown>;
|
|
45
|
+
export declare function useCaptureWorkspace(accountId: AccountId): import("@tanstack/react-query").UseQueryResult<import("../index.js").CaptureWorkspace, Error>;
|
|
46
|
+
export declare function useSetCaptureEnabled(accountId: AccountId): import("@tanstack/react-query").UseMutationResult<import("../index.js").CaptureWorkspace, Error, boolean, unknown>;
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
3
|
+
import { approveCaptureDeviceGrant, approveCaptureEnrollment, createCaptureEnrollmentToken, denyCaptureEnrollment, listCaptureEnrollments, listCaptureEnrollmentTokens, linkCaptureDevice, revokeCaptureEnrollmentToken, denyCaptureDeviceGrant, getCaptureChunkMedia, getCaptureDays, getCaptureDeviceGrant, getCapturePolicy, getCaptureTimeline, getCaptureTimelineItems, getCaptureWorkspace, listCaptureDevices, revokeCaptureDevice, searchCapture, setCaptureEnabled, setCapturePolicy, } from '../core/rest/platform-client/capture.js';
|
|
4
|
+
import { contract, FRESHNESS } from './query-contracts.js';
|
|
5
|
+
import { qk } from './query-keys.js';
|
|
6
|
+
export function useCaptureDeviceGrant(userCode) {
|
|
7
|
+
return useQuery({
|
|
8
|
+
queryKey: qk.capture.deviceGrant(userCode ?? ''),
|
|
9
|
+
queryFn: () => getCaptureDeviceGrant(userCode),
|
|
10
|
+
enabled: !!userCode,
|
|
11
|
+
...contract('volatile'),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export function useApproveCaptureDevice() {
|
|
15
|
+
const queryClient = useQueryClient();
|
|
16
|
+
return useMutation({
|
|
17
|
+
mutationFn: (args) => approveCaptureDeviceGrant(args.userCode, args.accountId),
|
|
18
|
+
onSuccess: (grant, args) => queryClient.setQueryData(qk.capture.deviceGrant(args.userCode), grant),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export function useDenyCaptureDevice() {
|
|
22
|
+
const queryClient = useQueryClient();
|
|
23
|
+
return useMutation({
|
|
24
|
+
mutationFn: (userCode) => denyCaptureDeviceGrant(userCode),
|
|
25
|
+
onSuccess: (grant, userCode) => queryClient.setQueryData(qk.capture.deviceGrant(userCode), grant),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export function useCaptureDevices(accountId, opts = {}) {
|
|
29
|
+
return useQuery({
|
|
30
|
+
queryKey: qk.capture.devices(accountId ?? '', opts.scope ?? 'mine', opts.userId ?? null),
|
|
31
|
+
queryFn: () => listCaptureDevices(accountId, opts),
|
|
32
|
+
enabled: !!accountId,
|
|
33
|
+
...contract(FRESHNESS.captureDevices),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export function useRevokeCaptureDevice(accountId) {
|
|
37
|
+
const queryClient = useQueryClient();
|
|
38
|
+
return useMutation({
|
|
39
|
+
mutationFn: (deviceId) => revokeCaptureDevice(accountId, deviceId),
|
|
40
|
+
onSuccess: () => queryClient.invalidateQueries({ queryKey: qk.capture.account(accountId ?? '') }),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
export function useCaptureDays(accountId, query = {}) {
|
|
44
|
+
return useQuery({
|
|
45
|
+
queryKey: qk.capture.timelineRead(accountId ?? '', 'days', query),
|
|
46
|
+
queryFn: () => getCaptureDays(accountId, query),
|
|
47
|
+
enabled: !!accountId,
|
|
48
|
+
...contract(FRESHNESS.captureTimeline),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
export function useCaptureTimeline(accountId, query) {
|
|
52
|
+
return useQuery({
|
|
53
|
+
queryKey: qk.capture.timelineRead(accountId ?? '', 'runs', query),
|
|
54
|
+
queryFn: () => getCaptureTimeline(accountId, query ?? undefined),
|
|
55
|
+
enabled: !!accountId && !!query,
|
|
56
|
+
...contract(FRESHNESS.captureTimeline),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
export function useCaptureTimelineItems(accountId, query) {
|
|
60
|
+
return useQuery({
|
|
61
|
+
queryKey: qk.capture.timelineRead(accountId ?? '', 'items', query),
|
|
62
|
+
queryFn: () => getCaptureTimelineItems(accountId, query ?? undefined),
|
|
63
|
+
enabled: !!accountId && !!query,
|
|
64
|
+
...contract(FRESHNESS.captureTimeline),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
export function useCaptureSearch(accountId, query) {
|
|
68
|
+
return useQuery({
|
|
69
|
+
queryKey: qk.capture.timelineRead(accountId ?? '', 'search', query),
|
|
70
|
+
queryFn: () => searchCapture(accountId, query),
|
|
71
|
+
enabled: !!accountId && !!query?.q.trim(),
|
|
72
|
+
...contract(FRESHNESS.captureTimeline),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
export function useCaptureChunkMedia(accountId, chunkId, opts = {}) {
|
|
76
|
+
return useQuery({
|
|
77
|
+
queryKey: qk.capture.timelineRead(accountId ?? '', 'media', { chunkId, userId: opts.userId ?? null }),
|
|
78
|
+
queryFn: () => getCaptureChunkMedia(accountId, chunkId, opts),
|
|
79
|
+
enabled: !!accountId && !!chunkId,
|
|
80
|
+
...contract(FRESHNESS.captureTimeline),
|
|
81
|
+
staleTime: 240_000,
|
|
82
|
+
refetchInterval: 240_000,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
export function useCaptureEnrollmentTokens(accountId) {
|
|
86
|
+
return useQuery({
|
|
87
|
+
queryKey: qk.capture.enrollmentTokens(accountId ?? ''),
|
|
88
|
+
queryFn: () => listCaptureEnrollmentTokens(accountId),
|
|
89
|
+
enabled: !!accountId,
|
|
90
|
+
...contract(FRESHNESS.captureEnrollmentTokens),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
export function useCreateCaptureEnrollmentToken(accountId) {
|
|
94
|
+
const queryClient = useQueryClient();
|
|
95
|
+
return useMutation({
|
|
96
|
+
mutationFn: (input) => createCaptureEnrollmentToken(accountId, input),
|
|
97
|
+
onSuccess: () => void queryClient.invalidateQueries({ queryKey: qk.capture.enrollmentTokens(accountId ?? '') }),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
export function useRevokeCaptureEnrollmentToken(accountId) {
|
|
101
|
+
const queryClient = useQueryClient();
|
|
102
|
+
return useMutation({
|
|
103
|
+
mutationFn: (tokenId) => revokeCaptureEnrollmentToken(accountId, tokenId),
|
|
104
|
+
onSuccess: () => void queryClient.invalidateQueries({ queryKey: qk.capture.enrollmentTokens(accountId ?? '') }),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
export function useCaptureEnrollments(accountId, opts = {}) {
|
|
108
|
+
return useQuery({
|
|
109
|
+
queryKey: [...qk.capture.enrollments(accountId ?? ''), opts.status ?? 'all'],
|
|
110
|
+
queryFn: () => listCaptureEnrollments(accountId, opts),
|
|
111
|
+
enabled: !!accountId,
|
|
112
|
+
...contract(FRESHNESS.captureEnrollments),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function invalidateRollout(queryClient, accountId) {
|
|
116
|
+
for (const queryKey of [qk.capture.enrollments(accountId), qk.capture.enrollmentTokens(accountId), [...qk.capture.account(accountId), 'devices']]) {
|
|
117
|
+
void queryClient.invalidateQueries({ queryKey });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
export function useApproveCaptureEnrollment(accountId) {
|
|
121
|
+
const queryClient = useQueryClient();
|
|
122
|
+
return useMutation({
|
|
123
|
+
mutationFn: (args) => approveCaptureEnrollment(accountId, args.enrollmentId, args.userId),
|
|
124
|
+
onSuccess: () => invalidateRollout(queryClient, accountId ?? ''),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
export function useDenyCaptureEnrollment(accountId) {
|
|
128
|
+
const queryClient = useQueryClient();
|
|
129
|
+
return useMutation({
|
|
130
|
+
mutationFn: (enrollmentId) => denyCaptureEnrollment(accountId, enrollmentId),
|
|
131
|
+
onSuccess: () => invalidateRollout(queryClient, accountId ?? ''),
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
export function useLinkCaptureDevice(accountId) {
|
|
135
|
+
const queryClient = useQueryClient();
|
|
136
|
+
return useMutation({
|
|
137
|
+
mutationFn: (args) => linkCaptureDevice(accountId, args.deviceId, args.userId),
|
|
138
|
+
onSuccess: () => invalidateRollout(queryClient, accountId ?? ''),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
export function useCapturePolicy(accountId) {
|
|
142
|
+
return useQuery({
|
|
143
|
+
queryKey: qk.capture.policy(accountId ?? ''),
|
|
144
|
+
queryFn: () => getCapturePolicy(accountId),
|
|
145
|
+
enabled: !!accountId,
|
|
146
|
+
...contract(FRESHNESS.capturePolicy),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
export function useSetCapturePolicy(accountId) {
|
|
150
|
+
const queryClient = useQueryClient();
|
|
151
|
+
return useMutation({
|
|
152
|
+
mutationFn: (policy) => setCapturePolicy(accountId, policy),
|
|
153
|
+
onSuccess: (record) => queryClient.setQueryData(qk.capture.policy(accountId ?? ''), record),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
export function useCaptureWorkspace(accountId) {
|
|
157
|
+
return useQuery({
|
|
158
|
+
queryKey: qk.capture.workspace(accountId ?? ''),
|
|
159
|
+
queryFn: () => getCaptureWorkspace(accountId),
|
|
160
|
+
enabled: !!accountId,
|
|
161
|
+
...contract(FRESHNESS.captureWorkspace),
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
export function useSetCaptureEnabled(accountId) {
|
|
165
|
+
const queryClient = useQueryClient();
|
|
166
|
+
return useMutation({
|
|
167
|
+
mutationFn: (enabled) => setCaptureEnabled(accountId, enabled),
|
|
168
|
+
onSuccess: (workspace) => {
|
|
169
|
+
queryClient.setQueryData(qk.capture.workspace(accountId ?? ''), workspace);
|
|
170
|
+
void queryClient.invalidateQueries({ queryKey: qk.capture.account(accountId ?? '') });
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { notifyPermissionRequest, notifyQuestion } from '../../platform/ui.js';
|
|
2
|
-
import {
|
|
2
|
+
import { qk } from '../query-keys.js';
|
|
3
|
+
import { asStringOrUndefined, notificationSessionId } from './helpers.js';
|
|
3
4
|
export function handleInteractionEvent(event, ctx) {
|
|
4
5
|
const { addPermission, removePermission, addQuestion, removeQuestion, getSessionTitle } = ctx;
|
|
6
|
+
const notifiedId = (runtimeId) => notificationSessionId(ctx.queryClient, ctx.projectId, ctx.sessionId, runtimeId, true) ?? runtimeId;
|
|
7
|
+
if (event.type.startsWith('question.') && ctx.projectId) {
|
|
8
|
+
ctx.queryClient.invalidateQueries({ queryKey: qk.project.needsInput(ctx.projectId) });
|
|
9
|
+
}
|
|
5
10
|
switch (event.type) {
|
|
6
11
|
case 'permission.asked': {
|
|
7
12
|
const props = event.properties;
|
|
@@ -9,7 +14,7 @@ export function handleInteractionEvent(event, ctx) {
|
|
|
9
14
|
addPermission(props);
|
|
10
15
|
const rawProps = props;
|
|
11
16
|
const toolName = asStringOrUndefined(rawProps.tool) ?? asStringOrUndefined(rawProps.type) ?? 'a tool';
|
|
12
|
-
notifyPermissionRequest(props.sessionID, toolName, getSessionTitle(props.sessionID));
|
|
17
|
+
notifyPermissionRequest(notifiedId(props.sessionID), toolName, getSessionTitle(props.sessionID));
|
|
13
18
|
}
|
|
14
19
|
break;
|
|
15
20
|
}
|
|
@@ -24,7 +29,7 @@ export function handleInteractionEvent(event, ctx) {
|
|
|
24
29
|
if (props.id && props.sessionID) {
|
|
25
30
|
addQuestion(props);
|
|
26
31
|
const questionText = props.questions[0]?.question || props.questions[0]?.header || 'Beeuni needs your input';
|
|
27
|
-
notifyQuestion(props.sessionID, questionText, getSessionTitle(props.sessionID));
|
|
32
|
+
notifyQuestion(notifiedId(props.sessionID), questionText, getSessionTitle(props.sessionID));
|
|
28
33
|
}
|
|
29
34
|
break;
|
|
30
35
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { useSyncStore } from '../../browser/stores/sync-store.js';
|
|
2
2
|
import { isAbortError } from '../../core/http/abort-error.js';
|
|
3
3
|
import { getClient } from '../../core/runtime/client.js';
|
|
4
|
+
import { extractGatewayErrorDetails, unwrapError } from '../../core/turns/errors.js';
|
|
4
5
|
import { notifySessionError, notifyTaskComplete } from '../../platform/ui.js';
|
|
5
6
|
import { runtimeKeys } from '../use-opencode-sessions/index.js';
|
|
6
|
-
import { patchBeeuniSessionTitleMirrors, readSessionInfo, realRuntimeTitle, refetchBeeuniSessionMirrors, } from './helpers.js';
|
|
7
|
+
import { notificationSessionId, patchBeeuniSessionTitleMirrors, readSessionInfo, realRuntimeTitle, refetchBeeuniSessionMirrors, } from './helpers.js';
|
|
7
8
|
export function handleSessionEvent(event, ctx, statusBeforeEvent) {
|
|
8
9
|
if (event.type === 'session.created' || event.type === 'session.updated')
|
|
9
10
|
handleSessionLifecycle(event, ctx);
|
|
@@ -146,6 +147,11 @@ function handleSessionCompaction(event, ctx) {
|
|
|
146
147
|
break;
|
|
147
148
|
}
|
|
148
149
|
}
|
|
150
|
+
function notifyTurnEnd(ctx, runtimeId, notify) {
|
|
151
|
+
const id = notificationSessionId(ctx.queryClient, ctx.projectId, ctx.sessionId, runtimeId);
|
|
152
|
+
if (id)
|
|
153
|
+
notify(id);
|
|
154
|
+
}
|
|
149
155
|
function handleSessionCompletion(event, ctx, statusBeforeEvent) {
|
|
150
156
|
const { reconcileTail, getSessionTitle, invalidateWorkspaceFilesAfterTurn } = ctx;
|
|
151
157
|
switch (event.type) {
|
|
@@ -164,7 +170,7 @@ function handleSessionCompletion(event, ctx, statusBeforeEvent) {
|
|
|
164
170
|
void reconcileTail(sessionID, 'turn-end');
|
|
165
171
|
const prevStatus = statusBeforeEvent;
|
|
166
172
|
if (status.type === 'idle' && prevStatus && prevStatus.type !== 'idle') {
|
|
167
|
-
|
|
173
|
+
notifyTurnEnd(ctx, sessionID, (id) => notifyTaskComplete(id, getSessionTitle(sessionID)));
|
|
168
174
|
invalidateWorkspaceFilesAfterTurn();
|
|
169
175
|
}
|
|
170
176
|
}
|
|
@@ -176,7 +182,7 @@ function handleSessionCompletion(event, ctx, statusBeforeEvent) {
|
|
|
176
182
|
void reconcileTail(sessionID, 'turn-end');
|
|
177
183
|
const prevStatus = statusBeforeEvent;
|
|
178
184
|
if (prevStatus && prevStatus.type !== 'idle') {
|
|
179
|
-
|
|
185
|
+
notifyTurnEnd(ctx, sessionID, (id) => notifyTaskComplete(id, getSessionTitle(sessionID)));
|
|
180
186
|
invalidateWorkspaceFilesAfterTurn();
|
|
181
187
|
}
|
|
182
188
|
}
|
|
@@ -195,11 +201,10 @@ function handleSessionFailure(event, ctx) {
|
|
|
195
201
|
const sessionID = props.sessionID;
|
|
196
202
|
const error = props.error;
|
|
197
203
|
stopCompaction(sessionID);
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
(
|
|
201
|
-
|
|
202
|
-
notifySessionError(sessionID, errorTitle, getSessionTitle(sessionID));
|
|
204
|
+
const errorTitle = extractGatewayErrorDetails(error)?.message || unwrapError(error);
|
|
205
|
+
if (!isAbortError(error)) {
|
|
206
|
+
notifyTurnEnd(ctx, sessionID, (id) => notifySessionError(id, errorTitle, getSessionTitle(sessionID)));
|
|
207
|
+
}
|
|
203
208
|
const key = runtimeKeys.runtimeMessages(sessionID);
|
|
204
209
|
queryClient.cancelQueries({ queryKey: key });
|
|
205
210
|
queryClient.setQueryData(key, (old) => {
|
|
@@ -19,6 +19,7 @@ export type HandlerContext = {
|
|
|
19
19
|
reconcileSessionTail?: (sessionID: string, reason: SessionSyncReason) => Promise<void>;
|
|
20
20
|
userPartsGraceMs?: number;
|
|
21
21
|
projectId?: string | null;
|
|
22
|
+
sessionId?: string | null;
|
|
22
23
|
} & {
|
|
23
24
|
reconcileTail: (sessionID: string, reason: import('../../core/session-sync/session-sync-controller.js').SessionSyncReason) => Promise<void>;
|
|
24
25
|
getSessionTitle: (sessionID: string) => string | undefined;
|
|
@@ -25,3 +25,4 @@ export declare function scheduleProjectMetadataRefetch(queryClient: QueryClient)
|
|
|
25
25
|
export declare function refetchBeeuniSessionMirrors(queryClient: QueryClient, projectId: string | null): void;
|
|
26
26
|
export declare function realRuntimeTitle(value: unknown): string | null;
|
|
27
27
|
export declare function patchBeeuniSessionTitleMirrors(queryClient: QueryClient, projectId: string | null, nativeSessionId: string, title: string | null): void;
|
|
28
|
+
export declare function notificationSessionId(queryClient: QueryClient, projectId: string | null | undefined, streamSessionId: string | null | undefined, runtimeId: string, subAgentAsStream?: boolean): string | null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { STREAM_OBSERVATION_MAX_MS } from '../../core/session/working.js';
|
|
2
2
|
import { runtimeKeys } from '../use-opencode-sessions/index.js';
|
|
3
3
|
import { qk } from '../query-keys.js';
|
|
4
|
-
import { updateCachedProjectSessions } from '../session-cache-write.js';
|
|
4
|
+
import { findCachedProjectSession, updateCachedProjectSessions } from '../session-cache-write.js';
|
|
5
5
|
export const WIRE_STATUS_FILL_FRESHNESS_MS = STREAM_OBSERVATION_MAX_MS;
|
|
6
6
|
export function shouldSkipStatusFill(input) {
|
|
7
7
|
if (!input.hasSlot)
|
|
@@ -124,3 +124,13 @@ export function patchBeeuniSessionTitleMirrors(queryClient, projectId, nativeSes
|
|
|
124
124
|
return changed ? next : rows;
|
|
125
125
|
});
|
|
126
126
|
}
|
|
127
|
+
export function notificationSessionId(queryClient, projectId, streamSessionId, runtimeId, subAgentAsStream = false) {
|
|
128
|
+
if (!streamSessionId)
|
|
129
|
+
return runtimeId;
|
|
130
|
+
const row = projectId
|
|
131
|
+
? findCachedProjectSession(queryClient, projectId, (session) => (session.runtime_session_id ?? session.opencode_session_id) === runtimeId)
|
|
132
|
+
: undefined;
|
|
133
|
+
if (row)
|
|
134
|
+
return row.session_id;
|
|
135
|
+
return subAgentAsStream ? streamSessionId : null;
|
|
136
|
+
}
|
|
@@ -11,6 +11,10 @@ export interface UseRuntimeLocalOptions {
|
|
|
11
11
|
defaultAgentName?: string | null;
|
|
12
12
|
freeTier?: boolean;
|
|
13
13
|
resolveServerDefault?: (agentName: string | undefined) => ModelKey | undefined;
|
|
14
|
+
projectSession?: {
|
|
15
|
+
metadata?: Record<string, unknown> | null;
|
|
16
|
+
} | null;
|
|
17
|
+
lastPromptModel?: ModelKey;
|
|
14
18
|
}
|
|
15
19
|
export interface RuntimeLocalAgent {
|
|
16
20
|
current: Agent | undefined;
|
|
@@ -64,7 +68,7 @@ export declare function resolveCurrentAgentName(input: {
|
|
|
64
68
|
explicitAgentName?: string;
|
|
65
69
|
lastAgentName?: string;
|
|
66
70
|
}): string | undefined;
|
|
67
|
-
export declare function useRuntimeLocal({ agents: rawAgents, providers, config, sessionId, boundAgentName, defaultAgentName, resolveServerDefault, }: UseRuntimeLocalOptions): RuntimeLocal;
|
|
71
|
+
export declare function useRuntimeLocal({ agents: rawAgents, providers, config, sessionId, boundAgentName, defaultAgentName, resolveServerDefault, projectSession, lastPromptModel, }: UseRuntimeLocalOptions): RuntimeLocal;
|
|
68
72
|
export type UseOpenCodeLocalOptions = UseRuntimeLocalOptions;
|
|
69
73
|
export type OpenCodeLocalAgent = RuntimeLocalAgent;
|
|
70
74
|
export type OpenCodeLocalModel = RuntimeLocalModel;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { flattenModels, isOfferedModel } from './model-flatten.js';
|
|
3
3
|
import { composerSelectableAgents } from '../core/agents/composer-agents.js';
|
|
4
|
-
import { resolveComposerModel } from '../core/models/composer-model.js';
|
|
4
|
+
import { resolveComposerModel, sessionModelCandidates } from '../core/models/composer-model.js';
|
|
5
5
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
6
6
|
import { createAgentSelectionScope } from './agent-selection-scope.js';
|
|
7
7
|
import { useBeeuniRouteProjectId } from './route-project.js';
|
|
@@ -65,7 +65,7 @@ export function resolveCurrentAgentName(input) {
|
|
|
65
65
|
defaultAgentName ??
|
|
66
66
|
(input.sessionId ? undefined : input.lastAgentName));
|
|
67
67
|
}
|
|
68
|
-
export function useRuntimeLocal({ agents: rawAgents, providers, config, sessionId, boundAgentName, defaultAgentName, resolveServerDefault, }) {
|
|
68
|
+
export function useRuntimeLocal({ agents: rawAgents, providers, config, sessionId, boundAgentName, defaultAgentName, resolveServerDefault, projectSession, lastPromptModel, }) {
|
|
69
69
|
const providerMode = useMemo(() => modelProviderMode(providers), [providers]);
|
|
70
70
|
const flatModels = useMemo(() => flattenModels(providers, { providerMode }), [providers, providerMode]);
|
|
71
71
|
const projectId = useBeeuniRouteProjectId();
|
|
@@ -119,11 +119,23 @@ export function useRuntimeLocal({ agents: rawAgents, providers, config, sessionI
|
|
|
119
119
|
return visibleAgents[0];
|
|
120
120
|
}, [visibleAgents, currentAgentName]);
|
|
121
121
|
const agentModelSlotKey = useMemo(() => agentScopedModelSelectionKey(providerMode, currentAgent?.name), [providerMode, currentAgent?.name]);
|
|
122
|
+
const sessionModels = useMemo(() => sessionModelCandidates({
|
|
123
|
+
session: projectSession,
|
|
124
|
+
lastPromptModel,
|
|
125
|
+
gatewayEnabled: providerMode === 'gateway',
|
|
126
|
+
}), [
|
|
127
|
+
projectSession?.metadata?.opencode_model,
|
|
128
|
+
projectSession?.metadata?.opencode_model_source,
|
|
129
|
+
lastPromptModel?.providerID,
|
|
130
|
+
lastPromptModel?.modelID,
|
|
131
|
+
providerMode,
|
|
132
|
+
]);
|
|
122
133
|
const modelResolution = useMemo(() => resolveComposerModel({
|
|
123
134
|
models: flatModels,
|
|
124
135
|
picks: [
|
|
125
136
|
scopedSessionModelKey ? modelStore.getSessionModel(scopedSessionModelKey) : undefined,
|
|
126
137
|
sessionId ? modelStore.getSessionModel(sessionId) : undefined,
|
|
138
|
+
...sessionModels,
|
|
127
139
|
modelStore.getSelectedModel(agentModelSlotKey),
|
|
128
140
|
currentAgent ? modelStore.getSelectedModel(currentAgent.name) : undefined,
|
|
129
141
|
],
|
|
@@ -140,6 +152,7 @@ export function useRuntimeLocal({ agents: rawAgents, providers, config, sessionI
|
|
|
140
152
|
agentModelSlotKey,
|
|
141
153
|
currentAgent,
|
|
142
154
|
resolveServerDefault,
|
|
155
|
+
sessionModels,
|
|
143
156
|
config?.model,
|
|
144
157
|
providers,
|
|
145
158
|
modelStore,
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import type { Command } from '../../core/runtime/runtime-types.js';
|
|
2
|
-
export declare function useRuntimeCommands(): import("@tanstack/react-query").UseQueryResult<Command[], Error>;
|
|
2
|
+
export declare function useRuntimeCommands(options?: UseRuntimeCommandsOptions): import("@tanstack/react-query").UseQueryResult<Command[], Error>;
|
|
3
|
+
export interface UseRuntimeCommandsOptions {
|
|
4
|
+
agent?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class CommandNotEnabledError extends Error {
|
|
7
|
+
readonly command: string;
|
|
8
|
+
readonly agent: string;
|
|
9
|
+
readonly status = 403;
|
|
10
|
+
readonly code = "command_not_enabled";
|
|
11
|
+
constructor(command: string, agent: string);
|
|
12
|
+
}
|
|
3
13
|
export interface ExecuteRuntimeCommandInput {
|
|
4
14
|
sessionId: string;
|
|
5
15
|
command: string;
|
|
@@ -4,7 +4,8 @@ import { getClient } from '../../core/runtime/client.js';
|
|
|
4
4
|
import { useRuntimeSupports } from '../use-runtime-supports.js';
|
|
5
5
|
import { runtimeKeys, useRuntimeReady } from './keys.js';
|
|
6
6
|
import { unwrap, asRuntimeList } from './shared.js';
|
|
7
|
-
export function useRuntimeCommands() {
|
|
7
|
+
export function useRuntimeCommands(options = {}) {
|
|
8
|
+
const { agent } = options;
|
|
8
9
|
const runtimeReady = useRuntimeReady();
|
|
9
10
|
const supported = useRuntimeSupports('session.commands');
|
|
10
11
|
return useQuery({
|
|
@@ -14,11 +15,26 @@ export function useRuntimeCommands() {
|
|
|
14
15
|
const result = await client.command.list();
|
|
15
16
|
return asRuntimeList(unwrap(result));
|
|
16
17
|
},
|
|
18
|
+
select: agent
|
|
19
|
+
? (commands) => commands.filter((command) => !command.agents || command.agents.includes(agent))
|
|
20
|
+
: undefined,
|
|
17
21
|
enabled: runtimeReady && supported,
|
|
18
22
|
staleTime: Infinity,
|
|
19
23
|
gcTime: 10 * 60 * 1000,
|
|
20
24
|
});
|
|
21
25
|
}
|
|
26
|
+
export class CommandNotEnabledError extends Error {
|
|
27
|
+
command;
|
|
28
|
+
agent;
|
|
29
|
+
status = 403;
|
|
30
|
+
code = 'command_not_enabled';
|
|
31
|
+
constructor(command, agent) {
|
|
32
|
+
super(`The agent "${agent}" cannot run /${command}.`);
|
|
33
|
+
this.command = command;
|
|
34
|
+
this.agent = agent;
|
|
35
|
+
this.name = 'CommandNotEnabledError';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
22
38
|
export async function executeRuntimeCommand({ sessionId, command, args, agent, model, variant, }) {
|
|
23
39
|
const client = getClient();
|
|
24
40
|
const result = await client.session.command({
|
|
@@ -29,6 +45,10 @@ export async function executeRuntimeCommand({ sessionId, command, args, agent, m
|
|
|
29
45
|
...(model ? { model } : {}),
|
|
30
46
|
...(variant ? { variant } : {}),
|
|
31
47
|
});
|
|
48
|
+
const body = result.error;
|
|
49
|
+
if (result.response?.status === 403 && body?.error === 'command_not_enabled') {
|
|
50
|
+
throw new CommandNotEnabledError(String(body.command ?? command), String(body.agent ?? agent ?? ''));
|
|
51
|
+
}
|
|
32
52
|
unwrap(result);
|
|
33
53
|
}
|
|
34
54
|
export function useExecuteRuntimeCommand() {
|