2026年2月5日 星期四

github-copilot 初體驗

Github Copilit-sdk初體驗 - 官方範例排雷

環境

  • 作業系統:windows 10 64bit
  • python:3.13
  • copilot cli:GitHub Copilot CLI 0.0.402.
  • github-copilot-sdk:0.1.21

請記得安裝好相關需求套件,copilot cli一定要安裝,官方文件來看似乎並沒有一定要登入,如果有自己架設好的推論資源也可以直接使用,不過這次的測試是基於登入copilot-plus帳號所使用。

官方文件:https://github.com/github/copilot-sdk/blob/main/docs/getting-started.md

官方範例如下:

import asyncio
from copilot import CopilotClient

async def main():
    client = CopilotClient()
    await client.start()

    session = await client.create_session({"model": "gpt-4.1"})
    response = await session.send_and_wait({"prompt": "What is 2 + 2?"})

    print(response.data.content)

    await client.stop()

asyncio.run(main())

上面程式碼執行之後立即爆雷:

Traceback (most recent call last):
  File "D:\codeProject\py_sdk\main.py", line 25, in <module>
    asyncio.run(main())           
    ~~~~~~~~~~~^^^^^^^^
  File "C:\Users\marty.chen\AppData\Roaming\uv\python\cpython-3.13.2-windows-x86_64-none\Lib\asyncio\runners.py", line 195, in run
    return runner.run(main)
           ~~~~~~~~~~^^^^^^
  File "C:\Users\marty.chen\AppData\Roaming\uv\python\cpython-3.13.2-windows-x86_64-none\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "C:\Users\marty.chen\AppData\Roaming\uv\python\cpython-3.13.2-windows-x86_64-none\Lib\asyncio\base_events.py", line 725, in run_until_complete
    return future.result()
           ~~~~~~~~~~~~~^^
  File "D:\codeProject\py_sdk\main.py", line 16, in main
    await client.start()
  File "D:\codeProject\py_sdk\.venv\Lib\site-packages\copilot\client.py", line 241, in start   
    await self._start_cli_server()
  File "D:\codeProject\py_sdk\.venv\Lib\site-packages\copilot\client.py", line 1068, in _start_cli_server
    self._process = subprocess.Popen(
                    ~~~~~~~~~~~~~~~~^
        args,
        ^^^^^
    ...<5 lines>...
        env=env,
        ^^^^^^^^
    )
    ^
  File "C:\Users\marty.chen\AppData\Roaming\uv\python\cpython-3.13.2-windows-x86_64-none\Lib\subprocess.py", line 1038, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
    ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                        pass_fds, cwd, env,
                        ^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
                        gid, gids, uid, umask,
                        start_new_session, process_group)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\marty.chen\AppData\Roaming\uv\python\cpython-3.13.2-windows-x86_64-none\Lib\subprocess.py", line 1550, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
                       ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
                             # no special security
                             ^^^^^^^^^^^^^^^^^^^^^
    ...<4 lines>...
                             cwd,
                             ^^^^
                             startupinfo)
                             ^^^^^^^^^^^^
FileNotFoundError: [WinError 2] 系統找不到指定的檔案。

可參考issue內的處理說明。

調整如下:

import os
import shutil
import asyncio
from copilot import CopilotClient

cli_path = os.environ.get('COPILOT_CLI_PATH') or shutil.which('copilot')
if not cli_path:
    raise RuntimeError(
        "copilot CLI not found. Set COPILOT_CLI_PATH or install the CLI and ensure it's on PATH."
    )   

async def main():
    client_opts = {'cli_path': cli_path}
    client = CopilotClient(client_opts)

    try:
        await client.start()
    
        # 嚐試確認登入狀態
        try:
            auth = await client.get_auth_status()
            print(f"Authentication Status: {auth.isAuthenticated}")
        except Exception as e:
            print(f"Authentication check failed: {e}")

        # 取得可用模型清單
        try:
            models = await client.list_models()
            print(f"\n{'='*60}")
            print("Available Models Numbers: ", len(models))
            print(f"{'='*60}\n")

            for model in models:
                print(f"- {model.name} (ID: {model.id})")
        except Exception as e:
            print(f"Failed to list models: {e}")
        
        # 執行官方文件的範例測試
        try:
            session = await client.create_session({'model': 'gpt-4.1'})
            response = await session.send_and_wait({'prompt': 'What is 2+2?'})
            print(f"\nResponse from model:\n{response.data.content}\n")
        except Exception as e:
            print(f"Session interaction failed: {e}")   
    finally:
        await client.stop()

    

if __name__ == "__main__":
    asyncio.run(main())         

總算,成功了:

Authentication Status: True

============================================================
Available Models Numbers:  14
============================================================

- Claude Sonnet 4.5 (ID: claude-sonnet-4.5)
- Claude Haiku 4.5 (ID: claude-haiku-4.5)
- Claude Opus 4.5 (ID: claude-opus-4.5)
- Claude Sonnet 4 (ID: claude-sonnet-4)
- Gemini 3 Pro (Preview) (ID: gemini-3-pro-preview)
- GPT-5.2-Codex (ID: gpt-5.2-codex)
- GPT-5.2 (ID: gpt-5.2)
- GPT-5.1-Codex-Max (ID: gpt-5.1-codex-max)
- GPT-5.1-Codex (ID: gpt-5.1-codex)
- GPT-5.1 (ID: gpt-5.1)
- GPT-5 (ID: gpt-5)
- GPT-5.1-Codex-Mini (ID: gpt-5.1-codex-mini)
- GPT-5 mini (ID: gpt-5-mini)
- GPT-4.1 (ID: gpt-4.1)

Response from model:
2+2 equals 4.

結論

還算是方便,這個坑花了我幾個小時處理,也不知道是windows特有的,還是linux也會有,總之,我爬出來了。

後續的官方範例只要基於調整後的模式套用就可以一路順暢。

沒有留言:

張貼留言