Skip to main content

クラウド セッション

ローカル CLI セッションではなく、Mission Control を使用してGitHubホストされたコンピューティングでCopilot セッションを実行します。

Prerequisites

クラウド セッションを作成する前に、次のことを確認してください。

  • ユーザーは、クラウド エージェントの権利を持つCopilotアクセス権を持っています。
  • セッションは、ユーザー トークンまたはログイン Copilot CLI ID を使用して、GitHubに対して認証できます。
  • セッションを GitHub リポジトリに関連付けることができます。 これは SDK の種類では省略可能ですが、Mission Control とクラウド エージェントにリポジトリ コンテキストが含まれるようにすることをお勧めします。
  • 組織ポリシーを使用すると、クラウド サーフェスからのリモート 制御とセッションの表示が可能になります。

クラウド セッションの作成

create-session cloud オプションを設定して、クラウド セッションを作成します。 リポジトリ メタデータを含め、クラウド セッションを GitHub リポジトリに関連付けることができます。

TypeScript

import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
await client.start();

const session = await client.createSession({
  onPermissionRequest: async () => ({ kind: "approve-once" }),
  cloud: {
    repository: {
      owner: "github",
      name: "copilot-sdk",
      branch: "main",
    },
  },
});

Python

from copilot import (
    CloudSessionOptions,
    CloudSessionRepository,
    CopilotClient,
    PermissionHandler,
)

client = CopilotClient()
await client.start()

session = await client.create_session(
    on_permission_request=PermissionHandler.approve_all,
    cloud=CloudSessionOptions(
        repository=CloudSessionRepository(
            owner="github",
            name="copilot-sdk",
            branch="main",
        )
    ),
)

Go

package main

import (
    "context"

    copilot "github.com/github/copilot-sdk/go"
    "github.com/github/copilot-sdk/go/rpc"
)

func main() {
    _ = run(context.Background())
}

func run(ctx context.Context) error {
    client := copilot.NewClient(nil)
    if err := client.Start(ctx); err != nil {
        return err
    }

    session, err := client.CreateSession(ctx, &copilot.SessionConfig{
        Cloud: &copilot.CloudSessionOptions{
            Repository: &copilot.CloudSessionRepository{
                Owner:  "github",
                Name:   "copilot-sdk",
                Branch: "main",
            },
        },
        OnPermissionRequest: func(_ copilot.PermissionRequest, _ copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
            return &rpc.PermissionDecisionApproveOnce{}, nil
        },
    })
    _ = session
    return err
}
client := copilot.NewClient(nil)
if err := client.Start(ctx); err != nil {
    return err
}

session, err := client.CreateSession(ctx, &copilot.SessionConfig{
    Cloud: &copilot.CloudSessionOptions{
        Repository: &copilot.CloudSessionRepository{
            Owner:  "github",
            Name:   "copilot-sdk",
            Branch: "main",
        },
    },
    OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
        return &rpc.PermissionDecisionApproveOnce{}, nil
    },
})
_ = session

.NET

await using var client = new CopilotClient();

var session = await client.CreateSessionAsync(new SessionConfig
{
    Cloud = new CloudSessionOptions
    {
        Repository = new CloudSessionRepository
        {
            Owner = "github",
            Name = "copilot-sdk",
            Branch = "main",
        },
    },
    OnPermissionRequest = (req, inv) =>
        Task.FromResult(PermissionDecision.ApproveOnce()),
});

Java

import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;

try (var client = new CopilotClient()) {
    client.start().get();

    var session = client.createSession(
        new SessionConfig()
            .setCloud(new CloudSessionOptions()
                .setRepository(new CloudSessionRepository()
                    .setOwner("github")
                    .setName("copilot-sdk")
                    .setBranch("main")))
            .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
    ).get();
}

Rust

use std::sync::Arc;
use github_copilot_sdk::{CloudSessionOptions, CloudSessionRepository, SessionConfig};
use github_copilot_sdk::handler::ApproveAllHandler;

let session = client.create_session(
    SessionConfig::default()
        .with_cloud(CloudSessionOptions::with_repository(
            CloudSessionRepository::new("github", "copilot-sdk").with_branch("main"),
        ))
        .with_permission_handler(Arc::new(ApproveAllHandler)),
).await?;

最初のプロンプトの送信

クラウド セッションは 2 つのフェーズで初期化されます。 createSession は、Mission Control がタスクを予約するとすぐに解決されますが、リモート copilot-agent ワーカーは接続して session.startを出力するためにもう 1 秒または 2 秒かかります。 その前にsession.sendを呼び出すと、ランタイムのRemoteSession.send"Remote session is still starting"をスローしますが、スキーマ ラッパーは起動して忘れ、コードに新しい**** を返しながらmessageId。 プロンプトはサーバー上で削除され、ワーカーに到達することはありません。

確実に送信するには、送信にイベントを購読し、producer"copilot-agent" である最初の session.start イベントを待ちます:

import { CopilotClient, type CopilotSession } from "@github/copilot-sdk";

const client = new CopilotClient();
await client.start();

const session: CopilotSession = await client.createSession({
  streaming: true, // required for assistant.message_delta to fire
  cloud: { repository: { owner: "github", name: "copilot-sdk" } },
  onPermissionRequest: async () => ({ kind: "approve-once" }),
});

// Subscribe BEFORE sending so you don't miss the start event.
const ready = new Promise<void>((resolve) => {
  const off = session.on("session.start", (event) => {
    if (event.data?.producer === "copilot-agent") {
      off();
      resolve();
    }
  });
});

await ready;
await session.send({ prompt: "Summarize the README" });

いくつかの注意事項:

  • ランタイムがstreaming: trueイベントを出力するように、createSessionassistant.message_deltaを設定します。 これを使用しない場合、最終的な assistant.message が得られる唯一のアシスタント シグナルです。バッチ使用には問題ありませんが、ライブ UI をレンダリングしている場合、チャットはフリーズした状態で表示されます。 「ストリーミング セッション イベント」を参照してください。
  • 最初session.sendだけがこのレースに敏感です。 ランタイムはセッションの有効期間中に hasSessionStarted 設定を維持するため、同じセッションでの後続の送信は正常に動作します。
  • 応答しなくなった Mission Control のプロビジョニングによってアプリが永久にハングしたままにならないよう、ready Promise にタイムアウト(例: 60 秒)を設定します。
  • すべての SDK 言語で同じパターンが機能します。 session.startをサブスクライブし、 producer === "copilot-agent"確認してから、 sendを呼び出します。

ミッション コントロール URL へのアクセス

クラウド セッションは本質的にリモートです。ワーカーが接続すると、Mission Control は https://github.com/copilot/tasks/{sessionId} でセッションを発行し、ランタイムは URL を使用して session.info イベントを生成します。 ** **を呼び出す必要remote.enable()。その API は、ローカル セッションを Mission Control に昇格させるためだけに使用されます。

session.infoをサブスクライブして URL をキャプチャし、infoType: "remote"でフィルター処理します。

session.on("session.info", (event) => {
  if (event.data?.infoType === "remote" && event.data.url) {
    console.log("Open from web or mobile:", event.data.url);
    // e.g. surface in your UI as a shareable link or QR code.
  }
});

イベントは、 session.startの直後に発生します。 イベントが既に発生した後にレンダラーがマウントされる場合は、URL をアプリの状態でセッション レコードと共に保持し、再マウント時にリハイドレートします。ランタイムは、それ自体で session.info を再出力しません。

remote: true を介して昇格されたローカル セッションで同一の配線構成を使用する場合は、リモート セッション を参照してください。

リポジトリの関連付け

cloud.repository オブジェクトは、クラウド セッションを GitHub リポジトリに関連付けます。

フィールド必須Description
ownerはいリポジトリの所有者または組織。
nameはいリポジトリ名。
branchいいえリポジトリ コンテキストに使用するブランチ。 ランタイムが既定のブランチまたは現在のリポジトリ コンテキストを選択できるようにするには、これを省略します。

SDK の種類ではリポジトリの関連付けは省略可能ですが、アプリがターゲット リポジトリを認識するたびにそれを含めます。 これは、Mission Control がセッションを適切なコンテキストで表示するのに役立ち、クラウド エージェントに明確な開始点を提供します。

特定のブランチから作業を開始する必要がある場合は、 branch を使用します。 アプリがプル要求、トリアージ フロー、またはデプロイ ワークフローからセッションを作成している場合は、ユーザーが表示するタスクに一致するブランチを渡します。

クラウド セッションの再開

cloud オプションは、新しいセッションを作成する場合にのみ適用されます。 既存のクラウド セッションを再開するには、SDK 言語の標準の再開 API を使用します。

import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
await client.start();

const session = await client.resumeSession("session-id", {
  onPermissionRequest: async () => ({ kind: "approve-once" }),
});
void session;
const session = await client.resumeSession("session-id", {
  onPermissionRequest: async () => ({ kind: "approve-once" }),
});

再開時に cloud を再度渡さないでください。 保存されたセッション メタデータは、セッションがクラウドでサポートされていることを判断し、再開は通常のセッション再開パスに従います。

組織のポリシーと権利

クラウド セッションの作成は、ユーザーまたは組織がクラウド エージェントの実行を受ける権利がない場合、または組織レベルのポリシーによってフローがブロックされた場合に失敗する可能性があります。 特に、クラウド サンドボックスのポリシーにより、クライアントがクラウド タスクを作成できなくなる可能性があります。

これが発生すると、ランタイムはクラウド タスクの作成 "policy_blocked" エラーの理由を報告します。 これは、一時的なインフラストラクチャ障害ではなく、承認またはポリシーの結果として扱います。

TypeScript で、再試行する前に理由を確認します。

import {
  CopilotClient,
  type CloudSessionRepository,
} from "@github/copilot-sdk";

const client = new CopilotClient();
await client.start();

const repository: CloudSessionRepository = {
  owner: "github",
  name: "copilot-sdk",
};

try {
  await client.createSession({
    cloud: { repository },
    onPermissionRequest: async () => ({ kind: "approve-once" }),
  });
} catch (error) {
  if ((error as { reason?: string }).reason === "policy_blocked") {
    // Show an admin-facing message or link to org policy settings.
  }
  throw error;
}
try {
  await client.createSession({ cloud: { repository } });
} catch (error) {
  if ((error as { reason?: string }).reason === "policy_blocked") {
    // Show an admin-facing message or link to org policy settings.
  }
  throw error;
}

SDK エラーの表現が異なる言語では、表示されたエラーの理由またはコードを調べて、 "policy_blocked" を明示的に処理します。 ポリシーを変更せずに再試行することは成功しません。

統合 ID とルーティング

クラウド セッションには、Copilot-Integration-Id 環境変数から派生した GITHUB_COPILOT_INTEGRATION_ID ヘッダーがスタンプされます。 この統合 ID は、ルーティング、属性、統合固有の動作のために Mission Control によって使用されます。

マルチユーザー サーバーのガイダンスと完全な統合 ID の詳細については、 AUTOTITLE を参照してください。

Mission Control は、SDK で作成されたクラウド セッションを copilot-developer-sandbox エージェント のスラッグにルーティングします。 この名前はクラウド エージェントの内部ルーティング スラッグであり、セッションがローカル Windows サンドボックスを使用するわけではありません。

詳細: COPILOT_MC_BASE_URL

既定では、ランタイムは、構成された Copilot API URL から Mission Control のベース URL を派生させます。 COPILOT_MC_BASE_URLそのミッション コントロール エンドポイントをオーバーライドする必要がある場合にのみ設定します。

これは、GitHub Enterprise Server の展開に必要な場合があります。 運用環境で使用する前に、GitHub担当者に正しい値とサポートの状態を確認してください。

COPILOT_MC_BASE_URL="https://example.com/agents"

クラウド セッションとリモート セッション

能力リモート セッションクラウド セッション
実行場所ローカル マシンまたはお使いのサーバーGitHubホスト型コンピューティング
ミッション コントロールの役割ローカル セッションを GitHub の Web/モバイル版と共有するホストされているセッションを作成してルーティングする
SDK オプション
remote: true クライアントまたはセッション上で
cloud: { ... } セッションの作成時
再開パス標準履歴書標準履歴書
Windows サンドボックス関連無関係無関係

セッションが SDK ランタイムが既に実行されている場所で実行する必要があるが、Mission Control からもアクセスできる場合は、リモート セッションを使用します。 GitHubホストされたコンピューティングでセッションを実行する必要がある場合は、クラウド セッションを使用します。

Troubleshooting

症状:考えられる原因確認すべきこと
クラウド セッションの作成は "policy_blocked" を返します組織のポリシーにより、クラウド フローからのリモート コントロールまたはビューがブロックされる組織のCopilotポリシーとユーザー権利を確認する
リポジトリ コンテキストなしでセッションが作成される
cloud.repository が省略されました
ownername、および必要に応じてbranchを渡します
再開で新しい cloud オプションが無視される
cloud 新しいセッションにのみ適用されます既存のセッションを通常どおりに再開する
サンドボックス設定との混同Windowsサンドボックスセッションとクラウドセッションは別々ですクラウドの実行に SANDBOX=true を使用しない
session.sendmessageId で解決されますが、 assistant.* イベントは発生せず、ミッション コントロールはプロンプトを表示しませんsession.send はリモートワーカーからの session.start より先に進み、ランタイムがプロンプトを飲み込んだ送信する前に、session.startで最初のproducer === "copilot-agent" イベントを待機します。
最初のプロンプトの送信を参照してください
クラウド ワーカーが処理している場合でも、ライブ UI が更新されることはありません
streamingcreateSessionに設定されていないため、最終的な assistant.message のみが出力されます
streaming: truecreateSessionを設定して再起動する
クラウド セッションは機能しますが、UI に共有可能な URL は表示されませんアプリが URL の session.info をサブスクライブしたことがない
session.infoをサブスクライブし、infoType === "remote"をフィルター処理します。
ミッション コントロール URL へのアクセスを参照してください

参照