Codemode 腳本
需要連續呼叫幾個工具、篩選結果再輸出時,Anyy 可以使用 Codemode。它執行 JavaScript,但沒有 Node.js、直接檔案系統、網路全域物件或定時器;讀檔案和存取外部服務都必須呼叫目前工作階段已有工具。沙箱不要求安裝 Node.js。
先確認工作階段已啟用
在 Dashboard → Tools → Built-in → codemode 儲存 Profile 預設,或對一個空閒、沒有排隊輸入的工作階段執行 Apply to Session。這兩項操作獨立,儲存預設不會替已有工作階段重選工具,詳見頁面設定。
CLI 也可選擇:
anyy --tools '+codemode'
anyy --resume SESSION_ID --tools '+codemode,+tool_search'
+ 從 Profile 預設工具集合計算,不是對復原工作階段目前活動清單增量修改,也不寫設定。符合條件的 MCP 還可自動啟用 Codemode,顯式排除和父範圍限制優先。
模式 on 保留直接工具宣告,only 將可經腳本呼叫的直接宣告從模型請求隱藏,控制代碼和 canonical 記錄仍保留。模式不負責啟用,也不改變 Role。codemode.inline_budget 預設約 3000 個估算 token,只控制內聯巢狀工具說明;沒內聯的工具仍可發現,不是整個上下文預算。工具組說明手工設定。
從一個簡單讀取開始
下面是供模型提交的腳本正文,不帶 Markdown 圍欄。頂層可以 await 和 return:
const result = await tools.bash({command: "git status --short"});
if (result.exit_code !== 0) {
throw new Error("git status failed with " + result.exit_code);
}
text(result.output);
工具的 canonical 參數是必需字串 code 的物件,例如:
{"code":"text(await tools.read({path: \"README.md\", limit: 30}));"}
只有 native model 標記 compat.supportsOpenAIGrammarTools 且 Provider 支援該路徑時,請求才使用原始 grammar JavaScript。其他模型仍傳 JSON code,兩條路徑儲存相同 canonical 參數,不要求使用者另開 grammar 設定。
程式物件不能僅依 Promise 是否 resolve 判定成功。bash 非零結束仍可回傳物件,應看 exit_code;MCP 要看 isError,產品結構化結果要看其狀態。沒有結構化回傳值的工具失敗通常 reject,可使用一般例外處理。
發現並呼叫工具
別猜遠端工具名。先搜尋、看宣告,再按宣告參數呼叫:
const matches = await searchTools("documentation search", {limit: 3});
text(matches);
for (const match of matches) text(await describeTool(match.name));
| 腳本 API | 讀取什麼 |
|---|---|
ALL_TOOLS | 本次可呼叫工具清單中的名稱和描述 |
searchTools(query, {limit?, namespace?}) | 同一份工具清單的相關工具,預設 limit 8 |
describeTool(name) | 一個工具的描述/TypeScript 宣告;不存在為 undefined |
describeNamespace(name) | namespace 描述、instructions 和工具識別名稱;不存在為 undefined |
tools.<identifier>({...}) | 經既有 host 執行一次已存在的工具呼叫 |
規範化將標點等字元改成 _,發現結果會給腳本識別名稱;describeTool 也接受 canonical 名。namespace 只是分組中繼資料,不擴張權限。重名時以目前宣告為準,hidden 和 model-only 工具不能透過腳本呼叫。
searchTools 僅搜尋目前可呼叫快照,不抓另一份遠端目錄,也不改變下一請求的活動宣告。需要啟用模型工具時,使用獨立的 tool_search。
所有已啟動呼叫應等待完成。併發適合互不依賴的讀取;後續操作依賴前一結果時順序 await。腳本結束後,仍未完成的工具呼叫會被取消。
輸出、逾時和分支狀態
可在第一行指定選項:
// @options: {"timeout_ms": 30000, "max_output_tokens": 1500}
const page = await tools.read({path: "README.md", limit: 40});
text(page);
store("last-inspected-file", "README.md");
timeout_ms 是不超過 2147483647 的正整數,含首次載入和 VM 啟動;省略時不另外增加腳本逾時,但父呼叫取消和工具時限仍生效。max_output_tokens 是非負整數,預設 10000,按近似字元預算截短文字。
text(value)和頂層return增加輸出,物件按 JSON 輸出。image(dataURLOrBlock)接受 base64 PNG/JPEG/GIF/WebP,儲存臨時圖片並輸出,不接受遠端 URL。console.log(...)進入單獨 console 輸出塊。exit()成功結束腳本。store(key, value)儲存 JSON 值,load(key)讀取,store(key, undefined)刪除。
每次呼叫重建 VM 和全域變數。只有成功結束的 store 變更提交到所選對話分支;切換分支讀取該分支提交值,資料庫重開後仍可讀。失敗、取消、逾時丟棄本次 staged store,保留過去已提交值,但不會撤回工具已經造成的修改。
store 單值 JSON 最多 262144 字元,key 與 JSON 值合計最多 1048576 字元;請存小狀態,不存認證資料或整份檔案。VM 記憶體上限 256 MiB。輸出超過 16777216 個 JavaScript 字元或 100000 次 text/image/console 呼叫會使腳本失敗。
失敗可帶已有部分輸出和錯誤。按預算截短文字時保留首尾並給出臨時全輸出檔案路徑;檔案存在期間可用 read 的 offset/limit 讀取,它不是持久附件承諾。邏輯引用、完整證據與工作階段總預算見工具結果。
分類和圖片模型
腳本還可直接使用目前設定的模型 API。完整型別說明在工具宣告指向的唯讀檔案 <ProfileHome>/system/docs/pi-v1.2.0/codemode.md,可先用 read 閱讀。
找模型時先指定型別:chat、image、classifier。getModelsOfType(type, provider?) 列出設定目錄;getAvailableOfType(type, provider?) 再按 Provider 啟用及本機可解析認證資料篩選,不是遠端健康探測。
精確查詢要給三個獨立字串:
const selected = await models.getModelOfType("classifier", "provider-id", "model-id");
if (!selected) { text("配置目录没有这个模型"); exit(); }
text(selected);
未知 provider/id 得到 undefined。執行時應傳入目錄中的 model 物件,不能傳入拼接的 provider/id 字串或自造 Endpoint。列出 chat 模型不代表存在腳本 chat 產生函式。
分類輸入
models.classify(model, context) 要求 state 物件、非空 questions 物件,可選 base64 images。每個問題必須有 instructions、type、criteria;choice 是標籤到含義的對映,score 是從低到高的字串層級,bool 給 true/false 兩個字串含義。
const candidates = await models.getAvailableOfType("classifier");
if (!candidates.length) { text("请先配置分类模型"); exit(); }
const result = await models.classify(candidates[0], {
state: {note: "下周三之前交付样稿"},
questions: {
urgency: {
type: "choice", instructions: "根据备注判断时间要求",
criteria: {dated: "有明确期限", undated: "未给期限"}
}
}
});
if (result.stopReason !== "stop") throw new Error(result.errorMessage || result.stopReason);
text(result);
圖片輸入與結果
models.generateImages(model, context) 的 input 是非空的區塊陣列,文字區塊給提示詞,base64 圖片區塊可作參考:
const candidates = await models.getAvailableOfType("image");
if (!candidates.length) { text("请先配置图片模型"); exit(); }
const result = await models.generateImages(candidates[0], {
input: [{type: "text", text: "白底,简洁的绿色叶片图标"}]
});
if (result.stopReason !== "stop") throw new Error(result.errorMessage || result.stopReason);
for (const part of result.output) {
if (part.type === "image") image(part);
else if (part.type === "text") text(part.text);
}
單一腳本最多同時執行四個分類/產生操作,usage 匯入 Codemode 結果。Provider 失敗通常回傳 stopReason 為 error/aborted 和 errorMessage,不一定拋出例外;參數錯誤可在遠端呼叫開始前拒絕。計費、認證資料及接受的圖片格式仍按已設定服務執行。