# 视觉 SDK

调摄像头、拍照、从文件选图，压缩后交给视觉模型做结构化判断，再把结果画回图上。只用浏览器原生能力（`getUserMedia`、`canvas`、`createImageBitmap`），不引第三方库。页面必须是 HTTPS（或 localhost）。

```js
import { vision } from "/developer/sdk/v1/aidc.js";
```

清单里声明：`"sdk": ["vision", "model"]`、`"permissions": { "camera": true }`、`"models": ["gpt-6-luna"]`。

## 摄像头

```js
const camera = await vision.openCamera({ video: document.querySelector("video"), facingMode: "environment" });
const photo = await camera.capture({ maxSize: 1280 });  // 长边 1280 的 JPEG
await camera.switchTo({ facingMode: "user" });          // 切前置
camera.stop();                                          // 幂等
```

| 方法 | 说明 |
| --- | --- |
| `openCamera(options)` | `video`（挂到哪个 `<video>`）、`facingMode`（`environment` 后置 / `user` 前置）、`deviceId`、`width` / `height` |
| `camera.capture(options)` | 拍一张 → `Photo`；`maxSize`（长边像素，缺省 1280）、`type`、`quality` |
| `camera.switchTo(target)` | 换摄像头 |
| `camera.devices()` | 列出可用摄像头 |
| `camera.stop()` | 关闭（释放设备） |

`Photo = { blob, dataUrl, width, height, type, takenAt }`。

## 没有摄像头时

```js
const photo = await vision.pickImage();          // 手机上优先调起相机；电脑上选文件；取消返回 null
const photo2 = await vision.fromFile(file);      // 已有的 File / Blob
```

## 看图判断

```js
const result = await vision.inspect(photo, {
  task: "检查成衣表面有没有污渍、破洞、跳线",
  criteria: "任何肉眼可见的污渍或破损都判不合格",   // 可选
  model: "gpt-6-luna",                             // 缺省
  reasoning: "low",                                // 缺省
});
// → { verdict: "pass" | "fail" | "uncertain", summary, findings: [...], model }
```

每条 `finding`：`label`（油污、划痕…）、`category`、`severity`（low / medium / high）、`confidence`（0–1）、`box`（归一化坐标 `[x0, y0, x1, y1]`，定位不准时为 `null`）、`note`。图片模糊或看不清时模型给 `uncertain`，不会硬判合格。

可以一次给多张图（同一件物品的不同角度）：`vision.inspect([photoA, photoB], { task })`。

## 画框标注

```js
const canvas = await vision.annotate(photo, result.findings);   // 返回画好框的 <canvas>
document.body.append(canvas);
```

## 上传给智能体

图片可以直接交给某个智能体（走 Agent API 的附件协议，24 小时内有效）：

```js
const agent = connect.agent(agentKey);
const fileId = await agent.upload(photo.blob, "defect.jpg");
await agent.send("这是今天 3 号线的不合格品，请登记。", { files: [fileId] });
```

见 [连接 SDK](connect.md)。

## 命令行

```bash
aidc vision inspect a.jpg b.jpg --task "布面有没有污渍" --json
```

## 错误

`camera_denied`（没给权限）、`camera_not_found`、`camera_busy`、`camera_unsupported`（非 HTTPS / 旧浏览器）、`invalid_model_output`；以及 API 的 `forbidden`（清单没声明模型）、`quota_exhausted`（应用当日额度用完）、`rate_limited`。
