跳至主要內容

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,不一定拋出例外;參數錯誤可在遠端呼叫開始前拒絕。計費、認證資料及接受的圖片格式仍按已設定服務執行。