@taskforcehq/taskforce 0.3.329 → 0.3.330
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Taskforce.module.css +290 -45
- package/dist/components/features/AiProfilesModule.js +3 -5
- package/dist/components/features/TaskSettings.js +70 -14
- package/dist/components/features/TaskforceAgentsModule.d.ts +1 -2
- package/dist/components/features/TaskforceAgentsModule.js +586 -116
- package/dist/components/features/agentConnections/AgentConnectionControl.d.ts +15 -0
- package/dist/components/features/agentConnections/AgentConnectionControl.js +125 -0
- package/dist/components/features/agentConnections/ModelConnectionsPanel.d.ts +18 -0
- package/dist/components/features/agentConnections/ModelConnectionsPanel.js +393 -0
- package/dist/components/features/agentConnections/modelConnectionsApi.d.ts +65 -0
- package/dist/components/features/agentConnections/modelConnectionsApi.js +129 -0
- package/dist/components/features/taskforceAgentAssignments/AgentBehaviorAssignments.js +15 -24
- package/dist/components/features/taskforceAgentEditorModel.d.ts +2 -1
- package/dist/components/features/taskforceAgentEditorModel.js +3 -1
- package/dist/components/features/workflowManager/workflowManagerApi.d.ts +1 -1
- package/dist/components/features/workflowManager/workflowManagerApi.js +3 -0
- package/dist/components/task/TaskWorkflowAssignmentField.js +68 -10
- package/dist/components/views/StandaloneLayout.js +27 -26
- package/dist/components/views/standalone/modals/SyncStatusModal.d.ts +4 -3
- package/dist/components/views/standalone/modals/SyncStatusModal.js +33 -38
- package/dist/config/envSchema.js +48 -1
- package/dist/core/McpTokenService.d.ts +23 -1
- package/dist/core/McpTokenService.js +93 -10
- package/dist/core/TaskChecklistCommandService.d.ts +27 -0
- package/dist/core/TaskChecklistCommandService.js +83 -5
- package/dist/core/TaskLifecycleCommandService.d.ts +3 -1
- package/dist/core/TaskLifecycleCommandService.js +6 -2
- package/dist/core/Taskforce.d.ts +32 -0
- package/dist/core/Taskforce.js +125 -4
- package/dist/core/types.d.ts +8 -0
- package/dist/documentReviews/commandService.d.ts +2 -1
- package/dist/documentReviews/commandService.js +6 -3
- package/dist/hooks/sync/orchestratorShared.d.ts +1 -0
- package/dist/hooks/sync/orchestratorShared.js +2 -0
- package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.d.ts +3 -0
- package/dist/hooks/sync/useLocalSyncCoordinatorSnapshot.js +85 -9
- package/dist/hooks/sync/useSyncStatusControls.d.ts +4 -1
- package/dist/hooks/sync/useSyncStatusControls.js +47 -11
- package/dist/hooks/useSyncOrchestrator.d.ts +3 -0
- package/dist/hooks/useSyncOrchestrator.js +111 -2
- package/dist/hooks/useTaskData.d.ts +31 -1
- package/dist/hooks/useTaskData.js +29 -7
- package/dist/hooks/useTaskMutations.d.ts +3 -1
- package/dist/hooks/useTaskMutations.js +46 -12
- package/dist/hooks/useTaskforce.d.ts +2 -0
- package/dist/hooks/useTaskforce.js +11 -2
- package/dist/mcp/clientRegistry.d.ts +2 -2
- package/dist/mcp/clientRegistry.js +1 -1
- package/dist/mcp/documentAssetRegistrar.js +9 -6
- package/dist/mcp/durableTaskMutationRouter.d.ts +4 -1
- package/dist/mcp/durableTaskMutationRouter.js +10 -0
- package/dist/mcp/durableTaskRelationshipMutationRouter.js +4 -0
- package/dist/mcp/httpProtocolRouting.d.ts +10 -0
- package/dist/mcp/httpProtocolRouting.js +19 -0
- package/dist/mcp/localCliHealth.d.ts +2 -2
- package/dist/mcp/localCliHealth.js +2 -2
- package/dist/mcp/localServiceProxy.d.ts +1 -0
- package/dist/mcp/localServiceProxy.js +530 -68
- package/dist/mcp/planningAttachmentCommandAdapter.d.ts +3 -1
- package/dist/mcp/planningAttachmentCommandAdapter.js +20 -2
- package/dist/mcp/runtime.d.ts +54 -79
- package/dist/mcp/runtime.js +384 -97
- package/dist/mcp/taskPlanningRegistrar.js +23 -4
- package/dist/mcp/toolProfiles.d.ts +2 -0
- package/dist/mcp/toolProfiles.js +10 -0
- package/dist/mcp/toolRegistry.d.ts +1 -0
- package/dist/mcp/toolRegistry.js +1 -0
- package/dist/mcp/workflowExecutionRegistrar.js +4 -4
- package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
- package/dist/migrations/taskSchemaMigrations.js +415 -0
- package/dist/runtime/appGates.d.ts +2 -1
- package/dist/runtime/appGates.js +7 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +108 -11
- package/dist/server/localDatabaseIdentity.js +4 -1
- package/dist/server/localServiceLease.js +2 -1
- package/dist/server/localServiceSessions.d.ts +14 -17
- package/dist/server/localServiceSessions.js +308 -94
- package/dist/server/localWorkspaceSyncServerRuntime.js +12 -14
- package/dist/server/routes/admin.d.ts +4 -0
- package/dist/server/routes/admin.js +112 -3
- package/dist/server/routes/agents.d.ts +7 -0
- package/dist/server/routes/agents.js +277 -24
- package/dist/server/routes/billing.js +5 -1
- package/dist/server/routes/durableTaskHttpRouters.d.ts +2 -0
- package/dist/server/routes/executorPhaseAApprovals.d.ts +19 -0
- package/dist/server/routes/executorPhaseAApprovals.js +140 -0
- package/dist/server/routes/executorPhaseAIssuerRedemptions.d.ts +11 -0
- package/dist/server/routes/executorPhaseAIssuerRedemptions.js +24 -0
- package/dist/server/routes/githubReviewEvidence.d.ts +19 -0
- package/dist/server/routes/githubReviewEvidence.js +116 -0
- package/dist/server/routes/localService.d.ts +15 -4
- package/dist/server/routes/localService.js +136 -40
- package/dist/server/routes/modelConnections.d.ts +24 -0
- package/dist/server/routes/modelConnections.js +205 -0
- package/dist/server/routes/shared.d.ts +19 -0
- package/dist/server/routes/shared.js +95 -19
- package/dist/server/routes/sync.js +1 -0
- package/dist/server/routes/syncAuxRoutes.js +5 -1
- package/dist/server/routes/syncPushRoutes.d.ts +1 -0
- package/dist/server/routes/syncPushRoutes.js +1 -0
- package/dist/server/routes/syncV3FeedRoutes.js +10 -1
- package/dist/server/routes/syncV3OperationRoutes.js +35 -9
- package/dist/server/routes/tasks.js +21 -2
- package/dist/server/routes/workflows.js +9 -1
- package/dist/server/routes.js +59 -0
- package/dist/services/codexAppServerModelGateway.d.ts +54 -5
- package/dist/services/codexAppServerModelGateway.js +246 -21
- package/dist/services/codexDeviceCodeLoginManager.d.ts +39 -0
- package/dist/services/codexDeviceCodeLoginManager.js +265 -0
- package/dist/services/codexModelProviderConnectionLifecycle.d.ts +8 -0
- package/dist/services/codexModelProviderConnectionLifecycle.js +73 -0
- package/dist/services/executorPhaseAApprovalRuntime.d.ts +14 -0
- package/dist/services/executorPhaseAApprovalRuntime.js +24 -0
- package/dist/services/executorPhaseAApprovalService.d.ts +40 -0
- package/dist/services/executorPhaseAApprovalService.js +609 -0
- package/dist/services/executorPhaseADriftEvaluator.d.ts +78 -0
- package/dist/services/executorPhaseADriftEvaluator.js +93 -0
- package/dist/services/executorPhaseAIssuerCore.d.ts +126 -0
- package/dist/services/executorPhaseAIssuerCore.js +295 -0
- package/dist/services/executorPhaseAIssuerRedemptionService.d.ts +34 -0
- package/dist/services/executorPhaseAIssuerRedemptionService.js +158 -0
- package/dist/services/githubReviewEvidenceRuntime.d.ts +14 -0
- package/dist/services/githubReviewEvidenceRuntime.js +30 -0
- package/dist/services/githubReviewEvidenceService.d.ts +93 -0
- package/dist/services/githubReviewEvidenceService.js +336 -0
- package/dist/services/modelGateway.d.ts +7 -0
- package/dist/services/modelProviderConnectionService.d.ts +71 -0
- package/dist/services/modelProviderConnectionService.js +279 -0
- package/dist/services/modelProviderCredentialHome.d.ts +32 -0
- package/dist/services/modelProviderCredentialHome.js +271 -0
- package/dist/services/ownerScopedModelConnectionGateway.d.ts +12 -0
- package/dist/services/ownerScopedModelConnectionGateway.js +30 -0
- package/dist/services/taskforceAgentConnectionBindingService.d.ts +66 -0
- package/dist/services/taskforceAgentConnectionBindingService.js +185 -0
- package/dist/services/taskforceAgentMcpBridge.d.ts +1 -1
- package/dist/services/taskforceAgentMcpBridge.js +7 -24
- package/dist/shared/adminEdgeProxy.d.ts +5 -0
- package/dist/shared/adminEdgeProxy.js +94 -0
- package/dist/shared/adminProxySessionCookies.d.ts +16 -0
- package/dist/shared/adminProxySessionCookies.js +86 -0
- package/dist/shared/aiProfileColors.d.ts +31 -1
- package/dist/shared/aiProfileColors.js +14 -6
- package/dist/shared/executorPhaseAApprovalGoldenVector.json +269 -0
- package/dist/shared/executorPhaseAApprovalReceipt.d.ts +112 -0
- package/dist/shared/executorPhaseAApprovalReceipt.js +58 -0
- package/dist/shared/executorPhaseAApprovalTrustPolicy.json +10 -0
- package/dist/shared/executorPhaseADriftContracts.d.ts +37 -0
- package/dist/shared/executorPhaseADriftContracts.js +63 -0
- package/dist/shared/executorPhaseAIssuerContracts.d.ts +75 -0
- package/dist/shared/executorPhaseAIssuerContracts.js +90 -0
- package/dist/shared/executorPhaseARunAuthorization.d.ts +120 -0
- package/dist/shared/executorPhaseARunAuthorization.js +232 -0
- package/dist/shared/executorPhaseASchemaValidation.d.ts +7 -0
- package/dist/shared/executorPhaseASchemaValidation.js +53 -0
- package/dist/shared/executorPhaseASchemas/approval-receipt.schema.json +106 -0
- package/dist/shared/executorPhaseASchemas/drift-attestation.schema.json +54 -0
- package/dist/shared/executorPhaseASchemas/drift-request.schema.json +47 -0
- package/dist/shared/executorPhaseASchemas/foundation-manifest.schema.json +29 -0
- package/dist/shared/executorPhaseASchemas/issuer-audit-record.schema.json +24 -0
- package/dist/shared/executorPhaseASchemas/issuer-proof.schema.json +43 -0
- package/dist/shared/executorPhaseASchemas/issuer-redemption-request.schema.json +18 -0
- package/dist/shared/executorPhaseASchemas/issuer-redemption-response.schema.json +39 -0
- package/dist/shared/executorPhaseASchemas/logical-envelope.schema.json +149 -0
- package/dist/shared/executorPhaseASchemas/preflight-report.schema.json +216 -0
- package/dist/shared/executorPhaseASchemas/run-capability.schema.json +111 -0
- package/dist/shared/executorPhaseASchemas/sender-proof.schema.json +37 -0
- package/dist/shared/executorPhaseASchemas/workload-grant.schema.json +68 -0
- package/dist/shared/executorPhaseASchemas/workload-jwt-claims.schema.json +67 -0
- package/dist/shared/executorPhaseATiming.d.ts +1 -0
- package/dist/shared/executorPhaseATiming.js +1 -0
- package/dist/shared/planningIdentity.js +1 -1
- package/dist/shared/productLogoKeys.d.ts +2 -0
- package/dist/shared/productLogoKeys.js +18 -0
- package/dist/shared/taskforceAgentDefinition.d.ts +0 -1
- package/dist/shared/taskforceAgentDefinition.js +6 -9
- package/dist/shared/taskforceAgentModels.js +7 -3
- package/dist/shared/userFeatureGrants.d.ts +4 -0
- package/dist/shared/userFeatureGrants.js +7 -0
- package/dist/storage/executorPhaseAApprovalReceiptStore.d.ts +37 -0
- package/dist/storage/executorPhaseAApprovalReceiptStore.js +81 -0
- package/dist/storage/executorPhaseARunAuthorizationStore.d.ts +103 -0
- package/dist/storage/executorPhaseARunAuthorizationStore.js +492 -0
- package/dist/storage/githubReviewEvidenceInstallationStore.d.ts +26 -0
- package/dist/storage/githubReviewEvidenceInstallationStore.js +89 -0
- package/dist/storage/modelProviderConnectionStore.d.ts +99 -0
- package/dist/storage/modelProviderConnectionStore.js +446 -0
- package/dist/storage/postgresAdapter.d.ts +4 -0
- package/dist/storage/postgresAdapter.js +11 -0
- package/dist/storage/postgresWorker.js +9 -1
- package/dist/storage/postgresWorkerProtocol.d.ts +1 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
- package/dist/sync/coordinator/localSyncExecutionPermitStore.js +60 -29
- package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.d.ts +10 -0
- package/dist/sync/coordinator/localWorkspaceSyncPendingV2PushProgress.js +29 -0
- package/dist/sync/coordinator/localWorkspaceSyncRunnerState.d.ts +15 -1
- package/dist/sync/coordinator/localWorkspaceSyncRunnerState.js +99 -2
- package/dist/sync/coordinator/workspaceSyncCredentialBroker.d.ts +1 -0
- package/dist/sync/coordinator/workspaceSyncCredentialBroker.js +33 -4
- package/dist/sync/engine/workspaceSyncContentLifecycleAdapter.d.ts +2 -1
- package/dist/sync/engine/workspaceSyncContentVersionStore.d.ts +38 -0
- package/dist/sync/engine/workspaceSyncContentVersionStore.js +50 -1
- package/dist/sync/engine/workspaceSyncEngineLifecyclePolicy.js +6 -6
- package/dist/sync/engine/workspaceSyncEnginePushCompletion.d.ts +14 -0
- package/dist/sync/engine/workspaceSyncEnginePushCompletion.js +84 -0
- package/dist/sync/engine/workspaceSyncEngineRecovery.js +1 -0
- package/dist/sync/engine/workspaceSyncEngineRuntime.d.ts +1 -0
- package/dist/sync/engine/workspaceSyncEngineRuntime.js +1 -0
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +112 -38
- package/dist/sync/engine/workspaceSyncEngineServerSnapshotReader.js +6 -0
- package/dist/sync/engine/workspaceSyncEngineTransfers.js +3 -1
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.d.ts +1 -0
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +29 -0
- package/dist/sync/syncApplyHandlers.d.ts +2 -0
- package/dist/sync/syncApplyHandlers.js +10 -1
- package/dist/sync/syncService.d.ts +15 -0
- package/dist/sync/syncService.js +83 -18
- package/dist/sync/taskforceAgentSyncAuthorization.d.ts +16 -0
- package/dist/sync/taskforceAgentSyncAuthorization.js +20 -0
- package/dist/sync/v3/combinedFeedCapability.js +4 -0
- package/dist/sync/v3/durableInitiativeMutationRouter.js +18 -10
- package/dist/sync/v3/durableOperationReplay.d.ts +14 -0
- package/dist/sync/v3/durableOperationReplay.js +18 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +3 -0
- package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -1
- package/dist/sync/v3/durableTaskChecklistMutationRouter.js +58 -15
- package/dist/sync/v3/durableTaskCommentMutationRouter.js +3 -0
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +1 -1
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +10 -0
- package/dist/sync/v3/durableTaxonomyMutationRouter.js +5 -0
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.d.ts +11 -0
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +39 -10
- package/dist/sync/v3/durableWorkstreamMutationRouter.js +18 -10
- package/dist/sync/v3/durableWorkstreamTaskOrderMutationRouter.js +16 -5
- package/dist/sync/v3/localOutboxDispatchRuntime.js +2 -2
- package/dist/sync/v3/localTaskChecklistOutboxHandler.js +16 -2
- package/dist/sync/v3/localTaskChecklistOutboxService.d.ts +4 -0
- package/dist/sync/v3/localTaskChecklistOutboxService.js +14 -1
- package/dist/sync/v3/localTaskStatusOutboxService.d.ts +8 -0
- package/dist/sync/v3/localTaskStatusOutboxService.js +219 -12
- package/dist/sync/v3/syncDurabilityStore.d.ts +34 -0
- package/dist/sync/v3/syncDurabilityStore.js +168 -2
- package/dist/sync/v3/taskChecklistMutationService.d.ts +11 -0
- package/dist/sync/v3/taskChecklistMutationService.js +44 -1
- package/dist/sync/v3/taskStatusMutationService.d.ts +29 -1
- package/dist/sync/v3/taskStatusMutationService.js +119 -3
- package/dist/sync/v3/workflowAssignmentSync.d.ts +5 -0
- package/dist/sync/v3/workflowAssignmentSync.js +27 -0
- package/dist/sync/v3/workspaceSyncJournalReader.js +1 -1
- package/dist/sync/v3/workspaceSyncOperationRetentionService.d.ts +16 -0
- package/dist/sync/v3/workspaceSyncOperationRetentionService.js +83 -0
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +9 -2
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +44 -32
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +9 -5
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +54 -38
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +70 -31
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +16 -0
- package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
- package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +3 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +5 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +36 -2
- package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.d.ts +17 -0
- package/dist/sync/v3/workspaceSyncV3RepairSnapshotRetentionService.js +64 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverCoverage.js +33 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowTaskCoverWireContract.js +8 -0
- package/dist/sync/workspaceRepair.d.ts +5 -2
- package/dist/sync/workspaceRepair.js +161 -6
- package/dist/sync/workspaceSyncModel.d.ts +21 -0
- package/dist/sync/workspaceSyncModel.js +35 -7
- package/dist/sync/workspaceSyncState.d.ts +1 -0
- package/dist/sync/workspaceSyncV2SnapshotBuilder.d.ts +6 -0
- package/dist/sync/workspaceSyncV2SnapshotBuilder.js +5 -0
- package/dist/ui/assets/AiIdentityRosterCard-OcSz1PkK.js +1 -0
- package/dist/ui/assets/AiProfilesModule-ByhYW5Xi.js +1 -0
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-B68Wg-RV.js → AnnotatedAttachmentWorkspace-BTM6nIg_.js} +1 -1
- package/dist/ui/assets/{AssetTraySortControl-C8Rztyal.js → AssetTraySortControl-DabEG8L4.js} +1 -1
- package/dist/ui/assets/{ContextAttachmentManager-Cj3c7X9y.js → ContextAttachmentManager-Coa8yVGM.js} +1 -1
- package/dist/ui/assets/{DocumentWorkspace-B5uvzems.js → DocumentWorkspace-BB0qhdix.js} +1 -1
- package/dist/ui/assets/{EntityActivityTimeline-BVFvCB5R.js → EntityActivityTimeline-CZ8x4UJE.js} +1 -1
- package/dist/ui/assets/{PlanningModule-B5DWQOGz.js → PlanningModule-pRPjR7v5.js} +1 -1
- package/dist/ui/assets/{PlansPage-AY4cGWco.js → PlansPage-D86pZSSl.js} +1 -1
- package/dist/ui/assets/{TaskContextUpload-DZxTVesW.js → TaskContextUpload-BVIkU9yT.js} +1 -1
- package/dist/ui/assets/TaskSettings-Cv1mNhv_.js +12 -0
- package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
- package/dist/ui/assets/TaskforceAgentsModule-gmH-PD2q.js +24 -0
- package/dist/ui/assets/{WorkflowManagerModule-DEr5di_r.js → WorkflowManagerModule-DbfnHJ-f.js} +1 -1
- package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
- package/dist/ui/assets/index-CTsDBaef.js +7 -0
- package/dist/ui/assets/{vendor-icons-D9Lpw-j4.js → vendor-icons-Bsq-mcEn.js} +1 -1
- package/dist/ui/branding/logos/letterhead_dark.png +0 -0
- package/dist/ui/branding/logos/letterhead_light.png +0 -0
- package/dist/ui/branding/logos/signature_dark.png +0 -0
- package/dist/ui/branding/logos/signature_light.png +0 -0
- package/dist/ui/index.html +3 -3
- package/dist/utils/aiProfileDefaultLogo.js +16 -48
- package/dist/utils/httpSetCookie.d.ts +1 -0
- package/dist/utils/httpSetCookie.js +4 -1
- package/dist/utils/localRuntimeUrl.d.ts +1 -0
- package/dist/utils/localRuntimeUrl.js +14 -0
- package/dist/utils/productLogoRegistry.d.ts +2 -0
- package/dist/utils/productLogoRegistry.js +36 -0
- package/dist/utils/syncStatusPresentation.d.ts +4 -0
- package/dist/utils/syncStatusPresentation.js +17 -0
- package/dist/utils/taskEvents.d.ts +2 -0
- package/dist/utils/workspaceSyncPresentation.d.ts +1 -1
- package/dist/utils/workspaceSyncPresentation.js +23 -17
- package/package.json +22 -4
- package/dist/ui/assets/AiIdentityRosterCard-BZM4aQnM.js +0 -1
- package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +0 -1
- package/dist/ui/assets/TaskSettings-BeWAuyZj.js +0 -12
- package/dist/ui/assets/TaskforceAgentsModule-BifCYtjR.js +0 -21
- package/dist/ui/assets/TaskforceAgentsModule-D6IC0S7Q.css +0 -1
- package/dist/ui/assets/index-I5zhdtgt.js +0 -7
- package/dist/ui/assets/index-VRFsx3wz.css +0 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type AgentConnectionControlProps = {
|
|
2
|
+
workspaceId: string;
|
|
3
|
+
runtimeMode: 'local' | 'cloud';
|
|
4
|
+
agentId: string | null;
|
|
5
|
+
providerKey: string;
|
|
6
|
+
active: boolean;
|
|
7
|
+
refreshKey: number;
|
|
8
|
+
cloudAccessAvailable?: boolean;
|
|
9
|
+
cloudAccessPending?: boolean;
|
|
10
|
+
cloudAuthConfigured?: boolean;
|
|
11
|
+
resolveCloudAuthUrl?: (path: string) => string;
|
|
12
|
+
onManageConnections: () => void;
|
|
13
|
+
};
|
|
14
|
+
export declare function AgentConnectionControl({ workspaceId, runtimeMode, agentId, providerKey, active, refreshKey, cloudAccessAvailable, cloudAccessPending, cloudAuthConfigured, resolveCloudAuthUrl, onManageConnections, }: AgentConnectionControlProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { AlertTriangle, CheckCircle, Link, Loader2, Plug } from 'lucide-react';
|
|
4
|
+
import styles from '../../../Taskforce.module.css';
|
|
5
|
+
import { bindAgentConnection, inspectAgentConnectionBinding, listModelConnections, } from './modelConnectionsApi.js';
|
|
6
|
+
export function AgentConnectionControl({ workspaceId, runtimeMode, agentId, providerKey, active, refreshKey, cloudAccessAvailable = runtimeMode === 'cloud', cloudAccessPending = false, cloudAuthConfigured = runtimeMode === 'cloud', resolveCloudAuthUrl, onManageConnections, }) {
|
|
7
|
+
const context = useMemo(() => ({
|
|
8
|
+
workspaceId,
|
|
9
|
+
resolveApiUrl: resolveCloudAuthUrl,
|
|
10
|
+
}), [resolveCloudAuthUrl, workspaceId]);
|
|
11
|
+
const [binding, setBinding] = useState(null);
|
|
12
|
+
const [connections, setConnections] = useState([]);
|
|
13
|
+
const [selectedConnectionId, setSelectedConnectionId] = useState('');
|
|
14
|
+
const [loading, setLoading] = useState(false);
|
|
15
|
+
const [busy, setBusy] = useState(false);
|
|
16
|
+
const [error, setError] = useState('');
|
|
17
|
+
const loadGenerationRef = useRef(0);
|
|
18
|
+
const activeConnections = useMemo(() => connections.filter((connection) => (connection.providerKey === providerKey
|
|
19
|
+
&& connection.authenticationType === 'chatgpt_device_code'
|
|
20
|
+
&& connection.lifecycleStatus === 'active')), [connections, providerKey]);
|
|
21
|
+
const load = useCallback(async () => {
|
|
22
|
+
if (!active || !cloudAccessAvailable || !agentId)
|
|
23
|
+
return;
|
|
24
|
+
const generation = ++loadGenerationRef.current;
|
|
25
|
+
setLoading(true);
|
|
26
|
+
setBinding(null);
|
|
27
|
+
setConnections([]);
|
|
28
|
+
setSelectedConnectionId('');
|
|
29
|
+
setError('');
|
|
30
|
+
try {
|
|
31
|
+
const [nextBinding, nextConnections] = await Promise.all([
|
|
32
|
+
inspectAgentConnectionBinding(agentId, context),
|
|
33
|
+
listModelConnections(context),
|
|
34
|
+
]);
|
|
35
|
+
if (generation !== loadGenerationRef.current)
|
|
36
|
+
return;
|
|
37
|
+
setConnections(nextConnections);
|
|
38
|
+
const ownedBindingId = nextBinding.ownerIsCaller ? String(nextBinding.connectionId || '') : '';
|
|
39
|
+
const matchingConnections = nextConnections.filter((connection) => (connection.providerKey === providerKey
|
|
40
|
+
&& connection.authenticationType === 'chatgpt_device_code'
|
|
41
|
+
&& connection.lifecycleStatus === 'active'));
|
|
42
|
+
const firstActiveId = matchingConnections[0]?.id || '';
|
|
43
|
+
const ownedBindingIsActive = matchingConnections.some((connection) => connection.id === ownedBindingId);
|
|
44
|
+
setSelectedConnectionId(ownedBindingIsActive ? ownedBindingId : firstActiveId);
|
|
45
|
+
let resolvedBinding = nextBinding;
|
|
46
|
+
const mayReplaceBinding = !nextBinding.bound || (nextBinding.ownerIsCaller && !nextBinding.available);
|
|
47
|
+
if (mayReplaceBinding && matchingConnections.length === 1) {
|
|
48
|
+
try {
|
|
49
|
+
resolvedBinding = await bindAgentConnection(agentId, matchingConnections[0].id, context);
|
|
50
|
+
}
|
|
51
|
+
catch (bindError) {
|
|
52
|
+
if (generation !== loadGenerationRef.current)
|
|
53
|
+
return;
|
|
54
|
+
setError(bindError.message || 'Unable to assign this account to the Agent.');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (generation !== loadGenerationRef.current)
|
|
58
|
+
return;
|
|
59
|
+
setBinding(resolvedBinding);
|
|
60
|
+
}
|
|
61
|
+
catch (loadError) {
|
|
62
|
+
if (generation !== loadGenerationRef.current)
|
|
63
|
+
return;
|
|
64
|
+
setError(loadError.message || 'Unable to inspect this Agent connection.');
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
if (generation === loadGenerationRef.current)
|
|
68
|
+
setLoading(false);
|
|
69
|
+
}
|
|
70
|
+
}, [active, agentId, cloudAccessAvailable, context, providerKey]);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
loadGenerationRef.current += 1;
|
|
73
|
+
setBinding(null);
|
|
74
|
+
setConnections([]);
|
|
75
|
+
setSelectedConnectionId('');
|
|
76
|
+
setLoading(false);
|
|
77
|
+
setBusy(false);
|
|
78
|
+
setError('');
|
|
79
|
+
}, [cloudAccessAvailable, context]);
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
void load();
|
|
82
|
+
return () => {
|
|
83
|
+
loadGenerationRef.current += 1;
|
|
84
|
+
};
|
|
85
|
+
}, [load, refreshKey]);
|
|
86
|
+
const bind = useCallback(async () => {
|
|
87
|
+
if (!agentId || !selectedConnectionId)
|
|
88
|
+
return;
|
|
89
|
+
const generation = loadGenerationRef.current;
|
|
90
|
+
setBusy(true);
|
|
91
|
+
setError('');
|
|
92
|
+
try {
|
|
93
|
+
const nextBinding = await bindAgentConnection(agentId, selectedConnectionId, context);
|
|
94
|
+
if (generation !== loadGenerationRef.current)
|
|
95
|
+
return;
|
|
96
|
+
setBinding(nextBinding);
|
|
97
|
+
}
|
|
98
|
+
catch (bindError) {
|
|
99
|
+
if (generation !== loadGenerationRef.current)
|
|
100
|
+
return;
|
|
101
|
+
setError(bindError.message || 'Unable to assign this account to the Agent.');
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
if (generation === loadGenerationRef.current)
|
|
105
|
+
setBusy(false);
|
|
106
|
+
}
|
|
107
|
+
}, [agentId, context, selectedConnectionId]);
|
|
108
|
+
if (!cloudAccessAvailable) {
|
|
109
|
+
return (_jsxs("div", { className: styles.taskforceAgentConnectionControl, children: [_jsxs("div", { children: [_jsx(Plug, { size: 15 }), _jsx("strong", { children: "Connected account" })] }), _jsx("span", { children: cloudAccessPending
|
|
110
|
+
? 'Checking Taskforce Cloud sign-in...'
|
|
111
|
+
: cloudAuthConfigured
|
|
112
|
+
? 'Sign in to Taskforce Cloud to configure this model.'
|
|
113
|
+
: 'Connect this local runtime to Taskforce Cloud to configure this model.' })] }));
|
|
114
|
+
}
|
|
115
|
+
if (!agentId) {
|
|
116
|
+
return (_jsxs("div", { className: styles.taskforceAgentConnectionControl, children: [_jsxs("div", { children: [_jsx(Plug, { size: 15 }), _jsx("strong", { children: "Connected account" })] }), _jsx("span", { children: "Save this Agent to assign a connected account." })] }));
|
|
117
|
+
}
|
|
118
|
+
return (_jsxs("div", { className: styles.taskforceAgentConnectionControl, children: [_jsxs("div", { className: styles.taskforceAgentConnectionControlHeader, children: [_jsxs("div", { children: [_jsx(Plug, { size: 15 }), _jsx("strong", { children: "Connected account" })] }), _jsx("span", { role: "status", "aria-live": "polite", children: loading ? _jsx(Loader2, { size: 14, className: styles.spinner }) : binding?.available ? (_jsxs("span", { className: "tf-chip-success", children: [_jsx(CheckCircle, { size: 12 }), " Assigned"] })) : binding?.bound ? (_jsxs("span", { className: "tf-chip-warning", children: [_jsx(AlertTriangle, { size: 12 }), " Unavailable"] })) : (_jsx("span", { className: "tf-chip-neutral", children: "Not assigned" })) })] }), error ? _jsx("span", { className: "tf-text-error", role: "alert", children: error }) : null, !loading && activeConnections.length > 0 && (!binding?.bound || binding.ownerIsCaller) ? (_jsxs("div", { className: styles.taskforceAgentConnectionBindingRow, children: [_jsxs("label", { className: styles.field, children: [_jsx("span", { className: styles.label, children: "Account" }), _jsx("select", { className: styles.select, value: selectedConnectionId, onChange: (event) => setSelectedConnectionId(event.target.value), "aria-label": "Connected model account", disabled: busy || activeConnections.length === 1, children: activeConnections.map((connection) => (_jsx("option", { value: connection.id, children: connection.displayMetadata.accountLabel
|
|
119
|
+
|| connection.displayMetadata.accountEmail
|
|
120
|
+
|| 'ChatGPT subscription' }, connection.id))) })] }), activeConnections.length > 1 || !binding?.available ? (_jsxs("button", { type: "button", className: "tf-button-secondary tf-button-compact", onClick: () => { void bind(); }, disabled: busy || !selectedConnectionId || (binding?.available && binding.connectionId === selectedConnectionId), children: [busy ? _jsx(Loader2, { size: 14, className: styles.spinner }) : _jsx(Link, { size: 14 }), "Use account"] })) : null] })) : !loading ? (_jsxs("div", { className: styles.taskforceAgentConnectionCallout, children: [_jsx("span", { children: binding?.bound && !binding.ownerIsCaller
|
|
121
|
+
? "This Agent uses another eligible user's private connection. Ask the connection owner to reconnect it."
|
|
122
|
+
: binding?.bound
|
|
123
|
+
? 'The bound connection is unavailable.'
|
|
124
|
+
: 'Connect ChatGPT before running this Agent.' }), binding?.ownerIsCaller !== false ? (_jsxs("button", { type: "button", className: "tf-button-secondary tf-button-compact", onClick: onManageConnections, children: [_jsx(Plug, { size: 14 }), " Manage connections"] })) : null] })) : null] }));
|
|
125
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ModelConnection } from './modelConnectionsApi.js';
|
|
2
|
+
type ModelConnectionsPanelProps = {
|
|
3
|
+
workspaceId: string;
|
|
4
|
+
active: boolean;
|
|
5
|
+
runtimeMode: 'local' | 'cloud';
|
|
6
|
+
eligible: boolean;
|
|
7
|
+
cloudAccessAvailable?: boolean;
|
|
8
|
+
cloudAccessPending?: boolean;
|
|
9
|
+
cloudAuthConfigured?: boolean;
|
|
10
|
+
resolveCloudAuthUrl?: (path: string) => string;
|
|
11
|
+
onConnectionActivated?: (connection: ModelConnection) => void | Promise<void>;
|
|
12
|
+
onConnectionUnavailable?: (connectionId: string) => void;
|
|
13
|
+
onReturnToAgent?: () => void;
|
|
14
|
+
pollIntervalMs?: number;
|
|
15
|
+
libraryPortalTarget?: HTMLElement | null;
|
|
16
|
+
};
|
|
17
|
+
export declare function ModelConnectionsPanel({ workspaceId, active, runtimeMode, eligible, cloudAccessAvailable, cloudAccessPending, cloudAuthConfigured, resolveCloudAuthUrl, onConnectionActivated, onConnectionUnavailable, onReturnToAgent, pollIntervalMs, libraryPortalTarget, }: ModelConnectionsPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
4
|
+
import { AlertTriangle, Check, CircleSlash, Copy, ExternalLink, Loader2, LogOut, Pencil, Plug, RefreshCw, RotateCcw, Trash2, X, } from 'lucide-react';
|
|
5
|
+
import styles from '../../../Taskforce.module.css';
|
|
6
|
+
import { cancelDeviceCodeLogin, createOpenAiCodexConnection, disconnectModelConnection, getDeviceCodeLogin, listModelConnections, loadModelConnectionsSnapshot, modelConnectionFailureMessage, refreshModelConnection, renameModelConnection, removeModelConnection, startDeviceCodeLogin, verifyModelConnection, } from './modelConnectionsApi.js';
|
|
7
|
+
import managerStyles from '../agentBehavior/AgentBehaviorManagerShared.module.css';
|
|
8
|
+
import { getProductLogoUrl } from '../../../utils/productLogoRegistry.js';
|
|
9
|
+
const LOGIN_POLL_INTERVAL_MS = 1_500;
|
|
10
|
+
const CHATGPT_LOGO_URL = getProductLogoUrl('chatgpt');
|
|
11
|
+
function connectionStatusLabel(status) {
|
|
12
|
+
switch (status) {
|
|
13
|
+
case 'active': return 'Connected';
|
|
14
|
+
case 'pending': return 'Not authorized';
|
|
15
|
+
case 'reconnect_required': return 'Reconnect required';
|
|
16
|
+
case 'revoked': return 'Revoked';
|
|
17
|
+
case 'disconnected': return 'Disconnected';
|
|
18
|
+
default: return 'Unavailable';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function connectionStatusClass(status) {
|
|
22
|
+
if (status === 'active')
|
|
23
|
+
return 'tf-chip-success';
|
|
24
|
+
if (status === 'pending' || status === 'disconnected')
|
|
25
|
+
return 'tf-chip-neutral';
|
|
26
|
+
if (status === 'reconnect_required')
|
|
27
|
+
return 'tf-chip-warning';
|
|
28
|
+
return 'tf-chip-danger';
|
|
29
|
+
}
|
|
30
|
+
function connectionAccountLabel(connection) {
|
|
31
|
+
return String(connection.displayMetadata.displayName
|
|
32
|
+
|| connection.displayMetadata.accountLabel
|
|
33
|
+
|| connection.displayMetadata.accountEmail
|
|
34
|
+
|| 'ChatGPT subscription');
|
|
35
|
+
}
|
|
36
|
+
function connectionLastChecked(connection) {
|
|
37
|
+
const timestamps = [connection.lastVerifiedAt, connection.lastRefreshedAt]
|
|
38
|
+
.filter((value) => Boolean(value))
|
|
39
|
+
.map((value) => new Date(value))
|
|
40
|
+
.filter((value) => !Number.isNaN(value.getTime()))
|
|
41
|
+
.sort((left, right) => right.getTime() - left.getTime());
|
|
42
|
+
const value = timestamps[0];
|
|
43
|
+
if (!value)
|
|
44
|
+
return 'Not verified yet';
|
|
45
|
+
return `Checked ${value.toLocaleString()}`;
|
|
46
|
+
}
|
|
47
|
+
export function ModelConnectionsPanel({ workspaceId, active, runtimeMode, eligible, cloudAccessAvailable = runtimeMode === 'cloud', cloudAccessPending = false, cloudAuthConfigured = runtimeMode === 'cloud', resolveCloudAuthUrl, onConnectionActivated, onConnectionUnavailable, onReturnToAgent, pollIntervalMs = LOGIN_POLL_INTERVAL_MS, libraryPortalTarget, }) {
|
|
48
|
+
const context = useMemo(() => ({
|
|
49
|
+
workspaceId,
|
|
50
|
+
resolveApiUrl: resolveCloudAuthUrl,
|
|
51
|
+
}), [resolveCloudAuthUrl, workspaceId]);
|
|
52
|
+
const [connections, setConnections] = useState([]);
|
|
53
|
+
const [selectedConnectionId, setSelectedConnectionId] = useState('');
|
|
54
|
+
const [localEligible, setLocalEligible] = useState(runtimeMode === 'local' ? null : eligible);
|
|
55
|
+
const [loading, setLoading] = useState(false);
|
|
56
|
+
const [busyConnectionId, setBusyConnectionId] = useState(null);
|
|
57
|
+
const [login, setLogin] = useState(null);
|
|
58
|
+
const [feedback, setFeedback] = useState(null);
|
|
59
|
+
const [copied, setCopied] = useState(false);
|
|
60
|
+
const [renamingConnectionId, setRenamingConnectionId] = useState(null);
|
|
61
|
+
const [connectionNameDraft, setConnectionNameDraft] = useState('');
|
|
62
|
+
const pollGenerationRef = useRef(0);
|
|
63
|
+
const loadGenerationRef = useRef(0);
|
|
64
|
+
const connectButtonRef = useRef(null);
|
|
65
|
+
const effectiveEligible = runtimeMode === 'local' ? localEligible : eligible;
|
|
66
|
+
const selectedConnection = connections.find((connection) => connection.id === selectedConnectionId) || null;
|
|
67
|
+
const loadConnections = useCallback(async (quiet = false) => {
|
|
68
|
+
if (!cloudAccessAvailable)
|
|
69
|
+
return;
|
|
70
|
+
const generation = ++loadGenerationRef.current;
|
|
71
|
+
if (!quiet)
|
|
72
|
+
setLoading(true);
|
|
73
|
+
try {
|
|
74
|
+
if (runtimeMode === 'local') {
|
|
75
|
+
const snapshot = await loadModelConnectionsSnapshot(context);
|
|
76
|
+
if (generation !== loadGenerationRef.current)
|
|
77
|
+
return;
|
|
78
|
+
setLocalEligible(snapshot.eligible);
|
|
79
|
+
setConnections(snapshot.connections);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const next = await listModelConnections(context);
|
|
83
|
+
if (generation !== loadGenerationRef.current)
|
|
84
|
+
return;
|
|
85
|
+
setConnections(next);
|
|
86
|
+
}
|
|
87
|
+
if (!quiet)
|
|
88
|
+
setFeedback(null);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
if (generation !== loadGenerationRef.current)
|
|
92
|
+
return;
|
|
93
|
+
const apiError = error;
|
|
94
|
+
setFeedback({ type: 'error', message: apiError.message || 'Unable to load model connections.' });
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
if (!quiet && generation === loadGenerationRef.current)
|
|
98
|
+
setLoading(false);
|
|
99
|
+
}
|
|
100
|
+
}, [cloudAccessAvailable, context, runtimeMode]);
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
loadGenerationRef.current += 1;
|
|
103
|
+
pollGenerationRef.current += 1;
|
|
104
|
+
setConnections([]);
|
|
105
|
+
setSelectedConnectionId('');
|
|
106
|
+
setLocalEligible(runtimeMode === 'local' ? null : eligible);
|
|
107
|
+
setLoading(false);
|
|
108
|
+
setBusyConnectionId(null);
|
|
109
|
+
setLogin(null);
|
|
110
|
+
setFeedback(null);
|
|
111
|
+
setCopied(false);
|
|
112
|
+
setRenamingConnectionId(null);
|
|
113
|
+
setConnectionNameDraft('');
|
|
114
|
+
}, [cloudAccessAvailable, context, eligible, runtimeMode]);
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
setSelectedConnectionId((current) => {
|
|
117
|
+
if (current && connections.some((connection) => connection.id === current))
|
|
118
|
+
return current;
|
|
119
|
+
return connections.length === 1 ? connections[0].id : '';
|
|
120
|
+
});
|
|
121
|
+
}, [connections]);
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
if (!active || !cloudAccessAvailable || (runtimeMode === 'cloud' && !eligible))
|
|
124
|
+
return;
|
|
125
|
+
void loadConnections();
|
|
126
|
+
}, [active, cloudAccessAvailable, eligible, loadConnections, runtimeMode]);
|
|
127
|
+
useEffect(() => () => {
|
|
128
|
+
pollGenerationRef.current += 1;
|
|
129
|
+
}, []);
|
|
130
|
+
const completeActiveLogin = useCallback(async (current, generation) => {
|
|
131
|
+
if (generation !== pollGenerationRef.current)
|
|
132
|
+
return;
|
|
133
|
+
setLogin(null);
|
|
134
|
+
let nextConnections;
|
|
135
|
+
try {
|
|
136
|
+
nextConnections = await listModelConnections(context);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
if (generation !== pollGenerationRef.current)
|
|
140
|
+
return;
|
|
141
|
+
setFeedback({
|
|
142
|
+
type: 'error',
|
|
143
|
+
message: error.message || 'ChatGPT was authorized, but the connection status could not be refreshed.',
|
|
144
|
+
});
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (generation !== pollGenerationRef.current)
|
|
148
|
+
return;
|
|
149
|
+
setConnections(nextConnections);
|
|
150
|
+
const activated = nextConnections.find((connection) => connection.id === current.connectionId) || null;
|
|
151
|
+
if (!activated) {
|
|
152
|
+
setFeedback({ type: 'error', message: 'ChatGPT was authorized, but the connection status could not be refreshed.' });
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
setSelectedConnectionId(activated.id);
|
|
156
|
+
try {
|
|
157
|
+
await onConnectionActivated?.(activated);
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
if (generation !== pollGenerationRef.current)
|
|
161
|
+
return;
|
|
162
|
+
setFeedback({
|
|
163
|
+
type: 'error',
|
|
164
|
+
message: `ChatGPT is connected, but this Agent could not refresh its account selection. ${error.message || 'Return to the Agent and select the account again.'}`,
|
|
165
|
+
returnToAgent: Boolean(onReturnToAgent),
|
|
166
|
+
});
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (generation !== pollGenerationRef.current)
|
|
170
|
+
return;
|
|
171
|
+
setFeedback({ type: 'success', message: 'ChatGPT connection authorized.' });
|
|
172
|
+
}, [context, onConnectionActivated, onReturnToAgent]);
|
|
173
|
+
const pollLogin = useCallback(async (initial, generation) => {
|
|
174
|
+
let current = initial;
|
|
175
|
+
while (generation === pollGenerationRef.current && current.status === 'pending') {
|
|
176
|
+
await new Promise((resolve) => window.setTimeout(resolve, pollIntervalMs));
|
|
177
|
+
if (generation !== pollGenerationRef.current)
|
|
178
|
+
return;
|
|
179
|
+
try {
|
|
180
|
+
current = await getDeviceCodeLogin(current.connectionId, current.id, context);
|
|
181
|
+
if (generation !== pollGenerationRef.current)
|
|
182
|
+
return;
|
|
183
|
+
setLogin(current);
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
if (generation !== pollGenerationRef.current)
|
|
187
|
+
return;
|
|
188
|
+
const apiError = error;
|
|
189
|
+
setFeedback({ type: 'error', message: apiError.message || 'Unable to check device authorization.' });
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (generation !== pollGenerationRef.current)
|
|
194
|
+
return;
|
|
195
|
+
if (current.status === 'active') {
|
|
196
|
+
await completeActiveLogin(current, generation);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
setLogin(null);
|
|
200
|
+
if (current.status !== 'cancelled') {
|
|
201
|
+
setFeedback({ type: 'error', message: modelConnectionFailureMessage(current.failureCode) });
|
|
202
|
+
}
|
|
203
|
+
}, [completeActiveLogin, context, pollIntervalMs]);
|
|
204
|
+
const beginAuthorization = useCallback(async (connection) => {
|
|
205
|
+
const generation = ++pollGenerationRef.current;
|
|
206
|
+
setFeedback(null);
|
|
207
|
+
setCopied(false);
|
|
208
|
+
setBusyConnectionId(connection?.id || 'new');
|
|
209
|
+
try {
|
|
210
|
+
const target = connection || await createOpenAiCodexConnection(context);
|
|
211
|
+
if (generation !== pollGenerationRef.current)
|
|
212
|
+
return;
|
|
213
|
+
setConnections((current) => current.some((item) => item.id === target.id)
|
|
214
|
+
? current.map((item) => item.id === target.id ? target : item)
|
|
215
|
+
: [target, ...current]);
|
|
216
|
+
setSelectedConnectionId(target.id);
|
|
217
|
+
const nextLogin = await startDeviceCodeLogin(target.id, context);
|
|
218
|
+
if (generation !== pollGenerationRef.current)
|
|
219
|
+
return;
|
|
220
|
+
setLogin(nextLogin);
|
|
221
|
+
window.open(nextLogin.verificationUrl, '_blank', 'noopener,noreferrer');
|
|
222
|
+
void pollLogin(nextLogin, generation);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
if (generation !== pollGenerationRef.current)
|
|
226
|
+
return;
|
|
227
|
+
const apiError = error;
|
|
228
|
+
setFeedback({
|
|
229
|
+
type: 'error',
|
|
230
|
+
message: apiError.code
|
|
231
|
+
? modelConnectionFailureMessage(apiError.code, apiError.message)
|
|
232
|
+
: apiError.message,
|
|
233
|
+
});
|
|
234
|
+
await loadConnections(true);
|
|
235
|
+
}
|
|
236
|
+
finally {
|
|
237
|
+
if (generation === pollGenerationRef.current)
|
|
238
|
+
setBusyConnectionId(null);
|
|
239
|
+
}
|
|
240
|
+
}, [context, loadConnections, pollLogin]);
|
|
241
|
+
const cancelLogin = useCallback(async () => {
|
|
242
|
+
if (!login)
|
|
243
|
+
return;
|
|
244
|
+
const generation = ++pollGenerationRef.current;
|
|
245
|
+
setBusyConnectionId(login.connectionId);
|
|
246
|
+
try {
|
|
247
|
+
const cancelled = await cancelDeviceCodeLogin(login.connectionId, login.id, context);
|
|
248
|
+
if (generation !== pollGenerationRef.current)
|
|
249
|
+
return;
|
|
250
|
+
if (cancelled.status === 'active') {
|
|
251
|
+
await completeActiveLogin(cancelled, generation);
|
|
252
|
+
}
|
|
253
|
+
else if (cancelled.status === 'pending') {
|
|
254
|
+
setLogin(cancelled);
|
|
255
|
+
setBusyConnectionId(null);
|
|
256
|
+
void pollLogin(cancelled, generation);
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
setLogin(null);
|
|
260
|
+
setFeedback(cancelled.status === 'cancelled'
|
|
261
|
+
? null
|
|
262
|
+
: { type: 'error', message: modelConnectionFailureMessage(cancelled.failureCode) });
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
catch (error) {
|
|
266
|
+
if (generation !== pollGenerationRef.current)
|
|
267
|
+
return;
|
|
268
|
+
setFeedback({ type: 'error', message: error.message || 'Unable to cancel authorization.' });
|
|
269
|
+
setBusyConnectionId(null);
|
|
270
|
+
void pollLogin(login, generation);
|
|
271
|
+
}
|
|
272
|
+
finally {
|
|
273
|
+
if (generation === pollGenerationRef.current)
|
|
274
|
+
setBusyConnectionId(null);
|
|
275
|
+
}
|
|
276
|
+
}, [completeActiveLogin, context, login, pollLogin]);
|
|
277
|
+
const copyCode = useCallback(async () => {
|
|
278
|
+
if (!login?.userCode || !navigator.clipboard?.writeText)
|
|
279
|
+
return;
|
|
280
|
+
try {
|
|
281
|
+
await navigator.clipboard.writeText(login.userCode);
|
|
282
|
+
setCopied(true);
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
setCopied(false);
|
|
286
|
+
}
|
|
287
|
+
}, [login?.userCode]);
|
|
288
|
+
const runConnectionAction = useCallback(async (connection, action) => {
|
|
289
|
+
setBusyConnectionId(connection.id);
|
|
290
|
+
setFeedback(null);
|
|
291
|
+
try {
|
|
292
|
+
if (action === 'disconnect' && !window.confirm('Disconnect this ChatGPT connection? Agents bound to it will be unavailable until you reconnect.'))
|
|
293
|
+
return;
|
|
294
|
+
if (action === 'remove' && !window.confirm('Remove this ChatGPT connection and its stored credentials? This cannot be undone.'))
|
|
295
|
+
return;
|
|
296
|
+
if (action === 'remove') {
|
|
297
|
+
await removeModelConnection(connection.id, context);
|
|
298
|
+
onConnectionUnavailable?.(connection.id);
|
|
299
|
+
setConnections((current) => current.filter((item) => item.id !== connection.id));
|
|
300
|
+
setSelectedConnectionId((current) => current === connection.id ? '' : current);
|
|
301
|
+
setFeedback({ type: 'success', message: 'ChatGPT connection removed.' });
|
|
302
|
+
window.setTimeout(() => connectButtonRef.current?.focus(), 0);
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const next = action === 'verify'
|
|
306
|
+
? await verifyModelConnection(connection.id, context)
|
|
307
|
+
: action === 'refresh'
|
|
308
|
+
? await refreshModelConnection(connection.id, context)
|
|
309
|
+
: await disconnectModelConnection(connection.id, context);
|
|
310
|
+
if (next.lifecycleStatus !== 'active')
|
|
311
|
+
onConnectionUnavailable?.(connection.id);
|
|
312
|
+
setConnections((current) => current.map((item) => item.id === next.id ? next : item));
|
|
313
|
+
setFeedback({
|
|
314
|
+
type: 'success',
|
|
315
|
+
message: action === 'disconnect' ? 'ChatGPT connection disconnected.' : 'ChatGPT connection verified.',
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
catch (error) {
|
|
319
|
+
const apiError = error;
|
|
320
|
+
setFeedback({
|
|
321
|
+
type: 'error',
|
|
322
|
+
message: apiError.code
|
|
323
|
+
? modelConnectionFailureMessage(apiError.code, apiError.message)
|
|
324
|
+
: apiError.message,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
finally {
|
|
328
|
+
setBusyConnectionId(null);
|
|
329
|
+
}
|
|
330
|
+
}, [context, onConnectionUnavailable]);
|
|
331
|
+
const saveConnectionName = useCallback(async (connection) => {
|
|
332
|
+
const displayName = connectionNameDraft.trim();
|
|
333
|
+
if (!displayName || busyConnectionId)
|
|
334
|
+
return;
|
|
335
|
+
setBusyConnectionId(connection.id);
|
|
336
|
+
setFeedback(null);
|
|
337
|
+
try {
|
|
338
|
+
const next = await renameModelConnection(connection.id, displayName, context);
|
|
339
|
+
setConnections((current) => current.map((item) => item.id === next.id ? next : item));
|
|
340
|
+
setRenamingConnectionId(null);
|
|
341
|
+
setConnectionNameDraft('');
|
|
342
|
+
setFeedback({ type: 'success', message: 'Model account renamed.' });
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
setFeedback({ type: 'error', message: error.message || 'Unable to rename this model account.' });
|
|
346
|
+
}
|
|
347
|
+
finally {
|
|
348
|
+
setBusyConnectionId(null);
|
|
349
|
+
}
|
|
350
|
+
}, [busyConnectionId, connectionNameDraft, context]);
|
|
351
|
+
const connectionLibrary = (_jsxs("div", { className: `${managerStyles.library} ${libraryPortalTarget ? managerStyles.libraryExternal : ''}`.trim(), "aria-label": "Connection list", children: [cloudAccessAvailable && effectiveEligible === true ? (_jsxs("button", { ref: connectButtonRef, type: "button", className: "tf-button-primary tf-button-compact", onClick: () => { void beginAuthorization(); }, disabled: Boolean(busyConnectionId || login), children: [busyConnectionId === 'new' ? _jsx(Loader2, { size: 14, className: styles.spinner }) : _jsx(Plug, { size: 14 }), "Connect ChatGPT"] })) : null, _jsx("div", { className: managerStyles.libraryList, "aria-busy": loading, children: !cloudAccessAvailable ? (_jsxs("div", { className: managerStyles.libraryState, children: [_jsx(CircleSlash, { size: 18 }), _jsx("span", { children: cloudAccessPending ? 'Checking Taskforce Cloud sign-in…' : 'Taskforce Cloud sign-in required.' })] })) : effectiveEligible === false ? (_jsxs("div", { className: managerStyles.libraryState, children: [_jsx(CircleSlash, { size: 18 }), _jsx("span", { children: "Connected accounts are not enabled." })] })) : effectiveEligible === null || loading ? (_jsxs("div", { className: managerStyles.libraryState, children: [_jsx(Loader2, { size: 16, className: styles.spinner }), _jsx("span", { children: "Loading connections\u2026" })] })) : connections.length === 0 ? (_jsxs("div", { className: managerStyles.libraryState, children: [_jsx(Plug, { size: 18 }), _jsx("span", { children: "No connections yet." })] })) : connections.map((connection) => {
|
|
352
|
+
const selected = connection.id === selectedConnectionId;
|
|
353
|
+
return (_jsxs("button", { type: "button", className: `${managerStyles.libraryCard} ${selected ? managerStyles.libraryCardSelected : ''}`.trim(), "aria-pressed": selected, "aria-label": `Open ${connectionAccountLabel(connection)}`, onClick: () => {
|
|
354
|
+
setSelectedConnectionId(connection.id);
|
|
355
|
+
setRenamingConnectionId(null);
|
|
356
|
+
setConnectionNameDraft('');
|
|
357
|
+
}, children: [_jsx("span", { className: `${managerStyles.libraryCardIcon} ${managerStyles.libraryCardLogo}`.trim(), "aria-hidden": "true", children: _jsx("img", { src: CHATGPT_LOGO_URL, alt: "" }) }), _jsxs("span", { className: managerStyles.libraryCardBody, children: [_jsx("strong", { children: connectionAccountLabel(connection) }), _jsxs("span", { children: ["OpenAI \u00B7 ", connection.displayMetadata.planLabel || 'ChatGPT'] })] }), _jsx("span", { className: connectionStatusClass(connection.lifecycleStatus), children: connectionStatusLabel(connection.lifecycleStatus) })] }, connection.id));
|
|
358
|
+
}) })] }));
|
|
359
|
+
let mainContent;
|
|
360
|
+
if (!cloudAccessAvailable) {
|
|
361
|
+
mainContent = (_jsxs("div", { className: styles.taskforceModelConnectionsEmpty, children: [_jsx(CircleSlash, { size: 28 }), _jsx("strong", { children: cloudAccessPending ? 'Checking Taskforce Cloud sign-in' : cloudAuthConfigured ? 'Taskforce Cloud sign-in required' : 'Taskforce Cloud connection required' }), _jsx("span", { children: cloudAccessPending
|
|
362
|
+
? 'Connection management will be available after your sign-in status is resolved.'
|
|
363
|
+
: cloudAuthConfigured
|
|
364
|
+
? 'Sign in to Taskforce Cloud to manage connected model accounts from this local runtime.'
|
|
365
|
+
: 'Connect this local runtime to a Taskforce Cloud environment to manage connected model accounts.' })] }));
|
|
366
|
+
}
|
|
367
|
+
else if (effectiveEligible === false) {
|
|
368
|
+
mainContent = (_jsxs("div", { className: styles.taskforceModelConnectionsEmpty, children: [_jsx(CircleSlash, { size: 28 }), _jsx("strong", { children: "Connected accounts are not enabled" }), _jsx("span", { children: "Contact a Taskforce administrator to enable subscription-backed models for this account." })] }));
|
|
369
|
+
}
|
|
370
|
+
else if (effectiveEligible === null) {
|
|
371
|
+
mainContent = feedback?.type === 'error' ? (_jsxs("div", { className: styles.taskforceAgentTestError, role: "alert", children: [_jsx(AlertTriangle, { size: 14 }), _jsx("span", { children: feedback.message }), _jsxs("button", { type: "button", className: "tf-button-secondary tf-button-compact", onClick: () => { void loadConnections(); }, disabled: loading, children: [_jsx(RefreshCw, { size: 14 }), " Retry"] })] })) : (_jsxs("div", { className: styles.taskforceModelConnectionsLoading, children: [_jsx(Loader2, { size: 18, className: styles.spinner }), " Checking connection access"] }));
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
const connection = selectedConnection;
|
|
375
|
+
const busy = connection ? busyConnectionId === connection.id : false;
|
|
376
|
+
const canAuthorize = connection?.lifecycleStatus === 'pending'
|
|
377
|
+
|| connection?.lifecycleStatus === 'reconnect_required'
|
|
378
|
+
|| connection?.lifecycleStatus === 'disconnected';
|
|
379
|
+
mainContent = (_jsxs(_Fragment, { children: [_jsx("header", { className: styles.taskforceModelConnectionsHeader, children: _jsxs("div", { children: [_jsx("span", { className: "tf-heading-section", children: login ? 'Add connection' : connection ? 'Connection details' : 'Connections' }), _jsx("p", { className: "tf-text-secondary", children: "Authorize accounts used by your Taskforce Agents in this environment." })] }) }), feedback ? (_jsxs("div", { className: feedback.type === 'error' ? styles.taskforceAgentTestError : styles.taskforceAgentTestNotice, role: feedback.type === 'error' ? 'alert' : 'status', children: [feedback.type === 'error' ? _jsx(AlertTriangle, { size: 14 }) : _jsx(Check, { size: 14 }), _jsx("span", { children: feedback.message }), feedback.returnToAgent ? (_jsx("button", { type: "button", className: "tf-button-secondary tf-button-compact", onClick: onReturnToAgent, children: "Return to Agent" })) : null] })) : null, login ? (_jsxs("section", { className: `${styles.taskforceModelConnectionCard} ${styles.taskforceModelConnectionLogin}`, children: [_jsxs("div", { className: styles.taskforceModelConnectionCardHeader, children: [_jsxs("div", { children: [_jsx("strong", { children: "Authorize ChatGPT" }), _jsx("span", { children: "Enter this one-time code in the browser window." })] }), _jsxs("span", { className: "tf-chip-warning", children: [_jsx(Loader2, { size: 12, className: styles.spinner }), " Waiting"] })] }), _jsxs("div", { className: styles.taskforceModelConnectionCodeRow, children: [_jsx("code", { children: login.userCode }), _jsx("button", { type: "button", className: "tf-control-icon", onClick: () => { void copyCode(); }, title: copied ? 'Authorization code copied' : 'Copy authorization code', "aria-label": copied ? 'Authorization code copied' : 'Copy authorization code', children: copied ? _jsx(Check, { size: 15 }) : _jsx(Copy, { size: 15 }) }), _jsx("span", { role: "status", "aria-live": "polite", children: copied ? 'Code copied.' : '' }), _jsxs("a", { className: "tf-button-secondary tf-button-compact", href: login.verificationUrl, target: "_blank", rel: "noreferrer", children: [_jsx(ExternalLink, { size: 14 }), " Open ChatGPT"] }), _jsxs("button", { type: "button", className: "tf-button-ghost tf-button-compact", onClick: () => { void cancelLogin(); }, children: [_jsx(X, { size: 14 }), " Cancel"] })] })] })) : loading ? (_jsxs("div", { className: styles.taskforceModelConnectionsLoading, children: [_jsx(Loader2, { size: 18, className: styles.spinner }), " Loading connections"] })) : !connection ? (_jsxs("div", { className: styles.taskforceModelConnectionsEmpty, children: [_jsx(Plug, { size: 28 }), _jsx("strong", { children: connections.length === 0 ? 'No connected accounts' : 'Select a connection' }), _jsx("span", { children: connections.length === 0
|
|
380
|
+
? 'Connect ChatGPT to run eligible Codex Agents with your subscription.'
|
|
381
|
+
: 'Choose an account from the Connection Library to view and manage it.' })] })) : (_jsxs("section", { className: styles.taskforceModelConnectionCard, children: [_jsxs("div", { className: styles.taskforceModelConnectionCardHeader, children: [_jsxs("div", { className: styles.taskforceModelConnectionIdentity, children: [_jsx("span", { className: styles.taskforceModelConnectionLogo, children: _jsx("img", { src: CHATGPT_LOGO_URL, alt: "" }) }), _jsxs("div", { className: styles.taskforceModelConnectionIdentityText, children: [renamingConnectionId === connection.id ? (_jsxs("div", { className: styles.taskforceModelConnectionNameEditor, children: [_jsx("input", { className: styles.input, value: connectionNameDraft, onChange: (event) => setConnectionNameDraft(event.target.value), "aria-label": "Model account name", maxLength: 80, autoFocus: true }), _jsx("button", { type: "button", className: "tf-control-icon", "aria-label": "Save model account name", title: "Save name", onClick: () => { void saveConnectionName(connection); }, disabled: busy || !connectionNameDraft.trim(), children: busy ? _jsx(Loader2, { size: 14, className: styles.spinner }) : _jsx(Check, { size: 14 }) }), _jsx("button", { type: "button", className: "tf-control-icon", "aria-label": "Cancel model account rename", title: "Cancel", onClick: () => {
|
|
382
|
+
setRenamingConnectionId(null);
|
|
383
|
+
setConnectionNameDraft('');
|
|
384
|
+
}, disabled: busy, children: _jsx(X, { size: 14 }) })] })) : (_jsxs("div", { className: styles.taskforceModelConnectionNameRow, children: [_jsx("strong", { children: connectionAccountLabel(connection) }), _jsx("button", { type: "button", className: "tf-control-icon", "aria-label": `Rename ${connectionAccountLabel(connection)}`, title: "Rename model account", onClick: () => {
|
|
385
|
+
setRenamingConnectionId(connection.id);
|
|
386
|
+
setConnectionNameDraft(connectionAccountLabel(connection));
|
|
387
|
+
}, children: _jsx(Pencil, { size: 13 }) })] })), _jsx("span", { children: "OpenAI \u00B7 ChatGPT/Codex subscription" })] })] }), _jsx("span", { className: connectionStatusClass(connection.lifecycleStatus), children: connectionStatusLabel(connection.lifecycleStatus) })] }), _jsxs("div", { className: styles.taskforceModelConnectionMeta, children: [_jsx("span", { children: connection.displayMetadata.planLabel || 'Subscription plan' }), _jsx("span", { children: connectionLastChecked(connection) })] }), connection.failureCode ? (_jsx("span", { className: "tf-text-warning", children: modelConnectionFailureMessage(connection.failureCode) })) : null, _jsxs("div", { className: styles.taskforceModelConnectionActions, children: [canAuthorize ? (_jsxs("button", { type: "button", className: "tf-button-primary tf-button-compact", onClick: () => { void beginAuthorization(connection); }, disabled: Boolean(busyConnectionId || login), children: [busy ? _jsx(Loader2, { size: 14, className: styles.spinner }) : _jsx(RotateCcw, { size: 14 }), connection.lifecycleStatus === 'pending' ? 'Authorize' : 'Reconnect'] })) : null, connection.lifecycleStatus === 'active' ? (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", className: "tf-button-secondary tf-button-compact", onClick: () => { void runConnectionAction(connection, 'verify'); }, disabled: busy, children: [_jsx(Check, { size: 14 }), " Verify"] }), _jsxs("button", { type: "button", className: "tf-button-ghost tf-button-compact", onClick: () => { void runConnectionAction(connection, 'refresh'); }, disabled: busy, title: "Refresh ChatGPT account status", children: [_jsx(RefreshCw, { size: 14 }), " Refresh"] }), _jsxs("button", { type: "button", className: "tf-button-ghost tf-button-compact", onClick: () => { void runConnectionAction(connection, 'disconnect'); }, disabled: busy, children: [_jsx(LogOut, { size: 14 }), " Disconnect"] })] })) : null, (connection.lifecycleStatus === 'pending'
|
|
388
|
+
|| connection.lifecycleStatus === 'reconnect_required'
|
|
389
|
+
|| connection.lifecycleStatus === 'disconnected'
|
|
390
|
+
|| connection.lifecycleStatus === 'revoked') ? (_jsxs("button", { type: "button", className: "tf-button-destructive tf-button-compact", onClick: () => { void runConnectionAction(connection, 'remove'); }, disabled: busy, children: [_jsx(Trash2, { size: 14 }), " Remove"] })) : null] })] }))] }));
|
|
391
|
+
}
|
|
392
|
+
return (_jsxs("div", { className: `${styles.taskforceModelConnectionsRoot} ${libraryPortalTarget ? styles.taskforceModelConnectionsRootExternalLibrary : ''}`.trim(), children: [libraryPortalTarget ? createPortal(connectionLibrary, libraryPortalTarget) : connectionLibrary, _jsx("div", { className: styles.taskforceModelConnectionsWorkspace, children: mainContent })] }));
|
|
393
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export type ModelConnectionLifecycleStatus = 'pending' | 'active' | 'reconnect_required' | 'revoked' | 'disconnected';
|
|
2
|
+
export type ModelConnection = {
|
|
3
|
+
id: string;
|
|
4
|
+
providerKey: string;
|
|
5
|
+
authenticationType: string;
|
|
6
|
+
lifecycleStatus: ModelConnectionLifecycleStatus;
|
|
7
|
+
displayMetadata: {
|
|
8
|
+
displayName?: string;
|
|
9
|
+
accountEmail?: string;
|
|
10
|
+
accountLabel?: string;
|
|
11
|
+
planLabel?: string;
|
|
12
|
+
};
|
|
13
|
+
lastVerifiedAt: string | null;
|
|
14
|
+
lastRefreshedAt: string | null;
|
|
15
|
+
failureCode: string | null;
|
|
16
|
+
createdAt: string;
|
|
17
|
+
updatedAt: string;
|
|
18
|
+
};
|
|
19
|
+
export type DeviceCodeLoginSession = {
|
|
20
|
+
id: string;
|
|
21
|
+
connectionId: string;
|
|
22
|
+
status: 'pending' | 'active' | 'failed' | 'cancelled' | 'expired';
|
|
23
|
+
userCode: string;
|
|
24
|
+
verificationUrl: string;
|
|
25
|
+
expiresAt: string;
|
|
26
|
+
failureCode?: string;
|
|
27
|
+
};
|
|
28
|
+
export type AgentConnectionBinding = {
|
|
29
|
+
bound: boolean;
|
|
30
|
+
available: boolean;
|
|
31
|
+
providerKey?: string;
|
|
32
|
+
modelSource?: string;
|
|
33
|
+
ownerIsCaller?: boolean;
|
|
34
|
+
connectionId?: string;
|
|
35
|
+
reasonCode?: string;
|
|
36
|
+
};
|
|
37
|
+
export type ModelConnectionsSnapshot = {
|
|
38
|
+
eligible: boolean;
|
|
39
|
+
connections: ModelConnection[];
|
|
40
|
+
};
|
|
41
|
+
export declare class ModelConnectionsApiError extends Error {
|
|
42
|
+
readonly code?: string | undefined;
|
|
43
|
+
readonly status?: number | undefined;
|
|
44
|
+
constructor(message: string, code?: string | undefined, status?: number | undefined);
|
|
45
|
+
}
|
|
46
|
+
export type ModelConnectionsApiContext = {
|
|
47
|
+
apiBaseUrl?: string;
|
|
48
|
+
workspaceId?: string;
|
|
49
|
+
resolveApiUrl?: (path: string) => string;
|
|
50
|
+
};
|
|
51
|
+
export declare function listModelConnections(context: ModelConnectionsApiContext): Promise<ModelConnection[]>;
|
|
52
|
+
export declare function loadModelConnectionsSnapshot(context: ModelConnectionsApiContext): Promise<ModelConnectionsSnapshot>;
|
|
53
|
+
export declare function createOpenAiCodexConnection(context: ModelConnectionsApiContext): Promise<ModelConnection>;
|
|
54
|
+
export declare function startDeviceCodeLogin(connectionId: string, context: ModelConnectionsApiContext): Promise<DeviceCodeLoginSession>;
|
|
55
|
+
export declare function getDeviceCodeLogin(connectionId: string, sessionId: string, context: ModelConnectionsApiContext): Promise<DeviceCodeLoginSession>;
|
|
56
|
+
export declare function cancelDeviceCodeLogin(connectionId: string, sessionId: string, context: ModelConnectionsApiContext): Promise<DeviceCodeLoginSession>;
|
|
57
|
+
export declare const verifyModelConnection: (connectionId: string, context: ModelConnectionsApiContext) => Promise<ModelConnection>;
|
|
58
|
+
export declare const refreshModelConnection: (connectionId: string, context: ModelConnectionsApiContext) => Promise<ModelConnection>;
|
|
59
|
+
export declare const disconnectModelConnection: (connectionId: string, context: ModelConnectionsApiContext) => Promise<ModelConnection>;
|
|
60
|
+
export declare function renameModelConnection(connectionId: string, displayName: string, context: ModelConnectionsApiContext): Promise<ModelConnection>;
|
|
61
|
+
export declare function removeModelConnection(connectionId: string, context: ModelConnectionsApiContext): Promise<void>;
|
|
62
|
+
export declare function inspectAgentConnectionBinding(agentId: string, context: ModelConnectionsApiContext): Promise<AgentConnectionBinding>;
|
|
63
|
+
export declare function bindAgentConnection(agentId: string, connectionId: string, context: ModelConnectionsApiContext): Promise<AgentConnectionBinding>;
|
|
64
|
+
export declare function clearAgentConnectionBinding(agentId: string, context: ModelConnectionsApiContext): Promise<void>;
|
|
65
|
+
export declare function modelConnectionFailureMessage(code: string | null | undefined, fallback?: string): string;
|