|
|
|
@@ -1,7 +1,7 @@
|
|
|
|
|
📦
|
|
|
|
|
27221 /main.js
|
|
|
|
|
27680 /main.js
|
|
|
|
|
✄
|
|
|
|
|
var ie="1.5.2",w="decai",P="~/.config/r2ai",H=P+"/apikeys.txt",T=P+"/decai.txt",D="Rewrite this pseudocode into concise and clean code. Output only the provided function. Do not add wrappers, helper examples, test code, or main-like functions. Replace goto with structured control flow, simplify as much as possible, infer types and use better names for variables and parameters, some strings may be appearing as comments, preserve only what is implied by the input, and remove dead code.",Y={decai:`# Using Decai
|
|
|
|
|
var te="1.5.4",b="decai",w="~/.config/r2ai",N=w+"/apikeys.txt",U=w+"/decai.txt",T="Rewrite this pseudocode into concise and clean code. Output only the provided function. Do not add wrappers, helper examples, test code, or main-like functions. Replace goto with structured control flow, simplify as much as possible, infer types and use better names for variables and parameters, some strings may be appearing as comments, preserve only what is implied by the input, and remove dead code.",L={decai:`# Using Decai
|
|
|
|
|
|
|
|
|
|
Decai is the radare2 plugin for decompiling functions with the help of language models.
|
|
|
|
|
|
|
|
|
@@ -26,6 +26,7 @@ These are the most recommended models for decompiling in local:
|
|
|
|
|
* 'decai -e apitype=chat|generate' choose the Ollama API endpoint (default: chat)
|
|
|
|
|
* 'decai -e headers=Authorization: Bearer ...\\nUser-Agent: curl/8.7.1' add or override HTTP headers
|
|
|
|
|
* "export DECAI_HEADERS='Authorization: Bearer ...\\nUser-Agent: curl/8.7.1'" set extra headers from the environment
|
|
|
|
|
* 'decai -e http=auto|r2|curl' select the HTTP transport (default: auto, prefers r2.http)
|
|
|
|
|
* 'decai -e timeout=0' disable curl timeouts, or set a positive number of seconds
|
|
|
|
|
|
|
|
|
|
* 'decai -e deterministic=true' to remove randomness from decompilation responses
|
|
|
|
@@ -117,54 +118,54 @@ Use radare2 to resolve user requests.
|
|
|
|
|
### Special cases
|
|
|
|
|
|
|
|
|
|
* On Swift binaries run...
|
|
|
|
|
`};var S={decopipe:{use:!1},host:"http://localhost",port:"11434",baseurl:"",extraHeaders:[],api:"ollama",pipeline:"",commands:"pdc",yolo:!1,tts:!1,language:"C",humanLanguage:"English",deterministic:!0,debug:!1,timeout:180,think:"",apitype:"chat",useFiles:!1,contextFile:"",model:"",cache:!1,maxInputTokens:-1,prompt:D,lastOutput:""},o={...S,decopipe:{...S.decopipe},extraHeaders:[...S.extraHeaders]};function ae(e){return(r2.cmd("-e dir.tmp").trim()??".")+"/"+e}function j(e,t){r2.cmd("'mkdir -p "+e),r2.cmd("'touch "+t)}function K(e){return(r2.cmd2("test -h").logs?.[0]?.message??"").includes("-fdx")?!0:r2.cmd("'test -vf "+e).startsWith("found")}function W(e,t){return e+" ".repeat(Math.max(0,t-e.length))}function x(e,t){return e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,"")}function se(e){return e.replace(/\x1b\[[0-9;]*m/g,"")}function le(e){let t=e.match(/```json\s*([\s\S]*?)```/);return t&&t[1]?t[1].trim():e}function ce(e){let t=e,n=t.indexOf("{");n!==-1&&(t=t.slice(n));let r=t.lastIndexOf("}");return r!==-1&&(t=t.slice(0,r+1)),t}function z(e){return btoa(e)}function ue(e,t){let n=z(t);r2.cmd("p6ds "+n+" > "+e)}function E(e){let t=e;return t=t.replace(/<think>[\s\S]*?<\/think>/gi,""),t.split(`
|
|
|
|
|
`};var E={decopipe:{use:!1},host:"http://localhost",port:"11434",baseurl:"",extraHeaders:[],api:"ollama",pipeline:"",commands:"pdc",yolo:!1,tts:!1,language:"C",humanLanguage:"English",deterministic:!0,debug:!1,timeout:180,http:"auto",think:"",apitype:"chat",useFiles:!1,contextFile:"",model:"",cache:!1,maxInputTokens:-1,prompt:T,lastOutput:""},r={...E,decopipe:{...E.decopipe},extraHeaders:[...E.extraHeaders]};function re(e){return(r2.cmd("-e dir.tmp").trim()??".")+"/"+e}function ne(e){if(!e.startsWith("~/"))return e;let t=r2.cmd("'%HOME").trim()||r2.cmd("'%USERPROFILE").trim();return t?t+e.slice(1):e}function H(e,t){r2.cmd("'mkdir -p "+ne(e)),r2.cmd("'touch "+ne(t))}function _(e){return(r2.cmd2("test -h").logs?.[0]?.message??"").includes("-fdx")?!0:r2.cmd("'test -vf "+e).startsWith("found")}function G(e,t){return e+" ".repeat(Math.max(0,t-e.length))}function h(e,t){return e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,"")}function oe(e){return e.replace(/\x1b\[[0-9;]*m/g,"")}function ie(e){let t=e.match(/```json\s*([\s\S]*?)```/);return t&&t[1]?t[1].trim():e}function ae(e){let t=e,n=t.indexOf("{");n!==-1&&(t=t.slice(n));let o=t.lastIndexOf("}");return o!==-1&&(t=t.slice(0,o+1)),t}function $(e){return btoa(e)}function se(e,t){let n=$(t);r2.cmd("p6ds "+n+" > "+e)}function k(e){let t=e;return t=t.replace(/<think>[\s\S]*?<\/think>/gi,""),t.split(`
|
|
|
|
|
`).filter(n=>!n.trim().startsWith("```")).join(`
|
|
|
|
|
`)}function V(e){o.debug&&console.log(e)}function de(e){let t={};for(let n of e.split(/\r?\n/)){let r=n.trim();if(!r||r.startsWith("#"))continue;let[i,...a]=r.split("=");if(!i||a.length===0)continue;let s=a.join("=").trim(),l=i.toLowerCase().replace(/_api_key$/i,"");t[l]=s}return t}var Ne=["DECAI_HEADERS","R2AI_HEADERS"];function Te(e){let t=r2.cmd("'%"+e).trim();return t!==""&&!t.includes("=")?t:""}function Ke(e){return e.trim().toLowerCase()}function qe(e){let t=e.indexOf(":"),n=e.indexOf("="),r=t!==-1&&(n===-1||t<n)?t:n;if(r===-1)return null;let i=e.slice(0,r).trim();return i===""?null:{name:i,value:e.slice(r+1).trim()}}function He(e){return e.value===""?`${e.name}:`:`${e.name}: ${e.value}`}function pe(e,t){for(let n of e){let r=qe(n.trim());r&&t.set(Ke(r.name),He(r))}}function Q(e){let t=new Map,n=e.replace(/\\n/g,`
|
|
|
|
|
`).split(/\r?\n/g).filter(r=>{let i=r.trim();return i&&!i.startsWith("#")});return pe(n,t),Array.from(t.values())}function fe(e){return e.join("\\n")}function C(...e){let t=new Map;for(let n of e)pe(n,t);return Array.from(t.values())}function De(){for(let e of Ne){let t=Te(e);if(t)return Q(t)}return[]}function me(){return C(De(),o.extraHeaders)}function q(e){return`'${e.replace(/'/g,`'"'"'`)}'`}function je(e){let{method:t,url:n,headers:r,payload:i}=e,a=C(["Content-Type: application/json"],r),s=r2.http;if(s)return s(t,n,a.join(`
|
|
|
|
|
`),i??"").body;let l=["curl","-s"];if(o.timeout>0&&l.push("--max-time",String(o.timeout)),a.forEach(c=>l.push("-H",q(c))),t==="POST"){if(!i)throw new Error("Payload required for POST requests");let c=r2.fdump(i);l.push("--data-binary","@"+q(c),q(n));let k=l.join(" ")+"; rm "+q(c);return V(k),r2.syscmds(k)}else{l.push(q(n));let c=l.join(" ");return V(c),r2.syscmds(c)}}function Be(e){let t=e.split(`
|
|
|
|
|
`).filter(i=>i.trim()!=="");if(t.length<=1)return null;let n="",r=null;for(let i of t)try{let a=JSON.parse(i);if(a.error)return a;a.message?.content!==void 0&&(n+=a.message.content),r=a}catch{return null}return r?(r.message={role:"assistant",content:n},r):null}function he(e){try{let t=je(e).trim();if(t==="")return{error:"empty response"};try{return JSON.parse(t)}catch{let n=Be(t);return n||{error:t,rawOutput:t}}}catch(t){return{error:t.message}}}function I(e,t){return he({method:"GET",url:e,headers:t})}function ge(e,t,n){return he({method:"POST",url:e,headers:t,payload:n})}function Z(e){return e.split("_")[0].toLowerCase()}function ye(e){if(!e.authKey)return;let t=Array.from(new Set([e.keyName,Z(e.authKey)].filter(Boolean))),n;for(let r of t){let i=B(r,e.authKey);if(i[0])return i;!n&&i[2]!=="nope"&&(n=i)}return n||B(Z(e.authKey),e.authKey)}function R(e){if(e)return typeof e=="string"?e:e.message||JSON.stringify(e)}function be(e){return o.baseurl||e.defaultBaseUrl}function ke(e,t=me()){return C(e,t)}function Fe(e){return e?["Authorization: Bearer "+e]:[]}function Le(e){let t=["anthropic-version: 2023-06-01"];return e?C(t,["x-api-key: "+e]):t}function xe(e,t){switch(e.authStyle||"none"){case"bearer":return Fe(t);case"anthropic":return Le(t);case"none":default:return[]}}function Ge(e,t,n){let r=I(e,t),i=R(r.error);return i?(console.error(i),"error invalid response"):r.data?.map(n).join(`
|
|
|
|
|
`)||""}function $e(e,t){let n=new Set;return e.filter(r=>{let i=t(r);return n.has(i)?!1:(n.add(i),!0)})}function ee(e){let t=ye(e)?.[0]||null;return{baseUrl:be(e),headers:ke(xe(e,t))}}function Je(e){let{baseUrl:t,headers:n}=ee(e),r=x(t,"v1/models");return Ge(r,n,i=>i.id)}function Ye(e){let{baseUrl:t,headers:n}=ee(e),r=I(x(t,"api/tags"),n),i=R(r.error);return i?(console.error(i),"error invalid response"):r.models?.map(a=>a.name).join(`
|
|
|
|
|
`)||""}function We(e){let{baseUrl:t,headers:n}=ee(e),r=I(x(t,"v1/models"),n);return r.data?$e(r.data,i=>i.name||i.id).map(i=>[W(i.name||i.id,30),W(""+(i.max_context_length||""),10),i.description||""].join(" ")).join(`
|
|
|
|
|
`):""}var ze={openai:{buildPayload:(e,t)=>({stream:!1,model:e,messages:[{role:"user",content:t}]}),parseResponse:e=>{if(e.error)throw new Error(R(e.error)||"Unknown error");if(e.choices&&e.choices[0]?.message?.content)return E(e.choices[0].message.content);throw new Error("Invalid response format")},buildUrl:e=>x(e,"v1/chat/completions")},anthropic:{buildPayload:(e,t)=>{let n={model:e,max_tokens:5128,messages:[{role:"user",content:t}]};return X()&&(n.thinking={type:"enabled",budget_tokens:4096},n.max_tokens=16e3),o.deterministic&&!X()&&Object.assign(n,{temperature:0,top_p:0,top_k:1}),n},parseResponse:e=>{if(e.content&&Array.isArray(e.content)){let t=[];for(let n of e.content)n.text&&t.push(n.text);if(t.length>0)return E(t.join(`
|
|
|
|
|
`))}throw e.error?new Error(R(e.error)||"Unknown error"):new Error("Invalid response format")},buildUrl:e=>x(e,"v1/messages")},ollama:{buildPayload:(e,t)=>{let n={stream:!1,model:e};return o.apitype==="generate"?n.prompt=t:n.messages=[{role:"user",content:t}],X()?o.think==="true"||o.think==="1"?n.think=!0:n.think=o.think:n.think=!1,o.deterministic&&(n.options={repeat_last_n:0,top_p:1,top_k:1,temperature:0,repeat_penalty:1,seed:123}),n},parseResponse:e=>{if(e.error)throw new Error(R(e.error));if(typeof e.response=="string")return E(e.response);if(e.message?.content)return E(e.message.content);throw new Error(JSON.stringify(e))},buildUrl:e=>x(e,"api/"+o.apitype)},gemini:{buildPayload:(e,t)=>{let n={contents:[{parts:[{text:t}]}]},r={};return o.deterministic&&Object.assign(r,{temperature:0,topP:1,topK:1}),o.think!==""&&(ne()?r.thinkingConfig={thinkingBudget:0}:r.thinkingConfig={thinkingBudget:8192}),Object.keys(r).length>0&&(n.generationConfig=r),n},parseResponse:e=>{if(e.candidates&&e.candidates[0]?.content?.parts){let n=e.candidates[0].content.parts.filter(r=>!r.thought&&r.text).map(r=>r.text);if(n.length>0)return E(n.join(`
|
|
|
|
|
`))}throw e.error?new Error(R(e.error)):(console.log(JSON.stringify(e)),new Error("Invalid response format"))},buildUrl:(e,t,n)=>x(e,`v1beta/models/${t}:generateContent?key=${n}`),requiresUrlApiKey:!0}},F={anthropic:{defaultModel:"claude-3-7-sonnet-20250219",defaultBaseUrl:"https://api.anthropic.com",authKey:"ANTHROPIC_API_KEY",keyName:"anthropic",authStyle:"anthropic",apiStyle:"anthropic"},claude:{defaultModel:"claude-3-7-sonnet-20250219",defaultBaseUrl:"https://api.anthropic.com",authKey:"ANTHROPIC_API_KEY",keyName:"claude",authStyle:"anthropic",apiStyle:"anthropic"},openai:{defaultModel:"gpt-4o-mini",defaultBaseUrl:"https://api.openai.com",authKey:"OPENAI_API_KEY",authStyle:"bearer",apiStyle:"openai"},ollama:{defaultModel:"qwen2.5-coder:latest",defaultBaseUrl:"http://localhost:11434",authStyle:"none",apiStyle:"ollama"},ollamacloud:{defaultModel:"gpt-oss:120b",defaultBaseUrl:"https://ollama.com",authKey:"OLLAMA_API_KEY",keyName:"ollamacloud",authStyle:"bearer",apiStyle:"ollama"},zen:{defaultModel:"big-pickle",defaultBaseUrl:"https://opencode.ai/zen",authKey:"OPENCODE_API_KEY",keyName:"zen",authStyle:"bearer",apiStyle:"openai",hardcodedModels:["big-pickle","glm-5","kimi-k2.5"]},gemini:{defaultModel:"gemini-2.5-flash",defaultBaseUrl:"https://generativelanguage.googleapis.com",authKey:"GEMINI_API_KEY",authStyle:"none",apiStyle:"gemini",hardcodedModels:["gemini-2.0-flash","gemini-2.0-flash-lite","gemini-2.5-pro","gemini-2.5-flash","gemini-2.5-flash-lite"]},mistral:{defaultModel:"codestral-latest",defaultBaseUrl:"https://api.mistral.ai",authKey:"MISTRAL_API_KEY",authStyle:"bearer",apiStyle:"openai"},xai:{defaultModel:"grok-beta",defaultBaseUrl:"https://api.x.ai",authKey:"XAI_API_KEY",authStyle:"bearer",apiStyle:"openai",hardcodedModels:["grok-2","grok-beta"]},lmstudio:{defaultModel:"local-model",defaultBaseUrl:"http://127.0.0.1:1234",authStyle:"none",apiStyle:"openai"},deepseek:{defaultModel:"deepseek-coder",defaultBaseUrl:"https://api.deepseek.com",authKey:"DEEPSEEK_API_KEY",authStyle:"bearer",apiStyle:"openai",hardcodedModels:["deepseek-coder","deepseek-chat"]},openrouter:{defaultModel:"openai/gpt-4o-mini",defaultBaseUrl:"https://openrouter.ai/api",authKey:"OPENROUTER_API_KEY",authStyle:"bearer",apiStyle:"openai"},groq:{defaultModel:"llama-3.3-70b-versatile",defaultBaseUrl:"https://api.groq.com/openai",authKey:"GROQ_API_KEY",authStyle:"bearer",apiStyle:"openai"}};function L(e){return F[e]}function te(){return Object.keys(F)}function ve(e){let t=L(e);if(!t)throw new Error(`Unknown provider: ${e}`);if(e==="mistral")return We(t);switch(t.apiStyle){case"openai":case"anthropic":return Je(t);case"ollama":return Ye(t);case"gemini":return"";default:return""}}function ne(){return o.think==="false"||o.think==="0"}function X(){return o.think!==""&&!ne()}function Ve(e,t,n){let r=e;return o.think!==""&&n==="openai"&&(ne()?(r+=' Answers directly and concisely, without showing any thinking steps or internal reasoning. Never include phrases like "Let me think".',r+=" /no_think"):r="Think step by step and explain the reasoning process, When answering, first output your reasoning inside <think> and </think> tags, then give the final answer."+r),t?r:o.prompt+Qe()+r}function Qe(){return`
|
|
|
|
|
.Translate the code into `+o.language+` programming language
|
|
|
|
|
`}function Xe(e,t,n,r){let i=o.model||e.defaultModel,a=Ve(n,r,e.apiStyle),s=ye(e);if(t.requiresUrlApiKey&&s?.[1]&&e.authKey)return`Cannot read ~/.r2ai.${Z(e.authKey)}-key`;let l=t.buildPayload(i,a),c=xe(e,s?.[0]||null);e.apiStyle==="ollama"&&c.push("Accept: application/x-ndjson");let k=ke(c),u=t.buildUrl(be(e),i,s?.[0]||void 0);try{return t.parseResponse(ge(u,k,JSON.stringify(l)))}catch(d){return"ERROR: "+d.message}}function Ae(e,t){let n=L(o.api);return n?Xe(n,ze[n.apiStyle],e,t):`Unknown value for 'decai -e api'. Available: ${te().join(", ")}`}function Ze(){return Object.fromEntries(Object.entries(F).filter(([,e])=>e.authKey).map(([e,t])=>[e,t.authKey]))}function B(e,t){let n=r2.cmd("'%"+t).trim();if(!n.includes("=")&&n!=="")return[n.trim(),null,"env"];let r=e.toLowerCase(),i=H;if(K(i)){let s=r2.cmd("'cat "+i),l=de(s);if(r in l)return[l[r],null,"txt"]}let a="~/.r2ai."+r+"-key";if(K(a)){let s=r2.cmd("'cat "+a);return s===""?[null,"Cannot read "+a,"no"]:[s.trim(),null,"file"]}return[null,"Not available","nope"]}function we(){j(P,H),r2.cmd("'ed "+H)}function oe(){Object.entries(Ze()).forEach(([e,t])=>{let n=B(e,t)[2];console.log(n," ",e)})}function Ee(e){let t=L(e);if(!t){console.error(`Unknown provider: ${e}`);return}try{let n=ve(e);n&&console.log(n),t.hardcodedModels&&t.hardcodedModels.forEach(r=>console.log(r)),e==="mistral"&&console.log("ministral-8b-latest"),!n&&!t.hardcodedModels&&console.log(t.defaultModel)}catch(n){let r=n;console.error(`Error listing models for ${e}:`,r.message),console.log(t.defaultModel)}}var re=!1;function et(e){return e==="true"||e==="1"}function U(e){let t=o;return{get:()=>t[e],set:n=>{t[e]=et(n)}}}function _(e){let t=o;return{get:()=>t[e],set:n=>{t[e]=n}}}function tt(e){let t=e.trim();return t==="chat"?"chat":t==="generate"?"generate":null}var Oe={pipeline:{get:()=>o.pipeline,set:e=>{o.pipeline=e;try{o.decopipe=JSON.parse(r2.cmd("cat "+e))}catch(t){console.error(t)}}},model:{get:()=>o.model,set:e=>{e==="?"?Ee(o.api):o.model=e.trim()}},deterministic:U("deterministic"),files:U("useFiles"),think:{get:()=>o.think||"false",set:e=>{o.think=e}},apitype:{get:()=>o.apitype,set:e=>{let t=tt(e);t?o.apitype=t:console.error("Invalid apitype. Use chat or generate.")}},debug:U("debug"),timeout:{get:()=>o.timeout,set:e=>{o.timeout=Math.max(0,parseInt(e,10)||0)}},api:{get:()=>o.api,set:e=>{e==="?"?console.error(te().join(`
|
|
|
|
|
`)):o.api=e}},lang:_("language"),hlang:_("humanLanguage"),cache:U("cache"),cmds:_("commands"),tts:U("tts"),yolo:U("yolo"),prompt:_("prompt"),ctxfile:_("contextFile"),baseurl:_("baseurl"),headers:{get:()=>fe(o.extraHeaders),set:e=>{o.extraHeaders=Q(e)}},maxtokens:{get:()=>o.maxInputTokens,set:e=>{o.maxInputTokens=parseInt(e,10)||-1}}};function nt(){let e={host:o.host,port:o.port,lastOutput:o.lastOutput};Object.assign(o,S,e),o.decopipe={...S.decopipe},o.extraHeaders=[...S.extraHeaders]}function ot(e){let t=e.trim();return!t||t.startsWith("#")?null:t.startsWith("decai -e ")?t.slice(9).trim():t}function O(e){let t=e.indexOf("="),n=t===-1?e:e.slice(0,t),r=t===-1?void 0:e.slice(t+1),i=Oe[n];if(!i){console.error("Unknown config key");return}typeof r<"u"?i.set(r):console.log(i.get())}function Se(){Object.entries(Oe).forEach(([e,t])=>{let n=t.get();console.log("decai -e "+e+"="+n)})}function Pe(){if(nt(),!K(T))return;let e=r2.call("cat "+T);for(let t of e.split(/\r?\n/)){let n=ot(t);n&&n[0]!="#"&&O(n)}}function Ce(){re||(Pe(),re=!0)}function Ie(){j(P,T),r2.cmd("'ed "+T),Pe(),re=!0}function p(e,t,n=!1){let r=(t||"").replace(/`/g,""),i=e.replace(/'/g,"");if(o.api==="r2"||o.api==="r2ai"){let s=ae(".pdc.txt");ue(s,r);let l=i.startsWith("-")?i:["-i",s,i].join(" "),c=o.baseurl||o.host+":"+o.port,k=x(c,"cmd/"+encodeURIComponent(l)),u=I(k,[]);return u.error?`Error: ${u.error}`:u.result||JSON.stringify(u)||"Cannot curl, use r2ai-server or r2ai -w"}if(i.startsWith("-"))return"";let a=i+`:
|
|
|
|
|
`+r;return o.maxInputTokens>0&&a.length>o.maxInputTokens&&(a=a.slice(0,o.maxInputTokens)),Ae(a,n)}function Ue(e){let t=r2.cmd("e scr.color");r2.cmd("e scr.color=0");try{return e()}finally{r2.cmd("e scr.color="+t)}}function Re(){let e="",t=n=>e+=" "+w+" "+n+`
|
|
|
|
|
`;e+="Usage: "+w+` (-h) ...
|
|
|
|
|
`,e+="Version: "+ie+`
|
|
|
|
|
`,t("-a [query] - solve query with auto mode"),t("-b [url] - set base URL (alias for decai -e baseurl)"),t("-d [f1 ..] - decompile given functions"),t("-dd [..] - same as above, but ignoring cache"),t("-dD [query] - decompile current function with given extra query"),t("-dr - decompile function and its called ones (recursive)"),t("-e - display and change eval config vars"),t("-E - edit and run decai.txt"),t("-h - show this help"),t("-H - help setting up r2ai"),t("-i [f] [q] - include given file and query"),t("-k - list API key status"),t("-K - edit apikeys.txt"),t("-m [model] - use -m? or -e model=? to list the available models"),t("-n - suggest better function name"),t("-p [provider] - same as decai -e api (will be provider)"),t("-q [text] - query language model with given text"),t("-Q [text] - query on top of the last output"),t("-r [prompt] - change role prompt (same as: decai -e prompt)"),t("-R - reset role prompt to default prompt"),t("-s - function signature"),t("-v - show local variables"),t("-V - find vulnerabilities"),t("-x[*] - eXplain current function (-x* for r2 script)"),r2.log(e.trim())}function G(e,t,n,r){if(n){let s=r2.cmd("anos").trim();if(s.length>0)return s}let i="";if(r){let s=r2.cmd("s");i+=`## Context functions:
|
|
|
|
|
`;let l=r2.cmdAt("axff~^C[2]~$$",s);for(let c of l.split(/\n/g))i+=r2.cmd("pdc@"+c);r2.cmd("s "+s)}let a=t?" "+e:"";try{let s=e.slice(2).trim(),l="";o.contextFile!==""&&r2.cmd2("test -f "+o.contextFile).value===0&&(l+=`## Context:
|
|
|
|
|
`)}function J(e){r.debug&&console.log(e)}function le(e){let t={};for(let n of e.split(/\r?\n/)){let o=n.trim();if(!o||o.startsWith("#"))continue;let[i,...a]=o.split("=");if(!i||a.length===0)continue;let s=a.join("=").trim(),l=i.toLowerCase().replace(/_api_key$/i,"");t[l]=s}return t}var Ue=["DECAI_HEADERS","R2AI_HEADERS"];function _e(e){let t=r2.cmd("'%"+e).trim();return t!==""&&!t.includes("=")?t:""}function Me(e){return e.trim().toLowerCase()}function Ne(e){let t=e.indexOf(":"),n=e.indexOf("="),o=t!==-1&&(n===-1||t<n)?t:n;if(o===-1)return null;let i=e.slice(0,o).trim();return i===""?null:{name:i,value:e.slice(o+1).trim()}}function Te(e){return e.value===""?`${e.name}:`:`${e.name}: ${e.value}`}function ce(e,t){for(let n of e){let o=Ne(n.trim());o&&t.set(Me(o.name),Te(o))}}function W(e){let t=new Map,n=e.replace(/\\n/g,`
|
|
|
|
|
`).split(/\r?\n/g).filter(o=>{let i=o.trim();return i&&!i.startsWith("#")});return ce(n,t),Array.from(t.values())}function ue(e){return e.join("\\n")}function A(...e){let t=new Map;for(let n of e)ce(n,t);return Array.from(t.values())}function He(){for(let e of Ue){let t=_e(e);if(t)return W(t)}return[]}function de(){return A(He(),r.extraHeaders)}function M(e){return`'${e.replace(/'/g,`'"'"'`)}'`}function Ke(e){let{method:t,url:n,headers:o,payload:i}=e,a=A(["Content-Type: application/json"],o);if(r.http!=="curl"){if(r2.http)return r2.http(t,n,a.join(`
|
|
|
|
|
`),i??"").body;if(r.http==="r2")throw new Error("r2.http is not available in this runtime")}let s=["curl","-s"];if(r.timeout>0&&s.push("--max-time",String(r.timeout)),a.forEach(l=>s.push("-H",M(l))),t==="POST"){if(!i)throw new Error("Payload required for POST requests");let l=r2.fdump(i);s.push("--data-binary","@"+M(l),M(n));let u=s.join(" ")+"; rm "+M(l);return J(u),r2.syscmds(u)}else{s.push(M(n));let l=s.join(" ");return J(l),r2.syscmds(l)}}function qe(e){let t=e.split(`
|
|
|
|
|
`).filter(i=>i.trim()!=="");if(t.length<=1)return null;let n="",o=null;for(let i of t)try{let a=JSON.parse(i);if(a.error)return a;a.message?.content!==void 0&&(n+=a.message.content),o=a}catch{return null}return o?(o.message={role:"assistant",content:n},o):null}function pe(e){try{let t=Ke(e).trim();if(t==="")return{error:"empty response"};try{return JSON.parse(t)}catch{let n=qe(t);return n||{error:t,rawOutput:t}}}catch(t){return{error:t.message}}}function O(e,t){return pe({method:"GET",url:e,headers:t})}function fe(e,t,n){return pe({method:"POST",url:e,headers:t,payload:n})}function z(e){return e.split("_")[0].toLowerCase()}function me(e){if(!e.authKey)return;let t=Array.from(new Set([e.keyName,z(e.authKey)].filter(Boolean))),n;for(let o of t){let i=K(o,e.authKey);if(i[0])return i;!n&&i[2]!=="nope"&&(n=i)}return n||K(z(e.authKey),e.authKey)}function S(e){if(e)return typeof e=="string"?e:e.message||JSON.stringify(e)}function he(e){return r.baseurl||e.defaultBaseUrl}function ge(e,t=de()){return A(e,t)}function De(e){return e?["Authorization: Bearer "+e]:[]}function je(e){let t=["anthropic-version: 2023-06-01"];return e?A(t,["x-api-key: "+e]):t}function ye(e,t){switch(e.authStyle||"none"){case"bearer":return De(t);case"anthropic":return je(t);case"none":default:return[]}}function Be(e,t,n){let o=O(e,t),i=S(o.error);return i?(console.error(i),"error invalid response"):o.data?.map(n).join(`
|
|
|
|
|
`)||""}function Fe(e,t){let n=new Set;return e.filter(o=>{let i=t(o);return n.has(i)?!1:(n.add(i),!0)})}function V(e){let t=me(e)?.[0]||null;return{baseUrl:he(e),headers:ge(ye(e,t))}}function Le(e){let{baseUrl:t,headers:n}=V(e),o=h(t,"v1/models");return Be(o,n,i=>i.id)}function Ge(e){let{baseUrl:t,headers:n}=V(e),o=O(h(t,"api/tags"),n),i=S(o.error);return i?(console.error(i),"error invalid response"):o.models?.map(a=>a.name).join(`
|
|
|
|
|
`)||""}function $e(e){let{baseUrl:t,headers:n}=V(e),o=O(h(t,"v1/models"),n);return o.data?Fe(o.data,i=>i.name||i.id).map(i=>[G(i.name||i.id,30),G(""+(i.max_context_length||""),10),i.description||""].join(" ")).join(`
|
|
|
|
|
`):""}var Je={openai:{buildPayload:(e,t)=>({stream:!1,model:e,messages:[{role:"user",content:t}]}),parseResponse:e=>{if(e.error)throw new Error(S(e.error)||"Unknown error");if(e.choices&&e.choices[0]?.message?.content)return k(e.choices[0].message.content);throw new Error("Invalid response format")},buildUrl:e=>h(e,"v1/chat/completions")},anthropic:{buildPayload:(e,t)=>{let n={model:e,max_tokens:5128,messages:[{role:"user",content:t}]};return Y()&&(n.thinking={type:"enabled",budget_tokens:4096},n.max_tokens=16e3),r.deterministic&&!Y()&&Object.assign(n,{temperature:0,top_p:0,top_k:1}),n},parseResponse:e=>{if(e.content&&Array.isArray(e.content)){let t=[];for(let n of e.content)n.text&&t.push(n.text);if(t.length>0)return k(t.join(`
|
|
|
|
|
`))}throw e.error?new Error(S(e.error)||"Unknown error"):new Error("Invalid response format")},buildUrl:e=>h(e,"v1/messages")},ollama:{buildPayload:(e,t)=>{let n={stream:!1,model:e};return r.apitype==="generate"?n.prompt=t:n.messages=[{role:"user",content:t}],Y()?r.think==="true"||r.think==="1"?n.think=!0:n.think=r.think:n.think=!1,r.deterministic&&(n.options={repeat_last_n:0,top_p:1,top_k:1,temperature:0,repeat_penalty:1,seed:123}),n},parseResponse:e=>{if(e.error)throw new Error(S(e.error));if(typeof e.response=="string")return k(e.response);if(e.message?.content)return k(e.message.content);throw new Error(JSON.stringify(e))},buildUrl:e=>h(e,"api/"+r.apitype)},gemini:{buildPayload:(e,t)=>{let n={contents:[{parts:[{text:t}]}]},o={};return r.deterministic&&Object.assign(o,{temperature:0,topP:1,topK:1}),r.think!==""&&(X()?o.thinkingConfig={thinkingBudget:0}:o.thinkingConfig={thinkingBudget:8192}),Object.keys(o).length>0&&(n.generationConfig=o),n},parseResponse:e=>{if(e.candidates&&e.candidates[0]?.content?.parts){let n=e.candidates[0].content.parts.filter(o=>!o.thought&&o.text).map(o=>o.text);if(n.length>0)return k(n.join(`
|
|
|
|
|
`))}throw e.error?new Error(S(e.error)):(console.log(JSON.stringify(e)),new Error("Invalid response format"))},buildUrl:(e,t,n)=>h(e,`v1beta/models/${t}:generateContent?key=${n}`),requiresUrlApiKey:!0}},q={anthropic:{defaultModel:"claude-sonnet-5-5",defaultBaseUrl:"https://api.anthropic.com",authKey:"ANTHROPIC_API_KEY",keyName:"anthropic",authStyle:"anthropic",apiStyle:"anthropic"},claude:{defaultModel:"claude-sonnet-5-5",defaultBaseUrl:"https://api.anthropic.com",authKey:"ANTHROPIC_API_KEY",keyName:"claude",authStyle:"anthropic",apiStyle:"anthropic"},openai:{defaultModel:"gpt-4o-mini",defaultBaseUrl:"https://api.openai.com",authKey:"OPENAI_API_KEY",authStyle:"bearer",apiStyle:"openai"},ollama:{defaultModel:"qwen2.5-coder:latest",defaultBaseUrl:"http://localhost:11434",authStyle:"none",apiStyle:"ollama"},ollamacloud:{defaultModel:"gpt-oss:120b",defaultBaseUrl:"https://ollama.com",authKey:"OLLAMA_API_KEY",keyName:"ollamacloud",authStyle:"bearer",apiStyle:"ollama"},zen:{defaultModel:"big-pickle",defaultBaseUrl:"https://opencode.ai/zen",authKey:"OPENCODE_API_KEY",keyName:"zen",authStyle:"bearer",apiStyle:"openai",hardcodedModels:["big-pickle","glm-5","kimi-k2.5"]},gemini:{defaultModel:"gemini-2.5-flash",defaultBaseUrl:"https://generativelanguage.googleapis.com",authKey:"GEMINI_API_KEY",authStyle:"none",apiStyle:"gemini",hardcodedModels:["gemini-2.0-flash","gemini-2.0-flash-lite","gemini-2.5-pro","gemini-2.5-flash","gemini-2.5-flash-lite"]},mistral:{defaultModel:"codestral-latest",defaultBaseUrl:"https://api.mistral.ai",authKey:"MISTRAL_API_KEY",authStyle:"bearer",apiStyle:"openai"},xai:{defaultModel:"grok-beta",defaultBaseUrl:"https://api.x.ai",authKey:"XAI_API_KEY",authStyle:"bearer",apiStyle:"openai",hardcodedModels:["grok-2","grok-beta"]},lmstudio:{defaultModel:"local-model",defaultBaseUrl:"http://127.0.0.1:1234",authStyle:"none",apiStyle:"openai"},deepseek:{defaultModel:"deepseek-coder",defaultBaseUrl:"https://api.deepseek.com",authKey:"DEEPSEEK_API_KEY",authStyle:"bearer",apiStyle:"openai",hardcodedModels:["deepseek-coder","deepseek-chat"]},openrouter:{defaultModel:"openai/gpt-4o-mini",defaultBaseUrl:"https://openrouter.ai/api",authKey:"OPENROUTER_API_KEY",authStyle:"bearer",apiStyle:"openai"},groq:{defaultModel:"llama-3.3-70b-versatile",defaultBaseUrl:"https://api.groq.com/openai",authKey:"GROQ_API_KEY",authStyle:"bearer",apiStyle:"openai"}};function D(e){return q[e]}function Q(){return Object.keys(q)}function be(e){let t=D(e);if(!t)throw new Error(`Unknown provider: ${e}`);if(e==="mistral")return $e(t);switch(t.apiStyle){case"openai":case"anthropic":return Le(t);case"ollama":return Ge(t);case"gemini":return"";default:return""}}function X(){return r.think==="false"||r.think==="0"}function Y(){return r.think!==""&&!X()}function We(e,t,n){let o=e;return r.think!==""&&n==="openai"&&(X()?(o+=' Answers directly and concisely, without showing any thinking steps or internal reasoning. Never include phrases like "Let me think".',o+=" /no_think"):o="Think step by step and explain the reasoning process, When answering, first output your reasoning inside <think> and </think> tags, then give the final answer."+o),t?o:r.prompt+Ye()+o}function Ye(){return`
|
|
|
|
|
.Translate the code into `+r.language+` programming language
|
|
|
|
|
`}function ze(e,t,n,o){let i=r.model||e.defaultModel,a=We(n,o,e.apiStyle),s=me(e);if(t.requiresUrlApiKey&&s?.[1]&&e.authKey)return`Cannot read ~/.r2ai.${z(e.authKey)}-key`;let l=t.buildPayload(i,a),u=ye(e,s?.[0]||null);e.apiStyle==="ollama"&&u.push("Accept: application/x-ndjson");let v=ge(u),c=t.buildUrl(he(e),i,s?.[0]||void 0);try{return t.parseResponse(fe(c,v,JSON.stringify(l)))}catch(d){return"ERROR: "+d.message}}function ke(e,t){let n=D(r.api);return n?ze(n,Je[n.apiStyle],e,t):`Unknown value for 'decai -e api'. Available: ${Q().join(", ")}`}function Ve(){return Object.fromEntries(Object.entries(q).filter(([,e])=>e.authKey).map(([e,t])=>[e,t.authKey]))}function K(e,t){let n=r2.cmd("'%"+t).trim();if(!n.includes("=")&&n!=="")return[n.trim(),null,"env"];let o=e.toLowerCase(),i=N;if(_(i)){let s=r2.cmd("'cat "+i),l=le(s);if(o in l)return[l[o],null,"txt"]}let a="~/.r2ai."+o+"-key";if(_(a)){let s=r2.cmd("'cat "+a);return s===""?[null,"Cannot read "+a,"no"]:[s.trim(),null,"file"]}return[null,"Not available","nope"]}function xe(){H(w,N),r2.cmd("'ed "+N)}function Z(){Object.entries(Ve()).forEach(([e,t])=>{let n=K(e,t)[2];console.log(n," ",e)})}function ve(e){let t=D(e);if(!t){console.error(`Unknown provider: ${e}`);return}try{let n=be(e);n&&console.log(n),t.hardcodedModels&&t.hardcodedModels.forEach(o=>console.log(o)),e==="mistral"&&console.log("ministral-8b-latest"),!n&&!t.hardcodedModels&&console.log(t.defaultModel)}catch(n){let o=n;console.error(`Error listing models for ${e}:`,o.message),console.log(t.defaultModel)}}var ee=!1;function Qe(e){return e==="true"||e==="1"}function P(e){let t=r;return{get:()=>t[e],set:n=>{t[e]=Qe(n)}}}function R(e){let t=r;return{get:()=>t[e],set:n=>{t[e]=n}}}function Xe(e){let t=e.trim();return t==="chat"?"chat":t==="generate"?"generate":null}var Ee={pipeline:{get:()=>r.pipeline,set:e=>{r.pipeline=e;try{r.decopipe=JSON.parse(r2.cmd("cat "+e))}catch(t){console.error(t)}}},model:{get:()=>r.model,set:e=>{e==="?"?ve(r.api):r.model=e.trim()}},deterministic:P("deterministic"),files:P("useFiles"),think:{get:()=>r.think||"false",set:e=>{r.think=e}},apitype:{get:()=>r.apitype,set:e=>{let t=Xe(e);t?r.apitype=t:console.error("Invalid apitype. Use chat or generate.")}},debug:P("debug"),http:{get:()=>r.http,set:e=>{let t=e.trim();t==="auto"||t==="r2"||t==="curl"?r.http=t:console.error("Invalid http backend. Use auto, r2 or curl.")}},timeout:{get:()=>r.timeout,set:e=>{r.timeout=Math.max(0,parseInt(e,10)||0)}},api:{get:()=>r.api,set:e=>{e==="?"?console.error(Q().join(`
|
|
|
|
|
`)):r.api=e}},lang:R("language"),hlang:R("humanLanguage"),cache:P("cache"),cmds:R("commands"),tts:P("tts"),yolo:P("yolo"),prompt:R("prompt"),ctxfile:R("contextFile"),baseurl:R("baseurl"),headers:{get:()=>ue(r.extraHeaders),set:e=>{r.extraHeaders=W(e)}},maxtokens:{get:()=>r.maxInputTokens,set:e=>{r.maxInputTokens=parseInt(e,10)||-1}}};function Ze(){let e={host:r.host,port:r.port,lastOutput:r.lastOutput};Object.assign(r,E,e),r.decopipe={...E.decopipe},r.extraHeaders=[...E.extraHeaders]}function et(e){let t=e.trim();return!t||t.startsWith("#")?null:t.startsWith("decai -e ")?t.slice(9).trim():t}function x(e){let t=e.indexOf("="),n=t===-1?e:e.slice(0,t),o=t===-1?void 0:e.slice(t+1),i=Ee[n];if(!i){console.error("Unknown config key");return}typeof o<"u"?i.set(o):console.log(i.get())}function we(){Object.entries(Ee).forEach(([e,t])=>{let n=t.get();console.log("decai -e "+e+"="+n)})}function Ae(){if(Ze(),!_(U))return;let e=r2.call("cat "+U);for(let t of e.split(/\r?\n/)){let n=et(t);n&&n[0]!="#"&&x(n)}}function Oe(){ee||(Ae(),ee=!0)}function Se(){H(w,U),r2.cmd("'ed "+U),Ae(),ee=!0}function p(e,t,n=!1){let o=(t||"").replace(/`/g,""),i=e.replace(/'/g,"");if(r.api==="r2"||r.api==="r2ai"){let s=re(".pdc.txt");se(s,o);let l=i.startsWith("-")?i:["-i",s,i].join(" "),u=r.baseurl||r.host+":"+r.port,v=h(u,"cmd/"+encodeURIComponent(l)),c=O(v,[]);return c.error?`Error: ${c.error}`:c.result||JSON.stringify(c)||"Cannot curl, use r2ai-server or r2ai -w"}if(i.startsWith("-"))return"";let a=i+`:
|
|
|
|
|
`+o;return r.maxInputTokens>0&&a.length>r.maxInputTokens&&(a=a.slice(0,r.maxInputTokens)),ke(a,n)}function Re(e){let t=r2.cmd("e scr.color");r2.cmd("e scr.color=0");try{return e()}finally{r2.cmd("e scr.color="+t)}}function Pe(){let e="",t=n=>e+=" "+b+" "+n+`
|
|
|
|
|
`;e+="Usage: "+b+` (-h) ...
|
|
|
|
|
`,e+="Version: "+te+`
|
|
|
|
|
`,t("-a [query] - solve query with auto mode"),t("-b [url] - set base URL (alias for decai -e baseurl)"),t("-d [f1 ..] - decompile given functions"),t("-dd [..] - same as above, but ignoring cache"),t("-dD [query] - decompile current function with given extra query"),t("-dr - decompile function and its called ones (recursive)"),t("-e - display and change eval config vars"),t("-E - edit and run decai.txt"),t("-h - show this help"),t("-H - help setting up r2ai"),t("-i [f] [q] - include given file and query"),t("-k - list API key status"),t("-K - edit apikeys.txt"),t("-m [model] - use -m? or -e model=? to list the available models"),t("-n - suggest better function name"),t("-p [provider] - same as decai -e api (will be provider)"),t("-q [text] - query language model with given text"),t("-Q [text] - query on top of the last output"),t("-r [prompt] - change role prompt (same as: decai -e prompt)"),t("-R - reset role prompt to default prompt"),t("-s - function signature"),t("-v - show local variables"),t("-V - find vulnerabilities"),t("-x[*] - eXplain current function (-x* for r2 script)"),r2.log(e.trim())}function j(e,t,n,o){if(n){let s=r2.cmd("anos").trim();if(s.length>0)return s}let i="";if(o){let s=r2.cmd("s");i+=`## Context functions:
|
|
|
|
|
`;let l=r2.cmdAt("axff~^C[2]~$$",s);for(let u of l.split(/\n/g))i+=r2.cmd("pdc@"+u);r2.cmd("s "+s)}let a=t?" "+e:"";try{let s=e.slice(2).trim(),l="";r.contextFile!==""&&r2.cmd2("test -f "+r.contextFile).value===0&&(l+=`## Context:
|
|
|
|
|
[START]
|
|
|
|
|
`+r2.cmd("cat "+o.contextFile)+`
|
|
|
|
|
`+r2.cmd("cat "+r.contextFile)+`
|
|
|
|
|
[END]
|
|
|
|
|
`);let{body:c,count:k}=Ue(()=>{let d=`## Before:
|
|
|
|
|
`,A=0;for(let v of o.commands.split(",")){if(v.trim()==="")continue;let M=t||s.trim().length===0?v:v+"@@= "+s,N=r2.cmd(M);N.length>5&&(d+="Output of "+v+`:
|
|
|
|
|
`);let{body:u,count:v}=Re(()=>{let d=`## Before:
|
|
|
|
|
`,y=0;for(let g of r.commands.split(",")){if(g.trim()==="")continue;let C=t||s.trim().length===0?g:g+"@@= "+s,I=r2.cmd(C);I.length>5&&(d+="Output of "+g+`:
|
|
|
|
|
[START]
|
|
|
|
|
`+N+`
|
|
|
|
|
`+I+`
|
|
|
|
|
[END]
|
|
|
|
|
`,A++)}return d+=`## After:
|
|
|
|
|
`,{body:d,count:A}});if(k===0){console.error("Nothing to do.");return}let u="";if(o.decopipe.use){let d=o.model;try{let A=o.decopipe[o.decopipe.default],v=l+c;for(let M of A.pipeline){M.model&&(o.model=M.model);let N=M.query+". "+A.globalQuery;u=p(N,v,!0),o.debug&&console.log(`QUERY
|
|
|
|
|
`,N,`
|
|
|
|
|
`,y++)}return d+=`## After:
|
|
|
|
|
`,{body:d,count:y}});if(v===0){console.error("Nothing to do.");return}let c="";if(r.decopipe.use){let d=r.model;try{let y=r.decopipe[r.decopipe.default],g=l+u;for(let C of y.pipeline){C.model&&(r.model=C.model);let I=C.query+". "+y.globalQuery;c=p(I,g,!0),r.debug&&console.log(`QUERY
|
|
|
|
|
`,I,`
|
|
|
|
|
INPUT
|
|
|
|
|
`,v,`
|
|
|
|
|
`,g,`
|
|
|
|
|
OUTPUT
|
|
|
|
|
`,u),v=u}u=v}finally{o.model=d}}else{let d=a;l+=c+i,u=p(d,l,!1),o.lastOutput=u}return n&&u.length>1&&r2.call("ano=base64:"+z(u)),u.startsWith("```")&&(u=u.replace(/```.*\n/,"").replace(/```$/,"")),u.trim()}catch(s){let l=s;console.error(l,l.stack);return}}function rt(){let e=Ue(()=>"[START]"+o.commands.split(",").map(r=>r2.cmd(r)).join(`
|
|
|
|
|
`)+"[END]"),n=p("Analyze function calls, references, comments and strings, loops and ignore registers and memory accesses. Explain the purpose of this function in a single short sentence. /no_think Do not introduce or argue the response, translation of the explanation in "+o.humanLanguage,e,!0).trim().split(/\n/g);return n[n.length-1].trim()}function it(){let e=o.language,t=r2.cmd("afv;pdc");o.language="C";let n="'afs "+p("analyze the uses of the arguments and return value to infer the signature, identify which is the correct type for the return. Do NOT print the function body, ONLY output the function signature, like if it was going to be used in a C header",t,!1),r=n.indexOf("{");return r!==-1&&(n=n.substring(0,r)),o.language=e,n}function at(e,t){let n=[];for(;;){let r=Y.auto;if(n.length>0){r+=`## Command Results
|
|
|
|
|
`,c),g=c}c=g}finally{r.model=d}}else{let d=a;l+=u+i,c=p(d,l,!1),r.lastOutput=c}return n&&c.length>1&&r2.call("ano=base64:"+$(c)),c.startsWith("```")&&(c=c.replace(/```.*\n/,"").replace(/```$/,"")),c.trim()}catch(s){let l=s;console.error(l,l.stack);return}}function tt(){let e=Re(()=>"[START]"+r.commands.split(",").map(o=>r2.cmd(o)).join(`
|
|
|
|
|
`)+"[END]"),n=p("Analyze function calls, references, comments and strings, loops and ignore registers and memory accesses. Explain the purpose of this function in a single short sentence. /no_think Do not introduce or argue the response, translation of the explanation in "+r.humanLanguage,e,!0).trim().split(/\n/g);return n[n.length-1].trim()}function nt(){let e=r.language,t=r2.cmd("afv;pdc");r.language="C";let n="'afs "+p("analyze the uses of the arguments and return value to infer the signature, identify which is the correct type for the return. Do NOT print the function body, ONLY output the function signature, like if it was going to be used in a C header",t,!1),o=n.indexOf("{");return o!==-1&&(n=n.substring(0,o)),r.language=e,n}function rt(e,t){let n=[];for(;;){let o=L.auto;if(n.length>0){o+=`## Command Results
|
|
|
|
|
|
|
|
|
|
`;for(let a of n){let s=JSON.parse(a);r+="### "+s.command+"\n\n```\n"+s.response+"\n```\n"}}r+=`
|
|
|
|
|
`;for(let a of n){let s=JSON.parse(a);o+="### "+s.command+"\n\n```\n"+s.response+"\n```\n"}}o+=`
|
|
|
|
|
|
|
|
|
|
## User Prompt
|
|
|
|
|
|
|
|
|
|
`+e,o.debug&&console.log(`#### input
|
|
|
|
|
`,r,`
|
|
|
|
|
#### /input`),console.log("Thinking...");let i=p("",r,!0);o.debug&&console.log(`#### output
|
|
|
|
|
`+e,r.debug&&console.log(`#### input
|
|
|
|
|
`,o,`
|
|
|
|
|
#### /input`),console.log("Thinking...");let i=p("",o,!0);r.debug&&console.log(`#### output
|
|
|
|
|
`,i,`
|
|
|
|
|
#### /output`);try{let a=JSON.parse(ce(le(E(i))));if(a.action==="r2cmd"||a.action==="response"||a.action===a.command){let s=a.command||"";a.reason&&(console.log("[r2cmd] Reasoning: "+a.reason),o.tts&&(r2.syscmd("pkill say"),r2.syscmd("say -v Alex -r 250 '"+a.reason.replace(/'/g,"")+"' &"))),console.log("[r2cmd] Action: "+a.description),console.log("[r2cmd] Command: "+s);let l=s;o.yolo||(l=st(s,t)),console.log("[r2cmd] Running: "+l);let c=r2.cmd2(l),k=c.logs?c.logs.map(A=>A.type+": "+A.message).join(`
|
|
|
|
|
`):"",u=(c.res+k).trim();console.log(u);let d=se(u);o.debug&&console.log(`<r2output>
|
|
|
|
|
#### /output`);try{let a=JSON.parse(ae(ie(k(i))));if(a.action==="r2cmd"||a.action==="response"||a.action===a.command){let s=a.command||"";a.reason&&(console.log("[r2cmd] Reasoning: "+a.reason),r.tts&&(r2.syscmd("pkill say"),r2.syscmd("say -v Alex -r 250 '"+a.reason.replace(/'/g,"")+"' &"))),console.log("[r2cmd] Action: "+a.description),console.log("[r2cmd] Command: "+s);let l=s;r.yolo||(l=ot(s,t)),console.log("[r2cmd] Running: "+l);let u=r2.cmd2(l),v=u.logs?u.logs.map(y=>y.type+": "+y.message).join(`
|
|
|
|
|
`):"",c=(u.res+v).trim();console.log(c);let d=oe(c);r.debug&&console.log(`<r2output>
|
|
|
|
|
`,d,`
|
|
|
|
|
<(r2output>`),n.push(JSON.stringify({action:"response",command:l,description:a.description,response:d}))}else if(a.action==="reply"){console.log(`Done
|
|
|
|
|
`,a.response);break}else{console.log(`Unknown response
|
|
|
|
|
`,JSON.stringify(i));break}}catch(a){let s=i.indexOf('response": "');if(s!==-1){let l=i.slice(s+12).replace(/\\n/g,`
|
|
|
|
|
`).replace(/\\/g,"");console.log(l)}else console.log(i),console.error(a);break}}}function st(e,t){for(;;){let n=r2.cmd("'?ie Tweak command? ('?' for help)").trim();if(n==="q!"){console.error("Break!");break}if(n==="?"){lt();continue}else if(n.startsWith(":")){console.log(r2.cmd(n.slice(1)));continue}else if(n.startsWith("-e")){t(n);continue}else{if(n==="!")return"?e do NOT execute '"+e+"' again, continue without it";if(n.startsWith("!")){console.log(r2.syscmd(n.slice(1)));continue}else{if(n==="q")return"?e All data collected!. Do not call more commands, reply the solutions";if(n){let r=n.indexOf("#");return r!==-1?n.slice(0,r).trim():n}else return e}}}return e}function lt(){console.log(" '!' do not run this command"),console.log(" '!c' run system command"),console.log(" 'q' to quit auto and try to solve"),console.log(" 'q!' quit auto without solving"),console.log(" 'c # C' use given command with comment"),console.log(" ':c' run r2 command without feeding auto"),console.log(" '-e' set decai configuration variables")}function ct(e){return e.slice(2).trim()}function $(){return r2.cmd("afi.").trim().length>0}var J="Cannot find function at current offset";function _e(e,t){if(e===""||!e.startsWith("-")){Re();return}let n="",r=e[1],i=ct(e);switch(r){case"H":console.log(Y.decai);break;case"a":at(i,t);break;case"m":{i==="="?O("model="):i?O("model="+i):O("model");break}case"n":case"f":{if(!$()){n=J;break}n=r2.cmd("axff~$[3]");let a=r2.cmd("fd.").trim().split(/\n/).filter(s=>!s.startsWith("secti")).join(",");n=p("give me a better name for this function. the output must be: 'afn NEWNAME'. do not include the function code, only the afn line. consider: "+a,n,!1).trim(),n+=" @ "+r2.cmd("?v $FB").trim();break}case"v":{if(!$()){n=J;break}n=r2.cmd("afv;pdc"),n=p("guess a better name and type for each local variable and function argument taking using. output an r2 script using afvn and afvt commands",n,!1);break}case"i":{let a=i.split(/\s+/).filter(Boolean);if(a.length>=2){let s=a[0],l=a.slice(1).join(" "),c=r2.cmd("cat "+s);console.log(p(l,c,!0))}else console.log("Use: decai -i [file] [query ...]");break}case"p":{i?O("api="+i):oe();break}case"r":{i?o.prompt=i:console.log(o.prompt);break}case"R":o.prompt=D;break;case"s":if(!$()){n=J;break}n=it();break;case"V":n=p("find vulnerabilities, dont show the code, only show the response, provide a sample exploit",o.lastOutput,!1);break;case"K":we();break;case"E":Ie();break;case"k":oe();break;case"b":{i?O("baseurl="+i):console.log(o.baseurl);break}case"e":{i?O(i):Se();break}case"q":try{n=p(i,null,!0)}catch(a){let s=a;console.error(s,s.stack)}break;case"Q":n=p(i,o.lastOutput,!1);break;case"x":if(!$()){n=J;break}n=rt(),(e[2]==="*"||e[2]==="r")&&(n="'CC "+n);break;case"d":e[2]==="r"?n=G(e.slice(2),!0,o.cache,!0)||"":e[2]==="d"?n=G(e,!1,!1,!1)||"":e[2]==="D"?n=G(e,!0,!1,!1)||"":n=G(e,!1,o.cache,!1)||"";break;default:Re();break}return n||void 0}function Me(e){Ce();let t=_e(e,Me);return t&&r2.log(t),!0}function ut(){r2.unload("core",w),r2.plugin("core",function(){function e(t){if(t.startsWith(w)){let n=t.slice(w.length).trim();return Me(n)}return!1}return{name:w,license:"MIT",desc:"r2 decompiler based on r2ai",call:e}})}ut();
|
|
|
|
|
`).replace(/\\/g,"");console.log(l)}else console.log(i),console.error(a);break}}}function ot(e,t){for(;;){let n=r2.cmd("'?ie Tweak command? ('?' for help)").trim();if(n==="q!"){console.error("Break!");break}if(n==="?"){it();continue}else if(n.startsWith(":")){console.log(r2.cmd(n.slice(1)));continue}else if(n.startsWith("-e")){t(n);continue}else{if(n==="!")return"?e do NOT execute '"+e+"' again, continue without it";if(n.startsWith("!")){console.log(r2.syscmd(n.slice(1)));continue}else{if(n==="q")return"?e All data collected!. Do not call more commands, reply the solutions";if(n){let o=n.indexOf("#");return o!==-1?n.slice(0,o).trim():n}else return e}}}return e}function it(){console.log(" '!' do not run this command"),console.log(" '!c' run system command"),console.log(" 'q' to quit auto and try to solve"),console.log(" 'q!' quit auto without solving"),console.log(" 'c # C' use given command with comment"),console.log(" ':c' run r2 command without feeding auto"),console.log(" '-e' set decai configuration variables")}function at(e){return e.slice(2).trim()}function B(){return r2.cmd("afi.").trim().length>0}var F="Cannot find function at current offset";function Ce(e,t){if(e===""||!e.startsWith("-")){Pe();return}let n="",o=e[1],i=at(e);switch(o){case"H":console.log(L.decai);break;case"a":rt(i,t);break;case"m":{i==="="?x("model="):i?x("model="+i):x("model");break}case"n":case"f":{if(!B()){n=F;break}n=r2.cmd("axff~$[3]");let a=r2.cmd("fd.").trim().split(/\n/).filter(s=>!s.startsWith("secti")).join(",");n=p("give me a better name for this function. the output must be: 'afn NEWNAME'. do not include the function code, only the afn line. consider: "+a,n,!1).trim(),n+=" @ "+r2.cmd("?v $FB").trim();break}case"v":{if(!B()){n=F;break}n=r2.cmd("afv;pdc"),n=p("guess a better name and type for each local variable and function argument taking using. output an r2 script using afvn and afvt commands",n,!1);break}case"i":{let a=i.split(/\s+/).filter(Boolean);if(a.length>=2){let s=a[0],l=a.slice(1).join(" "),u=r2.cmd("cat "+s);console.log(p(l,u,!0))}else console.log("Use: decai -i [file] [query ...]");break}case"p":{i?x("api="+i):Z();break}case"r":{i?r.prompt=i:console.log(r.prompt);break}case"R":r.prompt=T;break;case"s":if(!B()){n=F;break}n=nt();break;case"V":n=p("find vulnerabilities, dont show the code, only show the response, provide a sample exploit",r.lastOutput,!1);break;case"K":xe();break;case"E":Se();break;case"k":Z();break;case"b":{i?x("baseurl="+i):console.log(r.baseurl);break}case"e":{i?x(i):we();break}case"q":try{n=p(i,null,!0)}catch(a){let s=a;console.error(s,s.stack)}break;case"Q":n=p(i,r.lastOutput,!1);break;case"x":if(!B()){n=F;break}n=tt(),(e[2]==="*"||e[2]==="r")&&(n="'CC "+n);break;case"d":e[2]==="r"?n=j(e.slice(2),!0,r.cache,!0)||"":e[2]==="d"?n=j(e,!1,!1,!1)||"":e[2]==="D"?n=j(e,!0,!1,!1)||"":n=j(e,!1,r.cache,!1)||"";break;default:Pe();break}return n||void 0}function Ie(e){Oe();let t=Ce(e,Ie);return t&&r2.log(t),!0}function st(){r2.unload("core",b),r2.plugin("core",function(){function e(t){if(t.startsWith(b)){let n=t.slice(b.length).trim();return Ie(n)}return!1}return{name:b,license:"MIT",desc:"r2 decompiler based on r2ai",call:e}})}st();
|