focalapi-cli 0.2.0 → 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/CHANGELOG.md +13 -6
- package/README.md +60 -76
- package/dist/cli.js +7 -7
- package/package.json +6 -2
- package/scripts/postinstall.cjs +4 -4
- package/skills/focalapi/SKILL.md +26 -33
- package/skills/focalapi-auth/SKILL.md +8 -10
- package/skills/focalapi-chat/SKILL.md +7 -10
- package/skills/focalapi-gen/SKILL.md +18 -23
- package/skills/focalapi-models/SKILL.md +19 -19
- package/skills/focalapi-task/SKILL.md +8 -8
- package/skills/focalapi-usage/SKILL.md +9 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.1 - 2026-08-11
|
|
4
|
+
|
|
5
|
+
- Prepared the public GitHub repository metadata and refreshed the project documentation for external contributors.
|
|
6
|
+
- Rewrote bundled Agent Skills and source comments in English while preserving the existing CLI commands and runtime behavior.
|
|
7
|
+
- Clarified that audio transcription and speech synthesis require an explicit model selected from the current key's live model list.
|
|
8
|
+
- Added the CLI verification report and kept local benchmark artifacts out of the published repository.
|
|
9
|
+
|
|
3
10
|
## 0.2.0 - 2026-08-11
|
|
4
11
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
12
|
+
- Added `models resolve image|video`, backed by the live model list and detailed contracts, so image and video generation can omit `--model` and automatically select a currently available default.
|
|
13
|
+
- Reworked Agent integration across 44 Agent targets with shared Skills-directory deduplication, custom `--path` support, transactional installation, digest verification, safe uninstall, and `connect verify`.
|
|
14
|
+
- Added best-effort synchronization for detected Agents after npm installation while keeping `focalapi connect` as the stable entry point that does not depend on lifecycle scripts.
|
|
15
|
+
- Rewrote all seven bundled Skills so creative requests route automatically even when the user does not name FocalAPI, without probing generation models or changing the Agent's primary model/provider.
|
|
16
|
+
- Added model information and `next_command` to asynchronous image and video results so Agents can continue the original task without resubmitting it.
|
|
17
|
+
- Fixed CLI process exit codes so Agents and scripts can reliably detect failures from `doctor` and `connect verify`.
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# focalapi-cli
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Give any AI Agent direct access to FocalAPI creative models**
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/focalapi-cli)
|
|
8
8
|
[](./LICENSE)
|
|
@@ -14,127 +14,111 @@ npm i -g focalapi-cli
|
|
|
14
14
|
|
|
15
15
|
</div>
|
|
16
16
|
|
|
17
|
-
focalapi-cli
|
|
18
|
-
Skills。用户只需描述目标;Agent 不需要先试模型、猜参数、手写请求或切换平台。
|
|
17
|
+
focalapi-cli turns FocalAPI's creative-model gateway into commands and Skills that an Agent can run directly. Users describe the outcome they want; the Agent does not need to probe models, guess parameters, handcraft requests, or switch platforms first.
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
Cursor 等 Agent 保持原来的推理模型,只在图片、视频等创作任务中调用 focalapi。
|
|
19
|
+
It does not configure FocalAPI as the Agent's primary model or provider. Agents such as Codex, Claude Code, and Cursor keep their existing reasoning models and call FocalAPI only for creative tasks such as image and video generation.
|
|
22
20
|
|
|
23
|
-
##
|
|
21
|
+
## Connect in three steps
|
|
24
22
|
|
|
25
23
|
```shell
|
|
26
|
-
# 1.
|
|
24
|
+
# 1. Install. Skills are synchronized automatically when lifecycle scripts are allowed.
|
|
27
25
|
npm i -g focalapi-cli
|
|
28
26
|
|
|
29
|
-
# 2.
|
|
27
|
+
# 2. Configure a FocalAPI key.
|
|
30
28
|
focalapi auth login --key sk-xxxx
|
|
31
29
|
|
|
32
|
-
# 3.
|
|
30
|
+
# 3. Connect every detected Agent, then verify the installation. The operation is idempotent.
|
|
33
31
|
focalapi connect
|
|
34
32
|
focalapi connect verify --json
|
|
35
33
|
```
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
`FOCALAPI_API_KEY`,私有化部署可设置 `FOCALAPI_BASE_URL`。
|
|
35
|
+
Create a key at <https://focalapi.com/console/token>. CI and sandbox environments can use `FOCALAPI_API_KEY`; self-hosted deployments can set `FOCALAPI_BASE_URL`.
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
这也是稳定的接入入口。如需主动跳过安装后的自动接入,设置
|
|
42
|
-
`FOCALAPI_SKIP_POSTINSTALL=1`。
|
|
37
|
+
If an npm security policy blocks lifecycle scripts, run `focalapi connect` explicitly. This is also the stable manual integration entry point. Set `FOCALAPI_SKIP_POSTINSTALL=1` to intentionally skip automatic post-install integration.
|
|
43
38
|
|
|
44
|
-
## Agent
|
|
39
|
+
## Zero-guesswork Agent workflows
|
|
45
40
|
|
|
46
|
-
|
|
47
|
-
focalapi 维护的默认模型;只产生一次真实生成请求。
|
|
41
|
+
When no model is specified, the CLI reads the live model pool and detailed model contract available to the current key, selects the maintained FocalAPI default, and sends only one real generation request.
|
|
48
42
|
|
|
49
43
|
```shell
|
|
50
|
-
#
|
|
51
|
-
focalapi gen image "
|
|
44
|
+
# Automatically select the current default image model.
|
|
45
|
+
focalapi gen image "Product hero image, soft studio lighting" -o ./out --json
|
|
52
46
|
|
|
53
|
-
#
|
|
54
|
-
focalapi gen video "
|
|
47
|
+
# Automatically select the current default video model and return a task ID immediately.
|
|
48
|
+
focalapi gen video "Ocean waves hitting rocks, cinematic" --no-wait -o ./out --json
|
|
55
49
|
|
|
56
|
-
#
|
|
50
|
+
# Continue from next_command in the generation response without resubmitting the task.
|
|
57
51
|
focalapi task status <task-id> --json
|
|
58
52
|
focalapi task download <task-id> -o ./out --json
|
|
59
53
|
```
|
|
60
54
|
|
|
61
|
-
|
|
55
|
+
When the user specifies a model, read its authoritative contract first:
|
|
62
56
|
|
|
63
57
|
```shell
|
|
64
58
|
focalapi models get <model-id> --json
|
|
65
|
-
focalapi gen image "<prompt>" -m <model-id> [
|
|
59
|
+
focalapi gen image "<prompt>" -m <model-id> [contract-supported options] -o ./out --json
|
|
66
60
|
```
|
|
67
61
|
|
|
68
|
-
|
|
62
|
+
The CLI can also resolve a model without generating anything:
|
|
69
63
|
|
|
70
64
|
```shell
|
|
71
65
|
focalapi models resolve image --json
|
|
72
66
|
focalapi models resolve video --json
|
|
73
67
|
```
|
|
74
68
|
|
|
75
|
-
`resolve`
|
|
76
|
-
`supported_params`、候选模型与 `next_command`。模型列表摘要和详情不一致时,
|
|
77
|
-
详情契约始终是权威。
|
|
69
|
+
`resolve` returns the exact `model.id`, verified `endpoint_type`, complete `supported_params`, candidate models, and a `next_command`. When a list summary and detailed contract disagree, the detailed contract is authoritative.
|
|
78
70
|
|
|
79
|
-
## Agent
|
|
71
|
+
## Agent integration
|
|
80
72
|
|
|
81
73
|
```shell
|
|
82
|
-
focalapi connect #
|
|
83
|
-
focalapi connect list #
|
|
84
|
-
focalapi connect install codex cursor #
|
|
85
|
-
focalapi connect install --path <dir> #
|
|
86
|
-
focalapi connect verify --json #
|
|
87
|
-
focalapi connect uninstall #
|
|
74
|
+
focalapi connect # Install or repair every detected Agent.
|
|
75
|
+
focalapi connect list # Inspect supported, detected, and installed targets.
|
|
76
|
+
focalapi connect install codex cursor # Install for selected Agents.
|
|
77
|
+
focalapi connect install --path <dir> # Install to an unlisted or project-level Skills directory.
|
|
78
|
+
focalapi connect verify --json # Verify Skill integrity and authentication readiness.
|
|
79
|
+
focalapi connect uninstall # Remove only managed Skills that the user has not modified.
|
|
88
80
|
```
|
|
89
81
|
|
|
90
|
-
|
|
91
|
-
GitHub Copilot、OpenCode、OpenClaw、Cline、Windsurf、Warp、Trae、Qwen Code、
|
|
92
|
-
Kimi CLI、Hermes 等。Codex、Cline、Pi、Warp 等共享 `~/.agents/skills` 的目标
|
|
93
|
-
会按路径自动去重,只安装一份。
|
|
82
|
+
The built-in catalog currently covers 44 Agent targets, including Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode, OpenClaw, Cline, Windsurf, Warp, Trae, Qwen Code, Kimi CLI, and Hermes. Targets such as Codex, Cline, Pi, and Warp that share `~/.agents/skills` are deduplicated by path, so the Skills are installed only once.
|
|
94
83
|
|
|
95
|
-
|
|
96
|
-
manifest 记录每个 Skill 的 SHA-256 目录摘要。默认卸载仅删除摘要未变化的托管
|
|
97
|
-
Skills,用户修改过的内容保留。
|
|
84
|
+
Installation is transactional: the current `focalapi-*` catalog is written as one unit, and any failed step rolls back the operation. The manifest records a SHA-256 directory digest for each Skill. By default, uninstall removes only managed Skills whose digest has not changed and preserves user-modified content.
|
|
98
85
|
|
|
99
|
-
|
|
86
|
+
The Skill routing contract requires Agents to:
|
|
100
87
|
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
88
|
+
- trigger FocalAPI for creative tasks even when the user does not name it;
|
|
89
|
+
- omit `--model` when no model is specified, letting the CLI select one without generating test samples;
|
|
90
|
+
- use only the live parameter contract returned by `models get` for an explicitly selected model;
|
|
91
|
+
- reuse the original `task_id` for asynchronous work instead of charging for duplicate submissions while a task is `pending`;
|
|
92
|
+
- return to the original task after resolving an authentication error rather than stopping at diagnostics.
|
|
106
93
|
|
|
107
|
-
##
|
|
94
|
+
## Current capability boundary
|
|
108
95
|
|
|
109
|
-
|
|
110
|
-
视频和图生视频。CLI 仍保留文本、音频等命令,但只有实时模型详情与 CLI 帮助
|
|
111
|
-
共同给出可执行契约时 Agent 才会调用;不会根据模型名字猜测未来的音频、3D 或
|
|
112
|
-
其他模态能力。
|
|
96
|
+
The fully validated automatic generation paths currently cover images and video, including image editing, reference-image creation, text-to-video, and image-to-video. The CLI retains text and audio commands, but an Agent may use them only when both the live model details and CLI help expose an executable contract. It never infers future audio, 3D, or other modality support from model names alone.
|
|
113
97
|
|
|
114
|
-
##
|
|
98
|
+
## Stable output for Agents
|
|
115
99
|
|
|
116
|
-
-
|
|
117
|
-
-
|
|
118
|
-
- API
|
|
119
|
-
-
|
|
120
|
-
-
|
|
100
|
+
- All automation commands support `--json`; stdout contains JSON only, while progress and diagnostics go to stderr.
|
|
101
|
+
- Errors use `{ error: { code, message, hint, request_id? } }`.
|
|
102
|
+
- API keys are always redacted.
|
|
103
|
+
- Image results return local `files`; asynchronous video results return `task_id` and `next_command`.
|
|
104
|
+
- Local validation rejects known invalid billing multipliers and model parameters before sending a request.
|
|
121
105
|
|
|
122
|
-
##
|
|
106
|
+
## Command map
|
|
123
107
|
|
|
124
|
-
|
|
|
108
|
+
| Task | Command |
|
|
125
109
|
| --- | --- |
|
|
126
|
-
|
|
|
127
|
-
|
|
|
128
|
-
|
|
|
129
|
-
|
|
|
130
|
-
|
|
|
131
|
-
|
|
|
132
|
-
| Agent Skills
|
|
133
|
-
|
|
|
110
|
+
| Generate images with automatic or explicit model selection | `focalapi gen image` |
|
|
111
|
+
| Generate video with automatic or explicit model selection | `focalapi gen video` |
|
|
112
|
+
| Resolve models and inspect live contracts | `focalapi models resolve/get/search/list` |
|
|
113
|
+
| Check and download asynchronous tasks | `focalapi task status/download` |
|
|
114
|
+
| Sign in and inspect key status | `focalapi auth login/status/logout` |
|
|
115
|
+
| Inspect quota, usage, and diagnostics | `focalapi usage`, `focalapi doctor` |
|
|
116
|
+
| Connect Agent Skills | `focalapi connect` |
|
|
117
|
+
| Make read-only raw API requests | `focalapi request get/head` |
|
|
134
118
|
|
|
135
|
-
|
|
119
|
+
Every command includes built-in help: `focalapi <command> --help`.
|
|
136
120
|
|
|
137
|
-
##
|
|
121
|
+
## Development validation
|
|
138
122
|
|
|
139
123
|
```shell
|
|
140
124
|
npm install
|
|
@@ -143,12 +127,12 @@ npm run build
|
|
|
143
127
|
npm test
|
|
144
128
|
```
|
|
145
129
|
|
|
146
|
-
##
|
|
130
|
+
## Links
|
|
147
131
|
|
|
148
|
-
-
|
|
149
|
-
-
|
|
150
|
-
- npm
|
|
151
|
-
-
|
|
132
|
+
- FocalAPI: <https://focalapi.com>
|
|
133
|
+
- GitHub: <https://github.com/focalapi/focalapi-cli>
|
|
134
|
+
- npm: <https://www.npmjs.com/package/focalapi-cli>
|
|
135
|
+
- Bundled Skills: [`./skills`](./skills)
|
|
152
136
|
|
|
153
137
|
## License
|
|
154
138
|
|
package/dist/cli.js
CHANGED
|
@@ -8,11 +8,11 @@ var ApiError = class extends Error {
|
|
|
8
8
|
code;
|
|
9
9
|
status;
|
|
10
10
|
hint;
|
|
11
|
-
/**
|
|
11
|
+
/** Stable upstream error code or type, without sensitive request data such as keys. */
|
|
12
12
|
upstreamCode;
|
|
13
|
-
/**
|
|
13
|
+
/** Request ID that the service operator can use to correlate logs. */
|
|
14
14
|
requestId;
|
|
15
|
-
/**
|
|
15
|
+
/** Truncated raw upstream response for debugging only; redact it before printing. */
|
|
16
16
|
body;
|
|
17
17
|
constructor(code, message, opts) {
|
|
18
18
|
super(message);
|
|
@@ -155,7 +155,7 @@ function displayWidth(s) {
|
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
// src/lib/version.ts
|
|
158
|
-
var VERSION = true ? "0.2.
|
|
158
|
+
var VERSION = true ? "0.2.1" : "0.0.0-dev";
|
|
159
159
|
|
|
160
160
|
// src/commands/auth.ts
|
|
161
161
|
import { createInterface } from "readline/promises";
|
|
@@ -1762,8 +1762,8 @@ function registerTask(program) {
|
|
|
1762
1762
|
import { writeFile as writeFile2 } from "fs/promises";
|
|
1763
1763
|
import { resolve as resolve3 } from "path";
|
|
1764
1764
|
function registerAudio(program) {
|
|
1765
|
-
const audio = program.command("audio").description("\u97F3\u9891\uFF1A\u8F6C\u5199\u4E0E\u5408\u6210");
|
|
1766
|
-
audio.command("transcribe").description("\u8BED\u97F3\u8F6C\u6587\u5B57").argument("<file>", "\u97F3\u9891\u6587\u4EF6\u8DEF\u5F84").requiredOption("-m, --model <model>", "\u8F6C\u5199\u6A21\u578B ID").option("--language <lang>", "\u8BED\u8A00\u4EE3\u7801\uFF08\u5982 zh\u3001en\uFF09").action(async (file, opts, cmd) => {
|
|
1765
|
+
const audio = program.command("audio").description("\u97F3\u9891\uFF1A\u8F6C\u5199\u4E0E\u5408\u6210\uFF08\u6CA1\u6709\u9ED8\u8BA4\u6A21\u578B\uFF1B\u5148\u8FD0\u884C focalapi models list \u67E5\u770B\u5F53\u524D Key \u53EF\u7528\u7684\u97F3\u9891\u6A21\u578B\uFF09");
|
|
1766
|
+
audio.command("transcribe").description("\u8BED\u97F3\u8F6C\u6587\u5B57").argument("<file>", "\u97F3\u9891\u6587\u4EF6\u8DEF\u5F84").requiredOption("-m, --model <model>", "\u8F6C\u5199\u6A21\u578B ID\uFF08\u5FC5\u586B\u3001\u65E0\u9ED8\u8BA4\u503C\uFF1B\u8FD0\u884C focalapi models list \u67E5\u770B\uFF09").option("--language <lang>", "\u8BED\u8A00\u4EE3\u7801\uFF08\u5982 zh\u3001en\uFF09").action(async (file, opts, cmd) => {
|
|
1767
1767
|
const g = cmd.optsWithGlobals();
|
|
1768
1768
|
const auth = resolveAuth(g);
|
|
1769
1769
|
const input = readInputFile(file);
|
|
@@ -1784,7 +1784,7 @@ function registerAudio(program) {
|
|
|
1784
1784
|
process.stdout.write((res.text ?? JSON.stringify(res)) + "\n");
|
|
1785
1785
|
}
|
|
1786
1786
|
});
|
|
1787
|
-
audio.command("speech").description("\u6587\u5B57\u8F6C\u8BED\u97F3\uFF0C\u4EA7\u7269\u4FDD\u5B58\u4E3A\u97F3\u9891\u6587\u4EF6").argument("<text...>", "\u8981\u5408\u6210\u7684\u6587\u672C").requiredOption("-m, --model <model>", "TTS \u6A21\u578B ID").option("--voice <voice>", "\u97F3\u8272", "alloy").option("--format <fmt>", "\u97F3\u9891\u683C\u5F0F\uFF08mp3/wav/...\uFF09", "mp3").option("-o, --out <file>", "\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84").action(async (textParts, opts, cmd) => {
|
|
1787
|
+
audio.command("speech").description("\u6587\u5B57\u8F6C\u8BED\u97F3\uFF0C\u4EA7\u7269\u4FDD\u5B58\u4E3A\u97F3\u9891\u6587\u4EF6").argument("<text...>", "\u8981\u5408\u6210\u7684\u6587\u672C").requiredOption("-m, --model <model>", "TTS \u6A21\u578B ID\uFF08\u5FC5\u586B\u3001\u65E0\u9ED8\u8BA4\u503C\uFF1B\u8FD0\u884C focalapi models list \u67E5\u770B\uFF09").option("--voice <voice>", "\u97F3\u8272", "alloy").option("--format <fmt>", "\u97F3\u9891\u683C\u5F0F\uFF08mp3/wav/...\uFF09", "mp3").option("-o, --out <file>", "\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84").action(async (textParts, opts, cmd) => {
|
|
1788
1788
|
const g = cmd.optsWithGlobals();
|
|
1789
1789
|
const auth = resolveAuth(g);
|
|
1790
1790
|
const res = await rawRequest({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "focalapi-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "让任意 AI Agent 直接调用 focalapi 创作模型的命令行工具",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -38,7 +38,11 @@
|
|
|
38
38
|
"license": "Apache-2.0",
|
|
39
39
|
"repository": {
|
|
40
40
|
"type": "git",
|
|
41
|
-
"url": "https://
|
|
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"
|
|
42
46
|
},
|
|
43
47
|
"dependencies": {
|
|
44
48
|
"commander": "^12.1.0"
|
package/scripts/postinstall.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Best-effort Agent integration after global npm installation.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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
8
|
*/
|
|
9
9
|
|
|
10
10
|
const { existsSync } = require('node:fs');
|
|
@@ -30,7 +30,7 @@ if (result.status === 0) {
|
|
|
30
30
|
const count = Array.isArray(output.installed) ? output.installed.length : 0;
|
|
31
31
|
if (count > 0) console.log(`focalapi-cli: 已自动接入 ${count} 个 Agent Skills 目录;重启 Agent 后生效。`);
|
|
32
32
|
} catch {
|
|
33
|
-
// connect
|
|
33
|
+
// Unparseable output after a successful connect must not fail installation.
|
|
34
34
|
}
|
|
35
35
|
process.exit(0);
|
|
36
36
|
}
|
package/skills/focalapi/SKILL.md
CHANGED
|
@@ -1,54 +1,47 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: focalapi
|
|
3
3
|
version: 2.0.0
|
|
4
|
-
description: "
|
|
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
5
|
metadata:
|
|
6
6
|
requires:
|
|
7
7
|
bins: ["focalapi"]
|
|
8
8
|
cliHelp: "focalapi --help"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
#
|
|
11
|
+
# FocalAPI creative-model routing
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
model/provider。不要修改 Agent 的主模型配置,也不要要求用户先说“用 focalapi”。
|
|
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.
|
|
15
14
|
|
|
16
|
-
##
|
|
15
|
+
## Zero-guesswork execution contract
|
|
17
16
|
|
|
18
|
-
1.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
4. Agent/脚本调用统一加 `--json`。stdout 是唯一机读结果,诊断在 stderr。
|
|
24
|
-
5. 生成成功后必须把本地绝对文件路径交给用户;视频任务返回 `task_id` 时沿
|
|
25
|
-
`next_command` 续取,不要重复提交一个新任务。
|
|
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.
|
|
26
22
|
|
|
27
23
|
```bash
|
|
28
|
-
#
|
|
29
|
-
focalapi gen image "
|
|
30
|
-
focalapi gen video "
|
|
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
|
|
31
27
|
|
|
32
|
-
#
|
|
28
|
+
# Continue an asynchronous video task.
|
|
33
29
|
focalapi task status <task-id> --json
|
|
34
30
|
focalapi task download <task-id> -o ./focalapi-out --json
|
|
35
31
|
```
|
|
36
32
|
|
|
37
|
-
##
|
|
33
|
+
## Routing table
|
|
38
34
|
|
|
39
|
-
|
|
|
35
|
+
| User goal | Entry point | Skill |
|
|
40
36
|
| --- | --- | --- |
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
若业务命令返回 `missing_api_key`,转 focalapi-auth 完成登录后立即回到原任务;
|
|
54
|
-
其他错误只按 `{error.code, error.hint}` 修复一次,不要盲目轮换模型。
|
|
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,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: focalapi-auth
|
|
3
3
|
version: 2.0.0
|
|
4
|
-
description: "
|
|
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
5
|
metadata:
|
|
6
6
|
requires:
|
|
7
7
|
bins: ["focalapi"]
|
|
8
8
|
cliHelp: "focalapi auth --help"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
#
|
|
11
|
+
# FocalAPI authentication
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
npm i -g focalapi-cli
|
|
@@ -17,14 +17,12 @@ focalapi auth status --json
|
|
|
17
17
|
focalapi connect
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
完整 Key;CI/沙箱优先通过 `FOCALAPI_API_KEY` 注入。
|
|
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.
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
Do not run `auth status` before every business command. After an authentication error, follow this fixed path:
|
|
24
23
|
|
|
25
|
-
- `missing_api_key
|
|
26
|
-
- `invalid_api_key
|
|
27
|
-
- `upstream_auth_failed
|
|
28
|
-
用户反复更换自己的 Key。
|
|
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.
|
|
29
27
|
|
|
30
|
-
|
|
28
|
+
Retry the original business command immediately after authentication succeeds. Signing in is not the end of the task.
|
|
@@ -1,32 +1,29 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: focalapi-chat
|
|
3
3
|
version: 2.0.0
|
|
4
|
-
description: "
|
|
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
5
|
metadata:
|
|
6
6
|
requires:
|
|
7
7
|
bins: ["focalapi"]
|
|
8
8
|
cliHelp: "focalapi chat --help"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
#
|
|
11
|
+
# Supplementary FocalAPI capabilities
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
`focalapi-gen`。
|
|
13
|
+
This Skill is not the default route for creative requests. Route images, video, image editing, and image-to-video work to `focalapi-gen`.
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
When the user explicitly requests text assistance, get an available text model from the live list before calling it:
|
|
17
16
|
|
|
18
17
|
```bash
|
|
19
18
|
focalapi models list --json
|
|
20
|
-
focalapi chat "
|
|
19
|
+
focalapi chat "<user text task>" -m <text-model-from-list> --json
|
|
21
20
|
```
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
共同确认可执行时才能使用:
|
|
22
|
+
Use audio commands only when both `focalapi models get <model-id> --json` and `focalapi audio --help` confirm an executable contract:
|
|
25
23
|
|
|
26
24
|
```bash
|
|
27
25
|
focalapi audio transcribe <file> -m <model-id> --json
|
|
28
26
|
focalapi audio speech "<text>" -m <model-id> -o <file> --json
|
|
29
27
|
```
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
暂不可用,不要尝试相似模型或外部接口。
|
|
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,53 +1,48 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: focalapi-gen
|
|
3
3
|
version: 2.0.0
|
|
4
|
-
description: "
|
|
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
5
|
metadata:
|
|
6
6
|
requires:
|
|
7
7
|
bins: ["focalapi"]
|
|
8
8
|
cliHelp: "focalapi gen --help"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
#
|
|
11
|
+
# FocalAPI image and video generation
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Default: select automatically and run once
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
When the user does not specify a model, run:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
focalapi gen image "
|
|
19
|
-
focalapi gen video "
|
|
18
|
+
focalapi gen image "<complete prompt>" -o ./focalapi-out --json
|
|
19
|
+
focalapi gen video "<complete prompt>" --no-wait -o ./focalapi-out --json
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
CLI
|
|
23
|
-
测试提示词或多个模型各生成一次;这会产生不必要的费用和歧义。
|
|
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.
|
|
24
23
|
|
|
25
|
-
##
|
|
24
|
+
## Explicit models and advanced parameters
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
When the user names a model, read its live contract once:
|
|
28
27
|
|
|
29
28
|
```bash
|
|
30
29
|
focalapi models get <model-id> --json
|
|
31
|
-
focalapi gen image "<prompt>" -m <model-id> [
|
|
32
|
-
focalapi gen video "<prompt>" -m <model-id> [
|
|
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
|
|
33
32
|
```
|
|
34
33
|
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
- Gemini 原生图片仅在用户明确选中对应模型时使用 `gen gemini-image`;普通任务
|
|
40
|
-
继续使用自动入口 `gen image`。
|
|
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.
|
|
41
38
|
|
|
42
|
-
##
|
|
39
|
+
## Complete the result workflow
|
|
43
40
|
|
|
44
|
-
|
|
45
|
-
`next_command` 执行:
|
|
41
|
+
Synchronous image results contain local absolute paths in `files`; return them directly to the user. For asynchronous results, run the returned `next_command`:
|
|
46
42
|
|
|
47
43
|
```bash
|
|
48
44
|
focalapi task status <task-id> --json
|
|
49
45
|
focalapi task download <task-id> -o ./focalapi-out --json
|
|
50
46
|
```
|
|
51
47
|
|
|
52
|
-
`pending`
|
|
53
|
-
失败时读取结构化 `error.code` 和 `hint`,只修复明确问题,不盲目换模型。
|
|
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.
|
|
@@ -1,49 +1,49 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: focalapi-models
|
|
3
3
|
version: 2.0.0
|
|
4
|
-
description: "
|
|
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
5
|
metadata:
|
|
6
6
|
requires:
|
|
7
7
|
bins: ["focalapi"]
|
|
8
8
|
cliHelp: "focalapi models --help"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
#
|
|
11
|
+
# FocalAPI model selection
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Shortest path
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
When the user does not specify a model, do not list every model or rank them yourself:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
focalapi models resolve image --json
|
|
19
19
|
focalapi models resolve video --json
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
`resolve`
|
|
22
|
+
`resolve` reads the live list available to the current key, then reads detailed contracts for candidate models and returns:
|
|
23
23
|
|
|
24
|
-
- `model.id
|
|
25
|
-
- `endpoint_type
|
|
26
|
-
- `model.supported_params
|
|
27
|
-
- `next_command
|
|
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
28
|
|
|
29
|
-
|
|
29
|
+
Omitting `--model` from `focalapi gen image/video` uses the same selection logic internally.
|
|
30
30
|
|
|
31
|
-
##
|
|
31
|
+
## User-selected models
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
|
-
focalapi models get
|
|
34
|
+
focalapi models get <complete-model-id> --json
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Search once only when the user provides an incomplete provider or family name:
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
40
|
focalapi models search <keyword> --json
|
|
41
|
-
focalapi models get
|
|
41
|
+
focalapi models get <selected-complete-id> --json
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
Rules:
|
|
45
45
|
|
|
46
|
-
1. `models get`
|
|
47
|
-
2.
|
|
48
|
-
3.
|
|
49
|
-
4.
|
|
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.
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: focalapi-task
|
|
3
3
|
version: 2.0.0
|
|
4
|
-
description: "
|
|
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
5
|
metadata:
|
|
6
6
|
requires:
|
|
7
7
|
bins: ["focalapi"]
|
|
8
8
|
cliHelp: "focalapi task --help"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
#
|
|
11
|
+
# Complete asynchronous FocalAPI tasks
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
After a generation command returns `task_id`, prefer the response's `next_command`:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
focalapi task status <task-id> --json
|
|
17
17
|
focalapi task download <task-id> -o ./focalapi-out --json
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
- `pending`
|
|
21
|
-
- `success
|
|
22
|
-
- `failed
|
|
23
|
-
- `unknown
|
|
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
24
|
|
|
25
|
-
|
|
25
|
+
Polling must be bounded. When the user does not ask for blocking wait behavior, report the current status and `task_id`.
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: focalapi-usage
|
|
3
3
|
version: 2.0.0
|
|
4
|
-
description: "
|
|
4
|
+
description: "Inspect FocalAPI quota, usage, and billing, or diagnose network, authentication, and service errors. Use when the user asks about spend or balance, or when a failed business command needs an error-code-driven resolution. Do not add mandatory diagnostics before normal generation."
|
|
5
5
|
metadata:
|
|
6
6
|
requires:
|
|
7
7
|
bins: ["focalapi"]
|
|
8
8
|
cliHelp: "focalapi usage --help"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
#
|
|
11
|
+
# FocalAPI usage and diagnostics
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
focalapi usage --json
|
|
@@ -16,12 +16,11 @@ focalapi auth status --json
|
|
|
16
16
|
focalapi doctor --json
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
-
|
|
20
|
-
- `missing_api_key`
|
|
21
|
-
- `insufficient_quota
|
|
22
|
-
- `network_error
|
|
23
|
-
- `invalid_request
|
|
24
|
-
- `upstream_auth_failed
|
|
19
|
+
- For quota, balance, usage, or billing questions, run `usage`.
|
|
20
|
+
- For `missing_api_key` or `invalid_api_key`, route to focalapi-auth.
|
|
21
|
+
- For `insufficient_quota`, run `usage`, explain the shortfall, and do not add funds automatically.
|
|
22
|
+
- For `network_error`, `timeout`, or 5xx errors, run `doctor` once and follow `checks[].hint`.
|
|
23
|
+
- For `invalid_request`, return to the live `models get` parameter contract and do not resend the same request.
|
|
24
|
+
- For `upstream_auth_failed`, preserve the request ID and escalate to the service operator; do not ask the user to replace the FocalAPI key.
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
目标,减少无关调用。
|
|
26
|
+
Do not run `doctor` or a free rehearsal before a normal business command that has not failed. The Agent should complete the user's creative goal directly and avoid unrelated calls.
|