@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
|
+
import { reviewItemTarget } from './review-items.js';
|
|
2
|
+
export const PROJECT_ACTIONS = {
|
|
3
|
+
PROJECT_READ: 'project.read',
|
|
4
|
+
PROJECT_WRITE: 'project.write',
|
|
5
|
+
PROJECT_DELETE: 'project.delete',
|
|
6
|
+
PROJECT_SESSION_READ: 'project.session.read',
|
|
7
|
+
PROJECT_SESSION_START: 'project.session.start',
|
|
8
|
+
PROJECT_SESSION_STOP: 'project.session.stop',
|
|
9
|
+
PROJECT_SESSION_BINDINGS_WRITE: 'project.session.bindings.write',
|
|
10
|
+
PROJECT_MEMBERS_READ: 'project.members.read',
|
|
11
|
+
PROJECT_MEMBERS_MANAGE: 'project.members.manage',
|
|
12
|
+
PROJECT_TRIGGER_READ: 'project.trigger.read',
|
|
13
|
+
PROJECT_TRIGGER_CREATE: 'project.trigger.create',
|
|
14
|
+
PROJECT_TRIGGER_UPDATE: 'project.trigger.update',
|
|
15
|
+
PROJECT_TRIGGER_DELETE: 'project.trigger.delete',
|
|
16
|
+
PROJECT_TRIGGER_FIRE: 'project.trigger.fire',
|
|
17
|
+
PROJECT_GATEWAY_LOGS_READ: 'project.gateway.logs.read',
|
|
18
|
+
PROJECT_GATEWAY_SPEND_READ: 'project.gateway.spend.read',
|
|
19
|
+
PROJECT_USAGE_READ: 'project.usage.read',
|
|
20
|
+
PROJECT_GATEWAY_BUDGET_SET: 'project.gateway.budget.set',
|
|
21
|
+
PROJECT_GATEWAY_KEYS_MANAGE: 'project.gateway.keys.manage',
|
|
22
|
+
PROJECT_AGENT_READ: 'project.agent.read',
|
|
23
|
+
PROJECT_AGENT_WRITE: 'project.agent.write',
|
|
24
|
+
PROJECT_SKILL_READ: 'project.skill.read',
|
|
25
|
+
PROJECT_SKILL_WRITE: 'project.skill.write',
|
|
26
|
+
PROJECT_COMMAND_READ: 'project.command.read',
|
|
27
|
+
PROJECT_COMMAND_WRITE: 'project.command.write',
|
|
28
|
+
PROJECT_FILE_READ: 'project.file.read',
|
|
29
|
+
PROJECT_FILE_WRITE: 'project.file.write',
|
|
30
|
+
PROJECT_SETTINGS_WRITE: 'project.settings.write',
|
|
31
|
+
PROJECT_SANDBOX_WRITE: 'project.sandbox.write',
|
|
32
|
+
PROJECT_MODEL_READ: 'project.model.read',
|
|
33
|
+
PROJECT_MODEL_WRITE: 'project.model.write',
|
|
34
|
+
PROJECT_GITOPS_READ: 'project.gitops.read',
|
|
35
|
+
PROJECT_GITOPS_PUSH: 'project.gitops.push',
|
|
36
|
+
PROJECT_GITOPS_MERGE: 'project.gitops.merge',
|
|
37
|
+
PROJECT_GITOPS_REF_ANY: 'project.gitops.ref.any',
|
|
38
|
+
PROJECT_GITOPS_REF_DELETE: 'project.gitops.ref.delete',
|
|
39
|
+
PROJECT_SECRET_READ: 'project.secret.read',
|
|
40
|
+
PROJECT_SECRET_WRITE: 'project.secret.write',
|
|
41
|
+
PROJECT_CONNECTOR_READ: 'project.connector.read',
|
|
42
|
+
PROJECT_CONNECTOR_CONNECTIONS_MANAGE: 'project.connector.connections.manage',
|
|
43
|
+
PROJECT_CONNECTOR_WRITE: 'project.connector.write',
|
|
44
|
+
PROJECT_APP_READ: 'project.app.read',
|
|
45
|
+
PROJECT_APP_WRITE: 'project.app.write',
|
|
46
|
+
PROJECT_APP_DEPLOY: 'project.app.deploy',
|
|
47
|
+
PROJECT_APP_ADMIN: 'project.app.admin',
|
|
48
|
+
PROJECT_REVIEW_READ: 'project.review.read',
|
|
49
|
+
PROJECT_REVIEW_SUBMIT: 'project.review.submit',
|
|
50
|
+
PROJECT_REVIEW_ACT: 'project.review.act',
|
|
51
|
+
PROJECT_CREDENTIALS_ISSUE: 'project.credentials.issue',
|
|
52
|
+
};
|
|
53
|
+
export const TRIGGER_CONTROL_ACTIONS = [
|
|
54
|
+
PROJECT_ACTIONS.PROJECT_WRITE,
|
|
55
|
+
PROJECT_ACTIONS.PROJECT_TRIGGER_CREATE,
|
|
56
|
+
PROJECT_ACTIONS.PROJECT_TRIGGER_FIRE,
|
|
57
|
+
PROJECT_ACTIONS.PROJECT_TRIGGER_UPDATE,
|
|
58
|
+
PROJECT_ACTIONS.PROJECT_TRIGGER_DELETE,
|
|
59
|
+
];
|
|
60
|
+
export function triggerControlsFrom(cans) {
|
|
61
|
+
const allowed = (action) => cans[action]?.allowed === true;
|
|
62
|
+
const write = allowed(PROJECT_ACTIONS.PROJECT_WRITE);
|
|
63
|
+
return {
|
|
64
|
+
canCreate: write && allowed(PROJECT_ACTIONS.PROJECT_TRIGGER_CREATE),
|
|
65
|
+
canFire: allowed(PROJECT_ACTIONS.PROJECT_TRIGGER_FIRE),
|
|
66
|
+
canUpdate: write && allowed(PROJECT_ACTIONS.PROJECT_TRIGGER_UPDATE),
|
|
67
|
+
canDelete: write && allowed(PROJECT_ACTIONS.PROJECT_TRIGGER_DELETE),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export const REVIEW_CONTROL_ACTIONS = [
|
|
71
|
+
PROJECT_ACTIONS.PROJECT_WRITE,
|
|
72
|
+
PROJECT_ACTIONS.PROJECT_GITOPS_PUSH,
|
|
73
|
+
PROJECT_ACTIONS.PROJECT_GITOPS_MERGE,
|
|
74
|
+
PROJECT_ACTIONS.PROJECT_REVIEW_ACT,
|
|
75
|
+
];
|
|
76
|
+
export function changeRequestControlsFrom(cans) {
|
|
77
|
+
const allowed = (action) => cans[action]?.allowed === true;
|
|
78
|
+
const write = allowed(PROJECT_ACTIONS.PROJECT_WRITE);
|
|
79
|
+
return {
|
|
80
|
+
canOpen: write && allowed(PROJECT_ACTIONS.PROJECT_GITOPS_PUSH),
|
|
81
|
+
canMerge: write && allowed(PROJECT_ACTIONS.PROJECT_GITOPS_MERGE),
|
|
82
|
+
canClose: write,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export function reviewVerdictAllowed(item, verdict, cans) {
|
|
86
|
+
const target = reviewItemTarget(item.id);
|
|
87
|
+
if (target.type === 'connector_call') {
|
|
88
|
+
const call = item.kind === 'approval' ? item.detail.actions?.[0] : undefined;
|
|
89
|
+
return ((verdict === 'approve' || verdict === 'reject') &&
|
|
90
|
+
call?.canResolve !== false &&
|
|
91
|
+
call?.previewAuthorized !== false);
|
|
92
|
+
}
|
|
93
|
+
if (target.type === 'change_request') {
|
|
94
|
+
if (verdict === 'answer')
|
|
95
|
+
return false;
|
|
96
|
+
if (verdict === 'approve')
|
|
97
|
+
return changeRequestControlsFrom(cans).canMerge;
|
|
98
|
+
}
|
|
99
|
+
return (cans[PROJECT_ACTIONS.PROJECT_WRITE]?.allowed === true &&
|
|
100
|
+
cans[PROJECT_ACTIONS.PROJECT_REVIEW_ACT]?.allowed === true);
|
|
101
|
+
}
|
|
@@ -22,7 +22,7 @@ export declare function unregisterDeviceToken(deviceToken: string, options?: {
|
|
|
22
22
|
success: true;
|
|
23
23
|
deleted: boolean;
|
|
24
24
|
}>;
|
|
25
|
-
export declare const INBOX_NOTIFICATION_KINDS: readonly ["turn_done", "turn_error", "question", "permission", "shared", "automation_failed", "automation_recovered"];
|
|
25
|
+
export declare const INBOX_NOTIFICATION_KINDS: readonly ["turn_done", "turn_error", "question", "permission", "shared", "automation_failed", "automation_recovered", "capture_device_down", "capture_device_recovered"];
|
|
26
26
|
export type InboxNotificationKind = (typeof INBOX_NOTIFICATION_KINDS)[number];
|
|
27
27
|
export interface InboxNotification {
|
|
28
28
|
id: string;
|
|
@@ -14,6 +14,8 @@ export const INBOX_NOTIFICATION_KINDS = [
|
|
|
14
14
|
'shared',
|
|
15
15
|
'automation_failed',
|
|
16
16
|
'automation_recovered',
|
|
17
|
+
'capture_device_down',
|
|
18
|
+
'capture_device_recovered',
|
|
17
19
|
];
|
|
18
20
|
export async function listNotifications(params = {}, options) {
|
|
19
21
|
const query = new URLSearchParams();
|
|
@@ -39,6 +41,8 @@ export const DEFAULT_NOTIFICATION_PREFERENCES = {
|
|
|
39
41
|
shared: { push: true, email: true },
|
|
40
42
|
automation_failed: { push: true, email: true },
|
|
41
43
|
automation_recovered: { push: true, email: false },
|
|
44
|
+
capture_device_down: { push: true, email: true },
|
|
45
|
+
capture_device_recovered: { push: true, email: false },
|
|
42
46
|
};
|
|
43
47
|
export async function getNotificationPreferences() {
|
|
44
48
|
return unwrap(await backendApi.get('/notifications/preferences', { showErrors: false }));
|
|
@@ -2,8 +2,8 @@ import type { CatalogModel } from '@beeuni/llm-catalog';
|
|
|
2
2
|
import { type ApiClientOptions } from '../../http/api-client.js';
|
|
3
3
|
import type { SandboxProviderName } from '../platform-client/types.js';
|
|
4
4
|
import { type ProjectFileEntry, type ProjectGitConnection, type ProjectRole, type ServerTokenOptions } from './shared.js';
|
|
5
|
-
export type FeatureFlagKey = 'agent_tunnel' | 'marketplace' | 'connectors_api_discover' | 'agentmail_email' | 'teams' | 'llm_gateway' | 'review_center' | 'meta_agent' | 'apps' | 'monitors' | 'reminders' | 'warm_sessions' | 'secrets_egress' | 'pi_worker' | 'session_transcript_history' | 'pooled_provider_secrets' | 'pi_harness' | 'config_releases' | 'agent_principal' | 'us_region' | 'event_triggers' | 'notification_center' | 'volumes' | 'stateless_sessions' | 'drives' | 'ephemeral_sandboxes' | 'session_log' | 'human_messaging';
|
|
6
|
-
type GraduatedFeatureFlagKey = 'agent_tunnel' | 'teams' | 'review_center' | 'session_transcript_history' | 'agent_principal' | 'human_messaging' | 'pi_worker' | 'config_releases';
|
|
5
|
+
export type FeatureFlagKey = 'agent_tunnel' | 'marketplace' | 'connectors_api_discover' | 'agentmail_email' | 'teams' | 'llm_gateway' | 'review_center' | 'meta_agent' | 'apps' | 'monitors' | 'reminders' | 'warm_sessions' | 'secrets_egress' | 'pi_worker' | 'session_transcript_history' | 'pooled_provider_secrets' | 'pi_harness' | 'genui' | 'config_releases' | 'agent_principal' | 'us_region' | 'event_triggers' | 'notification_center' | 'volumes' | 'stateless_sessions' | 'drives' | 'ephemeral_sandboxes' | 'session_log' | 'session_log_restore' | 'human_messaging';
|
|
6
|
+
type GraduatedFeatureFlagKey = 'agent_tunnel' | 'teams' | 'review_center' | 'session_transcript_history' | 'agent_principal' | 'human_messaging' | 'pi_worker' | 'config_releases' | 'apps' | 'stateless_sessions' | 'ephemeral_sandboxes';
|
|
7
7
|
type ServedFeatureFlagKey = Exclude<FeatureFlagKey, GraduatedFeatureFlagKey>;
|
|
8
8
|
export declare const FEATURE_FLAG_KEYS: readonly FeatureFlagKey[];
|
|
9
9
|
export type FeatureFlagStability = 'experimental' | 'beta' | 'stable';
|
|
@@ -138,6 +138,7 @@ export interface GatewayCatalogModel {
|
|
|
138
138
|
}
|
|
139
139
|
export interface ProjectLlmCatalogResponse {
|
|
140
140
|
models: Record<string, GatewayCatalogModel>;
|
|
141
|
+
platformFeePercent?: number;
|
|
141
142
|
managedPricingRoutes?: Record<string, Array<{
|
|
142
143
|
route: string;
|
|
143
144
|
role: 'preferred' | 'eligible';
|
|
@@ -7,21 +7,20 @@ export const FEATURE_FLAG_KEYS = [
|
|
|
7
7
|
'agentmail_email',
|
|
8
8
|
'llm_gateway',
|
|
9
9
|
'meta_agent',
|
|
10
|
-
'apps',
|
|
11
10
|
'monitors',
|
|
12
11
|
'reminders',
|
|
13
12
|
'warm_sessions',
|
|
14
13
|
'secrets_egress',
|
|
15
14
|
'pooled_provider_secrets',
|
|
16
15
|
'pi_harness',
|
|
16
|
+
'genui',
|
|
17
17
|
'us_region',
|
|
18
18
|
'event_triggers',
|
|
19
19
|
'notification_center',
|
|
20
20
|
'volumes',
|
|
21
|
-
'stateless_sessions',
|
|
22
21
|
'drives',
|
|
23
|
-
'ephemeral_sandboxes',
|
|
24
22
|
'session_log',
|
|
23
|
+
'session_log_restore',
|
|
25
24
|
];
|
|
26
25
|
export async function listProjects() {
|
|
27
26
|
return unwrap(await backendApi.get('/projects'));
|
|
@@ -49,6 +49,8 @@ export interface ReviewApprovalAction {
|
|
|
49
49
|
rawArgsPreview?: Record<string, unknown>;
|
|
50
50
|
reviewComplete?: boolean;
|
|
51
51
|
previewAuthorized?: boolean;
|
|
52
|
+
canResolve?: boolean;
|
|
53
|
+
resolvers?: 'managers' | 'managers_and_launcher';
|
|
52
54
|
approvalContext?: string;
|
|
53
55
|
connectorRisk?: string | null;
|
|
54
56
|
policySource: string;
|
|
@@ -138,6 +138,10 @@ function approvalDetail(detail, row) {
|
|
|
138
138
|
rawArgsPreview: hasArgsPreview ? rawArgsPreview : undefined,
|
|
139
139
|
reviewComplete: detail.args_preview_complete === true,
|
|
140
140
|
previewAuthorized: detail.args_preview_authorized !== false,
|
|
141
|
+
canResolve: typeof row.can_resolve === 'boolean'
|
|
142
|
+
? row.can_resolve
|
|
143
|
+
: detail.args_preview_authorized !== false,
|
|
144
|
+
...(row.resolvers ? { resolvers: row.resolvers } : {}),
|
|
141
145
|
approvalContext: asString(detail.approval_context),
|
|
142
146
|
connectorRisk: asString(detail.risk) ?? null,
|
|
143
147
|
policySource: 'Requires approval',
|
|
@@ -24,13 +24,27 @@ export interface ApiReviewItem {
|
|
|
24
24
|
metadata: Record<string, unknown>;
|
|
25
25
|
created_at: string;
|
|
26
26
|
updated_at: string;
|
|
27
|
+
can_resolve?: boolean;
|
|
28
|
+
resolvers?: 'managers' | 'managers_and_launcher' | null;
|
|
27
29
|
}
|
|
28
|
-
export
|
|
30
|
+
export interface ReviewItemsQuery {
|
|
29
31
|
segment?: ReviewSegment;
|
|
30
32
|
kind?: ReviewItemKind;
|
|
31
|
-
|
|
33
|
+
sessionId?: string;
|
|
34
|
+
limit?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface ReviewItemsPage {
|
|
32
37
|
review_items: ApiReviewItem[];
|
|
33
|
-
|
|
38
|
+
next_cursor?: string | null;
|
|
39
|
+
}
|
|
40
|
+
export declare function listReviewItems(projectId: string, params?: ReviewItemsQuery & {
|
|
41
|
+
cursor?: string;
|
|
42
|
+
}): Promise<ReviewItemsPage>;
|
|
43
|
+
export interface ReviewSummary {
|
|
44
|
+
needs_you_total: number;
|
|
45
|
+
needs_you_by_session: Record<string, number>;
|
|
46
|
+
}
|
|
47
|
+
export declare function getReviewSummary(projectId: string): Promise<ReviewSummary>;
|
|
34
48
|
export declare function getReviewItem(projectId: string, reviewItemId: string): Promise<{
|
|
35
49
|
review_item: ApiReviewItem;
|
|
36
50
|
}>;
|
|
@@ -6,9 +6,20 @@ export async function listReviewItems(projectId, params) {
|
|
|
6
6
|
q.set('segment', params.segment);
|
|
7
7
|
if (params?.kind)
|
|
8
8
|
q.set('kind', params.kind);
|
|
9
|
+
if (params?.sessionId)
|
|
10
|
+
q.set('session_id', params.sessionId);
|
|
11
|
+
if (params?.limit != null)
|
|
12
|
+
q.set('limit', String(params.limit));
|
|
13
|
+
if (params?.cursor)
|
|
14
|
+
q.set('cursor', params.cursor);
|
|
9
15
|
const qs = q.toString();
|
|
10
16
|
return unwrap(await backendApi.get(`/projects/${projectId}/review/items${qs ? `?${qs}` : ''}`, { showErrors: false }));
|
|
11
17
|
}
|
|
18
|
+
export async function getReviewSummary(projectId) {
|
|
19
|
+
return unwrap(await backendApi.get(`/projects/${projectId}/review/summary`, {
|
|
20
|
+
showErrors: false,
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
12
23
|
export async function getReviewItem(projectId, reviewItemId) {
|
|
13
24
|
return unwrap(await backendApi.get(`/projects/${projectId}/review/items/${reviewItemId}`));
|
|
14
25
|
}
|
|
@@ -4,6 +4,7 @@ export type SecretDeliveryStrategy = 'runtime' | 'egress' | 'broker' | 'denied';
|
|
|
4
4
|
export type SecretConsumer = 'sandbox' | 'llm_gateway' | 'connector' | 'git_proxy' | 'http_broker' | 'network';
|
|
5
5
|
export type SecretDeliveryStatus = 'available' | 'unavailable' | 'disabled';
|
|
6
6
|
export type SecretDeliveryBlockedReason = 'no_agent_grant';
|
|
7
|
+
export type SecretValueStatus = 'ok' | 'undecryptable';
|
|
7
8
|
export type SecretInjectionSlot = {
|
|
8
9
|
kind: 'header';
|
|
9
10
|
name: string;
|
|
@@ -62,6 +63,7 @@ export interface ProjectSecret {
|
|
|
62
63
|
mine: {
|
|
63
64
|
active: boolean;
|
|
64
65
|
updated_at: string;
|
|
66
|
+
status?: SecretValueStatus;
|
|
65
67
|
} | null;
|
|
66
68
|
effective_source: 'mine' | 'shared' | 'none';
|
|
67
69
|
can_manage_shared: boolean;
|
|
@@ -76,6 +78,7 @@ export interface ProjectSecret {
|
|
|
76
78
|
requires_rotation?: boolean;
|
|
77
79
|
shared_with?: ConnectionShare[];
|
|
78
80
|
usable?: boolean;
|
|
81
|
+
status?: SecretValueStatus;
|
|
79
82
|
}
|
|
80
83
|
export interface SecretSharePrincipal {
|
|
81
84
|
principal_type: 'user' | 'group' | 'agent';
|
|
@@ -107,6 +107,18 @@ function showItems(raw) {
|
|
|
107
107
|
return [];
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
+
function asV1Message(record) {
|
|
111
|
+
const parts = record.blocks.filter(isObject).map((block) => {
|
|
112
|
+
if (block.type === "attachment")
|
|
113
|
+
return { type: "file", url: block.ref ?? block.url, filename: block.name, mime: block.mime };
|
|
114
|
+
if (block.type === "tool_call")
|
|
115
|
+
return { type: "tool", tool: block.name, state: { input: block.input } };
|
|
116
|
+
if (block.type === "harness" && isObject(block.data))
|
|
117
|
+
return block.data;
|
|
118
|
+
return block;
|
|
119
|
+
});
|
|
120
|
+
return { info: { id: record.message_id, role: record.role }, parts };
|
|
121
|
+
}
|
|
110
122
|
function attachmentsFromTextPart(text, add) {
|
|
111
123
|
for (const attrs of fileTagAttributes(text)) {
|
|
112
124
|
add(tagAttribute(attrs, "attachment"), tagAttribute(attrs, "filename") ?? basename(tagAttribute(attrs, "path")), tagAttribute(attrs, "mime"));
|
|
@@ -123,7 +135,8 @@ export function findSessionAttachments(messages) {
|
|
|
123
135
|
return [];
|
|
124
136
|
const found = [];
|
|
125
137
|
const seen = new Set();
|
|
126
|
-
for (const
|
|
138
|
+
for (const entry of messages) {
|
|
139
|
+
const message = isObject(entry) && Array.isArray(entry.blocks) ? asV1Message(entry) : entry;
|
|
127
140
|
if (!isObject(message) || !isObject(message.info) || !Array.isArray(message.parts))
|
|
128
141
|
continue;
|
|
129
142
|
const messageId = stringOrNull(message.info.id);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ApiClientOptions } from '../../http/api-client.js';
|
|
2
|
+
import { type SessionLogPage, type SessionLogPageQuery } from '../../session-log/source.js';
|
|
2
3
|
import type { AuditEvent } from './audit.js';
|
|
3
4
|
import { type ConnectorSharing } from './shared.js';
|
|
4
5
|
export type ProjectSessionStatus = 'queued' | 'branching' | 'provisioning' | 'running' | 'stopped' | 'failed' | 'completed';
|
|
@@ -52,6 +53,8 @@ export interface ProjectSession {
|
|
|
52
53
|
runtime_status?: 'provisioning' | 'active' | 'stopped' | 'error' | 'archived' | null;
|
|
53
54
|
deleted_at?: string | null;
|
|
54
55
|
deleted_by?: string | null;
|
|
56
|
+
pinned_at?: string | null;
|
|
57
|
+
archived_at?: string | null;
|
|
55
58
|
created_at: string;
|
|
56
59
|
updated_at: string;
|
|
57
60
|
}
|
|
@@ -83,6 +86,7 @@ export interface CreateProjectSessionInput {
|
|
|
83
86
|
agent_name?: string;
|
|
84
87
|
sandbox_slug?: string;
|
|
85
88
|
initial_prompt?: string;
|
|
89
|
+
initial_context?: string;
|
|
86
90
|
pending_prompt?: PendingSessionPrompt;
|
|
87
91
|
model?: string;
|
|
88
92
|
opencode_model?: string;
|
|
@@ -137,6 +141,7 @@ export interface ListProjectSessionsOptions {
|
|
|
137
141
|
startedBy?: 'me' | 'others' | 'automated';
|
|
138
142
|
q?: string;
|
|
139
143
|
labels?: string[];
|
|
144
|
+
view?: 'pinned' | 'archived';
|
|
140
145
|
}
|
|
141
146
|
export interface ProjectSessionPage {
|
|
142
147
|
items: ProjectSession[];
|
|
@@ -164,6 +169,12 @@ export declare function getSessionWatch(projectId: string, sessionId: string): P
|
|
|
164
169
|
export declare function setSessionWatch(projectId: string, sessionId: string, watching: boolean): Promise<{
|
|
165
170
|
watching: boolean;
|
|
166
171
|
}>;
|
|
172
|
+
export interface SessionListState {
|
|
173
|
+
pinned_at: string | null;
|
|
174
|
+
archived_at: string | null;
|
|
175
|
+
}
|
|
176
|
+
export declare function setSessionPinned(projectId: string, sessionId: string, pinned: boolean): Promise<SessionListState>;
|
|
177
|
+
export declare function setSessionArchived(projectId: string, sessionId: string, archived: boolean): Promise<SessionListState>;
|
|
167
178
|
export interface SessionPreviewCandidate {
|
|
168
179
|
id: string;
|
|
169
180
|
label: string;
|
|
@@ -247,6 +258,8 @@ export interface SessionAuditAction {
|
|
|
247
258
|
at: string;
|
|
248
259
|
resolved_at: string | null;
|
|
249
260
|
approval_url?: string | null;
|
|
261
|
+
can_resolve?: boolean;
|
|
262
|
+
resolvers?: 'managers' | 'managers_and_launcher' | null;
|
|
250
263
|
}
|
|
251
264
|
export interface SessionAudit {
|
|
252
265
|
session_id: string;
|
|
@@ -322,6 +335,9 @@ export declare function getSessionTranscriptSync(projectId: string, sessionId: s
|
|
|
322
335
|
before?: string | null;
|
|
323
336
|
child?: string | null;
|
|
324
337
|
}): Promise<SessionTranscriptSyncEnvelope>;
|
|
338
|
+
export declare function getSessionLogPage(projectId: string, sessionId: string, query?: SessionLogPageQuery, options?: {
|
|
339
|
+
signal?: AbortSignal;
|
|
340
|
+
}): Promise<SessionLogPage | null>;
|
|
325
341
|
export type SessionTurnState = 'delivering' | 'active';
|
|
326
342
|
export interface SessionTurn {
|
|
327
343
|
turn_token: string;
|
|
@@ -352,8 +368,11 @@ export interface SessionTurnStatus {
|
|
|
352
368
|
turns: SessionTurn[];
|
|
353
369
|
last_ended?: SessionTurnEnded;
|
|
354
370
|
recent_failures?: SessionTurnFailure[];
|
|
371
|
+
can_stop?: boolean;
|
|
355
372
|
}
|
|
356
|
-
export declare function getSessionTurn(projectId: string, sessionId: string
|
|
373
|
+
export declare function getSessionTurn(projectId: string, sessionId: string, options?: {
|
|
374
|
+
showErrors?: boolean;
|
|
375
|
+
}): Promise<SessionTurnStatus>;
|
|
357
376
|
export interface SessionOpenBundleUnknown {
|
|
358
377
|
known: false;
|
|
359
378
|
reason: string;
|
|
@@ -528,8 +547,15 @@ export interface UpdateProjectSessionInput {
|
|
|
528
547
|
export declare function updateProjectSession(projectId: string, sessionId: string, input: UpdateProjectSessionInput): Promise<ProjectSession>;
|
|
529
548
|
export declare function deleteProjectSession(projectId: string, sessionId: string): Promise<{
|
|
530
549
|
ok: boolean;
|
|
550
|
+
restore_until?: string;
|
|
551
|
+
}>;
|
|
552
|
+
export declare function recoverProjectSession(projectId: string, sessionId: string): Promise<{
|
|
553
|
+
ok: true;
|
|
554
|
+
}>;
|
|
555
|
+
export declare function restoreProjectSession(projectId: string, sessionId: string): Promise<{
|
|
556
|
+
ok: boolean;
|
|
531
557
|
}>;
|
|
532
|
-
export declare function restartProjectSession(projectId: string, sessionId: string,
|
|
558
|
+
export declare function restartProjectSession(projectId: string, sessionId: string, _opts?: {
|
|
533
559
|
reset_machine?: boolean;
|
|
534
560
|
discard_state?: boolean;
|
|
535
561
|
}): Promise<{
|
|
@@ -650,6 +676,7 @@ export type SessionMessageAuthor = {
|
|
|
650
676
|
export interface SessionMessageAuthors {
|
|
651
677
|
authors: Record<string, SessionMessageAuthor>;
|
|
652
678
|
initial_author: SessionMessageAuthor | null;
|
|
679
|
+
stops?: Record<string, SessionMessageAuthor>;
|
|
653
680
|
}
|
|
654
681
|
export declare function getSessionMessageAuthors(projectId: string, sessionId: string): Promise<SessionMessageAuthors>;
|
|
655
682
|
export interface SessionServedModel {
|
|
@@ -2,6 +2,8 @@ import { ApiError, backendApi } from '../../http/api-client.js';
|
|
|
2
2
|
import { markSessionFresh } from '../../http/fresh-sessions.js';
|
|
3
3
|
import { currentSavedCopyStore } from '../../session-sync/saved-copy-store.js';
|
|
4
4
|
import { noteSessionStopped } from '../../http/session-stopped.js';
|
|
5
|
+
import { isSessionLogPage } from '../../session-log/guard.js';
|
|
6
|
+
import { loadSessionLogPage } from '../../session-log/source.js';
|
|
5
7
|
import { unwrap } from './shared.js';
|
|
6
8
|
export function sessionParentId(session) {
|
|
7
9
|
const parent = typeof session.parent_session_id === 'string'
|
|
@@ -34,6 +36,8 @@ function projectSessionListQuery(options) {
|
|
|
34
36
|
params.set('q', q);
|
|
35
37
|
for (const label of options?.labels ?? [])
|
|
36
38
|
params.append('label', label);
|
|
39
|
+
if (options?.view)
|
|
40
|
+
params.set(options.view, 'only');
|
|
37
41
|
return params.size > 0 ? `?${params}` : '';
|
|
38
42
|
}
|
|
39
43
|
export async function listProjectSessionsPage(projectId, options) {
|
|
@@ -63,6 +67,12 @@ export async function setSessionWatch(projectId, sessionId, watching) {
|
|
|
63
67
|
watching,
|
|
64
68
|
}));
|
|
65
69
|
}
|
|
70
|
+
export async function setSessionPinned(projectId, sessionId, pinned) {
|
|
71
|
+
return unwrap(await backendApi.put(`/projects/${projectId}/sessions/${sessionId}/pin`, { pinned }));
|
|
72
|
+
}
|
|
73
|
+
export async function setSessionArchived(projectId, sessionId, archived) {
|
|
74
|
+
return unwrap(await backendApi.put(`/projects/${projectId}/sessions/${sessionId}/archive`, { archived }));
|
|
75
|
+
}
|
|
66
76
|
export function resolvePublicShareUrl(share, origin) {
|
|
67
77
|
const raw = share.public_url ?? share.public_path ?? share.proxy_path ?? share.public_token ?? '';
|
|
68
78
|
if (!raw)
|
|
@@ -165,8 +175,22 @@ export async function getSessionTranscriptSync(projectId, sessionId, options) {
|
|
|
165
175
|
search.set('child', options.child);
|
|
166
176
|
return unwrap(await backendApi.get(`/projects/${projectId}/sessions/${sessionId}/transcript?${search.toString()}`, { showErrors: false, signal: options?.signal }));
|
|
167
177
|
}
|
|
168
|
-
export async function
|
|
169
|
-
|
|
178
|
+
export async function getSessionLogPage(projectId, sessionId, query = {}, options) {
|
|
179
|
+
let page;
|
|
180
|
+
try {
|
|
181
|
+
page = await loadSessionLogPage(projectId, sessionId, query, options?.signal);
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
if (error?.status === 404)
|
|
185
|
+
return null;
|
|
186
|
+
throw error;
|
|
187
|
+
}
|
|
188
|
+
if (!isSessionLogPage(page))
|
|
189
|
+
throw new Error('The response is not a session log page');
|
|
190
|
+
return page;
|
|
191
|
+
}
|
|
192
|
+
export async function getSessionTurn(projectId, sessionId, options) {
|
|
193
|
+
return unwrap(await backendApi.get(`/projects/${projectId}/sessions/${sessionId}/turn`, options?.showErrors === false ? { showErrors: false } : undefined));
|
|
170
194
|
}
|
|
171
195
|
export async function getSessionOpenBundle(projectId, sessionId, options) {
|
|
172
196
|
const search = new URLSearchParams();
|
|
@@ -222,8 +246,14 @@ export async function deleteProjectSession(projectId, sessionId) {
|
|
|
222
246
|
void currentSavedCopyStore()?.remove(projectId, sessionId);
|
|
223
247
|
return result;
|
|
224
248
|
}
|
|
225
|
-
export async function
|
|
226
|
-
return unwrap(await backendApi.post(`/projects/${projectId}/sessions/${sessionId}/
|
|
249
|
+
export async function recoverProjectSession(projectId, sessionId) {
|
|
250
|
+
return unwrap(await backendApi.post(`/projects/${projectId}/sessions/${sessionId}/recover`, {}, { showErrors: false }));
|
|
251
|
+
}
|
|
252
|
+
export async function restoreProjectSession(projectId, sessionId) {
|
|
253
|
+
return unwrap(await backendApi.post(`/projects/${projectId}/sessions/${sessionId}/restore`, {}, { showErrors: false }));
|
|
254
|
+
}
|
|
255
|
+
export async function restartProjectSession(projectId, sessionId, _opts = {}) {
|
|
256
|
+
return unwrap(await backendApi.post(`/projects/${projectId}/sessions/${sessionId}/restart`, {}));
|
|
227
257
|
}
|
|
228
258
|
export async function stopProjectSession(projectId, sessionId) {
|
|
229
259
|
const stopped = unwrap(await backendApi.post(`/projects/${projectId}/sessions/${sessionId}/stop`, {}));
|
|
@@ -158,7 +158,7 @@ export function fetchEventTransport(fetchFn = globalThis.fetch) {
|
|
|
158
158
|
const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
|
|
159
159
|
const cancel = () => {
|
|
160
160
|
try {
|
|
161
|
-
|
|
161
|
+
reader.cancel().catch(() => { });
|
|
162
162
|
}
|
|
163
163
|
catch {
|
|
164
164
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type SessionAudit, type SessionOpenBundle, type SessionPrompt, type SessionTranscriptSyncEnvelope, type SessionTurn, type SessionTurnEnded, type SessionTurnFailure } from '../rest/projects-client/sessions.js';
|
|
2
2
|
export declare const OPEN_BUNDLE_SHARE_MS = 5000;
|
|
3
|
-
export declare const OPEN_BUNDLE_TRANSCRIPT_TTL_MS = 60000;
|
|
4
3
|
export declare const OPEN_BUNDLE_TRANSCRIPT_LIMIT = 40;
|
|
4
|
+
export declare const SAVED_WINDOW_HOLD_MS: number;
|
|
5
|
+
export declare function holdSavedWindow(projectId: string, sessionId: string, envelope: SessionTranscriptSyncEnvelope, nowMs?: number): void;
|
|
6
|
+
export declare function heldSavedWindow(projectId: string, sessionId: string, nowMs?: number): SessionTranscriptSyncEnvelope | null;
|
|
5
7
|
export declare function resetSessionOpenBundles(): void;
|
|
6
8
|
export interface OpenSessionBundleOptions {
|
|
7
9
|
transcript?: number;
|
|
@@ -9,16 +11,14 @@ export interface OpenSessionBundleOptions {
|
|
|
9
11
|
}
|
|
10
12
|
export declare function openSessionBundle(projectId: string, sessionId: string, options?: OpenSessionBundleOptions): void;
|
|
11
13
|
export declare function claimOpenBundle(projectId: string, sessionId: string, nowMs?: number): Promise<SessionOpenBundle | null> | null;
|
|
12
|
-
export declare function settledOpenBundle(projectId: string, sessionId: string, nowMs?: number): SessionOpenBundle | null;
|
|
13
14
|
export interface OpenBundleTurnObservation {
|
|
14
15
|
turns: SessionTurn[];
|
|
15
16
|
last_ended: SessionTurnEnded | undefined;
|
|
16
17
|
recent_failures?: SessionTurnFailure[];
|
|
18
|
+
can_stop?: boolean;
|
|
17
19
|
atMs: number;
|
|
18
20
|
}
|
|
19
21
|
export declare function openBundleTurn(bundle: SessionOpenBundle): OpenBundleTurnObservation | null;
|
|
20
22
|
export declare function openBundleQueue(bundle: SessionOpenBundle): SessionPrompt[] | null;
|
|
21
23
|
export declare function openBundleAudit(bundle: SessionOpenBundle): SessionAudit | null;
|
|
22
24
|
export declare function openBundleHistory(bundle: SessionOpenBundle): SessionTranscriptSyncEnvelope | null;
|
|
23
|
-
export declare function takeOpenBundleTranscriptAbsence(projectId: string, sessionId: string, nowMs?: number): boolean;
|
|
24
|
-
export declare function takeOpenBundleTranscript(projectId: string, sessionId: string, nowMs?: number): SessionTranscriptSyncEnvelope | null;
|
|
@@ -1,17 +1,37 @@
|
|
|
1
1
|
import { getSessionOpenBundle, } from '../rest/projects-client/sessions.js';
|
|
2
2
|
export const OPEN_BUNDLE_SHARE_MS = 5_000;
|
|
3
|
-
export const OPEN_BUNDLE_TRANSCRIPT_TTL_MS = 60_000;
|
|
4
3
|
export const OPEN_BUNDLE_TRANSCRIPT_LIMIT = 40;
|
|
4
|
+
export const SAVED_WINDOW_HOLD_MS = 5 * 60_000;
|
|
5
|
+
const HELD_WINDOW_CAP = 16;
|
|
6
|
+
const heldWindows = new Map();
|
|
7
|
+
export function holdSavedWindow(projectId, sessionId, envelope, nowMs = Date.now()) {
|
|
8
|
+
const key = scopeKey(projectId, sessionId);
|
|
9
|
+
heldWindows.delete(key);
|
|
10
|
+
heldWindows.set(key, { envelope, atMs: nowMs });
|
|
11
|
+
while (heldWindows.size > HELD_WINDOW_CAP) {
|
|
12
|
+
const oldest = heldWindows.keys().next().value;
|
|
13
|
+
if (oldest === undefined)
|
|
14
|
+
break;
|
|
15
|
+
heldWindows.delete(oldest);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function heldSavedWindow(projectId, sessionId, nowMs = Date.now()) {
|
|
19
|
+
const held = heldWindows.get(scopeKey(projectId, sessionId));
|
|
20
|
+
if (!held)
|
|
21
|
+
return null;
|
|
22
|
+
if (nowMs - held.atMs > SAVED_WINDOW_HOLD_MS) {
|
|
23
|
+
heldWindows.delete(scopeKey(projectId, sessionId));
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return held.envelope;
|
|
27
|
+
}
|
|
5
28
|
const entries = new Map();
|
|
6
|
-
const transcripts = new Map();
|
|
7
|
-
const absentTranscripts = new Map();
|
|
8
29
|
function scopeKey(projectId, sessionId) {
|
|
9
30
|
return `${projectId}/${sessionId}`;
|
|
10
31
|
}
|
|
11
32
|
export function resetSessionOpenBundles() {
|
|
12
33
|
entries.clear();
|
|
13
|
-
|
|
14
|
-
absentTranscripts.clear();
|
|
34
|
+
heldWindows.clear();
|
|
15
35
|
}
|
|
16
36
|
export function openSessionBundle(projectId, sessionId, options = {}) {
|
|
17
37
|
if (!projectId || !sessionId)
|
|
@@ -26,17 +46,12 @@ export function openSessionBundle(projectId, sessionId, options = {}) {
|
|
|
26
46
|
startedAtMs: nowMs,
|
|
27
47
|
settledAtMs: null,
|
|
28
48
|
promise: getSessionOpenBundle(projectId, sessionId, {
|
|
29
|
-
transcript: options.transcript ??
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
stashTranscript(key, bundle, now());
|
|
33
|
-
return bundle;
|
|
34
|
-
})
|
|
35
|
-
.catch(() => null),
|
|
49
|
+
transcript: options.transcript ??
|
|
50
|
+
(heldSavedWindow(projectId, sessionId, nowMs) ? 0 : OPEN_BUNDLE_TRANSCRIPT_LIMIT),
|
|
51
|
+
}).catch(() => null),
|
|
36
52
|
};
|
|
37
53
|
entry.promise = entry.promise.then((bundle) => {
|
|
38
54
|
entry.settledAtMs = now();
|
|
39
|
-
entry.bundle = bundle;
|
|
40
55
|
return bundle;
|
|
41
56
|
});
|
|
42
57
|
entries.set(key, entry);
|
|
@@ -59,10 +74,6 @@ export function claimOpenBundle(projectId, sessionId, nowMs = Date.now()) {
|
|
|
59
74
|
}
|
|
60
75
|
return entry.promise;
|
|
61
76
|
}
|
|
62
|
-
export function settledOpenBundle(projectId, sessionId, nowMs = Date.now()) {
|
|
63
|
-
const entry = entries.get(scopeKey(projectId, sessionId));
|
|
64
|
-
return entry && entry.settledAtMs !== null && claimable(entry, nowMs) ? (entry.bundle ?? null) : null;
|
|
65
|
-
}
|
|
66
77
|
export function openBundleTurn(bundle) {
|
|
67
78
|
const turn = bundle.turn;
|
|
68
79
|
if (!turn || turn.known !== true)
|
|
@@ -72,6 +83,7 @@ export function openBundleTurn(bundle) {
|
|
|
72
83
|
turns: turn.turns ?? [],
|
|
73
84
|
last_ended: turn.last_ended,
|
|
74
85
|
recent_failures: turn.recent_failures,
|
|
86
|
+
...(typeof turn.can_stop === 'boolean' ? { can_stop: turn.can_stop } : {}),
|
|
75
87
|
atMs: Number.isFinite(observedAtMs) ? observedAtMs : Date.now(),
|
|
76
88
|
};
|
|
77
89
|
}
|
|
@@ -104,32 +116,3 @@ export function openBundleHistory(bundle) {
|
|
|
104
116
|
const savedRoot = envelope.runtime_session_id ?? envelope.opencode_session_id;
|
|
105
117
|
return root && savedRoot === root ? envelope : null;
|
|
106
118
|
}
|
|
107
|
-
function stashTranscript(key, bundle, nowMs) {
|
|
108
|
-
const transcript = bundle.transcript;
|
|
109
|
-
if (!transcript || transcript.known !== true || transcript.requested !== true)
|
|
110
|
-
return;
|
|
111
|
-
if (!transcript.available || transcript.messages.length === 0) {
|
|
112
|
-
absentTranscripts.set(key, nowMs);
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
const { known: _known, requested: _requested, ...envelope } = transcript;
|
|
116
|
-
transcripts.set(key, { envelope, stashedAtMs: nowMs });
|
|
117
|
-
}
|
|
118
|
-
export function takeOpenBundleTranscriptAbsence(projectId, sessionId, nowMs = Date.now()) {
|
|
119
|
-
const key = scopeKey(projectId, sessionId);
|
|
120
|
-
const answeredAtMs = absentTranscripts.get(key);
|
|
121
|
-
if (answeredAtMs === undefined)
|
|
122
|
-
return false;
|
|
123
|
-
absentTranscripts.delete(key);
|
|
124
|
-
return nowMs - answeredAtMs <= OPEN_BUNDLE_TRANSCRIPT_TTL_MS;
|
|
125
|
-
}
|
|
126
|
-
export function takeOpenBundleTranscript(projectId, sessionId, nowMs = Date.now()) {
|
|
127
|
-
const key = scopeKey(projectId, sessionId);
|
|
128
|
-
const stash = transcripts.get(key);
|
|
129
|
-
if (!stash)
|
|
130
|
-
return null;
|
|
131
|
-
transcripts.delete(key);
|
|
132
|
-
if (nowMs - stash.stashedAtMs > OPEN_BUNDLE_TRANSCRIPT_TTL_MS)
|
|
133
|
-
return null;
|
|
134
|
-
return stash.envelope;
|
|
135
|
-
}
|