mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
192 lines
6.1 KiB
TypeScript
192 lines
6.1 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 Qwen Team
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* Control Service - Public Programmatic API
|
|
*
|
|
* Provides type-safe access to control plane functionality for internal
|
|
* CLI code. This is the ONLY programmatic interface that should be used by:
|
|
* - nonInteractiveCli
|
|
* - Session managers
|
|
* - Tool execution handlers
|
|
* - Internal CLI logic
|
|
*
|
|
* DO NOT use ControlDispatcher or controllers directly from application code.
|
|
*
|
|
* Architecture:
|
|
* - ControlContext stores shared session state (Layer 1)
|
|
* - ControlDispatcher handles protocol-level routing (Layer 2)
|
|
* - ControlService provides programmatic API for internal CLI usage (Layer 3)
|
|
*
|
|
* ControlService and ControlDispatcher share controller instances to ensure
|
|
* a single source of truth. All higher level code MUST access the control
|
|
* plane exclusively through ControlService.
|
|
*/
|
|
|
|
import type { IControlContext } from './ControlContext.js';
|
|
import type { ControlDispatcher } from './ControlDispatcher.js';
|
|
import type {
|
|
PermissionServiceAPI,
|
|
SystemServiceAPI,
|
|
// McpServiceAPI,
|
|
// HookServiceAPI,
|
|
} from './types/serviceAPIs.js';
|
|
|
|
/**
|
|
* Control Service
|
|
*
|
|
* Facade layer providing domain-grouped APIs for control plane operations.
|
|
* Shares controller instances with ControlDispatcher to ensure single source
|
|
* of truth and state consistency.
|
|
*/
|
|
export class ControlService {
|
|
private dispatcher: ControlDispatcher;
|
|
|
|
/**
|
|
* Construct ControlService
|
|
*
|
|
* @param context - Control context (unused directly, passed to dispatcher)
|
|
* @param dispatcher - Control dispatcher that owns the controller instances
|
|
*/
|
|
constructor(context: IControlContext, dispatcher: ControlDispatcher) {
|
|
this.dispatcher = dispatcher;
|
|
}
|
|
|
|
/**
|
|
* Permission Domain API
|
|
*
|
|
* Handles tool execution permissions, approval checks, and callbacks.
|
|
* Delegates to the shared PermissionController instance.
|
|
*/
|
|
get permission(): PermissionServiceAPI {
|
|
const controller = this.dispatcher.permissionController;
|
|
return {
|
|
/**
|
|
* Check if a tool should be allowed based on current permission settings
|
|
*
|
|
* Evaluates permission mode and tool registry to determine if execution
|
|
* should proceed. Can optionally modify tool arguments based on confirmation details.
|
|
*
|
|
* @param toolRequest - Tool call request information
|
|
* @param confirmationDetails - Optional confirmation details for UI
|
|
* @returns Permission decision with optional updated arguments
|
|
*/
|
|
shouldAllowTool: controller.shouldAllowTool.bind(controller),
|
|
|
|
/**
|
|
* Build UI suggestions for tool confirmation dialogs
|
|
*
|
|
* Creates actionable permission suggestions based on tool confirmation details.
|
|
*
|
|
* @param confirmationDetails - Tool confirmation details
|
|
* @returns Array of permission suggestions or null
|
|
*/
|
|
buildPermissionSuggestions:
|
|
controller.buildPermissionSuggestions.bind(controller),
|
|
|
|
/**
|
|
* Get callback for monitoring tool call status updates
|
|
*
|
|
* Returns callback function for integration with CoreToolScheduler.
|
|
*
|
|
* @returns Callback function for tool call updates
|
|
*/
|
|
getToolCallUpdateCallback:
|
|
controller.getToolCallUpdateCallback.bind(controller),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* System Domain API
|
|
*
|
|
* Handles system-level operations and session management.
|
|
* Delegates to the shared SystemController instance.
|
|
*/
|
|
get system(): SystemServiceAPI {
|
|
const controller = this.dispatcher.systemController;
|
|
return {
|
|
/**
|
|
* Get control capabilities
|
|
*
|
|
* Returns the control capabilities object indicating what control
|
|
* features are available. Used exclusively for the initialize
|
|
* control response. System messages do not include capabilities.
|
|
*
|
|
* @returns Control capabilities object
|
|
*/
|
|
getControlCapabilities: () => controller.buildControlCapabilities(),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* MCP Domain API
|
|
*
|
|
* Handles Model Context Protocol server interactions.
|
|
* Delegates to the shared MCPController instance.
|
|
*/
|
|
// get mcp(): McpServiceAPI {
|
|
// return {
|
|
// /**
|
|
// * Get or create MCP client for a server (lazy initialization)
|
|
// *
|
|
// * Returns existing client or creates new connection.
|
|
// *
|
|
// * @param serverName - Name of the MCP server
|
|
// * @returns Promise with client and config
|
|
// */
|
|
// getMcpClient: async (serverName: string) => {
|
|
// // MCPController has a private method getOrCreateMcpClient
|
|
// // We need to expose it via the API
|
|
// // For now, throw error as placeholder
|
|
// // The actual implementation will be added when we update MCPController
|
|
// throw new Error(
|
|
// `getMcpClient not yet implemented in ControlService. Server: ${serverName}`,
|
|
// );
|
|
// },
|
|
//
|
|
// /**
|
|
// * List all available MCP servers
|
|
// *
|
|
// * Returns names of configured/connected MCP servers.
|
|
// *
|
|
// * @returns Array of server names
|
|
// */
|
|
// listServers: () => {
|
|
// // Get servers from context
|
|
// const sdkServers = Array.from(
|
|
// this.dispatcher.mcpController['context'].sdkMcpServers,
|
|
// );
|
|
// const cliServers = Array.from(
|
|
// this.dispatcher.mcpController['context'].mcpClients.keys(),
|
|
// );
|
|
// return [...new Set([...sdkServers, ...cliServers])];
|
|
// },
|
|
// };
|
|
// }
|
|
|
|
/**
|
|
* Hook Domain API
|
|
*
|
|
* Handles hook callback processing (placeholder for future expansion).
|
|
* Delegates to the shared HookController instance.
|
|
*/
|
|
// get hook(): HookServiceAPI {
|
|
// // HookController has no public methods yet - controller access reserved for future use
|
|
// return {};
|
|
// }
|
|
|
|
/**
|
|
* Cleanup all controllers
|
|
*
|
|
* Should be called on session shutdown. Delegates to dispatcher's shutdown
|
|
* method to ensure all controllers are properly cleaned up.
|
|
*/
|
|
cleanup(): void {
|
|
// Delegate to dispatcher which manages controller cleanup
|
|
this.dispatcher.shutdown();
|
|
}
|
|
}
|