编写脚本
定义输入输出,调用平台能力,并检查运行结果。
脚本默认导出一个接收输入的函数;返回值成为运行的 output。
执行本页前,先在同一个 Bash 会话完成快速开始第 1–3 步:设置 PRAXIS_API_URL 与 PRAXIS_API_KEY、定义 SOURCE 并临时运行、定义并调用 read_result 辅助动作。该动作检查结果是否为 42,与本页的加一示例对应。
入口与 schema
把下面的内容保存为 script.ts:
export default async (input: { n: number }): Promise<{ answer: number }> => {
console.log("Adding one", input.n);
return { answer: input.n + 1 };
};输入 schema 从参数类型推导;输出 schema 从显式返回类型推导,Promise 会展开。支持基本类型、对象、数组、联合类型及可解析的本地类型别名。不能推导的类型会得到空 schema 和警告;不要把空 schema 当成已经验证了字段。省略返回类型时,不应依赖返回表达式自动推导出输出约束。
通过校验定义检查实际生成的 schema,再发布:
curl --fail-with-body -sS "$PRAXIS_API_URL/automation/v1/validate" \
-H "Authorization: Bearer $PRAXIS_API_KEY" \
-H 'Content-Type: application/json' \
--data "$(jq -n --rawfile source script.ts '{kind:"script",source:$source}')" \
| jq -e '.valid == true and .input_schema.properties.n.type == "number" and .output_schema.properties.answer.type == "number"'期望:输出 true,退出码 0。读取完整校验响应中的 errors 与 warnings 可以定位不能推导的类型。
运行与日志
RUN=$(curl --fail-with-body -sS "$PRAXIS_API_URL/automation/v1/runs" \
-H "Authorization: Bearer $PRAXIS_API_KEY" \
-H 'Content-Type: application/json' \
--data "$(jq -n --rawfile source script.ts \
'{source:$source,language:"ts",input:{n:41},wait:60}')")
RUN_ID=$(jq -er '.id' <<< "$RUN")
read_result "$RUN_ID"
curl --fail-with-body -sS "$PRAXIS_API_URL/automation/v1/runs/$RUN_ID/logs" \
-H "Authorization: Bearer $PRAXIS_API_KEY"期望:结果断言为 true;日志响应包含 Adding one 41。console.log/info/debug 记录为 info,console.warn 和 console.error 保留各自级别。日志不是返回值;需要交给调用方的数据必须 return。可通过日志接口读取,或使用 Accept: text/event-stream 订阅。
全局 praxis
运行时已经提供 praxis,无需 import、API Key 或安装包。它提供以下 SDK 入口;方法参数采用参考页中的 path、query、body 形状,例如 praxis.automation.runs.create({body:{target,input}})。能否调用仍取决于发起者权限。
| 入口 | 能力参考 |
|---|---|
praxis.agent | Agent |
praxis.model | Model |
praxis.file | File |
praxis.sandbox | Sandbox |
praxis.search | Search |
praxis.database | Database |
praxis.automation | Automation |
praxis.organization | Organization |
praxis.meta | Meta |
脚本不能直接访问外部网络。用平台提供的能力完成操作,并 await 调用以取得结果及处理异常。
调用平台内置动作
call("命名空间/名字", 输入) 接收 Action 引用和输入对象,返回 Action 的输出。它是当前运行里的一个步骤:有自己的输入、输出,并在调用记录里占一条,不会产生子运行。praxis 是平台命名空间;省略命名空间的裸名也只解析到平台 Action。调用总使用 Action 的当前修订,暂不支持 @版本;不再接受 命名空间::名字 写法。
调用失败时抛出错误,带 code、message、hint、调用记录序号 seq 和 request_id。多个 call 可以用 Promise.all 并发。praxis.* 只表示平台 SDK,call(...) 和 praxis.ocr(...) 这类写法已删除,运行时会报错并提示改用 call。
把下面内容保存为 chat.ts;它调用 praxis/chat。模型由动作内置并由维护者选择,调用时不选模型;praxis/ocr、praxis/image、praxis/embed 也一样。旧 model 字段已废弃,传入的值会被忽略。此调用会产生模型费用:
export default async (input: { prompt: string }) => {
return await call("praxis/chat", {
messages: [{ role: "user", content: input.prompt }],
stream: false,
});
};RUN=$(curl --fail-with-body -sS "$PRAXIS_API_URL/automation/v1/runs" \
-H "Authorization: Bearer $PRAXIS_API_KEY" \
-H 'Content-Type: application/json' \
--data "$(jq -n --rawfile source chat.ts \
'{source:$source,language:"ts",input:{prompt:"Say hello in one sentence."},wait:60}')")
RUN_ID=$(jq -er '.id' <<< "$RUN")
curl --fail-with-body -sS "$PRAXIS_API_URL/automation/v1/runs/$RUN_ID" \
-H "Authorization: Bearer $PRAXIS_API_KEY" | jq '{id,status,output,error}'期望:终态为 completed,output 为模型结果,error 为 null。若仍是 pending 或 running,重复最后一条 GET,直到终态;faulted 时读取错误,不能把 HTTP 成功当成模型成功。动作输入输出的完整约定可用读取动作查看 praxis/chat。
调用自建动作
以下示例创建动作,再用它的完整名字调用。生成的脚本源码中引用是字符串字面量,便于发布前校验。
ACTION_NAME="add-one-$(date +%s)-$RANDOM"
curl --fail-with-body -sS "$PRAXIS_API_URL/automation/v1/actions" \
-H "Authorization: Bearer $PRAXIS_API_KEY" \
-H 'Content-Type: application/json' \
--data "$(jq -n --arg name "$ACTION_NAME" '{
namespace:"docs-samples",name:$name,
input_schema:{type:"object",properties:{n:{type:"number"}},required:["n"],additionalProperties:false},
output_schema:{type:"object",properties:{answer:{type:"number"}},required:["answer"],additionalProperties:false},
implementation:{kind:"code",language:"ts",source:"export default async (input: { n: number }) => ({ answer: input.n + 1 });"}
}')" | jq -e '.id | startswith("act_")'
SOURCE="export default async (input: { n: number }) => await call(\"docs-samples/$ACTION_NAME\", input);"
RUN=$(curl --fail-with-body -sS "$PRAXIS_API_URL/automation/v1/runs" \
-H "Authorization: Bearer $PRAXIS_API_KEY" \
-H 'Content-Type: application/json' \
--data "$(jq -n --arg source "$SOURCE" \
'{source:$source,language:"ts",input:{n:41},wait:60}')")
RUN_ID=$(jq -er '.id' <<< "$RUN")
read_result "$RUN_ID"期望:动作创建与运行结果均输出 true,结果为 42。用完后可归档动作。动作可复用,但不能在动作内部再编排其他动作、脚本或工作流。
调用另一个脚本或工作流
invoke("命名空间/名字@版本", 输入) 把另一个已发布的脚本或工作流作为子运行启动,等它结束后返回子运行的输出;省略 @版本 用最新版。和 call 的区别:call 是当前运行里的一个步骤,不产生子运行;invoke 产生一个有自己 ID、状态和日志的子运行,并在调用记录里用 child_run_id 指向它。
export default async (input: { urls: string[] }) => {
// 多个 invoke 用 Promise.all 并发;子运行经队列启动,不受单次请求链长度限制。
const pages = await Promise.all(input.urls.map(url => invoke("team/fetch-page", { url })));
return { pages };
};- 等待有上限:
invoke同步等待子运行结束,等待时间受父运行deadline限制。到期时抛出INVOKE_TIMEOUT,消息里带子运行 ID;子运行不会因此被取消,可以用该 ID 另行读取结果。需要等很久的子运行,请在工作流里用run:步骤——工作流在等待期间不占用计算。 - 失败:子运行失败、被取消或无法创建时抛出错误,
code是子运行的错误码,message带子运行 ID。目标不存在或已归档时立即失败,不会排队。 - 取消与超时:父运行被取消或失败时,仍在等待中的子运行会一起被取消。
- 查看子运行:列出运行时用
parent_run_id筛选,得到每个子运行的 ID、目标、状态和耗时。 - 限制:每个运行最多 100 个子运行,同时执行的最多 20 个,多出的排队等待;嵌套最多 10 层,不允许自己调用自己。
脚本不能自行指定独立运行(detach)的子运行;需要“启动后不等结果”时,调用 创建运行。
返回值和时间预算
返回 JSON 可序列化的值;不要返回 undefined、BigInt 或循环引用。序列化后的 UTF-8 返回值最多 1 MiB,超过会使运行失败。大结果应保存到文件等存储中,返回引用。
脚本墙钟时间默认最多 5 分钟;CPU 时间最多 30 秒,并受剩余 deadline 进一步约束。等待平台调用与纯计算的耗时不同,增加等待时长不能解决死循环。全部数值见限制与错误。
有依据的错误与修法
| code | 报错原文 | 修法 |
|---|---|---|
SCRIPT_ERROR | 脚本执行出错 | 阅读 detail 中的原始异常及用户代码行号,修正后创建新运行。 |
CPU_LIMIT_EXCEEDED | 脚本 CPU 时间超出上限 | 终止无限循环,缩小每批纯计算量。 |
PAYLOAD_TOO_LARGE | Payload exceeds 1 MiB | 缩小 JSON 返回值,返回存储引用。 |
INPUT_INVALID | Value must be JSON serializable | 返回明确的 JSON 值,如对象或 null。 |
运行失败看 Run.error;创建请求被拒绝看 HTTP problem 响应。两者不能混用。