@stigmer/react 3.12.4 → 3.12.6
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.js +2 -2
- package/agent/AgentDetailView.js.map +1 -1
- package/agent/index.d.ts +0 -1
- package/agent/index.d.ts.map +1 -1
- package/agent/index.js +0 -1
- package/agent/index.js.map +1 -1
- package/agent/useUpdateAgent.d.ts +3 -3
- package/agent/useUpdateAgent.js +3 -3
- package/agent-instance/AgentInstanceDetailPanel.d.ts.map +1 -1
- package/agent-instance/AgentInstanceDetailPanel.js +5 -7
- package/agent-instance/AgentInstanceDetailPanel.js.map +1 -1
- package/agent-instance/useUpdateAgentInstance.d.ts +1 -1
- package/agent-instance/useUpdateAgentInstance.js +1 -1
- package/attachment/AttachmentChipList.js +16 -6
- package/attachment/AttachmentChipList.js.map +1 -1
- package/attachment/index.d.ts +1 -1
- package/attachment/index.d.ts.map +1 -1
- package/attachment/index.js.map +1 -1
- package/attachment/useAttachments.d.ts +51 -8
- package/attachment/useAttachments.d.ts.map +1 -1
- package/attachment/useAttachments.js +74 -3
- package/attachment/useAttachments.js.map +1 -1
- package/channel/AgentChannelsPanel.d.ts.map +1 -1
- package/channel/AgentChannelsPanel.js +10 -5
- package/channel/AgentChannelsPanel.js.map +1 -1
- package/channel/ChannelRunConfigDialog.d.ts +51 -0
- package/channel/ChannelRunConfigDialog.d.ts.map +1 -0
- package/channel/ChannelRunConfigDialog.js +121 -0
- package/channel/ChannelRunConfigDialog.js.map +1 -0
- package/channel/index.d.ts +2 -0
- package/channel/index.d.ts.map +1 -1
- package/channel/index.js +1 -0
- package/channel/index.js.map +1 -1
- package/channel/useSaveAgentChannel.d.ts.map +1 -1
- package/channel/useSaveAgentChannel.js +6 -3
- package/channel/useSaveAgentChannel.js.map +1 -1
- package/channel-app/ChannelAppDetailPanel.js +9 -9
- package/channel-app/ChannelAppDetailPanel.js.map +1 -1
- package/composer/ComposerToolbar.d.ts +6 -1
- package/composer/ComposerToolbar.d.ts.map +1 -1
- package/composer/ComposerToolbar.js +2 -2
- package/composer/ComposerToolbar.js.map +1 -1
- package/composer/SessionComposer.d.ts +9 -0
- package/composer/SessionComposer.d.ts.map +1 -1
- package/composer/SessionComposer.js +39 -13
- package/composer/SessionComposer.js.map +1 -1
- package/conversation/ConversationComposer.d.ts +19 -3
- package/conversation/ConversationComposer.d.ts.map +1 -1
- package/conversation/ConversationComposer.js +4 -4
- package/conversation/ConversationComposer.js.map +1 -1
- package/conversation/ConversationTemplatePickerDialog.d.ts +63 -0
- package/conversation/ConversationTemplatePickerDialog.d.ts.map +1 -0
- package/conversation/ConversationTemplatePickerDialog.js +151 -0
- package/conversation/ConversationTemplatePickerDialog.js.map +1 -0
- package/conversation/ConversationsWorkbench.d.ts.map +1 -1
- package/conversation/ConversationsWorkbench.js +16 -5
- package/conversation/ConversationsWorkbench.js.map +1 -1
- package/conversation/index.d.ts +3 -1
- package/conversation/index.d.ts.map +1 -1
- package/conversation/index.js +1 -0
- package/conversation/index.js.map +1 -1
- package/conversation/useConversationParticipation.d.ts +41 -4
- package/conversation/useConversationParticipation.d.ts.map +1 -1
- package/conversation/useConversationParticipation.js +13 -2
- package/conversation/useConversationParticipation.js.map +1 -1
- package/cursor-accounts/CursorAccountsConsole.d.ts.map +1 -1
- package/cursor-accounts/CursorAccountsConsole.js +12 -3
- package/cursor-accounts/CursorAccountsConsole.js.map +1 -1
- package/cursor-accounts/cursor-account-coverage.d.ts +30 -1
- package/cursor-accounts/cursor-account-coverage.d.ts.map +1 -1
- package/cursor-accounts/cursor-account-coverage.js +21 -0
- package/cursor-accounts/cursor-account-coverage.js.map +1 -1
- package/execution/useCreateAgentExecution.d.ts +15 -0
- package/execution/useCreateAgentExecution.d.ts.map +1 -1
- package/execution/useCreateAgentExecution.js +5 -0
- package/execution/useCreateAgentExecution.js.map +1 -1
- package/identity-account/AccountPreferencesPanel.d.ts +36 -0
- package/identity-account/AccountPreferencesPanel.d.ts.map +1 -0
- package/identity-account/AccountPreferencesPanel.js +202 -0
- package/identity-account/AccountPreferencesPanel.js.map +1 -0
- package/identity-account/index.d.ts +8 -0
- package/identity-account/index.d.ts.map +1 -1
- package/identity-account/index.js +4 -0
- package/identity-account/index.js.map +1 -1
- package/identity-account/useAccountExecutionDefaults.d.ts +36 -0
- package/identity-account/useAccountExecutionDefaults.d.ts.map +1 -0
- package/identity-account/useAccountExecutionDefaults.js +46 -0
- package/identity-account/useAccountExecutionDefaults.js.map +1 -0
- package/identity-account/useMyIdentityAccount.d.ts +55 -0
- package/identity-account/useMyIdentityAccount.d.ts.map +1 -0
- package/identity-account/useMyIdentityAccount.js +37 -0
- package/identity-account/useMyIdentityAccount.js.map +1 -0
- package/identity-account/useUpdateIdentityAccount.d.ts +42 -0
- package/identity-account/useUpdateIdentityAccount.d.ts.map +1 -0
- package/identity-account/useUpdateIdentityAccount.js +53 -0
- package/identity-account/useUpdateIdentityAccount.js.map +1 -0
- package/identity-provider/IdentityProviderDetailPanel.d.ts.map +1 -1
- package/identity-provider/IdentityProviderDetailPanel.js +16 -15
- package/identity-provider/IdentityProviderDetailPanel.js.map +1 -1
- package/index.d.ts +15 -13
- package/index.d.ts.map +1 -1
- package/index.js +11 -8
- package/index.js.map +1 -1
- package/internal/StandingContextField.d.ts +37 -0
- package/internal/StandingContextField.d.ts.map +1 -0
- package/internal/StandingContextField.js +24 -0
- package/internal/StandingContextField.js.map +1 -0
- package/library/InstanceVisibilitySelector.d.ts.map +1 -1
- package/library/InstanceVisibilitySelector.js +9 -2
- package/library/InstanceVisibilitySelector.js.map +1 -1
- package/library/ResourceVisibilityControl.d.ts +13 -3
- package/library/ResourceVisibilityControl.d.ts.map +1 -1
- package/library/ResourceVisibilityControl.js +33 -5
- package/library/ResourceVisibilityControl.js.map +1 -1
- package/library/VisibilityOptionRow.d.ts +6 -0
- package/library/VisibilityOptionRow.d.ts.map +1 -1
- package/library/VisibilityOptionRow.js +11 -1
- package/library/VisibilityOptionRow.js.map +1 -1
- package/library/VisibilitySelector.d.ts.map +1 -1
- package/library/VisibilitySelector.js +14 -2
- package/library/VisibilitySelector.js.map +1 -1
- 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/useCanSetPublicVisibility.d.ts +30 -0
- package/library/useCanSetPublicVisibility.d.ts.map +1 -0
- package/library/useCanSetPublicVisibility.js +41 -0
- package/library/useCanSetPublicVisibility.js.map +1 -0
- package/library/visibilityLevels.d.ts +32 -1
- package/library/visibilityLevels.d.ts.map +1 -1
- package/library/visibilityLevels.js +34 -14
- package/library/visibilityLevels.js.map +1 -1
- package/mcp-server/McpServerDetailView.js +2 -2
- package/mcp-server/McpServerDetailView.js.map +1 -1
- package/mcp-server/index.d.ts +0 -1
- package/mcp-server/index.d.ts.map +1 -1
- package/mcp-server/index.js +0 -1
- package/mcp-server/index.js.map +1 -1
- package/mcp-server/internal/definitionDrift.d.ts +14 -12
- package/mcp-server/internal/definitionDrift.d.ts.map +1 -1
- package/mcp-server/internal/definitionDrift.js +22 -19
- package/mcp-server/internal/definitionDrift.js.map +1 -1
- package/mcp-server/useMcpServerConnect.d.ts +8 -5
- package/mcp-server/useMcpServerConnect.d.ts.map +1 -1
- package/mcp-server/useMcpServerConnect.js +2 -1
- package/mcp-server/useMcpServerConnect.js.map +1 -1
- package/mcp-server/useMcpServerOAuthConnect.d.ts.map +1 -1
- package/mcp-server/useMcpServerOAuthConnect.js +7 -2
- package/mcp-server/useMcpServerOAuthConnect.js.map +1 -1
- package/mcp-server/useUpdateMcpServer.d.ts +3 -3
- package/mcp-server/useUpdateMcpServer.js +3 -3
- package/models/ModelSelector.d.ts +33 -1
- package/models/ModelSelector.d.ts.map +1 -1
- package/models/ModelSelector.js +37 -4
- package/models/ModelSelector.js.map +1 -1
- package/models/index.d.ts +2 -0
- package/models/index.d.ts.map +1 -1
- package/models/index.js +1 -0
- package/models/index.js.map +1 -1
- package/models/registry.d.ts +16 -0
- package/models/registry.d.ts.map +1 -1
- package/models/registry.js +13 -0
- package/models/registry.js.map +1 -1
- package/models/thinking-mode.d.ts +27 -0
- package/models/thinking-mode.d.ts.map +1 -0
- package/models/thinking-mode.js +32 -0
- package/models/thinking-mode.js.map +1 -0
- package/oauth-app/CreateOAuthAppForm.d.ts +2 -2
- package/oauth-app/CreateOAuthAppForm.d.ts.map +1 -1
- package/oauth-app/CreateOAuthAppForm.js +13 -4
- package/oauth-app/CreateOAuthAppForm.js.map +1 -1
- package/oauth-app/OAuthAppDetailPanel.d.ts.map +1 -1
- package/oauth-app/OAuthAppDetailPanel.js +50 -22
- package/oauth-app/OAuthAppDetailPanel.js.map +1 -1
- package/organization/OrgPreferencesPanel.d.ts +32 -0
- package/organization/OrgPreferencesPanel.d.ts.map +1 -0
- package/organization/OrgPreferencesPanel.js +90 -0
- package/organization/OrgPreferencesPanel.js.map +1 -0
- package/organization/OrgProfilePanel.d.ts.map +1 -1
- package/organization/OrgProfilePanel.js +5 -4
- package/organization/OrgProfilePanel.js.map +1 -1
- package/organization/index.d.ts +2 -0
- package/organization/index.d.ts.map +1 -1
- package/organization/index.js +1 -0
- package/organization/index.js.map +1 -1
- package/package.json +4 -4
- package/platform-client/PlatformClientDetailPanel.d.ts.map +1 -1
- package/platform-client/PlatformClientDetailPanel.js +12 -13
- package/platform-client/PlatformClientDetailPanel.js.map +1 -1
- package/schedule/ScheduleDetailView.d.ts.map +1 -1
- package/schedule/ScheduleDetailView.js +21 -10
- package/schedule/ScheduleDetailView.js.map +1 -1
- package/schedule/ScheduleForm.d.ts.map +1 -1
- package/schedule/ScheduleForm.js +13 -3
- package/schedule/ScheduleForm.js.map +1 -1
- package/session/NewSessionViewer.d.ts +10 -1
- package/session/NewSessionViewer.d.ts.map +1 -1
- package/session/NewSessionViewer.js +2 -1
- package/session/NewSessionViewer.js.map +1 -1
- package/session/run-config.d.ts +9 -0
- package/session/run-config.d.ts.map +1 -1
- package/session/run-config.js +5 -0
- package/session/run-config.js.map +1 -1
- package/session/useNewSessionFlow.d.ts +27 -1
- package/session/useNewSessionFlow.d.ts.map +1 -1
- package/session/useNewSessionFlow.js +51 -8
- package/session/useNewSessionFlow.js.map +1 -1
- package/session/useSessionConversation.d.ts +12 -1
- package/session/useSessionConversation.d.ts.map +1 -1
- package/session/useSessionConversation.js +15 -24
- package/session/useSessionConversation.js.map +1 -1
- package/session/useSessionPageFlow.d.ts.map +1 -1
- package/session/useSessionPageFlow.js +14 -10
- package/session/useSessionPageFlow.js.map +1 -1
- package/session/useUpdateSession.d.ts +18 -24
- package/session/useUpdateSession.d.ts.map +1 -1
- package/session/useUpdateSession.js +18 -24
- package/session/useUpdateSession.js.map +1 -1
- package/settings/AccountPreferencesSection.d.ts +3 -0
- package/settings/AccountPreferencesSection.d.ts.map +1 -0
- package/settings/AccountPreferencesSection.js +10 -0
- package/settings/AccountPreferencesSection.js.map +1 -0
- package/settings/OrgPreferencesSection.d.ts +3 -0
- package/settings/OrgPreferencesSection.d.ts.map +1 -0
- package/settings/OrgPreferencesSection.js +13 -0
- package/settings/OrgPreferencesSection.js.map +1 -0
- package/settings/index.d.ts +2 -0
- package/settings/index.d.ts.map +1 -1
- package/settings/index.js +2 -0
- package/settings/index.js.map +1 -1
- package/settings/settings-nav.d.ts.map +1 -1
- package/settings/settings-nav.js +17 -1
- package/settings/settings-nav.js.map +1 -1
- package/src/agent/AgentDetailView.tsx +2 -2
- package/src/agent/index.ts +0 -2
- package/src/agent/useUpdateAgent.ts +3 -3
- package/src/agent-instance/AgentInstanceDetailPanel.tsx +5 -7
- package/src/agent-instance/__tests__/AgentInstanceDetailPanel.test.tsx +75 -0
- package/src/agent-instance/useUpdateAgentInstance.ts +1 -1
- package/src/attachment/AttachmentChipList.tsx +19 -8
- package/src/attachment/__tests__/AttachmentChipList.test.tsx +12 -0
- package/src/attachment/__tests__/useAttachments.test.ts +293 -0
- package/src/attachment/index.ts +1 -0
- package/src/attachment/useAttachments.ts +143 -11
- package/src/channel/AgentChannelsPanel.tsx +26 -1
- package/src/channel/ChannelRunConfigDialog.tsx +351 -0
- package/src/channel/__tests__/ChannelRunConfigDialog.test.tsx +210 -0
- package/src/channel/index.ts +2 -0
- package/src/channel/useSaveAgentChannel.ts +6 -3
- package/src/channel-app/ChannelAppDetailPanel.tsx +9 -9
- package/src/channel-app/__tests__/channelAppWhatsApp.test.tsx +2 -0
- package/src/channel-app/__tests__/channelAppWipeSafety.test.tsx +87 -0
- package/src/composer/ComposerToolbar.tsx +9 -0
- package/src/composer/SessionComposer.tsx +59 -16
- package/src/composer/__tests__/SessionComposer-thinkingMode.test.tsx +176 -0
- package/src/conversation/ConversationComposer.tsx +38 -4
- package/src/conversation/ConversationTemplatePickerDialog.tsx +441 -0
- package/src/conversation/ConversationsWorkbench.tsx +40 -4
- package/src/conversation/__tests__/ConversationComposer.test.tsx +56 -1
- package/src/conversation/__tests__/ConversationTemplatePickerDialog.test.tsx +224 -0
- package/src/conversation/__tests__/useConversationParticipation.test.tsx +45 -4
- package/src/conversation/index.ts +4 -0
- package/src/conversation/useConversationParticipation.ts +58 -6
- package/src/cursor-accounts/CursorAccountsConsole.tsx +40 -5
- package/src/cursor-accounts/__tests__/CursorAccountsConsole.test.tsx +32 -0
- package/src/cursor-accounts/__tests__/cursor-account-coverage.test.ts +58 -1
- package/src/cursor-accounts/cursor-account-coverage.ts +55 -0
- package/src/execution/useCreateAgentExecution.ts +19 -0
- package/src/identity-account/AccountPreferencesPanel.tsx +532 -0
- package/src/identity-account/__tests__/AccountPreferencesPanel.test.tsx +267 -0
- package/src/identity-account/__tests__/useAccountExecutionDefaults.test.tsx +116 -0
- package/src/identity-account/__tests__/useMyIdentityAccount.test.tsx +121 -0
- package/src/identity-account/index.ts +11 -0
- package/src/identity-account/useAccountExecutionDefaults.ts +63 -0
- package/src/identity-account/useMyIdentityAccount.ts +75 -0
- package/src/identity-account/useUpdateIdentityAccount.ts +73 -0
- package/src/identity-provider/IdentityProviderDetailPanel.tsx +18 -15
- package/src/identity-provider/__tests__/IdentityProviderDetailPanel.test.tsx +80 -0
- package/src/index.ts +26 -4
- package/src/internal/StandingContextField.tsx +92 -0
- package/src/library/InstanceVisibilitySelector.tsx +9 -2
- package/src/library/ResourceVisibilityControl.tsx +46 -13
- package/src/library/VisibilityOptionRow.tsx +28 -6
- package/src/library/VisibilitySelector.tsx +14 -2
- package/src/library/__tests__/VisibilitySelector.test.tsx +48 -1
- package/src/library/__tests__/visibilityLevels.test.ts +67 -1
- package/src/library/index.ts +6 -1
- package/src/library/useCanSetPublicVisibility.ts +56 -0
- package/src/library/visibilityLevels.ts +65 -14
- package/src/mcp-server/McpServerDetailView.tsx +2 -2
- package/src/mcp-server/__tests__/useMcpServerConnect.asyncLane.test.tsx +117 -0
- package/src/mcp-server/index.ts +0 -2
- package/src/mcp-server/internal/definitionDrift.ts +22 -20
- package/src/mcp-server/useMcpServerConnect.ts +9 -6
- package/src/mcp-server/useMcpServerOAuthConnect.ts +7 -2
- package/src/mcp-server/useUpdateMcpServer.ts +3 -3
- package/src/models/ModelSelector.tsx +94 -1
- package/src/models/index.ts +2 -0
- package/src/models/registry.ts +29 -0
- package/src/models/thinking-mode.ts +48 -0
- package/src/oauth-app/CreateOAuthAppForm.tsx +58 -3
- package/src/oauth-app/OAuthAppDetailPanel.tsx +103 -20
- package/src/oauth-app/__tests__/OAuthAppDetailPanel.test.tsx +94 -0
- package/src/organization/OrgPreferencesPanel.tsx +221 -0
- package/src/organization/OrgProfilePanel.tsx +5 -4
- package/src/organization/__tests__/OrgPreferencesPanel.test.tsx +145 -0
- package/src/organization/__tests__/OrgProfilePanel.test.tsx +108 -0
- package/src/organization/index.ts +2 -0
- package/src/platform-client/PlatformClientDetailPanel.tsx +14 -13
- package/src/platform-client/__tests__/PlatformClientDetailPanel.test.tsx +82 -0
- package/src/schedule/ScheduleDetailView.tsx +29 -4
- package/src/schedule/ScheduleForm.tsx +14 -1
- package/src/session/NewSessionViewer.tsx +12 -0
- package/src/session/__tests__/useNewSessionFlow.test.tsx +151 -0
- package/src/session/run-config.ts +16 -0
- package/src/session/useNewSessionFlow.ts +82 -9
- package/src/session/useSessionConversation.ts +32 -40
- package/src/session/useSessionPageFlow.ts +14 -11
- package/src/session/useUpdateSession.ts +18 -24
- package/src/settings/AccountPreferencesSection.tsx +25 -0
- package/src/settings/OrgPreferencesSection.tsx +35 -0
- package/src/settings/__tests__/settings-nav.test.ts +27 -0
- package/src/settings/index.ts +2 -0
- package/src/settings/settings-nav.ts +18 -0
- package/src/workflow/ApprovalFormBuilder.tsx +20 -27
- package/src/workflow/WorkflowDetailView.tsx +2 -2
- package/src/workflow/__tests__/WorkflowInstanceDetailPanel.test.tsx +83 -0
- package/src/workflow/index.ts +0 -2
- package/src/workflow/instance/WorkflowInstanceDetailPanel.tsx +6 -7
- package/src/workflow/useUpdateWorkflow.ts +3 -3
- package/styles.css +1 -1
- package/workflow/ApprovalFormBuilder.d.ts.map +1 -1
- package/workflow/ApprovalFormBuilder.js +10 -5
- package/workflow/ApprovalFormBuilder.js.map +1 -1
- package/workflow/WorkflowDetailView.js +2 -2
- package/workflow/WorkflowDetailView.js.map +1 -1
- package/workflow/index.d.ts +0 -1
- package/workflow/index.d.ts.map +1 -1
- package/workflow/index.js +0 -1
- package/workflow/index.js.map +1 -1
- package/workflow/instance/WorkflowInstanceDetailPanel.d.ts.map +1 -1
- package/workflow/instance/WorkflowInstanceDetailPanel.js +6 -7
- package/workflow/instance/WorkflowInstanceDetailPanel.js.map +1 -1
- package/workflow/useUpdateWorkflow.d.ts +3 -3
- package/workflow/useUpdateWorkflow.js +3 -3
- package/agent/internal/agentToInput.d.ts +0 -15
- package/agent/internal/agentToInput.d.ts.map +0 -1
- package/agent/internal/agentToInput.js +0 -84
- package/agent/internal/agentToInput.js.map +0 -1
- package/mcp-server/internal/mcpServerToInput.d.ts +0 -12
- package/mcp-server/internal/mcpServerToInput.d.ts.map +0 -1
- package/mcp-server/internal/mcpServerToInput.js +0 -84
- package/mcp-server/internal/mcpServerToInput.js.map +0 -1
- package/session/session-spec-converters.d.ts +0 -24
- package/session/session-spec-converters.d.ts.map +0 -1
- package/session/session-spec-converters.js +0 -72
- package/session/session-spec-converters.js.map +0 -1
- package/src/agent/internal/__tests__/agentToInput.test.ts +0 -145
- package/src/agent/internal/agentToInput.ts +0 -102
- package/src/mcp-server/__tests__/mcpServerToInput.test.ts +0 -201
- package/src/mcp-server/internal/mcpServerToInput.ts +0 -98
- package/src/session/__tests__/session-spec-converters.test.ts +0 -183
- package/src/session/session-spec-converters.ts +0 -86
- package/src/workflow/internal/workflowToInput.ts +0 -96
- package/workflow/internal/workflowToInput.d.ts +0 -12
- package/workflow/internal/workflowToInput.d.ts.map +0 -1
- package/workflow/internal/workflowToInput.js +0 -73
- package/workflow/internal/workflowToInput.js.map +0 -1
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
type RunConfig,
|
|
38
38
|
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/invocation_pb";
|
|
39
39
|
import { Harness } from "@stigmer/protos/ai/stigmer/agentic/session/v1/enum_pb";
|
|
40
|
-
import { ServiceTier } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
40
|
+
import { ServiceTier, ThinkingMode } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
41
41
|
import type { WorkspaceEntry } from "@stigmer/protos/ai/stigmer/agentic/session/v1/workspace_pb";
|
|
42
42
|
import {
|
|
43
43
|
cadenceToCron,
|
|
@@ -60,6 +60,11 @@ import {
|
|
|
60
60
|
toProtoServiceTier,
|
|
61
61
|
type ServiceTierOption,
|
|
62
62
|
} from "../models/service-tier.js";
|
|
63
|
+
import {
|
|
64
|
+
fromProtoThinkingMode,
|
|
65
|
+
toProtoThinkingMode,
|
|
66
|
+
type ThinkingModeOption,
|
|
67
|
+
} from "../models/thinking-mode.js";
|
|
63
68
|
import { deriveScheduleState, formatNextFire } from "./scheduleState.js";
|
|
64
69
|
import {
|
|
65
70
|
ScheduleRunsCompactList,
|
|
@@ -599,10 +604,10 @@ export function ScheduleDetailView({
|
|
|
599
604
|
{editable && target ? (
|
|
600
605
|
<EngineModelInlineEditor
|
|
601
606
|
invocation={target}
|
|
602
|
-
onSave={(harness, modelName, serviceTier) =>
|
|
607
|
+
onSave={(harness, modelName, serviceTier, thinkingMode) =>
|
|
603
608
|
saveSpecField("engine-model", (s) => {
|
|
604
609
|
if (s.target.case === "agent") {
|
|
605
|
-
applyEngineModel(s.target.value, harness, modelName, serviceTier);
|
|
610
|
+
applyEngineModel(s.target.value, harness, modelName, serviceTier, thinkingMode);
|
|
606
611
|
}
|
|
607
612
|
})
|
|
608
613
|
}
|
|
@@ -1016,6 +1021,7 @@ function EngineModelInlineEditor({
|
|
|
1016
1021
|
harness: Harness,
|
|
1017
1022
|
modelName: string,
|
|
1018
1023
|
serviceTier: ServiceTierOption,
|
|
1024
|
+
thinkingMode: ThinkingModeOption,
|
|
1019
1025
|
) => Promise<boolean>;
|
|
1020
1026
|
readonly isSaving: boolean;
|
|
1021
1027
|
readonly error?: string;
|
|
@@ -1024,6 +1030,7 @@ function EngineModelInlineEditor({
|
|
|
1024
1030
|
const [modelName, setModelName] = useState("");
|
|
1025
1031
|
const [harness, setHarness] = useState<HarnessOption>("cursor");
|
|
1026
1032
|
const [serviceTier, setServiceTier] = useState<ServiceTierOption>("standard");
|
|
1033
|
+
const [thinkingMode, setThinkingMode] = useState<ThinkingModeOption>("disabled");
|
|
1027
1034
|
|
|
1028
1035
|
const startEdit = () => {
|
|
1029
1036
|
setModelName(invocation.runConfig?.modelName ?? "");
|
|
@@ -1035,6 +1042,9 @@ function EngineModelInlineEditor({
|
|
|
1035
1042
|
setServiceTier(
|
|
1036
1043
|
fromProtoServiceTier(invocation.runConfig?.serviceTier) ?? "standard",
|
|
1037
1044
|
);
|
|
1045
|
+
setThinkingMode(
|
|
1046
|
+
fromProtoThinkingMode(invocation.runConfig?.thinkingMode) ?? "disabled",
|
|
1047
|
+
);
|
|
1038
1048
|
setIsEditing(true);
|
|
1039
1049
|
};
|
|
1040
1050
|
|
|
@@ -1056,6 +1066,8 @@ function EngineModelInlineEditor({
|
|
|
1056
1066
|
onHarnessChange={setHarness}
|
|
1057
1067
|
serviceTier={serviceTier}
|
|
1058
1068
|
onServiceTierChange={setServiceTier}
|
|
1069
|
+
thinkingMode={thinkingMode}
|
|
1070
|
+
onThinkingModeChange={setThinkingMode}
|
|
1059
1071
|
placeholderLabel="Platform default"
|
|
1060
1072
|
disabled={isSaving}
|
|
1061
1073
|
/>
|
|
@@ -1065,6 +1077,7 @@ function EngineModelInlineEditor({
|
|
|
1065
1077
|
onClick={() => {
|
|
1066
1078
|
setModelName("");
|
|
1067
1079
|
setServiceTier("standard");
|
|
1080
|
+
setThinkingMode("disabled");
|
|
1068
1081
|
}}
|
|
1069
1082
|
disabled={isSaving}
|
|
1070
1083
|
className="stg:rounded-md stg:px-2 stg:py-1 stg:text-[0.65rem] stg:text-muted-foreground stg:hover:text-foreground stg:focus-visible:outline-none stg:focus-visible:ring-2 stg:focus-visible:ring-ring stg:disabled:pointer-events-none stg:disabled:opacity-50"
|
|
@@ -1084,6 +1097,7 @@ function EngineModelInlineEditor({
|
|
|
1084
1097
|
modelName !== "" ? toProtoHarness(harness) : Harness.UNSPECIFIED,
|
|
1085
1098
|
modelName,
|
|
1086
1099
|
serviceTier,
|
|
1100
|
+
thinkingMode,
|
|
1087
1101
|
);
|
|
1088
1102
|
if (ok) setIsEditing(false);
|
|
1089
1103
|
}}
|
|
@@ -1169,14 +1183,17 @@ function applyEngineModel(
|
|
|
1169
1183
|
harness: Harness,
|
|
1170
1184
|
modelName: string,
|
|
1171
1185
|
serviceTier: ServiceTierOption,
|
|
1186
|
+
thinkingMode: ThinkingModeOption,
|
|
1172
1187
|
): void {
|
|
1173
1188
|
invocation.harness = harness;
|
|
1174
1189
|
invocation.runConfig = normalizeRunConfig(
|
|
1175
1190
|
modelName,
|
|
1176
1191
|
invocation.runConfig?.maxCostUsd ?? 0,
|
|
1177
1192
|
invocation.runConfig?.maxToolRounds ?? 0,
|
|
1178
|
-
// The
|
|
1193
|
+
// The variant attributes ride the model choice: no model, no tier and
|
|
1194
|
+
// no thinking (#357/#772).
|
|
1179
1195
|
modelName.trim() !== "" ? serviceTier : "standard",
|
|
1196
|
+
modelName.trim() !== "" ? thinkingMode : "disabled",
|
|
1180
1197
|
);
|
|
1181
1198
|
}
|
|
1182
1199
|
|
|
@@ -1190,6 +1207,7 @@ function applyBudget(
|
|
|
1190
1207
|
maxCostUsd ?? 0,
|
|
1191
1208
|
invocation.runConfig?.maxToolRounds ?? 0,
|
|
1192
1209
|
fromProtoServiceTier(invocation.runConfig?.serviceTier) ?? "standard",
|
|
1210
|
+
fromProtoThinkingMode(invocation.runConfig?.thinkingMode) ?? "disabled",
|
|
1193
1211
|
);
|
|
1194
1212
|
}
|
|
1195
1213
|
|
|
@@ -1198,12 +1216,14 @@ function normalizeRunConfig(
|
|
|
1198
1216
|
maxCostUsd: number,
|
|
1199
1217
|
maxToolRounds: number,
|
|
1200
1218
|
serviceTier: ServiceTierOption,
|
|
1219
|
+
thinkingMode: ThinkingModeOption,
|
|
1201
1220
|
): RunConfig | undefined {
|
|
1202
1221
|
const fields: {
|
|
1203
1222
|
modelName?: string;
|
|
1204
1223
|
maxCostUsd?: number;
|
|
1205
1224
|
maxToolRounds?: number;
|
|
1206
1225
|
serviceTier?: ServiceTier;
|
|
1226
|
+
thinkingMode?: ThinkingMode;
|
|
1207
1227
|
} = {};
|
|
1208
1228
|
if (modelName.trim() !== "") fields.modelName = modelName.trim();
|
|
1209
1229
|
if (maxCostUsd > 0) fields.maxCostUsd = maxCostUsd;
|
|
@@ -1211,6 +1231,8 @@ function normalizeRunConfig(
|
|
|
1211
1231
|
// Only an active fast choice is carried — an untouched tier stays
|
|
1212
1232
|
// absent, preserving the unspecified-vs-explicit ledger distinction (#357).
|
|
1213
1233
|
if (serviceTier === "fast") fields.serviceTier = toProtoServiceTier(serviceTier);
|
|
1234
|
+
// The tier's #772 twin: only an active enabled choice is carried.
|
|
1235
|
+
if (thinkingMode === "enabled") fields.thinkingMode = toProtoThinkingMode(thinkingMode);
|
|
1214
1236
|
|
|
1215
1237
|
return Object.keys(fields).length > 0
|
|
1216
1238
|
? create(RunConfigSchema, fields)
|
|
@@ -1429,6 +1451,9 @@ function EngineModelSummary({
|
|
|
1429
1451
|
if (invocation?.runConfig?.serviceTier === ServiceTier.FAST) {
|
|
1430
1452
|
parts.push("Fast tier");
|
|
1431
1453
|
}
|
|
1454
|
+
if (invocation?.runConfig?.thinkingMode === ThinkingMode.ENABLED) {
|
|
1455
|
+
parts.push("Thinking");
|
|
1456
|
+
}
|
|
1432
1457
|
return <span className="stg:text-sm stg:text-foreground">{parts.join(" · ")}</span>;
|
|
1433
1458
|
}
|
|
1434
1459
|
|
|
@@ -16,6 +16,7 @@ import { useGitHubConnection } from "../github/useGitHubConnection.js";
|
|
|
16
16
|
import { ModelSelector } from "../models/ModelSelector.js";
|
|
17
17
|
import { toProtoHarness, type HarnessOption } from "../models/harness.js";
|
|
18
18
|
import { toProtoServiceTier, type ServiceTierOption } from "../models/service-tier.js";
|
|
19
|
+
import { toProtoThinkingMode, type ThinkingModeOption } from "../models/thinking-mode.js";
|
|
19
20
|
import { Switch } from "../switch/Switch.js";
|
|
20
21
|
import { useStigmerPortalContainer } from "../portal-container.js";
|
|
21
22
|
import { useWorkspaceEntries } from "../workspace/useWorkspaceEntries.js";
|
|
@@ -116,6 +117,8 @@ export function ScheduleForm({
|
|
|
116
117
|
// is picked. No model pinned = no tier pinned (fast requires a model,
|
|
117
118
|
// and the form's reset button clears both).
|
|
118
119
|
const [serviceTier, setServiceTier] = useState<ServiceTierOption>("standard");
|
|
120
|
+
// Thinking mode: the tier's #772 twin, capability-scoped the same way.
|
|
121
|
+
const [thinkingMode, setThinkingMode] = useState<ThinkingModeOption>("disabled");
|
|
119
122
|
|
|
120
123
|
const [budgetUsd, setBudgetUsd] = useState("");
|
|
121
124
|
|
|
@@ -152,7 +155,7 @@ export function ScheduleForm({
|
|
|
152
155
|
if (!canSubmit || !agentRef) return;
|
|
153
156
|
|
|
154
157
|
clearError();
|
|
155
|
-
const runConfig = buildRunConfig(modelName, budgetUsd, serviceTier);
|
|
158
|
+
const runConfig = buildRunConfig(modelName, budgetUsd, serviceTier, thinkingMode);
|
|
156
159
|
try {
|
|
157
160
|
const schedule = await create({
|
|
158
161
|
name: trimmedName,
|
|
@@ -195,6 +198,7 @@ export function ScheduleForm({
|
|
|
195
198
|
modelName,
|
|
196
199
|
modelHarness,
|
|
197
200
|
serviceTier,
|
|
201
|
+
thinkingMode,
|
|
198
202
|
budgetUsd,
|
|
199
203
|
workspace,
|
|
200
204
|
onComplete,
|
|
@@ -362,6 +366,8 @@ export function ScheduleForm({
|
|
|
362
366
|
onHarnessChange={setModelHarness}
|
|
363
367
|
serviceTier={serviceTier}
|
|
364
368
|
onServiceTierChange={setServiceTier}
|
|
369
|
+
thinkingMode={thinkingMode}
|
|
370
|
+
onThinkingModeChange={setThinkingMode}
|
|
365
371
|
placeholderLabel="Platform default"
|
|
366
372
|
disabled={isCreating}
|
|
367
373
|
/>
|
|
@@ -371,6 +377,7 @@ export function ScheduleForm({
|
|
|
371
377
|
onClick={() => {
|
|
372
378
|
setModelName("");
|
|
373
379
|
setServiceTier("standard");
|
|
380
|
+
setThinkingMode("disabled");
|
|
374
381
|
}}
|
|
375
382
|
disabled={isCreating}
|
|
376
383
|
className={cn(
|
|
@@ -514,6 +521,7 @@ function buildRunConfig(
|
|
|
514
521
|
modelName: string,
|
|
515
522
|
budgetUsd: string,
|
|
516
523
|
serviceTier: ServiceTierOption,
|
|
524
|
+
thinkingMode: ThinkingModeOption,
|
|
517
525
|
): RunConfigInput | undefined {
|
|
518
526
|
const model = modelName.trim();
|
|
519
527
|
const cost = Number.parseFloat(budgetUsd);
|
|
@@ -528,6 +536,11 @@ function buildRunConfig(
|
|
|
528
536
|
if (serviceTier === "fast" && model !== "") {
|
|
529
537
|
config.serviceTier = toProtoServiceTier(serviceTier);
|
|
530
538
|
}
|
|
539
|
+
// The tier's #772 twin: thinking is a per-model capability, same
|
|
540
|
+
// only-explicit-enabled + requires-a-model contract.
|
|
541
|
+
if (thinkingMode === "enabled" && model !== "") {
|
|
542
|
+
config.thinkingMode = toProtoThinkingMode(thinkingMode);
|
|
543
|
+
}
|
|
531
544
|
|
|
532
545
|
return Object.keys(config).length > 0 ? config : undefined;
|
|
533
546
|
}
|
|
@@ -9,6 +9,7 @@ import type { WorkspaceContentSearcher } from "../workspace/WorkspaceContentSear
|
|
|
9
9
|
import type { InteractionModeOption } from "../composer/index.js";
|
|
10
10
|
import { SessionComposer } from "../composer/index.js";
|
|
11
11
|
import type { HarnessOption } from "../models/harness.js";
|
|
12
|
+
import type { AccountExecutionDefaults } from "../identity-account/useAccountExecutionDefaults.js";
|
|
12
13
|
import { SessionViewerLayout } from "./SessionViewerLayout.js";
|
|
13
14
|
import { useWorkspaceEditors } from "../internal/store/index.js";
|
|
14
15
|
import { WorkspaceSurface } from "../workspace/WorkspaceSurface.js";
|
|
@@ -163,6 +164,15 @@ export interface NewSessionViewerProps {
|
|
|
163
164
|
*/
|
|
164
165
|
readonly defaultHarness?: HarnessOption;
|
|
165
166
|
|
|
167
|
+
/**
|
|
168
|
+
* The user's account-level execution defaults, typically from
|
|
169
|
+
* `useAccountExecutionDefaults()`. Seeds the harness and model pickers
|
|
170
|
+
* under the layered precedence documented on
|
|
171
|
+
* {@link UseNewSessionFlowOptions.accountDefaults}; explicit device
|
|
172
|
+
* picks always win. Ignored for the `"guest"` audience.
|
|
173
|
+
*/
|
|
174
|
+
readonly accountDefaults?: AccountExecutionDefaults;
|
|
175
|
+
|
|
166
176
|
/** Agent to auto-select on mount (used for draft flows). */
|
|
167
177
|
readonly initialAgentRef?: ResourceRef;
|
|
168
178
|
/**
|
|
@@ -253,6 +263,7 @@ export function NewSessionViewer({
|
|
|
253
263
|
panelOpen,
|
|
254
264
|
onPanelOpenChange,
|
|
255
265
|
defaultHarness,
|
|
266
|
+
accountDefaults,
|
|
256
267
|
initialAgentRef,
|
|
257
268
|
initialInstanceId,
|
|
258
269
|
initialAttachments,
|
|
@@ -269,6 +280,7 @@ export function NewSessionViewer({
|
|
|
269
280
|
onError,
|
|
270
281
|
getRuntimeEnv,
|
|
271
282
|
defaultHarness,
|
|
283
|
+
accountDefaults,
|
|
272
284
|
audience,
|
|
273
285
|
runConfig,
|
|
274
286
|
});
|
|
@@ -805,6 +805,157 @@ describe("useNewSessionFlow", () => {
|
|
|
805
805
|
});
|
|
806
806
|
});
|
|
807
807
|
|
|
808
|
+
describe("accountDefaults (oss#293 Phase 1.5 layered seed)", () => {
|
|
809
|
+
// Two native models so "stored pick outranks account default" is
|
|
810
|
+
// distinguishable; the shared TEST_MODELS carries one per harness.
|
|
811
|
+
const SEED_MODELS = parseRegistryJson({
|
|
812
|
+
models: [
|
|
813
|
+
{ id: "claude-sonnet-4.6", displayName: "Claude Sonnet 4.6", shortDescription: "", speedTier: "fast", provider: "anthropic", harness: "native", costTier: "standard", featured: true, pricing: { inputPricePerMillion: 3, outputPricePerMillion: 15, cacheWritePricePerMillion: 3.75, cacheReadPricePerMillion: 0.3 } },
|
|
814
|
+
{ id: "gpt-5.3", displayName: "GPT 5.3", shortDescription: "", speedTier: "fast", provider: "openai", harness: "native", costTier: "standard", featured: false, pricing: { inputPricePerMillion: 2, outputPricePerMillion: 8, cacheWritePricePerMillion: 2, cacheReadPricePerMillion: 0.2 } },
|
|
815
|
+
{ id: "default", displayName: "Cursor Auto", shortDescription: "", speedTier: "fast", provider: "cursor", harness: "cursor", costTier: "standard", featured: true, pricing: { inputPricePerMillion: 1.25, outputPricePerMillion: 6, cacheWritePricePerMillion: 1.25, cacheReadPricePerMillion: 0.25 } },
|
|
816
|
+
{ id: "composer-2.5", displayName: "Composer 2.5", shortDescription: "", speedTier: "fast", provider: "cursor", harness: "cursor", costTier: "standard", featured: false, pricing: { inputPricePerMillion: 1, outputPricePerMillion: 5, cacheWritePricePerMillion: 1, cacheReadPricePerMillion: 0.1 } },
|
|
817
|
+
],
|
|
818
|
+
});
|
|
819
|
+
|
|
820
|
+
function seedWrapper() {
|
|
821
|
+
const state: ModelRegistryState = { models: SEED_MODELS, isLoading: false, error: null, refetch: () => {} };
|
|
822
|
+
return function Wrapper({ children }: { children: ReactNode }) {
|
|
823
|
+
return (
|
|
824
|
+
<ModelRegistryContext.Provider value={state}>
|
|
825
|
+
{children}
|
|
826
|
+
</ModelRegistryContext.Provider>
|
|
827
|
+
);
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
it("seeds the harness when nothing is stored", () => {
|
|
832
|
+
const opts = { ...defaultOptions(), accountDefaults: { harness: "cursor" as const } };
|
|
833
|
+
const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
|
|
834
|
+
|
|
835
|
+
expect(result.current.harness).toBe("cursor");
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
it("a stored harness choice outranks the account default", () => {
|
|
839
|
+
localStorage.setItem(STORAGE_KEY_HARNESS, "native");
|
|
840
|
+
const opts = { ...defaultOptions(), accountDefaults: { harness: "cursor" as const } };
|
|
841
|
+
const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
|
|
842
|
+
|
|
843
|
+
expect(result.current.harness).toBe("native");
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
it("the account harness outranks the embedder defaultHarness", () => {
|
|
847
|
+
const opts = {
|
|
848
|
+
...defaultOptions(),
|
|
849
|
+
defaultHarness: "native" as const,
|
|
850
|
+
accountDefaults: { harness: "cursor" as const },
|
|
851
|
+
};
|
|
852
|
+
const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
|
|
853
|
+
|
|
854
|
+
expect(result.current.harness).toBe("cursor");
|
|
855
|
+
});
|
|
856
|
+
|
|
857
|
+
it("never persists the seeded harness — only explicit choices", () => {
|
|
858
|
+
const opts = { ...defaultOptions(), accountDefaults: { harness: "cursor" as const } };
|
|
859
|
+
renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
|
|
860
|
+
|
|
861
|
+
expect(localStorage.getItem(STORAGE_KEY_HARNESS)).toBeNull();
|
|
862
|
+
});
|
|
863
|
+
|
|
864
|
+
it("a late-arriving harness seed applies when the user has not picked (whoAmI resolves after mount)", () => {
|
|
865
|
+
const base: Parameters<typeof useNewSessionFlow>[0] = defaultOptions();
|
|
866
|
+
const { result, rerender } = renderHook(
|
|
867
|
+
(opts: Parameters<typeof useNewSessionFlow>[0]) => useNewSessionFlow(opts),
|
|
868
|
+
{ wrapper: seedWrapper(), initialProps: base },
|
|
869
|
+
);
|
|
870
|
+
expect(result.current.harness).toBe("native");
|
|
871
|
+
|
|
872
|
+
rerender({ ...base, accountDefaults: { harness: "cursor" as const } });
|
|
873
|
+
|
|
874
|
+
expect(result.current.harness).toBe("cursor");
|
|
875
|
+
expect(localStorage.getItem(STORAGE_KEY_HARNESS)).toBeNull();
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
it("a late-arriving harness seed never overrides an explicit pick this mount", () => {
|
|
879
|
+
const base: Parameters<typeof useNewSessionFlow>[0] = defaultOptions();
|
|
880
|
+
const { result, rerender } = renderHook(
|
|
881
|
+
(opts: Parameters<typeof useNewSessionFlow>[0]) => useNewSessionFlow(opts),
|
|
882
|
+
{ wrapper: seedWrapper(), initialProps: base },
|
|
883
|
+
);
|
|
884
|
+
act(() => result.current.setHarness("native"));
|
|
885
|
+
|
|
886
|
+
rerender({ ...base, accountDefaults: { harness: "cursor" as const } });
|
|
887
|
+
|
|
888
|
+
expect(result.current.harness).toBe("native");
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
it("seeds the model for the active harness when nothing is stored", () => {
|
|
892
|
+
const opts = { ...defaultOptions(), accountDefaults: { nativeModel: "gpt-5.3" } };
|
|
893
|
+
const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
|
|
894
|
+
|
|
895
|
+
expect(result.current.modelId).toBe("gpt-5.3");
|
|
896
|
+
});
|
|
897
|
+
|
|
898
|
+
it("a stored model pick outranks the account default", async () => {
|
|
899
|
+
localStorage.setItem(STORAGE_KEY_MODEL_NATIVE, "claude-sonnet-4.6");
|
|
900
|
+
const opts = { ...defaultOptions(), accountDefaults: { nativeModel: "gpt-5.3" } };
|
|
901
|
+
const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
|
|
902
|
+
|
|
903
|
+
// The stored restore lands in a passive effect once the registry is
|
|
904
|
+
// ready; the account seed must not win the race before it.
|
|
905
|
+
await act(async () => {});
|
|
906
|
+
expect(result.current.modelId).toBe("claude-sonnet-4.6");
|
|
907
|
+
});
|
|
908
|
+
|
|
909
|
+
it("self-heals a stale account model to the platform default (undefined)", () => {
|
|
910
|
+
const opts = { ...defaultOptions(), accountDefaults: { nativeModel: "retired-model" } };
|
|
911
|
+
const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
|
|
912
|
+
|
|
913
|
+
expect(result.current.modelId).toBeUndefined();
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
it("never persists the seeded model — only explicit choices", () => {
|
|
917
|
+
const opts = { ...defaultOptions(), accountDefaults: { nativeModel: "gpt-5.3" } };
|
|
918
|
+
renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
|
|
919
|
+
|
|
920
|
+
expect(localStorage.getItem(STORAGE_KEY_MODEL_NATIVE)).toBeNull();
|
|
921
|
+
});
|
|
922
|
+
|
|
923
|
+
it("follows the active harness: cursorModel seeds cursor sessions", () => {
|
|
924
|
+
const opts = {
|
|
925
|
+
...defaultOptions(),
|
|
926
|
+
accountDefaults: { harness: "cursor" as const, nativeModel: "gpt-5.3", cursorModel: "composer-2.5" },
|
|
927
|
+
};
|
|
928
|
+
const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
|
|
929
|
+
|
|
930
|
+
expect(result.current.harness).toBe("cursor");
|
|
931
|
+
expect(result.current.modelId).toBe("composer-2.5");
|
|
932
|
+
});
|
|
933
|
+
|
|
934
|
+
it("submits the seeded model explicitly — the pill promise (#663) and the DD-003 seed rule", async () => {
|
|
935
|
+
const opts = { ...defaultOptions(), accountDefaults: { nativeModel: "gpt-5.3" } };
|
|
936
|
+
const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
|
|
937
|
+
|
|
938
|
+
await act(async () => {
|
|
939
|
+
await result.current.submit("Hello");
|
|
940
|
+
});
|
|
941
|
+
|
|
942
|
+
expect(mockCreateExecution.mock.calls[0][0].modelName).toBe("gpt-5.3");
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
it("guest audience ignores accountDefaults entirely", () => {
|
|
946
|
+
const opts = {
|
|
947
|
+
...defaultOptions(),
|
|
948
|
+
audience: "guest" as const,
|
|
949
|
+
accountDefaults: { harness: "native" as const, nativeModel: "gpt-5.3", cursorModel: "composer-2.5" },
|
|
950
|
+
};
|
|
951
|
+
const { result } = renderHook(() => useNewSessionFlow(opts), { wrapper: seedWrapper() });
|
|
952
|
+
|
|
953
|
+
// Platform share policy: cursor harness, no client model.
|
|
954
|
+
expect(result.current.harness).toBe("cursor");
|
|
955
|
+
expect(result.current.modelId).toBeUndefined();
|
|
956
|
+
});
|
|
957
|
+
});
|
|
958
|
+
|
|
808
959
|
describe("submit while default agent is loading", () => {
|
|
809
960
|
it("awaits default agent and creates session when fetch resolves", async () => {
|
|
810
961
|
const resolvedAgent = { status: { defaultInstanceId: "awaited-inst" } };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ServiceTierOption } from "../models/service-tier.js";
|
|
2
|
+
import type { ThinkingModeOption } from "../models/thinking-mode.js";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Owner-pinned execution config for a session surface
|
|
@@ -39,6 +40,14 @@ export interface SessionRunConfig {
|
|
|
39
40
|
* pin is a host configuration error and throws at submit.
|
|
40
41
|
*/
|
|
41
42
|
readonly serviceTier?: ServiceTierOption;
|
|
43
|
+
/**
|
|
44
|
+
* Thinking mode for every execution (stigmer/stigmer#772).
|
|
45
|
+
* `"enabled"` requires {@link modelName} under the same contract as
|
|
46
|
+
* {@link serviceTier}: thinking is a per-model capability (the server
|
|
47
|
+
* refuses it fail-closed for Auto), so a mode pin without a model pin
|
|
48
|
+
* is a host configuration error and throws at submit.
|
|
49
|
+
*/
|
|
50
|
+
readonly thinkingMode?: ThinkingModeOption;
|
|
42
51
|
}
|
|
43
52
|
|
|
44
53
|
/**
|
|
@@ -56,4 +65,11 @@ export function assertValidRunConfig(runConfig: SessionRunConfig): void {
|
|
|
56
65
|
+ "dimension. Pin the model the surface should run.",
|
|
57
66
|
);
|
|
58
67
|
}
|
|
68
|
+
if (runConfig.thinkingMode === "enabled" && !runConfig.modelName) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
"SessionRunConfig: thinkingMode \"enabled\" requires modelName — "
|
|
71
|
+
+ "thinking is a per-model capability and Auto (no pinned model) has "
|
|
72
|
+
+ "no variant dimensions. Pin the model the surface should run.",
|
|
73
|
+
);
|
|
74
|
+
}
|
|
59
75
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
4
|
import { getUserMessage, type McpServerUsageInput, type ResourceRef } from "@stigmer/sdk";
|
|
5
|
+
import type { AccountExecutionDefaults } from "../identity-account/useAccountExecutionDefaults.js";
|
|
5
6
|
import type { AgentResolution } from "../agent/index.js";
|
|
6
7
|
import { useDefaultAgent } from "../agent/index.js";
|
|
7
8
|
import { useModelRegistry } from "../models/index.js";
|
|
@@ -102,6 +103,26 @@ export interface UseNewSessionFlowOptions {
|
|
|
102
103
|
* @default DEFAULT_HARNESS ("native")
|
|
103
104
|
*/
|
|
104
105
|
readonly defaultHarness?: HarnessOption;
|
|
106
|
+
/**
|
|
107
|
+
* The user's account-level execution defaults
|
|
108
|
+
* (`IdentityAccountPreferences.default_*`), typically from
|
|
109
|
+
* `useAccountExecutionDefaults()`. A SEED in the layered precedence —
|
|
110
|
+
* explicit device-local choices always outrank it:
|
|
111
|
+
*
|
|
112
|
+
* - harness: stored choice > `accountDefaults.harness` >
|
|
113
|
+
* {@link defaultHarness} > platform default. May arrive after mount
|
|
114
|
+
* (whoAmI resolves async); a late value still seeds unless the user
|
|
115
|
+
* has already picked a harness this mount.
|
|
116
|
+
* - model: stored per-harness choice > the account's model for the
|
|
117
|
+
* active harness (validated against the registry; a stale model
|
|
118
|
+
* silently falls through) > the harness default.
|
|
119
|
+
*
|
|
120
|
+
* Seeded values are never persisted to localStorage — the account
|
|
121
|
+
* preference keeps applying until the user decides. Ignored for the
|
|
122
|
+
* `"guest"` audience (platform share policy owns guest config), and
|
|
123
|
+
* consumers must not fetch identity for guest/embed surfaces.
|
|
124
|
+
*/
|
|
125
|
+
readonly accountDefaults?: AccountExecutionDefaults;
|
|
105
126
|
/**
|
|
106
127
|
* Who this flow serves. `"guest"` adapts the orchestration to the
|
|
107
128
|
* guest principal's permission model: the org default-agent lookup
|
|
@@ -162,7 +183,12 @@ export interface UseNewSessionFlowReturn {
|
|
|
162
183
|
/** Switch the harness. Resets the model if invalid for the new harness. */
|
|
163
184
|
readonly setHarness: (harness: HarnessOption) => void;
|
|
164
185
|
|
|
165
|
-
/**
|
|
186
|
+
/**
|
|
187
|
+
* The model an untouched send will run: the explicit device pick when
|
|
188
|
+
* one exists (persisted per-harness to localStorage), else the account
|
|
189
|
+
* default for the active harness. `undefined` resolves to the harness
|
|
190
|
+
* default downstream.
|
|
191
|
+
*/
|
|
166
192
|
readonly modelId: string | undefined;
|
|
167
193
|
/** Update the selected model. Automatically persists to localStorage. */
|
|
168
194
|
readonly setModelId: (id: string) => void;
|
|
@@ -269,6 +295,10 @@ export function useNewSessionFlow(
|
|
|
269
295
|
sessionContext,
|
|
270
296
|
} = options;
|
|
271
297
|
const isGuest = options.audience === "guest";
|
|
298
|
+
// Guests never inherit account defaults — the platform share policy owns
|
|
299
|
+
// guest execution config (GUEST_HARNESS reasoning), and identity-derived
|
|
300
|
+
// preferences must never shape a share/embed surface.
|
|
301
|
+
const accountDefaults = isGuest ? undefined : options.accountDefaults;
|
|
272
302
|
// Guests never carry a client pin: guest execution config is owned by
|
|
273
303
|
// the server-side share policy (GUEST_HARNESS reasoning). Validated at
|
|
274
304
|
// render so a statically-wrong pin (fast tier, no model) fails in the
|
|
@@ -277,6 +307,7 @@ export function useNewSessionFlow(
|
|
|
277
307
|
if (runConfig) assertValidRunConfig(runConfig);
|
|
278
308
|
const pinnedModelName = runConfig?.modelName;
|
|
279
309
|
const pinnedServiceTier = runConfig?.serviceTier;
|
|
310
|
+
const pinnedThinkingMode = runConfig?.thinkingMode;
|
|
280
311
|
const contextTarget = useExecutionTarget();
|
|
281
312
|
const executionTarget = options.executionTarget ?? contextTarget;
|
|
282
313
|
const adapter = useRunnerAdapter();
|
|
@@ -293,13 +324,30 @@ export function useNewSessionFlow(
|
|
|
293
324
|
// touch localStorage: a browser previously used in the Console must not
|
|
294
325
|
// leak its stored harness into a share/embed session.
|
|
295
326
|
if (isGuest) return GUEST_HARNESS;
|
|
296
|
-
if (typeof window === "undefined")
|
|
327
|
+
if (typeof window === "undefined")
|
|
328
|
+
return accountDefaults?.harness ?? defaultHarness ?? DEFAULT_HARNESS;
|
|
297
329
|
// Only explicit user choices are persisted (see setHarness), so a
|
|
298
|
-
// stored value always outranks the embedder's
|
|
330
|
+
// stored value always outranks the account default and the embedder's
|
|
331
|
+
// defaultHarness.
|
|
299
332
|
const stored = localStorage.getItem(STORAGE_KEY_HARNESS);
|
|
300
333
|
if (stored === "native" || stored === "cursor") return stored;
|
|
301
|
-
return defaultHarness ?? DEFAULT_HARNESS;
|
|
334
|
+
return accountDefaults?.harness ?? defaultHarness ?? DEFAULT_HARNESS;
|
|
302
335
|
});
|
|
336
|
+
// Set once the user picks a harness this mount — a late-arriving account
|
|
337
|
+
// default must never override an explicit choice (the composer's
|
|
338
|
+
// userOverrodeModel idiom).
|
|
339
|
+
const harnessTouchedRef = useRef(false);
|
|
340
|
+
|
|
341
|
+
// Account defaults resolve async (whoAmI): when the harness seed arrives
|
|
342
|
+
// after mount, apply it once — unless the user has picked or a stored
|
|
343
|
+
// choice exists. Never persisted: seeding must not masquerade as a user
|
|
344
|
+
// choice, or the account preference would stop applying elsewhere.
|
|
345
|
+
useEffect(() => {
|
|
346
|
+
const seed = accountDefaults?.harness;
|
|
347
|
+
if (isGuest || harnessTouchedRef.current || !seed) return;
|
|
348
|
+
if (typeof window !== "undefined" && localStorage.getItem(STORAGE_KEY_HARNESS)) return;
|
|
349
|
+
setHarnessRaw(seed);
|
|
350
|
+
}, [isGuest, accountDefaults?.harness]);
|
|
303
351
|
|
|
304
352
|
const stigmer = useStigmer();
|
|
305
353
|
const { getModel, isLoading: isModelsLoading } = useModelRegistry({ harness });
|
|
@@ -326,8 +374,26 @@ export function useNewSessionFlow(
|
|
|
326
374
|
|
|
327
375
|
const validModelId = modelId && getModel(modelId) ? modelId : undefined;
|
|
328
376
|
|
|
377
|
+
// The account's model for the active harness, registry-validated the same
|
|
378
|
+
// way as the stored choice (a stale/removed preference silently falls
|
|
379
|
+
// through to the harness default — self-healing). Derived, never written
|
|
380
|
+
// into `modelId` state: the persist effect below stores only explicit
|
|
381
|
+
// choices, and a derived seed cannot leak into localStorage.
|
|
382
|
+
const accountModelForHarness =
|
|
383
|
+
harness === "cursor" ? accountDefaults?.cursorModel : accountDefaults?.nativeModel;
|
|
384
|
+
const accountModelId =
|
|
385
|
+
accountModelForHarness && getModel(accountModelForHarness)
|
|
386
|
+
? accountModelForHarness
|
|
387
|
+
: undefined;
|
|
388
|
+
|
|
389
|
+
// Layered precedence: explicit device pick > account default. The result
|
|
390
|
+
// feeds the composer's model pill AND the submit path, so the pill always
|
|
391
|
+
// shows what an untouched send will run (#663).
|
|
392
|
+
const effectiveModelId = validModelId ?? accountModelId;
|
|
393
|
+
|
|
329
394
|
const setHarness = useCallback(
|
|
330
395
|
(h: HarnessOption) => {
|
|
396
|
+
harnessTouchedRef.current = true;
|
|
331
397
|
setHarnessRaw(h);
|
|
332
398
|
// Guests have no harness picker; if a caller invokes this anyway, the
|
|
333
399
|
// guest surface must never write into the Console's preference keys.
|
|
@@ -415,14 +481,20 @@ export function useNewSessionFlow(
|
|
|
415
481
|
// The owner pin wins over the composer and the restored
|
|
416
482
|
// preference (#664); the pinned tier is stamped only as
|
|
417
483
|
// "fast" — standard stays off the wire, preserving the #357
|
|
418
|
-
// UNSPECIFIED-vs-explicit telemetry distinction.
|
|
419
|
-
|
|
484
|
+
// UNSPECIFIED-vs-explicit telemetry distinction. The effective
|
|
485
|
+
// model carries the account-default seed explicitly (DD-003:
|
|
486
|
+
// the preference is a seed; the execution spec is the record).
|
|
487
|
+
modelName: pinnedModelName ?? selectedModel ?? effectiveModelId,
|
|
420
488
|
runtimeEnv,
|
|
421
489
|
attachments: context?.attachments,
|
|
422
490
|
interactionMode: context?.interactionMode,
|
|
423
491
|
serviceTier: pinnedModelName
|
|
424
492
|
? (pinnedServiceTier === "fast" ? "fast" : undefined)
|
|
425
493
|
: context?.serviceTier,
|
|
494
|
+
// The tier's #772 twin, same pin-wins + only-explicit-enabled rule.
|
|
495
|
+
thinkingMode: pinnedModelName
|
|
496
|
+
? (pinnedThinkingMode === "enabled" ? "enabled" : undefined)
|
|
497
|
+
: context?.thinkingMode,
|
|
426
498
|
workspaceFileRefs: context?.workspaceFileRefs,
|
|
427
499
|
autoApproveAll,
|
|
428
500
|
};
|
|
@@ -514,9 +586,10 @@ export function useNewSessionFlow(
|
|
|
514
586
|
autoApproveAll,
|
|
515
587
|
adapter,
|
|
516
588
|
getRuntimeEnv,
|
|
517
|
-
|
|
589
|
+
effectiveModelId,
|
|
518
590
|
pinnedModelName,
|
|
519
591
|
pinnedServiceTier,
|
|
592
|
+
pinnedThinkingMode,
|
|
520
593
|
workspace,
|
|
521
594
|
mcpServerUsages,
|
|
522
595
|
skillRefs,
|
|
@@ -539,7 +612,7 @@ export function useNewSessionFlow(
|
|
|
539
612
|
return {
|
|
540
613
|
harness,
|
|
541
614
|
setHarness,
|
|
542
|
-
modelId:
|
|
615
|
+
modelId: effectiveModelId,
|
|
543
616
|
setModelId,
|
|
544
617
|
agentRef,
|
|
545
618
|
setAgentRef,
|