@stigmer/react 3.0.5 → 3.0.7-dev.20260611143057
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/agent/AgentDetailView.d.ts.map +1 -1
- package/agent/AgentDetailView.js +1 -1
- package/agent/AgentDetailView.js.map +1 -1
- package/agent-instance/AgentInstanceDetailPanel.d.ts.map +1 -1
- package/agent-instance/AgentInstanceDetailPanel.js +2 -13
- package/agent-instance/AgentInstanceDetailPanel.js.map +1 -1
- package/agent-instance/AgentInstanceList.d.ts.map +1 -1
- package/agent-instance/AgentInstanceList.js +2 -13
- package/agent-instance/AgentInstanceList.js.map +1 -1
- package/agent-instance/CreateAgentInstanceDialog.d.ts.map +1 -1
- package/agent-instance/CreateAgentInstanceDialog.js +1 -1
- package/agent-instance/CreateAgentInstanceDialog.js.map +1 -1
- package/composer/SessionComposer.d.ts +14 -0
- package/composer/SessionComposer.d.ts.map +1 -1
- package/composer/SessionComposer.js +15 -9
- package/composer/SessionComposer.js.map +1 -1
- package/index.d.ts +3 -3
- package/index.d.ts.map +1 -1
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/library/InstanceVisibilitySelector.d.ts +30 -23
- package/library/InstanceVisibilitySelector.d.ts.map +1 -1
- package/library/InstanceVisibilitySelector.js +22 -145
- package/library/InstanceVisibilitySelector.js.map +1 -1
- package/library/ResourceVisibilityControl.d.ts +23 -6
- package/library/ResourceVisibilityControl.d.ts.map +1 -1
- package/library/ResourceVisibilityControl.js +38 -9
- package/library/ResourceVisibilityControl.js.map +1 -1
- package/library/ScopeToggle.d.ts +1 -1
- package/library/ScopeToggle.js +1 -1
- package/library/VisibilityOptionRow.d.ts +52 -0
- package/library/VisibilityOptionRow.d.ts.map +1 -0
- package/library/VisibilityOptionRow.js +92 -0
- package/library/VisibilityOptionRow.js.map +1 -0
- package/library/VisibilitySelector.d.ts +98 -0
- package/library/VisibilitySelector.d.ts.map +1 -0
- package/library/VisibilitySelector.js +193 -0
- package/library/VisibilitySelector.js.map +1 -0
- package/library/index.d.ts +4 -2
- package/library/index.d.ts.map +1 -1
- package/library/index.js +2 -1
- package/library/index.js.map +1 -1
- package/library/useUpdateVisibility.d.ts +5 -4
- package/library/useUpdateVisibility.d.ts.map +1 -1
- package/library/useUpdateVisibility.js +5 -4
- package/library/useUpdateVisibility.js.map +1 -1
- package/library/visibilityLevels.d.ts +96 -0
- package/library/visibilityLevels.d.ts.map +1 -0
- package/library/visibilityLevels.js +97 -0
- package/library/visibilityLevels.js.map +1 -0
- package/mcp-server/McpServerDetailView.d.ts +1 -11
- package/mcp-server/McpServerDetailView.d.ts.map +1 -1
- package/mcp-server/McpServerDetailView.js +3 -6
- package/mcp-server/McpServerDetailView.js.map +1 -1
- package/package.json +4 -4
- package/resource-detail/types.d.ts +1 -1
- package/session/NewSessionViewer.d.ts +32 -1
- package/session/NewSessionViewer.d.ts.map +1 -1
- package/session/NewSessionViewer.js +20 -9
- package/session/NewSessionViewer.js.map +1 -1
- package/session/SessionViewer.d.ts +24 -1
- package/session/SessionViewer.d.ts.map +1 -1
- package/session/SessionViewer.js +18 -12
- package/session/SessionViewer.js.map +1 -1
- package/session/audience.d.ts +21 -0
- package/session/audience.d.ts.map +1 -0
- package/session/audience.js +2 -0
- package/session/audience.js.map +1 -0
- package/session/index.d.ts +2 -0
- package/session/index.d.ts.map +1 -1
- package/session/index.js.map +1 -1
- package/session/runtime-env.d.ts +47 -0
- package/session/runtime-env.d.ts.map +1 -0
- package/session/runtime-env.js +20 -0
- package/session/runtime-env.js.map +1 -0
- package/session/useNewSessionFlow.d.ts +25 -0
- package/session/useNewSessionFlow.d.ts.map +1 -1
- package/session/useNewSessionFlow.js +20 -8
- package/session/useNewSessionFlow.js.map +1 -1
- package/session/useSessionPageFlow.d.ts +27 -2
- package/session/useSessionPageFlow.d.ts.map +1 -1
- package/session/useSessionPageFlow.js +34 -13
- package/session/useSessionPageFlow.js.map +1 -1
- package/skill/SkillDetailView.d.ts.map +1 -1
- package/skill/SkillDetailView.js +1 -1
- package/skill/SkillDetailView.js.map +1 -1
- package/src/agent/AgentDetailView.tsx +1 -0
- package/src/agent-instance/AgentInstanceDetailPanel.tsx +7 -32
- package/src/agent-instance/AgentInstanceList.tsx +7 -32
- package/src/agent-instance/CreateAgentInstanceDialog.tsx +1 -0
- package/src/composer/SessionComposer.tsx +30 -8
- package/src/composer/__tests__/SessionComposer-lockAgent.test.tsx +150 -0
- package/src/index.ts +10 -2
- package/src/library/InstanceVisibilitySelector.tsx +44 -283
- package/src/library/ResourceVisibilityControl.tsx +54 -8
- package/src/library/ScopeToggle.tsx +1 -1
- package/src/library/VisibilityOptionRow.tsx +244 -0
- package/src/library/VisibilitySelector.tsx +436 -0
- package/src/library/__tests__/VisibilitySelector.test.tsx +256 -0
- package/src/library/index.ts +13 -2
- package/src/library/useUpdateVisibility.ts +5 -4
- package/src/library/visibilityLevels.ts +174 -0
- package/src/mcp-server/McpServerDetailView.tsx +10 -35
- package/src/resource-detail/types.ts +1 -1
- package/src/session/NewSessionViewer.tsx +61 -12
- package/src/session/SessionViewer.tsx +51 -15
- package/src/session/__tests__/audienceWiring.test.tsx +274 -0
- package/src/session/__tests__/useNewSessionFlow.test.tsx +122 -0
- package/src/session/__tests__/useSessionPageFlow.runtimeEnv.test.tsx +170 -0
- package/src/session/audience.ts +20 -0
- package/src/session/index.ts +3 -0
- package/src/session/runtime-env.ts +57 -0
- package/src/session/useNewSessionFlow.ts +44 -9
- package/src/session/useSessionPageFlow.ts +65 -17
- package/src/skill/SkillDetailView.tsx +1 -0
- package/src/workflow/WorkflowDetailView.tsx +1 -0
- package/src/workflow/instance/CreateWorkflowInstanceDialog.tsx +1 -0
- package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +7 -32
- package/src/workflow/instance/WorkflowInstanceList.tsx +7 -32
- package/styles.css +1 -1
- package/workflow/WorkflowDetailView.d.ts.map +1 -1
- package/workflow/WorkflowDetailView.js +1 -1
- package/workflow/WorkflowDetailView.js.map +1 -1
- package/workflow/instance/CreateWorkflowInstanceDialog.d.ts.map +1 -1
- package/workflow/instance/CreateWorkflowInstanceDialog.js +1 -1
- package/workflow/instance/CreateWorkflowInstanceDialog.js.map +1 -1
- package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
- package/workflow/instance/WorkflowInstanceDetailPanel.js +2 -13
- package/workflow/instance/WorkflowInstanceDetailPanel.js.map +1 -1
- package/workflow/instance/WorkflowInstanceList.d.ts.map +1 -1
- package/workflow/instance/WorkflowInstanceList.js +2 -13
- package/workflow/instance/WorkflowInstanceList.js.map +1 -1
- package/library/VisibilityToggle.d.ts +0 -53
- package/library/VisibilityToggle.d.ts.map +0 -1
- package/library/VisibilityToggle.js +0 -100
- package/library/VisibilityToggle.js.map +0 -1
- package/src/library/VisibilityToggle.tsx +0 -280
|
@@ -10,8 +10,7 @@ import type { ResourceRef } from "@stigmer/sdk";
|
|
|
10
10
|
import { getUserMessage } from "@stigmer/sdk";
|
|
11
11
|
import { useUpdateAgentInstance } from "./useUpdateAgentInstance";
|
|
12
12
|
import { useDeleteAgentInstance } from "./useDeleteAgentInstance";
|
|
13
|
-
import {
|
|
14
|
-
import { InstanceVisibilitySelector } from "../library/InstanceVisibilitySelector";
|
|
13
|
+
import { ResourceVisibilityControl } from "../library/ResourceVisibilityControl";
|
|
15
14
|
import { PermissionGate } from "../iam-policy/PermissionGate";
|
|
16
15
|
import { SharePanel } from "../iam-policy/SharePanel";
|
|
17
16
|
import { EnvironmentPicker } from "../environment/EnvironmentPicker";
|
|
@@ -55,7 +54,6 @@ export function AgentInstanceDetailPanel({
|
|
|
55
54
|
|
|
56
55
|
const { update, isUpdating } = useUpdateAgentInstance();
|
|
57
56
|
const { deleteInstance, isDeleting } = useDeleteAgentInstance();
|
|
58
|
-
const { updateVisibility, isPending: isVisibilityPending } = useUpdateVisibility("agentInstance", id || null);
|
|
59
57
|
const { environments } = useEnvironmentList(org);
|
|
60
58
|
|
|
61
59
|
const [isEditingEnvs, setIsEditingEnvs] = useState(false);
|
|
@@ -64,14 +62,6 @@ export function AgentInstanceDetailPanel({
|
|
|
64
62
|
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
|
65
63
|
const [deleteError, setDeleteError] = useState<Error | null>(null);
|
|
66
64
|
|
|
67
|
-
const handleVisibilityChange = useCallback(
|
|
68
|
-
async (v: ApiResourceVisibility) => {
|
|
69
|
-
await updateVisibility(v);
|
|
70
|
-
onUpdated?.();
|
|
71
|
-
},
|
|
72
|
-
[updateVisibility, onUpdated],
|
|
73
|
-
);
|
|
74
|
-
|
|
75
65
|
const handleStartEditEnvs = useCallback(() => {
|
|
76
66
|
const currentRefs: ResourceRef[] = (spec?.environmentRefs ?? []).map((ref) => ({
|
|
77
67
|
org: ref.org || org,
|
|
@@ -254,21 +244,12 @@ export function AgentInstanceDetailPanel({
|
|
|
254
244
|
{/* Visibility */}
|
|
255
245
|
<div className="px-4 py-3">
|
|
256
246
|
<h4 className="text-xs font-medium text-muted-foreground mb-2">Visibility</h4>
|
|
257
|
-
<
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
</span>
|
|
264
|
-
}
|
|
265
|
-
>
|
|
266
|
-
<InstanceVisibilitySelector
|
|
267
|
-
visibility={meta?.visibility ?? ApiResourceVisibility.visibility_private}
|
|
268
|
-
onVisibilityChange={handleVisibilityChange}
|
|
269
|
-
isPending={isVisibilityPending}
|
|
270
|
-
/>
|
|
271
|
-
</PermissionGate>
|
|
247
|
+
<ResourceVisibilityControl
|
|
248
|
+
kind="agentInstance"
|
|
249
|
+
resourceId={id}
|
|
250
|
+
visibility={meta?.visibility ?? ApiResourceVisibility.visibility_private}
|
|
251
|
+
onChanged={onUpdated}
|
|
252
|
+
/>
|
|
272
253
|
</div>
|
|
273
254
|
|
|
274
255
|
{/* Share Panel */}
|
|
@@ -344,12 +325,6 @@ export function AgentInstanceDetailPanel({
|
|
|
344
325
|
);
|
|
345
326
|
}
|
|
346
327
|
|
|
347
|
-
const VISIBILITY_LABELS: Record<number, string> = {
|
|
348
|
-
[ApiResourceVisibility.visibility_private]: "Private",
|
|
349
|
-
[ApiResourceVisibility.visibility_org]: "Organization",
|
|
350
|
-
[ApiResourceVisibility.visibility_public]: "Public",
|
|
351
|
-
};
|
|
352
|
-
|
|
353
328
|
function CloseIcon() {
|
|
354
329
|
return (
|
|
355
330
|
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden="true">
|
|
@@ -6,8 +6,7 @@ import type { AgentInstance } from "@stigmer/protos/ai/stigmer/agentic/agentinst
|
|
|
6
6
|
import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
|
|
7
7
|
import { useAgentInstances } from "./useAgentInstances";
|
|
8
8
|
import { useEnvironmentList } from "../environment/useEnvironmentList";
|
|
9
|
-
import {
|
|
10
|
-
import { InstanceVisibilitySelector } from "../library/InstanceVisibilitySelector";
|
|
9
|
+
import { ResourceVisibilityControl } from "../library/ResourceVisibilityControl";
|
|
11
10
|
import { PermissionGate } from "../iam-policy/PermissionGate";
|
|
12
11
|
import { AgentInstanceEmptyState } from "./AgentInstanceEmptyState";
|
|
13
12
|
|
|
@@ -175,18 +174,9 @@ function InstanceRow({
|
|
|
175
174
|
const meta = instance.metadata;
|
|
176
175
|
const id = meta?.id ?? "";
|
|
177
176
|
const isPersonal = meta?.labels?.[PERSONAL_LABEL] === "true";
|
|
178
|
-
const { updateVisibility, isPending } = useUpdateVisibility("agentInstance", id || null);
|
|
179
177
|
|
|
180
178
|
const envRefs = instance.spec?.environmentRefs ?? [];
|
|
181
179
|
|
|
182
|
-
const handleVisibilityChange = useCallback(
|
|
183
|
-
async (v: ApiResourceVisibility) => {
|
|
184
|
-
await updateVisibility(v);
|
|
185
|
-
refetch();
|
|
186
|
-
},
|
|
187
|
-
[updateVisibility, refetch],
|
|
188
|
-
);
|
|
189
|
-
|
|
190
180
|
return (
|
|
191
181
|
<tr
|
|
192
182
|
className={cn(
|
|
@@ -245,21 +235,12 @@ function InstanceRow({
|
|
|
245
235
|
|
|
246
236
|
<td className="px-4 py-2.5" onClick={(e) => e.stopPropagation()}>
|
|
247
237
|
{id ? (
|
|
248
|
-
<
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
</span>
|
|
255
|
-
}
|
|
256
|
-
>
|
|
257
|
-
<InstanceVisibilitySelector
|
|
258
|
-
visibility={meta?.visibility ?? ApiResourceVisibility.visibility_private}
|
|
259
|
-
onVisibilityChange={handleVisibilityChange}
|
|
260
|
-
isPending={isPending}
|
|
261
|
-
/>
|
|
262
|
-
</PermissionGate>
|
|
238
|
+
<ResourceVisibilityControl
|
|
239
|
+
kind="agentInstance"
|
|
240
|
+
resourceId={id}
|
|
241
|
+
visibility={meta?.visibility ?? ApiResourceVisibility.visibility_private}
|
|
242
|
+
onChanged={refetch}
|
|
243
|
+
/>
|
|
263
244
|
) : (
|
|
264
245
|
<span className="text-xs text-muted-foreground">{"\u2014"}</span>
|
|
265
246
|
)}
|
|
@@ -304,12 +285,6 @@ function InstanceRow({
|
|
|
304
285
|
);
|
|
305
286
|
}
|
|
306
287
|
|
|
307
|
-
const VISIBILITY_LABELS: Record<number, string> = {
|
|
308
|
-
[ApiResourceVisibility.visibility_private]: "Private",
|
|
309
|
-
[ApiResourceVisibility.visibility_org]: "Organization",
|
|
310
|
-
[ApiResourceVisibility.visibility_public]: "Public",
|
|
311
|
-
};
|
|
312
|
-
|
|
313
288
|
function LoadingSkeleton() {
|
|
314
289
|
return (
|
|
315
290
|
<div className="space-y-2 py-4">
|
|
@@ -309,6 +309,21 @@ export interface SessionComposerProps {
|
|
|
309
309
|
*/
|
|
310
310
|
readonly isDefaultAgent?: boolean;
|
|
311
311
|
|
|
312
|
+
/**
|
|
313
|
+
* Lock the current agent: the Agent entry is removed from the
|
|
314
|
+
* Configure menu so the user cannot swap or deselect it.
|
|
315
|
+
*
|
|
316
|
+
* Locking does not unwire the agent machinery — `initialAgentRef`
|
|
317
|
+
* resolution still runs on mount, and when the agent requires
|
|
318
|
+
* credentials the environment form stays reachable in the Configure
|
|
319
|
+
* menu until setup completes (lock ≠ unwire). Pair with
|
|
320
|
+
* `initialAgentRef` to pin a pre-configured agent in end-user-facing
|
|
321
|
+
* embeds (see `SessionViewer` / `NewSessionViewer` `audience`).
|
|
322
|
+
*
|
|
323
|
+
* @default false
|
|
324
|
+
*/
|
|
325
|
+
readonly lockAgent?: boolean;
|
|
326
|
+
|
|
312
327
|
/**
|
|
313
328
|
* Currently selected MCP server usages.
|
|
314
329
|
* When `onMcpServerUsagesChange` is provided, a MCP server trigger
|
|
@@ -496,6 +511,7 @@ const SessionComposerInner = forwardRef<SessionComposerHandle, SessionComposerPr
|
|
|
496
511
|
initialAgentRef,
|
|
497
512
|
initialInstanceId,
|
|
498
513
|
isDefaultAgent = false,
|
|
514
|
+
lockAgent = false,
|
|
499
515
|
mcpServerUsages,
|
|
500
516
|
onMcpServerUsagesChange,
|
|
501
517
|
skillRefs,
|
|
@@ -1140,13 +1156,19 @@ const SessionComposerInner = forwardRef<SessionComposerHandle, SessionComposerPr
|
|
|
1140
1156
|
(agentSetup.state.status === "needsEnvVars" ||
|
|
1141
1157
|
agentSetup.state.status === "resolving" ||
|
|
1142
1158
|
agentSetup.state.status === "submitting");
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1159
|
+
// A locked agent stays out of the menu unless setup is pending:
|
|
1160
|
+
// the env-collection form lives in this panel and must remain
|
|
1161
|
+
// reachable until the agent resolves (lock ≠ unwire). Once
|
|
1162
|
+
// resolved, the entry disappears and the agent cannot be swapped.
|
|
1163
|
+
if (!lockAgent || agentPending) {
|
|
1164
|
+
items.push({
|
|
1165
|
+
id: "agent",
|
|
1166
|
+
icon: <AgentIcon />,
|
|
1167
|
+
label: "Agent",
|
|
1168
|
+
count: agentRef || agentPending ? 1 : 0,
|
|
1169
|
+
hasWarning: agentPending && agentSetup.state.status === "needsEnvVars",
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1150
1172
|
}
|
|
1151
1173
|
if (showMcp) {
|
|
1152
1174
|
items.push({
|
|
@@ -1174,7 +1196,7 @@ const SessionComposerInner = forwardRef<SessionComposerHandle, SessionComposerPr
|
|
|
1174
1196
|
});
|
|
1175
1197
|
}
|
|
1176
1198
|
return items;
|
|
1177
|
-
}, [showAgent, agentRef, agentSetup.state, showMcp, mcpCount, mcpSetup.needsSetupCount, showSkills, skillCount, showSessionVars, sessionVarCount]);
|
|
1199
|
+
}, [showAgent, lockAgent, agentRef, agentSetup.state, showMcp, mcpCount, mcpSetup.needsSetupCount, showSkills, skillCount, showSessionVars, sessionVarCount]);
|
|
1178
1200
|
|
|
1179
1201
|
const renderConfigPanel = useCallback(
|
|
1180
1202
|
(panelId: string): React.ReactNode => {
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeAll, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { render, screen, cleanup, fireEvent } from "@testing-library/react";
|
|
3
|
+
import type { ReactNode } from "react";
|
|
4
|
+
import type { Stigmer } from "@stigmer/sdk";
|
|
5
|
+
import { StigmerContext } from "../../context";
|
|
6
|
+
import { ModelRegistryContext } from "../../models/ModelRegistryContext";
|
|
7
|
+
|
|
8
|
+
// Without a StigmerProvider the portal container is null, and Base UI's
|
|
9
|
+
// Portal renders nothing — pin it to document.body so the popover mounts.
|
|
10
|
+
vi.mock("../../portal-container", () => ({
|
|
11
|
+
useStigmerPortalContainer: () => document.body,
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
// Controllable agent-setup state — lets these tests drive the lock × setup
|
|
15
|
+
// matrix directly instead of exercising the full resolution state machine
|
|
16
|
+
// (which is covered by useAgentSetup's own tests).
|
|
17
|
+
const mockAgentSetup = {
|
|
18
|
+
state: { status: "idle" } as Record<string, unknown>,
|
|
19
|
+
resolveAgent: vi.fn(),
|
|
20
|
+
resolveToInstance: vi.fn(),
|
|
21
|
+
submitEnvVars: vi.fn(),
|
|
22
|
+
reset: vi.fn(),
|
|
23
|
+
};
|
|
24
|
+
vi.mock("../../agent/useAgentSetup", () => ({
|
|
25
|
+
useAgentSetup: () => mockAgentSetup,
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
import { SessionComposer } from "../SessionComposer";
|
|
29
|
+
|
|
30
|
+
// Base UI's Popover positioner observes its anchor; happy-dom lacks
|
|
31
|
+
// ResizeObserver, so provide a no-op shim.
|
|
32
|
+
beforeAll(() => {
|
|
33
|
+
if (!("ResizeObserver" in globalThis)) {
|
|
34
|
+
(globalThis as unknown as { ResizeObserver: unknown }).ResizeObserver =
|
|
35
|
+
class {
|
|
36
|
+
observe() {}
|
|
37
|
+
unobserve() {}
|
|
38
|
+
disconnect() {}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
function createMinimalStigmerMock(): Stigmer {
|
|
44
|
+
return {
|
|
45
|
+
agentExecution: { uploadAttachment: vi.fn() },
|
|
46
|
+
environment: { getPersonal: vi.fn().mockResolvedValue(null) },
|
|
47
|
+
baseUrl: "http://localhost:8080",
|
|
48
|
+
getAuthCredential: vi.fn().mockResolvedValue("test-token"),
|
|
49
|
+
config: {
|
|
50
|
+
baseUrl: "http://localhost:8080",
|
|
51
|
+
getAccessToken: vi.fn().mockResolvedValue(""),
|
|
52
|
+
},
|
|
53
|
+
} as unknown as Stigmer;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function createWrapper(client: Stigmer) {
|
|
57
|
+
return function Wrapper({ children }: { children: ReactNode }) {
|
|
58
|
+
return (
|
|
59
|
+
<StigmerContext.Provider value={client}>
|
|
60
|
+
<ModelRegistryContext.Provider
|
|
61
|
+
value={{ models: [], isLoading: false, error: null, refetch: vi.fn() }}
|
|
62
|
+
>
|
|
63
|
+
{children}
|
|
64
|
+
</ModelRegistryContext.Provider>
|
|
65
|
+
</StigmerContext.Provider>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function renderComposer(
|
|
71
|
+
props?: Partial<React.ComponentProps<typeof SessionComposer>>,
|
|
72
|
+
) {
|
|
73
|
+
const client = createMinimalStigmerMock();
|
|
74
|
+
return render(
|
|
75
|
+
<SessionComposer
|
|
76
|
+
onSubmit={vi.fn()}
|
|
77
|
+
org="acme"
|
|
78
|
+
agentRef={null}
|
|
79
|
+
onAgentRefChange={vi.fn()}
|
|
80
|
+
onSkillRefsChange={vi.fn()}
|
|
81
|
+
skillRefs={[]}
|
|
82
|
+
{...props}
|
|
83
|
+
/>,
|
|
84
|
+
{ wrapper: createWrapper(client) },
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function openConfigureMenu() {
|
|
89
|
+
fireEvent.click(
|
|
90
|
+
screen.getByRole("button", { name: "Configure agent, tools, and skills" }),
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
beforeEach(() => {
|
|
95
|
+
mockAgentSetup.state = { status: "idle" };
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
afterEach(cleanup);
|
|
99
|
+
|
|
100
|
+
describe("SessionComposer — lockAgent", () => {
|
|
101
|
+
it("shows the Agent entry in the Configure menu by default", () => {
|
|
102
|
+
renderComposer();
|
|
103
|
+
openConfigureMenu();
|
|
104
|
+
|
|
105
|
+
expect(screen.getByRole("menuitem", { name: /Agent/ })).toBeTruthy();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("hides the Agent entry when locked, leaving other entries intact", () => {
|
|
109
|
+
renderComposer({
|
|
110
|
+
lockAgent: true,
|
|
111
|
+
agentRef: { org: "acme", slug: "support-bot" },
|
|
112
|
+
});
|
|
113
|
+
openConfigureMenu();
|
|
114
|
+
|
|
115
|
+
expect(screen.queryByRole("menuitem", { name: /Agent/ })).toBeNull();
|
|
116
|
+
expect(screen.getByRole("menuitem", { name: /Skills/ })).toBeTruthy();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("keeps the Agent entry reachable while a locked agent needs env vars", () => {
|
|
120
|
+
// A pinned agent that requires credentials: resolution is pending and
|
|
121
|
+
// the env form lives in the Configure > Agent panel — lock ≠ unwire.
|
|
122
|
+
mockAgentSetup.state = {
|
|
123
|
+
status: "needsEnvVars",
|
|
124
|
+
agentName: "Support Bot",
|
|
125
|
+
agentRef: { org: "acme", slug: "support-bot" },
|
|
126
|
+
missingVariables: [{ key: "API_KEY", isSecret: true }],
|
|
127
|
+
error: null,
|
|
128
|
+
};
|
|
129
|
+
renderComposer({ lockAgent: true });
|
|
130
|
+
|
|
131
|
+
// The composer surfaces the pending setup both as a warning banner...
|
|
132
|
+
expect(screen.getByText("Agent needs configuration before use")).toBeTruthy();
|
|
133
|
+
|
|
134
|
+
// ...and as a (warning-marked) Configure menu entry, despite the lock.
|
|
135
|
+
openConfigureMenu();
|
|
136
|
+
expect(screen.getByRole("menuitem", { name: /Agent/ })).toBeTruthy();
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("removes the Agent entry once the locked agent has resolved", () => {
|
|
140
|
+
mockAgentSetup.state = { status: "idle" };
|
|
141
|
+
renderComposer({
|
|
142
|
+
lockAgent: true,
|
|
143
|
+
agentRef: { org: "acme", slug: "support-bot" },
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
expect(screen.queryByText("Agent needs configuration before use")).toBeNull();
|
|
147
|
+
openConfigureMenu();
|
|
148
|
+
expect(screen.queryByRole("menuitem", { name: /Agent/ })).toBeNull();
|
|
149
|
+
});
|
|
150
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -150,6 +150,8 @@ export type {
|
|
|
150
150
|
SearchResultGroup,
|
|
151
151
|
SessionViewerProps,
|
|
152
152
|
NewSessionViewerProps,
|
|
153
|
+
RuntimeEnvProvider,
|
|
154
|
+
SessionAudience,
|
|
153
155
|
SessionInspectorProps,
|
|
154
156
|
SessionInspectorTabId,
|
|
155
157
|
UseSessionInspectorOptions,
|
|
@@ -853,7 +855,11 @@ export {
|
|
|
853
855
|
useExportResource,
|
|
854
856
|
useImportResource,
|
|
855
857
|
ImportResourceDialog,
|
|
856
|
-
|
|
858
|
+
VisibilitySelector,
|
|
859
|
+
VisibilityBadge,
|
|
860
|
+
blueprintVisibilityLevels,
|
|
861
|
+
INSTANCE_VISIBILITY_LEVELS,
|
|
862
|
+
visibilityLabel,
|
|
857
863
|
useUpdateVisibility,
|
|
858
864
|
} from "./library";
|
|
859
865
|
export type {
|
|
@@ -873,7 +879,9 @@ export type {
|
|
|
873
879
|
ImportPreview,
|
|
874
880
|
UseImportResourceReturn,
|
|
875
881
|
ImportResourceDialogProps,
|
|
876
|
-
|
|
882
|
+
VisibilitySelectorProps,
|
|
883
|
+
VisibilityLevelOption,
|
|
884
|
+
BlueprintVisibilityLevelsContext,
|
|
877
885
|
VisibilityResourceKind,
|
|
878
886
|
UseUpdateVisibilityReturn,
|
|
879
887
|
} from "./library";
|