外部システムからSessionを起動する

GitHub Actions、CI、webhookなどから固定したagent・mode・repoで新しいsessionを安全に起動するcredential、HTTP request、idempotency、rotate/revokeの契約。

External Session Runは、GitHub Actions、CI、webhook adapterなどaachat外のシステムから、projectのagentへ新しい仕事を渡す入口である。人間やagentが対話的に使うsession run、WebUI内で設定するscheduled startとは別のcredential面を持つ。

利用前に、対象projectがactiveで、対象agentがactiveなAdmin / Collaboratorとして参加し、owner側のruntimeが起動可能であることを確認する。

credentialを作る

project画面の Start from external app を開き、対象agentを選ぶ。credentialを管理できるのは、そのagentの現在のhuman ownerで、本人もprojectのAdmin / Collaboratorである場合だけである。

作成時に次を固定する。

  • credential name
  • 対象agent
  • agentがadvertiseするlaunch mode
  • project / teamから解決されたworkspace repo
  • 任意のexpiry

作成後にAACHAT_API_URLAACHAT_API_KEYが表示される。API keyはこの時だけ表示され、後から読み返せない。 secret storeまたはgit管理外の.envへ保存し、repo、log、documentへ貼らない。

requestを送る

bash
curl -fsS -X POST "$AACHAT_API_URL?wait=started" \
  -H "Authorization: Bearer $AACHAT_API_KEY" \
  --json '{
    "text": "Run the external check and report the result.",
    "idempotency_key": "github-run-12345"
  }'
  • textはsessionへ渡す依頼
  • idempotency_keyは外部eventを一意にする安定ID。同じkeyと同じrequestのretryはsessionを重複起動しない
  • 同じidempotency_keyを異なるtext / metadata / execution contextで再利用するとconflictになる。新しい仕事には新しいkeyを使う
  • ?wait=startedはruntimeがsession開始をacknowledgeするまで待つ。省略時は受付時点で返る
  • 任意のmetadata objectを外部eventとの照合に付けられる

responseのstatussession_idweb_urlで開始を確認する。accepted後にruntimeが起動できなければfailureとして返るため、同じ仕事をretryするときもまず既存invocationの状態を確認する。

rotate / revoke / expiry

  • Rotateは新しいtokenを発行して古いtokenを無効にする。呼び出し元のsecretを直ちに更新する
  • Revokeはそのcredentialからの新規受付を停止する
  • expiryを過ぎたcredentialは新規受付に使えない。新しいinvocationには新しいcredentialを発行して呼び出し元を更新する

credentialが有効でも、projectがactiveでない、作成者がproject Collaboratorでなくなった、agentのownerが変わった、agentがproject Collaboratorでなくなった場合は新規実行を拒否する。credentialはmembershipを迂回する権限ではない。

tokenがまだ認識される場合、revoke・期限切れ・membership変更の後でも、正確に同じ要求のretryは受付済みinvocationを返せます。これらの検査は新規受付を守り、以前の受付を消すものではありません。Rotateはcredential IDを維持してtokenを交換します。古いtokenは認識されなくなるため、新しいtokenで同じkey/bodyをretryします。revoke済み・期限切れのcredentialはRotateできません。新規作成したcredentialは別IDで、idempotencyのscopeも別です。

CI eventを重複した仕事にしない

意図した仕事ごとに安定したevent keyを付けます。GitHub Actionsならrepository、workflow run ID、操作名で1つの要求を識別できます。CI jobの再実行を同じinvocationの復旧にしたい場合、retry attemptはkeyへ含めません。別Sessionを開始したいときだけ、新しい仕事の識別子を明示的に使います。

次のshell stepにはcurljqが必要です。credential画面の値をAACHAT_API_URLAACHAT_API_KEYとしてCIの環境へ注入してください。event本文をJSON文字列へ直接埋め込まず、安全にJSONを組み立てます。通信の再試行では同じbodyとcredentialを保持します。

bash
# Supply AACHAT_API_URL and AACHAT_API_KEY through your CI secret settings.
# GITHUB_REPOSITORY and GITHUB_RUN_ID are provided by GitHub Actions.
set -eu
request_file="$(mktemp)"
trap 'rm -f "$request_file"' EXIT
jq -n \
  --arg event_key "github:${GITHUB_REPOSITORY}:${GITHUB_RUN_ID}:source-review" \
  --arg repository "$GITHUB_REPOSITORY" \
  --arg run_id "$GITHUB_RUN_ID" \
  '{text: "Review the public sources and report findings in this Project.",
    idempotency_key: $event_key,
    metadata: {repository: $repository, run_id: $run_id}}' > "$request_file"
curl --silent --show-error --fail-with-body \
  --request POST "$AACHAT_API_URL?wait=started" \
  --header "Authorization: Bearer $AACHAT_API_KEY" \
  --header 'Content-Type: application/json' \
  --data-binary "@$request_file"

shell tracing(set -x)を有効にしたり、credentialを持つ環境を表示したりしないでください。metadataはserverに保存する要求の一部なので、秘密情報のない照合情報に限定します。idempotency keyは空白だけにできず、UTF-8で200 bytes以内、metadataはserialize後 8192 bytes以内 のobjectです。repositoryと操作名で長すぎる場合は、一意性を保ってkeyを短くしてください。

keyのscopeはcredential IDごとです。同じkeyで、正規化されたtext、metadata、固定launch specification、workspace contextが同じなら既存invocationを返します。metadata objectのkey順序だけでは異なる要求になりません。内容を変えるとconflictになります。別credentialへ変える操作は、同じinvocationを安全にretryする方法ではありません。

受付・開始・失敗を分けて読む

responseの状態意味次の操作
acceptedserverがinvocationを記録し、開始待ちinvocation_idと正確な要求を保存。同一要求のretryで現在の結果を取得できます
startedruntimeがSession開始をacknowledgeしたsession_id / web_urlからSessionを開き、仕事の結果を確認
failedinvocationの起動が完了できなかったfailure.codefailure.messageを読み、原因を直し、意図した新しい試行にだけ新しいkeyを使う

wait=startedの待機には上限があり、acceptedのまま返ることもあります。仕事の完了までは待ちません。HTTP成功だけで仕事の成功とは判断せず、Sessionの紐付け前はweb_urlがない場合もあります。CIの照合情報として返されたinvocation IDとSession linkを保存し、aachatで実際の仕事と成果を確認します。

通信timeoutや応答紛失では、新しいtimestamp keyを作らず、同じcredential・key・正確に同じ要求 をretryしてください。既存invocationを取得できます。失敗したinvocationも同じinvocationのままで、同じkeyでは新しい試行を作りません。実際に失敗した仕事を再試行するwrapperでは、先の結果を確認してから明示的に判断します。

失敗した層を調べる

  • unauthorized、期限切れ、revoke済みなら、呼び出し元secretとcredential画面を確認します。Rotate後は古いtokenを交換します。問い合わせへkeyを貼らないでください。
  • 権限の失敗なら、Projectがactiveか、人間ownerとAgentが現在もProject membershipの条件を満たすかを確認します。keyでmembershipは追加できません。
  • validation errorなら、空でないtext、keyの長さ、metadataの形とサイズ、waitの値(acceptedまたはstarted)を確認します。
  • idempotency conflictなら、元の要求と実行contextを比較します。黙って新しいkeyに変え、仕事を重複させないでください。
  • 起動失敗なら、ownerのruntime、固定launch設定、固定workspace repoへのアクセスを確認し、前提を直してから意図的に再起動します。別の対象やlaunch contextが必要なら適切なcredentialを新規作成します。

Rotate・revoke・期限はcredentialの利用を制御するもので、開始済みSessionのcancelや仕事のrollbackではありません。開始済みの仕事はSession操作で管理します。このendpointはSessionを起動するもので、webhookからWorkflowを公開・実行する操作ではありません。

関連ページ