copilot-api 部署笔记

copilot-api

bash 复制代码
https://github.com/ericc-ch/copilot-api
bash 复制代码
# 一键构建并运行
docker build -t bun-app . && docker run -d -p 4141:4141 --name bun-app bun-app

# 查看实时日志
docker logs -f bun-app

# 停止并删除
docker rm -f bun-app

需要从github上输入验证码进行验证登录。

python测试脚本:

python 复制代码
#!/usr/bin/env python3
# geogebra_copilot_test.py

import requests
import json
import time
from typing import List, Dict, Optional


class GeoGebraCopilotTester:
    def __init__(self, base_url: str = "http://localhost:4141"):
        self.base_url = base_url
        self.session = requests.Session()
        self.session.headers.update({"Content-Type": "application/json"})
        self.conversation_history = []

    def generate_code(self, prompt: str, system_prompt: str = None) -> Optional[str]:
        """生成 GeoGebra 代码"""
        messages = []

        if system_prompt:
            messages.append({"role": "system", "content": system_prompt})

        messages.append({"role": "user", "content": prompt})

        payload = {"model": "gpt-4",  # 使用测试中成功的模型
            "messages": messages, "temperature": 0.3, "max_tokens": 1000}

        try:
            response = self.session.post(f"{self.base_url}/v1/chat/completions", json=payload)

            if response.status_code == 200:
                data = response.json()
                code = data['choices'][0]['message']['content']
                return code
            else:
                print(f"错误: {response.status_code} - {response.text}")
                return None
        except Exception as e:
            print(f"异常: {e}")
            return None

    def chat_with_context(self, user_message: str) -> Optional[str]:
        """带上下文的对话(保持会话历史)"""
        self.conversation_history.append({"role": "user", "content": user_message})

        payload = {"model": "gpt-4", "messages": self.conversation_history, "temperature": 0.3, "max_tokens": 1000}

        try:
            response = self.session.post(f"{self.base_url}/v1/chat/completions", json=payload)

            if response.status_code == 200:
                data = response.json()
                assistant_message = data['choices'][0]['message']['content']
                self.conversation_history.append({"role": "assistant", "content": assistant_message})
                return assistant_message
            else:
                print(f"错误: {response.status_code}")
                return None
        except Exception as e:
            print(f"异常: {e}")
            return None

    def clear_context(self):
        """清除对话历史"""
        self.conversation_history = []
        print("对话历史已清除")

    def test_basic_shapes(self):
        """测试基本几何图形生成"""
        print("\n" + "=" * 60)
        print("测试 1: 基本几何图形")
        print("=" * 60)

        tests = [("三角形", "画一个等边三角形,边长为5"), ("正方形", "画一个正方形,左下角在(0,0),边长为4"), ("圆", "画一个圆,圆心在(0,0),半径为3"), ("矩形", "画一个矩形,宽为6,高为4,左下角在(1,1)"), ]

        system_prompt = "You are a GeoGebra expert. Generate only GeoGebra executable code, no explanations."

        for name, prompt in tests:
            print(f"\n📐 生成{name}: {prompt}")
            print("-" * 40)
            code = self.generate_code(prompt, system_prompt)
            if code:
                print(f"✅ 生成的代码:\n{code}")
            else:
                print(f"❌ 生成失败")
            time.sleep(0.5)  # 避免请求过快

    def test_complex_shapes(self):
        """测试复杂图形生成"""
        print("\n" + "=" * 60)
        print("测试 2: 复杂图形")
        print("=" * 60)

        tests = [("五边形", "画一个正五边形,外接圆半径为4"), ("椭圆", "画一个椭圆,长轴为6,短轴为4,中心在(0,0)"), ("扇形", "画一个90度的扇形,圆心在(0,0),半径为5"),
            ("圆弧", "画一个半圆,从(0,0)到(4,0)"), ]

        system_prompt = "Generate GeoGebra code. Only output the code, no explanations."

        for name, prompt in tests:
            print(f"\n📐 生成{name}: {prompt}")
            print("-" * 40)
            code = self.generate_code(prompt, system_prompt)
            if code:
                print(f"✅ 生成的代码:\n{code}")
            else:
                print(f"❌ 生成失败")
            time.sleep(0.5)

    def test_multi_turn_conversation(self):
        """测试多轮对话"""
        print("\n" + "=" * 60)
        print("测试 3: 多轮对话")
        print("=" * 60)

        self.clear_context()

        # 添加系统提示
        self.conversation_history.append({"role": "system", "content": "You are a GeoGebra assistant. Generate only GeoGebra code, no explanations."})

        # 第一轮:画三角形
        print("\n👤 用户: 画一个三角形,顶点为(0,0), (3,0), (1.5, 2.6)")
        response1 = self.chat_with_context("画一个三角形,顶点为(0,0), (3,0), (1.5, 2.6)")
        if response1:
            print(f"🤖 助手:\n{response1}")

        # 第二轮:修改颜色
        print("\n👤 用户: 把这个三角形涂成红色")
        response2 = self.chat_with_context("把这个三角形涂成红色")
        if response2:
            print(f"🤖 助手:\n{response2}")

        # 第三轮:添加内切圆
        print("\n👤 用户: 在三角形内部画一个内切圆")
        response3 = self.chat_with_context("在三角形内部画一个内切圆")
        if response3:
            print(f"🤖 助手:\n{response3}")

    def test_geoegbra_commands(self):
        """测试特定 GeoGebra 命令"""
        print("\n" + "=" * 60)
        print("测试 4: GeoGebra 命令测试")
        print("=" * 60)

        commands = ["中点", "角平分线", "垂线", "平行线", "切线"]

        system_prompt = "Generate GeoGebra code. Output only the code."

        for cmd in commands:
            print(f"\n📐 测试命令: {cmd}")
            print("-" * 40)
            prompt = f"演示如何使用GeoGebra的{cmd}命令"
            code = self.generate_code(prompt, system_prompt)
            if code:
                print(f"✅ 生成的代码:\n{code}")
            else:
                print(f"❌ 生成失败")
            time.sleep(0.5)

    def test_error_handling(self):
        """测试错误处理"""
        print("\n" + "=" * 60)
        print("测试 5: 错误处理测试")
        print("=" * 60)

        # 测试空提示
        print("\n📐 测试空提示:")
        code = self.generate_code("")
        if code:
            print(f"✅ 响应: {code[:100]}...")
        else:
            print("✅ 正确处理空提示")

        # 测试无效请求
        print("\n📐 测试无效模型:")
        try:
            payload = {"model": "invalid_model_name", "messages": [{"role": "user", "content": "test"}]}
            response = self.session.post(f"{self.base_url}/v1/chat/completions", json=payload)
            print(f"状态码: {response.status_code}")
            if response.status_code == 400:
                print("✅ 正确处理无效模型")
        except Exception as e:
            print(f"错误处理: {e}")

    def get_usage_info(self):
        """获取使用统计"""
        print("\n" + "=" * 60)
        print("使用统计")
        print("=" * 60)

        try:
            # 获取使用情况
            response = self.session.get(f"{self.base_url}/usage")
            if response.status_code == 200:
                data = response.json()
                print("✅ 使用情况:")
                print(json.dumps(data, indent=2, ensure_ascii=False)[:500])
            else:
                print("⚠️ 无法获取使用情况")
        except Exception as e:
            print(f"获取使用情况失败: {e}")

        try:
            # 获取模型列表
            response = self.session.get(f"{self.base_url}/v1/models")
            if response.status_code == 200:
                data = response.json()
                models = data.get('data', [])
                print(f"\n✅ 可用模型 ({len(models)}个):")
                for model in models[:10]:  # 只显示前10个
                    print(f"   - {model.get('id')}")
        except Exception as e:
            print(f"获取模型列表失败: {e}")

    def run_all_tests(self):
        """运行所有测试"""
        print("=" * 60)
        print("GeoGebra Copilot API 完整测试")
        print("=" * 60)

        # 获取使用信息
        self.get_usage_info()

        # 运行测试
        self.test_basic_shapes()
        self.test_complex_shapes()
        self.test_multi_turn_conversation()
        self.test_geoegbra_commands()
        self.test_error_handling()

        print("\n" + "=" * 60)
        print("所有测试完成!")
        print("=" * 60)


def main():
    tester = GeoGebraCopilotTester("http://localhost:4141")
    tester.run_all_tests()


if __name__ == "__main__":
    main()
相关推荐
帐篷Li2 小时前
AI Token中转站盈利模式深度解析:定价、获客与成本控制
人工智能·github
淮北4942 小时前
claude +obsidian 建立自己的AI知识库,基于 karpathy
人工智能·claude·知识库·obsidian·chrom
TechMasterPlus2 小时前
agent-browser 技术深度解析:Vercel 推出的 AI 时代浏览器自动化利器
运维·人工智能·自动化
摘星编程2 小时前
当AI学会分工合作:用MCP和A2A协议搭一套多智能体系统,跑了跑真实业务流程
人工智能
HIT_Weston10 小时前
45、【Agent】【OpenCode】本地代理分析(请求&接收回调)
人工智能·agent·opencode
逻辑君10 小时前
认知神经科学研究报告【20260010】
人工智能·深度学习·神经网络·机器学习
星河耀银海10 小时前
远控体验分享:安全与实用性参考
人工智能·安全·微服务
企业架构师老王11 小时前
2026企业架构演进:科普Agent(龙虾)如何从“极客玩具”走向实在Agent规模化落地?
人工智能·ai·架构
GreenTea11 小时前
一文搞懂Harness Engineering与Meta-Harness
前端·人工智能·后端