@taskforcehq/taskforce 0.3.329 → 0.3.332
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/README.md +7 -2
- 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/agentCapabilities/AgentCapabilitiesPrototype.d.ts +2 -2
- package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.js +2 -2
- 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/planning/PlanningModule.js +15 -3
- package/dist/components/features/planning/planningMetadata.d.ts +10 -0
- package/dist/components/features/planning/planningMetadata.js +8 -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 +62 -27
- package/dist/components/views/panels/PlanningDrawer.d.ts +2 -1
- package/dist/components/views/panels/PlanningDrawer.js +12 -8
- 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 +55 -1
- package/dist/core/McpTokenService.d.ts +25 -1
- package/dist/core/McpTokenService.js +106 -15
- 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 +43 -3
- package/dist/core/Taskforce.js +158 -7
- package/dist/core/types.d.ts +9 -0
- package/dist/documentReviews/DocumentReviewCommentStore.d.ts +2 -0
- package/dist/documentReviews/DocumentReviewCommentStore.js +28 -9
- 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 +11 -0
- package/dist/mcp/httpProtocolRouting.js +22 -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 +408 -102
- package/dist/mcp/taskPlanningRegistrar.js +25 -6
- package/dist/mcp/toolProfiles.d.ts +2 -0
- package/dist/mcp/toolProfiles.js +11 -0
- package/dist/mcp/toolRegistry.d.ts +1 -0
- package/dist/mcp/toolRegistry.js +9 -8
- 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/buildInfo.d.ts +1 -0
- package/dist/server/buildInfo.js +5 -1
- package/dist/server/cloudMcpCapacityTelemetry.d.ts +68 -0
- package/dist/server/cloudMcpCapacityTelemetry.js +221 -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 +25 -19
- package/dist/server/routes/admin.d.ts +4 -0
- package/dist/server/routes/admin.js +126 -5
- 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 +22 -0
- package/dist/server/routes/shared.js +298 -182
- 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/service/localServiceCli.d.ts +2 -2
- package/dist/service/localServiceCli.js +4 -3
- 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 +139 -0
- package/dist/services/executorPhaseAIssuerCore.js +402 -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 +2 -2
- package/dist/services/taskforceAgentMcpBridge.js +42 -29
- 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 +14 -1
- package/dist/storage/postgresRequestDiagnostics.d.ts +9 -1
- package/dist/storage/postgresRequestDiagnostics.js +15 -2
- package/dist/storage/postgresWorker.js +20 -2
- package/dist/storage/postgresWorkerProtocol.d.ts +7 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.d.ts +31 -0
- package/dist/storage/taskforceAgentConnectionBindingStore.js +84 -0
- package/dist/storage/workflowStore.d.ts +2 -0
- package/dist/storage/workflowStore.js +39 -2
- package/dist/sync/cloudSyncApi.js +4 -2
- package/dist/sync/collaborationSyncState.js +5 -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/localWorkspaceSyncRunner.d.ts +3 -1
- package/dist/sync/coordinator/localWorkspaceSyncRunner.js +18 -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 +31 -0
- package/dist/sync/syncApplyHandlers.d.ts +3 -0
- package/dist/sync/syncApplyHandlers.js +81 -15
- 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 +18 -7
- package/dist/sync/v3/durableWorkflowRuntimeMutationRouter.js +89 -23
- 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/localOutboxRecoveryPreparationService.js +8 -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/localTaskCreateOutboxService.d.ts +3 -1
- package/dist/sync/v3/localTaskCreateOutboxService.js +6 -1
- package/dist/sync/v3/localTaskDeleteOutboxService.js +1 -0
- package/dist/sync/v3/localTaskLifecycleOutboxService.d.ts +2 -1
- package/dist/sync/v3/localTaskLifecycleOutboxService.js +5 -1
- package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -1
- package/dist/sync/v3/localTaskMetadataOutboxService.js +6 -2
- package/dist/sync/v3/localTaskStatusOutboxService.d.ts +10 -1
- package/dist/sync/v3/localTaskStatusOutboxService.js +238 -16
- package/dist/sync/v3/syncDurabilityStore.d.ts +36 -1
- package/dist/sync/v3/syncDurabilityStore.js +202 -8
- 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/workflowRuntimeMutationService.d.ts +5 -0
- package/dist/sync/v3/workflowRuntimeMutationService.js +124 -71
- 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/workspaceSyncV3CombinedLocalApply.js +25 -3
- 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/workspaceSyncV3Feed.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3Feed.js +6 -1
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +2 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +49 -18
- 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/workspaceSyncV3WorkflowRuntimeApply.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3WorkflowRuntimeApply.js +50 -5
- 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-CDMPtnbC.js +1 -0
- package/dist/ui/assets/AiProfilesModule-Cww85C4E.js +1 -0
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-B68Wg-RV.js → AnnotatedAttachmentWorkspace-Dt9TKYSH.js} +1 -1
- package/dist/ui/assets/{AssetTraySortControl-C8Rztyal.js → AssetTraySortControl-CKgapnxu.js} +1 -1
- package/dist/ui/assets/{ContextAttachmentManager-Cj3c7X9y.js → ContextAttachmentManager-T-cEVcOZ.js} +2 -2
- package/dist/ui/assets/{DocumentWorkspace-B5uvzems.js → DocumentWorkspace-HD4MUjAZ.js} +1 -1
- package/dist/ui/assets/{EntityActivityTimeline-BVFvCB5R.js → EntityActivityTimeline-_V0zfMuh.js} +1 -1
- package/dist/ui/assets/PlanningModule-mTkBygsB.js +1 -0
- package/dist/ui/assets/{PlansPage-AY4cGWco.js → PlansPage-Btiq06VO.js} +1 -1
- package/dist/ui/assets/{TaskContextUpload-DZxTVesW.js → TaskContextUpload-C00NVUpn.js} +1 -1
- package/dist/ui/assets/TaskSettings-Cp-L-4xh.js +12 -0
- package/dist/ui/assets/TaskforceAgentsModule-Coq9-PUp.js +24 -0
- package/dist/ui/assets/TaskforceAgentsModule-b-8R25cJ.css +1 -0
- package/dist/ui/assets/{WorkflowManagerModule-DEr5di_r.js → WorkflowManagerModule-CuqRzMmM.js} +1 -1
- package/dist/ui/assets/index-BZ-hdZSk.css +1 -0
- package/dist/ui/assets/index-DSQINwt9.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 +24 -4
- package/dist/ui/assets/AiIdentityRosterCard-BZM4aQnM.js +0 -1
- package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +0 -1
- package/dist/ui/assets/PlanningModule-B5DWQOGz.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,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,9 +57,9 @@ 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
|
-
readonly documents: readonly ["get_document", "get_document_reviews", "search_documents"];
|
|
62
|
+
readonly documents: readonly ["get_document", "get_document_reviews", "review_document", "search_documents"];
|
|
63
63
|
readonly images: readonly ["get_image", "get_image_annotations", "search_images"];
|
|
64
64
|
readonly workspace: readonly ["get_config", "get_current_profile", "list_assignees"];
|
|
65
65
|
}>;
|
|
@@ -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',
|
|
@@ -73,6 +75,7 @@ const MANAGED_AGENT_CAPABILITY_TOOLS = Object.freeze({
|
|
|
73
75
|
documents: [
|
|
74
76
|
'get_document',
|
|
75
77
|
'get_document_reviews',
|
|
78
|
+
'review_document',
|
|
76
79
|
'search_documents',
|
|
77
80
|
],
|
|
78
81
|
images: [
|
|
@@ -129,21 +132,8 @@ export function resolveManagedAgentMcpToolNames(toolPolicy, profile = MCP_MANAGE
|
|
|
129
132
|
}
|
|
130
133
|
return Array.from(effective).sort((left, right) => left.localeCompare(right));
|
|
131
134
|
}
|
|
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
135
|
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
|
-
}, {});
|
|
136
|
+
const result = await runtime.listTools();
|
|
147
137
|
return Array.isArray(result?.tools) ? result.tools : [];
|
|
148
138
|
}
|
|
149
139
|
function compactText(value, maxLength) {
|
|
@@ -198,21 +188,50 @@ function buildToolInstructions(baseSystem, tools, allowedMutationTaskId, readOnl
|
|
|
198
188
|
const toolLines = tools.map((tool) => (`- ${tool.name}: ${compactText(tool.description, 180)} Args: ${describeToolSchema(tool.inputSchema)}`));
|
|
199
189
|
const taskScope = String(allowedMutationTaskId || '').trim();
|
|
200
190
|
const canCompleteWorkflow = tools.some((tool) => tool.name === 'complete_workflow_step');
|
|
191
|
+
const canReviewDocuments = tools.some((tool) => tool.name === 'review_document');
|
|
192
|
+
const canAddComments = tools.some((tool) => [
|
|
193
|
+
'add_comment',
|
|
194
|
+
'add_initiative_comment',
|
|
195
|
+
'add_workstream_comment',
|
|
196
|
+
].includes(tool.name));
|
|
197
|
+
const canChangeChecklists = tools.some((tool) => [
|
|
198
|
+
'add_task_checklist_item',
|
|
199
|
+
'replace_task_checklist',
|
|
200
|
+
'update_task_checklist_item',
|
|
201
|
+
].includes(tool.name));
|
|
202
|
+
const allowedWrites = [
|
|
203
|
+
...(canAddComments ? ['comments'] : []),
|
|
204
|
+
...(canChangeChecklists ? ['checklist changes'] : []),
|
|
205
|
+
...(canReviewDocuments ? ['document review feedback'] : []),
|
|
206
|
+
...(canCompleteWorkflow ? ['completion of the current owned workflow step'] : []),
|
|
207
|
+
];
|
|
208
|
+
const allowedWritesSentence = allowedWrites.length > 0
|
|
209
|
+
? `Allowed writes: ${allowedWrites.join(', ')}.${canCompleteWorkflow ? ' Use complete_workflow_step only after finishing that step.' : ''}`
|
|
210
|
+
: 'No Taskforce writes are enabled for this run.';
|
|
211
|
+
const availableToolNames = new Set(tools.map((tool) => tool.name));
|
|
212
|
+
const selectedToolCallExample = [
|
|
213
|
+
{ name: 'get_task', arguments: { id: 'T-123' } },
|
|
214
|
+
{ name: 'get_document', arguments: { documentId: 'D-123' } },
|
|
215
|
+
{ name: 'get_initiative', arguments: { id: 'IN-123' } },
|
|
216
|
+
{ name: 'get_workstream', arguments: { id: 'WS-123' } },
|
|
217
|
+
{ name: 'get_config', arguments: {} },
|
|
218
|
+
].find((example) => availableToolNames.has(example.name));
|
|
219
|
+
const toolCallExample = selectedToolCallExample
|
|
220
|
+
? { tool: selectedToolCallExample.name, arguments: selectedToolCallExample.arguments }
|
|
221
|
+
: { tool: tools[0]?.name, arguments: {} };
|
|
201
222
|
return [
|
|
202
223
|
baseSystem,
|
|
203
224
|
'',
|
|
204
225
|
'Taskforce project tools are attached invisibly by the server. Use them when the user asks about current Taskforce tasks, initiatives, workstreams, documents, images, annotations, config, stats, or specific reference labels such as T-123, IN-123, WS-123, D-123, or I-123.',
|
|
205
226
|
readOnly
|
|
206
227
|
? 'This run is read-only. Use Taskforce tools only to inspect data; no Taskforce writes are available.'
|
|
207
|
-
:
|
|
208
|
-
? 'Allowed writes: task comments, checklist changes, and completion of the current owned workflow step. Use complete_workflow_step only after finishing that step.'
|
|
209
|
-
: 'Allowed writes: task comments and checklist changes.',
|
|
228
|
+
: allowedWritesSentence,
|
|
210
229
|
...(canCompleteWorkflow && !readOnly ? [
|
|
211
|
-
'For workflow-step work, call get_task_workflow before acting. If requiresCommentEvidence is true, call add_comment and
|
|
230
|
+
'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
231
|
] : []),
|
|
213
|
-
...(taskScope ? [`This run is task-scoped to ${taskScope}.
|
|
232
|
+
...(taskScope ? [`This run is task-scoped to ${taskScope}. Task-targeted mutations must target only this task.`] : []),
|
|
214
233
|
'To use a Taskforce tool, respond with only one JSON object and no prose:',
|
|
215
|
-
|
|
234
|
+
JSON.stringify(toolCallExample),
|
|
216
235
|
'After the server returns a tool result, answer the user normally unless another Taskforce tool is required; if another tool is required, respond with only one more tool-call JSON object.',
|
|
217
236
|
'Do not mention MCP setup or credentials.',
|
|
218
237
|
'Available Taskforce tools:',
|
|
@@ -495,7 +514,6 @@ export async function prepareTaskforceAgentMcpBridge(input, dependencies = {}) {
|
|
|
495
514
|
if (tools.length === 0)
|
|
496
515
|
return null;
|
|
497
516
|
const availableToolNames = new Set(tools.map((tool) => tool.name));
|
|
498
|
-
const callTool = getRuntimeHandler(runtime, 'tools/call');
|
|
499
517
|
return {
|
|
500
518
|
system: buildToolInstructions(input.system, tools, input.allowedMutationTaskId, input.readOnly),
|
|
501
519
|
availableToolNames: Array.from(availableToolNames),
|
|
@@ -509,14 +527,9 @@ export async function prepareTaskforceAgentMcpBridge(input, dependencies = {}) {
|
|
|
509
527
|
if (scopeFailure)
|
|
510
528
|
return scopeFailure;
|
|
511
529
|
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
|
-
},
|
|
530
|
+
const result = await runtime.callTool({
|
|
531
|
+
name: effectiveCall.name,
|
|
532
|
+
arguments: effectiveCall.arguments,
|
|
520
533
|
}, {
|
|
521
534
|
requestId: taskforceAgentMcpRequestId(effectiveCall),
|
|
522
535
|
});
|
|
@@ -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;
|