LifeOSAIエージェントシステム
UIの下にあるシステム
エージェントシステム、企業オーケストレーション、チャネルシステム、ハーネスとエージェントランタイム — リクエストの流れ、エージェントの起動と実行、設定・シークレット・ファイル・ライブイベントの所有先。
この文書は、UIレイヤーより下のLifeOSAIシステム・アーキテクチャを記述します。以下の4領域に焦点を当てます。
- LifeOSAIエージェントシステム
- 企業オーケストレーションシステム
- チャネルシステム
- ハーネスとエージェントランタイム
リクエストがシステムをどう流れるか、エージェントがどう起動・実行されるか、チャネルメッセージがどうルーティングされるか、そしてランタイム設定・シークレット・ファイル・ライブイベントの所有先を説明することを目的としています。
システム境界
LifeOSAIはクロスプラットフォームのエージェントオペレーティングシステムです。同じプロダクトモデルが2つのデプロイモードで動作します。
- クラウドモード: ブラウザトラフィックがクラウドサービスで処理され、エージェントランタイムはクラウドインフラで動作します。
- ローカルモード: Tauriデスクトップアプリがローカルサイドカーを起動し、ローカルファイルとローカルデータストアを使用します。
高位のサービス境界は以下の通りです。
apps/web または外部チャネルトランスポートapps/user-managementapps/apipackages/agent ランタイムアダプタapps/user-management はブラウザ向けのルーティングハブです。ユーザーセッションを検証し、プロダクトリクエストを正しいバックエンドサービスへ転送します。エージェント実行は apps/api、特にオーケストレーションエンジンとランタイムインボーカが所有します。
サービス責務
| レイヤー | 所有者 | 責務 |
|---|---|---|
| プロダクトエントリ | apps/web | LifeOSAIチャット、企業、アプリ、ファイル、設定、静的エクスポート対応シェル |
| デスクトップシェル | apps/tauri | ローカルデスクトップラッパー、アップデータ、サイドカープロセス管理 |
| ルーティングハブ | apps/user-management | ユーザー認証APIゲートウェイ、セッションリーダー、オーケストレーションプロキシ、ファイルプロキシ |
| エージェントAPI | apps/api | エージェントランタイムAPI、企業オーケストレーション、ウェイクアップ、スケジューラ、チャネル、シークレット |
| ランタイムSDK | packages/agent | ランタイム抽象化、Claude Codeアダプタ、Pi Agentアダプタ、正規化ストリーミングイベント |
| 共有契約 | packages/shared | オーケストレーション型、ライブイベント定数、環境変数正規化、バリデータ |
| 永続データ | Prisma DB | 企業、エージェント、課題、実行、ルーチン、アクティビティ、シークレット、チャネル状態 |
| ワークスペースデータ | ファイルシステムまたはマウントボリューム | チャットワークスペース、企業プロジェクトファイル、アーティファクト、スキル、ログ |
LifeOSAIエージェントシステム
エージェントシステムは通常のチャット、企業エージェントとのダイレクトチャット、ライブ実行トランスクリプトをカバーします。企業タスクオーケストレーションとは意図的に分離されていますが、両者は同じランタイムアダプタを使えます。
エージェントインタラクションモード
| モード | 説明 | 主要な状態 |
|---|---|---|
| LifeOSAIチャット | ユーザーが企業タスクの外で選択ランタイムとチャット | チャットセッションID、ランタイム、モデル |
| 企業エージェントとのダイレクトチャット | ユーザーが企業エージェントと直接対話 | 企業ID、エージェントID、記憶されたセッションID |
| ライブ実行トランスクリプト | UIがアクティブなオーケストレーション実行を追跡 | 実行ID、セッションID、ランタイムログストリーム |
| 完了済みトランスクリプト再生 | UIが過去の実行/セッションを読む | 保存済みセッションメッセージ |
| チャネル会話 | WhatsApp、Telegram、その他のトランスポートがエージェントと対話 | チャネルセッションキー、チャネルメタデータ、ランタイムセッションID |
フロントエンドはこれらのモードを異なる形で提示するかもしれませんが、バックエンドの契約は同じ考え方です: セッションがランタイムに紐付き、ランタイムがイベントをストリームし、それらのイベントがトランスクリプトレコードまたはライブ実行イベントとなります。
エージェント機能
LifeOSAIエージェントは以下によって拡張できます。
- スキル: バンドル、企業スコープ、またはユーザーアップロードの機能フォルダ
- プラグイン: インストールされたランタイム拡張とツールバンドル
- コネクタ: 外部アカウントまたはサービス統合
- MCPサーバー: チャネル、ブラウザ、Slack、カスタムツールなどのツールサーバー
- ファイル: 許可されたワークスペースルートと企業/プロジェクトファイルルート
- チャネル: トランスポート固有の受信メッセージと送信応答
ランタイムプロセスは、以下の組み合わせによってこれらの機能を受け取ります。
apps/apiから渡されるランタイムオプション- 起動前に組み立てられる環境変数
- MCPサーバー定義
- 追加スキルディレクトリ
- アダプタ固有のコマンドまたはSDKオプション
チャットセッションフロー
apps/webapps/user-management セッション/チャットルートapps/api またはランタイムハンドラpackages/agent ランタイムセッション発見とセッションメッセージ参照は別の関心事です。セッションリストは既知のLifeOSAIルートに限定し続けるべきです。メッセージ参照は、実行/セッションが既知の企業エージェントトランスクリプトパスを指している場合、それを解決できます。
企業オーケストレーションシステム
企業システムはマルチエージェント・オーケストレーション層です。企業、エージェント、プロジェクト、ゴール、課題、ルーチン、アクティビティ、実行、承認、企業スコープのファイルを所有します。
主要ドメインオブジェクト
| オブジェクト | 目的 |
|---|---|
| Company | エージェント、課題、プロジェクト、シークレット、チャネル、ファイルのテナント境界 |
| Agent | 役割、アダプタ設定、ランタイム設定、インストラクション、スキル、環境変数を持つ企業のチームメイト |
| Project | 課題とファイル向けのワークスペースとプロジェクトスコープの設定 |
| Goal | 課題やルーチンをまとめる高位の目標 |
| Issue | エージェントに割り当てられる、またはライフサイクル状態を移行する企業作業の単位 |
| Routine | エージェントが所有するスケジュール型またはトリガー型の定期作業 |
| Wakeup request | エージェントを実行する理由を伝える永続キュー項目 |
| Heartbeat run | 1回のエージェント呼び出しの実行記録 |
| Activity log | ユーザー、エージェント、システムアクションの監査/イベント履歴 |
| Company secret | 環境変数バインディングで使用される企業スコープのシークレット参照 |
ウェイクソース
エージェント実行は次のソースから開始される可能性があります。
- エージェントに割り当てられた課題
- 課題コメントまたはメンション
- 承認段階または審査決定
- ユーザーがハートビート実行をクリック
- バックグラウンドのハートビートタイマー発火
- ルーチンタイマー発火
- チャネル受信メッセージがエージェントにルーティング
- 企業エージェントへのダイレクトチャットメッセージ送信
これらはすべて実行前にウェイクコンテキストに正規化されます。エージェントは、ウェイクがUI、タイマー、課題、チャネルのどこから来たかを、受け取るウェイクフィールドを通じて以外は知る必要はありません。
ウェイクアップキューフロー
apps/api/src/orchestration/engine/wakeup.ts が永続キューのヘルパーを所有します。
enqueueWakeup(agentId, source, reason, payload, contextSnapshot)agentWakeupRequest ステータスがqueuedheartbeat_runs 行が作成または更新agent-invoker がランタイムプロセスを起動ウェイクアップレコードが捕捉する情報:
agentIdsourcetriggerDetailreasonpayloadcontextSnapshot- キューステータスとタイムスタンプ
コンテキストスナップショットは、プロダクトイベントからランタイム実行への安定した受け渡しとなるため重要です。例えば、課題割り当てウェイクアップには、後で課題が変わったとしても課題IDとソースコンテキストが含まれます。
実行ライフサイクル
実行ステータスはエージェントステータスと同じではありません。
queued -> running -> succeeded | failed | cancelled実行ステータスは1つの実行試行を表現します。エージェントステータスはエージェントの可視状態を表現します。queued状態の実行が、既にrunning状態のエージェントを「停止した」ように上書きすべきではありません。UIとイベント利用者は、実行ライフサイクルイベントとエージェントライフサイクルイベントを別ストリームとして扱うべきです。
エージェントステータス
エージェントステータスは、エージェント状態が実際に変化したときにのみ更新すべきです。例:
- idle
- active
- running
- paused
- error
キュー中の作業は実行のプロパティです。エージェント近くに表示してもよいですが、バックエンドが意図的にエージェントステータスイベントを設定しない限り、エージェントの主要ライフサイクルとして扱うべきではありません。
ライブイベントバス
apps/api/src/orchestration/engine/event-bus.ts が企業ライブイベントを発行します。共有型は packages/shared/src/orchestration/types/live.ts に、イベント名は packages/shared/src/orchestration/constants.ts にあります。
主要なイベントファミリー:
| イベントファミリー | 目的 |
|---|---|
heartbeat.run.queued | 実行が存在し、待機中または起動中 |
heartbeat.run.running | 実行が開始された |
heartbeat.run.log | ランタイムSDKストリームイベント、ツールイベント、テキスト、思考、システムイベント |
heartbeat.run.completed | 実行が成功裏に完了 |
heartbeat.run.failed | 実行が失敗 |
heartbeat.run.cancelled | 実行がキャンセルされた |
agent.status | エージェント状態が変化 |
issue.created | エージェントまたはユーザーが課題を作成 |
issue.updated | ステータスや担当者を含む課題フィールドが変更 |
issue.comment.created | コメントが書き込まれた |
issue.deleted | 課題がソフトまたはハード削除された |
activity.logged | 監査ログエントリが作成された |
ライブイベントペイロードには、利用者が企業全体を再取得せずに更新できる十分な非正規化データを含めるべきです。
- 実行ID、実行ステータス、セッションID、アダプタ種別、タイムスタンプ
- エージェントID、エージェント名、役割、ステータス、アダプタ/ランタイムメタデータ
- 課題ID、識別子、タイトル、ステータス、担当者、プロジェクト、ゴール
- アクティビティのアクター、アクション、エンティティ、詳細
復旧時の再取得は依然として許容されますが、通常パスではイベントペイロードを直接消費すべきです。
アクティビティログ
アクティビティログはUIフィード項目だけでなく監査記録です。以下を保存します。
- 企業ID
- アクター種別
- アクターID
- エージェントID
- 実行ID
- アクション
- エンティティ種別
- エンティティID
- 詳細
ライブイベントがメモリから消えた後でも、課題、実行、ルーチン、エージェントアクションの周辺で何が起きたかを再構築するために使用されます。
チャネルシステム
チャネルは、外部トランスポートがLifeOSAIエージェントと通信することを可能にします。
現在のチャネル構成:
- WhatsAppプラグイン
- Telegramプラグイン
- チャネルレジストリ
- チャネルセッションストア
- 受信ディスパッチ
- 送信メッセージツール
中心となる送信契約はチャネルメッセージツールです。Claude Codeはこれを mcp__channels__message として受け取ります。Pi Agentもランタイムツールパス配下に同等のツール実装を持ちます。
受信チャネルフロー
チャネルディスパッチャはトランスポート非依存です。WhatsAppとTelegramは配信動作が異なるため、それぞれ独自のストリームシンクを提供します。
- Telegramはストリーミングされたメッセージをより自然に更新できます。
- WhatsAppは通常バッファリングして最終メッセージを送信します。
チャネルから企業オーケストレーションへ
チャネルメッセージは次のいずれかとなり得ます。
- エージェントとのダイレクトチャネル会話を継続する、または
- メッセージが企業エージェントにマップされる場合、企業作業のウェイクアップを作成する。
ソースが channel の場合、ウェイクコンテキストはチャネルメタデータを保持すべきです。
- チャネルチャットID
- 送信者の電話番号またはセンダーID
- 送信者の表示名
- 受信メッセージ本文
- チャネルエイリアス
ランタイムはこれを LIFEOSAI_* 環境変数として受け取り、エージェントは直接のトランスポート認証情報なしにソースを判断できます。
送信チャネルツール
送信ツールは意図的にランタイム間で共有されます。
mcp__channels__message またはPiのチャネルツールapps/api/src/channels/message-tool.tsこれにより、チャネル送信はモデルのプロンプトから切り離され、監査されたツールパスの中で実行されます。
ハーネスとエージェントランタイム
ハーネスは、LifeOSAIオーケストレーションと実際のエージェントエンジンの間のランタイム境界です。
ランタイムインターフェース
packages/agent/src/runtimes/types.ts がランタイム契約を定義します。
AgentRuntime sessionId stream(prompt) sendMessage(content) interrupt() respondToPermission(toolUseId, response) close()ランタイムオプションには以下が含まれます。
cwdsystemPromptmodelsessionIdpermissionModeallowedToolsenvmcpServersuserManagementUrlprojectPathchannelsMessageHandleradditionalSkillPaths
アプリケーションの他の部分は、内部のランタイムがClaude CodeかPi Agentかを知る必要はありません。正規化されたストリームイベントを消費するだけで十分です。
サポートされるランタイム
| ランタイム | 配置場所 | 責務 |
|---|---|---|
| Claude Code | packages/agent/src/runtimes/claude-code-runtime.ts | Claude Code SDKセッションをラップし、SDKメッセージをストリーム |
| Pi Agent | packages/agent/src/runtimes/pi-agent-runtime.ts | Piコーディングエージェントセッションを実行し、イベントを正規化 |
| ランタイムファクトリ | packages/agent/src/runtimes/factory.ts | 設定されたアダプタ/ランタイムキーに基づきランタイムを選択 |
| イベントノーマライザ | packages/agent/src/runtimes/event-normalizer.ts | フロントエンドとオーケストレーション利用者向けにイベントを正規化 |
エージェントインボーカ
apps/api/src/orchestration/engine/agent-invoker.ts は、ハートビート実行からランタイムプロセスへの橋渡しを担います。
その責務は以下の通りです。
- アダプタ種別とモデルの解決
- インストラクションファイルとスキルパスの解決
- 企業、エージェント、プロジェクトのcwdの解決
- エージェント環境とプロジェクト環境の読み込み
- 企業シークレット参照の解決
- ランタイム環境のマージ
- 実行スコープのベアラートークンの発行
LIFEOSAI_*ウェイクコンテキストの注入- channels MCPサーバーのアタッチ
- Claude CodeまたはPi Agentの起動
- ログからのシークレットの秘匿化
- 実行ログイベントの発行
- セッションID、使用量、結果、エラー状態の返却
アダプタ設定とランタイム設定
これら2つを一つのBlobにまとめてはいけません。読み手と検証パスが異なります。
| フィールド種別 | 格納先 | 理由 |
|---|---|---|
| env, cwd, command, args, model | adapter_config | プロセス起動およびアダプタ入力 |
| instructionsBundleMode, instructionsRootPath, instructionsEntryFile | adapter_config | アダプタの発見ロジック |
| アダプタ固有のノブ | adapter_config | アダプタ実行で使用 |
| heartbeat enabled, intervalSec, wakeOnDemand, maxConcurrentRuns | runtime_config | スケジューラポリシー |
| session compaction policy | runtime_config | セッションローテーションポリシー |
デフォルト値はエージェント作成時に適用すべきです。PATCHは呼び出し元が送ったフィールドのみマージすべきで、部分更新が古いデフォルトを復活させないようにします。
ランタイム環境
LifeOSAIは2層の環境変数をサポートします。
- エージェントスコープ環境変数: エージェントに格納されます。
- プロジェクトスコープ環境変数: プロジェクトに格納されます。
キーが衝突した場合、プロジェクト環境変数がエージェント環境変数を上書きします。これにより、共通のランタイムキーをエージェントレベルで一度定義し、特定のプロジェクトでのみ上書きできます。
環境変数の値は、packages/shared/src/orchestration/env-config.ts の共有バインディングスキーマを使用します。
KEY=valueKEY={ type: "plain", value: "value" }KEY={ type: "secret_ref", ref: "company-secret-name" }検証ルール:
- キーは
^[A-Za-z_][A-Za-z0-9_]*$にマッチすること - 機密キーの平文はストリクトモードで拒否される場合がある
***REDACTED***は値として書き戻せない- シークレット参照は同じ企業に属している必要がある
- シークレットに紐づくキーはログ秘匿化のためマークされる
実行スコープAPI認証
エージェントが公開するAPIは、実行スコープのベアラートークンで保護されます。
Authorization: Bearer $LIFEOSAI_RUN_TOKENこのトークンはリクエストを以下に紐付けます。
- 企業ID
- エージェントID
- 実行ID
これは X-LIFEOSAI-AGENT-ID のようなユーザー提供ヘッダを信頼するよりも強固です。ヘッダは診断や後方互換性には引き続き有用ですが、セキュリティ境界として用いるべきではありません。
ランタイム環境変数
インボーカは、ウェイクおよび実行コンテキストを環境変数として注入します。一般的な値は以下の通りです。
LIFEOSAI_API_URLLIFEOSAI_RUN_TOKENLIFEOSAI_RUN_IDLIFEOSAI_AGENT_IDLIFEOSAI_COMPANY_IDLIFEOSAI_WAKE_REASONLIFEOSAI_WAKE_SOURCELIFEOSAI_TASK_IDまたは該当する場合は課題IDLIFEOSAI_TIMEZONE- ウェイクソースがチャネルの場合のチャネル固有値
タイマーウェイクには課題IDが含まれないことがあります。その場合、エージェントはハートビートまたはインボックスのインストラクションに従い、利用可能な作業を確認すべきです。
運用シーケンス
課題の割り当て
activity.logged が発火queueIssueAssignmentWakeup がウェイクアップをキュー登録heartbeat.run.queued イベントagent-invoker がランタイムを起動heartbeat.run.running イベントheartbeat.run.completed または heartbeat.run.failed企業エージェントとのダイレクトチャット
ダイレクトチャットは企業課題を作成する必要はありません。それでも企業コンテキスト、エージェントインストラクション、スキル、ファイル、環境変数、チャネルツールを使用できます。
ハートビートタイマー
runtime_config.heartbeat.enabled を持つエージェントを読み取りenqueueWakeup(source=“timer”, reason=“heartbeat_timer”)エージェント設定でハートビートをオンにすると、スケジューラ入力が更新されます。次のスケジューラチックは、エージェントプロセスを起動したままにすることなく、新しいランタイム設定を観測します。
ルーチンタイマー
nextFireAt で有効なルーチントリガーを探すnextFireAt を更新UTCが保存形式です。ルーチンのタイムゾーンがスケジュールの発火タイミングを制御します。ユーザーやエージェントがタイムゾーンを指定しない場合、ブラウザのタイムゾーンをデフォルトとして使えます。
チャネル受信メッセージ
ローカルとクラウドのデプロイ
ローカルモード
ローカルモードはTauriアプリとサイドカーサービスを中心に構築されています。
| ポート | サービス |
|---|---|
| 3000 | apps/web |
| 3001 | apps/user-management |
| 3002 | apps/auth |
| 4000 | apps/api |
重要なローカルルート:
~/LIFEOSAI~/.lifeosai/companies- ローカルデータベース(モードに応じて通常SQLiteまたはローカルPostgres)
クラウドモード
クラウドモードはGCPとCI/CDを使用します。
- GCPプロジェクト:
lifeosai-481608 - リージョン:
asia-south-1 - Artifact Registryリポジトリ:
docker-images - Cloud Runサービス: web, auth, user-management
- エージェント実行用のCompute Engineまたはランタイムコンテナ
- ワークスペースルート:
/workspace/LIFEOSAI
プロダクトAPIサーフェスはローカルとクラウドで同一に保たれるべきです。変化するのは実行ロケール、ファイルシステムルート、バッキングサービスのみです。
セキュリティ境界
| 境界 | 強制 |
|---|---|
| ユーザーセッション | apps/user-management がブラウザ/デスクトップリクエストを検証 |
| 企業アクセス | オーケストレーションサービスが読み取り/書き込み前に企業アクセスを確認 |
| エージェント実行API | 実行スコープのベアラートークンが企業、エージェント、実行を検証 |
| シークレット | 企業スコープのシークレット参照は書き込み時に検証され、呼び出し時に解決 |
| ファイル | セッションおよびファイルリーダーは既知のLifeOSAIルートのみを許可 |
| ログ | シークレットに紐づく環境変数は永続化前に秘匿化 |
| チャネル | トランスポートプラグインとチャネルセッションが受信メッセージを既知の企業/エージェントコンテキストにマップ |
コードマップ
| 領域 | 主要ファイル |
|---|---|
| ランタイムインターフェース | packages/agent/src/runtimes/types.ts |
| Claude Codeランタイム | packages/agent/src/runtimes/claude-code-runtime.ts |
| Pi Agentランタイム | packages/agent/src/runtimes/pi-agent-runtime.ts |
| ランタイムイベント正規化 | packages/agent/src/runtimes/event-normalizer.ts |
| エージェントインボーカ | apps/api/src/orchestration/engine/agent-invoker.ts |
| ウェイクアップキュー | apps/api/src/orchestration/engine/wakeup.ts |
| ハートビートスケジューラ | apps/api/src/orchestration/engine/heartbeat.ts |
| ルーチンスケジューラ | apps/api/src/orchestration/engine/routine-scheduler.ts |
| イベントバス | apps/api/src/orchestration/engine/event-bus.ts |
| 実行認証 | apps/api/src/orchestration/auth/run-token.ts |
| エージェントAPIガード | apps/api/src/orchestration/routes/middleware.ts |
| 課題 | apps/api/src/orchestration/services/issues.ts |
| エージェント | apps/api/src/orchestration/services/agents.ts |
| プロジェクト | apps/api/src/orchestration/services/projects.ts |
| ルーチン | apps/api/src/orchestration/services/routines.ts |
| アクティビティ | apps/api/src/orchestration/services/activity-log.ts |
| シークレット | apps/api/src/orchestration/services/secrets.ts |
| 環境変数設定 | packages/shared/src/orchestration/env-config.ts |
| ライブイベント型 | packages/shared/src/orchestration/types/live.ts |
| チャネルディスパッチ | apps/api/src/channels/dispatch.ts |
| チャネルメッセージツール | apps/api/src/channels/message-tool.ts |
| WhatsAppチャネル | apps/api/src/channels/plugins/whatsapp.ts |
| Telegramチャネル | apps/api/src/channels/plugins/telegram.ts |
| セッションリーダー | apps/user-management/src/sessions/reader.ts |