@bbigbang/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.js +380 -0
- package/dist/execution/executionDispatcher.js +3810 -0
- package/dist/main.js +90 -0
- package/dist/nodeEventHistory.js +206 -0
- package/dist/scheduler/dreamLogic.js +50 -0
- package/dist/scheduler/dreamScheduler.js +65 -0
- package/dist/services/agentFileAccessService.js +1913 -0
- package/dist/services/agentRuntimeCleanupBroker.js +62 -0
- package/dist/services/agentSkillsBroker.js +118 -0
- package/dist/services/agentSkillsService.js +83 -0
- package/dist/services/agentWorkspaceBroker.js +937 -0
- package/dist/services/agentWorkspaceService.js +70 -0
- package/dist/services/appVersion.js +14 -0
- package/dist/services/auth.js +586 -0
- package/dist/services/claudeControlBroker.js +154 -0
- package/dist/services/claudeTranscriptBroker.js +100 -0
- package/dist/services/claudeTranscriptService.js +359 -0
- package/dist/services/codexAppServerBroker.js +155 -0
- package/dist/services/codexTranscriptBroker.js +98 -0
- package/dist/services/codexTranscriptService.js +961 -0
- package/dist/services/droidMissionBroker.js +124 -0
- package/dist/services/droidMissionImporter.js +630 -0
- package/dist/services/droidModelOptions.js +165 -0
- package/dist/services/hubServerRegistrationService.js +268 -0
- package/dist/services/libraryManifest.js +43 -0
- package/dist/services/libraryScaffold.js +26 -0
- package/dist/services/libraryService.js +2263 -0
- package/dist/services/memoryService.js +386 -0
- package/dist/services/missionEvidence.js +377 -0
- package/dist/services/missionService.js +2361 -0
- package/dist/services/missionTrace.js +158 -0
- package/dist/services/nativeMissionBriefParser.js +120 -0
- package/dist/services/nativeMissionOrchestrator.js +2045 -0
- package/dist/services/nativeMissionReportGenerator.js +227 -0
- package/dist/services/nativeMissionValidationRunner.js +452 -0
- package/dist/services/nativeMissionWorkerBroker.js +190 -0
- package/dist/services/nodeRegistry.js +34 -0
- package/dist/services/nodeStateReconciler.js +97 -0
- package/dist/services/panelMediaScanner.js +119 -0
- package/dist/services/persistentRuntimeJsonlClient.js +153 -0
- package/dist/services/platformAgentPolicy.js +180 -0
- package/dist/services/platformAgentService.js +2041 -0
- package/dist/services/projectAccessResolver.js +93 -0
- package/dist/services/projectService.js +392 -0
- package/dist/services/resourceSpaceService.js +140 -0
- package/dist/services/scenarioRuntimeService.js +1130 -0
- package/dist/services/suggestedPlannerService.js +868 -0
- package/dist/services/workbenchGitBroker.js +161 -0
- package/dist/services/workbenchGitService.js +69 -0
- package/dist/services/workbenchInspectBroker.js +65 -0
- package/dist/services/workbenchNodePathService.js +79 -0
- package/dist/services/workbenchRegistryService.js +240 -0
- package/dist/services/workbenchRootService.js +181 -0
- package/dist/services/workbenchTerminalBroker.js +378 -0
- package/dist/services/workspaceRunOwnership.js +60 -0
- package/dist/services/workspaceScaffold.js +105 -0
- package/dist/services/workspaceSessionRuntimeService.js +576 -0
- package/dist/services/workspaceSessionService.js +245 -0
- package/dist/services/workspaceToolActionRunner.js +1582 -0
- package/dist/services/workspaceToolErrors.js +10 -0
- package/dist/services/workspaceToolExecutionUtils.js +895 -0
- package/dist/services/workspaceToolLatestStateProjector.js +91 -0
- package/dist/services/workspaceToolManifest.js +572 -0
- package/dist/services/workspaceToolMutationQueue.js +43 -0
- package/dist/services/workspaceToolPanelProjection.js +460 -0
- package/dist/services/workspaceToolPromotion.js +255 -0
- package/dist/services/workspaceToolPromotionState.js +224 -0
- package/dist/services/workspaceToolPublishDiagnostics.js +189 -0
- package/dist/services/workspaceToolPublishIdentityResolver.js +146 -0
- package/dist/services/workspaceToolReadModel.js +378 -0
- package/dist/services/workspaceToolRunLedger.js +239 -0
- package/dist/services/workspaceToolService.js +3067 -0
- package/dist/services/workspaceToolSnapshotPanelSync.js +293 -0
- package/dist/services/workspaceToolTerminalLifecycle.js +283 -0
- package/dist/services/workspaceToolTypes.js +1 -0
- package/dist/services/workspaceToolUploadMaterializer.js +228 -0
- package/dist/web/actionCardRoutes.js +129 -0
- package/dist/web/actionCards.js +469 -0
- package/dist/web/activationContext.js +684 -0
- package/dist/web/agentChannelGuards.js +48 -0
- package/dist/web/agentMentionCooldowns.js +32 -0
- package/dist/web/agentReminders.js +1668 -0
- package/dist/web/agentRuntimePresence.js +197 -0
- package/dist/web/agentSelfState.js +494 -0
- package/dist/web/agentTaskLinks.js +26 -0
- package/dist/web/agentVisibility.js +79 -0
- package/dist/web/assets.js +95 -0
- package/dist/web/channelActivationPrompt.js +395 -0
- package/dist/web/channelMemoryNotes.js +127 -0
- package/dist/web/channelMentions.js +10 -0
- package/dist/web/channelMessageSequences.js +19 -0
- package/dist/web/channelSubscriptions.js +26 -0
- package/dist/web/clearedTaskRoots.js +10 -0
- package/dist/web/collaborationPromptGuidance.js +36 -0
- package/dist/web/collaborationSurfaceState.js +140 -0
- package/dist/web/contextBundleRanking.js +154 -0
- package/dist/web/contextBundleResolver.js +488 -0
- package/dist/web/conversationBuiltinSkillRoots.js +50 -0
- package/dist/web/conversationControls.js +232 -0
- package/dist/web/conversationHandoffs.js +612 -0
- package/dist/web/conversationManager.js +2511 -0
- package/dist/web/conversationSummaries.js +876 -0
- package/dist/web/conversationSurfaceKinds.js +17 -0
- package/dist/web/conversationTargets.js +173 -0
- package/dist/web/directActivationPrompt.js +122 -0
- package/dist/web/directReplyTargets.js +69 -0
- package/dist/web/directThreadResolver.js +129 -0
- package/dist/web/dmTaskHandoffPrompt.js +120 -0
- package/dist/web/dmTaskThreadStatusProjection.js +229 -0
- package/dist/web/ftsQuery.js +33 -0
- package/dist/web/internalAgentRouter.js +11341 -0
- package/dist/web/libraryCuratorScheduler.js +58 -0
- package/dist/web/libraryDocumentPromptGuidance.js +8 -0
- package/dist/web/messageCheckpoints.js +19 -0
- package/dist/web/nodeWsHandler.js +2495 -0
- package/dist/web/notificationRounds.js +1061 -0
- package/dist/web/panelActionMessages.js +108 -0
- package/dist/web/panelActivationPrompt.js +18 -0
- package/dist/web/panelAudit.js +273 -0
- package/dist/web/panelLifecycle.js +222 -0
- package/dist/web/panelMediaPolicy.js +43 -0
- package/dist/web/panelPathPolicy.js +63 -0
- package/dist/web/panelPreviews.js +175 -0
- package/dist/web/panelQueryHandles.js +2749 -0
- package/dist/web/panelRoutes.js +2147 -0
- package/dist/web/panels.js +904 -0
- package/dist/web/peerInboxAggregates.js +1247 -0
- package/dist/web/planApprovalState.js +92 -0
- package/dist/web/platformAgentScheduler.js +66 -0
- package/dist/web/proactiveOpportunities.js +452 -0
- package/dist/web/promptContextSections.js +242 -0
- package/dist/web/promptHistorySanitizer.js +26 -0
- package/dist/web/promptSlashCommands.js +158 -0
- package/dist/web/rollingConversationSummary.js +453 -0
- package/dist/web/routeHelpers.js +11 -0
- package/dist/web/routes/handoff.js +288 -0
- package/dist/web/routes/history.js +345 -0
- package/dist/web/routes/memory.js +258 -0
- package/dist/web/routes/selfState.js +171 -0
- package/dist/web/routes/workspace.js +154 -0
- package/dist/web/runSurfaceWatermarks.js +431 -0
- package/dist/web/runtimeCapabilities.js +48 -0
- package/dist/web/sameAgentHandoffs.js +494 -0
- package/dist/web/server.js +15567 -0
- package/dist/web/sharedCollaborationCapsules.js +163 -0
- package/dist/web/soloSessionRelay.js +42 -0
- package/dist/web/soloWsHandler.js +138 -0
- package/dist/web/suggestedPlannerScheduler.js +56 -0
- package/dist/web/surfaceActivationPolicy.js +108 -0
- package/dist/web/surfaceCollaborators.js +61 -0
- package/dist/web/surfaceSystemStatus.js +263 -0
- package/dist/web/targetParticipants.js +77 -0
- package/dist/web/taskEvents.js +49 -0
- package/dist/web/taskLifecycleMessages.js +165 -0
- package/dist/web/taskLoops.js +732 -0
- package/dist/web/taskMemoryNotes.js +224 -0
- package/dist/web/taskNumbers.js +16 -0
- package/dist/web/taskOwnerGuards.js +49 -0
- package/dist/web/taskParticipantResolver.js +42 -0
- package/dist/web/taskParticipants.js +97 -0
- package/dist/web/taskSourceDetails.js +20 -0
- package/dist/web/taskStateViews.js +210 -0
- package/dist/web/taskStatusTransitions.js +9 -0
- package/dist/web/taskThreadFollowups.js +599 -0
- package/dist/web/taskThreadRuntimeClosure.js +685 -0
- package/dist/web/taskUpdateDelivery.js +104 -0
- package/dist/web/threadReplyContentHeuristics.js +30 -0
- package/dist/web/threadRoots.js +61 -0
- package/dist/web/threadTaskBindings.js +365 -0
- package/dist/web/uiPanelPromptGuidance.js +27 -0
- package/dist/web/workspaceMemoryHints.js +143 -0
- package/dist/web/workspaceToolPromptGuidance.js +30 -0
- package/dist/web/wsHandler.js +397 -0
- package/dist/web/wsSink.js +116 -0
- package/package.json +54 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export class KeyedMutationQueue {
|
|
2
|
+
pending = new Map();
|
|
3
|
+
async enqueue(key, work) {
|
|
4
|
+
const previous = this.pending.get(key) ?? Promise.resolve();
|
|
5
|
+
let releaseCurrent;
|
|
6
|
+
const current = new Promise((resolve) => {
|
|
7
|
+
releaseCurrent = resolve;
|
|
8
|
+
});
|
|
9
|
+
const stored = previous.catch(() => undefined).then(() => current);
|
|
10
|
+
this.pending.set(key, stored);
|
|
11
|
+
await previous.catch(() => undefined);
|
|
12
|
+
try {
|
|
13
|
+
return await work();
|
|
14
|
+
}
|
|
15
|
+
finally {
|
|
16
|
+
releaseCurrent();
|
|
17
|
+
if (this.pending.get(key) === stored) {
|
|
18
|
+
this.pending.delete(key);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
pendingKeyCount() {
|
|
23
|
+
return this.pending.size;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export class WorkspaceToolMutationQueues {
|
|
27
|
+
toolQueue = new KeyedMutationQueue();
|
|
28
|
+
publishQueue = new KeyedMutationQueue();
|
|
29
|
+
panelPromotionQueue = new KeyedMutationQueue();
|
|
30
|
+
agentPersistentStartQueue = new KeyedMutationQueue();
|
|
31
|
+
enqueueTool(toolId, work) {
|
|
32
|
+
return this.toolQueue.enqueue(toolId, work);
|
|
33
|
+
}
|
|
34
|
+
enqueuePublish(publishKey, work) {
|
|
35
|
+
return this.publishQueue.enqueue(publishKey, work);
|
|
36
|
+
}
|
|
37
|
+
enqueuePanelPromotion(panelId, work) {
|
|
38
|
+
return this.panelPromotionQueue.enqueue(panelId, work);
|
|
39
|
+
}
|
|
40
|
+
enqueueAgentPersistentStart(agentId, work) {
|
|
41
|
+
return this.agentPersistentStartQueue.enqueue(agentId, work);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
import { buildWorkspaceToolPanelActionParamKey, mapPanelLevelNodes, panelLevelNodeHasActionBar, } from '@bbigbang/protocol';
|
|
2
|
+
const TOOL_SNAPSHOT_RUNTIME_FIELD_LIMIT = 4;
|
|
3
|
+
const TOOL_RUNTIME_SUMMARY_MARKER = 'bigbang:tool-runtime-summary';
|
|
4
|
+
const TOOL_ACTION_PARAMETER_FORM_MARKER = 'bigbang:tool-action-parameter-form';
|
|
5
|
+
export function buildToolSnapshotPanelProjection(spec) {
|
|
6
|
+
const actions = spec.manifest.actions.map((action) => ({
|
|
7
|
+
id: action.actionId,
|
|
8
|
+
label: action.label,
|
|
9
|
+
...(action.description ? { description: action.description } : {}),
|
|
10
|
+
...(action.kind === 'stop' ? { variant: 'danger' } : {}),
|
|
11
|
+
}));
|
|
12
|
+
const sourceProps = spec.sourceProps ?? null;
|
|
13
|
+
const sourcePageSize = typeof sourceProps?.pageSize === 'number' && Number.isFinite(sourceProps.pageSize)
|
|
14
|
+
? Math.min(50, Math.max(1, Math.trunc(sourceProps.pageSize)))
|
|
15
|
+
: null;
|
|
16
|
+
const props = {
|
|
17
|
+
title: spec.manifest.view.title ?? spec.manifest.name,
|
|
18
|
+
pageSize: sourceProps ? (sourcePageSize ?? 10) : 1,
|
|
19
|
+
fields: spec.manifest.view.fields,
|
|
20
|
+
mediaSlots: spec.manifest.view.mediaSlots ?? [],
|
|
21
|
+
template: spec.manifest.view.template,
|
|
22
|
+
};
|
|
23
|
+
const summary = buildToolSnapshotSummaryNode(spec.manifest.view.summary ?? null, sourceProps?.summary, spec.latestState, {
|
|
24
|
+
manifest: spec.manifest,
|
|
25
|
+
allowSharedExec: spec.allowSharedExec,
|
|
26
|
+
status: spec.status,
|
|
27
|
+
});
|
|
28
|
+
if (summary)
|
|
29
|
+
props.summary = summary;
|
|
30
|
+
const parameterForm = buildToolSnapshotParameterFormNode(spec.manifest.view.parameterForm ?? null, sourceProps?.parameterForm, spec.manifest, {
|
|
31
|
+
includeActionBar: true,
|
|
32
|
+
stripSourceInteractiveControls: Boolean(spec.sourcePanelId),
|
|
33
|
+
});
|
|
34
|
+
if (parameterForm)
|
|
35
|
+
props.parameterForm = parameterForm;
|
|
36
|
+
const latestStateRow = spec.latestState ? {
|
|
37
|
+
rowId: 'tool-state',
|
|
38
|
+
fields: spec.latestState.fields,
|
|
39
|
+
media: spec.latestState.media ?? {},
|
|
40
|
+
nodeId: spec.nodeId,
|
|
41
|
+
} : null;
|
|
42
|
+
const sourceRows = spec.sourceRows && spec.sourceRows.length > 0
|
|
43
|
+
? spec.sourceRows
|
|
44
|
+
: spec.preservedRows ?? [];
|
|
45
|
+
const rows = sourceRows.length > 0
|
|
46
|
+
? sourceRows
|
|
47
|
+
: latestStateRow
|
|
48
|
+
? [latestStateRow]
|
|
49
|
+
: [];
|
|
50
|
+
const result = buildToolSnapshotPanelResult(spec.latestState, spec.status);
|
|
51
|
+
return {
|
|
52
|
+
props,
|
|
53
|
+
actions,
|
|
54
|
+
rows,
|
|
55
|
+
rowCount: rows.length,
|
|
56
|
+
result,
|
|
57
|
+
schemaFingerprint: buildToolSnapshotSchemaFingerprint(props),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export function buildToolSnapshotSchemaFingerprint(props) {
|
|
61
|
+
return stableStringify({
|
|
62
|
+
fields: props.fields ?? [],
|
|
63
|
+
mediaSlots: props.mediaSlots ?? [],
|
|
64
|
+
summary: props.summary ?? null,
|
|
65
|
+
template: props.template ?? null,
|
|
66
|
+
parameterForm: props.parameterForm ?? null,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
export function deriveWorkspaceToolBusinessState(latestState) {
|
|
70
|
+
const value = latestState?.fields?.status;
|
|
71
|
+
if (typeof value === 'string' && value.trim().length > 0)
|
|
72
|
+
return value.trim();
|
|
73
|
+
if (typeof value === 'number' || typeof value === 'boolean')
|
|
74
|
+
return String(value);
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
export function deriveWorkspaceToolRuntimeState(params) {
|
|
78
|
+
if (params.activeTerminalId)
|
|
79
|
+
return 'running';
|
|
80
|
+
if (params.lastRunStatus === 'failed')
|
|
81
|
+
return 'failed';
|
|
82
|
+
if (params.lastRunStatus === 'completed')
|
|
83
|
+
return 'completed';
|
|
84
|
+
return 'idle';
|
|
85
|
+
}
|
|
86
|
+
export function workspaceToolRuntimeStateToPanelStatus(runtimeState) {
|
|
87
|
+
if (runtimeState === 'running')
|
|
88
|
+
return 'running';
|
|
89
|
+
if (runtimeState === 'failed')
|
|
90
|
+
return 'failed';
|
|
91
|
+
if (runtimeState === 'completed')
|
|
92
|
+
return 'completed';
|
|
93
|
+
return 'idle';
|
|
94
|
+
}
|
|
95
|
+
export function buildToolActionParameterFormSectionForActions(actions, options) {
|
|
96
|
+
const children = [];
|
|
97
|
+
for (const action of actions) {
|
|
98
|
+
for (const field of action.paramsSchema ?? []) {
|
|
99
|
+
const props = {
|
|
100
|
+
name: buildWorkspaceToolPanelActionParamKey(action.actionId, field.name),
|
|
101
|
+
label: field.label ? `${action.label} · ${field.label}` : `${action.label} · ${field.name}`,
|
|
102
|
+
__bigbangBuiltin: TOOL_ACTION_PARAMETER_FORM_MARKER,
|
|
103
|
+
};
|
|
104
|
+
if (field.placeholder)
|
|
105
|
+
props.placeholder = field.placeholder;
|
|
106
|
+
if (field.defaultValue !== undefined)
|
|
107
|
+
props.defaultValue = field.defaultValue;
|
|
108
|
+
if (field.required === true)
|
|
109
|
+
props.required = true;
|
|
110
|
+
if (field.min !== undefined)
|
|
111
|
+
props.min = field.min;
|
|
112
|
+
if (field.max !== undefined)
|
|
113
|
+
props.max = field.max;
|
|
114
|
+
if (field.accept !== undefined)
|
|
115
|
+
props.accept = field.accept;
|
|
116
|
+
if (field.multiple === true)
|
|
117
|
+
props.multiple = true;
|
|
118
|
+
if (field.maxBytes !== undefined)
|
|
119
|
+
props.maxBytes = field.maxBytes;
|
|
120
|
+
if (field.options?.length) {
|
|
121
|
+
props.options = field.options.map((option) => ({
|
|
122
|
+
label: option.label,
|
|
123
|
+
value: option.value,
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
const input = field.input ?? 'text';
|
|
127
|
+
if (input === 'number') {
|
|
128
|
+
children.push({ type: 'NumberInput', props });
|
|
129
|
+
}
|
|
130
|
+
else if (input === 'checkbox') {
|
|
131
|
+
children.push({ type: 'Checkbox', props });
|
|
132
|
+
}
|
|
133
|
+
else if (input === 'select') {
|
|
134
|
+
children.push({ type: 'Select', props });
|
|
135
|
+
}
|
|
136
|
+
else if (input === 'multiselect') {
|
|
137
|
+
children.push({ type: 'MultiSelect', props });
|
|
138
|
+
}
|
|
139
|
+
else if (input === 'tags') {
|
|
140
|
+
children.push({ type: 'TagInput', props });
|
|
141
|
+
}
|
|
142
|
+
else if (input === 'date') {
|
|
143
|
+
children.push({ type: 'DatePicker', props });
|
|
144
|
+
}
|
|
145
|
+
else if (input === 'file') {
|
|
146
|
+
children.push({ type: 'FileUpload', props });
|
|
147
|
+
}
|
|
148
|
+
else if (input === 'textarea') {
|
|
149
|
+
children.push({ type: 'TextArea', props });
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
children.push({ type: 'TextInput', props });
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const actionBar = buildToolGeneratedActionBarNode(actions, options);
|
|
157
|
+
if (actionBar)
|
|
158
|
+
children.push(actionBar);
|
|
159
|
+
return children.length > 0
|
|
160
|
+
? {
|
|
161
|
+
type: 'ParameterFormSection',
|
|
162
|
+
children,
|
|
163
|
+
}
|
|
164
|
+
: null;
|
|
165
|
+
}
|
|
166
|
+
function stableStringify(value) {
|
|
167
|
+
if (value === undefined)
|
|
168
|
+
return 'undefined';
|
|
169
|
+
if (value === null || typeof value !== 'object')
|
|
170
|
+
return JSON.stringify(value) ?? 'undefined';
|
|
171
|
+
if (Array.isArray(value))
|
|
172
|
+
return `[${value.map((item) => stableStringify(item)).join(',')}]`;
|
|
173
|
+
const entries = Object.entries(value)
|
|
174
|
+
.sort(([a], [b]) => a.localeCompare(b));
|
|
175
|
+
return `{${entries.map(([key, entryValue]) => `${JSON.stringify(key)}:${stableStringify(entryValue)}`).join(',')}}`;
|
|
176
|
+
}
|
|
177
|
+
function buildToolSnapshotPanelResult(latestState, status) {
|
|
178
|
+
if (!latestState)
|
|
179
|
+
return null;
|
|
180
|
+
const summary = formatToolSnapshotLatestStateSummary(latestState.fields);
|
|
181
|
+
return {
|
|
182
|
+
summary,
|
|
183
|
+
status: status ?? null,
|
|
184
|
+
latestState: {
|
|
185
|
+
fields: latestState.fields,
|
|
186
|
+
media: latestState.media ?? {},
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function buildToolSnapshotSummaryNode(manifestSummary, sourceSummary, latestState, options) {
|
|
191
|
+
const baseSummary = stripToolSummaryNode(manifestSummary ?? sourceSummary);
|
|
192
|
+
const staticSummary = buildToolStaticSummaryNode(options.manifest, latestState, options);
|
|
193
|
+
const runtimeSummary = buildToolRuntimeSummaryNode(latestState);
|
|
194
|
+
const children = [baseSummary, staticSummary, runtimeSummary].filter((node) => node !== null);
|
|
195
|
+
if (children.length === 0)
|
|
196
|
+
return null;
|
|
197
|
+
if (children.length === 1)
|
|
198
|
+
return children[0] ?? null;
|
|
199
|
+
return {
|
|
200
|
+
type: 'Section',
|
|
201
|
+
children,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function buildToolStaticSummaryNode(manifest, latestState, options) {
|
|
205
|
+
const hasNotifyAgentActions = manifest.actions.some((action) => (action.mode ?? 'platform_exec') === 'notify_agent');
|
|
206
|
+
const children = [
|
|
207
|
+
buildToolStaticSummaryMetricCard('State', formatToolSnapshotBusinessState(latestState)),
|
|
208
|
+
buildToolStaticSummaryMetricCard('Runtime', formatToolSnapshotRuntimeStatus(options.status)),
|
|
209
|
+
buildToolStaticSummaryMetricCard('Shared execution', options.allowSharedExec ? 'Enabled' : 'Owner only'),
|
|
210
|
+
];
|
|
211
|
+
if (hasNotifyAgentActions) {
|
|
212
|
+
children.push(buildToolStaticSummaryMetricCard('Notify-agent actions', 'Owner only'));
|
|
213
|
+
}
|
|
214
|
+
if (!latestState) {
|
|
215
|
+
children.push(buildToolStaticSummaryMetricCard('Runtime data', 'Pending'));
|
|
216
|
+
}
|
|
217
|
+
return buildCompactToolSummaryColumns(children);
|
|
218
|
+
}
|
|
219
|
+
function buildToolStaticSummaryMetricCard(label, value) {
|
|
220
|
+
return {
|
|
221
|
+
type: 'MetricCard',
|
|
222
|
+
props: {
|
|
223
|
+
label,
|
|
224
|
+
value,
|
|
225
|
+
__bigbangBuiltin: TOOL_RUNTIME_SUMMARY_MARKER,
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function panelStatusToWorkspaceToolRuntimeState(status) {
|
|
230
|
+
if (status === 'running')
|
|
231
|
+
return 'running';
|
|
232
|
+
if (status === 'failed')
|
|
233
|
+
return 'failed';
|
|
234
|
+
if (status === 'completed')
|
|
235
|
+
return 'completed';
|
|
236
|
+
return 'idle';
|
|
237
|
+
}
|
|
238
|
+
function formatWorkspaceToolRuntimeStateLabel(runtimeState) {
|
|
239
|
+
if (runtimeState === 'running')
|
|
240
|
+
return 'Running';
|
|
241
|
+
if (runtimeState === 'failed')
|
|
242
|
+
return 'Failed';
|
|
243
|
+
if (runtimeState === 'completed')
|
|
244
|
+
return 'Completed';
|
|
245
|
+
return 'Idle';
|
|
246
|
+
}
|
|
247
|
+
function formatToolSnapshotBusinessState(latestState) {
|
|
248
|
+
return deriveWorkspaceToolBusinessState(latestState) ?? 'No runtime data yet';
|
|
249
|
+
}
|
|
250
|
+
function formatToolSnapshotRuntimeStatus(status) {
|
|
251
|
+
return formatWorkspaceToolRuntimeStateLabel(panelStatusToWorkspaceToolRuntimeState(status));
|
|
252
|
+
}
|
|
253
|
+
function buildToolSnapshotParameterFormNode(manifestParameterForm, sourceParameterForm, manifest, options) {
|
|
254
|
+
const baseParameterForm = manifestParameterForm
|
|
255
|
+
? canonicalizeToolActionParameterFormNode(manifestParameterForm, manifest)
|
|
256
|
+
: stripToolActionParameterFormNode(sourceParameterForm, {
|
|
257
|
+
stripGeneratedActionBar: options?.includeActionBar !== false,
|
|
258
|
+
stripSourceInteractiveControls: options?.stripSourceInteractiveControls === true,
|
|
259
|
+
});
|
|
260
|
+
const generatedParameterForm = manifestParameterForm
|
|
261
|
+
? (panelLevelNodeHasActionBar(manifestParameterForm)
|
|
262
|
+
? null
|
|
263
|
+
: buildToolGeneratedActionBarNode(manifest.actions, options))
|
|
264
|
+
: buildToolActionParameterFormSectionForActions(manifest.actions, options);
|
|
265
|
+
if (baseParameterForm && generatedParameterForm) {
|
|
266
|
+
return {
|
|
267
|
+
type: 'Section',
|
|
268
|
+
children: [baseParameterForm, generatedParameterForm],
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
return baseParameterForm ?? generatedParameterForm;
|
|
272
|
+
}
|
|
273
|
+
function canonicalizeToolActionParameterFormNode(node, manifest) {
|
|
274
|
+
const fieldByKey = new Map();
|
|
275
|
+
for (const action of manifest.actions) {
|
|
276
|
+
for (const field of action.paramsSchema ?? []) {
|
|
277
|
+
fieldByKey.set(buildWorkspaceToolPanelActionParamKey(action.actionId, field.name), { action, field });
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return mapPanelLevelNodes(node, (candidate) => {
|
|
281
|
+
const props = candidate.props;
|
|
282
|
+
if (!isPlainRecord(props))
|
|
283
|
+
return undefined;
|
|
284
|
+
const name = props.name;
|
|
285
|
+
if (typeof name !== 'string')
|
|
286
|
+
return undefined;
|
|
287
|
+
const binding = fieldByKey.get(name);
|
|
288
|
+
if (!binding)
|
|
289
|
+
return undefined;
|
|
290
|
+
const propsWithoutAuthoredContract = stripAuthoredToolParameterControlProps(props);
|
|
291
|
+
return {
|
|
292
|
+
...candidate,
|
|
293
|
+
props: {
|
|
294
|
+
...propsWithoutAuthoredContract,
|
|
295
|
+
...buildCanonicalToolParameterControlProps(binding.action, binding.field),
|
|
296
|
+
},
|
|
297
|
+
};
|
|
298
|
+
}) ?? node;
|
|
299
|
+
}
|
|
300
|
+
function stripAuthoredToolParameterControlProps(props) {
|
|
301
|
+
const next = { ...props };
|
|
302
|
+
for (const key of ['label', 'placeholder', 'defaultValue', 'value', 'checked', 'required', 'min', 'max', 'accept', 'multiple', 'maxBytes', 'options']) {
|
|
303
|
+
delete next[key];
|
|
304
|
+
}
|
|
305
|
+
return next;
|
|
306
|
+
}
|
|
307
|
+
function buildCanonicalToolParameterControlProps(action, field) {
|
|
308
|
+
const props = {
|
|
309
|
+
label: field.label ? `${action.label} · ${field.label}` : `${action.label} · ${field.name}`,
|
|
310
|
+
};
|
|
311
|
+
if (field.placeholder)
|
|
312
|
+
props.placeholder = field.placeholder;
|
|
313
|
+
if (field.defaultValue !== undefined)
|
|
314
|
+
props.defaultValue = field.defaultValue;
|
|
315
|
+
if (field.required === true)
|
|
316
|
+
props.required = true;
|
|
317
|
+
if (field.min !== undefined)
|
|
318
|
+
props.min = field.min;
|
|
319
|
+
if (field.max !== undefined)
|
|
320
|
+
props.max = field.max;
|
|
321
|
+
if (field.accept !== undefined)
|
|
322
|
+
props.accept = field.accept;
|
|
323
|
+
if (field.multiple === true)
|
|
324
|
+
props.multiple = true;
|
|
325
|
+
if (field.maxBytes !== undefined)
|
|
326
|
+
props.maxBytes = field.maxBytes;
|
|
327
|
+
if (field.options?.length) {
|
|
328
|
+
props.options = field.options.map((option) => ({
|
|
329
|
+
label: option.label,
|
|
330
|
+
value: option.value,
|
|
331
|
+
}));
|
|
332
|
+
}
|
|
333
|
+
return props;
|
|
334
|
+
}
|
|
335
|
+
function buildToolGeneratedActionBarNode(actions, options) {
|
|
336
|
+
if (options?.includeActionBar === false || actions.length === 0)
|
|
337
|
+
return null;
|
|
338
|
+
return {
|
|
339
|
+
type: 'ActionBar',
|
|
340
|
+
actionIds: actions.map((action) => action.actionId),
|
|
341
|
+
title: 'Actions',
|
|
342
|
+
layout: 'wrap',
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
function buildToolRuntimeSummaryNode(latestState) {
|
|
346
|
+
if (!latestState)
|
|
347
|
+
return null;
|
|
348
|
+
const children = [
|
|
349
|
+
{
|
|
350
|
+
type: 'MetricCard',
|
|
351
|
+
props: {
|
|
352
|
+
label: 'Latest tool state',
|
|
353
|
+
source: { kind: 'panel_result', path: ['summary'] },
|
|
354
|
+
__bigbangBuiltin: TOOL_RUNTIME_SUMMARY_MARKER,
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
];
|
|
358
|
+
const fieldEntries = Object.entries(latestState.fields)
|
|
359
|
+
.filter(([, value]) => (value === null
|
|
360
|
+
|| typeof value === 'string'
|
|
361
|
+
|| typeof value === 'number'
|
|
362
|
+
|| typeof value === 'boolean'))
|
|
363
|
+
.slice(0, TOOL_SNAPSHOT_RUNTIME_FIELD_LIMIT);
|
|
364
|
+
for (const [field] of fieldEntries) {
|
|
365
|
+
children.push({
|
|
366
|
+
type: 'MetricCard',
|
|
367
|
+
props: {
|
|
368
|
+
label: field,
|
|
369
|
+
source: { kind: 'panel_result', path: ['latestState', 'fields', field] },
|
|
370
|
+
__bigbangBuiltin: TOOL_RUNTIME_SUMMARY_MARKER,
|
|
371
|
+
},
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
return buildCompactToolSummaryColumns(children);
|
|
375
|
+
}
|
|
376
|
+
function buildCompactToolSummaryColumns(children) {
|
|
377
|
+
if (children.length === 0)
|
|
378
|
+
return null;
|
|
379
|
+
return {
|
|
380
|
+
type: 'Columns',
|
|
381
|
+
columns: children.map((child) => ({ children: [child] })),
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
function stripToolSummaryNode(node) {
|
|
385
|
+
if (!isPlainRecord(node))
|
|
386
|
+
return null;
|
|
387
|
+
return stripPanelLevelNodes(node, (candidate) => (isToolRuntimeSummaryNode(candidate)
|
|
388
|
+
|| isSourcePromotedToolInteractiveParameterNode(candidate)));
|
|
389
|
+
}
|
|
390
|
+
function stripToolActionParameterFormNode(node, options) {
|
|
391
|
+
if (!isPlainRecord(node))
|
|
392
|
+
return null;
|
|
393
|
+
return stripPanelLevelNodes(node, (candidate) => ((options?.stripSourceInteractiveControls === true
|
|
394
|
+
&& isSourcePromotedToolInteractiveParameterNode(candidate))
|
|
395
|
+
|| isToolActionParameterFormNode(candidate, options)));
|
|
396
|
+
}
|
|
397
|
+
function stripPanelLevelNodes(node, shouldStrip) {
|
|
398
|
+
return mapPanelLevelNodes(node, (candidate) => shouldStrip(candidate) ? null : undefined, {
|
|
399
|
+
pruneEmptyContainers: true,
|
|
400
|
+
pruneEmptyColumns: true,
|
|
401
|
+
collapseSingleChildContainers: true,
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
function isToolRuntimeSummaryNode(node) {
|
|
405
|
+
if (node.type === 'MetricCard') {
|
|
406
|
+
const props = node.props;
|
|
407
|
+
return isPlainRecord(props) && props.__bigbangBuiltin === TOOL_RUNTIME_SUMMARY_MARKER;
|
|
408
|
+
}
|
|
409
|
+
if (node.type === 'Section' && Array.isArray(node.children) && node.children.length > 0) {
|
|
410
|
+
return node.children.every((child) => isPlainRecord(child) && isToolRuntimeSummaryNode(child));
|
|
411
|
+
}
|
|
412
|
+
if (node.type === 'Columns' && Array.isArray(node.columns) && node.columns.length > 0) {
|
|
413
|
+
return node.columns.every((column) => (isPlainRecord(column)
|
|
414
|
+
&& Array.isArray(column.children)
|
|
415
|
+
&& column.children.length > 0
|
|
416
|
+
&& column.children.every((child) => isPlainRecord(child) && isToolRuntimeSummaryNode(child))));
|
|
417
|
+
}
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
function isToolActionParameterFormNode(node, options) {
|
|
421
|
+
if (options?.stripGeneratedActionBar === true
|
|
422
|
+
&& node.type === 'ActionBar'
|
|
423
|
+
&& Array.isArray(node.actionIds)
|
|
424
|
+
&& node.actionIds.every((actionId) => typeof actionId === 'string')
|
|
425
|
+
&& (node.layout === undefined || node.layout === 'wrap')
|
|
426
|
+
&& node.title === 'Actions') {
|
|
427
|
+
return true;
|
|
428
|
+
}
|
|
429
|
+
const props = node.props;
|
|
430
|
+
return isPlainRecord(props) && props.__bigbangBuiltin === TOOL_ACTION_PARAMETER_FORM_MARKER;
|
|
431
|
+
}
|
|
432
|
+
function isSourcePromotedToolInteractiveParameterNode(node) {
|
|
433
|
+
return node.type === 'ActionBar'
|
|
434
|
+
|| node.type === 'TextInput'
|
|
435
|
+
|| node.type === 'TextArea'
|
|
436
|
+
|| node.type === 'NumberInput'
|
|
437
|
+
|| node.type === 'Checkbox'
|
|
438
|
+
|| node.type === 'Select'
|
|
439
|
+
|| node.type === 'MultiSelect'
|
|
440
|
+
|| node.type === 'TagInput'
|
|
441
|
+
|| node.type === 'Slider'
|
|
442
|
+
|| node.type === 'DatePicker'
|
|
443
|
+
|| node.type === 'FileUpload'
|
|
444
|
+
|| node.type === 'Button';
|
|
445
|
+
}
|
|
446
|
+
function formatToolSnapshotLatestStateSummary(fields) {
|
|
447
|
+
const entries = Object.entries(fields)
|
|
448
|
+
.filter(([, value]) => (value === null
|
|
449
|
+
|| typeof value === 'string'
|
|
450
|
+
|| typeof value === 'number'
|
|
451
|
+
|| typeof value === 'boolean'))
|
|
452
|
+
.slice(0, TOOL_SNAPSHOT_RUNTIME_FIELD_LIMIT)
|
|
453
|
+
.map(([key, value]) => `${key}=${String(value)}`);
|
|
454
|
+
return entries.length > 0
|
|
455
|
+
? `Latest tool state: ${entries.join(', ')}`
|
|
456
|
+
: 'Latest tool state updated.';
|
|
457
|
+
}
|
|
458
|
+
function isPlainRecord(value) {
|
|
459
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
460
|
+
}
|