ドキュメント
アプリを開く

Architecture philosophy

このページの内容

SotaAgents は platform control plane と app data plane を意図的に分離します。Platform は user、organization、workspace、installation、selected environment、exact artifact、capability を理解し、app backend は検索、CAD、専用 API、business rule など domain を理解します。

SotaAgents が request を exact app environment に解決する architecture diagram
一つの authority decision が exact artifact、UI bundle、backend、environment data を bind します。

App に専用 backend が必要な理由#

  • 独立 ownership:Core に domain code を追加せず独自 cadence で ship。
  • Security boundary:Credential と integration を server-side に置き、signed context だけを受け入れる。
  • Data boundary:Domain に合う database、retention、residency、scaling を選択。
  • Operational isolation:他 app と分離して scale、fail、recover。
専用 backend は専用 identity system ではありません。

Browser 由来の任意 actor/workspace/environment を信頼せず、signed Sota request の exact context を使用します。

アシスタントはどのように tool を呼ぶのか#

Manifest への tool 宣言は物語の半分にすぎません。ここから先が、その宣言を runtime にプラットフォームがどう扱うか——アプリを単なる host 済み web service 以上のものにしている部分です。

1

Tool が model に提示される

Workspace が app surface を解決すると、公開済みの各 tool は app_<appId>_<toolName> という名前の、model が呼び出せる function 一つになります。Development と Staging は environment を挟み(app_my-app_stg_example)、Production は省くため、Production で model が学ぶ名前は簡潔に保たれます。model 向け名称が持てない文字——documents.query のようなドットを含む——はアンダースコアになり、64 文字を超える名前は短い hash 接尾辞を付けて切り詰められ、二つのアプリで衝突した場合は数字が付きます。model が読む description は manifest の description に App: <appId>. Runtime tool: <name>. を連結したものであり、inputSchema はそのまま parameter schema として model に渡されます。曖昧な description や緩い schema が即座に tool 選択の精度を落とすのは、model の判断材料がそれで全部だからです。

2

Platform が解決し認可する

Request が SotaAgents を出る前に、arguments は input schema で検証され、organization、workspace、installation、environment、そして適用される exact artifact が解決されます。その artifact に公開されていない tool、あるいはその workspace にインストールされていないアプリは、ここで拒否されます——backend には一切到達しません。

3

Signed request が backend に届く

Platform は、有効な environment 向けに解決された service.baseUrl の宣言済み path へ、server-to-server の HTTP request を送ります。Development では同じ request が sota dev の tunnel を通って手元のマシンに届きます。この経路に browser は介在しないため、backend が公開インターネットからユーザーに到達可能である必要はありません。

4

Backend が検証し、処理し、JSON を返す

Token を検証し、domain の処理を行い、JSON を返します。非 2xx、JSON として不正な body、timeout はいずれも tool の失敗として扱われます。

5

結果が conversation に戻る

Platform は tool result を tool の output part として conversation に stream し、記録します。surface: tool-view の UI contribution が toolNames にその tool を含んでいれば、素の結果の代わりに React module が描画されます。model が見るのは同じ結果の簡潔な JSON 射影です。

Platform が送る request#

Body は envelope です。model の arguments は body.input に入れ子になっており、scaffold の route が request.body ではなく request.body.body.input を読むのはそのためです。

HTTP
POST https://my-app.example.com/tools/example
content-type: application/json
authorization: Bearer <invocation JWT>
x-sota-core-token: <delegated Core token>   # アプリが Core tool grants を宣言した場合のみ

{
  "requestId": "01K...",
  "organizationId": "6a66...",
  "workspaceId": "6a66...",
  "appId": "my-first-project-demo",
  "hook": { "type": "tool", "name": "example" },
  "body": {
    "input":   { "message": "hello" },
    "context": { "organizationId": "…", "workspaceId": "…", "userId": "…",
                 "conversationId": "…", "agentId": "…", "toolCallId": "…", "config": {} }
  }
}
信頼するのは token であって envelope ではありません。

Body 内の organizationId、workspaceId、context は log と debug のための便宜的な値です。認可判断はすべて、検証済み JWT の claim から行ってください。署名されているのはそちらだけです。

Invocation token#

Authorization header は、この 1 回の呼び出しのために発行された短命の EdDSA 署名 JWT を運びます。Backend は <core origin>/.well-known/jwks.json で公開される platform の公開鍵で検証します。アプリは Sota の秘密鍵を持たず、自ら token を発行することもありません。

項目値
Algorithm / typEdDSA(Ed25519)、header type sota-invocation+jwt
isssota/invocation-token
aud自身の appId。別アプリ向けの token は拒否します
有効期間60 秒、時刻ずれ許容 30 秒
oid / wid呼び出しが属する organization と workspace
subActor がいる呼び出しの実行ユーザー
iid互換用の opaque install identity。Prefix から environment を推測しません。
ae / aei / ag正確な App Environment 名、environment identity、Backend Access Generation。3 claim が一つの resolved backend に認可を bind します。
aer署名済み exact execution reference。Persist/replay 時は新しい artifact を resolve せず、この reference を保持します。
scp現行 scope family は tool:<name>、route:prompt:<name>、route:systemPrompt:<name>、event:<name>、route:artifact:<name>、route:resolver:<path>、lifecycle route scope、app:http です。各 endpoint は、その surface に発行された exact scope を必ず要求します。
ridEnvelope の requestId。Log 突き合わせ用

各 route には最小の scope を要求してください。/tools/example の handler が求めるべきは tool:example であり、それより広い権限ではありません。Scaffold の src/backend/sota-auth.ts に、issuer・audience・algorithm・type・有効期限・tenant claim・scope という一連の検証が、再利用可能な middleware として揃っています。

Response の形#

通常の JSON HTTP response を返します。Sota 専用の wrapper を組み立てる必要はありません。

結果Platform の扱い
2xx + JSON body成功。Body がそのまま tool result になります。
非 2xx失敗。Body が { "code": "…", "message": "…" }(任意で details、hint)なら、汎用メッセージの代わりにその値がそのまま伝わります。成功を装った error body ではなく実際の status code を返してください。
JSON として不正な bodyVALIDATION_ERROR で失敗。
Deadline 内に応答なしTIMEOUT で失敗。

outputSchema は runtime の response に対しては検証されません。検証されるのは publish 時であり、そこで version 間の breaking change 検出に使われます。出力は境界で自分で検証してください。Schema は runtime の防御壁ではなく、consumer と renderer に対する約束としての contract です。

予約された 2 つの任意 key により、一つの結果が二つの読み手に対応できます。model 向けの簡潔な結論と renderer 向けの詳細 payload を同じ response に入れ、_sota.modelOutput で model にまったく別の射影を渡すか、_sota.modelProjection.omitKeys で renderer 専用 key を model の読む範囲から外します。model 可視の射影は約 32,000 文字で切り詰められるため、生の文書ではなく結論・ID・件数・citation に留めてください。

目次

Esc

全章のタイトルと本文を検索します。