@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,30 @@
|
|
|
1
|
+
export class OwnerScopedModelConnectionGateway {
|
|
2
|
+
connectionService;
|
|
3
|
+
ownerUserId;
|
|
4
|
+
connectionId;
|
|
5
|
+
createGateway;
|
|
6
|
+
constructor(connectionService, ownerUserId, connectionId, createGateway) {
|
|
7
|
+
this.connectionService = connectionService;
|
|
8
|
+
this.ownerUserId = ownerUserId;
|
|
9
|
+
this.connectionId = connectionId;
|
|
10
|
+
this.createGateway = createGateway;
|
|
11
|
+
}
|
|
12
|
+
generate(input) {
|
|
13
|
+
return this.connectionService.withConnectionLease({
|
|
14
|
+
ownerUserId: this.ownerUserId,
|
|
15
|
+
connectionId: this.connectionId,
|
|
16
|
+
operation: 'invoke',
|
|
17
|
+
}, async (context) => {
|
|
18
|
+
const result = await this.createGateway(context).generate(input);
|
|
19
|
+
return {
|
|
20
|
+
...result,
|
|
21
|
+
sourceMetadata: {
|
|
22
|
+
modelSource: 'subscription_dev',
|
|
23
|
+
connectionScope: 'personal',
|
|
24
|
+
providerKey: context.connection.providerKey,
|
|
25
|
+
billable: false,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { TaskforceAgentStore } from '../storage/taskforceAgentStore.js';
|
|
2
|
+
import type { ModelProviderConnectionRecord, ModelProviderConnectionStore } from '../storage/modelProviderConnectionStore.js';
|
|
3
|
+
import type { TaskforceAgentConnectionBindingRecord, TaskforceAgentConnectionBindingStore } from '../storage/taskforceAgentConnectionBindingStore.js';
|
|
4
|
+
import type { ModelProviderConnectionService } from './modelProviderConnectionService.js';
|
|
5
|
+
export declare class TaskforceAgentConnectionBindingError extends Error {
|
|
6
|
+
readonly statusCode: number;
|
|
7
|
+
readonly code: string;
|
|
8
|
+
constructor(message: string, statusCode: number, code: string);
|
|
9
|
+
}
|
|
10
|
+
type AgentStore = Pick<TaskforceAgentStore, 'get'>;
|
|
11
|
+
type ConnectionStore = Pick<ModelProviderConnectionStore, 'getOwned'>;
|
|
12
|
+
type BindingStore = Pick<TaskforceAgentConnectionBindingStore, 'get' | 'bind' | 'clear'>;
|
|
13
|
+
type ConnectionRuntime = Pick<ModelProviderConnectionService, 'assertReady' | 'withConnectionLease'>;
|
|
14
|
+
export interface ResolvedTaskforceAgentConnectionBinding {
|
|
15
|
+
binding: TaskforceAgentConnectionBindingRecord;
|
|
16
|
+
connection: ModelProviderConnectionRecord;
|
|
17
|
+
}
|
|
18
|
+
export interface PublicTaskforceAgentConnectionBinding {
|
|
19
|
+
bound: boolean;
|
|
20
|
+
available: boolean;
|
|
21
|
+
providerKey?: string;
|
|
22
|
+
modelSource?: string;
|
|
23
|
+
ownerIsCaller?: boolean;
|
|
24
|
+
connectionId?: string;
|
|
25
|
+
reasonCode?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare class TaskforceAgentConnectionBindingService {
|
|
28
|
+
private readonly bindings;
|
|
29
|
+
private readonly agents;
|
|
30
|
+
private readonly connections;
|
|
31
|
+
private readonly connectionRuntime;
|
|
32
|
+
private readonly hasGrant;
|
|
33
|
+
constructor(bindings: BindingStore, agents: AgentStore, connections: ConnectionStore, connectionRuntime: ConnectionRuntime, hasGrant: (userId: string) => boolean);
|
|
34
|
+
inspect(input: {
|
|
35
|
+
workspaceId: string;
|
|
36
|
+
agentId: string;
|
|
37
|
+
callerUserId: string;
|
|
38
|
+
}): PublicTaskforceAgentConnectionBinding;
|
|
39
|
+
bind(input: {
|
|
40
|
+
workspaceId: string;
|
|
41
|
+
agentId: string;
|
|
42
|
+
connectionId: string;
|
|
43
|
+
actorUserId: string;
|
|
44
|
+
}): Promise<TaskforceAgentConnectionBindingRecord>;
|
|
45
|
+
clear(input: {
|
|
46
|
+
workspaceId: string;
|
|
47
|
+
agentId: string;
|
|
48
|
+
actorUserId: string;
|
|
49
|
+
}): boolean;
|
|
50
|
+
resolveSaved(input: {
|
|
51
|
+
workspaceId: string;
|
|
52
|
+
agentId: string;
|
|
53
|
+
callerUserId: string;
|
|
54
|
+
}): ResolvedTaskforceAgentConnectionBinding;
|
|
55
|
+
resolveDraft(input: {
|
|
56
|
+
callerUserId: string;
|
|
57
|
+
connectionId: string;
|
|
58
|
+
providerKey: string;
|
|
59
|
+
}): ModelProviderConnectionRecord;
|
|
60
|
+
private requireBindableAgentSelection;
|
|
61
|
+
private requireOwnedActiveConnection;
|
|
62
|
+
private requireOwnedReadyConnection;
|
|
63
|
+
private assertCompatibleConnection;
|
|
64
|
+
private assertGranted;
|
|
65
|
+
}
|
|
66
|
+
export {};
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
export class TaskforceAgentConnectionBindingError extends Error {
|
|
2
|
+
statusCode;
|
|
3
|
+
code;
|
|
4
|
+
constructor(message, statusCode, code) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.statusCode = statusCode;
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.name = 'TaskforceAgentConnectionBindingError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const SUBSCRIPTION_AUTHENTICATION_TYPES = {
|
|
12
|
+
openai: 'chatgpt_device_code',
|
|
13
|
+
};
|
|
14
|
+
function requireIdentity(value) {
|
|
15
|
+
const normalized = String(value || '').trim();
|
|
16
|
+
if (!normalized) {
|
|
17
|
+
throw new TaskforceAgentConnectionBindingError('Authentication is required.', 401, 'AUTH_REQUIRED');
|
|
18
|
+
}
|
|
19
|
+
return normalized;
|
|
20
|
+
}
|
|
21
|
+
export class TaskforceAgentConnectionBindingService {
|
|
22
|
+
bindings;
|
|
23
|
+
agents;
|
|
24
|
+
connections;
|
|
25
|
+
connectionRuntime;
|
|
26
|
+
hasGrant;
|
|
27
|
+
constructor(bindings, agents, connections, connectionRuntime, hasGrant) {
|
|
28
|
+
this.bindings = bindings;
|
|
29
|
+
this.agents = agents;
|
|
30
|
+
this.connections = connections;
|
|
31
|
+
this.connectionRuntime = connectionRuntime;
|
|
32
|
+
this.hasGrant = hasGrant;
|
|
33
|
+
}
|
|
34
|
+
inspect(input) {
|
|
35
|
+
const callerUserId = requireIdentity(input.callerUserId);
|
|
36
|
+
const agent = this.agents.get(input.workspaceId, input.agentId);
|
|
37
|
+
if (!agent || agent.deletedAt) {
|
|
38
|
+
throw new TaskforceAgentConnectionBindingError('Taskforce Agent was not found.', 404, 'TASKFORCE_AGENT_NOT_FOUND');
|
|
39
|
+
}
|
|
40
|
+
const binding = this.bindings.get(input.workspaceId, input.agentId);
|
|
41
|
+
if (!binding)
|
|
42
|
+
return { bound: false, available: false, reasonCode: 'MODEL_CONNECTION_REQUIRED' };
|
|
43
|
+
const selection = agent.definition?.model;
|
|
44
|
+
const ownerIsCaller = binding.ownerUserId === callerUserId;
|
|
45
|
+
const callerGranted = this.hasGrant(callerUserId);
|
|
46
|
+
const ownerGranted = this.hasGrant(binding.ownerUserId);
|
|
47
|
+
let connectionReady = false;
|
|
48
|
+
if (callerGranted && ownerGranted) {
|
|
49
|
+
try {
|
|
50
|
+
const connection = this.requireOwnedReadyConnection(binding.ownerUserId, binding.connectionId, binding.providerKey);
|
|
51
|
+
connectionReady = Boolean(connection);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
connectionReady = false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const available = Boolean(connectionReady
|
|
58
|
+
&& selection?.providerKey === binding.providerKey
|
|
59
|
+
&& selection?.modelSource === binding.modelSource);
|
|
60
|
+
return {
|
|
61
|
+
bound: true,
|
|
62
|
+
available,
|
|
63
|
+
providerKey: binding.providerKey,
|
|
64
|
+
modelSource: binding.modelSource,
|
|
65
|
+
ownerIsCaller,
|
|
66
|
+
...(ownerIsCaller ? { connectionId: binding.connectionId } : {}),
|
|
67
|
+
...(available ? {} : { reasonCode: 'MODEL_CONNECTION_UNAVAILABLE' }),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
async bind(input) {
|
|
71
|
+
const actorUserId = requireIdentity(input.actorUserId);
|
|
72
|
+
this.assertGranted(actorUserId);
|
|
73
|
+
const selection = this.requireBindableAgentSelection(input.workspaceId, input.agentId);
|
|
74
|
+
const existing = this.bindings.get(input.workspaceId, input.agentId);
|
|
75
|
+
if (existing && existing.ownerUserId !== actorUserId) {
|
|
76
|
+
throw new TaskforceAgentConnectionBindingError('Only the current connection owner can replace this Agent binding.', 403, 'AGENT_CONNECTION_OWNER_REQUIRED');
|
|
77
|
+
}
|
|
78
|
+
return this.connectionRuntime.withConnectionLease({
|
|
79
|
+
ownerUserId: actorUserId,
|
|
80
|
+
connectionId: String(input.connectionId || '').trim(),
|
|
81
|
+
operation: 'invoke',
|
|
82
|
+
}, async (context) => {
|
|
83
|
+
this.assertCompatibleConnection(context.connection, selection.providerKey);
|
|
84
|
+
const binding = this.bindings.bind({
|
|
85
|
+
workspaceId: input.workspaceId,
|
|
86
|
+
agentId: input.agentId,
|
|
87
|
+
connectionId: context.connection.id,
|
|
88
|
+
ownerUserId: actorUserId,
|
|
89
|
+
providerKey: selection.providerKey,
|
|
90
|
+
modelSource: selection.modelSource,
|
|
91
|
+
actorUserId,
|
|
92
|
+
});
|
|
93
|
+
if (!binding) {
|
|
94
|
+
throw new TaskforceAgentConnectionBindingError('Only the current connection owner can replace this Agent binding.', 403, 'AGENT_CONNECTION_OWNER_REQUIRED');
|
|
95
|
+
}
|
|
96
|
+
return binding;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
clear(input) {
|
|
100
|
+
const actorUserId = requireIdentity(input.actorUserId);
|
|
101
|
+
const binding = this.bindings.get(input.workspaceId, input.agentId);
|
|
102
|
+
if (!binding)
|
|
103
|
+
return false;
|
|
104
|
+
if (binding.ownerUserId !== actorUserId) {
|
|
105
|
+
throw new TaskforceAgentConnectionBindingError('Only the connection owner can clear this Agent binding.', 403, 'AGENT_CONNECTION_OWNER_REQUIRED');
|
|
106
|
+
}
|
|
107
|
+
const cleared = this.bindings.clear(input.workspaceId, input.agentId, actorUserId);
|
|
108
|
+
if (cleared)
|
|
109
|
+
return true;
|
|
110
|
+
const current = this.bindings.get(input.workspaceId, input.agentId);
|
|
111
|
+
if (current && current.ownerUserId !== actorUserId) {
|
|
112
|
+
throw new TaskforceAgentConnectionBindingError('Only the connection owner can clear this Agent binding.', 403, 'AGENT_CONNECTION_OWNER_REQUIRED');
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
resolveSaved(input) {
|
|
117
|
+
const callerUserId = requireIdentity(input.callerUserId);
|
|
118
|
+
this.assertGranted(callerUserId);
|
|
119
|
+
const selection = this.requireBindableAgentSelection(input.workspaceId, input.agentId);
|
|
120
|
+
const binding = this.bindings.get(input.workspaceId, input.agentId);
|
|
121
|
+
if (!binding) {
|
|
122
|
+
throw new TaskforceAgentConnectionBindingError('Connect this Agent to an eligible model account before running it.', 409, 'AGENT_MODEL_CONNECTION_REQUIRED');
|
|
123
|
+
}
|
|
124
|
+
this.assertGranted(binding.ownerUserId);
|
|
125
|
+
if (binding.providerKey !== selection.providerKey || binding.modelSource !== selection.modelSource) {
|
|
126
|
+
throw new TaskforceAgentConnectionBindingError('The saved Agent model selection no longer matches its local connection.', 409, 'AGENT_MODEL_CONNECTION_MISMATCH');
|
|
127
|
+
}
|
|
128
|
+
const connection = this.requireOwnedReadyConnection(binding.ownerUserId, binding.connectionId, binding.providerKey);
|
|
129
|
+
return { binding, connection };
|
|
130
|
+
}
|
|
131
|
+
resolveDraft(input) {
|
|
132
|
+
const callerUserId = requireIdentity(input.callerUserId);
|
|
133
|
+
this.assertGranted(callerUserId);
|
|
134
|
+
return this.requireOwnedReadyConnection(callerUserId, input.connectionId, input.providerKey);
|
|
135
|
+
}
|
|
136
|
+
requireBindableAgentSelection(workspaceId, agentId) {
|
|
137
|
+
const agent = this.agents.get(workspaceId, agentId);
|
|
138
|
+
if (!agent || agent.deletedAt) {
|
|
139
|
+
throw new TaskforceAgentConnectionBindingError('Taskforce Agent was not found.', 404, 'TASKFORCE_AGENT_NOT_FOUND');
|
|
140
|
+
}
|
|
141
|
+
const model = agent.definition?.model;
|
|
142
|
+
if (!model
|
|
143
|
+
|| model.modelSource !== 'subscription_dev'
|
|
144
|
+
|| (model.connectionScope !== 'personal' && model.connectionScope !== 'local_dev')) {
|
|
145
|
+
throw new TaskforceAgentConnectionBindingError('This Agent does not use a personal subscription model connection.', 409, 'AGENT_MODEL_CONNECTION_NOT_APPLICABLE');
|
|
146
|
+
}
|
|
147
|
+
return model;
|
|
148
|
+
}
|
|
149
|
+
requireOwnedActiveConnection(ownerUserId, connectionIdRaw, providerKey) {
|
|
150
|
+
const connectionId = String(connectionIdRaw || '').trim();
|
|
151
|
+
const connection = connectionId
|
|
152
|
+
? this.connections.getOwned(ownerUserId, connectionId)
|
|
153
|
+
: null;
|
|
154
|
+
if (!connection) {
|
|
155
|
+
throw new TaskforceAgentConnectionBindingError('Model connection was not found.', 404, 'MODEL_CONNECTION_NOT_FOUND');
|
|
156
|
+
}
|
|
157
|
+
if (connection.providerKey !== providerKey) {
|
|
158
|
+
throw new TaskforceAgentConnectionBindingError('The model connection does not match the selected provider.', 409, 'MODEL_CONNECTION_PROVIDER_MISMATCH');
|
|
159
|
+
}
|
|
160
|
+
if (connection.lifecycleStatus !== 'active') {
|
|
161
|
+
throw new TaskforceAgentConnectionBindingError('The model connection is not active.', 409, 'MODEL_CONNECTION_INACTIVE');
|
|
162
|
+
}
|
|
163
|
+
this.assertCompatibleConnection(connection, providerKey);
|
|
164
|
+
return connection;
|
|
165
|
+
}
|
|
166
|
+
requireOwnedReadyConnection(ownerUserId, connectionId, providerKey) {
|
|
167
|
+
this.requireOwnedActiveConnection(ownerUserId, connectionId, providerKey);
|
|
168
|
+
const connection = this.connectionRuntime.assertReady(ownerUserId, connectionId);
|
|
169
|
+
this.assertCompatibleConnection(connection, providerKey);
|
|
170
|
+
return connection;
|
|
171
|
+
}
|
|
172
|
+
assertCompatibleConnection(connection, providerKey) {
|
|
173
|
+
const expectedAuthenticationType = SUBSCRIPTION_AUTHENTICATION_TYPES[providerKey];
|
|
174
|
+
if (!expectedAuthenticationType
|
|
175
|
+
|| connection.providerKey !== providerKey
|
|
176
|
+
|| connection.authenticationType !== expectedAuthenticationType) {
|
|
177
|
+
throw new TaskforceAgentConnectionBindingError('The model connection is not compatible with this subscription model.', 409, 'MODEL_CONNECTION_AUTHENTICATION_MISMATCH');
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
assertGranted(userId) {
|
|
181
|
+
if (this.hasGrant(userId))
|
|
182
|
+
return;
|
|
183
|
+
throw new TaskforceAgentConnectionBindingError('Subscription-backed models are not enabled for this account.', 403, 'SUBSCRIPTION_MODEL_ACCESS_REQUIRED');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -57,7 +57,7 @@ export declare function isTaskforceAgentMutationToolName(name: string): boolean;
|
|
|
57
57
|
export declare function taskforceAgentMutationCallKey(name: string, argumentsValue: Record<string, unknown>): string | null;
|
|
58
58
|
export declare function taskforceAgentMcpRequestId(call: TaskforceAgentMcpToolCall): string;
|
|
59
59
|
declare const MANAGED_AGENT_CAPABILITY_TOOLS: Readonly<{
|
|
60
|
-
readonly tasks: readonly ["add_comment", "add_task_checklist_item", "complete_workflow_step", "get_schedule_board", "get_stats", "get_task", "get_task_attachments", "get_task_checklist", "get_task_workflow", "list_task_relationships", "list_tasks", "replace_task_checklist", "search_tasks"];
|
|
60
|
+
readonly tasks: readonly ["add_comment", "add_task_checklist_item", "complete_workflow_step", "get_schedule_board", "get_stats", "get_task", "get_task_attachments", "get_task_checklist", "get_task_workflow", "list_task_relationships", "list_tasks", "replace_task_checklist", "search_tasks", "update_task_checklist_item"];
|
|
61
61
|
readonly planning: readonly ["add_initiative_comment", "add_workstream_comment", "get_initiative", "get_workstream", "list_initiatives", "list_workstreams"];
|
|
62
62
|
readonly documents: readonly ["get_document", "get_document_reviews", "search_documents"];
|
|
63
63
|
readonly images: readonly ["get_image", "get_image_annotations", "search_images"];
|
|
@@ -43,6 +43,7 @@ export function taskforceAgentMcpRequestId(call) {
|
|
|
43
43
|
const TASK_SCOPED_MUTATION_TOOL_NAMES = new Set([
|
|
44
44
|
'add_comment',
|
|
45
45
|
'add_task_checklist_item',
|
|
46
|
+
'update_task_checklist_item',
|
|
46
47
|
'replace_task_checklist',
|
|
47
48
|
'complete_workflow_step',
|
|
48
49
|
]);
|
|
@@ -61,6 +62,7 @@ const MANAGED_AGENT_CAPABILITY_TOOLS = Object.freeze({
|
|
|
61
62
|
'list_tasks',
|
|
62
63
|
'replace_task_checklist',
|
|
63
64
|
'search_tasks',
|
|
65
|
+
'update_task_checklist_item',
|
|
64
66
|
],
|
|
65
67
|
planning: [
|
|
66
68
|
'add_initiative_comment',
|
|
@@ -129,21 +131,8 @@ export function resolveManagedAgentMcpToolNames(toolPolicy, profile = MCP_MANAGE
|
|
|
129
131
|
}
|
|
130
132
|
return Array.from(effective).sort((left, right) => left.localeCompare(right));
|
|
131
133
|
}
|
|
132
|
-
function getRuntimeHandler(runtime, method) {
|
|
133
|
-
const handler = runtime.server._requestHandlers?.get(method);
|
|
134
|
-
if (typeof handler !== 'function') {
|
|
135
|
-
throw new Error(`Taskforce MCP ${method} handler is unavailable.`);
|
|
136
|
-
}
|
|
137
|
-
return handler;
|
|
138
|
-
}
|
|
139
134
|
async function listRuntimeTools(runtime) {
|
|
140
|
-
const
|
|
141
|
-
const result = await handler({
|
|
142
|
-
jsonrpc: '2.0',
|
|
143
|
-
id: 'taskforce-agent-tools-list',
|
|
144
|
-
method: 'tools/list',
|
|
145
|
-
params: {},
|
|
146
|
-
}, {});
|
|
135
|
+
const result = await runtime.listTools();
|
|
147
136
|
return Array.isArray(result?.tools) ? result.tools : [];
|
|
148
137
|
}
|
|
149
138
|
function compactText(value, maxLength) {
|
|
@@ -208,7 +197,7 @@ function buildToolInstructions(baseSystem, tools, allowedMutationTaskId, readOnl
|
|
|
208
197
|
? 'Allowed writes: task comments, checklist changes, and completion of the current owned workflow step. Use complete_workflow_step only after finishing that step.'
|
|
209
198
|
: 'Allowed writes: task comments and checklist changes.',
|
|
210
199
|
...(canCompleteWorkflow && !readOnly ? [
|
|
211
|
-
'For workflow-step work, call get_task_workflow before acting. If requiresCommentEvidence is true, call add_comment and
|
|
200
|
+
'For workflow-step work, call get_task_workflow before acting. Reuse its completionCall arguments exactly; never invent or reuse workflow IDs. If requiresCommentEvidence is true, call add_comment and add its returned comment.id as evidenceCommentId. After all required work succeeds, call complete_workflow_step before answering. A comment or other task mutation does not complete the workflow step.',
|
|
212
201
|
] : []),
|
|
213
202
|
...(taskScope ? [`This run is task-scoped to ${taskScope}. Mutating Taskforce tools must target only this task.`] : []),
|
|
214
203
|
'To use a Taskforce tool, respond with only one JSON object and no prose:',
|
|
@@ -495,7 +484,6 @@ export async function prepareTaskforceAgentMcpBridge(input, dependencies = {}) {
|
|
|
495
484
|
if (tools.length === 0)
|
|
496
485
|
return null;
|
|
497
486
|
const availableToolNames = new Set(tools.map((tool) => tool.name));
|
|
498
|
-
const callTool = getRuntimeHandler(runtime, 'tools/call');
|
|
499
487
|
return {
|
|
500
488
|
system: buildToolInstructions(input.system, tools, input.allowedMutationTaskId, input.readOnly),
|
|
501
489
|
availableToolNames: Array.from(availableToolNames),
|
|
@@ -509,14 +497,9 @@ export async function prepareTaskforceAgentMcpBridge(input, dependencies = {}) {
|
|
|
509
497
|
if (scopeFailure)
|
|
510
498
|
return scopeFailure;
|
|
511
499
|
const effectiveCall = normalizeManagedAgentMcpToolCall(call);
|
|
512
|
-
const result = await callTool({
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
method: 'tools/call',
|
|
516
|
-
params: {
|
|
517
|
-
name: effectiveCall.name,
|
|
518
|
-
arguments: effectiveCall.arguments,
|
|
519
|
-
},
|
|
500
|
+
const result = await runtime.callTool({
|
|
501
|
+
name: effectiveCall.name,
|
|
502
|
+
arguments: effectiveCall.arguments,
|
|
520
503
|
}, {
|
|
521
504
|
requestId: taskforceAgentMcpRequestId(effectiveCall),
|
|
522
505
|
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { TASKFORCE_CLOUD_ENVIRONMENTS, parseTaskforceCloudEnvironment } from '../config/cloudEnvironment.js';
|
|
2
|
+
import { readSetCookieHeaders, stripSetCookieDomainAttribute } from '../utils/httpSetCookie.js';
|
|
3
|
+
import { resolveAllAdminProxyUpstreamSessionCookieNames, resolveAdminProxyUpstreamSessionCookieName, rewriteAdminProxyRequestCookieHeader, rewriteAdminProxyResponseSetCookie, } from './adminProxySessionCookies.js';
|
|
4
|
+
function readEnvValue(env, key) {
|
|
5
|
+
const value = env[key];
|
|
6
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
7
|
+
}
|
|
8
|
+
function resolveProxyEnvironment(context) {
|
|
9
|
+
const processEnvironment = typeof process !== 'undefined' ? process.env : {};
|
|
10
|
+
return { ...processEnvironment, ...context.env };
|
|
11
|
+
}
|
|
12
|
+
function resolveUpstreamBaseUrl(environment) {
|
|
13
|
+
return TASKFORCE_CLOUD_ENVIRONMENTS[environment].appBaseUrl.replace(/\/+$/, '');
|
|
14
|
+
}
|
|
15
|
+
function isCloudflareAccessRedirect(response) {
|
|
16
|
+
if (response.status < 300 || response.status >= 400)
|
|
17
|
+
return false;
|
|
18
|
+
const location = String(response.headers.get('location') || '').trim();
|
|
19
|
+
if (!location)
|
|
20
|
+
return false;
|
|
21
|
+
try {
|
|
22
|
+
const url = new URL(location);
|
|
23
|
+
return url.hostname.toLowerCase() === 'stratnexus.cloudflareaccess.com'
|
|
24
|
+
|| url.pathname.startsWith('/cdn-cgi/access/login');
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return location.includes('/cdn-cgi/access/login');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function jsonError(status, error, code) {
|
|
31
|
+
return new Response(JSON.stringify({ error, code }), {
|
|
32
|
+
status,
|
|
33
|
+
headers: {
|
|
34
|
+
'Content-Type': 'application/json',
|
|
35
|
+
'Cache-Control': 'no-store',
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
export async function handleAdminEdgeProxyRequest(context) {
|
|
40
|
+
const request = context.request;
|
|
41
|
+
const environment = parseTaskforceCloudEnvironment(request.headers.get('x-taskforce-cloud-environment'));
|
|
42
|
+
if (!environment) {
|
|
43
|
+
return jsonError(400, 'A valid admin cloud environment is required.', 'ADMIN_ENVIRONMENT_REQUIRED');
|
|
44
|
+
}
|
|
45
|
+
const proxyEnvironment = resolveProxyEnvironment(context);
|
|
46
|
+
const upstreamSessionCookieName = resolveAdminProxyUpstreamSessionCookieName(environment, proxyEnvironment);
|
|
47
|
+
const requestUrl = new URL(request.url);
|
|
48
|
+
const upstreamUrl = `${resolveUpstreamBaseUrl(environment)}${requestUrl.pathname}${requestUrl.search}`;
|
|
49
|
+
const headers = new Headers(request.headers);
|
|
50
|
+
headers.delete('host');
|
|
51
|
+
const rewrittenCookie = rewriteAdminProxyRequestCookieHeader(headers.get('cookie'), environment, upstreamSessionCookieName, resolveAllAdminProxyUpstreamSessionCookieNames(proxyEnvironment));
|
|
52
|
+
if (rewrittenCookie)
|
|
53
|
+
headers.set('cookie', rewrittenCookie);
|
|
54
|
+
else
|
|
55
|
+
headers.delete('cookie');
|
|
56
|
+
headers.set('x-taskforce-origin-host', requestUrl.host);
|
|
57
|
+
headers.set('x-taskforce-origin-proto', requestUrl.protocol.replace(':', ''));
|
|
58
|
+
headers.set('x-taskforce-origin-base-url', requestUrl.origin);
|
|
59
|
+
headers.set('x-taskforce-origin-runtime', 'admin-edge-proxy');
|
|
60
|
+
const cloudProxyClientId = readEnvValue(proxyEnvironment, 'TASKFORCE_CF_ACCESS_CLIENT_ID')
|
|
61
|
+
|| readEnvValue(proxyEnvironment, 'CF_ACCESS_CLIENT_ID');
|
|
62
|
+
const cloudProxyClientSecret = readEnvValue(proxyEnvironment, 'TASKFORCE_CF_ACCESS_CLIENT_SECRET')
|
|
63
|
+
|| readEnvValue(proxyEnvironment, 'CF_ACCESS_CLIENT_SECRET');
|
|
64
|
+
if (cloudProxyClientId && cloudProxyClientSecret) {
|
|
65
|
+
headers.set('CF-Access-Client-Id', cloudProxyClientId);
|
|
66
|
+
headers.set('CF-Access-Client-Secret', cloudProxyClientSecret);
|
|
67
|
+
}
|
|
68
|
+
const method = request.method.toUpperCase();
|
|
69
|
+
const upstreamResponse = await fetch(upstreamUrl, {
|
|
70
|
+
method,
|
|
71
|
+
headers,
|
|
72
|
+
body: method !== 'GET' && method !== 'HEAD' ? await request.arrayBuffer() : undefined,
|
|
73
|
+
redirect: 'manual',
|
|
74
|
+
});
|
|
75
|
+
if (isCloudflareAccessRedirect(upstreamResponse)) {
|
|
76
|
+
return jsonError(401, 'Cloudflare Access authentication required for the selected environment.', 'CLOUDFLARE_ACCESS_REQUIRED');
|
|
77
|
+
}
|
|
78
|
+
const responseHeaders = new Headers(upstreamResponse.headers);
|
|
79
|
+
responseHeaders.delete('access-control-allow-origin');
|
|
80
|
+
responseHeaders.delete('access-control-allow-credentials');
|
|
81
|
+
responseHeaders.delete('access-control-allow-methods');
|
|
82
|
+
responseHeaders.delete('access-control-allow-headers');
|
|
83
|
+
responseHeaders.set('cache-control', 'no-store');
|
|
84
|
+
const setCookies = readSetCookieHeaders(upstreamResponse.headers);
|
|
85
|
+
responseHeaders.delete('set-cookie');
|
|
86
|
+
for (const setCookie of setCookies) {
|
|
87
|
+
responseHeaders.append('set-cookie', stripSetCookieDomainAttribute(rewriteAdminProxyResponseSetCookie(setCookie, environment, upstreamSessionCookieName)));
|
|
88
|
+
}
|
|
89
|
+
return new Response(upstreamResponse.body, {
|
|
90
|
+
status: upstreamResponse.status,
|
|
91
|
+
statusText: upstreamResponse.statusText,
|
|
92
|
+
headers: responseHeaders,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type TaskforceCloudEnvironment } from '../config/cloudEnvironment.js';
|
|
2
|
+
export declare const ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME = "taskforce_session";
|
|
3
|
+
export declare const ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_ENV = "TASKFORCE_ADMIN_PROXY_UPSTREAM_SESSION_COOKIE";
|
|
4
|
+
export declare function resolveAdminProxyUpstreamSessionCookieName(environment: TaskforceCloudEnvironment, env?: Record<string, unknown>): string;
|
|
5
|
+
export declare function resolveAllAdminProxyUpstreamSessionCookieNames(env?: Record<string, unknown>): string[];
|
|
6
|
+
export declare function adminProxySessionCookieName(environment: TaskforceCloudEnvironment): string;
|
|
7
|
+
/**
|
|
8
|
+
* Replace all browser-visible admin session cookies with the one upstream
|
|
9
|
+
* session cookie expected by the selected cloud environment.
|
|
10
|
+
*/
|
|
11
|
+
export declare function rewriteAdminProxyRequestCookieHeader(cookieHeader: string | null | undefined, environment: TaskforceCloudEnvironment, upstreamSessionCookieName?: string, additionalSessionCookieNames?: readonly string[]): string;
|
|
12
|
+
/**
|
|
13
|
+
* Namespace an upstream cloud session for the admin proxy host. Removing the
|
|
14
|
+
* upstream Domain attribute keeps the isolated session scoped to that proxy.
|
|
15
|
+
*/
|
|
16
|
+
export declare function rewriteAdminProxyResponseSetCookie(setCookie: string, environment: TaskforceCloudEnvironment, upstreamSessionCookieName?: string): string;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { TASKFORCE_CLOUD_ENVIRONMENT_ORDER, } from '../config/cloudEnvironment.js';
|
|
2
|
+
export const ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME = 'taskforce_session';
|
|
3
|
+
export const ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_ENV = 'TASKFORCE_ADMIN_PROXY_UPSTREAM_SESSION_COOKIE';
|
|
4
|
+
const ADMIN_PROXY_SESSION_COOKIE_PREFIX = '__Host-taskforce_admin_session_';
|
|
5
|
+
const LEGACY_ADMIN_PROXY_SESSION_COOKIE_PREFIX = 'taskforce_admin_session_';
|
|
6
|
+
const TASKFORCE_SESSION_COOKIE_NAMES = new Set([
|
|
7
|
+
ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME,
|
|
8
|
+
'taskforce_session_prod',
|
|
9
|
+
'taskforce_session_staging',
|
|
10
|
+
'taskforce_session_performance',
|
|
11
|
+
]);
|
|
12
|
+
export function resolveAdminProxyUpstreamSessionCookieName(environment, env = {}) {
|
|
13
|
+
const environmentKey = `${ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_ENV}_${environment.toUpperCase()}`;
|
|
14
|
+
const configured = String(env[environmentKey] || env[ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_ENV] || '').trim();
|
|
15
|
+
if (!configured)
|
|
16
|
+
return ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME;
|
|
17
|
+
if (!/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(configured)) {
|
|
18
|
+
throw new Error(`Invalid admin proxy upstream session cookie name for ${environment}.`);
|
|
19
|
+
}
|
|
20
|
+
return configured;
|
|
21
|
+
}
|
|
22
|
+
export function resolveAllAdminProxyUpstreamSessionCookieNames(env = {}) {
|
|
23
|
+
return [...new Set(TASKFORCE_CLOUD_ENVIRONMENT_ORDER.map((environment) => resolveAdminProxyUpstreamSessionCookieName(environment, env)))];
|
|
24
|
+
}
|
|
25
|
+
export function adminProxySessionCookieName(environment) {
|
|
26
|
+
return `${ADMIN_PROXY_SESSION_COOKIE_PREFIX}${environment}`;
|
|
27
|
+
}
|
|
28
|
+
function cookiePairName(pair) {
|
|
29
|
+
const separator = pair.indexOf('=');
|
|
30
|
+
return (separator >= 0 ? pair.slice(0, separator) : pair).trim();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Replace all browser-visible admin session cookies with the one upstream
|
|
34
|
+
* session cookie expected by the selected cloud environment.
|
|
35
|
+
*/
|
|
36
|
+
export function rewriteAdminProxyRequestCookieHeader(cookieHeader, environment, upstreamSessionCookieName = ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME, additionalSessionCookieNames = []) {
|
|
37
|
+
const selectedCookieName = adminProxySessionCookieName(environment);
|
|
38
|
+
const pairs = String(cookieHeader || '')
|
|
39
|
+
.split(';')
|
|
40
|
+
.map((part) => part.trim())
|
|
41
|
+
.filter(Boolean);
|
|
42
|
+
const selectedPair = pairs.find((pair) => cookiePairName(pair) === selectedCookieName);
|
|
43
|
+
const forwardedPairs = pairs.filter((pair) => {
|
|
44
|
+
const name = cookiePairName(pair);
|
|
45
|
+
return name !== upstreamSessionCookieName
|
|
46
|
+
&& !additionalSessionCookieNames.includes(name)
|
|
47
|
+
&& !TASKFORCE_SESSION_COOKIE_NAMES.has(name)
|
|
48
|
+
&& !name.startsWith(ADMIN_PROXY_SESSION_COOKIE_PREFIX)
|
|
49
|
+
&& !name.startsWith(LEGACY_ADMIN_PROXY_SESSION_COOKIE_PREFIX);
|
|
50
|
+
});
|
|
51
|
+
if (selectedPair) {
|
|
52
|
+
const separator = selectedPair.indexOf('=');
|
|
53
|
+
forwardedPairs.push(`${upstreamSessionCookieName}=${selectedPair.slice(separator + 1)}`);
|
|
54
|
+
}
|
|
55
|
+
return forwardedPairs.join('; ');
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Namespace an upstream cloud session for the admin proxy host. Removing the
|
|
59
|
+
* upstream Domain attribute keeps the isolated session scoped to that proxy.
|
|
60
|
+
*/
|
|
61
|
+
export function rewriteAdminProxyResponseSetCookie(setCookie, environment, upstreamSessionCookieName = ADMIN_PROXY_UPSTREAM_SESSION_COOKIE_NAME) {
|
|
62
|
+
const parts = String(setCookie || '')
|
|
63
|
+
.split(';')
|
|
64
|
+
.map((part) => part.trim())
|
|
65
|
+
.filter(Boolean);
|
|
66
|
+
if (parts.length === 0)
|
|
67
|
+
return setCookie;
|
|
68
|
+
const [nameValue, ...attributes] = parts;
|
|
69
|
+
const separator = nameValue.indexOf('=');
|
|
70
|
+
if (separator < 0 || nameValue.slice(0, separator).trim() !== upstreamSessionCookieName) {
|
|
71
|
+
return setCookie;
|
|
72
|
+
}
|
|
73
|
+
const value = nameValue.slice(separator + 1);
|
|
74
|
+
const hostOnlyAttributes = attributes.filter((attribute) => {
|
|
75
|
+
const lower = attribute.toLowerCase();
|
|
76
|
+
return !lower.startsWith('domain=')
|
|
77
|
+
&& !lower.startsWith('path=')
|
|
78
|
+
&& lower !== 'secure';
|
|
79
|
+
});
|
|
80
|
+
return [
|
|
81
|
+
`${adminProxySessionCookieName(environment)}=${value}`,
|
|
82
|
+
'Path=/',
|
|
83
|
+
'Secure',
|
|
84
|
+
...hostOnlyAttributes,
|
|
85
|
+
].join('; ');
|
|
86
|
+
}
|
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
export declare const AI_PROFILE_GENERIC_GRAY = "#6b7280";
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const AI_PROFILE_SIGNATURE_COLOR_OPTIONS: readonly [{
|
|
3
|
+
readonly name: "Blue";
|
|
4
|
+
readonly value: "#4269d0";
|
|
5
|
+
}, {
|
|
6
|
+
readonly name: "Orange";
|
|
7
|
+
readonly value: "#efb118";
|
|
8
|
+
}, {
|
|
9
|
+
readonly name: "Red";
|
|
10
|
+
readonly value: "#ff725c";
|
|
11
|
+
}, {
|
|
12
|
+
readonly name: "Cyan";
|
|
13
|
+
readonly value: "#6cc5b0";
|
|
14
|
+
}, {
|
|
15
|
+
readonly name: "Green";
|
|
16
|
+
readonly value: "#3ca951";
|
|
17
|
+
}, {
|
|
18
|
+
readonly name: "Pink";
|
|
19
|
+
readonly value: "#ff8ab7";
|
|
20
|
+
}, {
|
|
21
|
+
readonly name: "Purple";
|
|
22
|
+
readonly value: "#a463f2";
|
|
23
|
+
}, {
|
|
24
|
+
readonly name: "Light blue";
|
|
25
|
+
readonly value: "#97bbf5";
|
|
26
|
+
}, {
|
|
27
|
+
readonly name: "Brown";
|
|
28
|
+
readonly value: "#9c6b4e";
|
|
29
|
+
}, {
|
|
30
|
+
readonly name: "Gray";
|
|
31
|
+
readonly value: "#9498a0";
|
|
32
|
+
}];
|
|
3
33
|
export declare const AI_PROFILE_COLOR_SOURCES: readonly ["user_override", "agent_explicit", "product_default", "assigned_default", "legacy"];
|
|
4
34
|
export type AiProfileColorSource = typeof AI_PROFILE_COLOR_SOURCES[number];
|
|
5
35
|
export declare function normalizeAiProfileColor(value: unknown): string | null;
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveColor } from './colorPalette.js';
|
|
2
2
|
export const AI_PROFILE_GENERIC_GRAY = '#6b7280';
|
|
3
|
-
export const
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
export const AI_PROFILE_SIGNATURE_COLOR_OPTIONS = [
|
|
4
|
+
{ name: 'Blue', value: '#4269d0' },
|
|
5
|
+
{ name: 'Orange', value: '#efb118' },
|
|
6
|
+
{ name: 'Red', value: '#ff725c' },
|
|
7
|
+
{ name: 'Cyan', value: '#6cc5b0' },
|
|
8
|
+
{ name: 'Green', value: '#3ca951' },
|
|
9
|
+
{ name: 'Pink', value: '#ff8ab7' },
|
|
10
|
+
{ name: 'Purple', value: '#a463f2' },
|
|
11
|
+
{ name: 'Light blue', value: '#97bbf5' },
|
|
12
|
+
{ name: 'Brown', value: '#9c6b4e' },
|
|
13
|
+
{ name: 'Gray', value: '#9498a0' },
|
|
6
14
|
];
|
|
7
15
|
export const AI_PROFILE_COLOR_SOURCES = ['user_override', 'agent_explicit', 'product_default', 'assigned_default', 'legacy'];
|
|
8
16
|
export function normalizeAiProfileColor(value) {
|
|
@@ -28,6 +36,6 @@ export function assignedAiProfileColor(stableIdentity) {
|
|
|
28
36
|
hash ^= identity.charCodeAt(index);
|
|
29
37
|
hash = Math.imul(hash, 16777619);
|
|
30
38
|
}
|
|
31
|
-
const
|
|
32
|
-
return
|
|
39
|
+
const option = AI_PROFILE_SIGNATURE_COLOR_OPTIONS[(hash >>> 0) % AI_PROFILE_SIGNATURE_COLOR_OPTIONS.length];
|
|
40
|
+
return option.value;
|
|
33
41
|
}
|