refactor: 统一项目名称从OpenFang到ZCLAW
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

重构所有代码和文档中的项目名称,将OpenFang统一更新为ZCLAW。包括:
- 配置文件中的项目名称
- 代码注释和文档引用
- 环境变量和路径
- 类型定义和接口名称
- 测试用例和模拟数据

同时优化部分代码结构,移除未使用的模块,并更新相关依赖项。
This commit is contained in:
iven
2026-03-27 07:36:03 +08:00
parent 4b08804aa9
commit 0d4fa96b82
226 changed files with 7288 additions and 5788 deletions

View File

@@ -1,7 +1,7 @@
/**
* API Fallbacks for ZCLAW Gateway
*
* Provides sensible default data when OpenFang API endpoints return 404.
* Provides sensible default data when ZCLAW API endpoints return 404.
* This allows the UI to function gracefully even when backend features
* are not yet implemented.
*/
@@ -178,7 +178,7 @@ export function getUsageStatsFallback(sessions: SessionForStats[] = []): UsageSt
/**
* Convert skills to plugin status when /api/plugins/status returns 404.
* OpenFang uses Skills instead of traditional plugins.
* ZCLAW uses Skills instead of traditional plugins.
*/
export function getPluginStatusFallback(skills: SkillForPlugins[] = []): PluginStatusFallback[] {
if (skills.length === 0) {
@@ -215,7 +215,7 @@ export function getScheduledTasksFallback(triggers: TriggerForTasks[] = []): Sch
/**
* Default security status when /api/security/status returns 404.
* OpenFang has 16 security layers - show them with conservative defaults.
* ZCLAW has 16 security layers - show them with conservative defaults.
*/
export function getSecurityStatusFallback(): SecurityStatusFallback {
const layers: SecurityLayerFallback[] = [

View File

@@ -1,7 +1,7 @@
/**
* OpenFang Configuration Parser
* ZCLAW Configuration Parser
*
* Provides configuration parsing, validation, and serialization for OpenFang TOML files.
* Provides configuration parsing, validation, and serialization for ZCLAW TOML files.
*
* @module lib/config-parser
*/
@@ -9,7 +9,7 @@
import { tomlUtils, TomlParseError } from './toml-utils';
import { DEFAULT_MODEL_ID, DEFAULT_PROVIDER } from '../constants/models';
import type {
OpenFangConfig,
ZclawConfig,
ConfigValidationResult,
ConfigValidationError,
ConfigValidationWarning,
@@ -64,7 +64,7 @@ const REQUIRED_FIELDS: Array<{ path: string; description: string }> = [
/**
* Default configuration values
*/
const DEFAULT_CONFIG: Partial<OpenFangConfig> = {
const DEFAULT_CONFIG: Partial<ZclawConfig> = {
server: {
host: '127.0.0.1',
port: 4200,
@@ -74,7 +74,7 @@ const DEFAULT_CONFIG: Partial<OpenFangConfig> = {
},
agent: {
defaults: {
workspace: '~/.openfang/workspace',
workspace: '~/.zclaw/workspace',
default_model: DEFAULT_MODEL_ID,
},
},
@@ -89,7 +89,7 @@ const DEFAULT_CONFIG: Partial<OpenFangConfig> = {
*/
export const configParser = {
/**
* Parse TOML content into an OpenFang configuration object
* Parse TOML content into a ZCLAW configuration object
*
* @param content - The TOML content to parse
* @param envVars - Optional environment variables for resolution
@@ -101,13 +101,13 @@ export const configParser = {
* const config = configParser.parseConfig(tomlContent, { OPENAI_API_KEY: 'sk-...' });
* ```
*/
parseConfig: (content: string, envVars?: Record<string, string | undefined>): OpenFangConfig => {
parseConfig: (content: string, envVars?: Record<string, string | undefined>): ZclawConfig => {
try {
// First resolve environment variables
const resolved = tomlUtils.resolveEnvVars(content, envVars);
// Parse TOML
const parsed = tomlUtils.parse<OpenFangConfig>(resolved);
const parsed = tomlUtils.parse<ZclawConfig>(resolved);
return parsed;
} catch (error) {
if (error instanceof TomlParseError) {
@@ -121,7 +121,7 @@ export const configParser = {
},
/**
* Validate an OpenFang configuration object
* Validate a ZCLAW configuration object
*
* @param config - The configuration object to validate
* @returns Validation result with errors and warnings
@@ -238,7 +238,7 @@ export const configParser = {
parseAndValidate: (
content: string,
envVars?: Record<string, string | undefined>
): OpenFangConfig => {
): ZclawConfig => {
const config = configParser.parseConfig(content, envVars);
const result = configParser.validateConfig(config);
if (!result.valid) {
@@ -261,7 +261,7 @@ export const configParser = {
* const toml = configParser.stringifyConfig(config);
* ```
*/
stringifyConfig: (config: OpenFangConfig): string => {
stringifyConfig: (config: ZclawConfig): string => {
return tomlUtils.stringify(config as unknown as Record<string, unknown>);
},
@@ -276,8 +276,8 @@ export const configParser = {
* const fullConfig = configParser.mergeWithDefaults(partialConfig);
* ```
*/
mergeWithDefaults: (config: Partial<OpenFangConfig>): OpenFangConfig => {
return deepMerge(DEFAULT_CONFIG, config) as unknown as OpenFangConfig;
mergeWithDefaults: (config: Partial<ZclawConfig>): ZclawConfig => {
return deepMerge(DEFAULT_CONFIG, config) as unknown as ZclawConfig;
},
/**
@@ -307,19 +307,19 @@ export const configParser = {
/**
* Get default configuration
*
* @returns Default OpenFang configuration
* @returns Default ZCLAW configuration
*/
getDefaults: (): OpenFangConfig => {
return JSON.parse(JSON.stringify(DEFAULT_CONFIG)) as OpenFangConfig;
getDefaults: (): ZclawConfig => {
return JSON.parse(JSON.stringify(DEFAULT_CONFIG)) as ZclawConfig;
},
/**
* Check if a configuration object is valid
*
* @param config - The configuration to check
* @returns Type guard for OpenFangConfig
* @returns Type guard for ZclawConfig
*/
isOpenFangConfig: (config: unknown): config is OpenFangConfig => {
isZclawConfig: (config: unknown): config is ZclawConfig => {
const result = configParser.validateConfig(config);
return result.valid;
},

View File

@@ -7,13 +7,13 @@
* - Agents (Clones)
* - Stats & Workspace
* - Config (Quick Config, Channels, Skills, Scheduler, Models)
* - Hands (OpenFang)
* - Workflows (OpenFang)
* - Sessions (OpenFang)
* - Triggers (OpenFang)
* - Audit (OpenFang)
* - Security (OpenFang)
* - Approvals (OpenFang)
* - Hands (ZCLAW)
* - Workflows (ZCLAW)
* - Sessions (ZCLAW)
* - Triggers (ZCLAW)
* - Audit (ZCLAW)
* - Security (ZCLAW)
* - Approvals (ZCLAW)
*
* These methods are installed onto GatewayClient.prototype via installApiMethods().
* The GatewayClient core class exposes restGet/restPost/restPut/restDelete/restPatch
@@ -179,7 +179,7 @@ export function installApiMethods(ClientClass: { prototype: GatewayClient }): vo
const storedAutoStart = localStorage.getItem('zclaw-autoStart');
const storedShowToolCalls = localStorage.getItem('zclaw-showToolCalls');
// Map OpenFang config to frontend expected format
// Map ZCLAW config to frontend expected format
return {
quickConfig: {
agentName: 'ZCLAW',
@@ -220,15 +220,15 @@ export function installApiMethods(ClientClass: { prototype: GatewayClient }): vo
localStorage.setItem('zclaw-showToolCalls', String(config.showToolCalls));
}
// Map frontend config back to OpenFang format
const openfangConfig = {
// Map frontend config back to ZCLAW format
const zclawConfig = {
data_dir: config.workspaceDir,
default_model: config.defaultModel ? {
model: config.defaultModel,
provider: config.defaultProvider || 'bailian',
} : undefined,
};
return this.restPut('/api/config', openfangConfig);
return this.restPut('/api/config', zclawConfig);
};
// ─── Skills ───
@@ -333,7 +333,7 @@ export function installApiMethods(ClientClass: { prototype: GatewayClient }): vo
return this.restPatch(`/api/scheduler/tasks/${id}`, { enabled });
};
// ─── OpenFang Hands API ───
// ─── ZCLAW Hands API ───
proto.listHands = async function (this: GatewayClient): Promise<{
hands: {
@@ -407,7 +407,7 @@ export function installApiMethods(ClientClass: { prototype: GatewayClient }): vo
return this.restGet(`/api/hands/${name}/runs?${params}`);
};
// ─── OpenFang Workflows API ───
// ─── ZCLAW Workflows API ───
proto.listWorkflows = async function (this: GatewayClient): Promise<{ workflows: { id: string; name: string; steps: number }[] }> {
return this.restGet('/api/workflows');
@@ -476,7 +476,7 @@ export function installApiMethods(ClientClass: { prototype: GatewayClient }): vo
return this.restDelete(`/api/workflows/${id}`);
};
// ─── OpenFang Session API ───
// ─── ZCLAW Session API ───
proto.listSessions = async function (this: GatewayClient, opts?: { limit?: number; offset?: number }): Promise<{
sessions: Array<{
@@ -539,7 +539,7 @@ export function installApiMethods(ClientClass: { prototype: GatewayClient }): vo
return this.restGet(`/api/sessions/${sessionId}/messages?${params}`);
};
// ─── OpenFang Triggers API ───
// ─── ZCLAW Triggers API ───
proto.listTriggers = async function (this: GatewayClient): Promise<{ triggers: { id: string; type: string; enabled: boolean }[] }> {
return this.restGet('/api/triggers');
@@ -580,7 +580,7 @@ export function installApiMethods(ClientClass: { prototype: GatewayClient }): vo
return this.restDelete(`/api/triggers/${id}`);
};
// ─── OpenFang Audit API ───
// ─── ZCLAW Audit API ───
proto.getAuditLogs = async function (this: GatewayClient, opts?: { limit?: number; offset?: number }): Promise<{ logs: unknown[] }> {
const params = new URLSearchParams();
@@ -598,7 +598,7 @@ export function installApiMethods(ClientClass: { prototype: GatewayClient }): vo
return this.restGet(`/api/audit/verify/${logId}`);
};
// ─── OpenFang Security API ───
// ─── ZCLAW Security API ───
proto.getSecurityStatus = async function (this: GatewayClient): Promise<{ layers: { name: string; enabled: boolean }[] }> {
try {
@@ -626,7 +626,7 @@ export function installApiMethods(ClientClass: { prototype: GatewayClient }): vo
}
};
// ─── OpenFang Approvals API ───
// ─── ZCLAW Approvals API ───
proto.listApprovals = async function (this: GatewayClient, status?: string): Promise<{
approvals: {

View File

@@ -1,7 +1,7 @@
/**
/**
* ZCLAW Gateway Client (Browser/Tauri side)
*
* Core WebSocket client for OpenFang Kernel protocol.
* Core WebSocket client for ZCLAW Kernel protocol.
* Handles connection management, WebSocket framing, heartbeat,
* event dispatch, and chat/stream operations.
*
@@ -22,7 +22,7 @@ export type {
GatewayPong,
GatewayFrame,
AgentStreamDelta,
OpenFangStreamEvent,
ZclawStreamEvent,
ConnectionState,
EventCallback,
} from './gateway-types';
@@ -51,7 +51,7 @@ import type {
GatewayFrame,
GatewayResponse,
GatewayEvent,
OpenFangStreamEvent,
ZclawStreamEvent,
ConnectionState,
EventCallback,
AgentStreamDelta,
@@ -158,7 +158,7 @@ function createIdempotencyKey(): string {
export class GatewayClient {
private ws: WebSocket | null = null;
private openfangWs: WebSocket | null = null; // OpenFang stream WebSocket
private zclawWs: WebSocket | null = null; // ZCLAW stream WebSocket
private state: ConnectionState = 'disconnected';
private requestId = 0;
private pendingRequests = new Map<string, {
@@ -243,20 +243,20 @@ export class GatewayClient {
// === Connection ===
/** Connect using REST API only (for OpenFang mode) */
/** Connect using REST API only (for ZCLAW mode) */
async connectRest(): Promise<void> {
if (this.state === 'connected') {
return;
}
this.setState('connecting');
try {
// Check if OpenFang API is healthy
// Check if ZCLAW API is healthy
const health = await this.restGet<{ status: string; version?: string }>('/api/health');
if (health.status === 'ok') {
this.reconnectAttempts = 0;
this.setState('connected');
this.startHeartbeat(); // Start heartbeat after successful connection
this.log('info', `Connected to OpenFang via REST API${health.version ? ` (v${health.version})` : ''}`);
this.log('info', `Connected to ZCLAW via REST API${health.version ? ` (v${health.version})` : ''}`);
this.emitEvent('connected', { version: health.version });
} else {
throw new Error('Health check failed');
@@ -264,7 +264,7 @@ export class GatewayClient {
} catch (err: unknown) {
this.setState('disconnected');
const errorMessage = err instanceof Error ? err.message : String(err);
throw new Error(`Failed to connect to OpenFang: ${errorMessage}`);
throw new Error(`Failed to connect to ZCLAW: ${errorMessage}`);
}
}
@@ -273,7 +273,7 @@ export class GatewayClient {
return Promise.resolve();
}
// Check if URL is for OpenFang (port 4200 or 50051) - use REST mode
// Check if URL is for ZCLAW (port 4200 or 50051) - use REST mode
if (this.url.includes(':4200') || this.url.includes(':50051')) {
return this.connectRest();
}
@@ -389,10 +389,10 @@ export class GatewayClient {
// === High-level API ===
// Default agent ID for OpenFang (will be set dynamically from /api/agents)
// Default agent ID for ZCLAW (will be set dynamically from /api/agents)
private defaultAgentId: string = '';
/** Try to fetch default agent ID from OpenFang /api/agents endpoint */
/** Try to fetch default agent ID from ZCLAW /api/agents endpoint */
async fetchDefaultAgentId(): Promise<string | null> {
try {
// Use /api/agents endpoint which returns array of agents
@@ -422,7 +422,7 @@ export class GatewayClient {
return this.defaultAgentId;
}
/** Send message to agent (OpenFang chat API) */
/** Send message to agent (ZCLAW chat API) */
async chat(message: string, opts?: {
sessionKey?: string;
agentId?: string;
@@ -432,24 +432,24 @@ export class GatewayClient {
temperature?: number;
maxTokens?: number;
}): Promise<{ runId: string; sessionId?: string; response?: string }> {
// OpenFang uses /api/agents/{agentId}/message endpoint
// ZCLAW uses /api/agents/{agentId}/message endpoint
let agentId = opts?.agentId || this.defaultAgentId;
// If no agent ID, try to fetch from OpenFang status
// If no agent ID, try to fetch from ZCLAW status
if (!agentId) {
await this.fetchDefaultAgentId();
agentId = this.defaultAgentId;
}
if (!agentId) {
throw new Error('No agent available. Please ensure OpenFang has at least one agent.');
throw new Error('No agent available. Please ensure ZCLAW has at least one agent.');
}
const result = await this.restPost<{ response?: string; input_tokens?: number; output_tokens?: number }>(`/api/agents/${agentId}/message`, {
message,
session_id: opts?.sessionKey,
});
// OpenFang returns { response, input_tokens, output_tokens }
// ZCLAW returns { response, input_tokens, output_tokens }
return {
runId: createIdempotencyKey(),
sessionId: opts?.sessionKey,
@@ -457,7 +457,7 @@ export class GatewayClient {
};
}
/** Send message with streaming response (OpenFang WebSocket) */
/** Send message with streaming response (ZCLAW WebSocket) */
async chatStream(
message: string,
callbacks: {
@@ -472,20 +472,20 @@ export class GatewayClient {
agentId?: string;
}
): Promise<{ runId: string }> {
let agentId = opts?.agentId || this.defaultAgentId;
const agentId = opts?.agentId || this.defaultAgentId;
const runId = createIdempotencyKey();
const sessionId = opts?.sessionKey || `session_${Date.now()}`;
// If no agent ID, try to fetch from OpenFang status (async, but we'll handle it in connectOpenFangStream)
// If no agent ID, try to fetch from ZCLAW status (async, but we'll handle it in connectZclawStream)
if (!agentId) {
// Try to get default agent asynchronously
this.fetchDefaultAgentId().then(() => {
const resolvedAgentId = this.defaultAgentId;
if (resolvedAgentId) {
this.streamCallbacks.set(runId, callbacks);
this.connectOpenFangStream(resolvedAgentId, runId, sessionId, message);
this.connectZclawStream(resolvedAgentId, runId, sessionId, message);
} else {
callbacks.onError('No agent available. Please ensure OpenFang has at least one agent.');
callbacks.onError('No agent available. Please ensure ZCLAW has at least one agent.');
callbacks.onComplete();
}
}).catch((err) => {
@@ -498,22 +498,22 @@ export class GatewayClient {
// Store callbacks for this run
this.streamCallbacks.set(runId, callbacks);
// Connect to OpenFang WebSocket if not connected
this.connectOpenFangStream(agentId, runId, sessionId, message);
// Connect to ZCLAW WebSocket if not connected
this.connectZclawStream(agentId, runId, sessionId, message);
return { runId };
}
/** Connect to OpenFang streaming WebSocket */
private connectOpenFangStream(
/** Connect to ZCLAW streaming WebSocket */
private connectZclawStream(
agentId: string,
runId: string,
sessionId: string,
message: string
): void {
// Close existing connection if any
if (this.openfangWs && this.openfangWs.readyState !== WebSocket.CLOSED) {
this.openfangWs.close();
if (this.zclawWs && this.zclawWs.readyState !== WebSocket.CLOSED) {
this.zclawWs.close();
}
// Build WebSocket URL
@@ -528,34 +528,34 @@ export class GatewayClient {
wsUrl = httpUrl.replace(/^http/, 'ws') + `/api/agents/${agentId}/ws`;
}
this.log('info', `Connecting to OpenFang stream: ${wsUrl}`);
this.log('info', `Connecting to ZCLAW stream: ${wsUrl}`);
try {
this.openfangWs = new WebSocket(wsUrl);
this.zclawWs = new WebSocket(wsUrl);
this.openfangWs.onopen = () => {
this.log('info', 'OpenFang WebSocket connected');
// Send chat message using OpenFang actual protocol
this.zclawWs.onopen = () => {
this.log('info', 'ZCLAW WebSocket connected');
// Send chat message using ZCLAW actual protocol
const chatRequest = {
type: 'message',
content: message,
session_id: sessionId,
};
this.openfangWs?.send(JSON.stringify(chatRequest));
this.zclawWs?.send(JSON.stringify(chatRequest));
};
this.openfangWs.onmessage = (event) => {
this.zclawWs.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
this.handleOpenFangStreamEvent(runId, data, sessionId);
this.handleZclawStreamEvent(runId, data, sessionId);
} catch (err: unknown) {
const errorMessage = err instanceof Error ? err.message : String(err);
this.log('error', `Failed to parse stream event: ${errorMessage}`);
}
};
this.openfangWs.onerror = (_event) => {
this.log('error', 'OpenFang WebSocket error');
this.zclawWs.onerror = (_event) => {
this.log('error', 'ZCLAW WebSocket error');
const callbacks = this.streamCallbacks.get(runId);
if (callbacks) {
callbacks.onError('WebSocket connection failed');
@@ -563,14 +563,14 @@ export class GatewayClient {
}
};
this.openfangWs.onclose = (event) => {
this.log('info', `OpenFang WebSocket closed: ${event.code} ${event.reason}`);
this.zclawWs.onclose = (event) => {
this.log('info', `ZCLAW WebSocket closed: ${event.code} ${event.reason}`);
const callbacks = this.streamCallbacks.get(runId);
if (callbacks && event.code !== 1000) {
callbacks.onError(`Connection closed: ${event.reason || 'unknown'}`);
}
this.streamCallbacks.delete(runId);
this.openfangWs = null;
this.zclawWs = null;
};
} catch (err: unknown) {
const errorMessage = err instanceof Error ? err.message : String(err);
@@ -583,13 +583,13 @@ export class GatewayClient {
}
}
/** Handle OpenFang stream events */
private handleOpenFangStreamEvent(runId: string, data: OpenFangStreamEvent, sessionId: string): void {
/** Handle ZCLAW stream events */
private handleZclawStreamEvent(runId: string, data: ZclawStreamEvent, sessionId: string): void {
const callbacks = this.streamCallbacks.get(runId);
if (!callbacks) return;
switch (data.type) {
// OpenFang actual event types
// ZCLAW actual event types
case 'text_delta':
// Stream delta content
if (data.content) {
@@ -602,8 +602,8 @@ export class GatewayClient {
if (data.phase === 'done') {
callbacks.onComplete();
this.streamCallbacks.delete(runId);
if (this.openfangWs) {
this.openfangWs.close(1000, 'Stream complete');
if (this.zclawWs) {
this.zclawWs.close(1000, 'Stream complete');
}
}
break;
@@ -617,8 +617,8 @@ export class GatewayClient {
// Mark complete if phase done wasn't sent
callbacks.onComplete();
this.streamCallbacks.delete(runId);
if (this.openfangWs) {
this.openfangWs.close(1000, 'Stream complete');
if (this.zclawWs) {
this.zclawWs.close(1000, 'Stream complete');
}
break;
@@ -649,14 +649,14 @@ export class GatewayClient {
case 'error':
callbacks.onError(data.message || data.code || data.content || 'Unknown error');
this.streamCallbacks.delete(runId);
if (this.openfangWs) {
this.openfangWs.close(1011, 'Error');
if (this.zclawWs) {
this.zclawWs.close(1011, 'Error');
}
break;
case 'connected':
// Connection established
this.log('info', `OpenFang agent connected: ${data.agent_id}`);
this.log('info', `ZCLAW agent connected: ${data.agent_id}`);
break;
case 'agents_updated':
@@ -687,12 +687,12 @@ export class GatewayClient {
callbacks.onError('Stream cancelled');
this.streamCallbacks.delete(runId);
}
if (this.openfangWs && this.openfangWs.readyState === WebSocket.OPEN) {
this.openfangWs.close(1000, 'User cancelled');
if (this.zclawWs && this.zclawWs.readyState === WebSocket.OPEN) {
this.zclawWs.close(1000, 'User cancelled');
}
}
// === REST API Helpers (OpenFang) ===
// === REST API Helpers (ZCLAW) ===
public getRestBaseUrl(): string {
// In browser dev mode, use Vite proxy (empty string = relative path)

View File

@@ -1,5 +1,5 @@
/**
* OpenFang Gateway Configuration Types
* ZCLAW Gateway Configuration Types
*
* Types for gateway configuration and model choices.
*/

View File

@@ -42,7 +42,7 @@ export function isLocalhost(url: string): boolean {
// === URL Constants ===
// OpenFang endpoints (port 50051 - actual running port)
// ZCLAW endpoints (port 50051 - actual running port)
// Note: REST API uses relative path to leverage Vite proxy for CORS bypass
export const DEFAULT_GATEWAY_URL = `${DEFAULT_WS_PROTOCOL}127.0.0.1:50051/ws`;
export const REST_API_URL = ''; // Empty = use relative path (Vite proxy)

View File

@@ -66,8 +66,8 @@ export interface AgentStreamDelta {
workflowResult?: unknown;
}
/** OpenFang WebSocket stream event types */
export interface OpenFangStreamEvent {
/** ZCLAW WebSocket stream event types */
export interface ZclawStreamEvent {
type: 'text_delta' | 'phase' | 'response' | 'typing' | 'tool_call' | 'tool_result' | 'hand' | 'workflow' | 'error' | 'connected' | 'agents_updated';
content?: string;
phase?: 'streaming' | 'done';

View File

@@ -2,7 +2,7 @@
* Health Check Library
*
* Provides Tauri health check command wrappers and utilities
* for monitoring the health status of the OpenFang backend.
* for monitoring the health status of the ZCLAW backend.
*/
import { invoke } from '@tauri-apps/api/core';
@@ -19,7 +19,7 @@ export interface HealthCheckResult {
details?: Record<string, unknown>;
}
export interface OpenFangHealthResponse {
export interface ZclawHealthResponse {
healthy: boolean;
message?: string;
details?: Record<string, unknown>;
@@ -43,7 +43,7 @@ export async function performHealthCheck(): Promise<HealthCheckResult> {
}
try {
const response = await invoke<OpenFangHealthResponse>('openfang_health_check');
const response = await invoke<ZclawHealthResponse>('zclaw_health_check');
return {
status: response.healthy ? 'healthy' : 'unhealthy',

View File

@@ -239,6 +239,14 @@ export const memory = {
async dbPath(): Promise<string> {
return invoke('memory_db_path');
},
async buildContext(
agentId: string,
query: string,
maxTokens: number | null,
): Promise<{ systemPromptAddition: string; totalTokens: number; memoriesUsed: number }> {
return invoke('memory_build_context', { agentId, query, maxTokens });
},
};
// === Heartbeat API ===

View File

@@ -771,7 +771,7 @@ function saveSnapshotsToStorage(snapshots: IdentitySnapshot[]): void {
}
const fallbackIdentities = loadIdentitiesFromStorage();
let fallbackProposals = loadProposalsFromStorage();
const fallbackProposals = loadProposalsFromStorage();
let fallbackSnapshots = loadSnapshotsFromStorage();
const fallbackIdentity = {
@@ -1073,6 +1073,27 @@ export const intelligenceClient = {
}
return fallbackMemory.dbPath();
},
buildContext: async (
agentId: string,
query: string,
maxTokens?: number,
): Promise<{ systemPromptAddition: string; totalTokens: number; memoriesUsed: number }> => {
if (isTauriEnv()) {
return intelligence.memory.buildContext(agentId, query, maxTokens ?? null);
}
// Fallback: use basic search
const memories = await fallbackMemory.search({
agentId,
query,
limit: 8,
minImportance: 3,
});
const addition = memories.length > 0
? `## 相关记忆\n${memories.map(m => `- [${m.type}] ${m.content}`).join('\n')}`
: '';
return { systemPromptAddition: addition, totalTokens: 0, memoriesUsed: memories.length };
},
},
heartbeat: {

View File

@@ -2,7 +2,7 @@
* ZCLAW Kernel Client (Tauri Internal)
*
* Client for communicating with the internal ZCLAW Kernel via Tauri commands.
* This replaces the external OpenFang Gateway WebSocket connection.
* This replaces the external ZCLAW Gateway WebSocket connection.
*
* Phase 5 of Intelligence Layer Migration.
*/
@@ -648,24 +648,14 @@ export class KernelClient {
* Approve a hand execution
*/
async approveHand(name: string, runId: string, approved: boolean, reason?: string): Promise<{ status: string }> {
try {
return await invoke('hand_approve', { handName: name, runId, approved, reason });
} catch {
this.log('warn', `hand_approve not yet implemented, returning fallback`);
return { status: approved ? 'approved' : 'rejected' };
}
return await invoke('hand_approve', { handName: name, runId, approved, reason });
}
/**
* Cancel a hand execution
*/
async cancelHand(name: string, runId: string): Promise<{ status: string }> {
try {
return await invoke('hand_cancel', { handName: name, runId });
} catch {
this.log('warn', `hand_cancel not yet implemented, returning fallback`);
return { status: 'cancelled' };
}
return await invoke('hand_cancel', { handName: name, runId });
}
/**

View File

@@ -9,7 +9,7 @@
* Supports multiple backends:
* - OpenAI (GPT-4, GPT-3.5)
* - Volcengine (Doubao)
* - OpenFang Gateway (passthrough)
* - ZCLAW Gateway (passthrough)
*
* Part of ZCLAW L4 Self-Evolution capability.
*/
@@ -284,7 +284,7 @@ class VolcengineLLMAdapter implements LLMServiceAdapter {
}
}
// === Gateway Adapter (pass through to OpenFang or internal Kernel) ===
// === Gateway Adapter (pass through to ZCLAW or internal Kernel) ===
class GatewayLLMAdapter implements LLMServiceAdapter {
private config: LLMConfig;
@@ -346,7 +346,7 @@ class GatewayLLMAdapter implements LLMServiceAdapter {
}
}
// External Gateway mode: Use OpenFang's chat endpoint
// External Gateway mode: Use ZCLAW's chat endpoint
const agentId = localStorage.getItem('zclaw-default-agent-id') || 'default';
const response = await fetch(`/api/agents/${agentId}/message`, {
@@ -403,7 +403,7 @@ class GatewayLLMAdapter implements LLMServiceAdapter {
}
isAvailable(): boolean {
// Gateway is available if we're in browser (can connect to OpenFang)
// Gateway is available if we're in browser (can connect to ZCLAW)
return typeof window !== 'undefined';
}
@@ -460,7 +460,7 @@ export function loadConfig(): LLMConfig {
// Ignore parse errors
}
// Default to gateway (OpenFang passthrough) for L4 self-evolution
// Default to gateway (ZCLAW passthrough) for L4 self-evolution
return DEFAULT_CONFIGS.gateway;
}

View File

@@ -239,12 +239,7 @@ export function generateWelcomeMessage(config: {
const { userName, agentName, emoji, personality, scenarios } = config;
// Build greeting
let greeting = '';
if (userName) {
greeting = `你好,${userName}`;
} else {
greeting = '你好!';
}
const greeting = userName ? `你好,${userName}` : '你好!';
// Build introduction
let intro = `我是${emoji ? ' ' + emoji : ''} ${agentName}`;

View File

@@ -41,7 +41,7 @@ export function escapeHtml(input: string): string {
if (typeof input !== 'string') {
return '';
}
return input.replace(/[&<>"'`=\/]/g, char => HTML_ENTITIES[char] || char);
return input.replace(/[&<>"'`=/]/g, (char) => HTML_ENTITIES[char] || char);
}
/**
@@ -502,12 +502,13 @@ export function sanitizeFilename(filename: string): string {
}
// Remove path separators
let sanitized = filename.replace(/[\/\\]/g, '_');
let sanitized = filename.replace(/[/\\]/g, '_');
// Remove null bytes
sanitized = sanitized.replace(/\0/g, '');
// Remove control characters
// eslint-disable-next-line no-control-regex
sanitized = sanitized.replace(/[\x00-\x1f\x7f]/g, '');
// Remove dangerous characters

View File

@@ -1,7 +1,7 @@
/**
* TOML Utility Functions
*
* Provides TOML parsing and serialization capabilities for OpenFang configuration files.
* Provides TOML parsing and serialization capabilities for ZCLAW configuration files.
* Supports environment variable interpolation in the format ${VAR_NAME}.
*
* @module toml-utils

View File

@@ -369,7 +369,7 @@ export function yamlToCanvas(yamlString: string): WorkflowCanvas {
// Convert steps to nodes
if (pipeline.spec.steps) {
let x = 300;
const x = 300;
let y = 50;
for (const step of pipeline.spec.steps) {