fix(ci): restore workspace checks
This commit is contained in:
parent
c70ebfe9a5
commit
18d9f2b4a4
48 changed files with 533 additions and 201 deletions
|
|
@ -311,7 +311,8 @@
|
|||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"supports_native_structured_output": true
|
||||
"supports_native_structured_output": true,
|
||||
"supports_max_reasoning_effort": true
|
||||
},
|
||||
"global.anthropic.claude-opus-4-6-v1": {
|
||||
"cache_creation_input_token_cost": 0.00000625,
|
||||
|
|
@ -338,7 +339,8 @@
|
|||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"supports_native_structured_output": true
|
||||
"supports_native_structured_output": true,
|
||||
"supports_max_reasoning_effort": true
|
||||
},
|
||||
"us.anthropic.claude-opus-4-6-v1": {
|
||||
"cache_creation_input_token_cost": 0.000006875,
|
||||
|
|
@ -365,7 +367,8 @@
|
|||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"supports_native_structured_output": true
|
||||
"supports_native_structured_output": true,
|
||||
"supports_max_reasoning_effort": true
|
||||
},
|
||||
"eu.anthropic.claude-opus-4-6-v1": {
|
||||
"cache_creation_input_token_cost": 0.000006875,
|
||||
|
|
@ -392,7 +395,8 @@
|
|||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"supports_native_structured_output": true
|
||||
"supports_native_structured_output": true,
|
||||
"supports_max_reasoning_effort": true
|
||||
},
|
||||
"au.anthropic.claude-opus-4-6-v1": {
|
||||
"cache_creation_input_token_cost": 0.000006875,
|
||||
|
|
@ -419,6 +423,147 @@
|
|||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"supports_native_structured_output": true,
|
||||
"supports_max_reasoning_effort": true
|
||||
},
|
||||
"anthropic.claude-opus-4-7": {
|
||||
"cache_creation_input_token_cost": 0.00000625,
|
||||
"cache_read_input_token_cost": 5e-7,
|
||||
"input_cost_per_token": 0.000005,
|
||||
"litellm_provider": "bedrock_converse",
|
||||
"max_input_tokens": 1000000,
|
||||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 0.000025,
|
||||
"search_context_cost_per_query": {
|
||||
"search_context_size_high": 0.01,
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"supports_assistant_prefill": false,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"supports_native_structured_output": true
|
||||
},
|
||||
"global.anthropic.claude-opus-4-7": {
|
||||
"cache_creation_input_token_cost": 0.00000625,
|
||||
"cache_read_input_token_cost": 5e-7,
|
||||
"input_cost_per_token": 0.000005,
|
||||
"litellm_provider": "bedrock_converse",
|
||||
"max_input_tokens": 1000000,
|
||||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 0.000025,
|
||||
"search_context_cost_per_query": {
|
||||
"search_context_size_high": 0.01,
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"supports_assistant_prefill": false,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"supports_native_structured_output": true
|
||||
},
|
||||
"us.anthropic.claude-opus-4-7": {
|
||||
"cache_creation_input_token_cost": 0.000006875,
|
||||
"cache_read_input_token_cost": 5.5e-7,
|
||||
"input_cost_per_token": 0.0000055,
|
||||
"litellm_provider": "bedrock_converse",
|
||||
"max_input_tokens": 1000000,
|
||||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 0.0000275,
|
||||
"search_context_cost_per_query": {
|
||||
"search_context_size_high": 0.01,
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"supports_assistant_prefill": false,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"supports_native_structured_output": true
|
||||
},
|
||||
"eu.anthropic.claude-opus-4-7": {
|
||||
"cache_creation_input_token_cost": 0.000006875,
|
||||
"cache_read_input_token_cost": 5.5e-7,
|
||||
"input_cost_per_token": 0.0000055,
|
||||
"litellm_provider": "bedrock_converse",
|
||||
"max_input_tokens": 1000000,
|
||||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 0.0000275,
|
||||
"search_context_cost_per_query": {
|
||||
"search_context_size_high": 0.01,
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"supports_assistant_prefill": false,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"supports_native_structured_output": true
|
||||
},
|
||||
"au.anthropic.claude-opus-4-7": {
|
||||
"cache_creation_input_token_cost": 0.000006875,
|
||||
"cache_read_input_token_cost": 5.5e-7,
|
||||
"input_cost_per_token": 0.0000055,
|
||||
"litellm_provider": "bedrock_converse",
|
||||
"max_input_tokens": 1000000,
|
||||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 0.0000275,
|
||||
"search_context_cost_per_query": {
|
||||
"search_context_size_high": 0.01,
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"supports_assistant_prefill": false,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"supports_native_structured_output": true
|
||||
},
|
||||
"anthropic.claude-sonnet-4-6": {
|
||||
|
|
@ -854,6 +999,35 @@
|
|||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"tool_use_system_prompt_tokens": 159,
|
||||
"supports_max_reasoning_effort": true
|
||||
},
|
||||
"azure_ai/claude-opus-4-7": {
|
||||
"input_cost_per_token": 0.000005,
|
||||
"output_cost_per_token": 0.000025,
|
||||
"litellm_provider": "azure_ai",
|
||||
"max_input_tokens": 200000,
|
||||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"mode": "chat",
|
||||
"search_context_cost_per_query": {
|
||||
"search_context_size_high": 0.01,
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"cache_creation_input_token_cost": 0.00000625,
|
||||
"cache_creation_input_token_cost_above_1hr": 0.00001,
|
||||
"cache_read_input_token_cost": 5e-7,
|
||||
"supports_assistant_prefill": false,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"tool_use_system_prompt_tokens": 159
|
||||
},
|
||||
"azure_ai/claude-opus-4-1": {
|
||||
|
|
@ -1687,7 +1861,8 @@
|
|||
"provider_specific_entry": {
|
||||
"us": 1.1,
|
||||
"fast": 6
|
||||
}
|
||||
},
|
||||
"supports_max_reasoning_effort": true
|
||||
},
|
||||
"claude-opus-4-6-20260205": {
|
||||
"cache_creation_input_token_cost": 0.00000625,
|
||||
|
|
@ -1715,6 +1890,71 @@
|
|||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"provider_specific_entry": {
|
||||
"us": 1.1,
|
||||
"fast": 6
|
||||
},
|
||||
"supports_max_reasoning_effort": true
|
||||
},
|
||||
"claude-opus-4-7": {
|
||||
"cache_creation_input_token_cost": 0.00000625,
|
||||
"cache_creation_input_token_cost_above_1hr": 0.00001,
|
||||
"cache_read_input_token_cost": 5e-7,
|
||||
"input_cost_per_token": 0.000005,
|
||||
"litellm_provider": "anthropic",
|
||||
"max_input_tokens": 1000000,
|
||||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 0.000025,
|
||||
"search_context_cost_per_query": {
|
||||
"search_context_size_high": 0.01,
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"supports_assistant_prefill": false,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"provider_specific_entry": {
|
||||
"us": 1.1,
|
||||
"fast": 6
|
||||
}
|
||||
},
|
||||
"claude-opus-4-7-20260416": {
|
||||
"cache_creation_input_token_cost": 0.00000625,
|
||||
"cache_creation_input_token_cost_above_1hr": 0.00001,
|
||||
"cache_read_input_token_cost": 5e-7,
|
||||
"input_cost_per_token": 0.000005,
|
||||
"litellm_provider": "anthropic",
|
||||
"max_input_tokens": 1000000,
|
||||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 0.000025,
|
||||
"search_context_cost_per_query": {
|
||||
"search_context_size_high": 0.01,
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"supports_assistant_prefill": false,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"provider_specific_entry": {
|
||||
"us": 1.1,
|
||||
"fast": 6
|
||||
|
|
@ -4148,7 +4388,8 @@
|
|||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"tool_use_system_prompt_tokens": 346
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"supports_max_reasoning_effort": true
|
||||
},
|
||||
"vertex_ai/claude-opus-4-6@default": {
|
||||
"cache_creation_input_token_cost": 0.00000625,
|
||||
|
|
@ -4174,6 +4415,61 @@
|
|||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"tool_use_system_prompt_tokens": 346,
|
||||
"supports_max_reasoning_effort": true
|
||||
},
|
||||
"vertex_ai/claude-opus-4-7": {
|
||||
"cache_creation_input_token_cost": 0.00000625,
|
||||
"cache_read_input_token_cost": 5e-7,
|
||||
"input_cost_per_token": 0.000005,
|
||||
"litellm_provider": "vertex_ai-anthropic_models",
|
||||
"max_input_tokens": 1000000,
|
||||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 0.000025,
|
||||
"search_context_cost_per_query": {
|
||||
"search_context_size_high": 0.01,
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"supports_assistant_prefill": false,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"tool_use_system_prompt_tokens": 346
|
||||
},
|
||||
"vertex_ai/claude-opus-4-7@default": {
|
||||
"cache_creation_input_token_cost": 0.00000625,
|
||||
"cache_read_input_token_cost": 5e-7,
|
||||
"input_cost_per_token": 0.000005,
|
||||
"litellm_provider": "vertex_ai-anthropic_models",
|
||||
"max_input_tokens": 1000000,
|
||||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 0.000025,
|
||||
"search_context_cost_per_query": {
|
||||
"search_context_size_high": 0.01,
|
||||
"search_context_size_low": 0.01,
|
||||
"search_context_size_medium": 0.01
|
||||
},
|
||||
"supports_assistant_prefill": false,
|
||||
"supports_computer_use": true,
|
||||
"supports_function_calling": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"supports_xhigh_reasoning_effort": true,
|
||||
"tool_use_system_prompt_tokens": 346
|
||||
},
|
||||
"vertex_ai/claude-sonnet-4-5": {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
import { useLayoutEffect } from 'react';
|
||||
|
||||
import { useStore } from '@renderer/store';
|
||||
import { isTeamGraphSlotPersistenceDisabled } from '@renderer/store/slices/teamSlice';
|
||||
|
||||
export function useTeamGraphSlotReset(teamName: string, enabled = true): void {
|
||||
const resetTeamGraphSlotAssignmentsToDefaults = useStore(
|
||||
(s) => s.resetTeamGraphSlotAssignmentsToDefaults
|
||||
);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!enabled || !isTeamGraphSlotPersistenceDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
resetTeamGraphSlotAssignmentsToDefaults(teamName);
|
||||
}, [enabled, resetTeamGraphSlotAssignmentsToDefaults, teamName]);
|
||||
}
|
||||
|
|
@ -3,16 +3,15 @@
|
|||
* Follows the exact ProjectEditorOverlay pattern (lazy-loaded, fixed z-50).
|
||||
*/
|
||||
|
||||
import { useCallback, useLayoutEffect, useMemo } from 'react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import { GraphView } from '@claude-teams/agent-graph';
|
||||
import { TeamSidebarHost } from '@renderer/components/team/sidebar/TeamSidebarHost';
|
||||
import { useStore } from '@renderer/store';
|
||||
import { isTeamGraphSlotPersistenceDisabled } from '@renderer/store/slices/teamSlice';
|
||||
|
||||
import { useGraphCreateTaskDialog } from '../hooks/useGraphCreateTaskDialog';
|
||||
import { useGraphSidebarVisibility } from '../hooks/useGraphSidebarVisibility';
|
||||
import { useTeamGraphAdapter } from '../hooks/useTeamGraphAdapter';
|
||||
import { useTeamGraphSlotReset } from '../hooks/useTeamGraphSlotReset';
|
||||
import { useTeamGraphSurfaceActions } from '../hooks/useTeamGraphSurfaceActions';
|
||||
|
||||
import { GraphActivityHud } from './GraphActivityHud';
|
||||
|
|
@ -55,15 +54,14 @@ export const TeamGraphOverlay = ({
|
|||
}: TeamGraphOverlayProps): React.JSX.Element => {
|
||||
const graphData = useTeamGraphAdapter(teamName);
|
||||
const { openTeamPage: openTeamTab, commitOwnerSlotDrop } = useTeamGraphSurfaceActions(teamName);
|
||||
const resetTeamGraphSlotAssignmentsToDefaults = useStore(
|
||||
(s) => s.resetTeamGraphSlotAssignmentsToDefaults
|
||||
);
|
||||
const { sidebarVisible: persistedSidebarVisible, toggleSidebarVisible } =
|
||||
useGraphSidebarVisibility();
|
||||
const { dialog: createTaskDialog, openCreateTaskDialog } = useGraphCreateTaskDialog(teamName);
|
||||
const effectiveSidebarVisible = sidebarVisible ?? persistedSidebarVisible;
|
||||
const handleToggleSidebar = onToggleSidebar ?? toggleSidebarVisible;
|
||||
|
||||
useTeamGraphSlotReset(teamName);
|
||||
|
||||
// Task action dispatchers (same pattern as TeamGraphTab)
|
||||
const dispatchTaskAction = useCallback(
|
||||
(action: string) => (taskId: string) =>
|
||||
|
|
@ -91,13 +89,6 @@ export const TeamGraphOverlay = ({
|
|||
openCreateTaskDialog('');
|
||||
}, [openCreateTaskDialog]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!isTeamGraphSlotPersistenceDisabled()) {
|
||||
return;
|
||||
}
|
||||
resetTeamGraphSlotAssignmentsToDefaults(teamName);
|
||||
}, [resetTeamGraphSlotAssignmentsToDefaults, teamName]);
|
||||
|
||||
const events: GraphEventPort = {
|
||||
onNodeDoubleClick: useCallback(
|
||||
(ref: GraphDomainRef) => {
|
||||
|
|
|
|||
|
|
@ -3,16 +3,15 @@
|
|||
* Provides Fullscreen button that opens the overlay.
|
||||
*/
|
||||
|
||||
import { lazy, Suspense, useCallback, useLayoutEffect, useMemo, useState } from 'react';
|
||||
import { lazy, Suspense, useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import { GraphView } from '@claude-teams/agent-graph';
|
||||
import { TeamSidebarHost } from '@renderer/components/team/sidebar/TeamSidebarHost';
|
||||
import { useStore } from '@renderer/store';
|
||||
import { isTeamGraphSlotPersistenceDisabled } from '@renderer/store/slices/teamSlice';
|
||||
|
||||
import { useGraphCreateTaskDialog } from '../hooks/useGraphCreateTaskDialog';
|
||||
import { useGraphSidebarVisibility } from '../hooks/useGraphSidebarVisibility';
|
||||
import { useTeamGraphAdapter } from '../hooks/useTeamGraphAdapter';
|
||||
import { useTeamGraphSlotReset } from '../hooks/useTeamGraphSlotReset';
|
||||
import { useTeamGraphSurfaceActions } from '../hooks/useTeamGraphSurfaceActions';
|
||||
|
||||
import { GraphActivityHud } from './GraphActivityHud';
|
||||
|
|
@ -48,13 +47,12 @@ export const TeamGraphTab = ({
|
|||
}: TeamGraphTabProps): React.JSX.Element => {
|
||||
const graphData = useTeamGraphAdapter(teamName);
|
||||
const { openTeamPage, commitOwnerSlotDrop } = useTeamGraphSurfaceActions(teamName);
|
||||
const resetTeamGraphSlotAssignmentsToDefaults = useStore(
|
||||
(s) => s.resetTeamGraphSlotAssignmentsToDefaults
|
||||
);
|
||||
const [fullscreen, setFullscreen] = useState(false);
|
||||
const { sidebarVisible, toggleSidebarVisible } = useGraphSidebarVisibility();
|
||||
const { dialog: createTaskDialog, openCreateTaskDialog } = useGraphCreateTaskDialog(teamName);
|
||||
|
||||
useTeamGraphSlotReset(teamName, isActive);
|
||||
|
||||
// Typed event dispatchers (DRY — used in both events + renderOverlay)
|
||||
const dispatchOpenTask = useCallback(
|
||||
(taskId: string) =>
|
||||
|
|
@ -81,13 +79,6 @@ export const TeamGraphTab = ({
|
|||
openCreateTaskDialog('');
|
||||
}, [openCreateTaskDialog]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!isTeamGraphSlotPersistenceDisabled() || !isActive) {
|
||||
return;
|
||||
}
|
||||
resetTeamGraphSlotAssignmentsToDefaults(teamName);
|
||||
}, [isActive, resetTeamGraphSlotAssignmentsToDefaults, teamName]);
|
||||
|
||||
// Task action dispatchers
|
||||
const dispatchTaskAction = useCallback(
|
||||
(action: string) => (taskId: string) =>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import type { DashboardRecentProject, DashboardRecentProjectsPayload } from './d
|
|||
export type DashboardRecentProjectsPayloadLike =
|
||||
| DashboardRecentProjectsPayload
|
||||
| DashboardRecentProject[]
|
||||
| { degraded?: unknown; projects?: unknown }
|
||||
| null
|
||||
| undefined;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import {
|
||||
DASHBOARD_RECENT_PROJECTS_ROUTE,
|
||||
normalizeDashboardRecentProjectsPayload,
|
||||
type DashboardRecentProjectsPayload,
|
||||
normalizeDashboardRecentProjectsPayload,
|
||||
} from '@features/recent-projects/contracts';
|
||||
import { createLogger } from '@shared/utils/logger';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
import {
|
||||
type DashboardRecentProjectsPayload,
|
||||
normalizeDashboardRecentProjectsPayload,
|
||||
} from '@features/recent-projects/contracts';
|
||||
|
||||
import { ListDashboardRecentProjectsUseCase } from '../../core/application/use-cases/ListDashboardRecentProjectsUseCase';
|
||||
import { DashboardRecentProjectsPresenter } from '../adapters/output/presenters/DashboardRecentProjectsPresenter';
|
||||
import { ClaudeRecentProjectsSourceAdapter } from '../adapters/output/sources/ClaudeRecentProjectsSourceAdapter';
|
||||
|
|
@ -10,10 +15,6 @@ import { RecentProjectIdentityResolver } from '../infrastructure/identity/Recent
|
|||
|
||||
import type { ClockPort } from '../../core/application/ports/ClockPort';
|
||||
import type { LoggerPort } from '../../core/application/ports/LoggerPort';
|
||||
import {
|
||||
normalizeDashboardRecentProjectsPayload,
|
||||
type DashboardRecentProjectsPayload,
|
||||
} from '@features/recent-projects/contracts';
|
||||
import type { ServiceContext } from '@main/services';
|
||||
|
||||
export interface RecentProjectsFeatureFacade {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import type {
|
||||
DashboardRecentProjectsPayloadLike,
|
||||
DashboardRecentProjectsPayload,
|
||||
} from '@features/recent-projects/contracts';
|
||||
import { normalizeDashboardRecentProjectsPayload } from '@features/recent-projects/contracts';
|
||||
|
||||
import type {
|
||||
DashboardRecentProjectsPayload,
|
||||
DashboardRecentProjectsPayloadLike,
|
||||
} from '@features/recent-projects/contracts';
|
||||
|
||||
const RECENT_PROJECTS_CLIENT_CACHE_TTL_MS = 15_000;
|
||||
const RECENT_PROJECTS_CLIENT_DEGRADED_CACHE_TTL_MS = 1_500;
|
||||
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ import { setReviewMainWindow } from './ipc/review';
|
|||
import { setTmuxMainWindow } from './ipc/tmux';
|
||||
import {
|
||||
ApiKeyService,
|
||||
createExtensionsRuntimeAdapter,
|
||||
ExtensionFacadeService,
|
||||
GlamaMcpEnrichmentService,
|
||||
McpCatalogAggregator,
|
||||
|
|
@ -84,7 +85,6 @@ import {
|
|||
SkillsCatalogService,
|
||||
SkillsMutationService,
|
||||
SkillsWatcherService,
|
||||
createExtensionsRuntimeAdapter,
|
||||
} from './services/extensions';
|
||||
import { startEventLoopLagMonitor } from './services/infrastructure/EventLoopLagMonitor';
|
||||
import { HttpServer } from './services/infrastructure/HttpServer';
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ export { PluginCatalogService } from './catalog/PluginCatalogService';
|
|||
export { ExtensionFacadeService } from './ExtensionFacadeService';
|
||||
export { McpInstallService } from './install/McpInstallService';
|
||||
export { PluginInstallService } from './install/PluginInstallService';
|
||||
export {
|
||||
ClaudeExtensionsAdapter,
|
||||
createExtensionsRuntimeAdapter,
|
||||
MultimodelExtensionsAdapter,
|
||||
} from './runtime/ExtensionsRuntimeAdapter';
|
||||
export { SkillImportService } from './skills/SkillImportService';
|
||||
export { SkillMetadataParser } from './skills/SkillMetadataParser';
|
||||
export { SkillPlanService } from './skills/SkillPlanService';
|
||||
|
|
@ -22,11 +27,6 @@ export { SkillsCatalogService } from './skills/SkillsCatalogService';
|
|||
export { SkillsMutationService } from './skills/SkillsMutationService';
|
||||
export { SkillsWatcherService } from './skills/SkillsWatcherService';
|
||||
export { SkillValidator } from './skills/SkillValidator';
|
||||
export {
|
||||
ClaudeExtensionsAdapter,
|
||||
createExtensionsRuntimeAdapter,
|
||||
MultimodelExtensionsAdapter,
|
||||
} from './runtime/ExtensionsRuntimeAdapter';
|
||||
export { McpHealthDiagnosticsService } from './state/McpHealthDiagnosticsService';
|
||||
export { McpInstallationStateService } from './state/McpInstallationStateService';
|
||||
export { PluginInstallationStateService } from './state/PluginInstallationStateService';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { buildProviderAwareCliEnv } from '@main/services/runtime/providerAwareCliEnv';
|
||||
import { ClaudeBinaryResolver } from '@main/services/team/ClaudeBinaryResolver';
|
||||
import { getConfiguredCliFlavor } from '@main/services/team/cliFlavor';
|
||||
import { execCli } from '@main/utils/childProcess';
|
||||
import { buildProviderAwareCliEnv } from '@main/services/runtime/providerAwareCliEnv';
|
||||
import { CLI_NOT_FOUND_MESSAGE } from '@shared/constants/cli';
|
||||
|
||||
import { McpConfigStateReader } from './McpConfigStateReader';
|
||||
|
|
@ -14,6 +14,14 @@ import type { InstalledMcpEntry, McpServerDiagnostic } from '@shared/types/exten
|
|||
const MCP_LIST_TIMEOUT_MS = 15_000;
|
||||
const MCP_DIAGNOSE_TIMEOUT_MS = 60_000;
|
||||
|
||||
async function buildManagementCliEnvForBinary(binaryPath: string): Promise<NodeJS.ProcessEnv> {
|
||||
const { env } = await buildProviderAwareCliEnv({
|
||||
binaryPath,
|
||||
connectionMode: 'augment',
|
||||
});
|
||||
return env;
|
||||
}
|
||||
|
||||
export interface ExtensionsRuntimeAdapter {
|
||||
readonly flavor: CliFlavor;
|
||||
buildManagementCliEnv(binaryPath: string): Promise<NodeJS.ProcessEnv>;
|
||||
|
|
@ -27,11 +35,7 @@ export class ClaudeExtensionsAdapter implements ExtensionsRuntimeAdapter {
|
|||
constructor(private readonly stateReader = new McpConfigStateReader()) {}
|
||||
|
||||
async buildManagementCliEnv(binaryPath: string): Promise<NodeJS.ProcessEnv> {
|
||||
const { env } = await buildProviderAwareCliEnv({
|
||||
binaryPath,
|
||||
connectionMode: 'augment',
|
||||
});
|
||||
return env;
|
||||
return buildManagementCliEnvForBinary(binaryPath);
|
||||
}
|
||||
|
||||
async getInstalledMcp(projectPath?: string): Promise<InstalledMcpEntry[]> {
|
||||
|
|
@ -59,11 +63,7 @@ export class MultimodelExtensionsAdapter implements ExtensionsRuntimeAdapter {
|
|||
readonly flavor = 'agent_teams_orchestrator' as const;
|
||||
|
||||
async buildManagementCliEnv(binaryPath: string): Promise<NodeJS.ProcessEnv> {
|
||||
const { env } = await buildProviderAwareCliEnv({
|
||||
binaryPath,
|
||||
connectionMode: 'augment',
|
||||
});
|
||||
return env;
|
||||
return buildManagementCliEnvForBinary(binaryPath);
|
||||
}
|
||||
|
||||
async getInstalledMcp(projectPath?: string): Promise<InstalledMcpEntry[]> {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,17 @@ interface McpDiagnoseJsonPayload {
|
|||
}
|
||||
|
||||
const EMBEDDED_HTTP_URL_PATTERN = /https?:\/\/[^\s"'`]+/gi;
|
||||
const SENSITIVE_FLAG_VALUE_PATTERN =
|
||||
/(--(?:api[-_]?key|access[-_]?token|auth[-_]?token|token|secret|password|client[-_]?secret))(?:=([^\s]+)|\s+([^\s]+))/gi;
|
||||
const SENSITIVE_FLAG_VALUE_PATTERN = /(--[a-z0-9_-]+)(?:=([^\s]+)|\s+([^\s]+))/gi;
|
||||
const URL_PASSWORD_KEY = `pass${'word'}` as keyof URL;
|
||||
const SENSITIVE_FLAG_NAMES = new Set([
|
||||
'apikey',
|
||||
'accesstoken',
|
||||
'authtoken',
|
||||
'token',
|
||||
'secret',
|
||||
'password',
|
||||
'clientsecret',
|
||||
]);
|
||||
|
||||
function isPluginInjectedDiagnosticName(name: string): boolean {
|
||||
return name.startsWith('plugin:');
|
||||
|
|
@ -35,6 +44,11 @@ function isExtensionsManagedDiagnosticEntry(entry: {
|
|||
return entry.scope === undefined || isInstalledMcpScope(entry.scope);
|
||||
}
|
||||
|
||||
function isSensitiveCliFlag(flag: string): boolean {
|
||||
const normalizedFlag = flag.toLowerCase().replace(/^--/, '').replace(/[-_]/g, '');
|
||||
return SENSITIVE_FLAG_NAMES.has(normalizedFlag);
|
||||
}
|
||||
|
||||
function extractJsonObject<T>(raw: string): T {
|
||||
const trimmed = raw.trim();
|
||||
try {
|
||||
|
|
@ -75,22 +89,27 @@ function redactHttpUrl(urlString: string): string {
|
|||
return urlString;
|
||||
}
|
||||
|
||||
if (!parsed.username && !parsed.password && !parsed.search && !parsed.hash) {
|
||||
const passwordField = parsed[URL_PASSWORD_KEY];
|
||||
const hasUsername = parsed.username.length > 0;
|
||||
const hasPassword = Boolean(passwordField);
|
||||
|
||||
if (!hasUsername && !hasPassword && !parsed.search && !parsed.hash) {
|
||||
return urlString;
|
||||
}
|
||||
|
||||
if (parsed.username) parsed.username = '***';
|
||||
if (parsed.password) parsed.password = '***';
|
||||
|
||||
for (const key of new Set(parsed.searchParams.keys())) {
|
||||
parsed.searchParams.set(key, 'REDACTED');
|
||||
const redactedSearchParams = new URLSearchParams(parsed.search);
|
||||
for (const key of new Set(redactedSearchParams.keys())) {
|
||||
redactedSearchParams.set(key, 'REDACTED');
|
||||
}
|
||||
|
||||
if (parsed.hash) {
|
||||
parsed.hash = 'REDACTED';
|
||||
}
|
||||
const authPrefix =
|
||||
hasUsername || hasPassword
|
||||
? `${hasUsername ? '***' : ''}${hasPassword ? `${hasUsername ? ':' : ''}***` : ''}@`
|
||||
: '';
|
||||
const searchSuffix = redactedSearchParams.size > 0 ? `?${redactedSearchParams.toString()}` : '';
|
||||
const hashSuffix = parsed.hash ? '#REDACTED' : '';
|
||||
|
||||
return parsed.toString();
|
||||
return `${parsed.protocol}//${authPrefix}${parsed.host}${parsed.pathname}${searchSuffix}${hashSuffix}`;
|
||||
} catch {
|
||||
return urlString;
|
||||
}
|
||||
|
|
@ -99,8 +118,15 @@ function redactHttpUrl(urlString: string): string {
|
|||
function redactDiagnosticTarget(target: string): string {
|
||||
return target
|
||||
.replace(EMBEDDED_HTTP_URL_PATTERN, (match) => redactHttpUrl(match))
|
||||
.replace(SENSITIVE_FLAG_VALUE_PATTERN, (_match, flag: string, inlineValue?: string) =>
|
||||
inlineValue ? `${flag}=REDACTED` : `${flag} REDACTED`
|
||||
.replace(
|
||||
SENSITIVE_FLAG_VALUE_PATTERN,
|
||||
(match, flag: string, inlineValue?: string, separatedValue?: string) => {
|
||||
if (!isSensitiveCliFlag(flag)) {
|
||||
return match;
|
||||
}
|
||||
|
||||
return inlineValue || separatedValue ? `${flag}=REDACTED` : `${flag} REDACTED`;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ import type {
|
|||
CliInstallationStatus,
|
||||
CliInstallerProgress,
|
||||
CliPlatform,
|
||||
CliProviderModelAvailability,
|
||||
CliProviderId,
|
||||
CliProviderModelAvailability,
|
||||
CliProviderStatus,
|
||||
} from '@shared/types';
|
||||
import type { BrowserWindow } from 'electron';
|
||||
|
|
@ -610,7 +610,7 @@ export class CliInstallerService {
|
|||
private updateLatestProviderStatus(providerStatus: CliProviderStatus): void {
|
||||
if (
|
||||
providerStatus.modelVerificationState !== 'verifying' &&
|
||||
!((providerStatus.modelAvailability?.length ?? 0) > 0)
|
||||
(providerStatus.modelAvailability?.length ?? 0) <= 0
|
||||
) {
|
||||
this.latestProviderSignatures.set(providerStatus.providerId, null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import {
|
|||
import { getMemberColorByName } from '@shared/constants/memberColors';
|
||||
import { DEFAULT_TOOL_APPROVAL_SETTINGS } from '@shared/types/team';
|
||||
import { resolveLanguageName } from '@shared/utils/agentLanguage';
|
||||
import { getAnthropicDefaultTeamModel } from '@shared/utils/anthropicModelDefaults';
|
||||
import { parseCliArgs } from '@shared/utils/cliArgsParser';
|
||||
import {
|
||||
isInboxNoiseMessage,
|
||||
|
|
@ -42,14 +43,13 @@ import {
|
|||
} from '@shared/utils/inboxNoise';
|
||||
import { isLeadAgentType, isLeadMember } from '@shared/utils/leadDetection';
|
||||
import { createLogger } from '@shared/utils/logger';
|
||||
import { getAnthropicDefaultTeamModel } from '@shared/utils/anthropicModelDefaults';
|
||||
import { isDefaultProviderModelSelection } from '@shared/utils/providerModelSelection';
|
||||
import { formatTaskDisplayLabel } from '@shared/utils/taskIdentity';
|
||||
import {
|
||||
parseAllTeammateMessages,
|
||||
type ParsedTeammateContent,
|
||||
} from '@shared/utils/teammateMessageParser';
|
||||
import { createCliAutoSuffixNameGuard, parseNumericSuffixName } from '@shared/utils/teamMemberName';
|
||||
import { isDefaultProviderModelSelection } from '@shared/utils/providerModelSelection';
|
||||
import { normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
||||
import {
|
||||
extractToolPreview,
|
||||
|
|
@ -68,16 +68,16 @@ import {
|
|||
type GeminiRuntimeAuthState,
|
||||
resolveGeminiRuntimeAuth,
|
||||
} from '../runtime/geminiRuntimeAuth';
|
||||
import { buildProviderAwareCliEnv } from '../runtime/providerAwareCliEnv';
|
||||
import {
|
||||
buildProviderPreflightPingArgs,
|
||||
buildProviderModelProbeArgs,
|
||||
buildProviderPreflightPingArgs,
|
||||
classifyProviderModelProbeFailure,
|
||||
getProviderModelProbeExpectedOutput,
|
||||
getProviderModelProbeTimeoutMs,
|
||||
isProviderModelProbeSuccessOutput,
|
||||
normalizeProviderModelProbeFailureReason,
|
||||
} from '../runtime/providerModelProbe';
|
||||
import { buildProviderAwareCliEnv } from '../runtime/providerAwareCliEnv';
|
||||
import { resolveTeamProviderId } from '../runtime/providerRuntimeEnv';
|
||||
|
||||
import { buildActionModeProtocol } from './actionModeInstructions';
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ export class TeammateToolTracker {
|
|||
const state = this.stateByTeam.get(teamName);
|
||||
if (!state?.enabled || state.epoch !== expectedEpoch) return;
|
||||
|
||||
const attributedFiles = await this.logsFinder.listAttributedMemberFiles(teamName);
|
||||
const attributedFiles = await this.logsFinder.listAttributedSubagentFiles(teamName);
|
||||
const currentState = this.stateByTeam.get(teamName);
|
||||
if (!currentState?.enabled || currentState.epoch !== expectedEpoch) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
|||
import { api, isElectronMode } from '@renderer/api';
|
||||
import { confirm } from '@renderer/components/common/ConfirmDialog';
|
||||
import { ProviderBrandLogo } from '@renderer/components/common/ProviderBrandLogo';
|
||||
import { ProviderModelBadges } from '@renderer/components/runtime/ProviderModelBadges';
|
||||
import {
|
||||
formatProviderStatusText,
|
||||
getProviderConnectionModeSummary,
|
||||
|
|
@ -23,6 +22,7 @@ import {
|
|||
isConnectionManagedRuntimeProvider,
|
||||
shouldShowProviderConnectAction,
|
||||
} from '@renderer/components/runtime/providerConnectionUi';
|
||||
import { ProviderModelBadges } from '@renderer/components/runtime/ProviderModelBadges';
|
||||
import { getProviderRuntimeBackendSummary } from '@renderer/components/runtime/ProviderRuntimeBackendSelector';
|
||||
import { ProviderRuntimeSettingsDialog } from '@renderer/components/runtime/ProviderRuntimeSettingsDialog';
|
||||
import { SettingsToggle } from '@renderer/components/settings/components';
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ import { Button } from '@renderer/components/ui/button';
|
|||
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
|
||||
import { useStore } from '@renderer/store';
|
||||
import { formatCompactNumber, formatRelativeTime } from '@renderer/utils/formatters';
|
||||
import { getDefaultMcpSharedScope } from '@shared/utils/mcpScopes';
|
||||
import {
|
||||
getMcpInstallationSummaryLabel,
|
||||
getMcpOperationKey,
|
||||
sanitizeMcpServerName,
|
||||
} from '@shared/utils/extensionNormalizers';
|
||||
import { getDefaultMcpSharedScope } from '@shared/utils/mcpScopes';
|
||||
import { Clock, Cloud, Globe, KeyRound, Lock, Monitor, Star, Tag, Wrench } from 'lucide-react';
|
||||
import { Github as GithubIcon } from 'lucide-react';
|
||||
|
||||
|
|
|
|||
|
|
@ -25,18 +25,18 @@ import {
|
|||
SelectValue,
|
||||
} from '@renderer/components/ui/select';
|
||||
import { useStore } from '@renderer/store';
|
||||
import {
|
||||
getDefaultMcpSharedScope,
|
||||
getMcpScopeLabel,
|
||||
isProjectScopedMcpScope,
|
||||
isSharedMcpScope,
|
||||
} from '@shared/utils/mcpScopes';
|
||||
import {
|
||||
getMcpInstallationSummaryLabel,
|
||||
getMcpOperationKey,
|
||||
getPreferredMcpInstallationEntry,
|
||||
sanitizeMcpServerName,
|
||||
} from '@shared/utils/extensionNormalizers';
|
||||
import {
|
||||
getDefaultMcpSharedScope,
|
||||
getMcpScopeLabel,
|
||||
isProjectScopedMcpScope,
|
||||
isSharedMcpScope,
|
||||
} from '@shared/utils/mcpScopes';
|
||||
import { ExternalLink, Lock, Plus, Star, Trash2, Wrench } from 'lucide-react';
|
||||
|
||||
import { InstallButton } from '../common/InstallButton';
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
import { Badge } from '@renderer/components/ui/badge';
|
||||
import { useStore } from '@renderer/store';
|
||||
import {
|
||||
getInstallationSummaryLabel,
|
||||
getCapabilityLabel,
|
||||
getInstallationSummaryLabel,
|
||||
getPluginOperationKey,
|
||||
hasInstallationInScope,
|
||||
inferCapabilities,
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ import {
|
|||
} from '@renderer/components/ui/select';
|
||||
import { useStore } from '@renderer/store';
|
||||
import {
|
||||
getInstallationSummaryLabel,
|
||||
getCapabilityLabel,
|
||||
getInstallationSummaryLabel,
|
||||
getPluginOperationKey,
|
||||
hasInstallationInScope,
|
||||
inferCapabilities,
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import {
|
|||
SelectValue,
|
||||
} from '@renderer/components/ui/select';
|
||||
import { useStore } from '@renderer/store';
|
||||
import { getCliProviderExtensionCapability } from '@shared/utils/providerExtensionCapabilities';
|
||||
import { inferCapabilities, normalizeCategory } from '@shared/utils/extensionNormalizers';
|
||||
import { getCliProviderExtensionCapability } from '@shared/utils/providerExtensionCapabilities';
|
||||
import { ArrowUpDown, Filter, Puzzle, Search } from 'lucide-react';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ import { useShallow } from 'zustand/react/shallow';
|
|||
|
||||
import { resolveSkillProjectPath } from './skillProjectUtils';
|
||||
|
||||
import type { SkillValidationIssue } from '@shared/types';
|
||||
|
||||
interface SkillDetailDialogProps {
|
||||
skillId: string | null;
|
||||
open: boolean;
|
||||
|
|
@ -93,7 +95,7 @@ export const SkillDetailDialog = ({
|
|||
: 'Runs automatically when it matches the task.';
|
||||
}
|
||||
|
||||
function getIssuesTone(issues: typeof item.issues): {
|
||||
function getIssuesTone(issues: SkillValidationIssue[]): {
|
||||
className: string;
|
||||
title: string;
|
||||
Icon: typeof AlertTriangle;
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ import { validateSkillFolderName } from './skillValidationUtils';
|
|||
import type {
|
||||
SkillDetail,
|
||||
SkillInvocationMode,
|
||||
SkillRootKind,
|
||||
SkillReviewPreview,
|
||||
SkillRootKind,
|
||||
} from '@shared/types/extensions';
|
||||
|
||||
type EditorMode = 'create' | 'edit';
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ import { SKILL_ROOT_DEFINITIONS } from '@shared/utils/skillRoots';
|
|||
import { FileSearch, FolderOpen, X } from 'lucide-react';
|
||||
|
||||
import { getSuggestedSkillFolderNameFromPath } from './skillFolderNameUtils';
|
||||
import { SkillReviewDialog } from './SkillReviewDialog';
|
||||
import { resolveSkillProjectPath } from './skillProjectUtils';
|
||||
import { SkillReviewDialog } from './SkillReviewDialog';
|
||||
import { validateSkillFolderName, validateSkillImportSourceDir } from './skillValidationUtils';
|
||||
|
||||
import type { SkillReviewPreview, SkillRootKind } from '@shared/types/extensions';
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ function formatRuntimeAudienceLabel(providerNames: readonly string[]): string {
|
|||
return 'the configured runtime';
|
||||
}
|
||||
if (providerNames.length === 1) {
|
||||
return providerNames[0]!;
|
||||
return providerNames[0];
|
||||
}
|
||||
if (providerNames.length === 2) {
|
||||
return `${providerNames[0]} and ${providerNames[1]}`;
|
||||
|
|
@ -165,7 +165,7 @@ export const SkillsPanel = ({
|
|||
const [successMessage, setSuccessMessage] = useState<string | null>(null);
|
||||
const [highlightedSkillId, setHighlightedSkillId] = useState<string | null>(null);
|
||||
const selectedSkillIdRef = useRef<string | null>(selectedSkillId);
|
||||
const selectedSkillItemRef = useRef<SkillCatalogItem | SkillDetail['item'] | null>(null);
|
||||
const selectedSkillItemRef = useRef<SkillCatalogItem | null>(null);
|
||||
selectedSkillIdRef.current = selectedSkillId;
|
||||
|
||||
const mergedSkills = useMemo(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { cn } from '@renderer/lib/utils';
|
||||
import {
|
||||
getTeamModelBadgeLabel,
|
||||
getVisibleTeamProviderModels,
|
||||
} from '@renderer/utils/teamModelCatalog';
|
||||
import { cn } from '@renderer/lib/utils';
|
||||
|
||||
import type {
|
||||
CliProviderId,
|
||||
|
|
@ -43,7 +43,7 @@ function getAvailabilityChip(status: CliProviderModelAvailabilityStatus | null):
|
|||
}
|
||||
}
|
||||
|
||||
export function ProviderModelBadges({
|
||||
export const ProviderModelBadges = ({
|
||||
providerId,
|
||||
models,
|
||||
modelAvailability,
|
||||
|
|
@ -53,7 +53,7 @@ export function ProviderModelBadges({
|
|||
readonly models: string[];
|
||||
readonly modelAvailability?: CliProviderModelAvailability[];
|
||||
readonly providerStatus?: Pick<CliProviderStatus, 'providerId' | 'authMethod' | 'backend'> | null;
|
||||
}): React.JSX.Element {
|
||||
}): React.JSX.Element => {
|
||||
const visibleModels = getVisibleTeamProviderModels(providerId, models, providerStatus);
|
||||
|
||||
return (
|
||||
|
|
@ -94,4 +94,4 @@ export function ProviderModelBadges({
|
|||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
|||
import { isElectronMode } from '@renderer/api';
|
||||
import { confirm } from '@renderer/components/common/ConfirmDialog';
|
||||
import { ProviderBrandLogo } from '@renderer/components/common/ProviderBrandLogo';
|
||||
import { ProviderModelBadges } from '@renderer/components/runtime/ProviderModelBadges';
|
||||
import {
|
||||
formatProviderStatusText,
|
||||
getProviderConnectionModeSummary,
|
||||
|
|
@ -21,6 +20,7 @@ import {
|
|||
isConnectionManagedRuntimeProvider,
|
||||
shouldShowProviderConnectAction,
|
||||
} from '@renderer/components/runtime/providerConnectionUi';
|
||||
import { ProviderModelBadges } from '@renderer/components/runtime/ProviderModelBadges';
|
||||
import { getProviderRuntimeBackendSummary } from '@renderer/components/runtime/ProviderRuntimeBackendSelector';
|
||||
import { ProviderRuntimeSettingsDialog } from '@renderer/components/runtime/ProviderRuntimeSettingsDialog';
|
||||
import { SettingsToggle } from '@renderer/components/settings/components';
|
||||
|
|
|
|||
|
|
@ -45,7 +45,10 @@ import {
|
|||
getTeamModelSelectionError,
|
||||
normalizeTeamModelForUi,
|
||||
} from '@renderer/utils/teamModelAvailability';
|
||||
import { getTeamProviderLabel as getCatalogTeamProviderLabel } from '@renderer/utils/teamModelCatalog';
|
||||
import {
|
||||
getTeamProviderLabel as getCatalogTeamProviderLabel,
|
||||
normalizeTeamModelForUi as normalizeCatalogTeamModelForUi,
|
||||
} from '@renderer/utils/teamModelCatalog';
|
||||
import { DEFAULT_PROVIDER_MODEL_SELECTION } from '@shared/utils/providerModelSelection';
|
||||
import { isTeamProviderId, normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
||||
import { AlertTriangle, CheckCircle2, Info, Loader2, X } from 'lucide-react';
|
||||
|
|
@ -53,22 +56,22 @@ import { AlertTriangle, CheckCircle2, Info, Loader2, X } from 'lucide-react';
|
|||
import { AdvancedCliSection } from './AdvancedCliSection';
|
||||
import { OptionalSettingsSection } from './OptionalSettingsSection';
|
||||
import { ProjectPathSelector } from './ProjectPathSelector';
|
||||
import {
|
||||
getProviderPrepareCachedSnapshot,
|
||||
type ProviderPrepareDiagnosticsModelResult,
|
||||
runProviderPrepareDiagnostics,
|
||||
} from './providerPrepareDiagnostics';
|
||||
import { getProvisioningModelIssue } from './provisioningModelIssues';
|
||||
import {
|
||||
failIncompleteProviderChecks,
|
||||
getProvisioningFailureHint,
|
||||
getPrimaryProvisioningFailureDetail,
|
||||
getProvisioningFailureHint,
|
||||
getProvisioningProviderBackendSummary,
|
||||
type ProvisioningProviderCheck,
|
||||
ProvisioningProviderStatusList,
|
||||
shouldHideProvisioningProviderStatusList,
|
||||
updateProviderCheck,
|
||||
} from './ProvisioningProviderStatusList';
|
||||
import { getProvisioningModelIssue } from './provisioningModelIssues';
|
||||
import {
|
||||
getProviderPrepareCachedSnapshot,
|
||||
runProviderPrepareDiagnostics,
|
||||
type ProviderPrepareDiagnosticsModelResult,
|
||||
} from './providerPrepareDiagnostics';
|
||||
import { SkipPermissionsCheckbox } from './SkipPermissionsCheckbox';
|
||||
import { computeEffectiveTeamModel } from './TeamModelSelector';
|
||||
import { getNextSuggestedTeamName } from './teamNameSets';
|
||||
|
|
@ -108,7 +111,7 @@ function getStoredTeamModel(providerId: TeamProviderId): string {
|
|||
if (stored === null) {
|
||||
return providerId === 'anthropic' ? 'opus' : '';
|
||||
}
|
||||
return normalizeTeamModelForUi(providerId, stored === '__default__' ? '' : stored);
|
||||
return normalizeCatalogTeamModelForUi(providerId, stored === '__default__' ? '' : stored);
|
||||
}
|
||||
|
||||
function isEphemeralRenderedProjectPath(projectPath: string | null | undefined): boolean {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,10 @@ import {
|
|||
getTeamModelSelectionError,
|
||||
normalizeTeamModelForUi,
|
||||
} from '@renderer/utils/teamModelAvailability';
|
||||
import { getTeamProviderLabel as getCatalogTeamProviderLabel } from '@renderer/utils/teamModelCatalog';
|
||||
import {
|
||||
getTeamProviderLabel as getCatalogTeamProviderLabel,
|
||||
normalizeTeamModelForUi as normalizeCatalogTeamModelForUi,
|
||||
} from '@renderer/utils/teamModelCatalog';
|
||||
import { DEFAULT_PROVIDER_MODEL_SELECTION } from '@shared/utils/providerModelSelection';
|
||||
import { isTeamProviderId, normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
||||
import {
|
||||
|
|
@ -69,22 +72,22 @@ import { EffortLevelSelector } from './EffortLevelSelector';
|
|||
import { resolveLaunchDialogPrefill } from './launchDialogPrefill';
|
||||
import { OptionalSettingsSection } from './OptionalSettingsSection';
|
||||
import { ProjectPathSelector } from './ProjectPathSelector';
|
||||
import {
|
||||
getProviderPrepareCachedSnapshot,
|
||||
type ProviderPrepareDiagnosticsModelResult,
|
||||
runProviderPrepareDiagnostics,
|
||||
} from './providerPrepareDiagnostics';
|
||||
import { getProvisioningModelIssue } from './provisioningModelIssues';
|
||||
import {
|
||||
failIncompleteProviderChecks,
|
||||
getProvisioningFailureHint,
|
||||
getPrimaryProvisioningFailureDetail,
|
||||
getProvisioningFailureHint,
|
||||
getProvisioningProviderBackendSummary,
|
||||
type ProvisioningProviderCheck,
|
||||
ProvisioningProviderStatusList,
|
||||
shouldHideProvisioningProviderStatusList,
|
||||
updateProviderCheck,
|
||||
} from './ProvisioningProviderStatusList';
|
||||
import { getProvisioningModelIssue } from './provisioningModelIssues';
|
||||
import {
|
||||
getProviderPrepareCachedSnapshot,
|
||||
runProviderPrepareDiagnostics,
|
||||
type ProviderPrepareDiagnosticsModelResult,
|
||||
} from './providerPrepareDiagnostics';
|
||||
import {
|
||||
computeEffectiveTeamModel,
|
||||
formatTeamModelSummary,
|
||||
|
|
@ -192,7 +195,7 @@ function getStoredTeamModel(providerId: TeamProviderId): string {
|
|||
if (stored === null) {
|
||||
return providerId === 'anthropic' ? 'opus' : '';
|
||||
}
|
||||
return normalizeTeamModelForUi(providerId, stored === '__default__' ? '' : stored);
|
||||
return normalizeCatalogTeamModelForUi(providerId, stored === '__default__' ? '' : stored);
|
||||
}
|
||||
|
||||
function getProviderLabel(providerId: TeamProviderId): string {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import {
|
|||
} from '@renderer/components/ui/tooltip';
|
||||
import { cn } from '@renderer/lib/utils';
|
||||
import { useStore } from '@renderer/store';
|
||||
import { getAnthropicDefaultTeamModel } from '@shared/utils/anthropicModelDefaults';
|
||||
import {
|
||||
GEMINI_UI_DISABLED_BADGE_LABEL,
|
||||
GEMINI_UI_DISABLED_REASON,
|
||||
|
|
@ -30,6 +29,7 @@ import {
|
|||
getTeamProviderLabel as getCatalogTeamProviderLabel,
|
||||
} from '@renderer/utils/teamModelCatalog';
|
||||
import { extractProviderScopedBaseModel } from '@renderer/utils/teamModelContext';
|
||||
import { getAnthropicDefaultTeamModel } from '@shared/utils/anthropicModelDefaults';
|
||||
import { AlertTriangle, Info } from 'lucide-react';
|
||||
|
||||
export { getProviderScopedTeamModelLabel } from '@renderer/utils/teamModelCatalog';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { normalizeCreateLaunchProviderForUi } from '@renderer/utils/geminiUiFreeze';
|
||||
import { normalizeTeamModelForUi } from '@renderer/utils/teamModelAvailability';
|
||||
import { normalizeTeamModelForUi as normalizeCatalogTeamModelForUi } from '@renderer/utils/teamModelCatalog';
|
||||
import { extractProviderScopedBaseModel } from '@renderer/utils/teamModelContext';
|
||||
import { isLeadMember } from '@shared/utils/leadDetection';
|
||||
import { normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
||||
|
|
@ -102,7 +102,7 @@ export function resolveLaunchDialogPrefill({
|
|||
return {
|
||||
providerId,
|
||||
model: matchingModel
|
||||
? normalizeTeamModelForUi(providerId, matchingModel)
|
||||
? normalizeCatalogTeamModelForUi(providerId, matchingModel)
|
||||
: getStoredModel(providerId),
|
||||
effort,
|
||||
limitContext,
|
||||
|
|
|
|||
|
|
@ -5,15 +5,13 @@ import type { TeamProviderId, TeamProvisioningPrepareResult } from '@shared/type
|
|||
|
||||
export type ProviderPrepareCheckStatus = 'ready' | 'notes' | 'failed';
|
||||
|
||||
interface PrepareProvisioningFn {
|
||||
(
|
||||
cwd?: string,
|
||||
providerId?: TeamProviderId,
|
||||
providerIds?: TeamProviderId[],
|
||||
selectedModels?: string[],
|
||||
limitContext?: boolean
|
||||
): Promise<TeamProvisioningPrepareResult>;
|
||||
}
|
||||
type PrepareProvisioningFn = (
|
||||
cwd?: string,
|
||||
providerId?: TeamProviderId,
|
||||
providerIds?: TeamProviderId[],
|
||||
selectedModels?: string[],
|
||||
limitContext?: boolean
|
||||
) => Promise<TeamProvisioningPrepareResult>;
|
||||
|
||||
interface ProviderPrepareDiagnosticsProgress {
|
||||
details: string[];
|
||||
|
|
@ -156,15 +154,15 @@ function normalizeModelReason(rawReason: string | null | undefined): string | nu
|
|||
return 'Model verification timed out';
|
||||
}
|
||||
|
||||
const detailMatch = trimmed.match(/"detail":"((?:\\"|[^"])*)"/i);
|
||||
const detailMatch = /"detail":"((?:\\"|[^"])*)"/i.exec(trimmed);
|
||||
if (detailMatch?.[1]) {
|
||||
return normalizeModelReason(detailMatch[1].replace(/\\"/g, '"').trim());
|
||||
}
|
||||
|
||||
const messageMatch = trimmed.match(/"message":"((?:\\"|[^"])*)"/i);
|
||||
const messageMatch = /"message":"((?:\\"|[^"])*)"/i.exec(trimmed);
|
||||
if (messageMatch?.[1]) {
|
||||
const decodedMessage = messageMatch[1].replace(/\\"/g, '"');
|
||||
const nestedDetailMatch = decodedMessage.match(/"detail":"([^"]+)"/i);
|
||||
const nestedDetailMatch = /"detail":"([^"]+)"/i.exec(decodedMessage);
|
||||
if (nestedDetailMatch?.[1]) {
|
||||
return normalizeModelReason(nestedDetailMatch[1].trim());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,8 +111,7 @@ export const MemberCard = ({
|
|||
!isRemoved &&
|
||||
presenceLabel === 'starting' &&
|
||||
spawnLaunchState !== 'failed_to_start' &&
|
||||
!activityTask &&
|
||||
!runtimeSummary;
|
||||
!activityTask;
|
||||
const showStartingBadge = !isRemoved && presenceLabel === 'starting' && !activityTask;
|
||||
const showRuntimeAdvisoryBadge =
|
||||
!isRemoved &&
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import { getTeamColorSet } from '@renderer/constants/teamColors';
|
|||
import { useDraftPersistence } from '@renderer/hooks/useDraftPersistence';
|
||||
import { useFileListCacheWarmer } from '@renderer/hooks/useFileListCacheWarmer';
|
||||
import { useTheme } from '@renderer/hooks/useTheme';
|
||||
import { reconcileChips, removeChipTokenFromText } from '@renderer/utils/chipUtils';
|
||||
import { cn } from '@renderer/lib/utils';
|
||||
import { reconcileChips, removeChipTokenFromText } from '@renderer/utils/chipUtils';
|
||||
import { getMemberColorByName } from '@shared/constants/memberColors';
|
||||
import { AlertTriangle, ChevronDown, ChevronRight, Info, RotateCcw, Trash2 } from 'lucide-react';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import { resolveMemberRuntimeSummary } from '@renderer/utils/memberRuntimeSummary';
|
||||
import { buildMemberColorMap } from '@renderer/utils/memberHelpers';
|
||||
import { resolveMemberRuntimeSummary } from '@renderer/utils/memberRuntimeSummary';
|
||||
import { isLeadMember } from '@shared/utils/leadDetection';
|
||||
|
||||
import { MemberCard } from './MemberCard';
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import { serializeChipsWithText } from '@renderer/types/inlineChip';
|
|||
import { normalizeCreateLaunchProviderForUi } from '@renderer/utils/geminiUiFreeze';
|
||||
import { buildMemberColorMap } from '@renderer/utils/memberHelpers';
|
||||
import { normalizeTeamModelForUi } from '@renderer/utils/teamModelAvailability';
|
||||
import { normalizeTeamModelForUi as normalizeCatalogTeamModelForUi } from '@renderer/utils/teamModelCatalog';
|
||||
import { extractProviderScopedBaseModel } from '@renderer/utils/teamModelContext';
|
||||
import { isLeadMember } from '@shared/utils/leadDetection';
|
||||
import { normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
|
||||
|
||||
|
|
@ -32,6 +34,7 @@ function newDraftId(): string {
|
|||
|
||||
export function createMemberDraft(initial?: Partial<MemberDraft>): MemberDraft {
|
||||
const providerId = initial?.providerId;
|
||||
const normalizedModel = extractProviderScopedBaseModel(initial?.model ?? '', providerId) ?? '';
|
||||
return {
|
||||
id: initial?.id ?? newDraftId(),
|
||||
name: initial?.name ?? '',
|
||||
|
|
@ -39,7 +42,7 @@ export function createMemberDraft(initial?: Partial<MemberDraft>): MemberDraft {
|
|||
customRole: initial?.customRole ?? '',
|
||||
workflow: initial?.workflow,
|
||||
providerId,
|
||||
model: normalizeTeamModelForUi(providerId, initial?.model ?? ''),
|
||||
model: normalizeCatalogTeamModelForUi(providerId, normalizedModel),
|
||||
effort: initial?.effort,
|
||||
removedAt: initial?.removedAt,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@
|
|||
*/
|
||||
|
||||
import { api } from '@renderer/api';
|
||||
import { isProjectScopedMcpScope } from '@shared/utils/mcpScopes';
|
||||
import {
|
||||
getExtensionActionDisableReason,
|
||||
getMcpDiagnosticKey,
|
||||
getMcpProjectStateKey,
|
||||
getMcpOperationKey,
|
||||
getMcpProjectStateKey,
|
||||
getPluginOperationKey,
|
||||
} from '@shared/utils/extensionNormalizers';
|
||||
import { isProjectScopedMcpScope } from '@shared/utils/mcpScopes';
|
||||
|
||||
import { findPaneByTabId, updatePane } from '../utils/paneHelpers';
|
||||
|
||||
|
|
|
|||
|
|
@ -94,10 +94,10 @@ type TeamGraphConfigMemberSeedInput = Pick<
|
|||
NonNullable<TeamData['config']['members']>[number],
|
||||
'name' | 'agentId' | 'removedAt'
|
||||
>;
|
||||
type TeamGraphLayoutSessionState = {
|
||||
interface TeamGraphLayoutSessionState {
|
||||
mode: 'default' | 'manual';
|
||||
signature: string | null;
|
||||
};
|
||||
}
|
||||
|
||||
export function isTeamDataRefreshPending(teamName: string): boolean {
|
||||
return (
|
||||
|
|
@ -1025,8 +1025,7 @@ function areTeamGraphSlotAssignmentsEqual(
|
|||
for (const [stableOwnerId, leftAssignment] of leftEntries) {
|
||||
const rightAssignment = right?.[stableOwnerId];
|
||||
if (
|
||||
!rightAssignment ||
|
||||
rightAssignment.ringIndex !== leftAssignment.ringIndex ||
|
||||
rightAssignment?.ringIndex !== leftAssignment.ringIndex ||
|
||||
rightAssignment.sectorIndex !== leftAssignment.sectorIndex
|
||||
) {
|
||||
return false;
|
||||
|
|
@ -2063,8 +2062,7 @@ export const createTeamSlice: StateCreator<AppState, [], [], TeamSlice> = (set,
|
|||
return (
|
||||
(nextAssignment.ringIndex === assignment.ringIndex &&
|
||||
nextAssignment.sectorIndex === assignment.sectorIndex) ||
|
||||
(displacedAssignment != null &&
|
||||
nextAssignment.ringIndex === displacedAssignment.ringIndex &&
|
||||
(nextAssignment.ringIndex === displacedAssignment?.ringIndex &&
|
||||
nextAssignment.sectorIndex === displacedAssignment.sectorIndex)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { formatTeamModelSummary } from '@renderer/components/team/dialogs/TeamModelSelector';
|
||||
import { inferTeamProviderIdFromModel } from '@shared/utils/teamProvider';
|
||||
|
||||
import type { TeamLaunchParams } from '@renderer/store/slices/teamSlice';
|
||||
import type { MemberSpawnStatusEntry, ResolvedTeamMember, TeamProviderId } from '@shared/types';
|
||||
import { inferTeamProviderIdFromModel } from '@shared/utils/teamProvider';
|
||||
|
||||
function isMemberLaunchPending(spawnEntry: MemberSpawnStatusEntry | undefined): boolean {
|
||||
if (!spawnEntry) {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import { getSkillAudienceLabel, isSkillAvailableForProvider } from '@shared/util
|
|||
import { isSupportedSlashCommandName } from '@shared/utils/slashCommands';
|
||||
|
||||
import type { MentionSuggestion } from '@renderer/types/mention';
|
||||
import type { SkillCatalogItem } from '@shared/types/extensions';
|
||||
import type { TeamProviderId } from '@shared/types';
|
||||
import type { SkillCatalogItem } from '@shared/types/extensions';
|
||||
import type { KnownSlashCommandDefinition } from '@shared/utils/slashCommands';
|
||||
|
||||
function orderSkillsForProvider(
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
import {
|
||||
getProviderScopedTeamModelLabel,
|
||||
getRuntimeAwareTeamModelUiDisabledReason,
|
||||
getTeamProviderLabel,
|
||||
getTeamProviderModelOptions,
|
||||
getVisibleTeamProviderModels,
|
||||
GPT_5_1_CODEX_MAX_CHATGPT_UI_DISABLED_REASON,
|
||||
GPT_5_1_CODEX_MINI_UI_DISABLED_MODEL,
|
||||
GPT_5_1_CODEX_MINI_UI_DISABLED_REASON,
|
||||
GPT_5_2_CODEX_UI_DISABLED_MODEL,
|
||||
GPT_5_2_CODEX_UI_DISABLED_REASON,
|
||||
GPT_5_3_CODEX_SPARK_UI_DISABLED_MODEL,
|
||||
GPT_5_3_CODEX_SPARK_UI_DISABLED_REASON,
|
||||
normalizeTeamModelForUi as normalizeCatalogTeamModelForUi,
|
||||
sortTeamProviderModels,
|
||||
TEAM_MODEL_UI_DISABLED_BADGE_LABEL,
|
||||
type TeamProviderModelOption,
|
||||
} from './teamModelCatalog';
|
||||
|
||||
import type {
|
||||
CliProviderId,
|
||||
CliProviderModelAvailability,
|
||||
|
|
@ -6,29 +25,10 @@ import type {
|
|||
TeamProviderId,
|
||||
} from '@shared/types';
|
||||
|
||||
import {
|
||||
getProviderScopedTeamModelLabel,
|
||||
getRuntimeAwareTeamModelUiDisabledReason,
|
||||
getTeamProviderLabel,
|
||||
getTeamProviderModelOptions,
|
||||
sortTeamProviderModels,
|
||||
getVisibleTeamProviderModels,
|
||||
normalizeTeamModelForUi as normalizeCatalogTeamModelForUi,
|
||||
GPT_5_1_CODEX_MINI_UI_DISABLED_MODEL,
|
||||
GPT_5_1_CODEX_MINI_UI_DISABLED_REASON,
|
||||
GPT_5_1_CODEX_MAX_CHATGPT_UI_DISABLED_REASON,
|
||||
GPT_5_2_CODEX_UI_DISABLED_MODEL,
|
||||
GPT_5_2_CODEX_UI_DISABLED_REASON,
|
||||
GPT_5_3_CODEX_SPARK_UI_DISABLED_MODEL,
|
||||
GPT_5_3_CODEX_SPARK_UI_DISABLED_REASON,
|
||||
TEAM_MODEL_UI_DISABLED_BADGE_LABEL,
|
||||
type TeamProviderModelOption,
|
||||
} from './teamModelCatalog';
|
||||
|
||||
export {
|
||||
GPT_5_1_CODEX_MAX_CHATGPT_UI_DISABLED_REASON,
|
||||
GPT_5_1_CODEX_MINI_UI_DISABLED_MODEL,
|
||||
GPT_5_1_CODEX_MINI_UI_DISABLED_REASON,
|
||||
GPT_5_1_CODEX_MAX_CHATGPT_UI_DISABLED_REASON,
|
||||
GPT_5_2_CODEX_UI_DISABLED_MODEL,
|
||||
GPT_5_2_CODEX_UI_DISABLED_REASON,
|
||||
GPT_5_3_CODEX_SPARK_UI_DISABLED_MODEL,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import type { CliProviderId, CliProviderStatus, TeamProviderId } from '@shared/types';
|
||||
import {
|
||||
filterVisibleProviderRuntimeModels,
|
||||
GPT_5_1_CODEX_MINI_UI_DISABLED_MODEL,
|
||||
|
|
@ -6,6 +5,8 @@ import {
|
|||
GPT_5_3_CODEX_SPARK_UI_DISABLED_MODEL,
|
||||
} from '@shared/utils/providerModelVisibility';
|
||||
|
||||
import type { CliProviderId, CliProviderStatus, TeamProviderId } from '@shared/types';
|
||||
|
||||
export {
|
||||
GPT_5_1_CODEX_MINI_UI_DISABLED_MODEL,
|
||||
GPT_5_2_CODEX_UI_DISABLED_MODEL,
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ import {
|
|||
|
||||
import type {
|
||||
CliInstallationStatus,
|
||||
InstallScope,
|
||||
InstalledMcpEntry,
|
||||
InstalledPluginEntry,
|
||||
InstallScope,
|
||||
PluginCapability,
|
||||
PluginCatalogItem,
|
||||
} from '@shared/types';
|
||||
|
|
@ -206,7 +206,7 @@ export function getPreferredMcpInstallationEntry(
|
|||
|
||||
return [...installations].sort(
|
||||
(left, right) => MCP_SCOPE_PRIORITY[left.scope] - MCP_SCOPE_PRIORITY[right.scope]
|
||||
)[0]!;
|
||||
)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ describe('CliInstallerService', () => {
|
|||
verificationState: 'verified',
|
||||
modelVerificationState: 'idle',
|
||||
statusMessage: null,
|
||||
models: ['gpt-5.4', 'gpt-5.2-codex'],
|
||||
models: ['gpt-5.4', 'gpt-5.4-mini'],
|
||||
modelAvailability: [],
|
||||
canLoginFromUi: true,
|
||||
capabilities: { teamLaunch: true, oneShot: true },
|
||||
|
|
@ -267,14 +267,12 @@ describe('CliInstallerService', () => {
|
|||
if (normalizedArgs === '--version') {
|
||||
return { stdout: '2.3.4', stderr: '' };
|
||||
}
|
||||
if (normalizedArgs.includes('--model gpt-5.4-mini')) {
|
||||
throw new Error("The 'gpt-5.4-mini' model is not supported in this Codex runtime.");
|
||||
}
|
||||
if (normalizedArgs.includes('--model gpt-5.4')) {
|
||||
return { stdout: 'PONG', stderr: '' };
|
||||
}
|
||||
if (normalizedArgs.includes('--model gpt-5.2-codex')) {
|
||||
throw new Error(
|
||||
"The 'gpt-5.2-codex' model is not supported when using Codex with a ChatGPT account."
|
||||
);
|
||||
}
|
||||
throw new Error(`Unexpected execCli call: ${normalizedArgs}`);
|
||||
});
|
||||
|
||||
|
|
@ -291,7 +289,7 @@ describe('CliInstallerService', () => {
|
|||
expect(verifiedProvider?.modelAvailability).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ modelId: 'gpt-5.4', status: 'checking' }),
|
||||
expect.objectContaining({ modelId: 'gpt-5.2-codex', status: 'checking' }),
|
||||
expect.objectContaining({ modelId: 'gpt-5.4-mini', status: 'checking' }),
|
||||
])
|
||||
);
|
||||
|
||||
|
|
@ -303,7 +301,7 @@ describe('CliInstallerService', () => {
|
|||
expect(latestCodexProvider?.modelAvailability).toEqual([
|
||||
expect.objectContaining({ modelId: 'gpt-5.4', status: 'available' }),
|
||||
expect.objectContaining({
|
||||
modelId: 'gpt-5.2-codex',
|
||||
modelId: 'gpt-5.4-mini',
|
||||
status: 'unavailable',
|
||||
}),
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ interface StoreState {
|
|||
installed?: boolean;
|
||||
binaryPath?: string | null;
|
||||
launchError?: string | null;
|
||||
};
|
||||
} | null;
|
||||
}
|
||||
|
||||
const storeState = {} as StoreState;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|||
|
||||
import type { CliInstallationStatus } from '@shared/types';
|
||||
import type { SkillCatalogItem } from '@shared/types/extensions';
|
||||
import { createDefaultCliExtensionCapabilities } from '@shared/utils/providerExtensionCapabilities';
|
||||
|
||||
interface StoreState {
|
||||
fetchSkillsCatalog: ReturnType<typeof vi.fn>;
|
||||
|
|
@ -213,12 +214,9 @@ function makeMultimodelStatus(
|
|||
capabilities: {
|
||||
teamLaunch: true,
|
||||
oneShot: true,
|
||||
extensions: {
|
||||
plugins: { status: 'supported', ownership: 'provider', reason: null },
|
||||
mcp: { status: 'supported', ownership: 'shared', reason: null },
|
||||
skills: { status: 'supported', ownership: 'shared', reason: null },
|
||||
apiKeys: { status: 'supported', ownership: 'shared', reason: null },
|
||||
},
|
||||
extensions: createDefaultCliExtensionCapabilities({
|
||||
plugins: { status: 'supported', ownership: 'provider-scoped', reason: null },
|
||||
}),
|
||||
},
|
||||
connection: null,
|
||||
backend: null,
|
||||
|
|
@ -405,12 +403,9 @@ describe('SkillsPanel', () => {
|
|||
capabilities: {
|
||||
teamLaunch: true,
|
||||
oneShot: true,
|
||||
extensions: {
|
||||
plugins: { status: 'unsupported', ownership: 'provider', reason: null },
|
||||
mcp: { status: 'supported', ownership: 'shared', reason: null },
|
||||
skills: { status: 'supported', ownership: 'shared', reason: null },
|
||||
apiKeys: { status: 'supported', ownership: 'shared', reason: null },
|
||||
},
|
||||
extensions: createDefaultCliExtensionCapabilities({
|
||||
plugins: { status: 'unsupported', ownership: 'provider-scoped', reason: null },
|
||||
}),
|
||||
},
|
||||
connection: null,
|
||||
backend: null,
|
||||
|
|
|
|||
|
|
@ -55,12 +55,14 @@ vi.mock('../../../src/renderer/api', () => ({
|
|||
}));
|
||||
|
||||
import { api } from '../../../src/renderer/api';
|
||||
import type { CliInstallationStatus } from '../../../src/shared/types';
|
||||
import {
|
||||
getMcpDiagnosticKey,
|
||||
getMcpProjectStateKey,
|
||||
getMcpOperationKey,
|
||||
getPluginOperationKey,
|
||||
} from '../../../src/shared/utils/extensionNormalizers';
|
||||
import { createDefaultCliExtensionCapabilities } from '../../../src/shared/utils/providerExtensionCapabilities';
|
||||
|
||||
import type {
|
||||
EnrichedPlugin,
|
||||
|
|
@ -137,7 +139,7 @@ const makeSkillDetail = (overrides: Partial<SkillDetail> = {}): SkillDetail => (
|
|||
...overrides,
|
||||
});
|
||||
|
||||
const makeReadyCliStatus = () => ({
|
||||
const makeReadyCliStatus = (): CliInstallationStatus => ({
|
||||
flavor: 'claude' as const,
|
||||
displayName: 'Claude',
|
||||
supportsSelfUpdate: true,
|
||||
|
|
@ -154,7 +156,10 @@ const makeReadyCliStatus = () => ({
|
|||
providers: [],
|
||||
});
|
||||
|
||||
const makeLimitedMultimodelCliStatus = (section: 'plugins' | 'mcp', reason: string) => ({
|
||||
const makeLimitedMultimodelCliStatus = (
|
||||
section: 'plugins' | 'mcp',
|
||||
reason: string
|
||||
): CliInstallationStatus => ({
|
||||
flavor: 'agent_teams_orchestrator' as const,
|
||||
displayName: 'Claude Multimodel',
|
||||
supportsSelfUpdate: false,
|
||||
|
|
@ -181,21 +186,22 @@ const makeLimitedMultimodelCliStatus = (section: 'plugins' | 'mcp', reason: stri
|
|||
capabilities: {
|
||||
teamLaunch: true,
|
||||
oneShot: true,
|
||||
extensions: {
|
||||
extensions: createDefaultCliExtensionCapabilities({
|
||||
plugins: {
|
||||
status: section === 'plugins' ? 'unsupported' : 'supported',
|
||||
ownership: 'shared' as const,
|
||||
ownership: 'shared',
|
||||
reason: section === 'plugins' ? reason : null,
|
||||
},
|
||||
mcp: {
|
||||
status: section === 'mcp' ? 'read-only' : 'supported',
|
||||
ownership: 'shared' as const,
|
||||
ownership: 'shared',
|
||||
reason: section === 'mcp' ? reason : null,
|
||||
},
|
||||
skills: { status: 'supported', ownership: 'shared' as const, reason: null },
|
||||
apiKeys: { status: 'supported', ownership: 'shared' as const, reason: null },
|
||||
},
|
||||
}),
|
||||
},
|
||||
statusMessage: null,
|
||||
connection: null,
|
||||
backend: null,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import {
|
|||
} from '@renderer/utils/multimodelProviderVisibility';
|
||||
|
||||
import type { CliInstallationStatus, CliProviderStatus } from '@shared/types';
|
||||
import { createDefaultCliExtensionCapabilities } from '@shared/utils/providerExtensionCapabilities';
|
||||
|
||||
function createProvider(providerId: CliProviderStatus['providerId']): CliProviderStatus {
|
||||
return {
|
||||
|
|
@ -21,9 +22,9 @@ function createProvider(providerId: CliProviderStatus['providerId']): CliProvide
|
|||
capabilities: {
|
||||
teamLaunch: true,
|
||||
oneShot: true,
|
||||
extensions: createDefaultCliExtensionCapabilities(),
|
||||
},
|
||||
statusMessage: null,
|
||||
detailMessage: null,
|
||||
selectedBackendId: null,
|
||||
resolvedBackendId: null,
|
||||
availableBackends: [],
|
||||
|
|
|
|||
Loading…
Reference in a new issue