它不是业务失败。是 agent 自己写的 runner 在第一步就炸了。
`63e5e8a8` 还没走到 ElevenLabs、Rendi、字幕、Mai callback。 它卡在本地临时脚本的 helper 导入。更糟的是,agent 没有修脚本重跑,而是直接把任务打成 failed。
真实路径很短:写脚本,导 helper,崩溃,直接 fail。
这次失败不是长流程中间某个外部服务报错。它发生在本地脚本刚启动时。 所以任何把它归因到素材、Rendi、ElevenLabs、Cloudflare 的说法都不对。
实际发生的路径
本来应该走的路径
没有 `outputs/result.json`,没有 `outputs/deploy.json`,没有音频/视频产物。说明流程没到业务阶段,也没拿到可用的 callback envelope。
问题不是 importlib 本身。问题是少了一行注册。
Mai 的 correction 也确认了:原始脚本作为程序运行时,runner 自己的 `dataclass` 不是第一爆点。 第一爆点是 `load_helper()` 导入 helper。helper 里有 `@dataclass class Segment`。
def load_helper():
import importlib.util
spec = importlib.util.spec_from_file_location(
"vo",
ROOT / ".tobatsu/skills/voiceover-align/scripts/voiceover_align.py",
)
mod = importlib.util.module_from_spec(spec)
assert spec and spec.loader
spec.loader.exec_module(mod)
return mod
def load_helper():
import importlib.util
import sys
spec = importlib.util.spec_from_file_location(
"vo",
ROOT / ".tobatsu/skills/voiceover-align/scripts/voiceover_align.py",
)
mod = importlib.util.module_from_spec(spec)
assert spec and spec.loader
sys.modules[spec.name] = mod
spec.loader.exec_module(mod)
return mod
`dataclasses` 会按类的 `__module__` 去 `sys.modules` 里找 module namespace。动态导入时没注册,它拿到 `None`,于是报 `NoneType.__dict__`。
runner 的 `main()` 先跑 `load_helper()`,后读 `.tobatsu/context.json`。它在第一步就炸了,所以失败处理里没有完整 payload,也没有 callback URL / token 可以组装 Mai 业务失败回调。
这不是一次普通失败,是两层指令没兜住。
agent 写错代码本身可以发生。真正不能接受的是:错在自己脚本,还没自修复,就把 task 变成 terminal failed。
如果错误发生在 agent 自己写的 glue code 里,且还没调用外部服务,那第一动作是修代码,不是 fail。
补两道闸:一闸防写错,一闸防错了直接死。
不改 Mai。不重启 worker。新任务创建时会拿 DB 里的最新 workflow 和 skill。
安全 helper 导入
把 `importlib` 示例改成注册 `sys.modules` 的版本。写明 `dataclass` helper 不能裸 `exec_module`。
内部脚本先自救
runner import、临时脚本语法、NameError、AttributeError 都要先修脚本并重跑一次。
不能过早 fail
只有真实业务、provider、callback 错误才进入 failed callback 和 `tobatsu-agent fail`。
走 API 发布 DB revision。不要 sync,不要拉 worker,不要重启。旧 task snapshot 不变,新 task 使用新版本。
这条任务不能原地变成功。要用新 run 重打。
Tobatsu task 已经 terminal failed。后面就算脚本修好,也不能把同一个 task 改回 done。 正确做法是发布补丁后,让 Mai 用新的 Gateway run / callback envelope 重发。