feat: release github-copilot-sdk v0.6.0 and files-filter v0.1.2
This commit is contained in:
103
plugins/pipes/github-copilot-sdk/scripts/sync_to_workspace.py
Normal file
103
plugins/pipes/github-copilot-sdk/scripts/sync_to_workspace.py
Normal file
@@ -0,0 +1,103 @@
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import asyncio
|
||||
from typing import List, Dict
|
||||
|
||||
# 1. 尝试导入 OpenWebUI 环境
|
||||
try:
|
||||
from open_webui.models.models import Models, ModelForm, ModelMeta, ModelParams
|
||||
from open_webui.internal.db import get_session
|
||||
except ImportError:
|
||||
print("❌ 错误: 无法导入 OpenWebUI 模块。请确保在 OpenWebUI 环境(如 conda ai)中运行此脚本。")
|
||||
sys.exit(1)
|
||||
|
||||
# 2. 导入 Copilot SDK
|
||||
try:
|
||||
from copilot import CopilotClient
|
||||
except ImportError:
|
||||
print("❌ 错误: 无法导入 copilot SDK。请运行: pip install github-copilot-sdk==0.1.23")
|
||||
sys.exit(1)
|
||||
|
||||
async def fetch_real_models() -> List[Dict]:
|
||||
gh_token = os.environ.get("GH_TOKEN")
|
||||
if not gh_token:
|
||||
print("❌ 错误: 未设置 GH_TOKEN 环境变量。")
|
||||
return []
|
||||
|
||||
client = CopilotClient()
|
||||
try:
|
||||
await client.start()
|
||||
raw_models = await client.list_models()
|
||||
processed = []
|
||||
for m in raw_models:
|
||||
m_id = getattr(m, "id", str(m))
|
||||
# 提取倍率
|
||||
billing = getattr(m, "billing", {})
|
||||
if not isinstance(billing, dict): billing = vars(billing)
|
||||
multiplier = billing.get("multiplier", 1)
|
||||
|
||||
# 提取能力
|
||||
cap = getattr(m, "capabilities", None)
|
||||
vision = False
|
||||
reasoning = False
|
||||
if cap:
|
||||
supports = getattr(cap, "supports", {})
|
||||
if not isinstance(supports, dict): supports = vars(supports)
|
||||
vision = supports.get("vision", False)
|
||||
reasoning = supports.get("reasoning_effort", False)
|
||||
|
||||
processed.append({
|
||||
"id": m_id,
|
||||
"name": f"GitHub Copilot ({m_id})",
|
||||
"vision": vision,
|
||||
"reasoning": reasoning,
|
||||
"multiplier": multiplier
|
||||
})
|
||||
return processed
|
||||
except Exception as e:
|
||||
print(f"❌ 获取模型失败: {e}")
|
||||
return []
|
||||
finally:
|
||||
await client.stop()
|
||||
|
||||
async def sync_to_db():
|
||||
models = await fetch_real_models()
|
||||
if not models: return
|
||||
|
||||
print(f"🔄 发现 {len(models)} 个 Copilot 模型,正在同步到工作区...")
|
||||
|
||||
# 默认管理员 ID
|
||||
admin_user_id = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
for m in models:
|
||||
# 对应插件中的 ID 格式
|
||||
full_id = f"copilot-{m['id']}"
|
||||
|
||||
existing = Models.get_model_by_id(full_id)
|
||||
if existing:
|
||||
print(f"⚠️ 跳过: {full_id} (已存在)")
|
||||
continue
|
||||
|
||||
form_data = ModelForm(
|
||||
id=full_id,
|
||||
base_model_id=None,
|
||||
name=m['name'],
|
||||
meta=ModelMeta(
|
||||
description=f"GitHub Copilot 官方模型。倍率: {m['multiplier']}x。支持推理: {m['reasoning']}。",
|
||||
capabilities={
|
||||
"vision": m['vision'],
|
||||
"reasoning": m['reasoning']
|
||||
}
|
||||
),
|
||||
params=ModelParams()
|
||||
)
|
||||
|
||||
try:
|
||||
if Models.insert_new_model(form_data, admin_user_id):
|
||||
print(f"✅ 成功同步: {m['name']}")
|
||||
except Exception as e:
|
||||
print(f"❌ 同步 {m['id']} 失败: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(sync_to_db())
|
||||
111
plugins/pipes/github-copilot-sdk/scripts/test_sdk.py
Normal file
111
plugins/pipes/github-copilot-sdk/scripts/test_sdk.py
Normal file
@@ -0,0 +1,111 @@
|
||||
import asyncio
|
||||
import os
|
||||
import json
|
||||
import time
|
||||
from typing import Any
|
||||
from datetime import datetime
|
||||
from copilot import CopilotClient
|
||||
|
||||
# 自定义 JSON 编码器,处理 datetime 等对象
|
||||
class SDKEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
if isinstance(obj, datetime):
|
||||
return obj.isoformat()
|
||||
if hasattr(obj, "to_dict"):
|
||||
return obj.to_dict()
|
||||
try:
|
||||
return super().default(obj)
|
||||
except TypeError:
|
||||
return str(obj)
|
||||
|
||||
async def run_debug_test(client, model_id, effort, prompt):
|
||||
print(f"\n" + "🔍" * 15)
|
||||
print(f"DEBUGGING: {model_id} | {effort.upper()}")
|
||||
print("🔍" * 15)
|
||||
|
||||
session_config = {
|
||||
"model": model_id,
|
||||
"reasoning_effort": effort
|
||||
}
|
||||
|
||||
queue = asyncio.Queue()
|
||||
done = asyncio.Event()
|
||||
SENTINEL = object()
|
||||
|
||||
def handler(event):
|
||||
try:
|
||||
etype = getattr(event, "type", "unknown")
|
||||
if hasattr(etype, "value"): etype = etype.value
|
||||
|
||||
raw_data = {}
|
||||
# 优先尝试 SDK 自带的 to_dict
|
||||
if hasattr(event, "to_dict"):
|
||||
raw_data = event.to_dict()
|
||||
elif hasattr(event, "data"):
|
||||
data_obj = event.data
|
||||
if isinstance(data_obj, dict):
|
||||
raw_data = data_obj
|
||||
elif hasattr(data_obj, "to_dict"):
|
||||
raw_data = data_obj.to_dict()
|
||||
else:
|
||||
raw_data = {k: v for k, v in vars(data_obj).items() if not k.startswith('_')}
|
||||
else:
|
||||
raw_data = {k: v for k, v in vars(event).items() if not k.startswith('_')}
|
||||
|
||||
queue.put_nowait((etype, raw_data))
|
||||
|
||||
if etype in ["session.idle", "session.error"]:
|
||||
done.set()
|
||||
queue.put_nowait(SENTINEL)
|
||||
except Exception as e:
|
||||
print(f"Handler Error: {e}")
|
||||
|
||||
try:
|
||||
session = await client.create_session(config=session_config)
|
||||
unsubscribe = session.on(handler)
|
||||
|
||||
print(f"Sending prompt...")
|
||||
asyncio.create_task(session.send({"prompt": prompt, "mode": "immediate"}))
|
||||
|
||||
event_count = 0
|
||||
while True:
|
||||
try:
|
||||
item = await asyncio.wait_for(queue.get(), timeout=180)
|
||||
if item is SENTINEL: break
|
||||
|
||||
etype, data = item
|
||||
event_count += 1
|
||||
|
||||
# 打印所有事件,不进行过滤,这样我们可以看到完整的生命周期
|
||||
print(f"\n[#{event_count} EVENT: {etype}]")
|
||||
print(json.dumps(data, indent=2, ensure_ascii=False, cls=SDKEncoder))
|
||||
|
||||
except asyncio.TimeoutError:
|
||||
print("\n⚠️ Timeout: No events for 180s")
|
||||
break
|
||||
|
||||
unsubscribe()
|
||||
await session.destroy()
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Session Failed: {e}")
|
||||
|
||||
async def main():
|
||||
gh_token = os.environ.get("GH_TOKEN")
|
||||
if not gh_token:
|
||||
print("❌ Error: GH_TOKEN not set")
|
||||
return
|
||||
|
||||
client = CopilotClient()
|
||||
await client.start()
|
||||
|
||||
# 使用一个简单但需要思考的问题
|
||||
prompt = "123 * 456 等于多少?请给出思考过程。"
|
||||
target_model = "gpt-5-mini"
|
||||
|
||||
await run_debug_test(client, target_model, "high", prompt)
|
||||
|
||||
await client.stop()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user