@gftdcojp/actor-sdk
Version:
Comprehensive TypeScript SDK for GFTD Actor Platform with Well-becoming Agent as default - Supporting mental wellness and personal growth through AI
1 lines • 296 kB
Source Map (JSON)
{"version":3,"sources":["../src/lib/types/actor-v3.ts","../src/lib/types/config.ts","../src/lib/api/actor-v3-client.ts","../src/lib/api/chat-client.ts","../src/hooks/use-actor-v3.ts","../src/hooks/use-gftd-chat.ts","../src/lib/config/sdk-config-manager.ts","../src/lib/git/gitlab-client.ts","../src/lib/git/git-embedding-sdk.ts","../src/lib/git/git-fs.ts","../src/lib/git/git-vector-store.ts","../src/lib/git/actor-git-manager.ts","../src/lib/utils/uuid.ts","../src/lib/git/actor-repository-manager.ts","../src/lib/git/chat-git-manager.ts","../src/lib/git/chat-history-utils.ts","../src/lib/auth/auth-middleware.ts","../src/lib/auth/gftd-auth-client.ts","../src/lib/embedding/vector-store.ts","../src/lib/utils.ts","../src/lib/index.ts"],"sourcesContent":["/**\n * Actor v3 API型定義\n * プロセス代数とLangChain.js互換性\n * https://actor.gftd.ai/api/v3/actor\n */\n\n// UUID generation - using Web Crypto API\n\n// ===== Core Types =====\n\nexport type ActorID = string\n\nexport interface Message {\n id: string\n label: string\n payload: Record<string, any>\n timestamp: string\n sender?: ActorID\n}\n\nexport interface State {\n [key: string]: any\n}\n\nexport interface OutAction {\n type: 'send' | 'spawn' | 'terminate'\n target?: ActorID\n message?: Message\n behavior?: Behavior\n}\n\nexport interface BehaviorResult {\n new_state: State\n actions: OutAction[]\n error?: string\n}\n\nexport interface Behavior {\n id: string\n name: string\n description: string\n version: string\n handler: (message: Message, state: State) => Promise<BehaviorResult>\n metadata: {\n created_at: string\n updated_at: string\n author: string\n tags: string[]\n capabilities: string[]\n }\n process_algebra: {\n notation: 'CCS' | 'π-calculus' | 'ACP'\n expression: string\n channels: string[]\n }\n}\n\n// ===== API Request/Response Types =====\n\nexport interface CreateActorRequest {\n behavior: Behavior\n organization_id: string\n initial_state?: State\n}\n\nexport interface CreateActorResponse {\n actor_id: ActorID\n status: 'created'\n timestamp: string\n}\n\nexport interface SendMessageRequest {\n target: ActorID\n message: Omit<Message, 'id' | 'timestamp'>\n}\n\nexport interface SendMessageResponse {\n message_id: string\n status: 'sent'\n timestamp: string\n}\n\nexport interface ReceiveMessagesRequest {\n max_messages?: number\n timeout?: number\n filter?: {\n labels?: string[]\n sender?: ActorID\n }\n}\n\nexport interface ReceiveMessagesResponse {\n messages: Message[]\n behavior_results: BehaviorResult[]\n timestamp: string\n}\n\nexport interface ListActorsResponse {\n actors: {\n actor_id: ActorID\n behavior_name: string\n status: 'active' | 'inactive' | 'terminated'\n created_at: string\n }[]\n total_count: number\n}\n\nexport interface ActorSystemConfig {\n process_algebra_analysis: {\n deadlock_free: boolean\n livelock_free: boolean\n deadlock_actors?: ActorID[]\n livelock_patterns?: string[]\n }\n communication_topology: {\n edges: {\n from: ActorID\n to: ActorID\n channel: string\n weight: number\n }[]\n }\n}\n\nexport interface SystemStatsResponse {\n stats: {\n active_actors: number\n total_messages: number\n average_latency_ms: number\n }\n detailed_metrics: {\n performance_metrics: {\n throughput: number\n latency_p95: number\n }\n }\n}\n\n// ===== LangChain.js Compatibility Types =====\n\nexport interface LangChainMessage {\n role: \"user\" | \"assistant\" | \"system\"\n content: string\n name?: string\n function_call?: any\n}\n\nexport interface RunnableConfig {\n timeout?: number\n maxMessages?: number\n}\n\nexport interface ActorV3RunnableInterface {\n invoke(input: any, config?: RunnableConfig): Promise<any>\n stream(input: any, config?: RunnableConfig): AsyncGenerator<any, any, unknown>\n batch(inputs: any[], config?: RunnableConfig): Promise<any[]>\n pipe<T>(next: T): T\n withFallbacks(fallbacks: any[]): any\n}\n\n// ===== Utility Functions =====\n\nexport function createMessage(label: string, payload: Record<string, any>, sender?: ActorID): Message {\n return {\n id: crypto.randomUUID(),\n label,\n payload,\n timestamp: new Date().toISOString(),\n sender\n }\n}\n\nexport function langChainToActorV3(lcMsg: LangChainMessage): Message {\n return {\n id: crypto.randomUUID(),\n label: lcMsg.name || 'langchain_message',\n payload: { content: lcMsg.content },\n timestamp: new Date().toISOString(),\n sender: lcMsg.role === 'user' ? 'user' : undefined\n }\n}\n\nexport function actorV3ToLangChain(actorMsg: Message): LangChainMessage {\n return {\n role: actorMsg.sender ? \"user\" : \"assistant\",\n content: typeof actorMsg.payload === 'string' ? actorMsg.payload : JSON.stringify(actorMsg.payload),\n name: actorMsg.label\n }\n}\n\n// ===== Error Types =====\n\nexport interface ActorV3Error {\n code: string\n message: string\n details?: Record<string, any>\n}\n\nexport interface ApiV3Response<T> {\n success: boolean\n data?: T\n error?: ActorV3Error\n} ","/**\n * @file lib/types/config.ts\n * @description Actor SDK Config 設定システム\n * @author GFTD Co., Ltd.\n */\n\nimport { SessionConfig } from './session'\nimport { GitConfig } from '../git/git-fs'\nimport { ChatGitConfig } from './chat-git'\n\n/**\n * GFTD認証設定\n */\nexport interface GFTDAuthConfig {\n /** 認証必須かどうか */\n required?: boolean\n /** 認証サーバーURL */\n authUrl?: string\n /** 認証APIキー */\n apiKey?: string\n /** 認証トークンの有効期限 (秒) */\n tokenExpiry?: number\n /** 認証プロバイダー */\n provider?: 'gftd' | 'custom'\n /** 認証スコープ */\n scopes?: string[]\n /** 自動リフレッシュ設定 */\n autoRefresh?: boolean\n /** リダイレクトURL */\n redirectUrl?: string\n}\n\n/**\n * ツール機能設定\n */\nexport interface ToolsConfig {\n /** Actor管理機能 */\n actorManagement: boolean\n /** セッション管理機能 */\n sessionManagement: boolean\n /** ストリーミング機能 */\n streaming: boolean\n /** Embedding & Vector Search機能 */\n embedding: boolean\n /** Git統合機能 */\n gitIntegration: boolean\n /** チャット履歴Git管理 */\n chatGitManagement: boolean\n /** モニタリング & アナリティクス */\n monitoring: boolean\n /** React UI コンポーネント */\n uiComponents: boolean\n}\n\n/**\n * Actor API設定\n */\nexport interface ActorApiConfig {\n /** API ベース URL */\n baseUrl: string\n /** API キー */\n apiKey?: string\n /** タイムアウト設定 (秒) */\n timeout?: number\n /** リトライ回数 */\n retryCount?: number\n /** リクエストヘッダー */\n headers?: Record<string, string>\n}\n\n/**\n * Embedding設定\n */\nexport interface EmbeddingConfig {\n /** モデル名 */\n modelName?: string\n /** ベクトル次元数 */\n dimensions?: number\n /** キャッシュディレクトリ */\n cacheDir?: string\n /** バッチサイズ */\n batchSize?: number\n}\n\n/**\n * Git統合設定\n */\nexport interface GitIntegrationConfig {\n /** GitLab設定 */\n gitlab?: {\n url: string\n token: string\n defaultVisibility?: 'private' | 'internal' | 'public'\n }\n /** Git作成者情報 */\n author?: {\n name: string\n email: string\n }\n /** 自動コミット設定 */\n autoCommit?: boolean\n /** 自動プッシュ設定 */\n autoPush?: boolean\n /** デフォルトブランチ名 */\n defaultBranch?: string\n}\n\n/**\n * ストリーミング設定\n */\nexport interface StreamingConfig {\n /** ストリーミング有効化 */\n enabled: boolean\n /** チャンクサイズ */\n chunkSize?: number\n /** タイムアウト設定 (秒) */\n timeout?: number\n /** 再接続設定 */\n reconnect?: {\n enabled: boolean\n maxAttempts?: number\n interval?: number\n }\n}\n\n/**\n * モニタリング設定\n */\nexport interface MonitoringConfig {\n /** メトリクス収集 */\n metricsEnabled: boolean\n /** ログレベル */\n logLevel?: 'debug' | 'info' | 'warn' | 'error'\n /** パフォーマンス追跡 */\n performanceTracking?: boolean\n /** エラー自動レポート */\n errorReporting?: boolean\n}\n\n/**\n * UI設定\n */\nexport interface UIConfig {\n /** テーマ */\n theme?: 'light' | 'dark' | 'auto'\n /** 言語設定 */\n locale?: string\n /** デフォルトページサイズ */\n defaultPageSize?: number\n /** アニメーション有効化 */\n animations?: boolean\n /** カスタムCSS */\n customStyles?: string\n}\n\n/**\n * デバッグ設定\n */\nexport interface DebugConfig {\n /** デバッグモード */\n enabled: boolean\n /** 詳細ログ */\n verboseLogging?: boolean\n /** API呼び出しログ */\n logApiCalls?: boolean\n /** Git操作ログ */\n logGitOperations?: boolean\n /** パフォーマンス計測 */\n measurePerformance?: boolean\n}\n\n/**\n * Actor SDK 包括的設定\n */\nexport interface ActorSDKConfig {\n /** 有効化するtools */\n tools: ToolsConfig\n \n /** Actor API設定 */\n api: ActorApiConfig\n \n /** GFTD認証設定 */\n auth?: GFTDAuthConfig\n \n /** セッション管理のデフォルト設定 */\n session?: SessionConfig\n \n /** Embedding設定 */\n embedding?: EmbeddingConfig\n \n /** Git統合設定 */\n git?: GitIntegrationConfig\n \n /** チャット履歴Git管理設定 */\n chatGit?: ChatGitConfig\n \n /** ストリーミング設定 */\n streaming?: StreamingConfig\n \n /** モニタリング設定 */\n monitoring?: MonitoringConfig\n \n /** UI設定 */\n ui?: UIConfig\n \n /** デバッグ設定 */\n debug?: DebugConfig\n \n /** カスタム設定 */\n custom?: Record<string, any>\n}\n\n/**\n * デフォルト設定を生成\n */\nexport function createDefaultConfig(): ActorSDKConfig {\n return {\n api: {\n baseUrl: 'https://actor.gftd.ai/api/v3',\n timeout: 30000,\n retryCount: 3\n },\n tools: {\n actorManagement: true,\n sessionManagement: true,\n streaming: true,\n embedding: false,\n gitIntegration: false,\n chatGitManagement: false,\n monitoring: true,\n uiComponents: true\n },\n auth: {\n required: false,\n provider: 'gftd'\n },\n session: {\n max_iterations: 100,\n auto_save: true\n },\n streaming: {\n enabled: true,\n chunkSize: 1024,\n timeout: 60,\n reconnect: {\n enabled: true,\n maxAttempts: 3,\n interval: 5000\n }\n },\n monitoring: {\n metricsEnabled: true,\n logLevel: 'info',\n performanceTracking: false,\n errorReporting: false\n },\n ui: {\n theme: 'auto',\n locale: 'ja',\n defaultPageSize: 20,\n animations: true\n },\n debug: {\n enabled: false,\n verboseLogging: false,\n logApiCalls: false,\n logGitOperations: false,\n measurePerformance: false\n }\n }\n}\n\n/**\n * 開発環境用設定を生成\n */\nexport function createDevelopmentConfig(): ActorSDKConfig {\n const baseConfig = createDefaultConfig()\n return {\n ...baseConfig,\n api: {\n ...baseConfig.api,\n baseUrl: 'https://actor.gftd.ai/api/v3'\n },\n tools: {\n ...baseConfig.tools,\n gitIntegration: true,\n chatGitManagement: true,\n embedding: true,\n monitoring: true\n },\n auth: {\n required: false,\n provider: 'gftd'\n },\n debug: {\n enabled: true,\n logApiCalls: true,\n logGitOperations: true\n }\n }\n}\n\n/**\n * プロダクション環境用設定を生成\n */\nexport function createProductionConfig(): ActorSDKConfig {\n const baseConfig = createDefaultConfig()\n return {\n ...baseConfig,\n api: {\n ...baseConfig.api,\n baseUrl: 'https://actor.gftd.ai/api/v3'\n },\n auth: {\n required: true,\n provider: 'gftd'\n },\n debug: {\n enabled: false,\n logApiCalls: false,\n logGitOperations: false\n }\n }\n}\n\n/**\n * 設定をマージ\n */\nexport function mergeConfig(...configs: Partial<ActorSDKConfig>[]): ActorSDKConfig {\n // デフォルト設定をベースとして開始\n const baseConfig = {\n tools: {\n actorManagement: true,\n sessionManagement: true,\n streaming: true,\n embedding: false,\n gitIntegration: false,\n chatGitManagement: false,\n monitoring: true,\n uiComponents: true\n },\n api: {\n baseUrl: process.env.ACTOR_API_BASE_URL || 'https://api.gftd.ai',\n timeout: 30,\n retryCount: 3\n }\n } as ActorSDKConfig\n\n return configs.reduce<ActorSDKConfig>((acc, config) => {\n if (!config) return acc\n \n return {\n ...acc,\n ...config,\n tools: config.tools ? { ...acc.tools, ...config.tools } : acc.tools,\n api: config.api ? { ...acc.api, ...config.api } : acc.api,\n auth: config.auth ? { ...acc.auth, ...config.auth } : acc.auth,\n session: config.session ? { ...acc.session, ...config.session } : acc.session,\n embedding: config.embedding ? { ...acc.embedding, ...config.embedding } : acc.embedding,\n git: config.git ? { ...acc.git, ...config.git } : acc.git,\n chatGit: config.chatGit ? { ...acc.chatGit, ...config.chatGit } : acc.chatGit,\n streaming: config.streaming ? { ...acc.streaming, ...config.streaming } : acc.streaming,\n monitoring: config.monitoring ? { ...acc.monitoring, ...config.monitoring } : acc.monitoring,\n ui: config.ui ? { ...acc.ui, ...config.ui } : acc.ui,\n debug: config.debug ? { ...acc.debug, ...config.debug } : acc.debug,\n custom: config.custom ? { ...acc.custom, ...config.custom } : acc.custom,\n }\n }, baseConfig)\n}\n\n/**\n * 設定の検証\n */\nexport function validateConfig(config: ActorSDKConfig): { valid: boolean; errors: string[] } {\n const errors: string[] = []\n\n // 必須フィールドのチェック\n if (!config.api?.baseUrl) {\n errors.push('api.baseUrl is required')\n }\n\n return {\n valid: errors.length === 0,\n errors\n }\n}\n\n/**\n * 設定が有効かチェック\n */\nexport function isToolEnabled(config: ActorSDKConfig, tool: keyof ToolsConfig): boolean {\n return config.tools[tool] === true\n}\n\n/**\n * 環境変数から設定を生成\n */\nexport function createConfigFromEnv(): Partial<ActorSDKConfig> {\n const config: Partial<ActorSDKConfig> = {}\n\n // API設定\n if (process.env.ACTOR_API_BASE_URL) {\n config.api = {\n baseUrl: process.env.ACTOR_API_BASE_URL,\n apiKey: process.env.ACTOR_API_KEY,\n timeout: process.env.ACTOR_API_TIMEOUT ? parseInt(process.env.ACTOR_API_TIMEOUT) : undefined,\n }\n }\n\n // GFTD認証設定(環境変数から生成)\n if (process.env.GFTD_AUTH_URL || process.env.GFTD_AUTH_API_KEY) {\n config.auth = {\n required: process.env.GFTD_AUTH_REQUIRED !== 'false',\n authUrl: process.env.GFTD_AUTH_URL || 'https://auth.gftd.ai',\n apiKey: process.env.GFTD_AUTH_API_KEY,\n provider: 'gftd',\n tokenExpiry: process.env.GFTD_AUTH_TOKEN_EXPIRY ? parseInt(process.env.GFTD_AUTH_TOKEN_EXPIRY) : 3600,\n scopes: process.env.GFTD_AUTH_SCOPES ? process.env.GFTD_AUTH_SCOPES.split(',') : ['read', 'write'],\n autoRefresh: process.env.GFTD_AUTH_AUTO_REFRESH !== 'false',\n redirectUrl: process.env.GFTD_AUTH_REDIRECT_URL\n }\n }\n // デバッグ設定\n if (process.env.NODE_ENV === 'development') {\n config.debug = {\n enabled: true,\n verboseLogging: true,\n logApiCalls: true,\n logGitOperations: true\n }\n }\n\n return config\n}\n\n/**\n * 開発環境設定を生成(統一されたAPIエンドポイント使用)\n */\nexport function createLocalDevelopmentConfig(organizationId?: string): ActorSDKConfig {\n const baseConfig = createDevelopmentConfig()\n return {\n ...baseConfig,\n api: {\n ...baseConfig.api,\n baseUrl: 'https://actor.gftd.ai/api/v3'\n },\n tools: {\n ...baseConfig.tools,\n gitIntegration: true,\n chatGitManagement: true,\n embedding: true,\n monitoring: true\n },\n auth: {\n required: false,\n provider: 'gftd'\n },\n debug: {\n enabled: true,\n logApiCalls: true,\n logGitOperations: true\n }\n }\n}\n\n/**\n * 環境判定: 開発環境かどうか\n */\nexport function isLocalDevelopment(): boolean {\n return process.env.NODE_ENV === 'development'\n}\n\n/**\n * GitLabデフォルト設定付きSDK設定を生成\n */\nexport function createConfigWithDefaultGitLab(overrides?: Partial<ActorSDKConfig>): ActorSDKConfig {\n const defaultGitLabConfig = {\n git: {\n autoCommit: process.env.GIT_AUTO_COMMIT === 'true',\n autoPush: process.env.GIT_AUTO_PUSH === 'true',\n defaultBranch: process.env.GIT_DEFAULT_BRANCH || 'main'\n },\n tools: {\n gitIntegration: true,\n chatGitManagement: true,\n actorManagement: true,\n sessionManagement: true,\n streaming: true,\n embedding: false,\n monitoring: true,\n uiComponents: true\n }\n }\n const baseConfig = createDefaultConfig()\n \n return mergeConfig(baseConfig, defaultGitLabConfig, overrides || {})\n} ","/**\n * Actor v3 APIクライアント\n * プロセス代数とLangChain.js互換性対応\n * https://actor.gftd.ai/api/v3/actor\n */\n\nimport {\n ActorID,\n Message,\n State,\n Behavior,\n CreateActorRequest,\n CreateActorResponse,\n SendMessageRequest,\n SendMessageResponse,\n ReceiveMessagesRequest,\n ReceiveMessagesResponse,\n ListActorsResponse,\n ActorSystemConfig,\n SystemStatsResponse,\n ApiV3Response,\n ActorV3Error,\n RunnableConfig,\n LangChainMessage,\n langChainToActorV3,\n actorV3ToLangChain,\n createMessage\n} from \"@/lib/types/actor-v3\"\n\n/**\n * Actor v3 メインクライアント\n */\nexport class ActorV3Client {\n private baseUrl: string\n private apiKey?: string\n\n constructor(config: { apiKey?: string; baseUrl?: string } = {}) {\n this.baseUrl = config.baseUrl || \"https://actor.gftd.ai/api/v3\"\n this.apiKey = config.apiKey\n }\n\n private async request<T>(\n endpoint: string,\n options: RequestInit = {}\n ): Promise<ApiV3Response<T>> {\n const url = `${this.baseUrl}${endpoint}`\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options.headers as Record<string, string>),\n }\n\n if (this.apiKey) {\n headers.Authorization = `Bearer ${this.apiKey}`\n }\n\n try {\n const response = await fetch(url, {\n ...options,\n headers,\n })\n\n const data = await response.json()\n\n if (!response.ok) {\n return {\n success: false,\n error: {\n code: data.code || 'HTTP_ERROR',\n message: data.message || `HTTP ${response.status}: ${response.statusText}`,\n details: data.details\n }\n }\n }\n\n return {\n success: true,\n data: data as T\n }\n } catch (error) {\n return {\n success: false,\n error: {\n code: 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : 'Unknown network error'\n }\n }\n }\n }\n\n /**\n * アクター管理API\n */\n actors = {\n /**\n * 新しいアクターを作成\n */\n create: async (request: CreateActorRequest): Promise<ApiV3Response<CreateActorResponse>> => {\n return this.request<CreateActorResponse>(\"/actor\", {\n method: \"POST\",\n body: JSON.stringify(request),\n })\n },\n\n /**\n * アクター一覧を取得\n */\n list: async (organizationId?: string): Promise<ApiV3Response<ListActorsResponse>> => {\n const params = organizationId ? `?organization_id=${organizationId}` : \"\"\n return this.request<ListActorsResponse>(`/actor${params}`)\n },\n\n /**\n * アクターにメッセージを送信\n */\n send: async (actorId: ActorID, request: SendMessageRequest): Promise<ApiV3Response<SendMessageResponse>> => {\n const messageWithMetadata = {\n ...request.message,\n id: crypto.randomUUID(),\n timestamp: new Date().toISOString()\n }\n\n return this.request<SendMessageResponse>(`/actor/${actorId}/send`, {\n method: \"POST\",\n body: JSON.stringify({\n ...request,\n message: messageWithMetadata\n }),\n })\n },\n\n /**\n * アクターからメッセージを受信\n */\n receive: async (actorId: ActorID, request: ReceiveMessagesRequest = {}): Promise<ApiV3Response<ReceiveMessagesResponse>> => {\n const params = new URLSearchParams()\n if (request.max_messages) params.append(\"max_messages\", request.max_messages.toString())\n if (request.timeout) params.append(\"timeout\", request.timeout.toString())\n if (request.filter?.labels) params.append(\"filter_labels\", request.filter.labels.join(\",\"))\n if (request.filter?.sender) params.append(\"filter_sender\", request.filter.sender)\n\n const queryString = params.toString()\n const url = `/actor/${actorId}/receive${queryString ? `?${queryString}` : \"\"}`\n\n return this.request<ReceiveMessagesResponse>(url)\n },\n\n /**\n * アクターを削除\n */\n delete: async (actorId: ActorID): Promise<ApiV3Response<{ status: 'deleted' }>> => {\n return this.request(`/actor/${actorId}`, {\n method: \"DELETE\",\n })\n }\n }\n\n /**\n * システム管理API\n */\n system = {\n /**\n * システム設定を取得(プロセス代数分析含む)\n */\n getConfig: async (): Promise<ApiV3Response<ActorSystemConfig>> => {\n return this.request<ActorSystemConfig>(\"/system/config\")\n },\n\n /**\n * システム統計を取得\n */\n getStats: async (): Promise<ApiV3Response<SystemStatsResponse>> => {\n return this.request<SystemStatsResponse>(\"/system/stats\")\n }\n }\n}\n\n/**\n * LangChain.js互換性ラッパー\n */\nexport class ActorV3Runnable {\n constructor(\n private actorId: ActorID,\n private client: ActorV3Client\n ) {}\n\n /**\n * LangChain.js invoke() 互換メソッド\n */\n async invoke(input: any, config?: RunnableConfig): Promise<any> {\n // 1. LangChain input → Actor v3 Message\n const message = typeof input === 'string' \n ? createMessage('invoke', { content: input })\n : langChainToActorV3({\n role: 'user',\n content: typeof input === 'string' ? input : JSON.stringify(input)\n })\n\n // 2. Actor v3 send operation\n const sendResult = await this.client.actors.send(this.actorId, {\n target: this.actorId,\n message\n })\n\n if (!sendResult.success) {\n throw new Error(`Failed to send message: ${sendResult.error?.message}`)\n }\n\n // 3. Actor v3 receive operation\n const receiveResult = await this.client.actors.receive(this.actorId, {\n max_messages: 1,\n timeout: config?.timeout || 30000\n })\n\n if (!receiveResult.success) {\n throw new Error(`Failed to receive message: ${receiveResult.error?.message}`)\n }\n\n // 4. Actor v3 result → LangChain output\n const { messages, behavior_results } = receiveResult.data!\n \n if (behavior_results.length > 0 && behavior_results[0].actions.length > 0) {\n const outAction = behavior_results[0].actions[0]\n if (outAction.type === 'send' && outAction.message) {\n return actorV3ToLangChain(outAction.message)\n }\n }\n\n if (messages.length > 0) {\n return actorV3ToLangChain(messages[0])\n }\n\n return { role: 'assistant', content: 'No response generated' }\n }\n\n /**\n * LangChain.js stream() 互換メソッド\n */\n async *stream(input: any, config?: RunnableConfig): AsyncGenerator<any, any, unknown> {\n const message = typeof input === 'string'\n ? createMessage('stream', { content: input })\n : langChainToActorV3({\n role: 'user',\n content: typeof input === 'string' ? input : JSON.stringify(input)\n })\n\n await this.client.actors.send(this.actorId, {\n target: this.actorId,\n message\n })\n\n // Poll for messages with streaming-like behavior\n let receivedCount = 0\n const maxMessages = config?.maxMessages || 10\n\n while (receivedCount < maxMessages) {\n const { data } = await this.client.actors.receive(this.actorId, {\n max_messages: 1,\n timeout: 1000\n })\n\n if (data?.messages && data.messages.length > 0) {\n for (const msg of data.messages) {\n yield actorV3ToLangChain(msg)\n receivedCount++\n }\n } else {\n // No more messages, break\n break\n }\n }\n }\n\n /**\n * LangChain.js batch() 互換メソッド\n */\n async batch(inputs: any[], config?: RunnableConfig): Promise<any[]> {\n const promises = inputs.map(input => this.invoke(input, config))\n return Promise.all(promises)\n }\n\n /**\n * LangChain.js pipe() 互換メソッド\n */\n pipe<T>(next: T): T {\n // 簡単な実装。実際にはパイプライン機能を実装する必要がある\n return next\n }\n\n /**\n * LangChain.js withFallbacks() 互換メソッド\n */\n withFallbacks(fallbacks: any[]): ActorV3Runnable {\n // 簡単な実装。実際にはフォールバック機能を実装する必要がある\n return this\n }\n}\n\n/**\n * デフォルトクライアントインスタンス\n */\nexport const actorV3Api = new ActorV3Client()\n\n/**\n * サンプルBehavior作成ヘルパー\n */\nexport function createSampleBehavior(name: string, description: string): Behavior {\n return {\n id: crypto.randomUUID(),\n name,\n description,\n version: '1.0.0',\n handler: async (message: Message, state: State) => {\n // サンプル実装:エコー機能\n return {\n new_state: { ...state, last_message: message },\n actions: [{\n type: 'send',\n target: message.sender,\n message: createMessage('response', {\n content: `Echo: ${JSON.stringify(message.payload)}`\n })\n }]\n }\n },\n metadata: {\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n author: 'system',\n tags: ['sample', 'echo'],\n capabilities: ['message_processing']\n },\n process_algebra: {\n notation: 'CCS',\n expression: `${name}(x) = x?.input(msg).x!output(echo(msg)).${name}(x)`,\n channels: ['input', 'output']\n }\n }\n} ","/**\n * Actor v3 LangChain Chat API クライアント\n * https://api.actor.gftd.ai/v3/langchain/actor を使用したチャット機能を提供\n */\n\nexport interface ChatMessage {\n id: string\n role: \"user\" | \"assistant\" | \"system\"\n content: string\n timestamp: Date\n}\n\nexport interface LangChainActorConfig {\n name: string\n description?: string\n model?: \"gpt-4o\" | \"gpt-4o-mini\" | \"gpt-4-turbo\" | \"gpt-4\" | \"gpt-3.5-turbo\"\n temperature?: number\n max_tokens?: number\n system_prompt?: string\n organization_id: string\n openai_api_key?: string\n max_history_length?: number\n actor_id?: string\n}\n\nexport interface LangChainActorResponse {\n actor_id: string\n actor: any // ActorState\n config: LangChainActorConfig\n endpoints: {\n chat: string\n system_prompt: string\n config_update: string\n stats: string\n }\n}\n\nexport interface ChatRequest {\n message: string\n conversation_id?: string\n timeout?: number\n stream?: boolean\n}\n\nexport interface ChatResponse {\n content: string\n usage: {\n total_tokens: number\n prompt_tokens: number\n completion_tokens: number\n }\n model: string\n conversation_id: string\n execution_time_ms: number\n timestamp: string\n}\n\n/**\n * Actor v3 LangChain Chat API クライアントクラス\n * Actor v3のLangChain統合機能を使用したチャット機能を提供\n */\nexport class ActorV3ChatClient {\n private baseUrl: string\n private headers: HeadersInit\n private organizationId: string\n private currentActorId: string | null = null\n\n constructor(\n baseUrl = \"https://actor.gftd.ai/api/v3\",\n organizationId = \"actors\",\n apiKey?: string\n ) {\n this.baseUrl = baseUrl.replace(/\\/$/, \"\") // 末尾のスラッシュを削除\n this.organizationId = organizationId\n this.headers = {\n \"Content-Type\": \"application/json\",\n \"Accept\": \"application/json\",\n }\n\n if (apiKey) {\n this.headers[\"Authorization\"] = `Bearer ${apiKey}`\n }\n }\n\n /**\n * LangChain Actor を作成\n * @param config LangChain Actor設定\n * @returns LangChain Actor作成レスポンス\n */\n async createLangChainActor(config: Partial<LangChainActorConfig>): Promise<LangChainActorResponse> {\n try {\n const actorConfig: LangChainActorConfig = {\n name: config.name || \"GFTD Chat Assistant\",\n description: config.description || \"AI会話アシスタント\",\n model: config.model || \"gpt-3.5-turbo\",\n temperature: config.temperature || 0.7,\n max_tokens: config.max_tokens || 1000,\n system_prompt: config.system_prompt || \"あなたは親切で知識豊富なAIアシスタントです。\",\n organization_id: this.organizationId,\n max_history_length: config.max_history_length || 50,\n ...config,\n }\n\n const response = await fetch(`${this.baseUrl}/langchain/actor`, {\n method: \"POST\",\n headers: this.headers,\n body: JSON.stringify(actorConfig),\n })\n\n if (!response.ok) {\n throw new Error(`LangChain Actor作成エラー: ${response.status} ${response.statusText}`)\n }\n\n const data = await response.json()\n this.currentActorId = data.actor_id\n return data as LangChainActorResponse\n } catch (error) {\n console.error(\"LangChain Actor作成エラー:\", error)\n throw error\n }\n }\n\n /**\n * チャットメッセージを送信\n * @param actorId Actor ID\n * @param request チャットリクエスト\n * @returns チャットレスポンス\n */\n async sendChatMessage(actorId: string, request: ChatRequest): Promise<ChatResponse> {\n try {\n const response = await fetch(`${this.baseUrl}/langchain/actor/${actorId}/chat`, {\n method: \"POST\",\n headers: this.headers,\n body: JSON.stringify(request),\n })\n\n if (!response.ok) {\n throw new Error(`チャットメッセージ送信エラー: ${response.status} ${response.statusText}`)\n }\n\n const data = await response.json()\n return data as ChatResponse\n } catch (error) {\n console.error(\"チャットメッセージ送信エラー:\", error)\n throw error\n }\n }\n\n /**\n * 現在のActorでチャット(簡易版)\n * @param message メッセージ内容\n * @param conversationId 会話ID(オプション)\n * @returns チャットレスポンス\n */\n async chat(message: string, conversationId?: string): Promise<ChatResponse> {\n // Actorが存在しない場合は作成\n if (!this.currentActorId) {\n await this.createLangChainActor({})\n }\n\n if (!this.currentActorId) {\n throw new Error(\"LangChain Actorの作成に失敗しました\")\n }\n\n return this.sendChatMessage(this.currentActorId, {\n message,\n conversation_id: conversationId || \"default-conversation\",\n })\n }\n\n /**\n * システムプロンプトを更新\n * @param actorId Actor ID\n * @param systemPrompt 新しいシステムプロンプト\n */\n async updateSystemPrompt(actorId: string, systemPrompt: string): Promise<void> {\n try {\n const response = await fetch(`${this.baseUrl}/langchain/actor/${actorId}/system-prompt`, {\n method: \"PUT\",\n headers: this.headers,\n body: JSON.stringify({ system_prompt: systemPrompt }),\n })\n\n if (!response.ok) {\n throw new Error(`システムプロンプト更新エラー: ${response.status} ${response.statusText}`)\n }\n } catch (error) {\n console.error(\"システムプロンプト更新エラー:\", error)\n throw error\n }\n }\n\n /**\n * APIの健全性をチェック\n * @returns APIが利用可能かどうか\n */\n async healthCheck(): Promise<boolean> {\n try {\n const response = await fetch(`${this.baseUrl}/actor`, {\n method: \"GET\",\n headers: { \"Accept\": \"application/json\" },\n // タイムアウトを追加\n signal: AbortSignal.timeout(5000)\n })\n return response.ok\n } catch (error) {\n // ネットワークエラーは静かに処理\n return false\n }\n }\n\n /**\n * 現在のActor IDを取得\n * @returns 現在のActor ID\n */\n getCurrentActorId(): string | null {\n return this.currentActorId\n }\n\n /**\n * Actor IDを手動設定\n * @param actorId 設定するActor ID\n */\n setCurrentActorId(actorId: string): void {\n this.currentActorId = actorId\n }\n}\n\n/**\n * デフォルトのActor v3 Chat APIクライアントインスタンス\n */\nexport const actorV3ChatClient = new ActorV3ChatClient() ","\"use client\"\n\n/**\n * Actor v3 管理用React Hooks\n * プロセス代数とLangChain.js互換性対応\n * https://actor.gftd.ai/api/v3/actor\n */\n\nimport { useState, useEffect, useCallback } from \"react\"\nimport {\n ActorV3Client,\n ActorV3Runnable,\n actorV3Api,\n createSampleBehavior\n} from \"@/lib/api/actor-v3-client\"\nimport {\n ActorID,\n Message,\n State,\n Behavior,\n CreateActorRequest,\n CreateActorResponse,\n SendMessageRequest,\n ReceiveMessagesRequest,\n ListActorsResponse,\n ActorSystemConfig,\n SystemStatsResponse,\n ApiV3Response,\n createMessage\n} from \"@/lib/types/actor-v3\"\n\n/**\n * Actor v3 一覧管理Hook\n */\nexport function useActorV3List(organizationId?: string) {\n const [actors, setActors] = useState<ListActorsResponse[\"actors\"]>([])\n const [loading, setLoading] = useState<boolean>(false)\n const [error, setError] = useState<string | null>(null)\n const [totalCount, setTotalCount] = useState<number>(0)\n\n const fetchActors = useCallback(async () => {\n setLoading(true)\n setError(null)\n\n try {\n console.log('🎭 Fetching v3 actors with process algebra support:', organizationId)\n const response = await actorV3Api.actors.list(organizationId)\n \n if (response.success && response.data) {\n // 安全なデータ取得\n const actors = response.data.actors || []\n const totalCount = response.data.total_count || 0\n \n setActors(actors)\n setTotalCount(totalCount)\n \n console.log('✅ v3 actors loaded:', {\n count: actors.length,\n total: totalCount,\n actors: actors.map(a => ({\n id: a?.actor_id || 'unknown',\n name: a?.behavior_name || 'unnamed',\n status: a?.status || 'unknown'\n }))\n })\n } else {\n setError(response.error?.message || \"Failed to fetch v3 actors\")\n console.error('❌ v3 actors fetch failed:', response.error)\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : \"Unknown error\"\n setError(errorMsg)\n console.warn('❌ v3 actors fetch error:', err)\n } finally {\n setLoading(false)\n }\n }, [organizationId])\n\n // APIが利用可能になったので自動実行を有効化\n useEffect(() => {\n fetchActors()\n }, [fetchActors])\n\n const refetch = useCallback(() => {\n fetchActors()\n }, [fetchActors])\n\n return {\n actors,\n loading,\n error,\n totalCount,\n refetch,\n }\n}\n\n/**\n * Actor v3 作成Hook\n */\nexport function useActorV3Creation() {\n const [loading, setLoading] = useState<boolean>(false)\n const [error, setError] = useState<string | null>(null)\n\n const createActor = useCallback(async (\n behavior: Behavior,\n organizationId: string,\n initialState?: State\n ): Promise<CreateActorResponse | null> => {\n setLoading(true)\n setError(null)\n\n try {\n console.log('🎭 Creating v3 actor with process algebra behavior:', {\n name: behavior.name,\n version: behavior.version,\n processAlgebra: behavior.process_algebra,\n capabilities: behavior.metadata.capabilities\n })\n\n const request: CreateActorRequest = {\n behavior,\n organization_id: organizationId,\n initial_state: initialState\n }\n\n const response = await actorV3Api.actors.create(request)\n \n if (response.success && response.data) {\n console.log('✅ v3 actor created:', {\n actor_id: response.data.actor_id,\n status: response.data.status,\n timestamp: response.data.timestamp\n })\n return response.data\n } else {\n setError(response.error?.message || \"Failed to create v3 actor\")\n console.error('❌ v3 actor creation failed:', response.error)\n return null\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : \"Unknown error\"\n setError(errorMsg)\n console.error('❌ v3 actor creation error:', err)\n return null\n } finally {\n setLoading(false)\n }\n }, [])\n\n const createSampleActor = useCallback(async (\n name: string,\n description: string,\n organizationId: string\n ) => {\n const behavior = createSampleBehavior(name, description)\n return createActor(behavior, organizationId)\n }, [createActor])\n\n return {\n createActor,\n createSampleActor,\n loading,\n error,\n }\n}\n\n/**\n * Actor v3 メッセージング Hook\n */\nexport function useActorV3Messaging(actorId: ActorID) {\n const [loading, setLoading] = useState<boolean>(false)\n const [error, setError] = useState<string | null>(null)\n const [messages, setMessages] = useState<Message[]>([])\n\n const sendMessage = useCallback(async (\n label: string,\n payload: Record<string, any>,\n target?: ActorID\n ) => {\n setLoading(true)\n setError(null)\n\n try {\n const message = createMessage(label, payload)\n const request: SendMessageRequest = {\n target: target || actorId,\n message\n }\n\n console.log('📨 Sending v3 message:', {\n actorId,\n label,\n payload,\n target: target || actorId\n })\n\n const response = await actorV3Api.actors.send(actorId, request)\n \n if (response.success) {\n console.log('✅ v3 message sent:', response.data)\n return response.data\n } else {\n setError(response.error?.message || \"Failed to send message\")\n console.error('❌ v3 message send failed:', response.error)\n return null\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : \"Unknown error\"\n setError(errorMsg)\n console.error('❌ v3 message send error:', err)\n return null\n } finally {\n setLoading(false)\n }\n }, [actorId])\n\n const receiveMessages = useCallback(async (\n request: ReceiveMessagesRequest = {}\n ) => {\n setLoading(true)\n setError(null)\n\n try {\n console.log('📬 Receiving v3 messages:', { actorId, request })\n \n const response = await actorV3Api.actors.receive(actorId, request)\n \n if (response.success && response.data) {\n const newMessages = response.data.messages\n setMessages(prev => [...prev, ...newMessages])\n \n console.log('✅ v3 messages received:', {\n count: newMessages.length,\n behavior_results: response.data.behavior_results.length\n })\n \n return response.data\n } else {\n setError(response.error?.message || \"Failed to receive messages\")\n console.error('❌ v3 message receive failed:', response.error)\n return null\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : \"Unknown error\"\n setError(errorMsg)\n console.error('❌ v3 message receive error:', err)\n return null\n } finally {\n setLoading(false)\n }\n }, [actorId])\n\n const clearMessages = useCallback(() => {\n setMessages([])\n }, [])\n\n return {\n sendMessage,\n receiveMessages,\n clearMessages,\n messages,\n loading,\n error,\n }\n}\n\n/**\n * LangChain.js互換 Actor v3 Hook\n */\nexport function useActorV3Runnable(actorId: ActorID) {\n const [runnable] = useState(() => new ActorV3Runnable(actorId, actorV3Api))\n const [loading, setLoading] = useState<boolean>(false)\n const [error, setError] = useState<string | null>(null)\n\n const invoke = useCallback(async (input: any, config?: any) => {\n setLoading(true)\n setError(null)\n\n try {\n console.log('🔄 v3 LangChain invoke:', { actorId, input })\n const result = await runnable.invoke(input, config)\n console.log('✅ v3 LangChain invoke result:', result)\n return result\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : \"Invoke failed\"\n setError(errorMsg)\n console.error('❌ v3 LangChain invoke error:', err)\n throw err\n } finally {\n setLoading(false)\n }\n }, [runnable, actorId])\n\n const batch = useCallback(async (inputs: any[], config?: any) => {\n setLoading(true)\n setError(null)\n\n try {\n console.log('🔄 v3 LangChain batch:', { actorId, inputs })\n const results = await runnable.batch(inputs, config)\n console.log('✅ v3 LangChain batch results:', results)\n return results\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : \"Batch failed\"\n setError(errorMsg)\n console.error('❌ v3 LangChain batch error:', err)\n throw err\n } finally {\n setLoading(false)\n }\n }, [runnable, actorId])\n\n return {\n runnable,\n invoke,\n batch,\n loading,\n error,\n }\n}\n\n/**\n * Actor v3 システム管理Hook\n */\nexport function useActorV3System() {\n const [config, setConfig] = useState<ActorSystemConfig | null>(null)\n const [stats, setStats] = useState<SystemStatsResponse | null>(null)\n const [loading, setLoading] = useState<boolean>(false)\n const [error, setError] = useState<string | null>(null)\n\n const fetchConfig = useCallback(async () => {\n setLoading(true)\n setError(null)\n\n try {\n console.log('⚙️ Fetching v3 system config with process algebra analysis')\n const response = await actorV3Api.system.getConfig()\n \n if (response.success && response.data) {\n setConfig(response.data)\n console.log('✅ v3 system config loaded:', {\n deadlock_free: response.data.process_algebra_analysis.deadlock_free,\n livelock_free: response.data.process_algebra_analysis.livelock_free,\n topology_edges: response.data.communication_topology.edges.length\n })\n } else {\n const errorMsg = response.error?.message || \"Failed to fetch system config\"\n setError(errorMsg)\n console.warn('⚠️ v3 system config fetch failed:', response.error)\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : \"Unknown error\"\n setError(errorMsg)\n console.warn('❌ v3 system config fetch error:', err)\n } finally {\n setLoading(false)\n }\n }, [])\n\n const fetchStats = useCallback(async () => {\n setLoading(true)\n setError(null)\n\n try {\n console.log('📊 Fetching v3 system stats')\n const response = await actorV3Api.system.getStats()\n \n if (response.success && response.data) {\n setStats(response.data)\n console.log('✅ v3 system stats loaded:', {\n active_actors: response.data.stats.active_actors,\n total_messages: response.data.stats.total_messages,\n throughput: response.data.detailed_metrics.performance_metrics.throughput\n })\n } else {\n const errorMsg = response.error?.message || \"Failed to fetch system stats\"\n setError(errorMsg)\n console.warn('⚠️ v3 system stats fetch failed:', response.error)\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : \"Unknown error\"\n setError(errorMsg)\n console.warn('❌ v3 system stats fetch error:', err)\n } finally {\n setLoading(false)\n }\n }, [])\n\n const refreshAll = useCallback(async () => {\n await Promise.all([fetchConfig(), fetchStats()])\n }, [fetchConfig, fetchStats])\n\n // 自動実行は無効化 - 必要に応じて手動でrefreshAllを呼び出す\n // useEffect(() => {\n // refreshAll()\n // }, [refreshAll])\n\n return {\n config,\n stats,\n loading,\n error,\n fetchConfig,\n fetchStats,\n refreshAll,\n }\n}\n\n/**\n * Actor v3 ヘルスチェック Hook\n */\nexport function useActorV3Health() {\n const [status, setStatus] = useState<'checking' | 'healthy' | 'unhealthy' | 'unknown'>('unknown')\n const [lastChecked, setLastChecked] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n\n const checkHealth = useCallback(async () => {\n setStatus('checking')\n setError(null)\n\n try {\n console.log('🏥 Checking v3 API health')\n \n // 簡単なヘルスチェック:actor一覧を取得\n const response = await actorV3Api.actors.list()\n \n if (response.success) {\n setStatus('healthy')\n setLastChecked(new Date().toISOString())\n console.log('✅ v3 API is healthy')\n } else {\n setStatus('unhealthy')\n setError(response.error?.message || \"Health check failed\")\n console.warn('❌ v3 API health check failed:', response.error)\n }\n } catch (err) {\n setStatus('unhealthy')\n const errorMsg = err instanceof Error ? err.message : \"Health check error\"\n setError(errorMsg)\n console.warn('❌ v3 API health check error:', err)\n }\n }, [])\n\n // APIが利用可能になったのでヘルスチェックを有効化\n useEffect(() => {\n checkHealth()\n \n // 定期的なヘルスチェック(1分間隔)\n const interval = setInterval(checkHealth, 60000)\n return () => clearInterval(interval)\n }, [checkHealth])\n\n return {\n status,\n lastChecked,\n error,\n checkHealth,\n }\n} ","/**\n * Actor v3 LangChain Chat API用Reactフック\n * Actor v3のLangChain統合を使用したチャット機能の状態管理とAPI呼び出しを提供\n */\n\nimport { useState, useCallback, useRef, useEffect } from \"react\"\nimport { actorV3ChatClient, type ChatMessage, type ChatRequest } from \"@/lib/api/chat-client\"\n\nexport interface UseGftdChatOptions {\n initialMessages?: ChatMessage[]\n model?: string\n temperature?: number\n maxTokens?: number\n}\n\nexport interface UseGftdChatReturn {\n messages: ChatMessage[]\n isLoading: boolean\n error: string | null\n isConnected: boolean\n sendMessage: (content: string) => Promise<void>\n clearMessages: () => void\n retryLastMessage: () => Promise<void>\n setMessages: (messages: ChatMessage[]) => void\n}\n\n/**\n * GFTD Chat APIを使用するためのカスタムフック\n * @param options チャット設定オプション\n * @returns チャット機能のインターフェース\n */\nexport function useGftdChat(options: UseGftdChatOptions = {}): UseGftdChatReturn {\n const {\n initialMessages = [],\n model = \"gpt-3.5-turbo\",\n temperature = 0.7,\n maxTokens = 1000,\n } = options\n\n const [messages, setMessages] = useState<ChatMessage[]>(initialMessages)\n const [isLoading, setIsLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [isConnected, setIsConnected] = useState(false)\n const lastUserMessageRef = useRef<string>(\"\")\n\n // API接続状態を定期的にチェック\n useEffect(() => {\n const checkConnection = async () => {\n try {\n const connected = await actorV3ChatClient.healthCheck()\n setIsConnected(connected)\n } catch (error) {\n setIsConnected(false)\n }\n }\n\n // 初回チェック\n checkConnection()\n\n // 5分ごとにヘルスチェック(頻度を下げてエラーログを減らす)\n const interval = setInterval(checkConnection, 300000)\n\n return () => clearInterval(interval)\n }, [])\n\n /**\n * ユーザーメッセージを送信してAIからの返答を取得\n * @param content ユーザーのメッセージ内容\n */\n const sendMessage = useCallback(async (content: string) => {\n if (!content.trim()) return\n if (isLoading) return\n\n setError(null)\n setIsLoading(true)\n lastUserMessageRef.current = content\n\n // ユーザーメッセージを追加\n const userMessage: ChatMessage = {\n id: `user-${Date.now()}`,\n role: \"user\",\n content: content.trim(),\n timestamp: new Date(),\n }\n\n setMessages(prevMessages => [...prevMessages, userMessage])\n\n try {\n // Actor v3 LangChain統合のAPI呼び出し\n const response = await actorV3ChatClient.chat(content, \"default-conversation\")\n\n // レスポンスの安全性確認\n if (!response || typeof response.content !== 'string') {\n throw new Error(\"APIから無効な応答が返されました\")\n }\n\n const assistantMessage: ChatMessage = {\n id: `assistant-${Date.now()}`,\n role: \"assistant\",\n content: response.content,\n timestamp: new Date(),\n }\n\n setMessages(prevMessages => [...prevMessages, assistantMessage])\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"メッセージの送信に失敗しました\"\n setError(errorMessage)\n\n // ネットワークエラーは静かに処理\n if (errorMessage.includes('fetch') || errorMessage.includes('network')) {\n console.warn(\"チャットAPI接続エラー:\", errorMessage)\n } else {\n console.error(\"チャットメッセージ送信エラー:\", error)\n \n // エラーメッセージを表示\n const errorChatMessage: ChatMessage = {\n id: `error-${Date.now()}`,\n role: \"assistant\",\n content: `❌ エラー: ${errorMessage}`,\n timestamp: new Date(),\n }\n\n setMessages(prevMessages => [...prevMessages, errorChatMessage])\n }\n } finally {\n setIsLoading(false)\n }\n }, [messages, isLoading, model, temperature, maxTokens])\n\n /**\n * 最後のユーザーメッセージを再送信\n */\n const retryLastMessage = useCallback(async () => {\n if (lastUserMessageRef.current && !isLoading) {\n await sendMessage(lastUserMessageRef.current)\n }\n }, [sendMessage, isLoading])\n\n /**\n * メッセージ履歴をクリア\n */\n const clearMessages = useCallback(() => {\n setMessages([])\n setError(null)\n lastUserMessageRef.current = \"\"\n }, [])\n\n return {\n messages,\n isLoading,\n error,\n isConnected,\n sendMessage,\n clearMessages,\n retryLastMessage,\n setMessages,\n }\n} ","/**\n * @file lib/config/sdk-config-manager.ts\n * @description SDK起動時のconfigファイル管理\n * @author GFTD Co., Ltd.\n */\n\nexport interface SDKConfig {\n version: string\n initialized: boolean\n defaultActorId?: string\n actors: {\n [key: string]: {\n id: string\n name: string\n type: string\n repositoryType: 'local' | 'online'\n repositoryPath: string\n repositoryUrl?: string\n gitConfig?: any\n lastAccessed: string\n isDefault?: boolean\n }\n }\n settings: {\n theme: 'light' | 'dark'\n autoSave: boolean\n showWelcome: boolean\n defaultView: 'actors' | 'code' | 'preview'\n }\n created: string\n lastModified: string\n}\n\n/**\n * デフォルトアクター設定テンプレート\n */\nexport interface DefaultActorTemplate {\n name: string\n description: string\n type: string\n repositoryType: 'local'\n gitConfig: {\n user: {\n name: string\n email: string\n }\n remoteUrl?: string\n defaultBranch: string\n autoCommit: boolean\n autoSync: boolean\n }\n}\n\n/**\n * 利用可能なデフォルトアクタータイプ\n */\nexport const DEFAULT_ACTOR_TEMPLATES: Record<string, DefaultActorTemplate> = {\n 'chat-assistant': {\n name: 'Chat Assistant',\n description: 'AI-powered chat ass