任务

任务

任务是 Favonis 里的一段工作对话:新建任务即在云端发起一段工作模式的对话,任务完成或取消后再发消息,会在同一个任务里开始新的一轮回复,任务的状态和结果都取自最新的一轮。任务出现在应用的侧边栏中,未指定项目的列在任务分区,指定了项目的列在对应的项目下,随时能打开接着对话;反过来,API 也能读到这个身份下你在应用中发起的云端工作对话。我的电脑中的本地对话不在 API 的范围内。

任务对象

新建、查看、发消息、取消都返回同一个任务对象:

字段 说明
id 任务 ID
url 在 Favonis 中打开这个任务的地址
title 任务标题,第一轮回复结束前可能为空
status 任务状态,见下一节
reason status 为 paused 时停下的原因
project_id 任务所在的项目,用来列出项目文件
created_at 创建时间
updated_at 最近更新时间
result 最新一轮的结果,任务列表里不返回

result 包含:

字段 说明
text 回复的最后一段正文(Markdown),只有 completed 和 waiting_input 时有内容
files 这一轮交付的文件,每项有 id、version_id、path、name、size、mime;运行中会随交付逐步增加
questions waiting_input 时等待回答的问题,每项有 id、text 和建议的回答 options
points 这一轮已结算的积分

以后可能增加新的字段和状态值。请忽略不认识的字段,把不认识的状态当作“已停下”处理。

任务状态

status 含义 接下来做什么
running 正在执行,包括在等子任务完成 等待结果,或发消息补充说明
waiting_input Favonis 提出问题,在等你回答 发消息回答 result.questions 里的问题
paused 执行中途停下,原因见 reason 按下表处理
completed 这一轮已完成 读取结果和文件,或发消息开始新的一轮
cancelled 这一轮已取消 发消息开始新的一轮

waiting_input 只出现在应用里发起、Favonis 在等回答的那一轮上。通过 API 发起的一轮无人值守,不会中途提问。

paused 时 reason 的取值:

reason 含义和处理方式
by_user 你在应用里暂停任务,发消息继续
insufficient_credits 空间的积分已用完,补充积分后发消息继续,见积分用完时
member_points_cap 你在团队中这一期的积分额度已用完,所有者或管理员调整后发消息继续
provider_error 模型服务出错,稍后发消息继续
model_key_error 你在 Favonis 中设置的个人密钥不可用,例如已失效、余额不足、未开通或被限流,处理后发消息继续
interrupted 执行意外中断,发消息继续
level_choice 应用里发起的一轮在等你决定是否换用更高的档位;发一条不带内容的消息,按原档位继续
action_required 在等只能在应用里处理的操作,例如授权使用浏览器、批准命令,需要在 Favonis 中打开 url 处理。这时发不带内容的消息返回 409 和 error.conflict;带内容的消息会先保存,处理后 Favonis 一并读到

以后可能增加新的取值,同样按“已停下”处理:查看原因,必要时在 Favonis 中打开 url 查看详情。

积分用完时

积分不足不会让请求失败。空间的积分为 0 时,新建任务和发消息照常返回,任务随后暂停,reason 为 insufficient_credits。任务运行中积分用完时,Favonis 会先免费完成一次收尾作答,任务可能以 completed 结束;未能完成收尾时,任务暂停在 insufficient_credits。暂停的任务在补充积分后发消息继续。

新建任务

POST /v1/tasks 立即返回任务,不等它完成。

字段 说明
prompt 必填,要 Favonis 做的事,越具体越好;最多 100 万字,不能全是空白
project_id 在哪个项目里工作,见 GET /v1/projects;不填时是一个独立任务,有自己的文件
file_ids 附件,上传完成后得到的文件 ID
model 模型 ID,见模型与档位;不填时使用默认模型
level 档位名称;不填时使用这个模型的第一档
curl https://api.favonis.com/v1/tasks \
  -H "Authorization: Bearer $FAVONIS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c0e9a-2d4b-4f8e-9a37-5b2c8d1e0f46" \
  -d '{
    "prompt": "根据附件里的销售数据做一份季度复盘 PPT",
    "file_ids": ["0196a40b-7e21-7f3a-b8d5-2c9e61a4f0b3"]
  }'

通过 API 发起的任务无人值守,与定时任务相同:Favonis 不会中途提问,也不会停下来等你选择档位或授权使用浏览器,遇到不确定的地方按合理的假设完成,并在结果中说明。因此 prompt 要写完整:做什么、范围多大、交付什么格式。

新建任务前会检查是否已同意最新的协议、密钥的每月积分上限和同时运行的任务数,未通过时返回相应的错误,见错误码与限制。

查看与等待

GET /v1/tasks/{id} 返回任务和最新一轮的结果。带上 wait(0 到 25 秒)后,任务仍在运行时最多等待 wait 秒,停下后立即返回;不在运行的任务立即返回。

curl "https://api.favonis.com/v1/tasks/$TASK_ID?wait=25" \
  -H "Authorization: Bearer $FAVONIS_API_KEY"

循环调用,直到 status 不再是 running。HTTP 客户端的超时要长于 wait。任务较多或运行较久时,改用 Webhook 接收结果,不必一直等待。

列出任务

GET /v1/tasks 按创建时间倒序列出任务,不带 result。任务的状态变化不会让它在页与页之间移动。

查询参数 说明
status 只列这个状态的任务
limit 一页最多几个,1 到 100,不传时为 20
after 上一页返回的 next

所有列表接口都返回 {"data": [...], "next": "..."},不含 next 表示已是最后一页。按 status 筛选时,一页可能少于 limit 个,请一直翻到不再返回 next 为止。

发消息

POST /v1/tasks/{id}/messages 向任务发一条消息,可以带 text(最多 100 万字)和 file_ids。同一条消息按任务当前的状态处理:

任务状态 消息的作用
running 作为补充说明,Favonis 在下一步读到
waiting_input 回答问题:question_id 指定回答哪个问题,不填时回答第一个;回答只能是文字,最多 10 万字,不能带 file_ids
paused 不带内容时从停下的地方继续,带内容时作为补充说明并继续;action_required 例外,见任务状态
completed、cancelled 在同一个任务里开始新的一轮,同样无人值守

除了继续暂停的任务,消息至少要有 text 或 file_ids 之一。

curl https://api.favonis.com/v1/tasks/$TASK_ID/messages \
  -H "Authorization: Bearer $FAVONIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "只看 2025 年以后的数据"}'

返回发消息之后的任务对象。任务的状态恰好在这时变化(例如刚运行完)时,返回 409 和 error.conflict,这条消息未生效,重新发送后 Favonis 按新的状态处理。

发消息不支持幂等键。请求超时或网络出错时,先用 GET /v1/tasks/{id} 确认任务的状态,再决定是否重发:同一条消息可能已生效,重发后会按新的状态再处理一次,例如第一条开始新的一轮后,第二条又成为补充说明。

取消

POST /v1/tasks/{id}/cancel 停止这一轮,running、waiting_input 和 paused 的任务都会被取消,已交付的文件保留。取消不等执行收尾:返回时 status 可能仍是 running,随后变为 cancelled,可以带上 wait 查看任务,等它停下。completed 和 cancelled 的任务原样返回,重复调用不会出错。取消之后仍能发消息开始新的一轮。

删除

DELETE /v1/tasks/{id} 把任务移到回收站,返回 {"id": "...", "deleted": true}。回收站里的任务不再出现在列表中,也不再推送 Webhook,可以在 Favonis 的回收站中恢复。

幂等键

新建任务(POST /v1/tasks)可以带请求头 Idempotency-Key。同一个密钥、同一个键重复发送,得到的是同一个任务,不会重复执行,也不会重复扣积分。网络超时、不确定请求是否成功时,用原来的键重新发送。

重发时先按键查找第一次建好的任务,找到后原样返回,不再检查协议、每月积分上限和模型,所以即使此时已达到上限、协议有新版本或模型已下线,也不会报错;这个任务已删除时返回 404。

每个逻辑上的请求生成一个新的键,例如 UUID;不同的请求不要共用一个键。其他接口不认这个请求头,发消息的重发方式见发消息。幂等键只在 REST 中可用,MCP 的工具调用不支持。

模型与档位

GET /v1/models 列出这个空间可以用来执行任务的模型,和应用中模型选择器里的列表一致,不含画图模型:

{
	"data": [
		{
			"id": "0195f0c2-6b3d-7e41-9a85-2d7c4e1f0b36",
			"name": "Favon 0.2",
			"levels": ["标准", "深入"],
			"default": true
		}
	]
}

新建任务时用 model 传入模型的 id,用 level 传入 levels 中的一个名称,对应应用里的思考强度档位。不传 model 时使用 default 为 true 的模型,不传 level 时使用第一档。模型不存在或当前套餐不可用时返回 404 和 error.model_not_found,档位名称不对时返回 400 和 error.invalid_input。

上面的取值只是示例。模型 ID 和档位名称以 GET /v1/models 的返回为准,可能随模型调整而变化,请在程序中读取,不要写死。

发消息开始新的一轮时,沿用任务原来的模型和档位。