focalapi-cli 0.1.1 → 0.2.1

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,57 @@
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.1",
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": "git+https://github.com/focalapi/focalapi-cli.git"
42
+ },
43
+ "homepage": "https://github.com/focalapi/focalapi-cli#readme",
44
+ "bugs": {
45
+ "url": "https://github.com/focalapi/focalapi-cli/issues"
46
+ },
47
+ "dependencies": {
48
+ "commander": "^12.1.0"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^20.11.0",
52
+ "tsup": "^8.2.4",
53
+ "tsx": "^4.19.0",
54
+ "typescript": "^5.5.4",
55
+ "vitest": "^2.1.9"
56
+ }
57
+ }
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Best-effort Agent integration after global npm installation.
5
+ *
6
+ * Run local connect only: do not access the network, read an API key, or change an Agent provider.
7
+ * Missing Agents or integration failures never fail CLI installation; users can run focalapi connect later.
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
+ // Unparseable output after a successful connect must not fail installation.
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,47 @@
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: "Primary router for FocalAPI creative models. Use when the user wants to generate, edit, or process creative media, choose a creative model, or inspect a generation task, even when the user does not mention FocalAPI. Covers automatic image and video model selection, generation, asynchronous continuation, and error routing."
5
+ metadata:
6
+ requires:
7
+ bins: ["focalapi"]
8
+ cliHelp: "focalapi --help"
9
+ ---
10
+
11
+ # FocalAPI creative-model routing
12
+
13
+ FocalAPI is a creative-model gateway for the current Agent to call. It is not the Agent's own model or provider. Do not change the Agent's primary model configuration or require the user to say “use FocalAPI” first.
14
+
15
+ ## Zero-guesswork execution contract
16
+
17
+ 1. If the user does not specify a model, omit `--model`. The CLI selects a FocalAPI default from the live model pool and detailed contracts available to the current key. Do not generate a test sample first.
18
+ 2. If the user specifies a model or provider, run `focalapi models get <model-id> --json` first. If the model ID is incomplete, run `models search` once to find the exact ID, then read its details.
19
+ 3. Use only parameters and values listed in the detailed `supported_params`. Never infer support from a similar model.
20
+ 4. Add `--json` for Agent and script calls. stdout is the only machine-readable result; diagnostics go to stderr.
21
+ 5. After successful generation, return local absolute file paths to the user. If a video response contains `task_id`, follow `next_command`; never submit the same task again.
22
+
23
+ ```bash
24
+ # No model specified: run once without probing models first.
25
+ focalapi gen image "<user prompt>" -o ./focalapi-out --json
26
+ focalapi gen video "<user prompt>" --no-wait -o ./focalapi-out --json
27
+
28
+ # Continue an asynchronous video task.
29
+ focalapi task status <task-id> --json
30
+ focalapi task download <task-id> -o ./focalapi-out --json
31
+ ```
32
+
33
+ ## Routing table
34
+
35
+ | User goal | Entry point | Skill |
36
+ | --- | --- | --- |
37
+ | Generate or edit images; create from reference images | `focalapi gen image` | focalapi-gen |
38
+ | Generate video; animate images or reference media | `focalapi gen video` | focalapi-gen |
39
+ | Select, compare, or inspect model parameters | `focalapi models resolve/get/search` | focalapi-models |
40
+ | Inspect progress or failures; download results | `focalapi task status/download` | focalapi-task |
41
+ | Resolve key, sign-in, or 401 issues | `focalapi auth status/login` | focalapi-auth |
42
+ | Inspect quota, usage, or service failures | `focalapi usage/doctor` | focalapi-usage |
43
+ | Provide text assistance explicitly requested by the user | `focalapi chat` | focalapi-chat |
44
+
45
+ The fully validated automatic generation paths currently cover images and video. Audio, 3D, or another modality may be used only after both CLI help and `models get` expose an executable contract. Never infer a capability from a model list or name alone.
46
+
47
+ If a business command returns `missing_api_key`, route to focalapi-auth and return to the original task immediately after sign-in. For other errors, follow `{error.code, error.hint}` once; do not rotate models blindly.
@@ -1,50 +1,28 @@
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: "Handle focalapi-cli installation, first sign-in, key status, and 401/authentication errors. Trigger only during initial setup or when a business command explicitly returns missing_api_key or invalid_api_key. Return to the original creative task after authentication succeeds."
5
+ metadata:
6
+ requires:
7
+ bins: ["focalapi"]
8
+ cliHelp: "focalapi auth --help"
9
+ ---
10
+
11
+ # FocalAPI authentication
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
+ Create a key at `https://focalapi.com/console/token`. Never reveal the complete key in a response, log, or echoed command. Prefer `FOCALAPI_API_KEY` in CI and sandbox environments.
21
+
22
+ Do not run `auth status` before every business command. After an authentication error, follow this fixed path:
23
+
24
+ - `missing_api_key`: sign in or set `FOCALAPI_API_KEY`.
25
+ - `invalid_api_key`: ask the user to verify or create a key in the console, then sign in again.
26
+ - `upstream_auth_failed`: the FocalAPI key may be valid. Preserve the request ID and escalate to the service operator; do not repeatedly replace the user's key.
27
+
28
+ Retry the original business command immediately after authentication succeeds. Signing in is not the end of the task.
@@ -1,29 +1,29 @@
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: "Supplementary FocalAPI text and audio commands. Use only when the user explicitly requests text assistance through FocalAPI or when the live model contract confirms an available audio model. Route image and video creation to focalapi-gen."
5
+ metadata:
6
+ requires:
7
+ bins: ["focalapi"]
8
+ cliHelp: "focalapi chat --help"
9
+ ---
10
+
11
+ # Supplementary FocalAPI capabilities
12
+
13
+ This Skill is not the default route for creative requests. Route images, video, image editing, and image-to-video work to `focalapi-gen`.
14
+
15
+ When the user explicitly requests text assistance, get an available text model from the live list before calling it:
16
+
17
+ ```bash
18
+ focalapi models list --json
19
+ focalapi chat "<user text task>" -m <text-model-from-list> --json
20
+ ```
21
+
22
+ Use audio commands only when both `focalapi models get <model-id> --json` and `focalapi audio --help` confirm an executable contract:
23
+
24
+ ```bash
25
+ focalapi audio transcribe <file> -m <model-id> --json
26
+ focalapi audio speech "<text>" -m <model-id> -o <file> --json
27
+ ```
28
+
29
+ A name appearing in the model list does not prove that the CLI supports calling it. If the current key has no audio model contract, state that audio is unavailable; do not try a similar model or an external API.
@@ -1,79 +1,48 @@
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: "Use FocalAPI for image and video generation, image editing, image-to-video, and reference-media creation. Trigger directly when the user asks to draw, generate or edit an image, create video, or animate media, even without naming FocalAPI. Select a model automatically by default and do not probe models first."
5
+ metadata:
6
+ requires:
7
+ bins: ["focalapi"]
8
+ cliHelp: "focalapi gen --help"
9
+ ---
10
+
11
+ # FocalAPI image and video generation
12
+
13
+ ## Default: select automatically and run once
14
+
15
+ When the user does not specify a model, run:
16
+
17
+ ```bash
18
+ focalapi gen image "<complete prompt>" -o ./focalapi-out --json
19
+ focalapi gen video "<complete prompt>" --no-wait -o ./focalapi-out --json
20
+ ```
21
+
22
+ The CLI selects a default from the live model pool and detailed contracts available to the current key. Do not generate separate samples with a low-cost model, test prompt, or multiple models. Doing so creates unnecessary cost and ambiguity.
23
+
24
+ ## Explicit models and advanced parameters
25
+
26
+ When the user names a model, read its live contract once:
27
+
28
+ ```bash
29
+ focalapi models get <model-id> --json
30
+ focalapi gen image "<prompt>" -m <model-id> [contract-supported options] -o ./focalapi-out --json
31
+ focalapi gen video "<prompt>" -m <model-id> [contract-supported options] --no-wait -o ./focalapi-out --json
32
+ ```
33
+
34
+ - Use `--image <url...>` for image editing and reference images. Pass `--mask` only when the contract lists it.
35
+ - Use `--image <url...>` for video reference images. Pass duration, resolution, aspect ratio, and audio options only as allowed by `supported_params`.
36
+ - Never copy one model's `ratio`, `aspect_ratio`, `size`, or `resolution` to another model.
37
+ - Use `gen gemini-image` only when the user explicitly selects a native Gemini image model. Continue to use the automatic `gen image` entry point for ordinary requests.
38
+
39
+ ## Complete the result workflow
40
+
41
+ Synchronous image results contain local absolute paths in `files`; return them directly to the user. For asynchronous results, run the returned `next_command`:
42
+
43
+ ```bash
44
+ focalapi task status <task-id> --json
45
+ focalapi task download <task-id> -o ./focalapi-out --json
46
+ ```
47
+
48
+ `pending` and `running` are not failures. Keep checking the same `task_id` and never resubmit generation. On failure, read the structured `error.code` and `hint`, and fix only the explicit problem instead of rotating models blindly.
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: focalapi-models
3
+ version: 2.0.0
4
+ description: "Select FocalAPI creative models and inspect live parameter contracts. Use when the user does not specify a model, names a model or provider, compares models, or encounters a generation-parameter error. Use resolve to obtain a callable default and never infer capabilities from names or probe models one by one."
5
+ metadata:
6
+ requires:
7
+ bins: ["focalapi"]
8
+ cliHelp: "focalapi models --help"
9
+ ---
10
+
11
+ # FocalAPI model selection
12
+
13
+ ## Shortest path
14
+
15
+ When the user does not specify a model, do not list every model or rank them yourself:
16
+
17
+ ```bash
18
+ focalapi models resolve image --json
19
+ focalapi models resolve video --json
20
+ ```
21
+
22
+ `resolve` reads the live list available to the current key, then reads detailed contracts for candidate models and returns:
23
+
24
+ - `model.id`: the exact ID accepted by generation commands;
25
+ - `endpoint_type`: the generation endpoint verified by model details;
26
+ - `model.supported_params`: available parameters, defaults, enumerations, and ranges;
27
+ - `next_command`: the next command with no guessing required.
28
+
29
+ Omitting `--model` from `focalapi gen image/video` uses the same selection logic internally.
30
+
31
+ ## User-selected models
32
+
33
+ ```bash
34
+ focalapi models get <complete-model-id> --json
35
+ ```
36
+
37
+ Search once only when the user provides an incomplete provider or family name:
38
+
39
+ ```bash
40
+ focalapi models search <keyword> --json
41
+ focalapi models get <selected-complete-id> --json
42
+ ```
43
+
44
+ Rules:
45
+
46
+ 1. `models get` is authoritative for endpoints and parameters. A list summary may show only a protocol family and cannot be used to infer modality.
47
+ 2. Do not send generation requests to models one by one as an availability test. Discovery and detail queries are read-only preflight checks.
48
+ 3. If an explicitly selected model is unavailable, present available candidates or return to `models resolve`; never replace it silently.
49
+ 4. Return to the user's original generation task after the query instead of stopping at the model list.
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: focalapi-task
3
+ version: 2.0.0
4
+ description: "Continue asynchronous FocalAPI image or video tasks and download their outputs. Use when a generation response contains task_id or next_command, or when the user asks about progress, failure reasons, or result files. Reuse the original task_id and never generate again."
5
+ metadata:
6
+ requires:
7
+ bins: ["focalapi"]
8
+ cliHelp: "focalapi task --help"
9
+ ---
10
+
11
+ # Complete asynchronous FocalAPI tasks
12
+
13
+ After a generation command returns `task_id`, prefer the response's `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` or `running`: this is still the same valid task. Check it later and do not resubmit generation.
21
+ - `success`: run download, verify that the file exists, and return its absolute path to the user.
22
+ - `failed`: show the upstream error summary and hint. Generate again only when an explicit parameter or content issue requires it.
23
+ - `unknown`: preserve the raw response and run `focalapi doctor --json`; never fabricate a success state.
24
+
25
+ Polling must be bounded. When the user does not ask for blocking wait behavior, report the current status and `task_id`.