focalapi-cli 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,50 +1,53 @@
1
- {
2
- "name": "focalapi-cli",
3
- "version": "0.1.1",
4
- "description": "连接 focalapi 创作模型与 AI Agent 的命令行工具——图像、视频、音频与 DeepSeek 备用文本能力",
5
- "type": "module",
6
- "bin": {
7
- "focalapi": "dist/cli.js"
8
- },
9
- "files": [
10
- "dist",
11
- "skills",
12
- "README.md",
13
- "LICENSE"
14
- ],
15
- "engines": {
16
- "node": ">=18"
17
- },
18
- "scripts": {
19
- "dev": "tsx src/cli.ts",
20
- "build": "tsup",
21
- "test": "vitest run",
22
- "test:watch": "vitest",
23
- "typecheck": "tsc --noEmit",
24
- "prepublishOnly": "npm run build && npm test"
25
- },
26
- "keywords": [
27
- "focalapi",
28
- "ai",
29
- "agent",
30
- "cli",
31
- "llm",
32
- "image-generation",
33
- "video-generation"
34
- ],
35
- "license": "Apache-2.0",
36
- "repository": {
37
- "type": "git",
38
- "url": "https://gitee.com/xnn-ai/focalapi-cli.git"
39
- },
40
- "dependencies": {
41
- "commander": "^12.1.0"
42
- },
43
- "devDependencies": {
44
- "@types/node": "^20.11.0",
45
- "tsup": "^8.2.4",
46
- "tsx": "^4.19.0",
47
- "typescript": "^5.5.4",
48
- "vitest": "^2.1.9"
49
- }
50
- }
1
+ {
2
+ "name": "focalapi-cli",
3
+ "version": "0.2.0",
4
+ "description": "让任意 AI Agent 直接调用 focalapi 创作模型的命令行工具",
5
+ "type": "module",
6
+ "bin": {
7
+ "focalapi": "dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "scripts",
12
+ "skills",
13
+ "README.md",
14
+ "CHANGELOG.md",
15
+ "LICENSE"
16
+ ],
17
+ "engines": {
18
+ "node": ">=18"
19
+ },
20
+ "scripts": {
21
+ "dev": "tsx src/cli.ts",
22
+ "build": "tsup",
23
+ "test": "vitest run",
24
+ "test:watch": "vitest",
25
+ "typecheck": "tsc --noEmit",
26
+ "postinstall": "node scripts/postinstall.cjs",
27
+ "prepublishOnly": "npm run build && npm test"
28
+ },
29
+ "keywords": [
30
+ "focalapi",
31
+ "ai",
32
+ "agent",
33
+ "cli",
34
+ "llm",
35
+ "image-generation",
36
+ "video-generation"
37
+ ],
38
+ "license": "Apache-2.0",
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://gitee.com/xnn-ai/focalapi-cli.git"
42
+ },
43
+ "dependencies": {
44
+ "commander": "^12.1.0"
45
+ },
46
+ "devDependencies": {
47
+ "@types/node": "^20.11.0",
48
+ "tsup": "^8.2.4",
49
+ "tsx": "^4.19.0",
50
+ "typescript": "^5.5.4",
51
+ "vitest": "^2.1.9"
52
+ }
53
+ }
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * npm 全局安装后的 best-effort Agent 接入。
5
+ *
6
+ * 只运行本地 connect:不联网、不读取 API Key、不改 Agent provider。没有检测到
7
+ * Agent 或接入失败都不影响 CLI 安装;用户之后可运行 focalapi connect 修复。
8
+ */
9
+
10
+ const { existsSync } = require('node:fs');
11
+ const { join } = require('node:path');
12
+ const { spawnSync } = require('node:child_process');
13
+
14
+ if (process.env.FOCALAPI_SKIP_POSTINSTALL === '1' || process.env.CI === '1' || process.env.CI === 'true') {
15
+ process.exit(0);
16
+ }
17
+
18
+ const cli = join(__dirname, '..', 'dist', 'cli.js');
19
+ if (!existsSync(cli)) process.exit(0);
20
+
21
+ const result = spawnSync(process.execPath, [cli, 'connect', 'install', '--json'], {
22
+ encoding: 'utf8',
23
+ env: process.env,
24
+ windowsHide: true,
25
+ });
26
+
27
+ if (result.status === 0) {
28
+ try {
29
+ const output = JSON.parse(result.stdout || '{}');
30
+ const count = Array.isArray(output.installed) ? output.installed.length : 0;
31
+ if (count > 0) console.log(`focalapi-cli: 已自动接入 ${count} 个 Agent Skills 目录;重启 Agent 后生效。`);
32
+ } catch {
33
+ // connect 成功但输出不可解析不影响安装。
34
+ }
35
+ process.exit(0);
36
+ }
37
+
38
+ if (!String(result.stderr).includes('未检测到本机 Agent')) {
39
+ console.warn('focalapi-cli: Agent Skills 自动接入未完成;请稍后运行 `focalapi connect`。');
40
+ }
41
+ process.exit(0);
@@ -1,43 +1,54 @@
1
- ---
2
- name: focalapi
3
- description: focalapi 创作能力总入口。Use when 用户需要生成或处理图像、视频、音频、3D 或其他视觉创作内容;DeepSeek 仅用于提示词、分镜和轻量文本辅助。先读本技能选择对应的子技能或命令。
4
- ---
5
-
6
- # focalapi 创作能力总览
7
-
8
- focalapi 是面向创作工作流的模型中转服务。`focalapi` CLI 让 Agent 用命令完成图像、视频、音频与其他视觉创作任务;通用文本只将 DeepSeek 作为备用能力。
9
-
10
- ## 前置检查
11
-
12
- ```bash
13
- focalapi --version
14
- focalapi auth status
15
- focalapi models list --json
16
- # 选定创作模型后,读取支持参数、端点与默认值
17
- focalapi models get <模型ID> --json
18
- ```
19
-
20
- 模型、参数、并发和价格始终以 `focalapi models list --json` 与控制台模型广场的实际结果为准。命令失败时,先执行 `focalapi doctor` 排查 Key、网络与额度。
21
-
22
- ## 能力 命令速查
23
-
24
- | 需求 | 命令 | 子技能 |
25
- |---|---|---|
26
- | 生成或编辑图像 | `focalapi gen image`(可 `--no-wait` 提交持久任务) | focalapi-gen |
27
- | 生成 Gemini 原生图像 | `focalapi gen gemini-image` | focalapi-gen |
28
- | 生成视频 | `focalapi gen video`(任务制,可 `--no-wait`) | focalapi-gen |
29
- | 查询任务或下载视频产物 | `focalapi task status` / `focalapi task download` | focalapi-gen |
30
- | 语音转文字 | `focalapi audio transcribe` | focalapi-chat |
31
- | 文字转语音 | `focalapi audio speech` | focalapi-chat |
32
- | 提示词、分镜或脚本辅助 | `focalapi chat -m <DeepSeek 模型>` | focalapi-chat |
33
- | 额度与诊断 | `focalapi usage` / `focalapi doctor` | focalapi-usage |
34
- | 查询可用模型 | `focalapi models list --json` | focalapi |
35
-
36
- ## 使用约定
37
-
38
- 1. **创作优先**:图像、视频、音频和视觉模型是默认选择。3D 或其他视觉模型是否可用,以模型列表为准。
39
- 2. **文本边界**:仅在提示词、分镜、旁白草稿或轻量文本任务中使用 DeepSeek;不要假设其他文本、编码或聊天模型可用。
40
- 3. **机器可读输出**:命令加 `--json` 时,stdout 只输出 JSON。
41
- 4. **先查模型再调用**:不能猜测模型 ID;先运行 `focalapi models list --json`,选定模型后运行 `focalapi models get <模型ID> --json`,以 `supported_endpoint_types` 和 `supported_params` 为准。
42
- 5. **产物路径**:生成类命令默认写入 `./focalapi-out/`,完成后向用户报告绝对路径。
43
- 6. **原始只读请求**:优先使用语义化命令;只有读取尚未封装的端点时才使用 `request get` / `request head`。
1
+ ---
2
+ name: focalapi
3
+ version: 2.0.0
4
+ description: "focalapi 创作模型总入口。当用户要生成、编辑或处理创作内容,选择创作模型,或查询生成任务时,即使用户没有提到 focalapi,也应使用本技能;覆盖图片与视频的自动选模、生成、异步续取和故障分流。"
5
+ metadata:
6
+ requires:
7
+ bins: ["focalapi"]
8
+ cliHelp: "focalapi --help"
9
+ ---
10
+
11
+ # focalapi 创作模型路由
12
+
13
+ focalapi 是供当前 Agent 调用的创作模型中转能力,不是 Agent 自身的
14
+ model/provider。不要修改 Agent 的主模型配置,也不要要求用户先说“用 focalapi”。
15
+
16
+ ## 零试错执行契约
17
+
18
+ 1. 用户未指定模型:直接省略 `--model`。CLI 会根据当前 Key 的实时模型池和
19
+ 单模型详情契约选择 FocalAPI 默认模型;不要先生成测试样例。
20
+ 2. 用户指定模型或厂商:先运行 `focalapi models get <model-id> --json`;模型 ID
21
+ 不完整时只运行一次 `models search` 找到精确 ID,再读取详情。
22
+ 3. 只使用详情 `supported_params` 中存在的参数和允许值;不得根据相似模型猜测。
23
+ 4. Agent/脚本调用统一加 `--json`。stdout 是唯一机读结果,诊断在 stderr。
24
+ 5. 生成成功后必须把本地绝对文件路径交给用户;视频任务返回 `task_id` 时沿
25
+ `next_command` 续取,不要重复提交一个新任务。
26
+
27
+ ```bash
28
+ # 用户没指定模型:一步直达,不要先试模型
29
+ focalapi gen image "<用户提示词>" -o ./focalapi-out --json
30
+ focalapi gen video "<用户提示词>" --no-wait -o ./focalapi-out --json
31
+
32
+ # 视频异步续取
33
+ focalapi task status <task-id> --json
34
+ focalapi task download <task-id> -o ./focalapi-out --json
35
+ ```
36
+
37
+ ## 路由表
38
+
39
+ | 用户目标 | 入口 | 技能 |
40
+ | --- | --- | --- |
41
+ | 生图、图片编辑、参考图创作 | `focalapi gen image` | focalapi-gen |
42
+ | 生视频、图生视频、参考素材创作 | `focalapi gen video` | focalapi-gen |
43
+ | 指定/比较模型或查看参数 | `focalapi models resolve/get/search` | focalapi-models |
44
+ | 查询进度、失败原因、下载产物 | `focalapi task status/download` | focalapi-task |
45
+ | Key、401、登录问题 | `focalapi auth status/login` | focalapi-auth |
46
+ | 额度、用量、服务异常 | `focalapi usage/doctor` | focalapi-usage |
47
+ | 用户明确要求文本辅助 | `focalapi chat` | focalapi-chat |
48
+
49
+ 当前已闭环验证的自动生成入口是图片与视频。未来出现音频、3D 或其他模态时,
50
+ 只有在 CLI 帮助和 `models get` 同时给出可执行契约后才能调用;不要仅凭模型列表或
51
+ 名称推断能力。
52
+
53
+ 若业务命令返回 `missing_api_key`,转 focalapi-auth 完成登录后立即回到原任务;
54
+ 其他错误只按 `{error.code, error.hint}` 修复一次,不要盲目轮换模型。
@@ -1,50 +1,30 @@
1
- ---
2
- name: focalapi-auth
3
- description: focalapi CLI 的安装、登录、Key 管理与连通性验证。Use when focalapi 命令报 missing_api_key/invalid_api_key 错误、需要配置 FOCALAPI_API_KEY、或首次安装接入 focalapi。
4
- ---
5
-
6
- # focalapi 认证与接入
7
-
8
- ## 安装
9
-
10
- ```bash
11
- npm i -g focalapi-cli
12
- focalapi --version
13
- ```
14
-
15
- 要求 Node.js 18。
16
-
17
- ## 登录(三选一)
18
-
19
- ```bash
20
- # 1. 显式传 key(Agent 环境推荐)
21
- focalapi auth login --key sk-xxxx
22
-
23
- # 2. 环境变量(不落盘,CI/沙箱推荐)
24
- export FOCALAPI_API_KEY=sk-xxxx
25
-
26
- # 3. 交互粘贴(仅终端)
27
- focalapi auth login
28
- ```
29
-
30
- Key 在 https://focalapi.com/console/token 创建。本地保存位置:`~/.focalapi/config.json`(权限 600)。
31
-
32
- ## 验证
33
-
34
- ```bash
35
- focalapi auth status # Key 有效性 + 额度 + 来源
36
- focalapi doctor # 网络→鉴权→演练模型→额度 全链路(免费)
37
- ```
38
-
39
- ## 自定义端点
40
-
41
- 私有化部署时:`export FOCALAPI_BASE_URL=https://你的域名`(或 `--base-url` flag,或登录时写入 profile)。
42
-
43
- ## 常见错误
44
-
45
- | 错误码 | 含义 | 处理 |
46
- |---|---|---|
47
- | missing_api_key | 没配 Key | 按上面任一方式登录 |
48
- | invalid_api_key | Key 无效/过期/被删 | 控制台重建 Key 后重新 login |
49
- | insufficient_quota | 额度不足 | 控制台充值;`focalapi usage` 查明细 |
50
- | network_error | 连不上 | 查网络/代理/BASE_URL;跑 `focalapi doctor` |
1
+ ---
2
+ name: focalapi-auth
3
+ version: 2.0.0
4
+ description: "处理 focalapi-cli 安装、首次登录、Key 状态和 401/鉴权错误。仅在首次接入或业务命令明确返回 missing_api_key/invalid_api_key 时触发;认证完成后必须回到原创作任务。"
5
+ metadata:
6
+ requires:
7
+ bins: ["focalapi"]
8
+ cliHelp: "focalapi auth --help"
9
+ ---
10
+
11
+ # focalapi 认证
12
+
13
+ ```bash
14
+ npm i -g focalapi-cli
15
+ focalapi auth login --key <sk-key>
16
+ focalapi auth status --json
17
+ focalapi connect
18
+ ```
19
+
20
+ Key 在 `https://focalapi.com/console/token` 创建。不要在回复、日志或命令回显中展示
21
+ 完整 Key;CI/沙箱优先通过 `FOCALAPI_API_KEY` 注入。
22
+
23
+ 业务命令未报鉴权错误时,不要每次都运行 `auth status`。命中错误后按固定路径:
24
+
25
+ - `missing_api_key`:登录或设置 `FOCALAPI_API_KEY`;
26
+ - `invalid_api_key`:让用户在控制台确认/新建 Key 后重新登录;
27
+ - `upstream_auth_failed`:本站 Key 可能正常,保留 request ID,转服务方排查;不要让
28
+ 用户反复更换自己的 Key。
29
+
30
+ 认证成功后立即重试原业务命令,不要把登录本身当作任务终点。
@@ -1,29 +1,32 @@
1
- ---
2
- name: focalapi-chat
3
- description: 用 DeepSeek 作为创作流程的文本备用能力,并通过 focalapi 处理音频转写和语音合成。Use when 用户需要提示词、分镜、脚本草稿、看图辅助、音频转写或文字转语音。
4
- ---
5
-
6
- # focalapi 文本辅助与音频
7
-
8
- ## DeepSeek 文本辅助
9
-
10
- DeepSeek 是 focalapi 唯一对外展示的通用文本备用能力。先查询可用模型,再用于提示词、分镜、旁白与轻量脚本任务:
11
-
12
- ```bash
13
- focalapi models list --json
14
- focalapi chat "把这个产品简介写成 6 镜头分镜" -m <DeepSeek模型>
15
- ```
16
-
17
- - 不要猜测模型 ID,也不要假设其他文本或编码模型可用。
18
- - 需要结构化输出时使用 `--json`;长结果可加 `--stream`。
19
- - `--input @image.png` 可把图片作为辅助输入;图像生成请改用 `focalapi gen image`。
20
-
21
- ## 音频
22
-
23
- ```bash
24
- focalapi audio transcribe interview.mp3 -m <转写模型>
25
- focalapi audio speech "这里是一段旁白" -m <语音模型> -o narration.mp3
26
- ```
27
-
28
- - 音频模型、可用音色和格式以 `focalapi models list --json` 为准。
29
- - 批量任务前先用短样本确认质量和单价。
1
+ ---
2
+ name: focalapi-chat
3
+ version: 2.0.0
4
+ description: "focalapi 的补充文本与音频命令。仅当用户明确要求通过 focalapi 做文本辅助,或实时模型契约明确存在可调用的音频模型时使用;图片/视频创作必须转 focalapi-gen。"
5
+ metadata:
6
+ requires:
7
+ bins: ["focalapi"]
8
+ cliHelp: "focalapi chat --help"
9
+ ---
10
+
11
+ # focalapi 补充能力
12
+
13
+ 本技能不是创作请求的默认入口。图片、视频、改图、图生视频统一转
14
+ `focalapi-gen`。
15
+
16
+ 用户明确要求文本辅助时,先从实时列表取得可用文本模型,再调用:
17
+
18
+ ```bash
19
+ focalapi models list --json
20
+ focalapi chat "<用户文本任务>" -m <列表中的文本模型> --json
21
+ ```
22
+
23
+ 音频命令只有在 `focalapi models get <model-id> --json` 与 `focalapi audio --help`
24
+ 共同确认可执行时才能使用:
25
+
26
+ ```bash
27
+ focalapi audio transcribe <file> -m <model-id> --json
28
+ focalapi audio speech "<text>" -m <model-id> -o <file> --json
29
+ ```
30
+
31
+ 模型列表里出现名称不等于 CLI 已支持调用。当前 Key 没有音频模型契约时应明确说明
32
+ 暂不可用,不要尝试相似模型或外部接口。
@@ -1,79 +1,53 @@
1
- ---
2
- name: focalapi-gen
3
- description: 用 focalapi 生成图片和视频(产物自动下载到本地)。Use when 用户要画图、生成海报/插画/logo、图生图、文生视频、或查询/下载视频生成任务产物。
4
- ---
5
-
6
- # focalapi 图像与视频生成
7
-
8
- ## 图片(同步)
9
-
10
- 调用创作模型前,先读取它的机器可读契约;不要猜测尺寸、时长或原生端点:
11
-
12
- ```bash
13
- focalapi models get <模型ID> --json
14
- ```
15
-
16
- 响应中的 `supported_endpoint_types` 指明应使用的 API 协议,`supported_params` 列出参数、默认值、枚举和边界。CLI 会提前拒绝已知无效参数;应修正参数,不要将同一参数重试给上游。
17
-
18
- ```bash
19
- focalapi gen image "未来城市夜景海报,赛博朋克风" -m <图像模型> --size 1024x1024 -o ./out
20
- # 多张:--n 4(上限 128)
21
- # 参考图/编辑:image 可重复给 URL;response-format 只接受 url 或 b64_json
22
- focalapi gen image "将背景改为雨夜" -m gpt-image-2 --image https://example.com/source.png \
23
- --mask https://example.com/mask.png --response-format b64_json -o ./out
24
- # 长任务编排:--no-wait 要求服务端持久化任务,返回 task_id;图像结果从 task status 的 raw.data 读取 URL
25
- focalapi gen image "未来城市夜景海报,赛博朋克风" -m gpt-image-2 --size 1024x1024 --no-wait --json
26
- focalapi task status <task_id> --json
27
-
28
- # Gemini 图像模型必须走原生 Gemini generateContent 端点,不能使用 gen image
29
- focalapi gen gemini-image "未来城市夜景海报,赛博朋克风" -m gemini-3.1-flash-image-preview \
30
- --aspect-ratio 16:9 --image-size 2K -o ./out
31
- # Gemini named flags cover --image, --system, --seed, --thinking-level, --temperature, and --top-p.
32
- # For another documented generationConfig field, use --config; the command keeps responseFormat.image and candidateCount=1 authoritative.
33
- ```
34
-
35
- 产物保存到 `-o` 目录(默认 `./focalapi-out/`),stdout/stderr 会打印绝对路径,把路径直接交给用户或后续步骤。
36
-
37
- ## 视频(任务制)
38
-
39
- ```bash
40
- # 方式一:前台等待完成并自动下载(默认)
41
- focalapi gen video "海浪拍打礁石,电影感" -m <视频模型> --seconds 5 -o ./out
42
-
43
- # Seedance 2.0:使用模型原生参数。Fast/Mini 只支持 480p 和 720p;所有 Seedance 2.0 时长为 4–15 秒。
44
- focalapi gen video "海浪拍打礁石,电影感" -m doubao-seedance-2-0-260128 \
45
- --seconds 5 --resolution 720p --ratio 16:9 --generate-audio true --no-wait --json
46
-
47
- # 图生视频与 Seedance 的任务控制参数会映射到请求 metadata;布尔参数必须显式为 true 或 false
48
- focalapi gen video "让海浪缓慢推进" -m doubao-seedance-2-0-260128 \
49
- --image https://example.com/frame.png --generate-audio false --watermark true \
50
- --return-last-frame true --callback-url https://example.com/callback \
51
- --execution-expires-after 7200 --safety-identifier customer-42 --priority 4 --no-wait --json
52
-
53
- # Ark-compatible metadata.content keeps native text/image_url/video_url/audio_url items and roles unchanged:
54
- focalapi gen video "ignored when content is supplied" -m doubao-seedance-2-0-260128 \
55
- --content '[{"type":"text","text":"A cinematic ocean wave."}]' --no-wait --json
56
-
57
- # 方式二:异步——Agent 做长任务编排时推荐
58
- focalapi gen video "..." -m <视频模型> --no-wait --json # 立即拿 task_id
59
- focalapi task status <task_id> --json # 轮询状态
60
- focalapi task download <task_id> -o ./out # 完成后取 mp4
61
- ```
62
-
63
- - `--seconds` 上限 3600(CLI 与后端双重 clamp,超限直接报错)。
64
- - 轮询参数:`--poll-interval <ms>`(默认 5000)、`--timeout <分钟>`(默认 30)。
65
- - 产物下载走 focalapi 内容代理(`/v1/videos/:task_id/content`),不依赖上游签名 URL,不过期。
66
-
67
- ## JSON 输出约定(供 Agent 解析)
68
-
69
- - `gen image --json` → `{"files": ["..."], "count": N}`
70
- - `gen image --no-wait --json` → `{"task_id": "...", "status": "queued", "submitted": true}`
71
- - `gen gemini-image --json` → `{"files": ["..."], "count": N}`
72
- - `gen video --no-wait --json` → `{"task_id": "...", "submitted": true}`
73
- - `gen video --json`(等待模式)→ `{"task_id": "...", "status": "success", "file": "..."}`
74
- - `task status --json` → `{"task_id","status":"pending|running|success|failed|unknown","progress","raw"}`
75
-
76
- ## 排错
77
-
78
- - 任务失败:`focalapi task status <task_id> --json` 看 `raw` 里上游详情。
79
- - 模型名不确定:`focalapi models list --filter video` / `--filter image`。
1
+ ---
2
+ name: focalapi-gen
3
+ version: 2.0.0
4
+ description: "用 focalapi 完成图片/视频生成、图片编辑、图生视频和参考素材创作。当用户表达画图、生图、改图、生成视频或让素材动起来时直接触发,即使未提 focalapi;默认自动选模,不先试模型。"
5
+ metadata:
6
+ requires:
7
+ bins: ["focalapi"]
8
+ cliHelp: "focalapi gen --help"
9
+ ---
10
+
11
+ # focalapi 图片与视频生成
12
+
13
+ ## 默认:自动选模,一次执行
14
+
15
+ 用户没有指定模型时,直接运行:
16
+
17
+ ```bash
18
+ focalapi gen image "<完整提示词>" -o ./focalapi-out --json
19
+ focalapi gen video "<完整提示词>" --no-wait -o ./focalapi-out --json
20
+ ```
21
+
22
+ CLI 会用当前 Key 的实时模型池与详情契约选择默认模型。不要先用低成本模型、
23
+ 测试提示词或多个模型各生成一次;这会产生不必要的费用和歧义。
24
+
25
+ ## 指定模型或高级参数
26
+
27
+ 用户点名模型时,先读一次实时契约:
28
+
29
+ ```bash
30
+ focalapi models get <model-id> --json
31
+ focalapi gen image "<prompt>" -m <model-id> [契约允许的参数] -o ./focalapi-out --json
32
+ focalapi gen video "<prompt>" -m <model-id> [契约允许的参数] --no-wait -o ./focalapi-out --json
33
+ ```
34
+
35
+ - 图片编辑/参考图使用 `--image <url...>`;mask 仅在契约列出时传 `--mask`。
36
+ - 视频参考图使用 `--image <url...>`;时长、清晰度、画面比例和音频开关只按
37
+ `supported_params` 传递。
38
+ - 不把一个模型的 `ratio`、`aspect_ratio`、`size` 或 `resolution` 复制给另一模型。
39
+ - Gemini 原生图片仅在用户明确选中对应模型时使用 `gen gemini-image`;普通任务
40
+ 继续使用自动入口 `gen image`。
41
+
42
+ ## 结果闭环
43
+
44
+ 图片同步结果的 `files` 是本地绝对路径,直接交付用户。异步结果按返回的
45
+ `next_command` 执行:
46
+
47
+ ```bash
48
+ focalapi task status <task-id> --json
49
+ focalapi task download <task-id> -o ./focalapi-out --json
50
+ ```
51
+
52
+ `pending` / `running` 不是失败;继续查询同一个 `task_id`,不得重新提交生成。
53
+ 失败时读取结构化 `error.code` `hint`,只修复明确问题,不盲目换模型。
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: focalapi-models
3
+ version: 2.0.0
4
+ description: "focalapi 创作模型选择与实时参数契约。当用户未指定模型、点名厂商/模型、比较模型,或生成参数报错时使用;默认用 resolve 直接得到可调用模型,禁止靠模型名猜能力或逐个试。"
5
+ metadata:
6
+ requires:
7
+ bins: ["focalapi"]
8
+ cliHelp: "focalapi models --help"
9
+ ---
10
+
11
+ # focalapi 模型选择
12
+
13
+ ## 最短路径
14
+
15
+ 用户未指定模型时,不需要先列全量模型,也不需要 Agent 自己排序:
16
+
17
+ ```bash
18
+ focalapi models resolve image --json
19
+ focalapi models resolve video --json
20
+ ```
21
+
22
+ `resolve` 会读取当前 Key 的实时列表,再读取候选模型的详情契约,返回:
23
+
24
+ - `model.id`:可直接传给生成命令的精确 ID;
25
+ - `endpoint_type`:已由详情确认的生成端点;
26
+ - `model.supported_params`:本次可用参数、默认值、枚举和范围;
27
+ - `next_command`:无需猜测的下一条命令。
28
+
29
+ 如果调用 `focalapi gen image/video` 时省略 `--model`,CLI 内部执行同一选择逻辑。
30
+
31
+ ## 用户指定模型
32
+
33
+ ```bash
34
+ focalapi models get <完整模型-id> --json
35
+ ```
36
+
37
+ 只有用户给的是不完整厂商/系列名时,才先做一次搜索:
38
+
39
+ ```bash
40
+ focalapi models search <keyword> --json
41
+ focalapi models get <选中的完整-id> --json
42
+ ```
43
+
44
+ 规则:
45
+
46
+ 1. `models get` 是端点和参数的最终权威;列表摘要可能只展示协议族,不能据此猜模态。
47
+ 2. 不逐个模型发生成请求做可用性测试;模型发现与详情查询是只读预检。
48
+ 3. 指定模型不可用时,把可用候选交给用户或回到 `models resolve`,不要偷偷换模型。
49
+ 4. 查询完成后回到用户原始生成任务,不要停在模型清单。
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: focalapi-task
3
+ version: 2.0.0
4
+ description: "续取 focalapi 图片/视频异步任务并下载产物。当生成结果包含 task_id/next_command,或用户问进度、失败原因、结果文件时使用;必须复用原 task_id,不重复生成。"
5
+ metadata:
6
+ requires:
7
+ bins: ["focalapi"]
8
+ cliHelp: "focalapi task --help"
9
+ ---
10
+
11
+ # focalapi 异步任务闭环
12
+
13
+ 生成命令返回 `task_id` 后,以响应里的 `next_command` 为第一选择:
14
+
15
+ ```bash
16
+ focalapi task status <task-id> --json
17
+ focalapi task download <task-id> -o ./focalapi-out --json
18
+ ```
19
+
20
+ - `pending` / `running`:仍是同一个有效任务,稍后查询;不要重提生成请求。
21
+ - `success`:执行 download,检查文件存在,并把绝对路径交给用户。
22
+ - `failed`:展示上游错误摘要和 hint;只有参数/内容问题被明确指出时才重新生成。
23
+ - `unknown`:保留原始响应并运行 `focalapi doctor --json`,不要伪造成功状态。
24
+
25
+ 轮询要有边界;用户没有要求阻塞等待时,汇报当前状态和 `task_id` 即可。