# eduwin AI 大模型 API

> 头文件：`eduwin_ai.h`（或通过 `eduwin.h` 统一引用）

基于 WinHTTP 调用大语言模型 API，提供同步、异步、窗口异步三种调用方式。依赖 `eduwin_net` 的 HTTP 能力。线程安全——异步接口内部使用 `eduwin_thread` 的 `thread_run` 管理线程。

## 初始化

```c
void ai_setup(const char *api_key, const char *model, const char *base_url);
```

配置 API Key、模型名、Base URL。**必须先调 `net_init()`**。

```c
net_init();
ai_setup("sk-xxx", "deepseek-chat", "https://api.deepseek.com/v1");
```

## 同步调用

```c
char* ai_chat(const char *prompt);
void  ai_free(char *ptr);
```

发送 prompt，阻塞等待完整回复。返回的字符串需用 `ai_free` 释放。

```c
char *reply = ai_chat("用 C 语言实现冒泡排序");
if (reply) {
    printf("%s", reply);
    ai_free(reply);
}
```

**注意：** 同步调用会阻塞当前线程。GUI 程序请用异步或窗口异步接口。

## 异步调用

```c
typedef void (*ai_callback_t)(const char *reply, void *userdata);

void ai_chat_async(const char *prompt, ai_callback_t callback, void *userdata);
```

不阻塞调用线程，请求完成后通过回调返回结果。`userdata` 在回调中原样传回。

```c
void on_reply(const char *reply, void *userdata) {
    if (reply) set_text(g_label, L"AI 回复已收到");
    ai_free((void*)reply);
}
ai_chat_async("你好", on_reply, NULL);
```

## 窗口异步调用

```c
void ai_chat_async_to_hwnd(HWND hwnd, const char *prompt, void *userdata);
int  ai_handle_async_msg(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
                                void (*on_result)(const char *reply, void *userdata));
```

请求完成后通过 `PostMessage` 通知指定窗口，在窗口过程中用 `ai_handle_async_msg` 处理。

```c
// 窗口过程中
LRESULT CALLBACK WndProc(HWND h, UINT m, WPARAM w, LPARAM l) {
    if (ai_handle_async_msg(h, m, w, l, on_result))
        return 0;
}

// 任意位置发起请求
ai_chat_async_to_hwnd(g_win, "写一首诗", NULL);
```

## 完整示例

参见 `samples/ai_chat_demo/`。

## 模型兼容性

`eduwin_ai` 使用 OpenAI 兼容 API 格式（Chat Completion），支持：

- DeepSeek (`api.deepseek.com`)
- 智谱 GLM (`open.bigmodel.cn`)
- 阿里通义千问 (`dashscope.aliyuncs.com/compatible-mode`)
- 任何提供 `/v1/chat/completions` 端点的服务

## 编译要求

与 `eduwin_net` 相同，需要在 link 命令中添加：

```
ws2_32.lib winhttp.lib
```
