コンテンツにスキップ

LifeOSAIエージェントシステム

アーキテクチャとコード

UIの下にあるシステム

エージェントシステム、企業オーケストレーション、チャネルシステム、ハーネスとエージェントランタイム — リクエストの流れ、エージェントの起動と実行、設定・シークレット・ファイル・ライブイベントの所有先。

この文書は、UIレイヤーより下のLifeOSAIシステム・アーキテクチャを記述します。以下の4領域に焦点を当てます。

  1. LifeOSAIエージェントシステム
  2. 企業オーケストレーションシステム
  3. チャネルシステム
  4. ハーネスとエージェントランタイム

リクエストがシステムをどう流れるか、エージェントがどう起動・実行されるか、チャネルメッセージがどうルーティングされるか、そしてランタイム設定・シークレット・ファイル・ライブイベントの所有先を説明することを目的としています。

システム境界

LifeOSAIはクロスプラットフォームのエージェントオペレーティングシステムです。同じプロダクトモデルが2つのデプロイモードで動作します。

  • クラウドモード: ブラウザトラフィックがクラウドサービスで処理され、エージェントランタイムはクラウドインフラで動作します。
  • ローカルモード: Tauriデスクトップアプリがローカルサイドカーを起動し、ローカルファイルとローカルデータストアを使用します。

高位のサービス境界は以下の通りです。

ユーザー / チャネル / オペレーター
apps/web または外部チャネルトランスポート
apps/user-management
apps/api
packages/agent ランタイムアダプタ
Claude CodeエージェントまたはPiエージェント

apps/user-management はブラウザ向けのルーティングハブです。ユーザーセッションを検証し、プロダクトリクエストを正しいバックエンドサービスへ転送します。エージェント実行は apps/api、特にオーケストレーションエンジンとランタイムインボーカが所有します。

サービス責務

レイヤー所有者責務
プロダクトエントリapps/webLifeOSAIチャット、企業、アプリ、ファイル、設定、静的エクスポート対応シェル
デスクトップシェルapps/tauriローカルデスクトップラッパー、アップデータ、サイドカープロセス管理
ルーティングハブapps/user-managementユーザー認証APIゲートウェイ、セッションリーダー、オーケストレーションプロキシ、ファイルプロキシ
エージェントAPIapps/apiエージェントランタイムAPI、企業オーケストレーション、ウェイクアップ、スケジューラ、チャネル、シークレット
ランタイムSDKpackages/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/web
apps/user-management セッション/チャットルート
apps/api またはランタイムハンドラ
packages/agent ランタイム
Claude CodeまたはPi Agent
正規化されたストリームイベント
永続化されたトランスクリプトおよび/またはライブレスポンス

セッション発見とセッションメッセージ参照は別の関心事です。セッションリストは既知のLifeOSAIルートに限定し続けるべきです。メッセージ参照は、実行/セッションが既知の企業エージェントトランスクリプトパスを指している場合、それを解決できます。

企業オーケストレーションシステム

企業システムはマルチエージェント・オーケストレーション層です。企業、エージェント、プロジェクト、ゴール、課題、ルーチン、アクティビティ、実行、承認、企業スコープのファイルを所有します。

主要ドメインオブジェクト

オブジェクト目的
Companyエージェント、課題、プロジェクト、シークレット、チャネル、ファイルのテナント境界
Agent役割、アダプタ設定、ランタイム設定、インストラクション、スキル、環境変数を持つ企業のチームメイト
Project課題とファイル向けのワークスペースとプロジェクトスコープの設定
Goal課題やルーチンをまとめる高位の目標
Issueエージェントに割り当てられる、またはライフサイクル状態を移行する企業作業の単位
Routineエージェントが所有するスケジュール型またはトリガー型の定期作業
Wakeup requestエージェントを実行する理由を伝える永続キュー項目
Heartbeat run1回のエージェント呼び出しの実行記録
Activity logユーザー、エージェント、システムアクションの監査/イベント履歴
Company secret環境変数バインディングで使用される企業スコープのシークレット参照

ウェイクソース

エージェント実行は次のソースから開始される可能性があります。

  • エージェントに割り当てられた課題
  • 課題コメントまたはメンション
  • 承認段階または審査決定
  • ユーザーがハートビート実行をクリック
  • バックグラウンドのハートビートタイマー発火
  • ルーチンタイマー発火
  • チャネル受信メッセージがエージェントにルーティング
  • 企業エージェントへのダイレクトチャットメッセージ送信

これらはすべて実行前にウェイクコンテキストに正規化されます。エージェントは、ウェイクがUI、タイマー、課題、チャネルのどこから来たかを、受け取るウェイクフィールドを通じて以外は知る必要はありません。

ウェイクアップキューフロー

apps/api/src/orchestration/engine/wakeup.ts が永続キューのヘルパーを所有します。

作業ソース
enqueueWakeup(agentId, source, reason, payload, contextSnapshot)
agentWakeupRequest ステータスがqueued
スケジューラまたは即時ランナーがウェイクアップをクレーム
heartbeat_runs 行が作成または更新
agent-invoker がランタイムプロセスを起動
ウェイクアップが完了または失敗

ウェイクアップレコードが捕捉する情報:

  • agentId
  • source
  • triggerDetail
  • reason
  • payload
  • contextSnapshot
  • キューステータスとタイムスタンプ

コンテキストスナップショットは、プロダクトイベントからランタイム実行への安定した受け渡しとなるため重要です。例えば、課題割り当てウェイクアップには、後で課題が変わったとしても課題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の受信メッセージ
トランスポートプラグイン
チャネルレジストリが企業、エージェント、セッションを解決
チャネルディスパッチがシステムプロンプトとランタイムオプションを構築
ランタイムが回答をストリーム
ストリームシンクがトランスポート経由で返信を送信
チャネルセッションのメタデータが永続化

チャネルディスパッチャはトランスポート非依存です。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()

ランタイムオプションには以下が含まれます。

  • cwd
  • systemPrompt
  • model
  • sessionId
  • permissionMode
  • allowedTools
  • env
  • mcpServers
  • userManagementUrl
  • projectPath
  • channelsMessageHandler
  • additionalSkillPaths

アプリケーションの他の部分は、内部のランタイムがClaude CodeかPi Agentかを知る必要はありません。正規化されたストリームイベントを消費するだけで十分です。

サポートされるランタイム

ランタイム配置場所責務
Claude Codepackages/agent/src/runtimes/claude-code-runtime.tsClaude Code SDKセッションをラップし、SDKメッセージをストリーム
Pi Agentpackages/agent/src/runtimes/pi-agent-runtime.tsPiコーディングエージェントセッションを実行し、イベントを正規化
ランタイムファクトリ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, modeladapter_configプロセス起動およびアダプタ入力
instructionsBundleMode, instructionsRootPath, instructionsEntryFileadapter_configアダプタの発見ロジック
アダプタ固有のノブadapter_configアダプタ実行で使用
heartbeat enabled, intervalSec, wakeOnDemand, maxConcurrentRunsruntime_configスケジューラポリシー
session compaction policyruntime_configセッションローテーションポリシー

デフォルト値はエージェント作成時に適用すべきです。PATCHは呼び出し元が送ったフィールドのみマージすべきで、部分更新が古いデフォルトを復活させないようにします。

ランタイム環境

LifeOSAIは2層の環境変数をサポートします。

  1. エージェントスコープ環境変数: エージェントに格納されます。
  2. プロジェクトスコープ環境変数: プロジェクトに格納されます。

キーが衝突した場合、プロジェクト環境変数がエージェント環境変数を上書きします。これにより、共通のランタイムキーをエージェントレベルで一度定義し、特定のプロジェクトでのみ上書きできます。

環境変数の値は、packages/shared/src/orchestration/env-config.ts の共有バインディングスキーマを使用します。

KEY=value
KEY={ 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_URL
  • LIFEOSAI_RUN_TOKEN
  • LIFEOSAI_RUN_ID
  • LIFEOSAI_AGENT_ID
  • LIFEOSAI_COMPANY_ID
  • LIFEOSAI_WAKE_REASON
  • LIFEOSAI_WAKE_SOURCE
  • LIFEOSAI_TASK_ID または該当する場合は課題ID
  • LIFEOSAI_TIMEZONE
  • ウェイクソースがチャネルの場合のチャネル固有値

タイマーウェイクには課題IDが含まれないことがあります。その場合、エージェントはハートビートまたはインボックスのインストラクションに従い、利用可能な作業を確認すべきです。

運用シーケンス

課題の割り当て

ユーザーまたはエージェントが担当者付きの課題を作成/更新
課題サービスが課題を永続化
activity.logged が発火
queueIssueAssignmentWakeup がウェイクアップをキュー登録
スケジューラがウェイクアップをクレーム
ハートビート実行がキューイング
heartbeat.run.queued イベント
agent-invoker がランタイムを起動
heartbeat.run.running イベント
ランタイムが実行トークンAPI経由でタスク/インボックスを読み取る
ランタイムがコメント、課題更新、ファイル書き込み、承認依頼を行う
課題/アクティビティ/実行のライブイベントが利用者にストリーム
heartbeat.run.completed または heartbeat.run.failed

企業エージェントとのダイレクトチャット

ユーザーが企業エージェントを選択
ダイレクトチャットセッションが解決または作成
エージェント設定から選択ランタイム/モデルを取得
メッセージがランタイムアダプタ経由で送信
応答がチャットパネルにストリーム
そのエージェントのセッションIDが記憶される

ダイレクトチャットは企業課題を作成する必要はありません。それでも企業コンテキスト、エージェントインストラクション、スキル、ファイル、環境変数、チャネルツールを使用できます。

ハートビートタイマー

ハートビートスケジューラのチック
runtime_config.heartbeat.enabled を持つエージェントを読み取り
間隔と実行中ポリシーをチェック
enqueueWakeup(source=“timer”, reason=“heartbeat_timer”)
課題IDなしで実行を開始
エージェントがインボックスライトまたはハートビートインストラクションを確認
作業がなければエージェントが終了

エージェント設定でハートビートをオンにすると、スケジューラ入力が更新されます。次のスケジューラチックは、エージェントプロセスを起動したままにすることなく、新しいランタイム設定を観測します。

ルーチンタイマー

ルーチンスケジューラのチック
nextFireAt で有効なルーチントリガーを探す
ルーチンウェイクコンテキストを作成
ルーチンポリシーに従いエージェント実行を開始またはキュー
UTCで nextFireAt を更新
次回実行をユーザー/ブラウザのタイムゾーンで表示

UTCが保存形式です。ルーチンのタイムゾーンがスケジュールの発火タイミングを制御します。ユーザーやエージェントがタイムゾーンを指定しない場合、ブラウザのタイムゾーンをデフォルトとして使えます。

チャネル受信メッセージ

外部チャネルメッセージ
トランスポートプラグインがメッセージを検証・解析
チャネルセッションが企業/エージェント/セッションにマップ
ディスパッチがランタイムコンテキストを構築
ランタイムが応答
ストリームシンクが送信応答を送信または編集
チャネルセッションと監査状態が更新

ローカルとクラウドのデプロイ

ローカルモード

ローカルモードはTauriアプリとサイドカーサービスを中心に構築されています。

ポートサービス
3000apps/web
3001apps/user-management
3002apps/auth
4000apps/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

次に読む