tg-agent 1.9.2 → 1.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.cn.md CHANGED
@@ -91,7 +91,7 @@ bot_token = "YOUR_BOT_TOKEN"
91
91
 
92
92
  - 直接发送图片、文档、音频、视频、语音或视频笔记给机器人,文件会保存到 `~/.tg-agent/uploads`,并自动附加到提示词中
93
93
  - 图片会作为多模态输入传给模型(若模型支持图像)
94
- - Agent 可使用 `send_photo` / `send_file` 工具把本地文件发回 Telegram(路径需在工作目录或 uploads 下)
94
+ - Agent 可使用 `send_photo` / `send_file` / `send_voice` 工具把本地文件发回 Telegram(路径需在工作目录或 uploads 下)
95
95
 
96
96
  ## 配置文件
97
97
 
package/README.md CHANGED
@@ -91,7 +91,7 @@ Send the following commands in Telegram:
91
91
 
92
92
  - Send images, documents, audio, video, voice, or video notes directly to the bot. Files are saved to `~/.tg-agent/uploads` and automatically attached to the prompt
93
93
  - Images are passed as multimodal input to the model (if the model supports images)
94
- - Agent can use `send_photo` / `send_file` tools to send local files back to Telegram (paths must be in workspace directory or uploads folder)
94
+ - Agent can use `send_photo` / `send_file` / `send_voice` tools to send local files back to Telegram (paths must be in workspace directory or uploads folder)
95
95
 
96
96
  ## Configuration
97
97
 
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- var I=(e,t)=>()=>(e&&(t=e(e=0)),t);import at from"node:fs/promises";import Ro from"node:os";import je from"node:path";import{randomUUID as Yt}from"node:crypto";function D(){return Date.now()}function W(e){return e.startsWith("~")?je.join(Ro.homedir(),e.slice(1)):e}async function C(e){await at.mkdir(e,{recursive:!0})}async function ye(e,t){let n=je.dirname(e),o=`${je.basename(e)}.${Yt()}.tmp`,r=je.join(n,o),i=JSON.stringify(t,null,2);await at.writeFile(r,i,"utf8"),await at.rename(r,e)}function oe(){return Yt().split("-")[0]}function ct(e,t){if(e.length<=t)return[e];let n=[],o=e;for(;o.length>t;){let r=o.slice(0,t),i=r.lastIndexOf(`
3
- `);i>t*.6&&(r=r.slice(0,i)),n.push(r),o=o.slice(r.length)}return o.length>0&&n.push(o),n}function Xt(){let e=new Map;return async function(n,o){let i=(e.get(n)??Promise.resolve()).then(o,o);e.set(n,i);try{return await i}finally{e.get(n)===i&&e.delete(n)}}}function Qt(e){let t=0,n=[],o=()=>{if(t>=e)return;let r=n.shift();r&&(t+=1,r())};return async function(i){await new Promise(c=>{n.push(c),o()});try{return await i()}finally{t=Math.max(0,t-1),o()}}}var J=I(()=>{"use strict"});import Zt from"node:fs";import Ae from"node:path";import*as Ue from"@iarna/toml";function nn(){let e=W(en);return Ae.join(e,To)}function N(e,t){let n=e[t];return n&&typeof n=="object"&&!Array.isArray(n)?n:{}}function R(e,t){return typeof e=="string"?e:typeof e=="number"||typeof e=="boolean"?String(e):t}function V(e,t){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"){let n=Number.parseInt(e,10);return Number.isNaN(n)?t:n}return t}function he(e,t){if(typeof e=="boolean")return e;if(typeof e=="string"){let n=e.trim().toLowerCase();if(n==="true"||n==="1"||n==="yes")return!0;if(n==="false"||n==="0"||n==="no")return!1}return t}function on(e){return Array.isArray(e)?e.map(t=>typeof t=="string"?t:String(t)).map(t=>t.trim()).filter(Boolean):typeof e=="string"?e.split(",").map(t=>t.trim()).filter(Boolean):[]}function Eo(e){return new Set(on(e))}function Do(e){let t=new Map;for(let[n,o]of Object.entries(e))typeof o=="string"&&o.trim()&&t.set(n,Ae.resolve(W(o.trim())));return t}function Me(){let e=nn();try{let t=Zt.readFileSync(e,"utf8"),n=Ue.parse(t);return{configPath:e,data:n,exists:!0}}catch{return{configPath:e,data:{},exists:!1}}}async function Ie(e,t){await C(Ae.dirname(e));let n=Ue.stringify(t);await Zt.promises.writeFile(e,n,"utf8")}function rn(){return{telegram:{bot_token:"",allowed_user_ids:[],parse_mode:""},model:{provider:"openai-codex",model:"gpt-5.2",openai_api_key:""},paths:{workspace_dir:"",session_dir:"~/.tg-agent/tg-sessions",restart_script_path:""},workspace_mappings:{},limits:{max_sessions:5,max_concurrent:5,max_history_messages:40,max_output_tokens:0},timeouts:{model_timeout_ms:6e4,model_timeout_stream_ms:3e5,fetch_timeout_ms:6e4},fetch:{max_bytes:2e5,proxy_url:""},proxy:{url:""},auth:{codex_home:"~/.codex"},logging:{agent_events:!0,agent_stream:!0},system:{prompt:tn},tls:{extra_ca_certs:"",reject_unauthorized:""},security_audit:{enabled:!1,model_provider:"",model_id:"",whitelist_patterns:[],confirm_timeout_ms:12e4},memory:{enabled:!0,model_provider:"",model_id:"",system_prompt:"",rag:{enabled:!0,embedding_model:"openai/text-embedding-3-small",embedding_base_url:"",embedding_api_key:"",similarity_threshold:.5,max_results:5}}}}function Le(e){return!!(e&&typeof e=="object"&&!Array.isArray(e))}function sn(e,t){let n=!1,o=(r,i)=>{for(let[c,u]of Object.entries(i)){if(!(c in r)){r[c]=u,n=!0;continue}let l=r[c];Le(l)&&Le(u)&&o(l,u)}};return Le(e)&&Le(t)&&o(e,t),n}function an(e){let t=N(e,"telegram");return R(t.bot_token,"").trim()}function cn(e,t){let n=N(e,"telegram");n.bot_token=t.trim(),e.telegram=n}function ln(e){let t=N(e,"telegram"),n=N(e,"model"),o=N(e,"paths"),r=N(e,"limits"),i=N(e,"timeouts"),c=N(e,"fetch"),u=N(e,"proxy"),l=N(e,"auth"),m=N(e,"logging"),s=N(e,"system"),a=N(e,"tls"),d=N(e,"workspace_mappings"),p=N(e,"security_audit"),h=N(e,"memory"),y=N(h,"rag"),w=R(o.workspace_dir,process.cwd()),x=R(o.session_dir,"~/.tg-agent/tg-sessions"),M=Do(d),S=R(a.reject_unauthorized,""),P=S===""?null:he(S,!0);return{telegramToken:R(t.bot_token,"").trim(),telegramAllowedUsers:Eo(t.allowed_user_ids),telegramParseMode:R(t.parse_mode,"").trim(),modelProvider:R(n.provider,"openai-codex").trim(),modelRef:R(n.model,"gpt-5.2").trim(),openaiApiKey:R(n.openai_api_key,"").trim(),sessionDir:W(x),agentDir:W(en),restartScriptPath:(()=>{let U=R(o.restart_script_path,"").trim();return U?Ae.resolve(W(U)):""})(),workspaceDir:Ae.resolve(W(w)),workspaceMappings:M,maxSessions:V(r.max_sessions,5),maxConcurrent:V(r.max_concurrent,5),maxHistoryMessages:V(r.max_history_messages,40),maxOutputTokens:V(r.max_output_tokens,0),fetchMaxBytes:V(c.max_bytes,2e5),fetchTimeoutMs:V(i.fetch_timeout_ms,6e4),modelTimeoutMs:V(i.model_timeout_ms,6e4),modelTimeoutStreamingMs:V(i.model_timeout_stream_ms,3e5),systemPrompt:R(s.prompt,tn),proxyUrl:R(u.url,"").trim(),fetchProxyUrl:R(c.proxy_url,"").trim(),codexHome:W(R(l.codex_home,"~/.codex")),logAgentEvents:he(m.agent_events,!0),logAgentStream:he(m.agent_stream,!0),tlsExtraCaCerts:R(a.extra_ca_certs,"").trim(),tlsRejectUnauthorized:P,audit:{enabled:he(p.enabled,!1),modelProvider:R(p.model_provider,"").trim(),modelId:R(p.model_id,"").trim(),whitelistPatterns:on(p.whitelist_patterns),confirmTimeoutMs:V(p.confirm_timeout_ms,6e4)},memory:{enabled:he(h.enabled,!0),modelProvider:R(h.model_provider,"").trim(),modelId:R(h.model_id,"").trim(),systemPrompt:R(h.system_prompt,"").trim(),rag:{enabled:he(y.enabled,!0),embeddingModel:R(y.embedding_model,"openai/text-embedding-3-small").trim(),embeddingBaseUrl:R(y.embedding_base_url,"").trim(),embeddingApiKey:R(y.embedding_api_key,"").trim(),similarityThreshold:V(y.similarity_threshold,.5),maxResults:V(y.max_results,5)}}}}function un(){let{data:e}=Me();return f=ln(e),f}function dn(){let e=[];if(f.telegramToken||e.push("telegram.bot_token"),e.length>0)throw new Error(`Missing config values: ${e.join(", ")} (edit ${nn()})`)}var en,To,tn,Oo,f,K=I(()=>{"use strict";J();en="~/.tg-agent",To="config.toml",tn=`You are running in user's personal computer or VPS, using telegram bot to interact with user.
2
+ var F=(e,t)=>()=>(e&&(t=e(e=0)),t);import at from"node:fs/promises";import Ro from"node:os";import je from"node:path";import{randomUUID as Qt}from"node:crypto";function O(){return Date.now()}function W(e){return e.startsWith("~")?je.join(Ro.homedir(),e.slice(1)):e}async function C(e){await at.mkdir(e,{recursive:!0})}async function ye(e,t){let n=je.dirname(e),r=`${je.basename(e)}.${Qt()}.tmp`,o=je.join(n,r),i=JSON.stringify(t,null,2);await at.writeFile(o,i,"utf8"),await at.rename(o,e)}function re(){return Qt().split("-")[0]}function ct(e,t){if(e.length<=t)return[e];let n=[],r=e;for(;r.length>t;){let o=r.slice(0,t),i=o.lastIndexOf(`
3
+ `);i>t*.6&&(o=o.slice(0,i)),n.push(o),r=r.slice(o.length)}return r.length>0&&n.push(r),n}function Zt(){let e=new Map;return async function(n,r){let i=(e.get(n)??Promise.resolve()).then(r,r);e.set(n,i);try{return await i}finally{e.get(n)===i&&e.delete(n)}}}function en(e){let t=0,n=[],r=()=>{if(t>=e)return;let o=n.shift();o&&(t+=1,o())};return async function(i){await new Promise(c=>{n.push(c),r()});try{return await i()}finally{t=Math.max(0,t-1),r()}}}var J=F(()=>{"use strict"});import tn from"node:fs";import Ae from"node:path";import*as Ue from"@iarna/toml";function rn(){let e=W(nn);return Ae.join(e,To)}function L(e,t){let n=e[t];return n&&typeof n=="object"&&!Array.isArray(n)?n:{}}function R(e,t){return typeof e=="string"?e:typeof e=="number"||typeof e=="boolean"?String(e):t}function G(e,t){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"){let n=Number.parseInt(e,10);return Number.isNaN(n)?t:n}return t}function he(e,t){if(typeof e=="boolean")return e;if(typeof e=="string"){let n=e.trim().toLowerCase();if(n==="true"||n==="1"||n==="yes")return!0;if(n==="false"||n==="0"||n==="no")return!1}return t}function sn(e){return Array.isArray(e)?e.map(t=>typeof t=="string"?t:String(t)).map(t=>t.trim()).filter(Boolean):typeof e=="string"?e.split(",").map(t=>t.trim()).filter(Boolean):[]}function Eo(e){return new Set(sn(e))}function Do(e){let t=new Map;for(let[n,r]of Object.entries(e))typeof r=="string"&&r.trim()&&t.set(n,Ae.resolve(W(r.trim())));return t}function Me(){let e=rn();try{let t=tn.readFileSync(e,"utf8"),n=Ue.parse(t);return{configPath:e,data:n,exists:!0}}catch{return{configPath:e,data:{},exists:!1}}}async function Ie(e,t){await C(Ae.dirname(e));let n=Ue.stringify(t);await tn.promises.writeFile(e,n,"utf8")}function an(){return{telegram:{bot_token:"",allowed_user_ids:[],parse_mode:""},model:{provider:"openai-codex",model:"gpt-5.2",openai_api_key:""},paths:{workspace_dir:"",session_dir:"~/.tg-agent/tg-sessions",restart_script_path:""},workspace_mappings:{},limits:{max_sessions:5,max_concurrent:5,max_history_messages:40,max_output_tokens:0},timeouts:{model_timeout_ms:6e4,model_timeout_stream_ms:3e5,fetch_timeout_ms:6e4},fetch:{max_bytes:2e5,proxy_url:""},proxy:{url:""},auth:{codex_home:"~/.codex"},logging:{agent_events:!0,agent_stream:!0},system:{prompt:on},tls:{extra_ca_certs:"",reject_unauthorized:""},security_audit:{enabled:!1,model_provider:"",model_id:"",whitelist_patterns:[],confirm_timeout_ms:12e4},memory:{enabled:!0,model_provider:"",model_id:"",system_prompt:"",rag:{enabled:!0,embedding_model:"openai/text-embedding-3-small",embedding_base_url:"",embedding_api_key:"",similarity_threshold:.5,max_results:5}}}}function Le(e){return!!(e&&typeof e=="object"&&!Array.isArray(e))}function cn(e,t){let n=!1,r=(o,i)=>{for(let[c,u]of Object.entries(i)){if(!(c in o)){o[c]=u,n=!0;continue}let l=o[c];Le(l)&&Le(u)&&r(l,u)}};return Le(e)&&Le(t)&&r(e,t),n}function ln(e){let t=L(e,"telegram");return R(t.bot_token,"").trim()}function un(e,t){let n=L(e,"telegram");n.bot_token=t.trim(),e.telegram=n}function dn(e){let t=L(e,"telegram"),n=L(e,"model"),r=L(e,"paths"),o=L(e,"limits"),i=L(e,"timeouts"),c=L(e,"fetch"),u=L(e,"proxy"),l=L(e,"auth"),m=L(e,"logging"),s=L(e,"system"),a=L(e,"tls"),d=L(e,"workspace_mappings"),f=L(e,"security_audit"),h=L(e,"memory"),y=L(h,"rag"),w=R(r.workspace_dir,process.cwd()),x=R(r.session_dir,"~/.tg-agent/tg-sessions"),M=Do(d),S=R(a.reject_unauthorized,""),_=S===""?null:he(S,!0);return{telegramToken:R(t.bot_token,"").trim(),telegramAllowedUsers:Eo(t.allowed_user_ids),telegramParseMode:R(t.parse_mode,"").trim(),modelProvider:R(n.provider,"openai-codex").trim(),modelRef:R(n.model,"gpt-5.2").trim(),openaiApiKey:R(n.openai_api_key,"").trim(),sessionDir:W(x),agentDir:W(nn),restartScriptPath:(()=>{let I=R(r.restart_script_path,"").trim();return I?Ae.resolve(W(I)):""})(),workspaceDir:Ae.resolve(W(w)),workspaceMappings:M,maxSessions:G(o.max_sessions,5),maxConcurrent:G(o.max_concurrent,5),maxHistoryMessages:G(o.max_history_messages,40),maxOutputTokens:G(o.max_output_tokens,0),fetchMaxBytes:G(c.max_bytes,2e5),fetchTimeoutMs:G(i.fetch_timeout_ms,6e4),modelTimeoutMs:G(i.model_timeout_ms,6e4),modelTimeoutStreamingMs:G(i.model_timeout_stream_ms,3e5),systemPrompt:R(s.prompt,on),proxyUrl:R(u.url,"").trim(),fetchProxyUrl:R(c.proxy_url,"").trim(),codexHome:W(R(l.codex_home,"~/.codex")),logAgentEvents:he(m.agent_events,!0),logAgentStream:he(m.agent_stream,!0),tlsExtraCaCerts:R(a.extra_ca_certs,"").trim(),tlsRejectUnauthorized:_,audit:{enabled:he(f.enabled,!1),modelProvider:R(f.model_provider,"").trim(),modelId:R(f.model_id,"").trim(),whitelistPatterns:sn(f.whitelist_patterns),confirmTimeoutMs:G(f.confirm_timeout_ms,6e4)},memory:{enabled:he(h.enabled,!0),modelProvider:R(h.model_provider,"").trim(),modelId:R(h.model_id,"").trim(),systemPrompt:R(h.system_prompt,"").trim(),rag:{enabled:he(y.enabled,!0),embeddingModel:R(y.embedding_model,"openai/text-embedding-3-small").trim(),embeddingBaseUrl:R(y.embedding_base_url,"").trim(),embeddingApiKey:R(y.embedding_api_key,"").trim(),similarityThreshold:G(y.similarity_threshold,.5),maxResults:G(y.max_results,5)}}}}function mn(){let{data:e}=Me();return p=dn(e),p}function pn(){let e=[];if(p.telegramToken||e.push("telegram.bot_token"),e.length>0)throw new Error(`Missing config values: ${e.join(", ")} (edit ${rn()})`)}var nn,To,on,Oo,p,K=F(()=>{"use strict";J();nn="~/.tg-agent",To="config.toml",on=`You are running in user's personal computer or VPS, using telegram bot to interact with user.
4
4
 
5
5
  Important behavioral rules:
6
6
  - Do NOT mention the name of your underlying framework, technical implementation, or any package names
@@ -9,23 +9,23 @@ Important behavioral rules:
9
9
  - Focus on helping with tasks rather than discussing your technical stack or architecture
10
10
  - Do not mention documentation paths or framework-specific resources unless directly relevant to the task
11
11
 
12
- Be concise and practical in all responses.`;({data:Oo}=Me()),f=ln(Oo)});import{createHash as No}from"node:crypto";import mn from"node:fs";import jo from"node:path";import{execSync as Lo}from"node:child_process";function Fo(){return jo.join(f.codexHome,Uo)}function zo(e){return`cli|${No("sha256").update(e).digest("hex").slice(0,16)}`}function Ko(){if(process.platform!=="darwin")return null;let e=f.codexHome,t=zo(e);try{let n=Lo(`security find-generic-password -s "${Io}" -a "${t}" -w`,{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}).trim(),o=JSON.parse(n),r=o.tokens,i=r?.access_token,c=r?.refresh_token;if(typeof i!="string"||!i||typeof c!="string"||!c)return null;let u=o.last_refresh,l=typeof u=="string"||typeof u=="number"?new Date(u).getTime():Date.now(),m=Number.isFinite(l)?l+3600*1e3:Date.now()+3600*1e3;return{accessToken:i,refreshToken:c,expiresAt:m,source:"keychain"}}catch{return null}}function Bo(){let e=Fo();try{let t=mn.readFileSync(e,"utf8"),o=JSON.parse(t).tokens,r=o?.access_token,i=o?.refresh_token;if(typeof r!="string"||!r||typeof i!="string"||!i)return null;let c=Date.now()+3600*1e3;try{c=mn.statSync(e).mtimeMs+3600*1e3}catch{}return{accessToken:r,refreshToken:i,expiresAt:c,source:"file"}}catch{return null}}function X(){return Ko()??Bo()}var Uo,Io,we=I(()=>{"use strict";K();Uo="auth.json",Io="Codex Auth"});function pn(e){let t=e.trim().toLowerCase();if(t==="openai-codex"||t==="codex"){let n=X();if(n)return{apiKey:n.accessToken,source:`codex:${n.source}`};throw new Error("No Codex OAuth credentials found. Run `codex login`.")}if(f.openaiApiKey)return{apiKey:f.openaiApiKey,source:"config.model.openai_api_key"};throw new Error(`No API key for provider: ${e}`)}function Wo(){return f.proxyUrl?{url:f.proxyUrl,source:"config.proxy.url"}:f.fetchProxyUrl?{url:f.fetchProxyUrl,source:"config.fetch.proxy_url"}:null}function fn(e){let t=e.toLowerCase();return t.startsWith("socks5://")||t.startsWith("socks4://")||t.startsWith("socks://")?"socks":t.startsWith("https://")?"https":"http"}function gn(){let e=Wo();return e?{url:e.url,kind:fn(e.url),source:e.source}:null}function yn(){let e=[{key:"config.fetch.proxy_url",value:f.fetchProxyUrl},{key:"config.proxy.url",value:f.proxyUrl}];for(let t of e){let n=t.value?.trim();if(!n)continue;let o=fn(n);if(o!=="socks")return{url:n,kind:o,source:t.key}}return null}var lt=I(()=>{"use strict";K();we()});import{ProxyAgent as Jo,setGlobalDispatcher as Ho}from"undici";function Fe(){if(hn)return ut;hn=!0;let e=yn();if(!e)return ut=null,null;let t=new Jo(e.url);return Ho(t),ut=e,e}var hn,ut,dt=I(()=>{"use strict";lt();hn=!1,ut=null});import qo from"node:fs";import Go from"node:fs/promises";import Vo from"node:path";import Yo from"node:readline";import{spawn as Xo}from"node:child_process";import*as bn from"@iarna/toml";function Sn(e){return Vo.join(e,"config.toml")}function ze(e){let t=Sn(e);try{let n=qo.readFileSync(t,"utf8");return kn(n)}catch{return[]}}async function ke(e){let t=Sn(e);try{let n=await Go.readFile(t,"utf8");return kn(n)}catch{return[]}}async function me(e,t={}){if(be)return be;let n=await ke(e);if(n.length===0)return be="","";let o=t.maxTools??Zo,r=t.maxChars??er,i=t.timeoutMs??4e3,c=t.maxBytes??vn,u=["MCP catalog (auto-discovered):","Use tool 'mcp' with server=<name> method=<tool> params=<object>."];for(let m of n){let s=await nr(m,{timeoutMs:i,maxBytes:c});if(u.push(`${m.name} (${m.type})`),s.length===0){u.push(" - tools unavailable");continue}let a=s.slice(0,o);for(let d of a){let p=d.description?`: ${d.description}`:"";u.push(` - ${d.name}${p}`)}s.length>a.length&&u.push(` - ...and ${s.length-a.length} more`)}let l=u.join(`
13
- `);return l.length>r&&(l=`${l.slice(0,r-20)}...
14
- (truncated)`),be=l,l}function Pe(){be&&(xn=!0)}function $n(){be=null,xn=!1,H.clear()}function pe(e){if(e.type==="http")return e.url?`url=${e.url}`:"url=(missing)";let t=e.args&&e.args.length>0?` ${e.args.join(" ")}`:"";return e.command?`command=${e.command}${t}`:"command=(missing)"}async function An(e,t=5e3){let n=Date.now();try{return await Ke(e,"tools/list",{},{timeoutMs:t}),{ok:!0,durationMs:Date.now()-n}}catch(o){let r=o instanceof Error?o.message:String(o);return{ok:!1,durationMs:Date.now()-n,error:r}}}async function Ke(e,t,n,o={}){let r=wn(o.timeoutMs??Qo,1e3,12e4),i=wn(o.maxBytes??vn,1024,5e6),c=new AbortController,u=()=>c.abort();o.signal?.addEventListener("abort",u,{once:!0});let l=setTimeout(()=>c.abort(),r);try{return e.type==="http"?(t!=="initialize"&&t!=="notifications/initialized"&&await sr(e,i,c.signal),await rr(e,t,n,i,c.signal)):await cr(e,t,n,i,c.signal)}finally{clearTimeout(l),o.signal?.removeEventListener("abort",u)}}function wn(e,t,n){return Number.isNaN(e)?t:Math.min(n,Math.max(t,e))}async function nr(e,t){try{let n=await Ke(e,"tools/list",{},t);return or(n.output)}catch(n){let o=n instanceof Error?n.message:String(n);return console.warn(`[tg-agent] mcp tools/list failed server=${e.name} error=${o}`),[]}}function or(e){let t;try{t=JSON.parse(e)}catch{return[]}if(!t||typeof t!="object")return[];let n=t,r=(n.result??n).tools??n.tools;if(!Array.isArray(r))return[];let i=[];for(let c of r){if(!c||typeof c!="object")continue;let u=c,l=typeof u.name=="string"?u.name:"";if(!l)continue;let m=typeof u.description=="string"?u.description:void 0,s=u.inputSchema;i.push({name:l,description:m,inputSchema:s})}return i}async function rr(e,t,n,o,r){if(!e.url)throw new Error("MCP server url is missing.");let i=Date.now(),c=await mt(e,t,n,o,r),u=Mn(c.parsed);if(u)throw new Error(u);let l=c.bodyText;return c.parsed&&(l=JSON.stringify(c.parsed,null,2)),{ok:c.statusCode>=200&&c.statusCode<300,output:l,durationMs:Date.now()-i,bytes:c.bytes,truncated:c.truncated,statusCode:c.statusCode,statusText:c.statusText,contentType:c.contentType}}async function mt(e,t,n,o,r){if(!e.url)throw new Error("MCP server url is missing.");let i=H.get(e.name),c={jsonrpc:"2.0",id:`tg-agent-${Date.now()}`,method:t,params:n??{}},u={"content-type":"application/json"};e.auth&&(u.authorization=e.auth.startsWith("Bearer ")?e.auth:`Bearer ${e.auth}`),i?.cookie&&(u.cookie=i.cookie),i?.sessionId&&(u["mcp-session-id"]=i.sessionId);let l=await fetch(e.url,{method:"POST",headers:u,body:JSON.stringify(c),signal:r});ir(e.name,l);let m=await lr(l,o,r),s;try{s=JSON.parse(m.text)}catch{s=void 0}return ar(e.name,s),{statusCode:l.status,statusText:l.statusText,contentType:l.headers.get("content-type"),bodyText:m.text,parsed:s,bytes:m.bytes,truncated:m.truncated}}function Mn(e){if(!e||typeof e!="object")return null;let t=e;if(t.error&&typeof t.error=="object"){let n=t.error;if(typeof n.message=="string")return n.message}return typeof t.error_description=="string"?t.error_description:typeof t.error=="string"?t.error:null}async function sr(e,t,n){let o=H.get(e.name);if(o?.initializedAt)return;if(o?.inFlight){await o.inFlight;return}let r=(async()=>{let i=await mt(e,"initialize",{protocolVersion:"2024-11-05",clientInfo:{name:"tg-agent",version:process.env.npm_package_version??"dev"},capabilities:{}},t,n),c=Mn(i.parsed);if(c){let m=c.toLowerCase();if(m.includes("method")&&m.includes("not"))return;throw new Error(c)}let u=new AbortController,l=setTimeout(()=>u.abort(),tr);try{await mt(e,"notifications/initialized",{},t,u.signal)}catch{}finally{clearTimeout(l)}})();H.set(e.name,{initializedAt:Date.now(),inFlight:r});try{await r;let i=H.get(e.name);H.set(e.name,{initializedAt:Date.now(),cookie:i?.cookie,sessionId:i?.sessionId})}catch(i){throw H.delete(e.name),i}}function ir(e,t){let o=H.get(e)??{initializedAt:0},r=t.headers.get("set-cookie"),i=t.headers.getSetCookie?.(),c=i&&i.length>0?i.join("; "):r;c&&H.set(e,{...o,cookie:c});let u=t.headers.get("mcp-session-id")??t.headers.get("x-mcp-session-id");u&&H.set(e,{...o,sessionId:u})}function ar(e,t){if(!t||typeof t!="object")return;let o=t.result;if(!o)return;let r=typeof o.sessionId=="string"&&o.sessionId||typeof o.session_id=="string"&&o.session_id;if(!r)return;let i=H.get(e)??{initializedAt:0};H.set(e,{...i,sessionId:r})}async function cr(e,t,n,o,r){if(!e.command)throw new Error("MCP server command is missing.");let i=Date.now(),c=Xo(e.command,e.args??[],{stdio:["pipe","pipe","pipe"]}),u=()=>{c.killed||c.kill("SIGTERM")};if(r.aborted)throw u(),new Error("MCP request aborted.");let l=new Map,m=!1,s="",a=new Error("MCP request aborted."),d=Yo.createInterface({input:c.stdout,terminal:!1});d.on("line",$=>{if($.length>o){m=!0;return}let b=null;try{b=JSON.parse($)}catch{return}let k=typeof b.id=="string"?b.id:typeof b.id=="number"?String(b.id):"";if(!k)return;let F=l.get(k);F&&(l.delete(k),F.resolve(b))}),c.stderr?.on("data",$=>{let b=$.toString();if(s.length+b.length>o){m=!0;return}s+=b});let p=()=>{for(let $ of l.values())$.reject(a);l.clear(),u()};r.addEventListener("abort",p,{once:!0});let h=$=>{let b=$===0?"MCP stdio exited.":s.trim()||"MCP stdio exited with error.";for(let k of l.values())k.reject(new Error(b));l.clear()};c.once("exit",$=>h($));let y=async($,b)=>{let k=`tg-agent-${Date.now()}-${Math.random().toString(16).slice(2,8)}`,F={jsonrpc:"2.0",id:k,method:$,params:b??{}};return await new Promise((ae,rt)=>{l.set(k,{resolve:ae,reject:rt}),c.stdin?.write(`${JSON.stringify(F)}
12
+ Be concise and practical in all responses.`;({data:Oo}=Me()),p=dn(Oo)});import{createHash as No}from"node:crypto";import fn from"node:fs";import jo from"node:path";import{execSync as Lo}from"node:child_process";function Fo(){return jo.join(p.codexHome,Uo)}function zo(e){return`cli|${No("sha256").update(e).digest("hex").slice(0,16)}`}function Ko(){if(process.platform!=="darwin")return null;let e=p.codexHome,t=zo(e);try{let n=Lo(`security find-generic-password -s "${Io}" -a "${t}" -w`,{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}).trim(),r=JSON.parse(n),o=r.tokens,i=o?.access_token,c=o?.refresh_token;if(typeof i!="string"||!i||typeof c!="string"||!c)return null;let u=r.last_refresh,l=typeof u=="string"||typeof u=="number"?new Date(u).getTime():Date.now(),m=Number.isFinite(l)?l+3600*1e3:Date.now()+3600*1e3;return{accessToken:i,refreshToken:c,expiresAt:m,source:"keychain"}}catch{return null}}function Bo(){let e=Fo();try{let t=fn.readFileSync(e,"utf8"),r=JSON.parse(t).tokens,o=r?.access_token,i=r?.refresh_token;if(typeof o!="string"||!o||typeof i!="string"||!i)return null;let c=Date.now()+3600*1e3;try{c=fn.statSync(e).mtimeMs+3600*1e3}catch{}return{accessToken:o,refreshToken:i,expiresAt:c,source:"file"}}catch{return null}}function Q(){return Ko()??Bo()}var Uo,Io,we=F(()=>{"use strict";K();Uo="auth.json",Io="Codex Auth"});function gn(e){let t=e.trim().toLowerCase();if(t==="openai-codex"||t==="codex"){let n=Q();if(n)return{apiKey:n.accessToken,source:`codex:${n.source}`};throw new Error("No Codex OAuth credentials found. Run `codex login`.")}if(p.openaiApiKey)return{apiKey:p.openaiApiKey,source:"config.model.openai_api_key"};throw new Error(`No API key for provider: ${e}`)}function Wo(){return p.proxyUrl?{url:p.proxyUrl,source:"config.proxy.url"}:p.fetchProxyUrl?{url:p.fetchProxyUrl,source:"config.fetch.proxy_url"}:null}function yn(e){let t=e.toLowerCase();return t.startsWith("socks5://")||t.startsWith("socks4://")||t.startsWith("socks://")?"socks":t.startsWith("https://")?"https":"http"}function hn(){let e=Wo();return e?{url:e.url,kind:yn(e.url),source:e.source}:null}function wn(){let e=[{key:"config.fetch.proxy_url",value:p.fetchProxyUrl},{key:"config.proxy.url",value:p.proxyUrl}];for(let t of e){let n=t.value?.trim();if(!n)continue;let r=yn(n);if(r!=="socks")return{url:n,kind:r,source:t.key}}return null}var lt=F(()=>{"use strict";K();we()});import{ProxyAgent as Jo,setGlobalDispatcher as Ho}from"undici";function Fe(){if(bn)return ut;bn=!0;let e=wn();if(!e)return ut=null,null;let t=new Jo(e.url);return Ho(t),ut=e,e}var bn,ut,dt=F(()=>{"use strict";lt();bn=!1,ut=null});import qo from"node:fs";import Vo from"node:fs/promises";import Go from"node:path";import Yo from"node:readline";import{spawn as Xo}from"node:child_process";import*as xn from"@iarna/toml";function An(e){return Go.join(e,"config.toml")}function ze(e){let t=An(e);try{let n=qo.readFileSync(t,"utf8");return _n(n)}catch{return[]}}async function ke(e){let t=An(e);try{let n=await Vo.readFile(t,"utf8");return _n(n)}catch{return[]}}async function me(e,t={}){if(be)return be;let n=await ke(e);if(n.length===0)return be="","";let r=t.maxTools??Zo,o=t.maxChars??er,i=t.timeoutMs??4e3,c=t.maxBytes??Sn,u=["MCP catalog (auto-discovered):","Use tool 'mcp' with server=<name> method=<tool> params=<object>."];for(let m of n){let s=await nr(m,{timeoutMs:i,maxBytes:c});if(u.push(`${m.name} (${m.type})`),s.length===0){u.push(" - tools unavailable");continue}let a=s.slice(0,r);for(let d of a){let f=d.description?`: ${d.description}`:"";u.push(` - ${d.name}${f}`)}s.length>a.length&&u.push(` - ...and ${s.length-a.length} more`)}let l=u.join(`
13
+ `);return l.length>o&&(l=`${l.slice(0,o-20)}...
14
+ (truncated)`),be=l,l}function Pe(){be&&($n=!0)}function Mn(){be=null,$n=!1,H.clear()}function pe(e){if(e.type==="http")return e.url?`url=${e.url}`:"url=(missing)";let t=e.args&&e.args.length>0?` ${e.args.join(" ")}`:"";return e.command?`command=${e.command}${t}`:"command=(missing)"}async function kn(e,t=5e3){let n=Date.now();try{return await Ke(e,"tools/list",{},{timeoutMs:t}),{ok:!0,durationMs:Date.now()-n}}catch(r){let o=r instanceof Error?r.message:String(r);return{ok:!1,durationMs:Date.now()-n,error:o}}}async function Ke(e,t,n,r={}){let o=vn(r.timeoutMs??Qo,1e3,12e4),i=vn(r.maxBytes??Sn,1024,5e6),c=new AbortController,u=()=>c.abort();r.signal?.addEventListener("abort",u,{once:!0});let l=setTimeout(()=>c.abort(),o);try{return e.type==="http"?(t!=="initialize"&&t!=="notifications/initialized"&&await sr(e,i,c.signal),await rr(e,t,n,i,c.signal)):await cr(e,t,n,i,c.signal)}finally{clearTimeout(l),r.signal?.removeEventListener("abort",u)}}function vn(e,t,n){return Number.isNaN(e)?t:Math.min(n,Math.max(t,e))}async function nr(e,t){try{let n=await Ke(e,"tools/list",{},t);return or(n.output)}catch(n){let r=n instanceof Error?n.message:String(n);return console.warn(`[tg-agent] mcp tools/list failed server=${e.name} error=${r}`),[]}}function or(e){let t;try{t=JSON.parse(e)}catch{return[]}if(!t||typeof t!="object")return[];let n=t,o=(n.result??n).tools??n.tools;if(!Array.isArray(o))return[];let i=[];for(let c of o){if(!c||typeof c!="object")continue;let u=c,l=typeof u.name=="string"?u.name:"";if(!l)continue;let m=typeof u.description=="string"?u.description:void 0,s=u.inputSchema;i.push({name:l,description:m,inputSchema:s})}return i}async function rr(e,t,n,r,o){if(!e.url)throw new Error("MCP server url is missing.");let i=Date.now(),c=await mt(e,t,n,r,o),u=Pn(c.parsed);if(u)throw new Error(u);let l=c.bodyText;return c.parsed&&(l=JSON.stringify(c.parsed,null,2)),{ok:c.statusCode>=200&&c.statusCode<300,output:l,durationMs:Date.now()-i,bytes:c.bytes,truncated:c.truncated,statusCode:c.statusCode,statusText:c.statusText,contentType:c.contentType}}async function mt(e,t,n,r,o){if(!e.url)throw new Error("MCP server url is missing.");let i=H.get(e.name),c={jsonrpc:"2.0",id:`tg-agent-${Date.now()}`,method:t,params:n??{}},u={"content-type":"application/json"};e.auth&&(u.authorization=e.auth.startsWith("Bearer ")?e.auth:`Bearer ${e.auth}`),i?.cookie&&(u.cookie=i.cookie),i?.sessionId&&(u["mcp-session-id"]=i.sessionId);let l=await fetch(e.url,{method:"POST",headers:u,body:JSON.stringify(c),signal:o});ir(e.name,l);let m=await lr(l,r,o),s;try{s=JSON.parse(m.text)}catch{s=void 0}return ar(e.name,s),{statusCode:l.status,statusText:l.statusText,contentType:l.headers.get("content-type"),bodyText:m.text,parsed:s,bytes:m.bytes,truncated:m.truncated}}function Pn(e){if(!e||typeof e!="object")return null;let t=e;if(t.error&&typeof t.error=="object"){let n=t.error;if(typeof n.message=="string")return n.message}return typeof t.error_description=="string"?t.error_description:typeof t.error=="string"?t.error:null}async function sr(e,t,n){let r=H.get(e.name);if(r?.initializedAt)return;if(r?.inFlight){await r.inFlight;return}let o=(async()=>{let i=await mt(e,"initialize",{protocolVersion:"2024-11-05",clientInfo:{name:"tg-agent",version:process.env.npm_package_version??"dev"},capabilities:{}},t,n),c=Pn(i.parsed);if(c){let m=c.toLowerCase();if(m.includes("method")&&m.includes("not"))return;throw new Error(c)}let u=new AbortController,l=setTimeout(()=>u.abort(),tr);try{await mt(e,"notifications/initialized",{},t,u.signal)}catch{}finally{clearTimeout(l)}})();H.set(e.name,{initializedAt:Date.now(),inFlight:o});try{await o;let i=H.get(e.name);H.set(e.name,{initializedAt:Date.now(),cookie:i?.cookie,sessionId:i?.sessionId})}catch(i){throw H.delete(e.name),i}}function ir(e,t){let r=H.get(e)??{initializedAt:0},o=t.headers.get("set-cookie"),i=t.headers.getSetCookie?.(),c=i&&i.length>0?i.join("; "):o;c&&H.set(e,{...r,cookie:c});let u=t.headers.get("mcp-session-id")??t.headers.get("x-mcp-session-id");u&&H.set(e,{...r,sessionId:u})}function ar(e,t){if(!t||typeof t!="object")return;let r=t.result;if(!r)return;let o=typeof r.sessionId=="string"&&r.sessionId||typeof r.session_id=="string"&&r.session_id;if(!o)return;let i=H.get(e)??{initializedAt:0};H.set(e,{...i,sessionId:o})}async function cr(e,t,n,r,o){if(!e.command)throw new Error("MCP server command is missing.");let i=Date.now(),c=Xo(e.command,e.args??[],{stdio:["pipe","pipe","pipe"]}),u=()=>{c.killed||c.kill("SIGTERM")};if(o.aborted)throw u(),new Error("MCP request aborted.");let l=new Map,m=!1,s="",a=new Error("MCP request aborted."),d=Yo.createInterface({input:c.stdout,terminal:!1});d.on("line",$=>{if($.length>r){m=!0;return}let b=null;try{b=JSON.parse($)}catch{return}let k=typeof b.id=="string"?b.id:typeof b.id=="number"?String(b.id):"";if(!k)return;let E=l.get(k);E&&(l.delete(k),E.resolve(b))}),c.stderr?.on("data",$=>{let b=$.toString();if(s.length+b.length>r){m=!0;return}s+=b});let f=()=>{for(let $ of l.values())$.reject(a);l.clear(),u()};o.addEventListener("abort",f,{once:!0});let h=$=>{let b=$===0?"MCP stdio exited.":s.trim()||"MCP stdio exited with error.";for(let k of l.values())k.reject(new Error(b));l.clear()};c.once("exit",$=>h($));let y=async($,b)=>{let k=`tg-agent-${Date.now()}-${Math.random().toString(16).slice(2,8)}`,E={jsonrpc:"2.0",id:k,method:$,params:b??{}};return await new Promise((ae,rt)=>{l.set(k,{resolve:ae,reject:rt}),c.stdin?.write(`${JSON.stringify(E)}
15
15
  `)})};fetch("http://127.0.0.1:7243/ingest/9e452bb4-cc67-4519-89fa-8fb51d810231",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"mcp.ts:callStdioMcp:beforeInit",message:"sending initialize request",data:{elapsed:Date.now()-i},timestamp:Date.now(),sessionId:"debug-session",hypothesisId:"B,C"})}).catch(()=>{});let w=await y("initialize",{protocolVersion:"2024-11-05",clientInfo:{name:"tg-agent",version:process.env.npm_package_version??"dev"},capabilities:{}});if(fetch("http://127.0.0.1:7243/ingest/9e452bb4-cc67-4519-89fa-8fb51d810231",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"mcp.ts:callStdioMcp:afterInit",message:"initialize response received",data:{elapsed:Date.now()-i,hasError:!!w.error},timestamp:Date.now(),sessionId:"debug-session",hypothesisId:"B,C"})}).catch(()=>{}),w.error&&typeof w.error=="object"){let $=w.error.message??"MCP initialize failed.";throw u(),new Error(String($))}let x={jsonrpc:"2.0",method:"notifications/initialized"};c.stdin?.write(`${JSON.stringify(x)}
16
- `),fetch("http://127.0.0.1:7243/ingest/9e452bb4-cc67-4519-89fa-8fb51d810231",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"mcp.ts:callStdioMcp:beforeMethod",message:"sending method request",data:{method:t,elapsed:Date.now()-i},timestamp:Date.now(),sessionId:"debug-session",hypothesisId:"C"})}).catch(()=>{});let M=await y(t,n);r.removeEventListener("abort",p),d.close(),c.stdin?.end(),u();let S=new Promise($=>{c.once("exit",()=>$())});if(await Promise.race([S,new Promise($=>setTimeout($,500))]),M.error&&typeof M.error=="object"){let $=M.error.message??"MCP request failed.";throw new Error(String($))}let P=JSON.stringify(M,null,2),U=P.length>o?P.slice(0,o):P;return P.length>o&&(m=!0),{ok:!0,output:U,durationMs:Date.now()-i,bytes:Math.min(P.length,o),truncated:m}}async function lr(e,t,n){let o=e.body?.getReader?.();if(!o){let a=await e.text(),d=Math.min(a.length,t);return{text:a.slice(0,t),bytes:d,truncated:a.length>t}}let r=new TextDecoder("utf-8"),i=[],c=0,u=!1;for(;;){if(n.aborted){try{await o.cancel()}catch{}throw new Error("MCP request aborted.")}let{done:a,value:d}=await o.read();if(a)break;if(!d)continue;let p=c+d.byteLength;if(p>t){let h=Math.max(0,t-c);h>0&&(i.push(d.slice(0,h)),c+=h),u=!0;try{await o.cancel()}catch{}break}i.push(d),c=p}let l=new Uint8Array(c),m=0;for(let a of i)l.set(a,m),m+=a.byteLength;return{text:r.decode(l),bytes:c,truncated:u}}function kn(e){let t=[],n;try{n=bn.parse(e)}catch{return t}let o=n.mcp_servers;if(!o||typeof o!="object")return t;for(let[r,i]of Object.entries(o)){if(!i||typeof i!="object")continue;let c=i,u=typeof c.type=="string"?c.type.toLowerCase():void 0,l=typeof c.url=="string"?c.url:void 0,m=typeof c.command=="string"?c.command:void 0,s=u==="http"||u==="stdio"?u:l?"http":m?"stdio":void 0;if(!s||s==="http"&&!l||s==="stdio"&&!m)continue;let a;Array.isArray(c.args)&&(a=c.args.filter(p=>typeof p=="string").map(p=>p.trim()));let d=typeof c.auth=="string"?c.auth:typeof c.authorization=="string"?c.authorization:typeof c.token=="string"?c.token:void 0;t.push({name:r,type:s,url:l,command:m,args:a,auth:d})}return t}var Qo,vn,Zo,er,be,xn,H,tr,_e=I(()=>{"use strict";Qo=6e4,vn=2e5,Zo=40,er=3500,be=null,xn=!1,H=new Map,tr=1500});import re from"node:path";import ur from"node:fs/promises";import{Type as _}from"@sinclair/typebox";function Be(e,t,n){return Number.isNaN(e)?t:Math.min(n,Math.max(t,e))}function pr(e){if(!e)return{};let t={};if(Array.isArray(e)){for(let n of e)n?.name&&(t[n.name]=n.value??"");return t}for(let[n,o]of Object.entries(e))n&&(t[n]=o);return t}function Pn(e){let t=f.fetchTimeoutMs>0?f.fetchTimeoutMs:mr;return Be(e||t,1e3,12e4)}function _n(e){let t=f.fetchMaxBytes>0?f.fetchMaxBytes:dr;return Be(e||t,1024,5e6)}function Cn(e,t,n){let o=e.trim();if(!o)return null;let r=W(o),i=re.isAbsolute(r)?r:re.join(n,r),c=re.resolve(i);for(let u of t){let l=re.resolve(u);if(c===l||c.startsWith(`${l}${re.sep}`))return c}return null}async function Rn(e){try{let t=await ur.stat(e);return t.isFile()?{bytes:t.size}:null}catch{return null}}function fr(e){try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}function gr(e,t){let n=new Uint8Array(t),o=0;for(let r of e)n.set(r,o),o+=r.byteLength;return n}async function yr(e,t,n){let o=e.body?.getReader?.();if(!o){let s=await e.text?.()??"",a=Math.min(s.length,t),d=s.length>t;return{text:s.slice(0,t),bytes:a,truncated:d}}let r=new TextDecoder("utf-8"),i=[],c=0,u=!1;for(;;){if(n?.aborted){try{await o.cancel?.()}catch{}throw new Error("Fetch aborted")}let{done:s,value:a}=await o.read();if(s)break;if(!a)continue;let d=c+a.byteLength;if(d>t){let p=Math.max(0,t-c);p>0&&(i.push(a.slice(0,p)),c+=p),u=!0;try{await o.cancel?.()}catch{}break}i.push(a),c=d}let l=gr(i,c);return{text:r.decode(l),bytes:c,truncated:u}}function hr(e,t){let n=`HTTP ${e.status} ${e.statusText}`.trim(),o=[`url: ${e.url}`,`bytes: ${e.bytes}${e.truncated?" (truncated)":""}`,`content-type: ${e.contentType??"unknown"}`];return`${n}
17
- ${o.join(`
16
+ `),fetch("http://127.0.0.1:7243/ingest/9e452bb4-cc67-4519-89fa-8fb51d810231",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"mcp.ts:callStdioMcp:beforeMethod",message:"sending method request",data:{method:t,elapsed:Date.now()-i},timestamp:Date.now(),sessionId:"debug-session",hypothesisId:"C"})}).catch(()=>{});let M=await y(t,n);o.removeEventListener("abort",f),d.close(),c.stdin?.end(),u();let S=new Promise($=>{c.once("exit",()=>$())});if(await Promise.race([S,new Promise($=>setTimeout($,500))]),M.error&&typeof M.error=="object"){let $=M.error.message??"MCP request failed.";throw new Error(String($))}let _=JSON.stringify(M,null,2),I=_.length>r?_.slice(0,r):_;return _.length>r&&(m=!0),{ok:!0,output:I,durationMs:Date.now()-i,bytes:Math.min(_.length,r),truncated:m}}async function lr(e,t,n){let r=e.body?.getReader?.();if(!r){let a=await e.text(),d=Math.min(a.length,t);return{text:a.slice(0,t),bytes:d,truncated:a.length>t}}let o=new TextDecoder("utf-8"),i=[],c=0,u=!1;for(;;){if(n.aborted){try{await r.cancel()}catch{}throw new Error("MCP request aborted.")}let{done:a,value:d}=await r.read();if(a)break;if(!d)continue;let f=c+d.byteLength;if(f>t){let h=Math.max(0,t-c);h>0&&(i.push(d.slice(0,h)),c+=h),u=!0;try{await r.cancel()}catch{}break}i.push(d),c=f}let l=new Uint8Array(c),m=0;for(let a of i)l.set(a,m),m+=a.byteLength;return{text:o.decode(l),bytes:c,truncated:u}}function _n(e){let t=[],n;try{n=xn.parse(e)}catch{return t}let r=n.mcp_servers;if(!r||typeof r!="object")return t;for(let[o,i]of Object.entries(r)){if(!i||typeof i!="object")continue;let c=i,u=typeof c.type=="string"?c.type.toLowerCase():void 0,l=typeof c.url=="string"?c.url:void 0,m=typeof c.command=="string"?c.command:void 0,s=u==="http"||u==="stdio"?u:l?"http":m?"stdio":void 0;if(!s||s==="http"&&!l||s==="stdio"&&!m)continue;let a;Array.isArray(c.args)&&(a=c.args.filter(f=>typeof f=="string").map(f=>f.trim()));let d=typeof c.auth=="string"?c.auth:typeof c.authorization=="string"?c.authorization:typeof c.token=="string"?c.token:void 0;t.push({name:o,type:s,url:l,command:m,args:a,auth:d})}return t}var Qo,Sn,Zo,er,be,$n,H,tr,_e=F(()=>{"use strict";Qo=6e4,Sn=2e5,Zo=40,er=3500,be=null,$n=!1,H=new Map,tr=1500});import Y from"node:path";import ur from"node:fs/promises";import{Type as P}from"@sinclair/typebox";function Be(e,t,n){return Number.isNaN(e)?t:Math.min(n,Math.max(t,e))}function pr(e){if(!e)return{};let t={};if(Array.isArray(e)){for(let n of e)n?.name&&(t[n.name]=n.value??"");return t}for(let[n,r]of Object.entries(e))n&&(t[n]=r);return t}function Cn(e){let t=p.fetchTimeoutMs>0?p.fetchTimeoutMs:mr;return Be(e||t,1e3,12e4)}function Rn(e){let t=p.fetchMaxBytes>0?p.fetchMaxBytes:dr;return Be(e||t,1024,5e6)}function pt(e,t,n){let r=e.trim();if(!r)return null;let o=W(r),i=Y.isAbsolute(o)?o:Y.join(n,o),c=Y.resolve(i);for(let u of t){let l=Y.resolve(u);if(c===l||c.startsWith(`${l}${Y.sep}`))return c}return null}async function ft(e){try{let t=await ur.stat(e);return t.isFile()?{bytes:t.size}:null}catch{return null}}function fr(e){try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}function gr(e,t){let n=new Uint8Array(t),r=0;for(let o of e)n.set(o,r),r+=o.byteLength;return n}async function yr(e,t,n){let r=e.body?.getReader?.();if(!r){let s=await e.text?.()??"",a=Math.min(s.length,t),d=s.length>t;return{text:s.slice(0,t),bytes:a,truncated:d}}let o=new TextDecoder("utf-8"),i=[],c=0,u=!1;for(;;){if(n?.aborted){try{await r.cancel?.()}catch{}throw new Error("Fetch aborted")}let{done:s,value:a}=await r.read();if(s)break;if(!a)continue;let d=c+a.byteLength;if(d>t){let f=Math.max(0,t-c);f>0&&(i.push(a.slice(0,f)),c+=f),u=!0;try{await r.cancel?.()}catch{}break}i.push(a),c=d}let l=gr(i,c);return{text:o.decode(l),bytes:c,truncated:u}}function hr(e,t){let n=`HTTP ${e.status} ${e.statusText}`.trim(),r=[`url: ${e.url}`,`bytes: ${e.bytes}${e.truncated?" (truncated)":""}`,`content-type: ${e.contentType??"unknown"}`];return`${n}
17
+ ${r.join(`
18
18
  `)}
19
19
 
20
- ${t}`}function br(){return{name:"fetch",label:"fetch",description:"Fetch a URL via HTTP(S) and return the response body.",parameters:wr,execute:async(e,t,n,o,r)=>{if(!fr(t.url))return{content:[{type:"text",text:"Invalid URL. Only http(s) is allowed."}],details:{url:t.url,status:0,statusText:"invalid_url",bytes:0,truncated:!1,contentType:null}};let i=Pn(t.timeoutMs),c=_n(t.maxBytes),u=new AbortController,l=()=>u.abort();r?.addEventListener("abort",l,{once:!0});let m=setTimeout(()=>u.abort(),i);try{n?.({content:[{type:"text",text:`Fetching ${t.url}...`}],details:{url:t.url,status:0,statusText:"pending",bytes:0,truncated:!1,contentType:null}});let s=await fetch(t.url,{method:t.method?.toUpperCase()??"GET",headers:pr(t.headers),body:t.body,signal:u.signal}),a=await yr(s,c,r),d=s.headers.get("content-type");return{content:[{type:"text",text:hr({url:s.url,status:s.status,statusText:s.statusText,bytes:a.bytes,truncated:a.truncated,contentType:d},a.text)}],details:{url:s.url,status:s.status,statusText:s.statusText,bytes:a.bytes,truncated:a.truncated,contentType:d}}}catch(s){return{content:[{type:"text",text:`Fetch failed: ${s instanceof Error?s.message:String(s)}`}],details:{url:t.url,status:0,statusText:"error",bytes:0,truncated:!1,contentType:null}}}finally{clearTimeout(m),r?.removeEventListener("abort",l)}}}}function xr(e,t,n){let o=t.status>0?`HTTP ${t.status} ${t.statusText}`.trim():t.statusText,r=[`server: ${e.name}`,`type: ${e.type}`,`target: ${t.target}`,`bytes: ${t.bytes}${t.truncated?" (truncated)":""}`,`content-type: ${t.contentType??"unknown"}`];return`${o}
21
- ${r.join(`
20
+ ${t}`}function br(){return{name:"fetch",label:"fetch",description:"Fetch a URL via HTTP(S) and return the response body.",parameters:wr,execute:async(e,t,n,r,o)=>{if(!fr(t.url))return{content:[{type:"text",text:"Invalid URL. Only http(s) is allowed."}],details:{url:t.url,status:0,statusText:"invalid_url",bytes:0,truncated:!1,contentType:null}};let i=Cn(t.timeoutMs),c=Rn(t.maxBytes),u=new AbortController,l=()=>u.abort();o?.addEventListener("abort",l,{once:!0});let m=setTimeout(()=>u.abort(),i);try{n?.({content:[{type:"text",text:`Fetching ${t.url}...`}],details:{url:t.url,status:0,statusText:"pending",bytes:0,truncated:!1,contentType:null}});let s=await fetch(t.url,{method:t.method?.toUpperCase()??"GET",headers:pr(t.headers),body:t.body,signal:u.signal}),a=await yr(s,c,o),d=s.headers.get("content-type");return{content:[{type:"text",text:hr({url:s.url,status:s.status,statusText:s.statusText,bytes:a.bytes,truncated:a.truncated,contentType:d},a.text)}],details:{url:s.url,status:s.status,statusText:s.statusText,bytes:a.bytes,truncated:a.truncated,contentType:d}}}catch(s){return{content:[{type:"text",text:`Fetch failed: ${s instanceof Error?s.message:String(s)}`}],details:{url:t.url,status:0,statusText:"error",bytes:0,truncated:!1,contentType:null}}}finally{clearTimeout(m),o?.removeEventListener("abort",l)}}}}function xr(e,t,n){let r=t.status>0?`HTTP ${t.status} ${t.statusText}`.trim():t.statusText,o=[`server: ${e.name}`,`type: ${e.type}`,`target: ${t.target}`,`bytes: ${t.bytes}${t.truncated?" (truncated)":""}`,`content-type: ${t.contentType??"unknown"}`];return`${r}
21
+ ${o.join(`
22
22
  `)}
23
23
 
24
- ${n}`}function Sr(e){return{name:"mcp",label:"mcp",description:"Call an MCP endpoint via JSON-RPC.",parameters:vr,execute:async(t,n,o,r,i)=>{let c=await e();if(c.length===0)return{content:[{type:"text",text:"MCP is not configured. Add [mcp_servers.*] to ~/.tg-agent/config.toml."}],details:{server:"",type:"http",target:"",status:0,statusText:"not_configured",bytes:0,truncated:!1,contentType:null}};let u=n.server?.trim()??"";if(!u)if(c.length===1)u=c[0]?.name??"";else return{content:[{type:"text",text:`Multiple MCP servers configured. Provide server name. Available: ${c.map(m=>m.name).join(", ")}`}],details:{server:"",type:"http",target:"",status:0,statusText:"server_required",bytes:0,truncated:!1,contentType:null}};let l=c.find(m=>m.name===u);if(!l)return{content:[{type:"text",text:`MCP server not found: ${u}. Available: ${c.map(m=>m.name).join(", ")}`}],details:{server:u,type:"http",target:"",status:0,statusText:"server_not_found",bytes:0,truncated:!1,contentType:null}};try{o?.({content:[{type:"text",text:`Calling MCP ${l.name} ${n.method}...`}],details:{server:l.name,type:l.type,target:pe(l),status:0,statusText:"pending",bytes:0,truncated:!1,contentType:null}});let m=await Ke(l,n.method,n.params??{},{timeoutMs:Pn(void 0),maxBytes:_n(void 0),signal:i});return{content:[{type:"text",text:xr(l,{server:l.name,type:l.type,target:pe(l),status:m.statusCode??0,statusText:m.statusText??(m.ok?"ok":"error"),bytes:m.bytes,truncated:m.truncated,contentType:m.contentType??null},m.output)}],details:{server:l.name,type:l.type,target:pe(l),status:m.statusCode??0,statusText:m.statusText??(m.ok?"ok":"error"),bytes:m.bytes,truncated:m.truncated,contentType:m.contentType??null}}}catch(m){return{content:[{type:"text",text:`MCP failed: ${m instanceof Error?m.message:String(m)}`}],details:{server:l.name,type:l.type,target:pe(l),status:0,statusText:"error",bytes:0,truncated:!1,contentType:null}}}}}}function Mr(e){let t=[f.workspaceDir,re.join(f.agentDir,"uploads")];return{name:"send_photo",label:"send_photo",description:"Send an image file to the current Telegram chat.",parameters:$r,execute:async(n,o)=>{let r=Cn(o.path,t,f.workspaceDir);if(!r)return{content:[{type:"text",text:"Invalid path. Only workspace or uploads are allowed."}],details:{path:o.path,bytes:0}};let i=await Rn(r);return i?(await e.sendPhoto(r,o.caption?.trim()||void 0),{content:[{type:"text",text:`Photo sent: ${re.basename(r)}`}],details:{path:r,bytes:i.bytes}}):{content:[{type:"text",text:`File not found: ${r}`}],details:{path:r,bytes:0}}}}}function kr(e){let t=[f.workspaceDir,re.join(f.agentDir,"uploads")];return{name:"send_file",label:"send_file",description:"Send a file to the current Telegram chat.",parameters:Ar,execute:async(n,o)=>{let r=Cn(o.path,t,f.workspaceDir);if(!r)return{content:[{type:"text",text:"Invalid path. Only workspace or uploads are allowed."}],details:{path:o.path,bytes:0}};let i=await Rn(r);return i?(await e.sendDocument(r,o.caption?.trim()||void 0),{content:[{type:"text",text:`File sent: ${re.basename(r)}`}],details:{path:r,bytes:i.bytes}}):{content:[{type:"text",text:`File not found: ${r}`}],details:{path:r,bytes:0}}}}}function Tn(e){let t=[br()];return e?.telegram&&(t.push(Mr(e.telegram)),t.push(kr(e.telegram))),ze(f.agentDir).length>0&&t.push(Sr(()=>ke(f.agentDir))),t}var dr,mr,wr,vr,$r,Ar,En=I(()=>{"use strict";K();_e();J();dr=2e5,mr=6e4;wr=_.Object({url:_.String({description:"HTTP or HTTPS URL"}),method:_.Optional(_.String({description:"HTTP method (default: GET)"})),headers:_.Optional(_.Array(_.Object({name:_.String({description:"Header name"}),value:_.String({description:"Header value"})}),{description:"Request headers as name/value pairs"})),body:_.Optional(_.String({description:"Request body (string)"})),timeoutMs:_.Optional(_.Integer({description:"Timeout in milliseconds",minimum:1e3,maximum:12e4})),maxBytes:_.Optional(_.Integer({description:"Max response bytes",minimum:1024,maximum:5e6}))});vr=_.Object({server:_.Optional(_.String({description:"MCP server name"})),method:_.String({description:"MCP method name"}),params:_.Optional(_.Any({description:"MCP params payload"}))});$r=_.Object({path:_.String({description:"Image file path (relative to workspace or uploads)."}),caption:_.Optional(_.String({description:"Caption text (plain text)."}))}),Ar=_.Object({path:_.String({description:"File path (relative to workspace or uploads)."}),caption:_.Optional(_.String({description:"Caption text (plain text)."}))})});import Nn from"node:fs/promises";import jn from"node:path";function Ln(e){return jn.join(f.sessionDir,`${e}.json`)}function Dn(e){return e.replace(/[^a-zA-Z0-9_-]/g,"_")}function pt(e,t){let n=Dn(e),o=Dn(t);return jn.join(f.sessionDir,`${n}-${o}.jsonl`)}async function ve(e,t){let n=pt(e,t);try{await Nn.unlink(n)}catch(o){if(o.code==="ENOENT")return;throw o}}function On(e,t){let n=t?.sessions??{},o=t?.activeSessionId??null,r=t?.workspaceDir,i={chatId:e,workspaceDir:r,activeSessionId:o,sessions:n};return(!o||!n[o])&&(i.activeSessionId=null),i}async function Je(e){await C(f.sessionDir);let t=We.get(e);if(t)return t;let n=Ln(e);try{let o=await Nn.readFile(n,"utf8"),r=JSON.parse(o),i=On(e,r);return We.set(e,i),i}catch(o){if(o.code==="ENOENT"){let r=On(e,{});return We.set(e,r),r}throw o}}async function T(e){await C(f.sessionDir);let t=Ln(e.chatId);await ye(t,e),We.set(e.chatId,e)}function ft(e){return Object.values(e.sessions).sort((t,n)=>n.updatedAt-t.updatedAt)}function gt(e){return[]}function He(e,t){if(Object.keys(e.sessions).length>=f.maxSessions)throw new Error("Max sessions reached");let o=oe(),r=D(),i={id:o,title:t&&t.length>0?t:`session-${o}`,messages:[],createdAt:r,updatedAt:r};return e.sessions[o]=i,e.activeSessionId=o,i}function Un(e,t){return e.sessions[t]?(e.activeSessionId=t,!0):!1}function fe(e){return e.activeSessionId?e.sessions[e.activeSessionId]??null:null}function yt(e,t){return e.sessions[t]?(delete e.sessions[t],e.activeSessionId===t&&(e.activeSessionId=null),!0):!1}function In(e){e.messages=[],e.updatedAt=D()}function ht(e,t,n){e.messages.push(t),e.messages.length>n&&(e.messages=e.messages.slice(-n)),e.updatedAt=D()}function Fn(e,t){e.workspaceDir=t}var We,wt=I(()=>{"use strict";K();J();We=new Map});import Pr from"node:fs/promises";import Kn from"node:path";import{completeSimple as _r}from"@mariozechner/pi-ai";function Er(e,t){let n=e==="bash"&&typeof t.command=="string"?t.command:`${e}: ${JSON.stringify(t)}`;return Tr.replace("{{command}}",n)}function Dr(e){let t=e.trim();console.log(`[audit] AI response: ${t.slice(0,200)}`);try{let n=JSON.parse(t),o=n.riskLevel?.toLowerCase();if(o==="none"||o==="low"||o==="critical")return{riskLevel:o,reason:n.reason??"No reason"}}catch{}try{let n=t.match(/\{[^{}]*"riskLevel"\s*:\s*"[^"]*"[^{}]*\}/);if(n){let r=JSON.parse(n[0]),i=r.riskLevel?.toLowerCase();if(i==="none"||i==="low"||i==="critical")return{riskLevel:i,reason:r.reason??"No reason"}}let o=t.toLowerCase();return o.includes('"critical"')||o.includes("critical risk")?{riskLevel:"critical",reason:"AI indicated critical risk"}:o.includes('"none"')||o.includes("no risk")?{riskLevel:"none",reason:"AI indicated no risk"}:(console.warn("[audit] could not parse response, defaulting to low"),{riskLevel:"low",reason:"Could not parse AI response"})}catch(n){return console.warn("[audit] parse error:",n),{riskLevel:"low",reason:"Failed to parse AI response"}}}async function Or(e,t,n,o,r){let i=Er(n,o);try{let u={systemPrompt:'You are a security analyst. Reply with ONLY valid JSON: {"riskLevel":"none|low|critical","reason":"brief explanation"}.',messages:[{role:"user",content:i,timestamp:Date.now()}]},l=await _r(e,u,{apiKey:t,maxTokens:500,temperature:0,...r&&{sessionId:r}}),m=l.content.find(a=>a.type==="text"),s=m?.type==="text"?m.text:"";return s.trim()||(s=l.content.filter(d=>d.type==="thinking").map(d=>d.type==="thinking"?d.thinking:"").filter(Boolean).join(`
24
+ ${n}`}function Sr(e){return{name:"mcp",label:"mcp",description:"Call an MCP endpoint via JSON-RPC.",parameters:vr,execute:async(t,n,r,o,i)=>{let c=await e();if(c.length===0)return{content:[{type:"text",text:"MCP is not configured. Add [mcp_servers.*] to ~/.tg-agent/config.toml."}],details:{server:"",type:"http",target:"",status:0,statusText:"not_configured",bytes:0,truncated:!1,contentType:null}};let u=n.server?.trim()??"";if(!u)if(c.length===1)u=c[0]?.name??"";else return{content:[{type:"text",text:`Multiple MCP servers configured. Provide server name. Available: ${c.map(m=>m.name).join(", ")}`}],details:{server:"",type:"http",target:"",status:0,statusText:"server_required",bytes:0,truncated:!1,contentType:null}};let l=c.find(m=>m.name===u);if(!l)return{content:[{type:"text",text:`MCP server not found: ${u}. Available: ${c.map(m=>m.name).join(", ")}`}],details:{server:u,type:"http",target:"",status:0,statusText:"server_not_found",bytes:0,truncated:!1,contentType:null}};try{r?.({content:[{type:"text",text:`Calling MCP ${l.name} ${n.method}...`}],details:{server:l.name,type:l.type,target:pe(l),status:0,statusText:"pending",bytes:0,truncated:!1,contentType:null}});let m=await Ke(l,n.method,n.params??{},{timeoutMs:Cn(void 0),maxBytes:Rn(void 0),signal:i});return{content:[{type:"text",text:xr(l,{server:l.name,type:l.type,target:pe(l),status:m.statusCode??0,statusText:m.statusText??(m.ok?"ok":"error"),bytes:m.bytes,truncated:m.truncated,contentType:m.contentType??null},m.output)}],details:{server:l.name,type:l.type,target:pe(l),status:m.statusCode??0,statusText:m.statusText??(m.ok?"ok":"error"),bytes:m.bytes,truncated:m.truncated,contentType:m.contentType??null}}}catch(m){return{content:[{type:"text",text:`MCP failed: ${m instanceof Error?m.message:String(m)}`}],details:{server:l.name,type:l.type,target:pe(l),status:0,statusText:"error",bytes:0,truncated:!1,contentType:null}}}}}}function kr(e){let t=[p.workspaceDir,Y.join(p.agentDir,"uploads")];return{name:"send_photo",label:"send_photo",description:"Send an image file to the current Telegram chat.",parameters:$r,execute:async(n,r)=>{let o=pt(r.path,t,p.workspaceDir);if(!o)return{content:[{type:"text",text:"Invalid path. Only workspace or uploads are allowed."}],details:{path:r.path,bytes:0}};let i=await ft(o);return i?(await e.sendPhoto(o,r.caption?.trim()||void 0),{content:[{type:"text",text:`Photo sent: ${Y.basename(o)}`}],details:{path:o,bytes:i.bytes}}):{content:[{type:"text",text:`File not found: ${o}`}],details:{path:o,bytes:0}}}}}function Pr(e){let t=[p.workspaceDir,Y.join(p.agentDir,"uploads")];return{name:"send_file",label:"send_file",description:"Send a file to the current Telegram chat.",parameters:Ar,execute:async(n,r)=>{let o=pt(r.path,t,p.workspaceDir);if(!o)return{content:[{type:"text",text:"Invalid path. Only workspace or uploads are allowed."}],details:{path:r.path,bytes:0}};let i=await ft(o);return i?(await e.sendDocument(o,r.caption?.trim()||void 0),{content:[{type:"text",text:`File sent: ${Y.basename(o)}`}],details:{path:o,bytes:i.bytes}}):{content:[{type:"text",text:`File not found: ${o}`}],details:{path:o,bytes:0}}}}}function _r(e){let t=[p.workspaceDir,Y.join(p.agentDir,"uploads")];return{name:"send_voice",label:"send_voice",description:"Send a voice message file to the current Telegram chat.",parameters:Mr,execute:async(n,r)=>{let o=pt(r.path,t,p.workspaceDir);if(!o)return{content:[{type:"text",text:"Invalid path. Only workspace or uploads are allowed."}],details:{path:r.path,bytes:0}};let i=await ft(o);return i?(await e.sendVoice(o,r.caption?.trim()||void 0),{content:[{type:"text",text:`Voice sent: ${Y.basename(o)}`}],details:{path:o,bytes:i.bytes}}):{content:[{type:"text",text:`File not found: ${o}`}],details:{path:o,bytes:0}}}}}function Tn(e){let t=[br()];return e?.telegram&&(t.push(kr(e.telegram)),t.push(Pr(e.telegram)),t.push(_r(e.telegram))),ze(p.agentDir).length>0&&t.push(Sr(()=>ke(p.agentDir))),t}var dr,mr,wr,vr,$r,Ar,Mr,En=F(()=>{"use strict";K();_e();J();dr=2e5,mr=6e4;wr=P.Object({url:P.String({description:"HTTP or HTTPS URL"}),method:P.Optional(P.String({description:"HTTP method (default: GET)"})),headers:P.Optional(P.Array(P.Object({name:P.String({description:"Header name"}),value:P.String({description:"Header value"})}),{description:"Request headers as name/value pairs"})),body:P.Optional(P.String({description:"Request body (string)"})),timeoutMs:P.Optional(P.Integer({description:"Timeout in milliseconds",minimum:1e3,maximum:12e4})),maxBytes:P.Optional(P.Integer({description:"Max response bytes",minimum:1024,maximum:5e6}))});vr=P.Object({server:P.Optional(P.String({description:"MCP server name"})),method:P.String({description:"MCP method name"}),params:P.Optional(P.Any({description:"MCP params payload"}))});$r=P.Object({path:P.String({description:"Image file path (relative to workspace or uploads)."}),caption:P.Optional(P.String({description:"Caption text (plain text)."}))}),Ar=P.Object({path:P.String({description:"File path (relative to workspace or uploads)."}),caption:P.Optional(P.String({description:"Caption text (plain text)."}))}),Mr=P.Object({path:P.String({description:"Voice file path (relative to workspace or uploads). Telegram sendVoice expects OGG/OPUS for best compatibility."}),caption:P.Optional(P.String({description:"Caption text (plain text)."}))})});import Nn from"node:fs/promises";import jn from"node:path";function Ln(e){return jn.join(p.sessionDir,`${e}.json`)}function Dn(e){return e.replace(/[^a-zA-Z0-9_-]/g,"_")}function gt(e,t){let n=Dn(e),r=Dn(t);return jn.join(p.sessionDir,`${n}-${r}.jsonl`)}async function ve(e,t){let n=gt(e,t);try{await Nn.unlink(n)}catch(r){if(r.code==="ENOENT")return;throw r}}function On(e,t){let n=t?.sessions??{},r=t?.activeSessionId??null,o=t?.workspaceDir,i={chatId:e,workspaceDir:o,activeSessionId:r,sessions:n};return(!r||!n[r])&&(i.activeSessionId=null),i}async function Je(e){await C(p.sessionDir);let t=We.get(e);if(t)return t;let n=Ln(e);try{let r=await Nn.readFile(n,"utf8"),o=JSON.parse(r),i=On(e,o);return We.set(e,i),i}catch(r){if(r.code==="ENOENT"){let o=On(e,{});return We.set(e,o),o}throw r}}async function T(e){await C(p.sessionDir);let t=Ln(e.chatId);await ye(t,e),We.set(e.chatId,e)}function yt(e){return Object.values(e.sessions).sort((t,n)=>n.updatedAt-t.updatedAt)}function ht(e){return[]}function He(e,t){if(Object.keys(e.sessions).length>=p.maxSessions)throw new Error("Max sessions reached");let r=re(),o=O(),i={id:r,title:t&&t.length>0?t:`session-${r}`,messages:[],createdAt:o,updatedAt:o};return e.sessions[r]=i,e.activeSessionId=r,i}function Un(e,t){return e.sessions[t]?(e.activeSessionId=t,!0):!1}function fe(e){return e.activeSessionId?e.sessions[e.activeSessionId]??null:null}function wt(e,t){return e.sessions[t]?(delete e.sessions[t],e.activeSessionId===t&&(e.activeSessionId=null),!0):!1}function In(e){e.messages=[],e.updatedAt=O()}function bt(e,t,n){e.messages.push(t),e.messages.length>n&&(e.messages=e.messages.slice(-n)),e.updatedAt=O()}function Fn(e,t){e.workspaceDir=t}var We,vt=F(()=>{"use strict";K();J();We=new Map});import Cr from"node:fs/promises";import Kn from"node:path";import{completeSimple as Rr}from"@mariozechner/pi-ai";function Or(e,t){let n=e==="bash"&&typeof t.command=="string"?t.command:`${e}: ${JSON.stringify(t)}`;return Dr.replace("{{command}}",n)}function Nr(e){let t=e.trim();console.log(`[audit] AI response: ${t.slice(0,200)}`);try{let n=JSON.parse(t),r=n.riskLevel?.toLowerCase();if(r==="none"||r==="low"||r==="critical")return{riskLevel:r,reason:n.reason??"No reason"}}catch{}try{let n=t.match(/\{[^{}]*"riskLevel"\s*:\s*"[^"]*"[^{}]*\}/);if(n){let o=JSON.parse(n[0]),i=o.riskLevel?.toLowerCase();if(i==="none"||i==="low"||i==="critical")return{riskLevel:i,reason:o.reason??"No reason"}}let r=t.toLowerCase();return r.includes('"critical"')||r.includes("critical risk")?{riskLevel:"critical",reason:"AI indicated critical risk"}:r.includes('"none"')||r.includes("no risk")?{riskLevel:"none",reason:"AI indicated no risk"}:(console.warn("[audit] could not parse response, defaulting to low"),{riskLevel:"low",reason:"Could not parse AI response"})}catch(n){return console.warn("[audit] parse error:",n),{riskLevel:"low",reason:"Failed to parse AI response"}}}async function jr(e,t,n,r,o){let i=Or(n,r);try{let u={systemPrompt:'You are a security analyst. Reply with ONLY valid JSON: {"riskLevel":"none|low|critical","reason":"brief explanation"}.',messages:[{role:"user",content:i,timestamp:Date.now()}]},l=await Rr(e,u,{apiKey:t,maxTokens:500,temperature:0,...o&&{sessionId:o}}),m=l.content.find(a=>a.type==="text"),s=m?.type==="text"?m.text:"";return s.trim()||(s=l.content.filter(d=>d.type==="thinking").map(d=>d.type==="thinking"?d.thinking:"").filter(Boolean).join(`
25
25
 
26
- `)),Dr(s)}catch(c){let u=c instanceof Error?c.message:String(c);return console.error("[audit] AI analysis failed:",u),{riskLevel:"low",reason:`AI analysis failed: ${u}`}}}function Nr(e,t){let n=e.trim();return t.some(o=>o.test(n))}function jr(e){let t=[];for(let n of e)try{t.push(new RegExp(n,"i"))}catch{console.warn(`[audit] invalid whitelist pattern: ${n}`)}return t}async function ce(e,t,n){try{await C(zn);let o=Kn.join(zn,`${e}-${t}.log`),r=JSON.stringify(n)+`
27
- `;await Pr.appendFile(o,r,"utf8")}catch(o){let r=o instanceof Error?o.message:String(o);console.error(`[audit] failed to write audit log: ${r}`)}}function Lr(e){let t=e.toolName==="bash"?e.input.command??JSON.stringify(e.input):JSON.stringify(e.input,null,2);return["[Security Alert]",`Tool: ${e.toolName}`,`Command: ${t.slice(0,300)}`,`Risk: ${e.riskLevel.toUpperCase()} - ${e.analysis}`,"",'Press "Approve" to continue or "Stop" to block.'].join(`
28
- `)}function Bn(e,t){let n=f.audit,o=jr(n.whitelistPatterns);return r=>{r.on("tool_call",async(i,c)=>{let{toolName:u,toolCallId:l,input:m}=i,s={timestamp:new Date().toISOString(),sessionId:e.sessionId,toolName:u,toolCallId:l,input:m,riskLevel:"none",analysis:"",action:"passed"};if(Cr.has(u)){s.analysis="Read-only tool",await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} action=passed (read-only)`);return}if(!Rr.has(u)){s.analysis="Tool not in analysis scope",await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} action=passed (not analyzed)`);return}if(u==="bash"){let d=m.command??"";if(Nr(d,o)){s.analysis="Whitelisted bash command",await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} action=passed (whitelisted)`);return}}if(!t){s.analysis="No audit model configured",await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} action=passed (no audit model)`);return}console.log(`[audit] analyzing tool=${u} id=${l}`);let a=await Or(t.model,t.apiKey,u,m,e.sessionId);if(s.riskLevel=a.riskLevel,s.analysis=a.reason,a.riskLevel==="none"||a.riskLevel==="low"){s.action="passed",await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} risk=${a.riskLevel} action=passed`);return}console.log(`[audit] CRITICAL tool=${u} id=${l} reason=${a.reason}`);try{let d=Lr(s);if(await e.requestConfirmation(d,n.confirmTimeoutMs)){s.action="approved",await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} action=approved`);return}return s.action="blocked",await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} action=blocked (user rejected)`),c.abort(),{block:!0,reason:"Operation blocked by user due to security risk."}}catch(d){let p=d instanceof Error?d.message:String(d);return s.action="blocked",s.analysis=`${a.reason} (confirmation failed: ${p})`,await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} action=blocked (${p})`),c.abort(),{block:!0,reason:`Security confirmation failed: ${p}`}}})}}var Cr,Rr,Tr,zn,Wn=I(()=>{"use strict";K();J();Cr=new Set(["read","ls","find","grep"]),Rr=new Set(["bash"]),Tr=`Analyze this command for security risks. Reply with ONLY a JSON object, no other text.
26
+ `)),Nr(s)}catch(c){let u=c instanceof Error?c.message:String(c);return console.error("[audit] AI analysis failed:",u),{riskLevel:"low",reason:`AI analysis failed: ${u}`}}}function Lr(e,t){let n=e.trim();return t.some(r=>r.test(n))}function Ur(e){let t=[];for(let n of e)try{t.push(new RegExp(n,"i"))}catch{console.warn(`[audit] invalid whitelist pattern: ${n}`)}return t}async function ce(e,t,n){try{await C(zn);let r=Kn.join(zn,`${e}-${t}.log`),o=JSON.stringify(n)+`
27
+ `;await Cr.appendFile(r,o,"utf8")}catch(r){let o=r instanceof Error?r.message:String(r);console.error(`[audit] failed to write audit log: ${o}`)}}function Ir(e){let t=e.toolName==="bash"?e.input.command??JSON.stringify(e.input):JSON.stringify(e.input,null,2);return["[Security Alert]",`Tool: ${e.toolName}`,`Command: ${t.slice(0,300)}`,`Risk: ${e.riskLevel.toUpperCase()} - ${e.analysis}`,"",'Press "Approve" to continue or "Stop" to block.'].join(`
28
+ `)}function Bn(e,t){let n=p.audit,r=Ur(n.whitelistPatterns);return o=>{o.on("tool_call",async(i,c)=>{let{toolName:u,toolCallId:l,input:m}=i,s={timestamp:new Date().toISOString(),sessionId:e.sessionId,toolName:u,toolCallId:l,input:m,riskLevel:"none",analysis:"",action:"passed"};if(Tr.has(u)){s.analysis="Read-only tool",await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} action=passed (read-only)`);return}if(!Er.has(u)){s.analysis="Tool not in analysis scope",await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} action=passed (not analyzed)`);return}if(u==="bash"){let d=m.command??"";if(Lr(d,r)){s.analysis="Whitelisted bash command",await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} action=passed (whitelisted)`);return}}if(!t){s.analysis="No audit model configured",await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} action=passed (no audit model)`);return}console.log(`[audit] analyzing tool=${u} id=${l}`);let a=await jr(t.model,t.apiKey,u,m,e.sessionId);if(s.riskLevel=a.riskLevel,s.analysis=a.reason,a.riskLevel==="none"||a.riskLevel==="low"){s.action="passed",await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} risk=${a.riskLevel} action=passed`);return}console.log(`[audit] CRITICAL tool=${u} id=${l} reason=${a.reason}`);try{let d=Ir(s);if(await e.requestConfirmation(d,n.confirmTimeoutMs)){s.action="approved",await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} action=approved`);return}return s.action="blocked",await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} action=blocked (user rejected)`),c.abort(),{block:!0,reason:"Operation blocked by user due to security risk."}}catch(d){let f=d instanceof Error?d.message:String(d);return s.action="blocked",s.analysis=`${a.reason} (confirmation failed: ${f})`,await ce(e.chatId,e.sessionId,s),console.log(`[audit] tool=${u} id=${l} action=blocked (${f})`),c.abort(),{block:!0,reason:`Security confirmation failed: ${f}`}}})}}var Tr,Er,Dr,zn,Wn=F(()=>{"use strict";K();J();Tr=new Set(["read","ls","find","grep"]),Er=new Set(["bash"]),Dr=`Analyze this command for security risks. Reply with ONLY a JSON object, no other text.
29
29
 
30
30
  Command: {{command}}
31
31
 
@@ -35,23 +35,23 @@ Risk levels:
35
35
  - "critical": High risk (secrets exposure, destructive ops, network attacks, privilege escalation)
36
36
 
37
37
  Reply format (ONLY this JSON, nothing else):
38
- {"riskLevel":"none|low|critical","reason":"brief explanation"}`;zn=Kn.join(f.sessionDir,"audit-logs")});import{readFileSync as Ur,existsSync as Ir,chmodSync as Fr}from"node:fs";import Jn from"node:path";import{getOAuthProvider as zr}from"@mariozechner/pi-ai";function Q(){return bt||(bt=new vt),bt}var vt,bt,xt=I(()=>{"use strict";K();J();vt=class{filePath;data={};constructor(t){this.filePath=t??Jn.join(f.agentDir,"multi-auth.json"),this.reload()}reload(){if(!Ir(this.filePath)){this.data={};return}try{let t=Ur(this.filePath,"utf8");this.data=JSON.parse(t)}catch{this.data={}}}async save(){let t=Jn.dirname(this.filePath);await C(t),await ye(this.filePath,this.data);try{Fr(this.filePath,384)}catch{}}listAccounts(t){let n=this.data[t];return n?Object.entries(n.accounts).map(([o,r])=>({id:o,email:r.email,isDefault:n.defaultAccountId===o,lastUsedAt:r.lastUsedAt})):[]}async addAccount(t,n,o){this.data[t]||(this.data[t]={accounts:{}});let r=`acc_${oe()}`,i=n,c=typeof o?.email=="string"?o.email:typeof i.email=="string"?i.email:void 0;return this.data[t].accounts[r]={type:"oauth",refresh:n.refresh,access:n.access,expires:n.expires,email:c,projectId:i.projectId,createdAt:Date.now(),lastUsedAt:Date.now()},this.data[t].defaultAccountId||(this.data[t].defaultAccountId=r),await this.save(),r}getAccount(t,n){return this.data[t]?.accounts[n]??null}getDefaultAccount(t){let n=this.data[t];if(!n?.defaultAccountId)return null;let o=n.accounts[n.defaultAccountId];return o?{id:n.defaultAccountId,credential:o}:null}async setDefaultAccount(t,n){let o=this.data[t];return o?.accounts[n]?(o.defaultAccountId=n,await this.save(),!0):!1}async removeAccount(t,n){let o=this.data[t];if(!o?.accounts[n])return!1;if(delete o.accounts[n],o.defaultAccountId===n){let r=Object.keys(o.accounts);o.defaultAccountId=r[0]}return Object.keys(o.accounts).length===0&&delete this.data[t],await this.save(),!0}async removeAllAccounts(t){let n=this.data[t];if(!n)return 0;let o=Object.keys(n.accounts).length;return delete this.data[t],await this.save(),o}async updateCredential(t,n,o){let r=this.data[t]?.accounts[n];if(!r)return;r.refresh=o.refresh,r.access=o.access,r.expires=o.expires,r.lastUsedAt=Date.now();let i=o;i.projectId!==void 0&&(r.projectId=i.projectId),await this.save()}async getApiKey(t,n){let o=this.data[t]?.accounts[n];if(!o)return null;let r=zr(t);if(!r)return null;let i=Date.now(),c=300*1e3;if(o.expires-i<c)try{let u={refresh:o.refresh,access:o.access,expires:o.expires,...o.projectId!==void 0&&{projectId:o.projectId}},l=await r.refreshToken(u);return await this.updateCredential(t,n,l),r.getApiKey(l)}catch(u){return console.warn(`[multi-auth] token refresh failed for ${t}/${n}:`,u),o.expires>i?r.getApiKey(o):null}return r.getApiKey(o)}hasMultipleAccounts(t){let n=this.data[t]?.accounts;return n?Object.keys(n).length>1:!1}hasAccounts(t){let n=this.data[t]?.accounts;return n?Object.keys(n).length>0:!1}},bt=null});import{chmodSync as Kr,existsSync as Br,readFileSync as Wr}from"node:fs";import Hn from"node:path";function Jr(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e,n=typeof t.apiKey=="string"?t.apiKey.trim():"",o=typeof t.baseUrl=="string"?t.baseUrl.trim():"",r=typeof t.updatedAt=="number"?t.updatedAt:Date.now();return!n&&!o?null:{...n?{apiKey:n}:{},...o?{baseUrl:o}:{},updatedAt:r}}function se(){return St||(St=new $t),St}var $t,St,At=I(()=>{"use strict";K();J();$t=class{filePath;data={};constructor(t){this.filePath=t??Hn.join(f.agentDir,"api-key-auth.json"),this.reload()}reload(){if(!Br(this.filePath)){this.data={};return}try{let t=JSON.parse(Wr(this.filePath,"utf8"));if(!t||typeof t!="object"||Array.isArray(t)){this.data={};return}let n={};for(let[o,r]of Object.entries(t)){let i=Jr(r);i&&(n[o]=i)}this.data=n}catch{this.data={}}}async save(){await C(Hn.dirname(this.filePath)),await ye(this.filePath,this.data);try{Kr(this.filePath,384)}catch{}}upsert(t){let n=this.data[t];if(n)return n;let o={updatedAt:Date.now()};return this.data[t]=o,o}cleanup(t){let n=this.data[t];n&&!n.apiKey&&!n.baseUrl&&delete this.data[t]}listProviders(){return Object.keys(this.data).sort((t,n)=>t.localeCompare(n))}getProviderConfig(t){let n=this.data[t];return n?{...n}:null}hasApiKey(t){return!!this.data[t]?.apiKey}async setApiKey(t,n){let o=this.upsert(t);o.apiKey=n.trim(),o.updatedAt=Date.now(),this.cleanup(t),await this.save()}async clearApiKey(t){let n=this.data[t];return n?.apiKey?(delete n.apiKey,n.updatedAt=Date.now(),this.cleanup(t),await this.save(),!0):!1}async setBaseUrl(t,n){let o=this.upsert(t);o.baseUrl=n.trim(),o.updatedAt=Date.now(),this.cleanup(t),await this.save()}async clearBaseUrl(t){let n=this.data[t];return n?.baseUrl?(delete n.baseUrl,n.updatedAt=Date.now(),this.cleanup(t),await this.save(),!0):!1}},St=null});import{createAgentSession as Hr,AuthStorage as qr,ModelRegistry as Gr,SessionManager as Vr,SettingsManager as Yr,DefaultResourceLoader as Xr}from"@mariozechner/pi-coding-agent";import qe from"node:fs/promises";import Ge from"node:path";function qn(e){let t=e.trim().toLowerCase();return t==="codex"?"openai-codex":t}function Zr(e){if(!e)return;let t=e.trim().toLowerCase();if(t==="oauth")return"oauth";if(t==="api_key"||t==="apikey")return"api_key"}function es(e,t){let n=e.trim();if(!n)return{provider:t,modelId:""};if(n.includes("/")){let[o,r]=n.split("/",2);return{provider:o.trim()||t,modelId:r.trim()}}return{provider:t,modelId:n}}function ts(e,t){return e!=="openai-codex"?t:Qr[t]??t}function Gn(e,t){let n=e.getAvailable().filter(r=>r.provider===t);return n.length>0?n[0]:e.getAll().filter(r=>r.provider===t)[0]}function ns(e,t,n){let o=Gn(e,t);if(o)return{...o,id:n,name:n}}function os(e,t){let n=!!t?.provider?.trim(),o=!!t?.modelId?.trim(),r=qn(t?.provider||f.modelProvider||"openai-codex"),i=n||o?"":f.modelRef||"",{provider:c,modelId:u}=es(i,r),l=t?.provider?r:qn(c),m=o?t?.modelId?.trim()||"":u;if(!m){let p=Gn(e,l);return p?{model:p,provider:l,modelId:p.id,syntheticModel:!1}:{model:void 0,provider:l,modelId:"",syntheticModel:!1}}let s=ts(l,m),a=e.find(l,s);if(a)return{model:a,provider:l,modelId:s,syntheticModel:!1};let d=ns(e,l,s);return d?{model:d,provider:l,modelId:s,syntheticModel:!0}:{model:void 0,provider:l,modelId:s,syntheticModel:!1}}function rs(e){let t=X();return t?(e.setRuntimeApiKey("openai-codex",t.accessToken),{source:t.source,expiresAt:t.expiresAt}):null}function ss(e){if(e?.role!=="assistant")return"";let n=e.content;if(typeof n=="string")return n.trim();if(!Array.isArray(n))return"";let o=n.filter(i=>typeof i=="object"&&i&&i.type==="text").map(i=>i.text??"").map(i=>i.trim()).filter(Boolean);if(o.length>0)return o.join(`
38
+ {"riskLevel":"none|low|critical","reason":"brief explanation"}`;zn=Kn.join(p.sessionDir,"audit-logs")});import{readFileSync as Fr,existsSync as zr,chmodSync as Kr}from"node:fs";import Jn from"node:path";import{getOAuthProvider as Br}from"@mariozechner/pi-ai";function Z(){return xt||(xt=new St),xt}var St,xt,$t=F(()=>{"use strict";K();J();St=class{filePath;data={};constructor(t){this.filePath=t??Jn.join(p.agentDir,"multi-auth.json"),this.reload()}reload(){if(!zr(this.filePath)){this.data={};return}try{let t=Fr(this.filePath,"utf8");this.data=JSON.parse(t)}catch{this.data={}}}async save(){let t=Jn.dirname(this.filePath);await C(t),await ye(this.filePath,this.data);try{Kr(this.filePath,384)}catch{}}listAccounts(t){let n=this.data[t];return n?Object.entries(n.accounts).map(([r,o])=>({id:r,email:o.email,isDefault:n.defaultAccountId===r,lastUsedAt:o.lastUsedAt})):[]}async addAccount(t,n,r){this.data[t]||(this.data[t]={accounts:{}});let o=`acc_${re()}`,i=n,c=typeof r?.email=="string"?r.email:typeof i.email=="string"?i.email:void 0;return this.data[t].accounts[o]={type:"oauth",refresh:n.refresh,access:n.access,expires:n.expires,email:c,projectId:i.projectId,createdAt:Date.now(),lastUsedAt:Date.now()},this.data[t].defaultAccountId||(this.data[t].defaultAccountId=o),await this.save(),o}getAccount(t,n){return this.data[t]?.accounts[n]??null}getDefaultAccount(t){let n=this.data[t];if(!n?.defaultAccountId)return null;let r=n.accounts[n.defaultAccountId];return r?{id:n.defaultAccountId,credential:r}:null}async setDefaultAccount(t,n){let r=this.data[t];return r?.accounts[n]?(r.defaultAccountId=n,await this.save(),!0):!1}async removeAccount(t,n){let r=this.data[t];if(!r?.accounts[n])return!1;if(delete r.accounts[n],r.defaultAccountId===n){let o=Object.keys(r.accounts);r.defaultAccountId=o[0]}return Object.keys(r.accounts).length===0&&delete this.data[t],await this.save(),!0}async removeAllAccounts(t){let n=this.data[t];if(!n)return 0;let r=Object.keys(n.accounts).length;return delete this.data[t],await this.save(),r}async updateCredential(t,n,r){let o=this.data[t]?.accounts[n];if(!o)return;o.refresh=r.refresh,o.access=r.access,o.expires=r.expires,o.lastUsedAt=Date.now();let i=r;i.projectId!==void 0&&(o.projectId=i.projectId),await this.save()}async getApiKey(t,n){let r=this.data[t]?.accounts[n];if(!r)return null;let o=Br(t);if(!o)return null;let i=Date.now(),c=300*1e3;if(r.expires-i<c)try{let u={refresh:r.refresh,access:r.access,expires:r.expires,...r.projectId!==void 0&&{projectId:r.projectId}},l=await o.refreshToken(u);return await this.updateCredential(t,n,l),o.getApiKey(l)}catch(u){return console.warn(`[multi-auth] token refresh failed for ${t}/${n}:`,u),r.expires>i?o.getApiKey(r):null}return o.getApiKey(r)}hasMultipleAccounts(t){let n=this.data[t]?.accounts;return n?Object.keys(n).length>1:!1}hasAccounts(t){let n=this.data[t]?.accounts;return n?Object.keys(n).length>0:!1}},xt=null});import{chmodSync as Wr,existsSync as Jr,readFileSync as Hr}from"node:fs";import Hn from"node:path";function qr(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e,n=typeof t.apiKey=="string"?t.apiKey.trim():"",r=typeof t.baseUrl=="string"?t.baseUrl.trim():"",o=typeof t.updatedAt=="number"?t.updatedAt:Date.now();return!n&&!r?null:{...n?{apiKey:n}:{},...r?{baseUrl:r}:{},updatedAt:o}}function se(){return At||(At=new Mt),At}var Mt,At,kt=F(()=>{"use strict";K();J();Mt=class{filePath;data={};constructor(t){this.filePath=t??Hn.join(p.agentDir,"api-key-auth.json"),this.reload()}reload(){if(!Jr(this.filePath)){this.data={};return}try{let t=JSON.parse(Hr(this.filePath,"utf8"));if(!t||typeof t!="object"||Array.isArray(t)){this.data={};return}let n={};for(let[r,o]of Object.entries(t)){let i=qr(o);i&&(n[r]=i)}this.data=n}catch{this.data={}}}async save(){await C(Hn.dirname(this.filePath)),await ye(this.filePath,this.data);try{Wr(this.filePath,384)}catch{}}upsert(t){let n=this.data[t];if(n)return n;let r={updatedAt:Date.now()};return this.data[t]=r,r}cleanup(t){let n=this.data[t];n&&!n.apiKey&&!n.baseUrl&&delete this.data[t]}listProviders(){return Object.keys(this.data).sort((t,n)=>t.localeCompare(n))}getProviderConfig(t){let n=this.data[t];return n?{...n}:null}hasApiKey(t){return!!this.data[t]?.apiKey}async setApiKey(t,n){let r=this.upsert(t);r.apiKey=n.trim(),r.updatedAt=Date.now(),this.cleanup(t),await this.save()}async clearApiKey(t){let n=this.data[t];return n?.apiKey?(delete n.apiKey,n.updatedAt=Date.now(),this.cleanup(t),await this.save(),!0):!1}async setBaseUrl(t,n){let r=this.upsert(t);r.baseUrl=n.trim(),r.updatedAt=Date.now(),this.cleanup(t),await this.save()}async clearBaseUrl(t){let n=this.data[t];return n?.baseUrl?(delete n.baseUrl,n.updatedAt=Date.now(),this.cleanup(t),await this.save(),!0):!1}},At=null});import{createAgentSession as Vr,AuthStorage as Gr,ModelRegistry as Yr,SessionManager as Xr,SettingsManager as Qr,DefaultResourceLoader as Zr}from"@mariozechner/pi-coding-agent";import qe from"node:fs/promises";import Ve from"node:path";function qn(e){let t=e.trim().toLowerCase();return t==="codex"?"openai-codex":t}function ts(e){if(!e)return;let t=e.trim().toLowerCase();if(t==="oauth")return"oauth";if(t==="api_key"||t==="apikey")return"api_key"}function ns(e,t){let n=e.trim();if(!n)return{provider:t,modelId:""};if(n.includes("/")){let[r,o]=n.split("/",2);return{provider:r.trim()||t,modelId:o.trim()}}return{provider:t,modelId:n}}function os(e,t){return e!=="openai-codex"?t:es[t]??t}function Vn(e,t){let n=e.getAvailable().filter(o=>o.provider===t);return n.length>0?n[0]:e.getAll().filter(o=>o.provider===t)[0]}function rs(e,t,n){let r=Vn(e,t);if(r)return{...r,id:n,name:n}}function ss(e,t){let n=!!t?.provider?.trim(),r=!!t?.modelId?.trim(),o=qn(t?.provider||p.modelProvider||"openai-codex"),i=n||r?"":p.modelRef||"",{provider:c,modelId:u}=ns(i,o),l=t?.provider?o:qn(c),m=r?t?.modelId?.trim()||"":u;if(!m){let f=Vn(e,l);return f?{model:f,provider:l,modelId:f.id,syntheticModel:!1}:{model:void 0,provider:l,modelId:"",syntheticModel:!1}}let s=os(l,m),a=e.find(l,s);if(a)return{model:a,provider:l,modelId:s,syntheticModel:!1};let d=rs(e,l,s);return d?{model:d,provider:l,modelId:s,syntheticModel:!0}:{model:void 0,provider:l,modelId:s,syntheticModel:!1}}function is(e){let t=Q();return t?(e.setRuntimeApiKey("openai-codex",t.accessToken),{source:t.source,expiresAt:t.expiresAt}):null}function as(e){if(e?.role!=="assistant")return"";let n=e.content;if(typeof n=="string")return n.trim();if(!Array.isArray(n))return"";let r=n.filter(i=>typeof i=="object"&&i&&i.type==="text").map(i=>i.text??"").map(i=>i.trim()).filter(Boolean);if(r.length>0)return r.join(`
39
39
 
40
- `);let r=n.filter(i=>typeof i=="object"&&i&&i.type==="thinking").map(i=>i.thinking??"").map(i=>i.trim()).filter(Boolean);return r.length>0?r.join(`
40
+ `);let o=n.filter(i=>typeof i=="object"&&i&&i.type==="thinking").map(i=>i.thinking??"").map(i=>i.trim()).filter(Boolean);return o.length>0?o.join(`
41
41
 
42
- `):""}function is(e){if(e.length===0)return"messages=0";let t=e.slice(-6).map(n=>{let o=n?.role??"unknown",r=n.content,i=n?.stopReason,c=n?.errorMessage;if(typeof r=="string")return`${o}(text:${r.length}${i?`,stop=${i}`:""})`;if(Array.isArray(r)){let l=[`blocks:${r.map(m=>typeof m=="object"&&m&&"type"in m?String(m.type||"unknown"):typeof m).join(",")||"none"}`,i?`stop=${i}`:null,c?"error=1":null].filter(Boolean).join(",");return`${o}(${l})`}if(r==null){let u=["empty",i?`stop=${i}`:null,c?"error=1":null].filter(Boolean).join(",");return`${o}(${u})`}return`${o}(${typeof r}${i?`,stop=${i}`:""})`});return`messages=${e.length} last=[${t.join(" ")}]`}function as(e){let t=e.trim();return t.toLowerCase().includes("usage limit")?`${t}
42
+ `):""}function cs(e){if(e.length===0)return"messages=0";let t=e.slice(-6).map(n=>{let r=n?.role??"unknown",o=n.content,i=n?.stopReason,c=n?.errorMessage;if(typeof o=="string")return`${r}(text:${o.length}${i?`,stop=${i}`:""})`;if(Array.isArray(o)){let l=[`blocks:${o.map(m=>typeof m=="object"&&m&&"type"in m?String(m.type||"unknown"):typeof m).join(",")||"none"}`,i?`stop=${i}`:null,c?"error=1":null].filter(Boolean).join(",");return`${r}(${l})`}if(o==null){let u=["empty",i?`stop=${i}`:null,c?"error=1":null].filter(Boolean).join(",");return`${r}(${u})`}return`${r}(${typeof o}${i?`,stop=${i}`:""})`});return`messages=${e.length} last=[${t.join(" ")}]`}function ls(e){let t=e.trim();return t.toLowerCase().includes("usage limit")?`${t}
43
43
 
44
- Suggestion: wait for the limit to reset or switch to another provider/model.`:t}function cs(e,t){let n=t?.getLastAssistantText?.();if(n?.trim())return n.trim();for(let o=e.length-1;o>=0;o-=1){let r=ss(e[o]);if(r)return r}return""}function ls(e){for(let t=e.length-1;t>=0;t-=1)if(e[t]?.role==="assistant")return e[t]}async function Ve(e){let t=e.workspaceDir||f.workspaceDir;await C(f.sessionDir),await C(f.agentDir),await C(t);let n=pt(e.chatId,e.sessionId),o=Ge.join(f.agentDir,"auth.json"),r=new qr(o),i=rs(r);i&&console.log(`[tg-agent] codex oauth source=${i.source} expiresAt=${new Date(i.expiresAt).toISOString()}`);let c=e.modelProvider||f.modelProvider,u=Zr(e.authMode),l=Ge.join(f.agentDir,"models.json"),m=new Gr(r,l);if(u==="api_key"){let A=se().getProviderConfig(c),O=A?.apiKey?.trim();if(!O)throw new Error(`API key mode selected for ${c}, but no key is configured. Use /apikey ${c} <key>.`);r.setRuntimeApiKey(c,O),A?.baseUrl&&(m.registerProvider(c,{baseUrl:A.baseUrl}),console.log(`[tg-agent] api-key-auth: using endpoint=${A.baseUrl} for ${c}`)),console.log(`[tg-agent] api-key-auth: enabled for ${c}`)}let s=Q();if(u!=="api_key"&&e.accountId){let v=await s.getApiKey(c,e.accountId);v?(r.setRuntimeApiKey(c,v),console.log(`[tg-agent] multi-auth: using account=${e.accountId} for ${c}`)):console.warn(`[tg-agent] multi-auth: account not found ${c}/${e.accountId}`)}else if(u!=="api_key"&&s.hasAccounts(c)){let v=s.getDefaultAccount(c);if(v){let A=await s.getApiKey(c,v.id);A&&(r.setRuntimeApiKey(c,A),console.log(`[tg-agent] multi-auth: using default account=${v.id} for ${c}`))}}let{model:a,provider:d,modelId:p,syntheticModel:h}=os(m,{provider:e.modelProvider,modelId:e.modelId});p&&!a?console.warn(`[tg-agent] model not found: ${d}/${p}`):h&&console.log(`[tg-agent] model override: using custom model id ${d}/${p} via provider template`);let y=Vr.open(n),w=Yr.create(t,f.agentDir);try{let v=Ge.join(f.agentDir,"skills"),A=Ge.join(t,".pi","skills"),O=await qe.access(v).then(()=>!0).catch(()=>!1),E=await qe.access(A).then(()=>!0).catch(()=>!1);if(O){let ne=(await qe.readdir(v,{withFileTypes:!0})).filter(G=>G.isDirectory()).map(G=>G.name);console.log(`[tg-agent] skills directory found at ${v} with ${ne.length} skill(s): ${ne.join(", ")}`)}else console.log(`[tg-agent] skills directory not found at ${v}`);if(E){let ne=(await qe.readdir(A,{withFileTypes:!0})).filter(G=>G.isDirectory()).map(G=>G.name);console.log(`[tg-agent] workspace skills directory found at ${A} with ${ne.length} skill(s): ${ne.join(", ")}`)}let q=w.getSettings?.();if(q){let ne=q.skills?.enabled!==!1;console.log(`[tg-agent] skills enabled in settings: ${ne}`)}}catch(v){let A=v instanceof Error?v.message:String(v);console.warn(`[tg-agent] skills check failed: ${A}`)}let x="";try{x=await me(f.agentDir,{timeoutMs:4e3,maxBytes:f.fetchMaxBytes,maxChars:3e3})}catch(v){let A=v instanceof Error?v.message:String(v);console.warn(`[tg-agent] mcp catalog error: ${A}`)}let M=[];if(f.audit.enabled&&e.auditContext){let v={...e.auditContext,sessionId:e.sessionId},A;if(f.audit.modelProvider&&f.audit.modelId){let O=m.find(f.audit.modelProvider,f.audit.modelId);if(O){let E=await r.getApiKey(f.audit.modelProvider);A={provider:f.audit.modelProvider,model:O,apiKey:E??void 0},console.log(`[tg-agent] audit model: ${f.audit.modelProvider}/${f.audit.modelId} apiKey=${E?"present":"missing"}`)}else console.warn(`[tg-agent] audit model not found: ${f.audit.modelProvider}/${f.audit.modelId}`)}M.push(Bn(v,A)),console.log(`[tg-agent] security audit enabled for session ${e.sessionId}`)}let S=e.systemPrompt?.trim(),P=[];S&&P.push(S),x&&P.push(x);let U=P.length>0?P.join(`
44
+ Suggestion: wait for the limit to reset or switch to another provider/model.`:t}function us(e,t){let n=t?.getLastAssistantText?.();if(n?.trim())return n.trim();for(let r=e.length-1;r>=0;r-=1){let o=as(e[r]);if(o)return o}return""}function ds(e){for(let t=e.length-1;t>=0;t-=1)if(e[t]?.role==="assistant")return e[t]}async function Ge(e){let t=e.workspaceDir||p.workspaceDir;await C(p.sessionDir),await C(p.agentDir),await C(t);let n=gt(e.chatId,e.sessionId),r=Ve.join(p.agentDir,"auth.json"),o=new Gr(r),i=is(o);i&&console.log(`[tg-agent] codex oauth source=${i.source} expiresAt=${new Date(i.expiresAt).toISOString()}`);let c=e.modelProvider||p.modelProvider,u=ts(e.authMode),l=Ve.join(p.agentDir,"models.json"),m=new Yr(o,l);if(u==="api_key"){let A=se().getProviderConfig(c),j=A?.apiKey?.trim();if(!j)throw new Error(`API key mode selected for ${c}, but no key is configured. Use /apikey ${c} <key>.`);o.setRuntimeApiKey(c,j),A?.baseUrl&&(m.registerProvider(c,{baseUrl:A.baseUrl}),console.log(`[tg-agent] api-key-auth: using endpoint=${A.baseUrl} for ${c}`)),console.log(`[tg-agent] api-key-auth: enabled for ${c}`)}let s=Z();if(u!=="api_key"&&e.accountId){let v=await s.getApiKey(c,e.accountId);v?(o.setRuntimeApiKey(c,v),console.log(`[tg-agent] multi-auth: using account=${e.accountId} for ${c}`)):console.warn(`[tg-agent] multi-auth: account not found ${c}/${e.accountId}`)}else if(u!=="api_key"&&s.hasAccounts(c)){let v=s.getDefaultAccount(c);if(v){let A=await s.getApiKey(c,v.id);A&&(o.setRuntimeApiKey(c,A),console.log(`[tg-agent] multi-auth: using default account=${v.id} for ${c}`))}}let{model:a,provider:d,modelId:f,syntheticModel:h}=ss(m,{provider:e.modelProvider,modelId:e.modelId});f&&!a?console.warn(`[tg-agent] model not found: ${d}/${f}`):h&&console.log(`[tg-agent] model override: using custom model id ${d}/${f} via provider template`);let y=Xr.open(n),w=Qr.create(t,p.agentDir);try{let v=Ve.join(p.agentDir,"skills"),A=Ve.join(t,".pi","skills"),j=await qe.access(v).then(()=>!0).catch(()=>!1),D=await qe.access(A).then(()=>!0).catch(()=>!1);if(j){let oe=(await qe.readdir(v,{withFileTypes:!0})).filter(V=>V.isDirectory()).map(V=>V.name);console.log(`[tg-agent] skills directory found at ${v} with ${oe.length} skill(s): ${oe.join(", ")}`)}else console.log(`[tg-agent] skills directory not found at ${v}`);if(D){let oe=(await qe.readdir(A,{withFileTypes:!0})).filter(V=>V.isDirectory()).map(V=>V.name);console.log(`[tg-agent] workspace skills directory found at ${A} with ${oe.length} skill(s): ${oe.join(", ")}`)}let q=w.getSettings?.();if(q){let oe=q.skills?.enabled!==!1;console.log(`[tg-agent] skills enabled in settings: ${oe}`)}}catch(v){let A=v instanceof Error?v.message:String(v);console.warn(`[tg-agent] skills check failed: ${A}`)}let x="";try{x=await me(p.agentDir,{timeoutMs:4e3,maxBytes:p.fetchMaxBytes,maxChars:3e3})}catch(v){let A=v instanceof Error?v.message:String(v);console.warn(`[tg-agent] mcp catalog error: ${A}`)}let M=[];if(p.audit.enabled&&e.auditContext){let v={...e.auditContext,sessionId:e.sessionId},A;if(p.audit.modelProvider&&p.audit.modelId){let j=m.find(p.audit.modelProvider,p.audit.modelId);if(j){let D=await o.getApiKey(p.audit.modelProvider);A={provider:p.audit.modelProvider,model:j,apiKey:D??void 0},console.log(`[tg-agent] audit model: ${p.audit.modelProvider}/${p.audit.modelId} apiKey=${D?"present":"missing"}`)}else console.warn(`[tg-agent] audit model not found: ${p.audit.modelProvider}/${p.audit.modelId}`)}M.push(Bn(v,A)),console.log(`[tg-agent] security audit enabled for session ${e.sessionId}`)}let S=e.systemPrompt?.trim(),_=[];S&&_.push(S),x&&_.push(x);let I=_.length>0?_.join(`
45
45
 
46
- `):void 0;console.log(`[tg-agent] systemPrompt append=${U?U.slice(0,80)+"...":"(none)"}`);let $=new Xr({cwd:t,agentDir:f.agentDir,settingsManager:w,extensionFactories:M.length>0?M:void 0,appendSystemPrompt:U});await $.reload();let{session:b,modelFallbackMessage:k}=await Hr({cwd:t,agentDir:f.agentDir,authStorage:r,modelRegistry:m,model:a??void 0,sessionManager:y,settingsManager:w,resourceLoader:$,customTools:Tn({telegram:e.telegram})});try{let v=b.messages,A=v.some(z=>{let ne=z.role,G=z.content;return ne==="system"&&typeof G=="string"?G.toLowerCase().includes("compaction")||G.toLowerCase().includes("compact"):z.type==="compaction"||z.compaction!==void 0});console.log(`[tg-agent] session manager type: ${typeof y}`),console.log(`[tg-agent] session messages count: ${v.length}`),console.log(`[tg-agent] compacting support detected: ${A||"unknown (will be detected during runtime)"}`);let E=typeof y.compact=="function",q=typeof y.appendCompaction=="function";console.log(`[tg-agent] SessionManager.compact method: ${E}`),console.log(`[tg-agent] SessionManager.appendCompaction method: ${q}`)}catch(v){let A=v instanceof Error?v.message:String(v);console.warn(`[tg-agent] compacting check failed: ${A}`)}k&&console.warn(`[tg-agent] modelFallback=${k}`);let F=!1,qt=()=>{F=!0,b.abort()};e.onAbortReady?.(qt);let ae=f.logAgentEvents,rt=f.logAgentStream,st=new Map,Co=b.subscribe(v=>{switch(v.type){case"agent_start":ae&&console.log(`[tg-agent] agent start session=${e.sessionId}`),B=Date.now(),e.onStatus?.({type:"agent_start"});break;case"agent_end":ae&&console.log(`[tg-agent] agent end session=${e.sessionId}`),e.onStatus?.({type:"agent_end"});break;case"turn_start":ae&&console.log(`[tg-agent] turn start session=${e.sessionId}`),B=Date.now(),e.onStatus?.({type:"turn_start"});break;case"turn_end":ae&&console.log(`[tg-agent] turn end session=${e.sessionId} toolResults=${v.toolResults.length}`),B=Date.now(),e.onStatus?.({type:"turn_end",toolResults:v.toolResults.length});break;case"message_start":{if(ae){let A=v.message.role??"unknown";console.log(`[tg-agent] message start session=${e.sessionId} role=${A}`)}B=Date.now();{let A=v.message.role??"unknown";e.onStatus?.({type:"message_start",role:A})}break}case"message_end":{if(ae){let A=v.message.role??"unknown";console.log(`[tg-agent] message end session=${e.sessionId} role=${A}`)}B=Date.now();{let A=v.message.role??"unknown";e.onStatus?.({type:"message_end",role:A})}break}case"message_update":{if(!rt)break;if(v.assistantMessageEvent.type==="text_delta"){let O=(v.assistantMessageEvent.delta??"").length;O>0&&console.log(`[tg-agent] stream delta session=${e.sessionId} chars=${O}`),B=Date.now()}v.assistantMessageEvent.type==="thinking_delta"&&(B=Date.now());break}case"tool_execution_start":{st.set(v.toolCallId,Date.now()),console.log(`[tg-agent] tool start name=${v.toolName} id=${v.toolCallId}`),Ne+=1,B=Date.now(),e.onStatus?.({type:"tool_start",name:v.toolName,id:v.toolCallId,args:v.args});break}case"tool_execution_end":{let A=st.get(v.toolCallId),O=A?Date.now()-A:0;console.log(`[tg-agent] tool end name=${v.toolName} id=${v.toolCallId} ok=${!v.isError} durationMs=${O}`),st.delete(v.toolCallId),Ne=Math.max(0,Ne-1),B=Date.now(),e.onStatus?.({type:"tool_end",name:v.toolName,id:v.toolCallId,ok:!v.isError,durationMs:O});break}case"auto_compaction_start":{let A=v.reason??"unknown";console.log(`[tg-agent] auto compaction started session=${e.sessionId} reason=${A}`),B=Date.now();break}case"auto_compaction_end":{let A=v.willRetry??!1;console.log(`[tg-agent] auto compaction ended session=${e.sessionId} willRetry=${A}`),B=Date.now();break}default:break}}),$e=null,it=null,Oe=!1,Gt=0,Vt=!1,B=Date.now(),Ne=0;try{let v=Date.now();$e=setInterval(()=>{let E=Date.now()-v;console.log(`[tg-agent] prompt running session=${e.sessionId} elapsedMs=${E} streaming=${b.isStreaming}`),e.onStatus?.({type:"heartbeat",elapsedMs:E,streaming:b.isStreaming})},15e3),it=setInterval(()=>{if(Oe||Ne>0)return;let E=Date.now()-B,q=b.isStreaming?f.modelTimeoutStreamingMs:f.modelTimeoutMs,z=Math.max(1e3,q);E>=z&&(Oe=!0,Gt=z,Vt=b.isStreaming,console.warn(`[tg-agent] model timeout session=${e.sessionId} elapsedMs=${E}`),b.abort())},2e3);try{if(await b.prompt(e.prompt,e.images&&e.images.length>0?{images:e.images}:void 0),Oe)throw new Error(`Model request timed out after ${f.modelTimeoutMs}ms`)}catch(E){if(F)throw new Error("Cancelled by user.");if(Oe){let q=Vt?" (streaming)":"",z=Gt||f.modelTimeoutMs;throw new Error(`Model request timed out after ${z}ms${q}`)}throw E}$e&&clearInterval($e);let A=ls(b.messages);if(A){let E=A?.stopReason,q=A?.errorMessage;if(E==="error"){let z=q?as(q):"Model error without details.";throw console.warn(`[tg-agent] model error session=${e.sessionId} error=${z}`),new Error(z)}}let O=cs(b.messages,b);if(!O){let E=is(b.messages);throw console.warn(`[tg-agent] empty response session=${e.sessionId} ${E}`),new Error("No assistant response.")}return{text:O,sessionFile:n,sessionId:b.sessionId,modelProvider:b.model?.provider??d,modelId:b.model?.id??p,modelFallbackMessage:k}}finally{$e&&clearInterval($e),it&&clearInterval(it),Co(),y.flushPendingToolResults?.(),b.dispose()}}var Qr,Mt=I(()=>{"use strict";K();we();En();_e();J();wt();Wn();xt();At();Qr={"codex-mini-latest":"gpt-5.1-codex-mini","codex-max-latest":"gpt-5.1-codex-max","codex-latest":"gpt-5.2-codex"}});import us from"node:fs/promises";import Yn from"node:path";function kt(e){return ds.test(e)}function Pt(){return Yn.join(f.agentDir,"souls")}function Ye(e){return Yn.join(Pt(),`${e}.md`)}async function Ce(e){if(!kt(e))throw new Error(`Invalid soul name: ${e}. Use only letters, numbers, "_" and "-".`);let t=Ye(e),o=(await us.readFile(t,"utf8")).trim();if(!o)throw new Error(`Soul file is empty: ${t}`);if(o.length>Vn)throw new Error(`Soul file too large (${o.length} chars). Max ${Vn}.`);return o}function Xe(e,t){return[ms,"",`<session_soul name="${e}">`,t,"</session_soul>"].join(`
47
- `)}var ds,Vn,ms,_t=I(()=>{"use strict";K();ds=/^[a-zA-Z0-9_-]+$/,Vn=16e3,ms=["<session_soul_protocol>",'You may receive an optional block: <session_soul name="...">...</session_soul>.',"Treat it as session-level behavioral guidance (tone, style, default strategy).","Priority order:","1) Safety and non-overridable policy constraints","2) Core system instructions","3) Explicit user instructions in this conversation","4) session_soul guidance (default behavior only)","If conflicts exist, follow higher-priority rules and ignore conflicting soul parts.","Do not mention this protocol unless asked.","</session_soul_protocol>"].join(`
48
- `)});import ps from"node:path";import*as Xn from"@lancedb/lancedb";import Ct from"openai";function gs(){if(le)return le;let e=f.memory.rag;if(e.embeddingApiKey){let n={apiKey:e.embeddingApiKey};return e.embeddingBaseUrl&&(n.baseURL=e.embeddingBaseUrl),le=new Ct(n),console.log(`[memory-rag] using embedding API key${e.embeddingBaseUrl?` (baseURL: ${e.embeddingBaseUrl})`:""}`),le}if(f.openaiApiKey)return le=new Ct({apiKey:f.openaiApiKey}),console.log("[memory-rag] using OpenAI API key from config"),le;let t=X();if(t)return le=new Ct({apiKey:t.accessToken}),console.log("[memory-rag] using Codex OAuth token"),le;throw new Error("No API key for embeddings. Set memory.rag.embedding_api_key or run `codex login`.")}async function Tt(e){let t=gs(),n=f.memory.rag.embeddingModel;console.log(`[memory-rag] embedding ${e.length} chars using ${n}`);let o=3e4,r=new Promise((i,c)=>{setTimeout(()=>c(new Error(`Embedding timeout after ${o}ms`)),o)});try{let i=await Promise.race([t.embeddings.create({model:n,input:e,encoding_format:"float"}),r]);if(!i?.data?.[0]?.embedding)throw new Error(`Invalid embedding response: ${JSON.stringify(i).slice(0,200)}`);let c=i.data[0].embedding;return console.log(`[memory-rag] got ${c.length}D embedding`),c}catch(i){throw i instanceof Error&&console.error(`[memory-rag] embedding error: ${i.message}`),i}}async function xe(){return Qe||(await C(Rt),Qe=await Xn.connect(Rt),console.log(`[memory-rag] connected to DB at ${Rt}`),Qe)}async function Ze(e,t,n,o,r){let i={sessionSaved:!1,memoriesIndexed:0,errors:[]};if(!f.memory.rag.enabled)return console.log("[memory-rag] RAG disabled, skipping save"),i;console.log(`[memory-rag] saving session ${e}`);try{let c=await xe(),u=await c.tableNames(),l={sessionId:e,date:t,title:n,transcript:o,reflection:JSON.stringify(r),memoryCount:r.memories?.length??0,timestamp:Date.now()};if(u.includes(ue)?await(await c.openTable(ue)).add([l]):await c.createTable(ue,[l]),i.sessionSaved=!0,console.log("[memory-rag] session saved to DB"),r.memories&&r.memories.length>0){let m=await hs(e,t,r.memories);i.memoriesIndexed=m.indexed,i.errors=m.errors}return i}catch(c){let u=c instanceof Error?c.message:String(c);return console.error(`[memory-rag] saveSession failed: ${u}`),i.errors.push(u),i}}async function ys(){try{let e=await xe();return(await e.tableNames()).includes(ue)?(await(await e.openTable(ue)).query().toArray()).map(r=>({sessionId:r.sessionId,date:r.date,title:r.title,transcript:r.transcript,reflection:r.reflection,memoryCount:r.memoryCount,timestamp:r.timestamp})):[]}catch(e){return console.error(`[memory-rag] getAllSessions failed: ${e}`),[]}}async function hs(e,t,n){let o={indexed:0,errors:[]};if(!f.memory.rag.enabled||n.length===0)return o;console.log(`[memory-rag] indexing ${n.length} memories for session ${e}`);try{let r=await xe(),i=await r.tableNames(),c,u=!1;i.includes(Z)?c=await r.openTable(Z):u=!0;for(let l=0;l<n.length;l++){let m=n[l];try{let s=await Tt(m.content),a={id:`${e}-${l}`,sessionId:e,date:t,type:m.type,content:m.content,vector:s,timestamp:Date.now()};u?(c=await r.createTable(Z,[a]),u=!1,console.log("[memory-rag] created memories table")):await c.add([a]),o.indexed++,console.log(`[memory-rag] indexed [${l+1}/${n.length}]: ${m.type}`)}catch(s){let a=s instanceof Error?s.message:String(s);o.errors.push(`${m.type}: ${a}`),console.error(`[memory-rag] failed to index item ${l}: ${a}`)}l<n.length-1&&await new Promise(s=>setTimeout(s,200))}return console.log(`[memory-rag] indexed ${o.indexed}/${n.length} memories`),o}catch(r){let i=r instanceof Error?r.message:String(r);return console.error(`[memory-rag] indexMemoryItems failed: ${i}`),o.errors.push(i),o}}async function Qn(e,t=f.memory.rag.maxResults,n=f.memory.rag.similarityThreshold){if(!f.memory.rag.enabled)return[];console.log(`[memory-rag] searching: "${e.slice(0,50)}..."`);try{let o=await xe();if(!(await o.tableNames()).includes(Z))return console.log("[memory-rag] memories table not found"),[];let i=await o.openTable(Z),c=await i.countRows();console.log(`[memory-rag] memories table has ${c} rows`);let u=await Tt(e),l=await i.vectorSearch(u).column(fs).limit(t*2).toArray();if(console.log(`[memory-rag] search returned ${l.length} results`),l.length>0){let a=l.map(d=>d._distance?.toFixed(4)??"N/A");console.log(`[memory-rag] distances: [${a.join(", ")}]`)}let m=(1-n)*2;console.log(`[memory-rag] threshold=${n}, maxDistance=${m.toFixed(4)}`);let s=l.filter(a=>{let d=a._distance;return d===void 0||d<=m}).slice(0,t).map(a=>({id:a.id,sessionId:a.sessionId,date:a.date,type:a.type,content:a.content,timestamp:a.timestamp,_distance:a._distance}));return console.log(`[memory-rag] filtered: ${s.length} memories`),s.length>0&&s.forEach((a,d)=>{console.log(`[memory-rag] ${d+1}. [${a.type}] "${a.content.slice(0,50)}..." (dist=${a._distance?.toFixed(4)??"N/A"})`)}),s}catch(o){let r=o instanceof Error?o.message:String(o);return console.warn(`[memory-rag] search failed: ${r}`),[]}}async function Zn(){try{let e=await xe(),t=await e.tableNames(),n=0,o=0;return t.includes(ue)&&(n=await(await e.openTable(ue)).countRows()),t.includes(Z)&&(o=await(await e.openTable(Z)).countRows()),{sessionsCount:n,memoriesCount:o,embeddingModel:f.memory.rag.embeddingModel}}catch{return{sessionsCount:0,memoriesCount:0,embeddingModel:f.memory.rag.embeddingModel}}}async function eo(e){let t={success:!1,totalSessions:0,totalMemories:0,indexedMemories:0,errors:[],embeddingModel:f.memory.rag.embeddingModel,vectorDimension:null};console.log("[reindex] ========================================"),console.log("[reindex] Rebuilding memories from sessions table"),console.log(`[reindex] Embedding model: ${f.memory.rag.embeddingModel}`),console.log("[reindex] ========================================");try{let n=await xe(),o=await n.tableNames();if(!o.includes(ue))return console.log("[reindex] No sessions table found, nothing to reindex"),t.success=!0,t;let r=await ys();if(t.totalSessions=r.length,r.length===0)return console.log("[reindex] No sessions found"),t.success=!0,t;console.log(`[reindex] Found ${r.length} sessions`);let i=[];for(let u of r)try{let l=JSON.parse(u.reflection);if(l.memories&&l.memories.length>0)for(let m of l.memories)i.push({sessionId:u.sessionId,date:u.date,item:m})}catch(l){console.warn(`[reindex] Failed to parse reflection for session ${u.sessionId}: ${l}`)}if(t.totalMemories=i.length,console.log(`[reindex] Found ${i.length} memories to reindex`),i.length===0)return console.log("[reindex] No memories to reindex"),t.success=!0,t;o.includes(Z)&&(await n.dropTable(Z),console.log("[reindex] Dropped old memories table"));let c=null;for(let u=0;u<i.length;u++){let{sessionId:l,date:m,item:s}=i[u],a=`[${u+1}/${i.length}]`;try{e?.(u+1,i.length,`Indexing: ${s.content.slice(0,30)}...`);let d=await Tt(s.content);t.vectorDimension===null&&(t.vectorDimension=d.length);let p={id:`${l}-${u}`,sessionId:l,date:m,type:s.type,content:s.content,vector:d,timestamp:Date.now()};c===null?(c=await n.createTable(Z,[p]),console.log(`[reindex] ${a} Created new memories table`)):await c.add([p]),t.indexedMemories++,console.log(`[reindex] ${a} Indexed: [${s.type}] ${s.content.slice(0,40)}...`)}catch(d){let p=d instanceof Error?d.message:String(d);t.errors.push(`${s.content.slice(0,30)}: ${p}`),console.error(`[reindex] ${a} Failed: ${p}`)}u<i.length-1&&await new Promise(d=>setTimeout(d,200))}return console.log("[reindex] ========================================"),console.log("[reindex] Reindex complete!"),console.log(`[reindex] Sessions: ${t.totalSessions}`),console.log(`[reindex] Total memories: ${t.totalMemories}`),console.log(`[reindex] Indexed: ${t.indexedMemories}`),console.log(`[reindex] Errors: ${t.errors.length}`),console.log("[reindex] ========================================"),t.success=!0,t}catch(n){let o=n instanceof Error?n.message:String(n);return console.error(`[reindex] Failed: ${o}`),t.errors.push(o),t}}var Rt,ue,Z,fs,Qe,le,Et=I(()=>{"use strict";K();J();we();Rt=ps.join(f.agentDir,"tg-memory-db"),ue="sessions",Z="memories",fs="vector",Qe=null,le=null});import to from"node:path";import{AuthStorage as ws,ModelRegistry as bs}from"@mariozechner/pi-coding-agent";import{completeSimple as vs,getModel as xs}from"@mariozechner/pi-ai";function $s(){return f.memory.systemPrompt||Ss}function Ms(e){let t=e.trim().toLowerCase();return t==="codex"?"openai-codex":t}function ks(e,t){return e!=="openai-codex"?t:As[t]??t}async function Ps(e,t){await C(f.agentDir);let n=to.join(f.agentDir,"auth.json"),o=new ws(n),r=X();r&&o.setRuntimeApiKey("openai-codex",r.accessToken);let i=to.join(f.agentDir,"models.json"),c=new bs(o,i),u=async(a,d,p)=>{let h=Ms(a),y=ks(h,d),w=c.find(h,y);if(!w)try{w=xs(h,y)}catch{}if(w){let x=await o.getApiKey(h);return{model:w,provider:h,modelId:y,apiKey:x??void 0,source:p}}return null};if(e&&t){let a=await u(e,t,"session");if(a)return console.log(`[memory] using session model: ${a.provider}/${a.modelId}`),a}if(f.memory.modelProvider&&f.memory.modelId){let a=await u(f.memory.modelProvider,f.memory.modelId,"memory-config");if(a)return console.log(`[memory] using configured memory model: ${a.provider}/${a.modelId}`),a}let l=f.modelProvider,m=f.modelRef.includes("/")?f.modelRef.split("/")[1]:f.modelRef;if(l&&m){let a=await u(l,m,"system-default");if(a)return console.log(`[memory] using system default model: ${a.provider}/${a.modelId}`),a}let s=c.getAll();if(s.length>0){let a=s[0],d=await o.getApiKey(a.provider);return console.log(`[memory] using first available model: ${a.provider}/${a.id}`),{model:a,provider:a.provider,modelId:a.id,apiKey:d??void 0,source:"first-available"}}return console.warn("[memory] no model available for reflection"),null}function _s(e){let t={emotional:"",insights:"",advice:"",memories:[]};if(!e.trim())return t;try{let n=e.trim(),o=n.match(/```(?:json)?\s*([\s\S]*?)```/);o&&(n=o[1].trim());let r=JSON.parse(n),i={emotional:typeof r.emotional=="string"?r.emotional:"",insights:typeof r.insights=="string"?r.insights:"",advice:typeof r.advice=="string"?r.advice:"",memories:[]};if(Array.isArray(r.memories))for(let c of r.memories)c&&typeof c=="object"&&typeof c.type=="string"&&typeof c.content=="string"&&i.memories.push({type:c.type,content:c.content});return i}catch(n){return console.warn(`[memory] failed to parse reflection JSON: ${n}`),{emotional:"",insights:e.slice(0,500),advice:"",memories:[{type:"insight",content:`Session summary: ${e.slice(0,200)}`}]}}}async function et(e,t,n){if(!f.memory.enabled)return{success:!0,reflected:!1,memoriesIndexed:0};if(e.messages.length===0)return{success:!0,reflected:!1,memoriesIndexed:0};let r=new Date().toISOString().split("T")[0],i=e.messages.map(u=>`[${u.role.toUpperCase()}]: ${u.content}`).join(`
46
+ `):void 0;console.log(`[tg-agent] systemPrompt append=${I?I.slice(0,80)+"...":"(none)"}`);let $=new Zr({cwd:t,agentDir:p.agentDir,settingsManager:w,extensionFactories:M.length>0?M:void 0,appendSystemPrompt:I});await $.reload();let{session:b,modelFallbackMessage:k}=await Vr({cwd:t,agentDir:p.agentDir,authStorage:o,modelRegistry:m,model:a??void 0,sessionManager:y,settingsManager:w,resourceLoader:$,customTools:Tn({telegram:e.telegram})});try{let v=b.messages,A=v.some(z=>{let oe=z.role,V=z.content;return oe==="system"&&typeof V=="string"?V.toLowerCase().includes("compaction")||V.toLowerCase().includes("compact"):z.type==="compaction"||z.compaction!==void 0});console.log(`[tg-agent] session manager type: ${typeof y}`),console.log(`[tg-agent] session messages count: ${v.length}`),console.log(`[tg-agent] compacting support detected: ${A||"unknown (will be detected during runtime)"}`);let D=typeof y.compact=="function",q=typeof y.appendCompaction=="function";console.log(`[tg-agent] SessionManager.compact method: ${D}`),console.log(`[tg-agent] SessionManager.appendCompaction method: ${q}`)}catch(v){let A=v instanceof Error?v.message:String(v);console.warn(`[tg-agent] compacting check failed: ${A}`)}k&&console.warn(`[tg-agent] modelFallback=${k}`);let E=!1,Gt=()=>{E=!0,b.abort()};e.onAbortReady?.(Gt);let ae=p.logAgentEvents,rt=p.logAgentStream,st=new Map,Co=b.subscribe(v=>{switch(v.type){case"agent_start":ae&&console.log(`[tg-agent] agent start session=${e.sessionId}`),B=Date.now(),e.onStatus?.({type:"agent_start"});break;case"agent_end":ae&&console.log(`[tg-agent] agent end session=${e.sessionId}`),e.onStatus?.({type:"agent_end"});break;case"turn_start":ae&&console.log(`[tg-agent] turn start session=${e.sessionId}`),B=Date.now(),e.onStatus?.({type:"turn_start"});break;case"turn_end":ae&&console.log(`[tg-agent] turn end session=${e.sessionId} toolResults=${v.toolResults.length}`),B=Date.now(),e.onStatus?.({type:"turn_end",toolResults:v.toolResults.length});break;case"message_start":{if(ae){let A=v.message.role??"unknown";console.log(`[tg-agent] message start session=${e.sessionId} role=${A}`)}B=Date.now();{let A=v.message.role??"unknown";e.onStatus?.({type:"message_start",role:A})}break}case"message_end":{if(ae){let A=v.message.role??"unknown";console.log(`[tg-agent] message end session=${e.sessionId} role=${A}`)}B=Date.now();{let A=v.message.role??"unknown";e.onStatus?.({type:"message_end",role:A})}break}case"message_update":{if(!rt)break;if(v.assistantMessageEvent.type==="text_delta"){let j=(v.assistantMessageEvent.delta??"").length;j>0&&console.log(`[tg-agent] stream delta session=${e.sessionId} chars=${j}`),B=Date.now()}v.assistantMessageEvent.type==="thinking_delta"&&(B=Date.now());break}case"tool_execution_start":{st.set(v.toolCallId,Date.now()),console.log(`[tg-agent] tool start name=${v.toolName} id=${v.toolCallId}`),Ne+=1,B=Date.now(),e.onStatus?.({type:"tool_start",name:v.toolName,id:v.toolCallId,args:v.args});break}case"tool_execution_end":{let A=st.get(v.toolCallId),j=A?Date.now()-A:0;console.log(`[tg-agent] tool end name=${v.toolName} id=${v.toolCallId} ok=${!v.isError} durationMs=${j}`),st.delete(v.toolCallId),Ne=Math.max(0,Ne-1),B=Date.now(),e.onStatus?.({type:"tool_end",name:v.toolName,id:v.toolCallId,ok:!v.isError,durationMs:j});break}case"auto_compaction_start":{let A=v.reason??"unknown";console.log(`[tg-agent] auto compaction started session=${e.sessionId} reason=${A}`),B=Date.now();break}case"auto_compaction_end":{let A=v.willRetry??!1;console.log(`[tg-agent] auto compaction ended session=${e.sessionId} willRetry=${A}`),B=Date.now();break}default:break}}),$e=null,it=null,Oe=!1,Yt=0,Xt=!1,B=Date.now(),Ne=0;try{let v=Date.now();$e=setInterval(()=>{let D=Date.now()-v;console.log(`[tg-agent] prompt running session=${e.sessionId} elapsedMs=${D} streaming=${b.isStreaming}`),e.onStatus?.({type:"heartbeat",elapsedMs:D,streaming:b.isStreaming})},15e3),it=setInterval(()=>{if(Oe||Ne>0)return;let D=Date.now()-B,q=b.isStreaming?p.modelTimeoutStreamingMs:p.modelTimeoutMs,z=Math.max(1e3,q);D>=z&&(Oe=!0,Yt=z,Xt=b.isStreaming,console.warn(`[tg-agent] model timeout session=${e.sessionId} elapsedMs=${D}`),b.abort())},2e3);try{if(await b.prompt(e.prompt,e.images&&e.images.length>0?{images:e.images}:void 0),Oe)throw new Error(`Model request timed out after ${p.modelTimeoutMs}ms`)}catch(D){if(E)throw new Error("Cancelled by user.");if(Oe){let q=Xt?" (streaming)":"",z=Yt||p.modelTimeoutMs;throw new Error(`Model request timed out after ${z}ms${q}`)}throw D}$e&&clearInterval($e);let A=ds(b.messages);if(A){let D=A?.stopReason,q=A?.errorMessage;if(D==="error"){let z=q?ls(q):"Model error without details.";throw console.warn(`[tg-agent] model error session=${e.sessionId} error=${z}`),new Error(z)}}let j=us(b.messages,b);if(!j){let D=cs(b.messages);throw console.warn(`[tg-agent] empty response session=${e.sessionId} ${D}`),new Error("No assistant response.")}return{text:j,sessionFile:n,sessionId:b.sessionId,modelProvider:b.model?.provider??d,modelId:b.model?.id??f,modelFallbackMessage:k}}finally{$e&&clearInterval($e),it&&clearInterval(it),Co(),y.flushPendingToolResults?.(),b.dispose()}}var es,Pt=F(()=>{"use strict";K();we();En();_e();J();vt();Wn();$t();kt();es={"codex-mini-latest":"gpt-5.1-codex-mini","codex-max-latest":"gpt-5.1-codex-max","codex-latest":"gpt-5.2-codex"}});import ms from"node:fs/promises";import Yn from"node:path";function _t(e){return ps.test(e)}function Ct(){return Yn.join(p.agentDir,"souls")}function Ye(e){return Yn.join(Ct(),`${e}.md`)}async function Ce(e){if(!_t(e))throw new Error(`Invalid soul name: ${e}. Use only letters, numbers, "_" and "-".`);let t=Ye(e),r=(await ms.readFile(t,"utf8")).trim();if(!r)throw new Error(`Soul file is empty: ${t}`);if(r.length>Gn)throw new Error(`Soul file too large (${r.length} chars). Max ${Gn}.`);return r}function Xe(e,t){return[fs,"",`<session_soul name="${e}">`,t,"</session_soul>"].join(`
47
+ `)}var ps,Gn,fs,Rt=F(()=>{"use strict";K();ps=/^[a-zA-Z0-9_-]+$/,Gn=16e3,fs=["<session_soul_protocol>",'You may receive an optional block: <session_soul name="...">...</session_soul>.',"Treat it as session-level behavioral guidance (tone, style, default strategy).","Priority order:","1) Safety and non-overridable policy constraints","2) Core system instructions","3) Explicit user instructions in this conversation","4) session_soul guidance (default behavior only)","If conflicts exist, follow higher-priority rules and ignore conflicting soul parts.","Do not mention this protocol unless asked.","</session_soul_protocol>"].join(`
48
+ `)});import gs from"node:path";import*as Xn from"@lancedb/lancedb";import Tt from"openai";function hs(){if(le)return le;let e=p.memory.rag;if(e.embeddingApiKey){let n={apiKey:e.embeddingApiKey};return e.embeddingBaseUrl&&(n.baseURL=e.embeddingBaseUrl),le=new Tt(n),console.log(`[memory-rag] using embedding API key${e.embeddingBaseUrl?` (baseURL: ${e.embeddingBaseUrl})`:""}`),le}if(p.openaiApiKey)return le=new Tt({apiKey:p.openaiApiKey}),console.log("[memory-rag] using OpenAI API key from config"),le;let t=Q();if(t)return le=new Tt({apiKey:t.accessToken}),console.log("[memory-rag] using Codex OAuth token"),le;throw new Error("No API key for embeddings. Set memory.rag.embedding_api_key or run `codex login`.")}async function Dt(e){let t=hs(),n=p.memory.rag.embeddingModel;console.log(`[memory-rag] embedding ${e.length} chars using ${n}`);let r=3e4,o=new Promise((i,c)=>{setTimeout(()=>c(new Error(`Embedding timeout after ${r}ms`)),r)});try{let i=await Promise.race([t.embeddings.create({model:n,input:e,encoding_format:"float"}),o]);if(!i?.data?.[0]?.embedding)throw new Error(`Invalid embedding response: ${JSON.stringify(i).slice(0,200)}`);let c=i.data[0].embedding;return console.log(`[memory-rag] got ${c.length}D embedding`),c}catch(i){throw i instanceof Error&&console.error(`[memory-rag] embedding error: ${i.message}`),i}}async function xe(){return Qe||(await C(Et),Qe=await Xn.connect(Et),console.log(`[memory-rag] connected to DB at ${Et}`),Qe)}async function Ze(e,t,n,r,o){let i={sessionSaved:!1,memoriesIndexed:0,errors:[]};if(!p.memory.rag.enabled)return console.log("[memory-rag] RAG disabled, skipping save"),i;console.log(`[memory-rag] saving session ${e}`);try{let c=await xe(),u=await c.tableNames(),l={sessionId:e,date:t,title:n,transcript:r,reflection:JSON.stringify(o),memoryCount:o.memories?.length??0,timestamp:Date.now()};if(u.includes(ue)?await(await c.openTable(ue)).add([l]):await c.createTable(ue,[l]),i.sessionSaved=!0,console.log("[memory-rag] session saved to DB"),o.memories&&o.memories.length>0){let m=await bs(e,t,o.memories);i.memoriesIndexed=m.indexed,i.errors=m.errors}return i}catch(c){let u=c instanceof Error?c.message:String(c);return console.error(`[memory-rag] saveSession failed: ${u}`),i.errors.push(u),i}}async function ws(){try{let e=await xe();return(await e.tableNames()).includes(ue)?(await(await e.openTable(ue)).query().toArray()).map(o=>({sessionId:o.sessionId,date:o.date,title:o.title,transcript:o.transcript,reflection:o.reflection,memoryCount:o.memoryCount,timestamp:o.timestamp})):[]}catch(e){return console.error(`[memory-rag] getAllSessions failed: ${e}`),[]}}async function bs(e,t,n){let r={indexed:0,errors:[]};if(!p.memory.rag.enabled||n.length===0)return r;console.log(`[memory-rag] indexing ${n.length} memories for session ${e}`);try{let o=await xe(),i=await o.tableNames(),c,u=!1;i.includes(ee)?c=await o.openTable(ee):u=!0;for(let l=0;l<n.length;l++){let m=n[l];try{let s=await Dt(m.content),a={id:`${e}-${l}`,sessionId:e,date:t,type:m.type,content:m.content,vector:s,timestamp:Date.now()};u?(c=await o.createTable(ee,[a]),u=!1,console.log("[memory-rag] created memories table")):await c.add([a]),r.indexed++,console.log(`[memory-rag] indexed [${l+1}/${n.length}]: ${m.type}`)}catch(s){let a=s instanceof Error?s.message:String(s);r.errors.push(`${m.type}: ${a}`),console.error(`[memory-rag] failed to index item ${l}: ${a}`)}l<n.length-1&&await new Promise(s=>setTimeout(s,200))}return console.log(`[memory-rag] indexed ${r.indexed}/${n.length} memories`),r}catch(o){let i=o instanceof Error?o.message:String(o);return console.error(`[memory-rag] indexMemoryItems failed: ${i}`),r.errors.push(i),r}}async function Qn(e,t=p.memory.rag.maxResults,n=p.memory.rag.similarityThreshold){if(!p.memory.rag.enabled)return[];console.log(`[memory-rag] searching: "${e.slice(0,50)}..."`);try{let r=await xe();if(!(await r.tableNames()).includes(ee))return console.log("[memory-rag] memories table not found"),[];let i=await r.openTable(ee),c=await i.countRows();console.log(`[memory-rag] memories table has ${c} rows`);let u=await Dt(e),l=await i.vectorSearch(u).column(ys).limit(t*2).toArray();if(console.log(`[memory-rag] search returned ${l.length} results`),l.length>0){let a=l.map(d=>d._distance?.toFixed(4)??"N/A");console.log(`[memory-rag] distances: [${a.join(", ")}]`)}let m=(1-n)*2;console.log(`[memory-rag] threshold=${n}, maxDistance=${m.toFixed(4)}`);let s=l.filter(a=>{let d=a._distance;return d===void 0||d<=m}).slice(0,t).map(a=>({id:a.id,sessionId:a.sessionId,date:a.date,type:a.type,content:a.content,timestamp:a.timestamp,_distance:a._distance}));return console.log(`[memory-rag] filtered: ${s.length} memories`),s.length>0&&s.forEach((a,d)=>{console.log(`[memory-rag] ${d+1}. [${a.type}] "${a.content.slice(0,50)}..." (dist=${a._distance?.toFixed(4)??"N/A"})`)}),s}catch(r){let o=r instanceof Error?r.message:String(r);return console.warn(`[memory-rag] search failed: ${o}`),[]}}async function Zn(){try{let e=await xe(),t=await e.tableNames(),n=0,r=0;return t.includes(ue)&&(n=await(await e.openTable(ue)).countRows()),t.includes(ee)&&(r=await(await e.openTable(ee)).countRows()),{sessionsCount:n,memoriesCount:r,embeddingModel:p.memory.rag.embeddingModel}}catch{return{sessionsCount:0,memoriesCount:0,embeddingModel:p.memory.rag.embeddingModel}}}async function eo(e){let t={success:!1,totalSessions:0,totalMemories:0,indexedMemories:0,errors:[],embeddingModel:p.memory.rag.embeddingModel,vectorDimension:null};console.log("[reindex] ========================================"),console.log("[reindex] Rebuilding memories from sessions table"),console.log(`[reindex] Embedding model: ${p.memory.rag.embeddingModel}`),console.log("[reindex] ========================================");try{let n=await xe(),r=await n.tableNames();if(!r.includes(ue))return console.log("[reindex] No sessions table found, nothing to reindex"),t.success=!0,t;let o=await ws();if(t.totalSessions=o.length,o.length===0)return console.log("[reindex] No sessions found"),t.success=!0,t;console.log(`[reindex] Found ${o.length} sessions`);let i=[];for(let u of o)try{let l=JSON.parse(u.reflection);if(l.memories&&l.memories.length>0)for(let m of l.memories)i.push({sessionId:u.sessionId,date:u.date,item:m})}catch(l){console.warn(`[reindex] Failed to parse reflection for session ${u.sessionId}: ${l}`)}if(t.totalMemories=i.length,console.log(`[reindex] Found ${i.length} memories to reindex`),i.length===0)return console.log("[reindex] No memories to reindex"),t.success=!0,t;r.includes(ee)&&(await n.dropTable(ee),console.log("[reindex] Dropped old memories table"));let c=null;for(let u=0;u<i.length;u++){let{sessionId:l,date:m,item:s}=i[u],a=`[${u+1}/${i.length}]`;try{e?.(u+1,i.length,`Indexing: ${s.content.slice(0,30)}...`);let d=await Dt(s.content);t.vectorDimension===null&&(t.vectorDimension=d.length);let f={id:`${l}-${u}`,sessionId:l,date:m,type:s.type,content:s.content,vector:d,timestamp:Date.now()};c===null?(c=await n.createTable(ee,[f]),console.log(`[reindex] ${a} Created new memories table`)):await c.add([f]),t.indexedMemories++,console.log(`[reindex] ${a} Indexed: [${s.type}] ${s.content.slice(0,40)}...`)}catch(d){let f=d instanceof Error?d.message:String(d);t.errors.push(`${s.content.slice(0,30)}: ${f}`),console.error(`[reindex] ${a} Failed: ${f}`)}u<i.length-1&&await new Promise(d=>setTimeout(d,200))}return console.log("[reindex] ========================================"),console.log("[reindex] Reindex complete!"),console.log(`[reindex] Sessions: ${t.totalSessions}`),console.log(`[reindex] Total memories: ${t.totalMemories}`),console.log(`[reindex] Indexed: ${t.indexedMemories}`),console.log(`[reindex] Errors: ${t.errors.length}`),console.log("[reindex] ========================================"),t.success=!0,t}catch(n){let r=n instanceof Error?n.message:String(n);return console.error(`[reindex] Failed: ${r}`),t.errors.push(r),t}}var Et,ue,ee,ys,Qe,le,Ot=F(()=>{"use strict";K();J();we();Et=gs.join(p.agentDir,"tg-memory-db"),ue="sessions",ee="memories",ys="vector",Qe=null,le=null});import to from"node:path";import{AuthStorage as vs,ModelRegistry as xs}from"@mariozechner/pi-coding-agent";import{completeSimple as Ss,getModel as $s}from"@mariozechner/pi-ai";function Ms(){return p.memory.systemPrompt||As}function Ps(e){let t=e.trim().toLowerCase();return t==="codex"?"openai-codex":t}function _s(e,t){return e!=="openai-codex"?t:ks[t]??t}async function Cs(e,t){await C(p.agentDir);let n=to.join(p.agentDir,"auth.json"),r=new vs(n),o=Q();o&&r.setRuntimeApiKey("openai-codex",o.accessToken);let i=to.join(p.agentDir,"models.json"),c=new xs(r,i),u=async(a,d,f)=>{let h=Ps(a),y=_s(h,d),w=c.find(h,y);if(!w)try{w=$s(h,y)}catch{}if(w){let x=await r.getApiKey(h);return{model:w,provider:h,modelId:y,apiKey:x??void 0,source:f}}return null};if(e&&t){let a=await u(e,t,"session");if(a)return console.log(`[memory] using session model: ${a.provider}/${a.modelId}`),a}if(p.memory.modelProvider&&p.memory.modelId){let a=await u(p.memory.modelProvider,p.memory.modelId,"memory-config");if(a)return console.log(`[memory] using configured memory model: ${a.provider}/${a.modelId}`),a}let l=p.modelProvider,m=p.modelRef.includes("/")?p.modelRef.split("/")[1]:p.modelRef;if(l&&m){let a=await u(l,m,"system-default");if(a)return console.log(`[memory] using system default model: ${a.provider}/${a.modelId}`),a}let s=c.getAll();if(s.length>0){let a=s[0],d=await r.getApiKey(a.provider);return console.log(`[memory] using first available model: ${a.provider}/${a.id}`),{model:a,provider:a.provider,modelId:a.id,apiKey:d??void 0,source:"first-available"}}return console.warn("[memory] no model available for reflection"),null}function Rs(e){let t={emotional:"",insights:"",advice:"",memories:[]};if(!e.trim())return t;try{let n=e.trim(),r=n.match(/```(?:json)?\s*([\s\S]*?)```/);r&&(n=r[1].trim());let o=JSON.parse(n),i={emotional:typeof o.emotional=="string"?o.emotional:"",insights:typeof o.insights=="string"?o.insights:"",advice:typeof o.advice=="string"?o.advice:"",memories:[]};if(Array.isArray(o.memories))for(let c of o.memories)c&&typeof c=="object"&&typeof c.type=="string"&&typeof c.content=="string"&&i.memories.push({type:c.type,content:c.content});return i}catch(n){return console.warn(`[memory] failed to parse reflection JSON: ${n}`),{emotional:"",insights:e.slice(0,500),advice:"",memories:[{type:"insight",content:`Session summary: ${e.slice(0,200)}`}]}}}async function et(e,t,n){if(!p.memory.enabled)return{success:!0,reflected:!1,memoriesIndexed:0};if(e.messages.length===0)return{success:!0,reflected:!1,memoriesIndexed:0};let o=new Date().toISOString().split("T")[0],i=e.messages.map(u=>`[${u.role.toUpperCase()}]: ${u.content}`).join(`
49
49
 
50
- `),c=await Ps(t,n);if(!c){console.log("[memory] no model available, saving raw session");let u={emotional:"",insights:"No model available for reflection",advice:"",memories:[]};return{success:(await Ze(e.id,r,e.title,i,u)).sessionSaved,reflected:!1,memoriesIndexed:0}}console.log(`[memory] reflecting on session ${e.id} using ${c.provider}/${c.modelId}`);try{let l={systemPrompt:$s(),messages:[{role:"user",content:`Conversation transcript:
50
+ `),c=await Cs(t,n);if(!c){console.log("[memory] no model available, saving raw session");let u={emotional:"",insights:"No model available for reflection",advice:"",memories:[]};return{success:(await Ze(e.id,o,e.title,i,u)).sessionSaved,reflected:!1,memoriesIndexed:0}}console.log(`[memory] reflecting on session ${e.id} using ${c.provider}/${c.modelId}`);try{let l={systemPrompt:Ms(),messages:[{role:"user",content:`Conversation transcript:
51
51
 
52
- ${i}`,timestamp:Date.now()}]},m=await vs(c.model,l,{apiKey:c.apiKey,maxTokens:2e3,sessionId:e.id});if(m.stopReason==="error")throw new Error(m.errorMessage||"Unknown API error");let s=m.content.find(h=>h.type==="text"),a=s?.type==="text"?s.text:"";a.trim()||(a=m.content.filter(y=>y.type==="thinking").map(y=>y.type==="thinking"?y.thinking:"").filter(Boolean).join(`
52
+ ${i}`,timestamp:Date.now()}]},m=await Ss(c.model,l,{apiKey:c.apiKey,maxTokens:2e3,sessionId:e.id});if(m.stopReason==="error")throw new Error(m.errorMessage||"Unknown API error");let s=m.content.find(h=>h.type==="text"),a=s?.type==="text"?s.text:"";a.trim()||(a=m.content.filter(y=>y.type==="thinking").map(y=>y.type==="thinking"?y.thinking:"").filter(Boolean).join(`
53
53
 
54
- `));let d=_s(a);console.log(`[memory] reflection generated: ${d.memories.length} memories`);let p=await Ze(e.id,r,e.title,i,d);return p.errors.length>0&&console.warn(`[memory] some errors during save: ${p.errors.join(", ")}`),console.log(`[memory] session archived, ${p.memoriesIndexed} memories indexed`),{success:p.sessionSaved,reflected:!0,memoriesIndexed:p.memoriesIndexed}}catch(u){let l=u instanceof Error?u.message:String(u);console.error(`[memory] reflection failed: ${l}`);let m={emotional:"",insights:`Reflection failed: ${l}`,advice:"",memories:[]};return{success:(await Ze(e.id,r,e.title,i,m)).sessionSaved,reflected:!1,memoriesIndexed:0,error:l}}}var Ss,As,no=I(()=>{"use strict";K();J();we();Et();Ss=`You are a caring AI companion summarizing a conversation with Shawn.
54
+ `));let d=Rs(a);console.log(`[memory] reflection generated: ${d.memories.length} memories`);let f=await Ze(e.id,o,e.title,i,d);return f.errors.length>0&&console.warn(`[memory] some errors during save: ${f.errors.join(", ")}`),console.log(`[memory] session archived, ${f.memoriesIndexed} memories indexed`),{success:f.sessionSaved,reflected:!0,memoriesIndexed:f.memoriesIndexed}}catch(u){let l=u instanceof Error?u.message:String(u);console.error(`[memory] reflection failed: ${l}`);let m={emotional:"",insights:`Reflection failed: ${l}`,advice:"",memories:[]};return{success:(await Ze(e.id,o,e.title,i,m)).sessionSaved,reflected:!1,memoriesIndexed:0,error:l}}}var As,ks,no=F(()=>{"use strict";K();J();we();Ot();As=`You are a caring AI companion summarizing a conversation with Shawn.
55
55
 
56
56
  Your task is to:
57
57
  1. Understand Shawn's emotional state and what's important to them
@@ -84,74 +84,74 @@ Guidelines:
84
84
  - Each memory should be self-contained and specific
85
85
  - Focus on information that would help Shawn in the future
86
86
  - Keep each memory concise (one sentence)
87
- - Prioritize what matters for Shawn's growth and wellbeing`;As={"codex-mini-latest":"gpt-5.1-codex-mini","codex-max-latest":"gpt-5.1-codex-max","codex-latest":"gpt-5.2-codex"}});var Ai={};import Se from"node:path";import{spawn as Cs}from"node:child_process";import oo from"node:fs/promises";import Rs from"node-telegram-bot-api";import{AuthStorage as Ts,ModelRegistry as Es}from"@mariozechner/pi-coding-agent";import{getOAuthProviders as ro,getOAuthProvider as Ds}from"@mariozechner/pi-ai";function Ns(e,t){De.set(e,t)}function Ut(e){De.delete(e)}function js(e){let t=e.trim();if(t){if(t==="Markdown"||t==="MarkdownV2"||t==="HTML")return t;console.warn(`[tg-agent] invalid TELEGRAM_PARSE_MODE=${t}, ignoring`)}}function Us(){return Se.join(f.agentDir,"uploads")}function Is(e){return e.length===0?null:e.reduce((t,n)=>{let o=t.file_size??t.width*t.height;return(n.file_size??n.width*n.height)>o?n:t})}function Fs(e){return!!e?.startsWith("image/")}function zs(e){switch(Se.extname(e).toLowerCase()){case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";case".webp":return"image/webp";case".gif":return"image/gif";default:return}}function Ks(e){if(!Number.isFinite(e)||e<=0)return"0 B";let t=["B","KB","MB","GB"],n=e,o=0;for(;n>=1024&&o<t.length-1;)n/=1024,o+=1;return`${n.toFixed(n>=10||o===0?0:1)} ${t[o]}`}function Bs(e){return e.length===0?"":e.map(t=>{let n=[];t.mimeType&&n.push(t.mimeType),t.bytes>0&&n.push(Ks(t.bytes));let o=n.length>0?` (${n.join(", ")})`:"";return`Attachment saved: ${t.path}${o}`}).join(`
88
- `)}function Ws(e){let t=[];if(e.photo&&e.photo.length>0){let n=Is(e.photo);n&&t.push({kind:"photo",fileId:n.file_id,fileSize:n.file_size})}if(e.document&&t.push({kind:"document",fileId:e.document.file_id,fileName:e.document.file_name,mimeType:e.document.mime_type,fileSize:e.document.file_size}),e.audio){let n=e.audio.mime_type?.split("/")[1]??"mp3",o=e.audio.title??e.audio.performer??"audio";t.push({kind:"document",fileId:e.audio.file_id,fileName:`${o}.${n}`,mimeType:e.audio.mime_type,fileSize:e.audio.file_size})}if(e.voice&&t.push({kind:"document",fileId:e.voice.file_id,fileName:`voice.${e.voice.mime_type?.split("/")[1]??"ogg"}`,mimeType:e.voice.mime_type,fileSize:e.voice.file_size}),e.video){let n=e.video.mime_type?.split("/")[1]??"mp4";t.push({kind:"document",fileId:e.video.file_id,fileName:`video.${n}`,mimeType:e.video.mime_type,fileSize:e.video.file_size})}return e.video_note&&t.push({kind:"document",fileId:e.video_note.file_id,fileName:"video_note.mp4",mimeType:"video/mp4",fileSize:e.video_note.file_size}),t}async function Js(e){if(e.length===0)return{resolved:[],images:[]};let t=Us();await C(t);let n=[],o=[];for(let r of e)try{let i=await L.downloadFile(r.fileId,t),c=await oo.stat(i),u=r.fileName??Se.basename(i),l=r.mimeType??zs(i),m=r.kind==="photo"||Fs(l),s={path:i,name:u,mimeType:l,bytes:c.size,isImage:m};if(n.push(s),m){let a=await oo.readFile(i);o.push({type:"image",data:a.toString("base64"),mimeType:l??Ls})}}catch(i){console.warn("[tg-agent] attachment download failed",i)}return{resolved:n,images:o}}function Re(e,t){let n=0;for(let o=0;o<e.length;o+=1){let r=e[o];if(r==="\\"){o+=1;continue}r===t&&(n+=1)}return n}function qs(e){if(Re(e,"*")%2!==0||Re(e,"_")%2!==0||Re(e,"`")%2!==0)return!1;let r=Re(e,"["),i=Re(e,"]");return r===i}function Gs(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(n==="\\"){t+=1;continue}if(Hs.has(n))return!1}return!0}function yo(e){let t=js(f.telegramParseMode);return t?[t]:Gs(e)?["MarkdownV2","Markdown"]:qs(e)?["Markdown"]:[]}function Ee(e,t){let n=Te.get(e);return n?(clearTimeout(n.timeoutId),Te.delete(e),n.messageId&&L.editMessageReplyMarkup({inline_keyboard:[]},{chat_id:n.chatId,message_id:n.messageId}).catch(()=>{}),n.resolve(t),!0):!1}async function so(e,t,n,o,r){if(Te.has(e))throw new Error("Audit confirmation already pending.");let i=zt([{label:"Approve",command:"/approve"},{label:"Stop",command:"/stop"}],2),c=await Kt(t,n,i,r);return await new Promise((u,l)=>{let m=setTimeout(()=>{Te.delete(e),L.editMessageText(`${n}
87
+ - Prioritize what matters for Shawn's growth and wellbeing`;ks={"codex-mini-latest":"gpt-5.1-codex-mini","codex-max-latest":"gpt-5.1-codex-max","codex-latest":"gpt-5.2-codex"}});var ki={};import Se from"node:path";import{spawn as Ts}from"node:child_process";import oo from"node:fs/promises";import Es from"node-telegram-bot-api";import{AuthStorage as Ds,ModelRegistry as Os}from"@mariozechner/pi-coding-agent";import{getOAuthProviders as ro,getOAuthProvider as Ns}from"@mariozechner/pi-ai";function Ls(e,t){De.set(e,t)}function Ft(e){De.delete(e)}function Us(e){let t=e.trim();if(t){if(t==="Markdown"||t==="MarkdownV2"||t==="HTML")return t;console.warn(`[tg-agent] invalid TELEGRAM_PARSE_MODE=${t}, ignoring`)}}function Fs(){return Se.join(p.agentDir,"uploads")}function zs(e){return e.length===0?null:e.reduce((t,n)=>{let r=t.file_size??t.width*t.height;return(n.file_size??n.width*n.height)>r?n:t})}function Ks(e){return!!e?.startsWith("image/")}function Bs(e){switch(Se.extname(e).toLowerCase()){case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";case".webp":return"image/webp";case".gif":return"image/gif";default:return}}function Ws(e){if(!Number.isFinite(e)||e<=0)return"0 B";let t=["B","KB","MB","GB"],n=e,r=0;for(;n>=1024&&r<t.length-1;)n/=1024,r+=1;return`${n.toFixed(n>=10||r===0?0:1)} ${t[r]}`}function Js(e){return e.length===0?"":e.map(t=>{let n=[];t.mimeType&&n.push(t.mimeType),t.bytes>0&&n.push(Ws(t.bytes));let r=n.length>0?` (${n.join(", ")})`:"";return`Attachment saved: ${t.path}${r}`}).join(`
88
+ `)}function Hs(e){let t=[];if(e.photo&&e.photo.length>0){let n=zs(e.photo);n&&t.push({kind:"photo",fileId:n.file_id,fileSize:n.file_size})}if(e.document&&t.push({kind:"document",fileId:e.document.file_id,fileName:e.document.file_name,mimeType:e.document.mime_type,fileSize:e.document.file_size}),e.audio){let n=e.audio.mime_type?.split("/")[1]??"mp3",r=e.audio.title??e.audio.performer??"audio";t.push({kind:"document",fileId:e.audio.file_id,fileName:`${r}.${n}`,mimeType:e.audio.mime_type,fileSize:e.audio.file_size})}if(e.voice&&t.push({kind:"document",fileId:e.voice.file_id,fileName:`voice.${e.voice.mime_type?.split("/")[1]??"ogg"}`,mimeType:e.voice.mime_type,fileSize:e.voice.file_size}),e.video){let n=e.video.mime_type?.split("/")[1]??"mp4";t.push({kind:"document",fileId:e.video.file_id,fileName:`video.${n}`,mimeType:e.video.mime_type,fileSize:e.video.file_size})}return e.video_note&&t.push({kind:"document",fileId:e.video_note.file_id,fileName:"video_note.mp4",mimeType:"video/mp4",fileSize:e.video_note.file_size}),t}async function qs(e){if(e.length===0)return{resolved:[],images:[]};let t=Fs();await C(t);let n=[],r=[];for(let o of e)try{let i=await N.downloadFile(o.fileId,t),c=await oo.stat(i),u=o.fileName??Se.basename(i),l=o.mimeType??Bs(i),m=o.kind==="photo"||Ks(l),s={path:i,name:u,mimeType:l,bytes:c.size,isImage:m};if(n.push(s),m){let a=await oo.readFile(i);r.push({type:"image",data:a.toString("base64"),mimeType:l??Is})}}catch(i){console.warn("[tg-agent] attachment download failed",i)}return{resolved:n,images:r}}function Re(e,t){let n=0;for(let r=0;r<e.length;r+=1){let o=e[r];if(o==="\\"){r+=1;continue}o===t&&(n+=1)}return n}function Gs(e){if(Re(e,"*")%2!==0||Re(e,"_")%2!==0||Re(e,"`")%2!==0)return!1;let o=Re(e,"["),i=Re(e,"]");return o===i}function Ys(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(n==="\\"){t+=1;continue}if(Vs.has(n))return!1}return!0}function yo(e){let t=Us(p.telegramParseMode);return t?[t]:Ys(e)?["MarkdownV2","Markdown"]:Gs(e)?["Markdown"]:[]}function Ee(e,t){let n=Te.get(e);return n?(clearTimeout(n.timeoutId),Te.delete(e),n.messageId&&N.editMessageReplyMarkup({inline_keyboard:[]},{chat_id:n.chatId,message_id:n.messageId}).catch(()=>{}),n.resolve(t),!0):!1}async function so(e,t,n,r,o){if(Te.has(e))throw new Error("Audit confirmation already pending.");let i=Bt([{label:"Approve",command:"/approve"},{label:"Stop",command:"/stop"}],2),c=await Wt(t,n,i,o);return await new Promise((u,l)=>{let m=setTimeout(()=>{Te.delete(e),N.editMessageText(`${n}
89
89
 
90
- [Timed out - Operation blocked]`,{chat_id:t,message_id:c.message_id}).catch(()=>{}),l(new Error("Audit confirmation timed out."))},o);Te.set(e,{resolve:u,reject:l,timeoutId:m,chatId:t,messageThreadId:r,messageId:c.message_id})})}function j(e){let t=e.trim().toLowerCase();return Ys.get(t)??t}function io(e,t){return e!=="openai-codex"?t:Xs[t]??t}async function Y(){await C(f.agentDir);let e=Se.join(f.agentDir,"auth.json"),t=new Ts(e),n=X();n&&t.setRuntimeApiKey("openai-codex",n.accessToken);let o=Se.join(f.agentDir,"models.json"),r=new Es(t,o);return{authStorage:t,modelRegistry:r}}function ho(e){let t=de.get(e);t&&(clearTimeout(t.timeoutId),de.delete(e))}function Qs(e,t){let n=de.get(e);n&&(clearTimeout(n.timeoutId),de.delete(e),n.reject(new Error(t)))}async function ao(e,t,n,o){if(de.has(e))throw new Error("Login is already awaiting input.");let r=n.placeholder?`${n.message} (${n.placeholder})`:n.message;return await g(t,r,o),await new Promise((i,c)=>{let u=setTimeout(()=>{de.delete(e),c(new Error("Login prompt timed out."))},Vs);de.set(e,{resolve:i,reject:c,timeoutId:u,chatId:t})})}async function wo(e,t,n){let o=De.get(t);if(!o){await g(e,"No active request to stop.",n);return}o.cancelRequested=!0,o.abortRequested=!0,o.status&&o.status.update("Cancelled by user.",!0),o.abort&&o.abort(),(!o.status||o.chatId!==e)&&await g(e,"Stopping current request...",n)}async function bo(e,t,n,o){let r=await Je(t),i=n||r.activeSessionId;if(!i){await g(e,"No active session to close.",o);return}let c=r.sessions[i];if(c&&c.messages.length>0)try{await g(e,"Reflecting on session memory...",o);let s=await et(c,c.modelProvider,c.modelId);s.reflected?await g(e,"Memory archived successfully.",o):s.error?await g(e,`Memory saved (reflection failed: ${s.error})`,o):await g(e,"Memory saved (no reflection).",o)}catch(s){console.warn("[tg-agent] memory archival failed",s),await g(e,`Memory archival failed: ${ie(s)}`,o)}let u=De.get(t);if(u){if(u.cancelRequested=!0,u.abortRequested=!0,u.status&&u.status.update("Cancelled by user.",!0),u.abort)try{u.abort()}catch(s){console.warn("[tg-agent] abort callback failed during force close",s)}Ut(t)}if(!yt(r,i)){await g(e,`Session not found: ${i}`,o);return}await T(r),await ve(t,i).catch(s=>{console.warn(`[tg-agent] delete session file failed id=${i}`,s)});let m=u?`Force-closed session ${i} (interrupted running task).`:`Closed session ${i}.`;await g(e,m,o)}function Zs(){console.log(`[tg-agent] modelProvider=${f.modelProvider} modelRef=${f.modelRef} sessionDir=${f.sessionDir} maxConcurrent=${f.maxConcurrent}`),console.log(`[tg-agent] agentDir=${f.agentDir} workspaceDir=${f.workspaceDir}`);let e=ze(f.agentDir),t=e.length>0?`on (${e.length})`:"off";console.log(`[tg-agent] tools fetchMaxBytes=${f.fetchMaxBytes} fetchTimeoutMs=${f.fetchTimeoutMs} mcp=${t}`),console.log(`[tg-agent] proxy url=${f.proxyUrl||"(none)"} fetchProxy=${f.fetchProxyUrl||"(none)"}`),console.log(`[tg-agent] tls extra_ca=${f.tlsExtraCaCerts||"(empty)"} reject_unauthorized=${f.tlsRejectUnauthorized===null?"(unset)":String(f.tlsRejectUnauthorized)}`);try{let{source:o}=pn(f.modelProvider);console.log(`[tg-agent] authSource=${o}`)}catch(o){let r=o instanceof Error?o.message:String(o);console.warn(`[tg-agent] authSource=missing (${r})`)}let n=gn();console.log(n?`[tg-agent] proxyUrl=${n.url} kind=${n.kind} source=${n.source}`:"[tg-agent] proxyUrl=(none)")}function It(e){if(!e.startsWith("/"))return null;let t=e.trim(),[n,...o]=t.split(" ");return{command:n.split("@")[0].slice(1).toLowerCase(),args:o.join(" ").trim()}}async function ge(e,t,n){let o=fe(e);return o||(o=He(e,""),await T(e),await g(t,`Created session ${o.id}.`,n)),o}function ti(e,t){let n=se(),o=e.getAll(),r=new Map;for(let i of o){let c=r.get(i.provider)??{count:0,auth:t.hasAuth(i.provider)||n.hasApiKey(i.provider)};c.count+=1,r.set(i.provider,c)}return Array.from(r.entries()).filter(([i])=>ei.has(i)).sort((i,c)=>i[0].localeCompare(c[0])).map(([i,c])=>({label:`${i} (${c.count}, ${c.auth?"ok":"no auth"})`,command:`/provider ${i}`}))}function ni(e,t,n=[]){let o=e.getAll().filter(u=>u.provider===t).sort((u,l)=>u.id.localeCompare(l.id));if(n.length===0)return o.map(u=>({label:u.id,command:`/model ${t}/${u.id}`}));let r=new Map(o.map(u=>[u.id,u])),i=new Set,c=[];for(let u of n){let l=r.get(u);!l||i.has(l.id)||(i.add(l.id),c.push(l))}for(let u of o)i.has(u.id)||c.push(u);return c.map(u=>({label:u.id,command:`/model ${t}/${u.id}`}))}function oi(e,t,n=3){let o=new Set,r=[],i=ft(e);for(let c of i){if(c.modelProvider!==t)continue;let u=c.modelId;if(!(!u||o.has(u))&&(o.add(u),r.push(u),r.length>=n))break}return r}function co(e){let t=e.trim();if(!t)return null;let n=t.indexOf(" ");if(n>0){let o=t.slice(0,n).trim(),r=t.slice(n+1).trim();return!o||!r?null:{provider:j(o),modelId:r}}if(t.includes("/")){let o=t.indexOf("/"),r=t.slice(0,o).trim(),i=t.slice(o+1).trim();return!r||!i?null:{provider:j(r),modelId:i}}return{modelId:t}}function jt(e){if(!e)return;let t=e.trim().toLowerCase();if(t==="oauth")return"oauth";if(t==="api_key"||t==="apikey")return"api_key"}function Ot(e){let t=e.trim();return t?t.startsWith("!")?"command(...)":/^[A-Z][A-Z0-9_]{2,}$/.test(t)?`env:${t}`:t.length<=8?`${"*".repeat(Math.max(0,t.length-2))}${t.slice(-2)}`:`${t.slice(0,4)}...${t.slice(-4)}`:"(empty)"}function lo(e){let t=e.trim().toLowerCase();return t==="clear"||t==="remove"||t==="unset"}function uo(e){let t=e.trim();if(!t)return null;let n=t.indexOf(" ");if(n<=0)return null;let o=j(t.slice(0,n)),r=t.slice(n+1).trim();return!o||!r?null:{provider:o,value:r}}function ri(e){try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}function vo(e,t){let n=Date.now(),o=mo.get(e)??0;n-o<si||(mo.set(e,n),console.warn(`[tg-agent] unauthorized user=${e} chat=${t}`))}function xo(e){let t=f.telegramAllowedUsers;return!t||t.size===0?!0:t.has(e)}function ii(e){return e.length===0?"No sessions found.":["Sessions:",...e.map(n=>{let o=new Date(n.updatedAt).toISOString();return`- ${n.id} | ${n.title} | updated ${o}`})].join(`
91
- `)}function ot(e,t,n){let o=String(e);return t!==void 0&&!n?null:t!==void 0&&n?`${o}_${t}`:o}function Lt(e,t){if(t.workspaceDir)return t.workspaceDir;let n=f.workspaceMappings.get(e);return n||f.workspaceDir}async function Ft(e,t,n,o){let r={};return n&&(r.parse_mode=n),o!==void 0&&(r.message_thread_id=o),await L.sendMessage(e,t,r)}async function So(e,t,n,o,r){let i={chat_id:e,message_id:t};o&&(i.parse_mode=o),r!==void 0&&(i.message_thread_id=r),await L.editMessageText(n,i)}async function $o(e,t){let n;for(let o of t)try{return await e(o)}catch(r){n=r;let i=r instanceof Error?r.message:String(r);console.warn(`[tg-agent] parse_mode ${o} failed, trying fallback: ${i}`)}try{return await e(void 0)}catch(o){if(n){let r=o instanceof Error?o.message:String(o);console.warn(`[tg-agent] parse_mode fallback to plain failed: ${r}`)}throw o}}async function ai(e,t,n){return await $o(o=>Ft(e,t,o,n),yo(t))}async function ci(e,t,n,o){await $o(r=>So(e,t,n,r,o),yo(n))}async function g(e,t,n){let o=ct(t,3900);for(let r of o)await ai(e,r,n)}async function li(e,t,n){let o=ct(t,3900);for(let r of o)await Ft(e,r,void 0,n)}function di(){let e=D()-Ao;for(let[o,r]of ee)r.createdAt<e&&ee.delete(o);if(ee.size<=po)return;let t=Array.from(ee.entries()).sort((o,r)=>o[1].createdAt-r[1].createdAt),n=ee.size-po;for(let o=0;o<n;o+=1)ee.delete(t[o][0])}function mi(e){di();let t=oe();for(;ee.has(t);)t=oe();return ee.set(t,{command:e,createdAt:D()}),t}function pi(e){if(!e.startsWith("cmd:"))return null;let t=e.slice(4),n=ee.get(t);return n?D()-n.createdAt>Ao?(ee.delete(t),null):n.command:null}function fi(e,t){if(e.length<=t)return[e];let n=[];for(let o=0;o<e.length;o+=t)n.push(e.slice(o,o+t));return n}function zt(e,t){let n=[],o=[];for(let r of e){let i=mi(r.command);o.push({text:r.label,callback_data:`cmd:${i}`}),o.length>=t&&(n.push(o),o=[])}return o.length>0&&n.push(o),n}async function Kt(e,t,n,o){let r={reply_markup:{inline_keyboard:n}};return o!==void 0&&(r.message_thread_id=o),await L.sendMessage(e,t,r)}async function nt(e,t,n,o){let r=o?.perRow??1,i=o?.pageSize??ui,c=o?.footer,u=o?.messageThreadId,l=fi(n,i);for(let m=0;m<l.length;m+=1){let s=l[m],a=l.length>1?` (page ${m+1}/${l.length})`:"",d=[`${t}${a}`];c&&d.push(c);let p=zt(s,r);await Kt(e,d.join(`
92
- `),p,u)}}function Nt(e,t=gi){return e.length<=t?{text:e,truncated:!1}:{text:`${e.slice(0,Math.max(0,t-15))}...
90
+ [Timed out - Operation blocked]`,{chat_id:t,message_id:c.message_id}).catch(()=>{}),l(new Error("Audit confirmation timed out."))},r);Te.set(e,{resolve:u,reject:l,timeoutId:m,chatId:t,messageThreadId:o,messageId:c.message_id})})}function U(e){let t=e.trim().toLowerCase();return Qs.get(t)??t}function io(e,t){return e!=="openai-codex"?t:Zs[t]??t}async function X(){await C(p.agentDir);let e=Se.join(p.agentDir,"auth.json"),t=new Ds(e),n=Q();n&&t.setRuntimeApiKey("openai-codex",n.accessToken);let r=Se.join(p.agentDir,"models.json"),o=new Os(t,r);return{authStorage:t,modelRegistry:o}}function ho(e){let t=de.get(e);t&&(clearTimeout(t.timeoutId),de.delete(e))}function ei(e,t){let n=de.get(e);n&&(clearTimeout(n.timeoutId),de.delete(e),n.reject(new Error(t)))}async function ao(e,t,n,r){if(de.has(e))throw new Error("Login is already awaiting input.");let o=n.placeholder?`${n.message} (${n.placeholder})`:n.message;return await g(t,o,r),await new Promise((i,c)=>{let u=setTimeout(()=>{de.delete(e),c(new Error("Login prompt timed out."))},Xs);de.set(e,{resolve:i,reject:c,timeoutId:u,chatId:t})})}async function wo(e,t,n){let r=De.get(t);if(!r){await g(e,"No active request to stop.",n);return}r.cancelRequested=!0,r.abortRequested=!0,r.status&&r.status.update("Cancelled by user.",!0),r.abort&&r.abort(),(!r.status||r.chatId!==e)&&await g(e,"Stopping current request...",n)}async function bo(e,t,n,r){let o=await Je(t),i=n||o.activeSessionId;if(!i){await g(e,"No active session to close.",r);return}let c=o.sessions[i];if(c&&c.messages.length>0)try{await g(e,"Reflecting on session memory...",r);let s=await et(c,c.modelProvider,c.modelId);s.reflected?await g(e,"Memory archived successfully.",r):s.error?await g(e,`Memory saved (reflection failed: ${s.error})`,r):await g(e,"Memory saved (no reflection).",r)}catch(s){console.warn("[tg-agent] memory archival failed",s),await g(e,`Memory archival failed: ${ie(s)}`,r)}let u=De.get(t);if(u){if(u.cancelRequested=!0,u.abortRequested=!0,u.status&&u.status.update("Cancelled by user.",!0),u.abort)try{u.abort()}catch(s){console.warn("[tg-agent] abort callback failed during force close",s)}Ft(t)}if(!wt(o,i)){await g(e,`Session not found: ${i}`,r);return}await T(o),await ve(t,i).catch(s=>{console.warn(`[tg-agent] delete session file failed id=${i}`,s)});let m=u?`Force-closed session ${i} (interrupted running task).`:`Closed session ${i}.`;await g(e,m,r)}function ti(){console.log(`[tg-agent] modelProvider=${p.modelProvider} modelRef=${p.modelRef} sessionDir=${p.sessionDir} maxConcurrent=${p.maxConcurrent}`),console.log(`[tg-agent] agentDir=${p.agentDir} workspaceDir=${p.workspaceDir}`);let e=ze(p.agentDir),t=e.length>0?`on (${e.length})`:"off";console.log(`[tg-agent] tools fetchMaxBytes=${p.fetchMaxBytes} fetchTimeoutMs=${p.fetchTimeoutMs} mcp=${t}`),console.log(`[tg-agent] proxy url=${p.proxyUrl||"(none)"} fetchProxy=${p.fetchProxyUrl||"(none)"}`),console.log(`[tg-agent] tls extra_ca=${p.tlsExtraCaCerts||"(empty)"} reject_unauthorized=${p.tlsRejectUnauthorized===null?"(unset)":String(p.tlsRejectUnauthorized)}`);try{let{source:r}=gn(p.modelProvider);console.log(`[tg-agent] authSource=${r}`)}catch(r){let o=r instanceof Error?r.message:String(r);console.warn(`[tg-agent] authSource=missing (${o})`)}let n=hn();console.log(n?`[tg-agent] proxyUrl=${n.url} kind=${n.kind} source=${n.source}`:"[tg-agent] proxyUrl=(none)")}function zt(e){if(!e.startsWith("/"))return null;let t=e.trim(),[n,...r]=t.split(" ");return{command:n.split("@")[0].slice(1).toLowerCase(),args:r.join(" ").trim()}}async function ge(e,t,n){let r=fe(e);return r||(r=He(e,""),await T(e),await g(t,`Created session ${r.id}.`,n)),r}function oi(e,t){let n=se(),r=e.getAll(),o=new Map;for(let i of r){let c=o.get(i.provider)??{count:0,auth:t.hasAuth(i.provider)||n.hasApiKey(i.provider)};c.count+=1,o.set(i.provider,c)}return Array.from(o.entries()).filter(([i])=>ni.has(i)).sort((i,c)=>i[0].localeCompare(c[0])).map(([i,c])=>({label:`${i} (${c.count}, ${c.auth?"ok":"no auth"})`,command:`/provider ${i}`}))}function ri(e,t,n=[]){let r=e.getAll().filter(u=>u.provider===t).sort((u,l)=>u.id.localeCompare(l.id));if(n.length===0)return r.map(u=>({label:u.id,command:`/model ${t}/${u.id}`}));let o=new Map(r.map(u=>[u.id,u])),i=new Set,c=[];for(let u of n){let l=o.get(u);!l||i.has(l.id)||(i.add(l.id),c.push(l))}for(let u of r)i.has(u.id)||c.push(u);return c.map(u=>({label:u.id,command:`/model ${t}/${u.id}`}))}function si(e,t,n=3){let r=new Set,o=[],i=yt(e);for(let c of i){if(c.modelProvider!==t)continue;let u=c.modelId;if(!(!u||r.has(u))&&(r.add(u),o.push(u),o.length>=n))break}return o}function co(e){let t=e.trim();if(!t)return null;let n=t.indexOf(" ");if(n>0){let r=t.slice(0,n).trim(),o=t.slice(n+1).trim();return!r||!o?null:{provider:U(r),modelId:o}}if(t.includes("/")){let r=t.indexOf("/"),o=t.slice(0,r).trim(),i=t.slice(r+1).trim();return!o||!i?null:{provider:U(o),modelId:i}}return{modelId:t}}function Ut(e){if(!e)return;let t=e.trim().toLowerCase();if(t==="oauth")return"oauth";if(t==="api_key"||t==="apikey")return"api_key"}function jt(e){let t=e.trim();return t?t.startsWith("!")?"command(...)":/^[A-Z][A-Z0-9_]{2,}$/.test(t)?`env:${t}`:t.length<=8?`${"*".repeat(Math.max(0,t.length-2))}${t.slice(-2)}`:`${t.slice(0,4)}...${t.slice(-4)}`:"(empty)"}function lo(e){let t=e.trim().toLowerCase();return t==="clear"||t==="remove"||t==="unset"}function uo(e){let t=e.trim();if(!t)return null;let n=t.indexOf(" ");if(n<=0)return null;let r=U(t.slice(0,n)),o=t.slice(n+1).trim();return!r||!o?null:{provider:r,value:o}}function ii(e){try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}function vo(e,t){let n=Date.now(),r=mo.get(e)??0;n-r<ai||(mo.set(e,n),console.warn(`[tg-agent] unauthorized user=${e} chat=${t}`))}function xo(e){let t=p.telegramAllowedUsers;return!t||t.size===0?!0:t.has(e)}function ci(e){return e.length===0?"No sessions found.":["Sessions:",...e.map(n=>{let r=new Date(n.updatedAt).toISOString();return`- ${n.id} | ${n.title} | updated ${r}`})].join(`
91
+ `)}function ot(e,t,n){let r=String(e);return t!==void 0&&!n?null:t!==void 0&&n?`${r}_${t}`:r}function It(e,t){if(t.workspaceDir)return t.workspaceDir;let n=p.workspaceMappings.get(e);return n||p.workspaceDir}async function Kt(e,t,n,r){let o={};return n&&(o.parse_mode=n),r!==void 0&&(o.message_thread_id=r),await N.sendMessage(e,t,o)}async function So(e,t,n,r,o){let i={chat_id:e,message_id:t};r&&(i.parse_mode=r),o!==void 0&&(i.message_thread_id=o),await N.editMessageText(n,i)}async function $o(e,t){let n;for(let r of t)try{return await e(r)}catch(o){n=o;let i=o instanceof Error?o.message:String(o);console.warn(`[tg-agent] parse_mode ${r} failed, trying fallback: ${i}`)}try{return await e(void 0)}catch(r){if(n){let o=r instanceof Error?r.message:String(r);console.warn(`[tg-agent] parse_mode fallback to plain failed: ${o}`)}throw r}}async function li(e,t,n){return await $o(r=>Kt(e,t,r,n),yo(t))}async function ui(e,t,n,r){await $o(o=>So(e,t,n,o,r),yo(n))}async function g(e,t,n){let r=ct(t,3900);for(let o of r)await li(e,o,n)}async function di(e,t,n){let r=ct(t,3900);for(let o of r)await Kt(e,o,void 0,n)}function pi(){let e=O()-Ao;for(let[r,o]of te)o.createdAt<e&&te.delete(r);if(te.size<=po)return;let t=Array.from(te.entries()).sort((r,o)=>r[1].createdAt-o[1].createdAt),n=te.size-po;for(let r=0;r<n;r+=1)te.delete(t[r][0])}function fi(e){pi();let t=re();for(;te.has(t);)t=re();return te.set(t,{command:e,createdAt:O()}),t}function gi(e){if(!e.startsWith("cmd:"))return null;let t=e.slice(4),n=te.get(t);return n?O()-n.createdAt>Ao?(te.delete(t),null):n.command:null}function yi(e,t){if(e.length<=t)return[e];let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n}function Bt(e,t){let n=[],r=[];for(let o of e){let i=fi(o.command);r.push({text:o.label,callback_data:`cmd:${i}`}),r.length>=t&&(n.push(r),r=[])}return r.length>0&&n.push(r),n}async function Wt(e,t,n,r){let o={reply_markup:{inline_keyboard:n}};return r!==void 0&&(o.message_thread_id=r),await N.sendMessage(e,t,o)}async function nt(e,t,n,r){let o=r?.perRow??1,i=r?.pageSize??mi,c=r?.footer,u=r?.messageThreadId,l=yi(n,i);for(let m=0;m<l.length;m+=1){let s=l[m],a=l.length>1?` (page ${m+1}/${l.length})`:"",d=[`${t}${a}`];c&&d.push(c);let f=Bt(s,o);await Wt(e,d.join(`
92
+ `),f,u)}}function Lt(e,t=hi){return e.length<=t?{text:e,truncated:!1}:{text:`${e.slice(0,Math.max(0,t-15))}...
93
93
 
94
- [truncated]`,truncated:!0}}async function hi(e,t){let n="Working...",r=(await Ft(e,n,void 0,t)).message_id,i=n,c=0,u=Promise.resolve(),l=(s,a=!1)=>{let d=Date.now();!a&&d-c<yi||s!==i&&(i=s,c=d,u=u.then(async()=>{await So(e,r,s,void 0,t)}).catch(p=>{console.warn("[tg-agent] status edit failed",p)}))},m=s=>{i=s,c=Date.now(),u=u.then(async()=>{await ci(e,r,s,t)}).catch(a=>{console.warn("[tg-agent] status edit failed",a)})};return{update:(s,a=!1)=>{let d=Nt(s).text;l(d,a)},finalize:async s=>{let a=Nt(s).text;m(a),await u},fail:async s=>{let a=Nt(s).text;m(a),await u}}}function wi(e){switch(e.type){case"agent_start":return"Working...";case"tool_start":return`Running tool: ${e.name}
95
- args: ${bi(e.args)}`;case"tool_end":return e.ok?`Tool finished: ${e.name} (${e.durationMs}ms)`:`Tool failed: ${e.name} (${e.durationMs}ms)`;case"message_start":return e.role==="assistant"?"Generating reply...":null;case"message_end":return e.role==="assistant"?"Finalizing reply...":null;case"heartbeat":return`Working... ${Math.max(1,Math.round(e.elapsedMs/1e3))}s`;default:return null}}function bi(e){try{let t=new WeakSet,n=200,o=12,r=12,i=3,c=(m,s)=>{if(m==null)return m;if(typeof m=="string")return m.length>n?`${m.slice(0,n)}...`:m;if(typeof m=="number"||typeof m=="boolean")return m;if(typeof m=="bigint")return m.toString();if(typeof m=="function")return"[function]";if(typeof m!="object")return String(m);if(t.has(m))return"[circular]";if(s>=i)return"[truncated]";if(t.add(m),Array.isArray(m)){let p=m.slice(0,r).map(h=>c(h,s+1));return m.length>r&&p.push("[truncated]"),p}let a=Object.entries(m),d={};for(let[p,h]of a.slice(0,o))d[p]=c(h,s+1);return a.length>o&&(d._truncated=!0),d},u=c(e,0),l=JSON.stringify(u);return l?l.length>700?`${l.slice(0,700)}...`:l:"null"}catch{return"[unavailable]"}}function ie(e){let t=e instanceof Error?e.message:String(e),n=e?.cause;return n instanceof Error?`${t} (${n.message})`:n?`${t} (${String(n)})`:t}function vi(e,t=140){return e.length<=t?e:`${e.slice(0,t-3)}...`}async function xi(){let e=await ke(f.agentDir);if(e.length===0)return"No MCP servers configured. Add [mcp_servers.*] to ~/.tg-agent/config.toml.";let t=await Promise.all(e.map(o=>An(o))),n=["MCP servers:"];for(let o=0;o<e.length;o+=1){let r=e[o],i=t[o],c=i.ok?"ok":`error: ${vi(i.error??"unknown")}`;n.push(`- ${r.name} (${r.type}) ${pe(r)} status=${c} (${i.durationMs}ms)`)}return n.join(`
96
- `)}async function Bt(e,t,n,o,r){let i=r,u=ot(e,i,i!==void 0);if(!u)return;let l=await Je(u),m=gt(l);switch(m.length>0&&(await T(l),await Promise.all(m.map(s=>ve(u,s).catch(a=>{console.warn(`[tg-agent] cleanup session file failed id=${s}`,a)})))),n){case"start":case"help":{let s=["Commands:","/new [title] - create a new session","/list - list sessions","/use <id> - switch active session","/close [id] - close a session (default: active)","/reset - clear active session history","/workspace [path] - view or set workspace directory","/providers - list available providers","/models [provider] - list models for provider","/provider <name> - set provider for current session","/model <provider>/<model> - set model for current session","/modelraw <provider> <model> - set custom model id for current session","/mcp - list configured MCP servers","/mcp refresh - reload MCP catalog","/status - show session and workspace settings","/soul [name|off] - bind or clear session soul from ~/.tg-agent/souls/<name>.md","/login <provider> - login to OAuth provider","/logout <provider> - logout from provider (lists accountIds if multiple)","/accounts [provider] - list OAuth accounts, tap to switch","/setdefault <provider>/<accountId> - set default OAuth account","/apikey [provider] | /apikey <provider> <key> - manage API keys","/endpoint [provider] | /endpoint <provider> <url> - manage custom endpoints","/useapikey <provider> - force current session to API key mode","/useoauth <provider>[/accountId] - force current session to OAuth mode","/restart - run restart script (paths.restart_script_path in config)","/stop - stop the current running request","/approve - approve a pending security audit confirmation","/memory - show memory RAG status","/reindex - rebuild vector index for all memories","","Tips:","Send images or files to attach them to the prompt."].join(`
97
- `);await g(e,s,r);return}case"new":{try{let s=o||"",a=fe(l),d=a?.modelProvider,p=a?.modelId,h=a?.accountId,y=jt(a?.authMode),w=He(l,s);d&&(w.modelProvider=d,p&&(w.modelId=p)),h&&(w.accountId=h),y&&(w.authMode=y),await T(l),await g(e,`Created session ${w.id} (${w.title}).`,r)}catch(s){await g(e,s.message,r)}return}case"list":{await T(l),await g(e,ii(ft(l)),r);return}case"use":{if(!o){await g(e,"Usage: /use <id>",r);return}if(!Un(l,o)){await g(e,`Session not found: ${o}`,r);return}await T(l),await g(e,`Active session set to ${o}.`,r);return}case"close":{let s=o||l.activeSessionId;if(!s){await g(e,"No active session to close.",r);return}let a=l.sessions[s];if(a&&a.messages.length>0)try{await g(e,"Reflecting on session memory...",r);let y=await et(a,a.modelProvider,a.modelId);y.reflected?await g(e,"Memory archived successfully.",r):y.error?await g(e,`Memory saved (reflection failed: ${y.error})`,r):await g(e,"Memory saved (no reflection).",r)}catch(y){console.warn("[tg-agent] memory archival failed",y),await g(e,`Memory archival failed: ${ie(y)}`,r)}let d=De.get(u);if(d){if(d.cancelRequested=!0,d.abortRequested=!0,d.status&&d.status.update("Cancelled by user.",!0),d.abort)try{d.abort()}catch(y){console.warn("[tg-agent] abort callback failed during force close",y)}Ut(u)}if(!yt(l,s)){await g(e,`Session not found: ${s}`,r);return}await T(l),await ve(u,s).catch(y=>{console.warn(`[tg-agent] delete session file failed id=${s}`,y)});let h=d?`Force-closed session ${s} (interrupted running task).`:`Closed session ${s}.`;await g(e,h,r);return}case"reset":{let s=fe(l);if(!s){await g(e,"No active session.",r);return}if(s.messages.length>0)try{await g(e,"Reflecting on session memory...",r);let a=await et(s,s.modelProvider,s.modelId);a.reflected?await g(e,"Memory archived successfully.",r):a.error?await g(e,`Memory saved (reflection failed: ${a.error})`,r):await g(e,"Memory saved (no reflection).",r)}catch(a){console.warn("[tg-agent] memory archival failed",a),await g(e,`Memory archival failed: ${ie(a)}`,r)}In(s),await T(l),await ve(u,s.id).catch(a=>{console.warn(`[tg-agent] reset session file failed id=${s.id}`,a)}),await g(e,`Reset session ${s.id}.`,r);return}case"workspace":{if(!o){let a=Lt(u,l),d=l.workspaceDir?"chat":f.workspaceMappings.has(u)?"config":"default";await g(e,`Workspace: ${a} (source: ${d})`,r);return}let s=Se.resolve(W(o.trim()));Fn(l,s),await T(l),await g(e,`Workspace set to: ${s}`,r);return}case"providers":{let{authStorage:s,modelRegistry:a}=await Y(),d=a.getError(),p=ti(a,s);if(p.length===0){let y=d?`Warning: ${d}
94
+ [truncated]`,truncated:!0}}async function bi(e,t){let n="Working...",o=(await Kt(e,n,void 0,t)).message_id,i=n,c=0,u=Promise.resolve(),l=(s,a=!1)=>{let d=Date.now();!a&&d-c<wi||s!==i&&(i=s,c=d,u=u.then(async()=>{await So(e,o,s,void 0,t)}).catch(f=>{console.warn("[tg-agent] status edit failed",f)}))},m=s=>{i=s,c=Date.now(),u=u.then(async()=>{await ui(e,o,s,t)}).catch(a=>{console.warn("[tg-agent] status edit failed",a)})};return{update:(s,a=!1)=>{let d=Lt(s).text;l(d,a)},finalize:async s=>{let a=Lt(s).text;m(a),await u},fail:async s=>{let a=Lt(s).text;m(a),await u}}}function vi(e){switch(e.type){case"agent_start":return"Working...";case"tool_start":return`Running tool: ${e.name}
95
+ args: ${xi(e.args)}`;case"tool_end":return e.ok?`Tool finished: ${e.name} (${e.durationMs}ms)`:`Tool failed: ${e.name} (${e.durationMs}ms)`;case"message_start":return e.role==="assistant"?"Generating reply...":null;case"message_end":return e.role==="assistant"?"Finalizing reply...":null;case"heartbeat":return`Working... ${Math.max(1,Math.round(e.elapsedMs/1e3))}s`;default:return null}}function xi(e){try{let t=new WeakSet,n=200,r=12,o=12,i=3,c=(m,s)=>{if(m==null)return m;if(typeof m=="string")return m.length>n?`${m.slice(0,n)}...`:m;if(typeof m=="number"||typeof m=="boolean")return m;if(typeof m=="bigint")return m.toString();if(typeof m=="function")return"[function]";if(typeof m!="object")return String(m);if(t.has(m))return"[circular]";if(s>=i)return"[truncated]";if(t.add(m),Array.isArray(m)){let f=m.slice(0,o).map(h=>c(h,s+1));return m.length>o&&f.push("[truncated]"),f}let a=Object.entries(m),d={};for(let[f,h]of a.slice(0,r))d[f]=c(h,s+1);return a.length>r&&(d._truncated=!0),d},u=c(e,0),l=JSON.stringify(u);return l?l.length>700?`${l.slice(0,700)}...`:l:"null"}catch{return"[unavailable]"}}function ie(e){let t=e instanceof Error?e.message:String(e),n=e?.cause;return n instanceof Error?`${t} (${n.message})`:n?`${t} (${String(n)})`:t}function Si(e,t=140){return e.length<=t?e:`${e.slice(0,t-3)}...`}async function $i(){let e=await ke(p.agentDir);if(e.length===0)return"No MCP servers configured. Add [mcp_servers.*] to ~/.tg-agent/config.toml.";let t=await Promise.all(e.map(r=>kn(r))),n=["MCP servers:"];for(let r=0;r<e.length;r+=1){let o=e[r],i=t[r],c=i.ok?"ok":`error: ${Si(i.error??"unknown")}`;n.push(`- ${o.name} (${o.type}) ${pe(o)} status=${c} (${i.durationMs}ms)`)}return n.join(`
96
+ `)}async function Jt(e,t,n,r,o){let i=o,u=ot(e,i,i!==void 0);if(!u)return;let l=await Je(u),m=ht(l);switch(m.length>0&&(await T(l),await Promise.all(m.map(s=>ve(u,s).catch(a=>{console.warn(`[tg-agent] cleanup session file failed id=${s}`,a)})))),n){case"start":case"help":{let s=["Commands:","/new [title] - create a new session","/list - list sessions","/use <id> - switch active session","/close [id] - close a session (default: active)","/reset - clear active session history","/workspace [path] - view or set workspace directory","/providers - list available providers","/models [provider] - list models for provider","/provider <name> - set provider for current session","/model <provider>/<model> - set model for current session","/modelraw <provider> <model> - set custom model id for current session","/mcp - list configured MCP servers","/mcp refresh - reload MCP catalog","/status - show session and workspace settings","/soul [name|off] - bind or clear session soul from ~/.tg-agent/souls/<name>.md","/login <provider> - login to OAuth provider","/logout <provider> - logout from provider (lists accountIds if multiple)","/accounts [provider] - list OAuth accounts, tap to switch","/setdefault <provider>/<accountId> - set default OAuth account","/apikey [provider] | /apikey <provider> <key> - manage API keys","/endpoint [provider] | /endpoint <provider> <url> - manage custom endpoints","/useapikey <provider> - force current session to API key mode","/useoauth <provider>[/accountId] - force current session to OAuth mode","/restart - run restart script (paths.restart_script_path in config)","/stop - stop the current running request","/approve - approve a pending security audit confirmation","/memory - show memory RAG status","/reindex - rebuild vector index for all memories","","Tips:","Send images or files to attach them to the prompt."].join(`
97
+ `);await g(e,s,o);return}case"new":{try{let s=r||"",a=fe(l),d=a?.modelProvider,f=a?.modelId,h=a?.accountId,y=Ut(a?.authMode),w=He(l,s);d&&(w.modelProvider=d,f&&(w.modelId=f)),h&&(w.accountId=h),y&&(w.authMode=y),await T(l),await g(e,`Created session ${w.id} (${w.title}).`,o)}catch(s){await g(e,s.message,o)}return}case"list":{await T(l),await g(e,ci(yt(l)),o);return}case"use":{if(!r){await g(e,"Usage: /use <id>",o);return}if(!Un(l,r)){await g(e,`Session not found: ${r}`,o);return}await T(l),await g(e,`Active session set to ${r}.`,o);return}case"close":{let s=r||l.activeSessionId;if(!s){await g(e,"No active session to close.",o);return}let a=l.sessions[s];if(a&&a.messages.length>0)try{await g(e,"Reflecting on session memory...",o);let y=await et(a,a.modelProvider,a.modelId);y.reflected?await g(e,"Memory archived successfully.",o):y.error?await g(e,`Memory saved (reflection failed: ${y.error})`,o):await g(e,"Memory saved (no reflection).",o)}catch(y){console.warn("[tg-agent] memory archival failed",y),await g(e,`Memory archival failed: ${ie(y)}`,o)}let d=De.get(u);if(d){if(d.cancelRequested=!0,d.abortRequested=!0,d.status&&d.status.update("Cancelled by user.",!0),d.abort)try{d.abort()}catch(y){console.warn("[tg-agent] abort callback failed during force close",y)}Ft(u)}if(!wt(l,s)){await g(e,`Session not found: ${s}`,o);return}await T(l),await ve(u,s).catch(y=>{console.warn(`[tg-agent] delete session file failed id=${s}`,y)});let h=d?`Force-closed session ${s} (interrupted running task).`:`Closed session ${s}.`;await g(e,h,o);return}case"reset":{let s=fe(l);if(!s){await g(e,"No active session.",o);return}if(s.messages.length>0)try{await g(e,"Reflecting on session memory...",o);let a=await et(s,s.modelProvider,s.modelId);a.reflected?await g(e,"Memory archived successfully.",o):a.error?await g(e,`Memory saved (reflection failed: ${a.error})`,o):await g(e,"Memory saved (no reflection).",o)}catch(a){console.warn("[tg-agent] memory archival failed",a),await g(e,`Memory archival failed: ${ie(a)}`,o)}In(s),await T(l),await ve(u,s.id).catch(a=>{console.warn(`[tg-agent] reset session file failed id=${s.id}`,a)}),await g(e,`Reset session ${s.id}.`,o);return}case"workspace":{if(!r){let a=It(u,l),d=l.workspaceDir?"chat":p.workspaceMappings.has(u)?"config":"default";await g(e,`Workspace: ${a} (source: ${d})`,o);return}let s=Se.resolve(W(r.trim()));Fn(l,s),await T(l),await g(e,`Workspace set to: ${s}`,o);return}case"providers":{let{authStorage:s,modelRegistry:a}=await X(),d=a.getError(),f=oi(a,s);if(f.length===0){let y=d?`Warning: ${d}
98
98
 
99
- No providers found.`:"No providers found.";await g(e,y,r);return}let h=[];d&&h.push(`Warning: ${d}`),h.push("Providers:"),await nt(e,h.join(`
100
- `),p,{perRow:1,footer:"Tap a provider to set it. Use /models <provider> to list models.",messageThreadId:r});return}case"models":{let{authStorage:s,modelRegistry:a}=await Y(),d=o?j(o):"";if(!d){let x=fe(l);if(!x?.modelProvider){await g(e,"Usage: /models <provider>",r);return}d=x.modelProvider}let p=se(),h=s.hasAuth(d)||p.hasApiKey(d),y=oi(l,d),w=ni(a,d,y);if(w.length===0){await g(e,`No models found for provider ${d}.`,r);return}await nt(e,`Models for ${d} (auth: ${h?"ok":"missing"}):`,w,{perRow:1,footer:"Tap a model to set it.",messageThreadId:r});return}case"provider":{if(!o){await g(e,"Usage: /provider <name>",r);return}let s=j(o),{modelRegistry:a}=await Y();if(!a.getAll().some(y=>y.provider===s)){await g(e,`Unknown provider: ${s}`,r);return}let p=await ge(l,e,r),h=p.modelProvider!==s;p.modelProvider=s,p.modelId=void 0,h&&(p.accountId=void 0),p.updatedAt=D(),await T(l),await g(e,`Session ${p.id} provider set to ${s}.`,r),await Bt(e,t,"models",s,r);return}case"model":{let s=co(o);if(!s){await g(e,"Usage: /model <provider>/<model>",r);return}let a=await ge(l,e,r),d=j(s.provider??a.modelProvider??"");if(!d){await g(e,"Usage: /model <provider>/<model>",r);return}let{modelRegistry:p}=await Y(),h=io(d,s.modelId);if(!p.find(d,h)){await g(e,`Model not found: ${d}/${h}
99
+ No providers found.`:"No providers found.";await g(e,y,o);return}let h=[];d&&h.push(`Warning: ${d}`),h.push("Providers:"),await nt(e,h.join(`
100
+ `),f,{perRow:1,footer:"Tap a provider to set it. Use /models <provider> to list models.",messageThreadId:o});return}case"models":{let{authStorage:s,modelRegistry:a}=await X(),d=r?U(r):"";if(!d){let x=fe(l);if(!x?.modelProvider){await g(e,"Usage: /models <provider>",o);return}d=x.modelProvider}let f=se(),h=s.hasAuth(d)||f.hasApiKey(d),y=si(l,d),w=ri(a,d,y);if(w.length===0){await g(e,`No models found for provider ${d}.`,o);return}await nt(e,`Models for ${d} (auth: ${h?"ok":"missing"}):`,w,{perRow:1,footer:"Tap a model to set it.",messageThreadId:o});return}case"provider":{if(!r){await g(e,"Usage: /provider <name>",o);return}let s=U(r),{modelRegistry:a}=await X();if(!a.getAll().some(y=>y.provider===s)){await g(e,`Unknown provider: ${s}`,o);return}let f=await ge(l,e,o),h=f.modelProvider!==s;f.modelProvider=s,f.modelId=void 0,h&&(f.accountId=void 0),f.updatedAt=O(),await T(l),await g(e,`Session ${f.id} provider set to ${s}.`,o),await Jt(e,t,"models",s,o);return}case"model":{let s=co(r);if(!s){await g(e,"Usage: /model <provider>/<model>",o);return}let a=await ge(l,e,o),d=U(s.provider??a.modelProvider??"");if(!d){await g(e,"Usage: /model <provider>/<model>",o);return}let{modelRegistry:f}=await X(),h=io(d,s.modelId);if(!f.find(d,h)){await g(e,`Model not found: ${d}/${h}
101
101
  Use /models ${d} to list available models.
102
- To force a custom id, use: /modelraw ${d} ${h}`,r);return}a.modelProvider=d,a.modelId=h,a.updatedAt=D(),await T(l),await g(e,`Session ${a.id} model set to ${d}/${h}.`,r);return}case"modelraw":{let s=co(o);if(!s){await g(e,`Usage: /modelraw <provider> <model>
103
- Also supported: /modelraw <provider>/<model>`,r);return}let a=await ge(l,e,r),d=j(s.provider??a.modelProvider??"");if(!d){await g(e,`Usage: /modelraw <provider> <model>
104
- Also supported: /modelraw <provider>/<model>`,r);return}let{modelRegistry:p}=await Y();if(!p.getAll().some(M=>M.provider===d)){await g(e,`Unknown provider: ${d}`,r);return}let y=io(d,s.modelId),w=!!p.find(d,y);a.modelProvider=d,a.modelId=y,a.updatedAt=D(),await T(l);let x=w?"registered":"custom";await g(e,`Session ${a.id} model set to ${d}/${y} (${x}).`,r);return}case"status":{let s=fe(l);if(!s){await g(e,"No active session.",r);return}let a=f.modelRef.includes("/")?f.modelRef:`${f.modelProvider}/${f.modelRef}`,d=s.modelProvider||s.modelId?`Model: ${s.modelProvider??"?"}/${s.modelId??"?"}`:`Model: ${a} (default)`,p="",h=jt(s.authMode);if(h==="api_key"){let M=se(),S=s.modelProvider||"",P=S?M.getProviderConfig(S):null,U=P?.baseUrl?`, endpoint=${P.baseUrl}`:"";p=`
105
- Auth: api_key (${P?.apiKey?"key=present":"key=missing"}${U})`}else if(s.accountId){let S=Q().getAccount(s.modelProvider||"",s.accountId);S?p=`
106
- Auth: oauth (${S.email||s.accountId})`:p=`
107
- Auth: oauth (${s.accountId}, not found)`}else h==="oauth"&&(p=`
108
- Auth: oauth (default account)`);let y=Lt(u,l),w=l.workspaceDir?"chat":f.workspaceMappings.has(u)?"config":"default",x=[`Session: ${s.id} (${s.title})`,d+p,`Soul: ${s.soulName??"(none)"}`,`Workspace: ${y} (${w})`].join(`
109
- `);await g(e,x,r);return}case"soul":{let s=await ge(l,e,r),a=o.trim();if(!a){if(!s.soulName){await g(e,[`Session ${s.id} soul: (none)`,"Set one with: /soul <name>",`File location: ${Pt()}/<name>.md`].join(`
110
- `),r);return}let p=Ye(s.soulName);await g(e,`Session ${s.id} soul: ${s.soulName}
111
- Path: ${p}`,r);return}let d=a.toLowerCase();if(d==="off"||d==="none"){s.soulName=void 0,s.updatedAt=D(),await T(l),await g(e,`Session ${s.id} soul cleared.`,r);return}if(!kt(a)){await g(e,["Invalid soul name.","Use only letters, numbers, '_' and '-'.","Example: /soul girlfriend"].join(`
112
- `),r);return}try{let p=await Ce(a);s.soulName=a,s.updatedAt=D(),await T(l),await g(e,[`Session ${s.id} soul set to ${a}.`,`Path: ${Ye(a)}`,`Loaded chars: ${p.length}`].join(`
113
- `),r)}catch(p){await g(e,`Failed to load soul "${a}": ${ie(p)}`,r)}return}case"apikey":{let s=se(),a=o.trim();if(!a){let p=s.listProviders().filter(y=>!!s.getProviderConfig(y)?.apiKey);if(p.length===0){await g(e,`No API keys configured.
102
+ To force a custom id, use: /modelraw ${d} ${h}`,o);return}a.modelProvider=d,a.modelId=h,a.updatedAt=O(),await T(l),await g(e,`Session ${a.id} model set to ${d}/${h}.`,o);return}case"modelraw":{let s=co(r);if(!s){await g(e,`Usage: /modelraw <provider> <model>
103
+ Also supported: /modelraw <provider>/<model>`,o);return}let a=await ge(l,e,o),d=U(s.provider??a.modelProvider??"");if(!d){await g(e,`Usage: /modelraw <provider> <model>
104
+ Also supported: /modelraw <provider>/<model>`,o);return}let{modelRegistry:f}=await X();if(!f.getAll().some(M=>M.provider===d)){await g(e,`Unknown provider: ${d}`,o);return}let y=io(d,s.modelId),w=!!f.find(d,y);a.modelProvider=d,a.modelId=y,a.updatedAt=O(),await T(l);let x=w?"registered":"custom";await g(e,`Session ${a.id} model set to ${d}/${y} (${x}).`,o);return}case"status":{let s=fe(l);if(!s){await g(e,"No active session.",o);return}let a=p.modelRef.includes("/")?p.modelRef:`${p.modelProvider}/${p.modelRef}`,d=s.modelProvider||s.modelId?`Model: ${s.modelProvider??"?"}/${s.modelId??"?"}`:`Model: ${a} (default)`,f="",h=Ut(s.authMode);if(h==="api_key"){let M=se(),S=s.modelProvider||"",_=S?M.getProviderConfig(S):null,I=_?.baseUrl?`, endpoint=${_.baseUrl}`:"";f=`
105
+ Auth: api_key (${_?.apiKey?"key=present":"key=missing"}${I})`}else if(s.accountId){let S=Z().getAccount(s.modelProvider||"",s.accountId);S?f=`
106
+ Auth: oauth (${S.email||s.accountId})`:f=`
107
+ Auth: oauth (${s.accountId}, not found)`}else h==="oauth"&&(f=`
108
+ Auth: oauth (default account)`);let y=It(u,l),w=l.workspaceDir?"chat":p.workspaceMappings.has(u)?"config":"default",x=[`Session: ${s.id} (${s.title})`,d+f,`Soul: ${s.soulName??"(none)"}`,`Workspace: ${y} (${w})`].join(`
109
+ `);await g(e,x,o);return}case"soul":{let s=await ge(l,e,o),a=r.trim();if(!a){if(!s.soulName){await g(e,[`Session ${s.id} soul: (none)`,"Set one with: /soul <name>",`File location: ${Ct()}/<name>.md`].join(`
110
+ `),o);return}let f=Ye(s.soulName);await g(e,`Session ${s.id} soul: ${s.soulName}
111
+ Path: ${f}`,o);return}let d=a.toLowerCase();if(d==="off"||d==="none"){s.soulName=void 0,s.updatedAt=O(),await T(l),await g(e,`Session ${s.id} soul cleared.`,o);return}if(!_t(a)){await g(e,["Invalid soul name.","Use only letters, numbers, '_' and '-'.","Example: /soul girlfriend"].join(`
112
+ `),o);return}try{let f=await Ce(a);s.soulName=a,s.updatedAt=O(),await T(l),await g(e,[`Session ${s.id} soul set to ${a}.`,`Path: ${Ye(a)}`,`Loaded chars: ${f.length}`].join(`
113
+ `),o)}catch(f){await g(e,`Failed to load soul "${a}": ${ie(f)}`,o)}return}case"apikey":{let s=se(),a=r.trim();if(!a){let f=s.listProviders().filter(y=>!!s.getProviderConfig(y)?.apiKey);if(f.length===0){await g(e,`No API keys configured.
114
114
  Usage: /apikey <provider> <key>
115
- Clear: /apikey <provider> clear`,r);return}let h=p.map(y=>{let w=s.getProviderConfig(y),x=w?.baseUrl?` | endpoint=${w.baseUrl}`:"";return`- ${y}: ${Ot(w?.apiKey??"")}${x}`});await g(e,["API key providers:",...h,"","Set: /apikey <provider> <key>","Clear: /apikey <provider> clear"].join(`
116
- `),r);return}let d=uo(a);if(!d){let p=j(a),h=s.getProviderConfig(p);if(!h?.apiKey){await g(e,`No API key for ${p}.
117
- Set one with: /apikey ${p} <key>`,r);return}let y=h.baseUrl?`
118
- Endpoint: ${h.baseUrl}`:"";await g(e,`API key for ${p}: ${Ot(h.apiKey)}${y}`,r);return}if(lo(d.value)){if(!await s.clearApiKey(d.provider)){await g(e,`No API key to clear for ${d.provider}.`,r);return}await g(e,`Cleared API key for ${d.provider}.`,r);return}await s.setApiKey(d.provider,d.value),await g(e,`Saved API key for ${d.provider} (${Ot(d.value)}).
119
- Use /useapikey ${d.provider} to force API key mode in this session.`,r);return}case"endpoint":{let s=se(),a=o.trim();if(!a){let p=s.listProviders().filter(y=>!!s.getProviderConfig(y)?.baseUrl);if(p.length===0){await g(e,`No custom endpoints configured.
115
+ Clear: /apikey <provider> clear`,o);return}let h=f.map(y=>{let w=s.getProviderConfig(y),x=w?.baseUrl?` | endpoint=${w.baseUrl}`:"";return`- ${y}: ${jt(w?.apiKey??"")}${x}`});await g(e,["API key providers:",...h,"","Set: /apikey <provider> <key>","Clear: /apikey <provider> clear"].join(`
116
+ `),o);return}let d=uo(a);if(!d){let f=U(a),h=s.getProviderConfig(f);if(!h?.apiKey){await g(e,`No API key for ${f}.
117
+ Set one with: /apikey ${f} <key>`,o);return}let y=h.baseUrl?`
118
+ Endpoint: ${h.baseUrl}`:"";await g(e,`API key for ${f}: ${jt(h.apiKey)}${y}`,o);return}if(lo(d.value)){if(!await s.clearApiKey(d.provider)){await g(e,`No API key to clear for ${d.provider}.`,o);return}await g(e,`Cleared API key for ${d.provider}.`,o);return}await s.setApiKey(d.provider,d.value),await g(e,`Saved API key for ${d.provider} (${jt(d.value)}).
119
+ Use /useapikey ${d.provider} to force API key mode in this session.`,o);return}case"endpoint":{let s=se(),a=r.trim();if(!a){let f=s.listProviders().filter(y=>!!s.getProviderConfig(y)?.baseUrl);if(f.length===0){await g(e,`No custom endpoints configured.
120
120
  Usage: /endpoint <provider> <url>
121
- Clear: /endpoint <provider> clear`,r);return}let h=p.map(y=>{let w=s.getProviderConfig(y);return`- ${y}: ${w?.baseUrl}`});await g(e,["Custom endpoints:",...h,"","Set: /endpoint <provider> <url>","Clear: /endpoint <provider> clear"].join(`
122
- `),r);return}let d=uo(a);if(!d){let p=j(a),h=s.getProviderConfig(p);if(!h?.baseUrl){await g(e,`No custom endpoint for ${p}.
123
- Set one with: /endpoint ${p} <url>`,r);return}await g(e,`Endpoint for ${p}: ${h.baseUrl}`,r);return}if(lo(d.value)){if(!await s.clearBaseUrl(d.provider)){await g(e,`No endpoint to clear for ${d.provider}.`,r);return}await g(e,`Cleared custom endpoint for ${d.provider}.`,r);return}if(!ri(d.value)){await g(e,`Invalid endpoint URL: ${d.value}`,r);return}await s.setBaseUrl(d.provider,d.value),await g(e,`Saved endpoint for ${d.provider}: ${d.value}
124
- This endpoint is used when session auth mode is API key.`,r);return}case"useapikey":{if(!o){await g(e,"Usage: /useapikey <provider>",r);return}let s=j(o),{modelRegistry:a}=await Y();if(!a.getAll().some(M=>M.provider===s)){await g(e,`Unknown provider: ${s}`,r);return}let h=se().getProviderConfig(s);if(!h?.apiKey){await g(e,`No API key for ${s}. Set one with: /apikey ${s} <key>`,r);return}let y=await ge(l,e,r),w=y.modelProvider!==s;y.modelProvider=s,w&&(y.modelId=void 0),y.accountId=void 0,y.authMode="api_key",y.updatedAt=D(),await T(l);let x=h.baseUrl?`
125
- Endpoint: ${h.baseUrl}`:"";await g(e,`Session ${y.id} now uses API key mode for ${s}.${x}`,r);return}case"useoauth":{if(!o){await g(e,"Usage: /useoauth <provider>[/accountId]",r);return}let s=o.trim(),a=s,d;if(s.includes("/")){let[b,k]=s.split("/",2);if(a=b.trim(),d=k?.trim(),!a||!d){await g(e,"Usage: /useoauth <provider>[/accountId]",r);return}}let p=j(a),{modelRegistry:h}=await Y();if(!h.getAll().some(b=>b.provider===p)){await g(e,`Unknown provider: ${p}`,r);return}let w=Q(),x=w.listAccounts(p);if(x.length===0){await g(e,`No OAuth account for ${p}. Login first: /login ${p}`,r);return}let M=d?x.find(b=>b.id===d):void 0;if(d&&!M){await g(e,`Account not found: ${p}/${d}`,r);return}if(!M){let b=w.getDefaultAccount(p);M=x.find(k=>k.id===b?.id)||x[0]}let S=await ge(l,e,r),P=S.modelProvider!==p;S.modelProvider=p,P&&(S.modelId=void 0),S.accountId=M.id,S.authMode="oauth",S.updatedAt=D(),await T(l);let U=M.email||M.id,$=d?"":" [default]";await g(e,`Session ${S.id} now uses OAuth mode for ${p} (${U}${$}).`,r);return}case"mcp":{if(o.trim().toLowerCase()==="refresh"){$n(),await me(f.agentDir,{timeoutMs:5e3,maxBytes:f.fetchMaxBytes,maxChars:3e3}),Pe(),await g(e,"MCP catalog refreshed.",r);return}let s=await xi();await g(e,s,r);return}case"login":{let s=ro();if(!o){let p=s.map(h=>`- ${h.id} (${h.name})`);await g(e,["OAuth providers:",...p].join(`
126
- `),r);return}let a=j(o);if(Dt.has(t)){await g(e,"Login already in progress.",r);return}let d=s.find(p=>p.id===a);if(!d){await g(e,`Unknown OAuth provider: ${a}`,r);return}Dt.add(t);try{let{authStorage:p}=await Y(),h=Q(),y=h.listAccounts(a);y.length>0&&await g(e,`You have ${y.length} account(s) for ${a}. Adding a new one...`,r),await g(e,`Starting login for ${d.id}...`,r);let w=Ds(a);if(!w)throw new Error(`OAuth provider not found: ${a}`);let x=await w.login({onAuth:({url:$,instructions:b})=>{let k=["Open this URL in your browser:",$];b&&k.push("",b),li(e,k.join(`
127
- `),r)},onPrompt:$=>ao(t,e,$,r),onProgress:$=>{g(e,$,r)},onManualCodeInput:()=>ao(t,e,{message:"Paste the authorization code:"},r)}),M=x.email,S=await h.addAccount(a,x,{email:M});p.set(a,{type:"oauth",...x});let P=h.listAccounts(a),U=M||S;await g(e,`Login completed for ${d.id}.
128
- Account: ${U}
121
+ Clear: /endpoint <provider> clear`,o);return}let h=f.map(y=>{let w=s.getProviderConfig(y);return`- ${y}: ${w?.baseUrl}`});await g(e,["Custom endpoints:",...h,"","Set: /endpoint <provider> <url>","Clear: /endpoint <provider> clear"].join(`
122
+ `),o);return}let d=uo(a);if(!d){let f=U(a),h=s.getProviderConfig(f);if(!h?.baseUrl){await g(e,`No custom endpoint for ${f}.
123
+ Set one with: /endpoint ${f} <url>`,o);return}await g(e,`Endpoint for ${f}: ${h.baseUrl}`,o);return}if(lo(d.value)){if(!await s.clearBaseUrl(d.provider)){await g(e,`No endpoint to clear for ${d.provider}.`,o);return}await g(e,`Cleared custom endpoint for ${d.provider}.`,o);return}if(!ii(d.value)){await g(e,`Invalid endpoint URL: ${d.value}`,o);return}await s.setBaseUrl(d.provider,d.value),await g(e,`Saved endpoint for ${d.provider}: ${d.value}
124
+ This endpoint is used when session auth mode is API key.`,o);return}case"useapikey":{if(!r){await g(e,"Usage: /useapikey <provider>",o);return}let s=U(r),{modelRegistry:a}=await X();if(!a.getAll().some(M=>M.provider===s)){await g(e,`Unknown provider: ${s}`,o);return}let h=se().getProviderConfig(s);if(!h?.apiKey){await g(e,`No API key for ${s}. Set one with: /apikey ${s} <key>`,o);return}let y=await ge(l,e,o),w=y.modelProvider!==s;y.modelProvider=s,w&&(y.modelId=void 0),y.accountId=void 0,y.authMode="api_key",y.updatedAt=O(),await T(l);let x=h.baseUrl?`
125
+ Endpoint: ${h.baseUrl}`:"";await g(e,`Session ${y.id} now uses API key mode for ${s}.${x}`,o);return}case"useoauth":{if(!r){await g(e,"Usage: /useoauth <provider>[/accountId]",o);return}let s=r.trim(),a=s,d;if(s.includes("/")){let[b,k]=s.split("/",2);if(a=b.trim(),d=k?.trim(),!a||!d){await g(e,"Usage: /useoauth <provider>[/accountId]",o);return}}let f=U(a),{modelRegistry:h}=await X();if(!h.getAll().some(b=>b.provider===f)){await g(e,`Unknown provider: ${f}`,o);return}let w=Z(),x=w.listAccounts(f);if(x.length===0){await g(e,`No OAuth account for ${f}. Login first: /login ${f}`,o);return}let M=d?x.find(b=>b.id===d):void 0;if(d&&!M){await g(e,`Account not found: ${f}/${d}`,o);return}if(!M){let b=w.getDefaultAccount(f);M=x.find(k=>k.id===b?.id)||x[0]}let S=await ge(l,e,o),_=S.modelProvider!==f;S.modelProvider=f,_&&(S.modelId=void 0),S.accountId=M.id,S.authMode="oauth",S.updatedAt=O(),await T(l);let I=M.email||M.id,$=d?"":" [default]";await g(e,`Session ${S.id} now uses OAuth mode for ${f} (${I}${$}).`,o);return}case"mcp":{if(r.trim().toLowerCase()==="refresh"){Mn(),await me(p.agentDir,{timeoutMs:5e3,maxBytes:p.fetchMaxBytes,maxChars:3e3}),Pe(),await g(e,"MCP catalog refreshed.",o);return}let s=await $i();await g(e,s,o);return}case"login":{let s=ro();if(!r){let f=s.map(h=>`- ${h.id} (${h.name})`);await g(e,["OAuth providers:",...f].join(`
126
+ `),o);return}let a=U(r);if(Nt.has(t)){await g(e,"Login already in progress.",o);return}let d=s.find(f=>f.id===a);if(!d){await g(e,`Unknown OAuth provider: ${a}`,o);return}Nt.add(t);try{let{authStorage:f}=await X(),h=Z(),y=h.listAccounts(a);y.length>0&&await g(e,`You have ${y.length} account(s) for ${a}. Adding a new one...`,o),await g(e,`Starting login for ${d.id}...`,o);let w=Ns(a);if(!w)throw new Error(`OAuth provider not found: ${a}`);let x=await w.login({onAuth:({url:$,instructions:b})=>{let k=["Open this URL in your browser:",$];b&&k.push("",b),di(e,k.join(`
127
+ `),o)},onPrompt:$=>ao(t,e,$,o),onProgress:$=>{g(e,$,o)},onManualCodeInput:()=>ao(t,e,{message:"Paste the authorization code:"},o)}),M=x.email,S=await h.addAccount(a,x,{email:M});f.set(a,{type:"oauth",...x});let _=h.listAccounts(a),I=M||S;await g(e,`Login completed for ${d.id}.
128
+ Account: ${I}
129
129
  Account ID: ${S}
130
- Total accounts: ${P.length}
131
- Use /accounts ${a} to see all accounts.`,r)}catch(p){let h=ie(p);await g(e,`Login failed: ${h}`,r)}finally{Dt.delete(t),ho(t)}return}case"logout":{if(!o){await g(e,`Usage: /logout <provider> \u2014 lists accountIds if multiple.
130
+ Total accounts: ${_.length}
131
+ Use /accounts ${a} to see all accounts.`,o)}catch(f){let h=ie(f);await g(e,`Login failed: ${h}`,o)}finally{Nt.delete(t),ho(t)}return}case"logout":{if(!r){await g(e,`Usage: /logout <provider> \u2014 lists accountIds if multiple.
132
132
  /logout <provider>/<accountId> \u2014 logout one account.
133
- /logout <provider>/all \u2014 logout all accounts for that provider.`,r);return}let s=Q();if(o.includes("/")){let[a,d]=o.split("/",2),p=j(a);if(d==="all"){let w=await s.removeAllAccounts(p),{authStorage:x}=await Y();x.logout(p),await g(e,`Logged out from ${p} (${w} account(s)).`,r);return}let h=s.getAccount(p,d);if(!h){await g(e,`Account not found: ${p}/${d}`,r);return}let y=h.email||d;if(await s.removeAccount(p,d),!s.hasAccounts(p)){let{authStorage:w}=await Y();w.logout(p)}await g(e,`Logged out: ${y} (${p})`,r)}else{let a=j(o),d=s.listAccounts(a);if(d.length===0){await g(e,`No accounts for ${a}.`,r);return}if(d.length>1){let y=d.map(S=>` ${S.id}${S.email?` (${S.email})`:""}${S.isDefault?" [default]":""}`),w=[...d.map(S=>({label:S.email?`Logout ${S.email}`:`Logout ${S.id}`,command:`/logout ${a}/${S.id}`})),{label:"Logout all",command:`/logout ${a}/all`}],x=zt(w,1),M=`You have ${d.length} account(s) for ${a}:
133
+ /logout <provider>/all \u2014 logout all accounts for that provider.`,o);return}let s=Z();if(r.includes("/")){let[a,d]=r.split("/",2),f=U(a);if(d==="all"){let w=await s.removeAllAccounts(f),{authStorage:x}=await X();x.logout(f),await g(e,`Logged out from ${f} (${w} account(s)).`,o);return}let h=s.getAccount(f,d);if(!h){await g(e,`Account not found: ${f}/${d}`,o);return}let y=h.email||d;if(await s.removeAccount(f,d),!s.hasAccounts(f)){let{authStorage:w}=await X();w.logout(f)}await g(e,`Logged out: ${y} (${f})`,o)}else{let a=U(r),d=s.listAccounts(a);if(d.length===0){await g(e,`No accounts for ${a}.`,o);return}if(d.length>1){let y=d.map(S=>` ${S.id}${S.email?` (${S.email})`:""}${S.isDefault?" [default]":""}`),w=[...d.map(S=>({label:S.email?`Logout ${S.email}`:`Logout ${S.id}`,command:`/logout ${a}/${S.id}`})),{label:"Logout all",command:`/logout ${a}/all`}],x=Bt(w,1),M=`You have ${d.length} account(s) for ${a}:
134
134
  ${y.join(`
135
135
  `)}
136
136
 
137
- Tap to logout:`;await Kt(e,M,x,r);return}let p=await s.removeAllAccounts(a),{authStorage:h}=await Y();h.logout(a),p>0?await g(e,`Logged out from ${a} (${p} account(s)).`,r):await g(e,`Logged out from ${a}.`,r)}return}case"accounts":{let s=Q();if(!o){let h=ro(),y=[];for(let w of h){let x=s.listAccounts(w.id);for(let M of x){let S=M.email||M.id,P=M.isDefault?" *":"";y.push({label:`${w.id}: ${S}${P}`,command:`/useaccount ${w.id}/${M.id}`})}}if(y.length===0){await g(e,"No accounts found. Use /login <provider> to add one.",r);return}await nt(e,"All accounts (tap to switch session to this account):",y,{perRow:1,footer:"Tap to switch provider and account. * = default for that provider.",messageThreadId:r});return}let a=j(o),d=s.listAccounts(a);if(d.length===0){await g(e,`No accounts for ${a}. Use /login ${a} to add one.`,r);return}let p=d.map(h=>{let y=h.email||h.id,w=h.isDefault?" *":"";return{label:`${y}${w}`,command:`/useaccount ${a}/${h.id}`}});await nt(e,`Accounts for ${a}:`,p,{perRow:1,footer:"Tap to use this account for current session. * = default",messageThreadId:r});return}case"useaccount":{if(!o||!o.includes("/")){await g(e,"Usage: /useaccount <provider>/<accountId>",r);return}let[s,a]=o.split("/",2),d=j(s),h=Q().getAccount(d,a);if(!h){await g(e,`Account not found: ${d}/${a}`,r);return}let y=await ge(l,e,r),w=y.modelProvider!==d;y.modelProvider=d,w&&(y.modelId=void 0),y.accountId=a,y.authMode="oauth",y.updatedAt=D(),await T(l);let x=h.email||a;await g(e,`Session "${y.title||y.id}" now using: ${x} (${d})`,r);return}case"setdefault":{if(!o||!o.includes("/")){await g(e,"Usage: /setdefault <provider>/<accountId>",r);return}let[s,a]=o.split("/",2),d=j(s),p=Q(),h=p.getAccount(d,a);if(!h){await g(e,`Account not found: ${d}/${a}`,r);return}if(!await p.setDefaultAccount(d,a)){await g(e,"Failed to set default account.",r);return}let w=h.email||a;await g(e,`Default account for ${d} set to: ${w}`,r);return}case"restart":{let s=f.restartScriptPath;if(!s){await g(e,'restart_script_path not configured. Set [paths] restart_script_path = "path/to/script.sh" in config.toml.',r);return}try{Cs("bash",[s],{stdio:"ignore",detached:!0}).unref(),await g(e,`Restart script started: ${s}`,r)}catch(a){let d=a instanceof Error?a.message:String(a);await g(e,`Restart failed: ${d}`,r)}return}case"memory":{let s=f.memory.rag,a=await Zn(),d=["Memory System Status:","",`RAG Enabled: ${s.enabled?"Yes":"No"}`,`Embedding Model: ${s.embeddingModel}`,`Embedding Base URL: ${s.embeddingBaseUrl||"(default)"}`,`Similarity Threshold: ${s.similarityThreshold}`,`Max Results: ${s.maxResults}`,"","Database:",` Sessions: ${a.sessionsCount}`,` Memories: ${a.memoriesCount}`,"","Tip: Use /reindex to rebuild memory vectors after changing embedding model."];await g(e,d.join(`
138
- `),r);return}case"reindex":{if(!f.memory.rag.enabled){await g(e,"Memory RAG is disabled. Enable it in config.toml first.",r);return}await g(e,["Starting memory reindex...","",`Embedding Model: ${f.memory.rag.embeddingModel}`,"","Reading sessions and rebuilding memories table..."].join(`
139
- `),r);try{let s=await eo((a,d,p)=>{(a%5===0||a===d)&&console.log(`[reindex] Progress: ${a}/${d} - ${p}`)});if(s.success){let a=["Reindex completed!","",`Sessions: ${s.totalSessions}`,`Total memories: ${s.totalMemories}`,`Indexed: ${s.indexedMemories}`,`Errors: ${s.errors.length}`,"",`Embedding Model: ${s.embeddingModel}`,`Vector Dimension: ${s.vectorDimension??"N/A"}`];s.errors.length>0&&(a.push("","Errors:"),s.errors.slice(0,5).forEach(d=>a.push(` - ${d}`)),s.errors.length>5&&a.push(` ... and ${s.errors.length-5} more`)),await g(e,a.join(`
140
- `),r)}else await g(e,`Reindex failed: ${s.errors.join(", ")}`,r)}catch(s){let a=s instanceof Error?s.message:String(s);await g(e,`Reindex failed: ${a}`,r)}return}default:await g(e,`Unknown command: ${n}`,r)}}async function Si(e,t,n,o=[],r){let i=It(n);if(i){await Bt(e,t,i.command,i.args,r);return}let u=ot(e,r,r!==void 0);if(!u)return;let l=await Je(u),m=gt(l);m.length>0&&(await T(l),await Promise.all(m.map(S=>ve(u,S).catch(P=>{console.warn(`[tg-agent] cleanup session file failed id=${S}`,P)}))));let s=fe(l);if(!s)try{s=He(l,""),await T(l),await g(e,`Created session ${s.id}.`,r)}catch(S){await g(e,S.message,r);return}let{resolved:a,images:d}=await Js(o);if(o.length>0&&a.length===0&&!n.trim()){await g(e,"Failed to download attachments.",r);return}let p=Bs(a),h=[];n.trim()&&h.push(n.trim()),p&&h.push(p);let y=h.join(`
137
+ Tap to logout:`;await Wt(e,M,x,o);return}let f=await s.removeAllAccounts(a),{authStorage:h}=await X();h.logout(a),f>0?await g(e,`Logged out from ${a} (${f} account(s)).`,o):await g(e,`Logged out from ${a}.`,o)}return}case"accounts":{let s=Z();if(!r){let h=ro(),y=[];for(let w of h){let x=s.listAccounts(w.id);for(let M of x){let S=M.email||M.id,_=M.isDefault?" *":"";y.push({label:`${w.id}: ${S}${_}`,command:`/useaccount ${w.id}/${M.id}`})}}if(y.length===0){await g(e,"No accounts found. Use /login <provider> to add one.",o);return}await nt(e,"All accounts (tap to switch session to this account):",y,{perRow:1,footer:"Tap to switch provider and account. * = default for that provider.",messageThreadId:o});return}let a=U(r),d=s.listAccounts(a);if(d.length===0){await g(e,`No accounts for ${a}. Use /login ${a} to add one.`,o);return}let f=d.map(h=>{let y=h.email||h.id,w=h.isDefault?" *":"";return{label:`${y}${w}`,command:`/useaccount ${a}/${h.id}`}});await nt(e,`Accounts for ${a}:`,f,{perRow:1,footer:"Tap to use this account for current session. * = default",messageThreadId:o});return}case"useaccount":{if(!r||!r.includes("/")){await g(e,"Usage: /useaccount <provider>/<accountId>",o);return}let[s,a]=r.split("/",2),d=U(s),h=Z().getAccount(d,a);if(!h){await g(e,`Account not found: ${d}/${a}`,o);return}let y=await ge(l,e,o),w=y.modelProvider!==d;y.modelProvider=d,w&&(y.modelId=void 0),y.accountId=a,y.authMode="oauth",y.updatedAt=O(),await T(l);let x=h.email||a;await g(e,`Session "${y.title||y.id}" now using: ${x} (${d})`,o);return}case"setdefault":{if(!r||!r.includes("/")){await g(e,"Usage: /setdefault <provider>/<accountId>",o);return}let[s,a]=r.split("/",2),d=U(s),f=Z(),h=f.getAccount(d,a);if(!h){await g(e,`Account not found: ${d}/${a}`,o);return}if(!await f.setDefaultAccount(d,a)){await g(e,"Failed to set default account.",o);return}let w=h.email||a;await g(e,`Default account for ${d} set to: ${w}`,o);return}case"restart":{let s=p.restartScriptPath;if(!s){await g(e,'restart_script_path not configured. Set [paths] restart_script_path = "path/to/script.sh" in config.toml.',o);return}try{Ts("bash",[s],{stdio:"ignore",detached:!0}).unref(),await g(e,`Restart script started: ${s}`,o)}catch(a){let d=a instanceof Error?a.message:String(a);await g(e,`Restart failed: ${d}`,o)}return}case"memory":{let s=p.memory.rag,a=await Zn(),d=["Memory System Status:","",`RAG Enabled: ${s.enabled?"Yes":"No"}`,`Embedding Model: ${s.embeddingModel}`,`Embedding Base URL: ${s.embeddingBaseUrl||"(default)"}`,`Similarity Threshold: ${s.similarityThreshold}`,`Max Results: ${s.maxResults}`,"","Database:",` Sessions: ${a.sessionsCount}`,` Memories: ${a.memoriesCount}`,"","Tip: Use /reindex to rebuild memory vectors after changing embedding model."];await g(e,d.join(`
138
+ `),o);return}case"reindex":{if(!p.memory.rag.enabled){await g(e,"Memory RAG is disabled. Enable it in config.toml first.",o);return}await g(e,["Starting memory reindex...","",`Embedding Model: ${p.memory.rag.embeddingModel}`,"","Reading sessions and rebuilding memories table..."].join(`
139
+ `),o);try{let s=await eo((a,d,f)=>{(a%5===0||a===d)&&console.log(`[reindex] Progress: ${a}/${d} - ${f}`)});if(s.success){let a=["Reindex completed!","",`Sessions: ${s.totalSessions}`,`Total memories: ${s.totalMemories}`,`Indexed: ${s.indexedMemories}`,`Errors: ${s.errors.length}`,"",`Embedding Model: ${s.embeddingModel}`,`Vector Dimension: ${s.vectorDimension??"N/A"}`];s.errors.length>0&&(a.push("","Errors:"),s.errors.slice(0,5).forEach(d=>a.push(` - ${d}`)),s.errors.length>5&&a.push(` ... and ${s.errors.length-5} more`)),await g(e,a.join(`
140
+ `),o)}else await g(e,`Reindex failed: ${s.errors.join(", ")}`,o)}catch(s){let a=s instanceof Error?s.message:String(s);await g(e,`Reindex failed: ${a}`,o)}return}default:await g(e,`Unknown command: ${n}`,o)}}async function Ai(e,t,n,r=[],o){let i=zt(n);if(i){await Jt(e,t,i.command,i.args,o);return}let u=ot(e,o,o!==void 0);if(!u)return;let l=await Je(u),m=ht(l);m.length>0&&(await T(l),await Promise.all(m.map(S=>ve(u,S).catch(_=>{console.warn(`[tg-agent] cleanup session file failed id=${S}`,_)}))));let s=fe(l);if(!s)try{s=He(l,""),await T(l),await g(e,`Created session ${s.id}.`,o)}catch(S){await g(e,S.message,o);return}let{resolved:a,images:d}=await qs(r);if(r.length>0&&a.length===0&&!n.trim()){await g(e,"Failed to download attachments.",o);return}let f=Js(a),h=[];n.trim()&&h.push(n.trim()),f&&h.push(f);let y=h.join(`
141
141
 
142
- `)||"Attachment received.",w={role:"user",content:y,ts:D()};ht(s,w,f.maxHistoryMessages),await T(l),console.log(`[tg-agent] request user=${t} chat=${u} session=${s.id} messages=${s.messages.length} textLen=${y.length} attachments=${a.length} provider=${s.modelProvider??"-"} model=${s.modelId??"-"}`);let x=null;try{x=await hi(e,r)}catch(S){console.warn("[tg-agent] status message failed",S)}let M={sessionId:s.id,chatId:e,messageThreadId:r,status:x,abortRequested:!1,cancelRequested:!1};Ns(u,M);try{let S=f.systemPrompt;if(s.soulName)try{let $=await Ce(s.soulName);S+=`
142
+ `)||"Attachment received.",w={role:"user",content:y,ts:O()};bt(s,w,p.maxHistoryMessages),await T(l),console.log(`[tg-agent] request user=${t} chat=${u} session=${s.id} messages=${s.messages.length} textLen=${y.length} attachments=${a.length} provider=${s.modelProvider??"-"} model=${s.modelId??"-"}`);let x=null;try{x=await bi(e,o)}catch(S){console.warn("[tg-agent] status message failed",S)}let M={sessionId:s.id,chatId:e,messageThreadId:o,status:x,abortRequested:!1,cancelRequested:!1};Ls(u,M);try{let S=p.systemPrompt;if(s.soulName)try{let $=await Ce(s.soulName);S+=`
143
143
 
144
- ${Xe(s.soulName,$)}`,console.log(`[tg-agent] injected soul name=${s.soulName} chars=${$.length}`)}catch($){console.warn(`[tg-agent] failed to load soul name=${s.soulName}: ${ie($)}`)}if(f.memory.rag.enabled&&y.trim())try{let $=await Qn(y);if($.length>0){let b=$.map(k=>`- [${k.type}] ${k.content} (${k.date})`).join(`
144
+ ${Xe(s.soulName,$)}`,console.log(`[tg-agent] injected soul name=${s.soulName} chars=${$.length}`)}catch($){console.warn(`[tg-agent] failed to load soul name=${s.soulName}: ${ie($)}`)}if(p.memory.rag.enabled&&y.trim())try{let $=await Qn(y);if($.length>0){let b=$.map(k=>`- [${k.type}] ${k.content} (${k.date})`).join(`
145
145
  `);S+=`
146
146
 
147
147
  <relevant_memories>
148
148
  Relevant facts about Shawn from past conversations:
149
149
 
150
150
  ${b}
151
- </relevant_memories>`,console.log(`[memory-rag] injected ${$.length} memories into context`)}}catch($){console.warn(`[memory-rag] retrieval failed: ${$}`)}let P=await Os(async()=>{let $=await Ve({chatId:u,sessionId:s.id,prompt:y,images:d,systemPrompt:S,modelProvider:s.modelProvider,modelId:s.modelId,accountId:s.accountId,authMode:jt(s.authMode),workspaceDir:Lt(u,l),telegram:{chatId:e,sendPhoto:async(b,k)=>{let F={};k&&(F.caption=k),r!==void 0&&(F.message_thread_id=r),await L.sendPhoto(e,b,F)},sendDocument:async(b,k)=>{let F={};k&&(F.caption=k),r!==void 0&&(F.message_thread_id=r),await L.sendDocument(e,b,F)},sendMessage:async b=>{await g(e,b,r)},requestConfirmation:async(b,k)=>await so(u,e,b,k,r)},auditContext:f.audit.enabled?{chatId:u,requestConfirmation:async(b,k)=>await so(u,e,b,k,r),sendNotification:async b=>{await g(e,b,r)}}:void 0,onAbortReady:b=>{M.abort=b,M.abortRequested&&b()},onStatus:x?b=>{let k=wi(b);k&&x?.update(k)}:void 0});return console.log(`[tg-agent] response session=${s.id} model=${$.modelProvider}/${$.modelId} file=${$.sessionFile}`),$.text});if(M.cancelRequested){x?await x.finalize("Cancelled by user."):await g(e,"Cancelled by user.",r);return}let U={role:"assistant",content:P,ts:D()};ht(s,U,f.maxHistoryMessages),await T(l),x?await x.finalize(P):await g(e,P,r)}catch(S){if(console.error("[tg-agent] runModel error",S),M.cancelRequested){x?await x.fail("Cancelled by user."):await g(e,"Cancelled by user.",r);return}let P=ie(S);x?await x.fail(`Error: ${P}`):await g(e,`Error: ${P}`,r)}finally{Ut(u)}}async function $i(){let e=[{type:"default"},{type:"all_private_chats"},{type:"all_group_chats"}];for(let t of e)try{await L.setMyCommands(fo,{scope:t}),console.log(`[tg-agent] bot commands registered scope=${t.type} count=${fo.length}`)}catch(n){let o=n instanceof Error?n.message:String(n);console.warn(`[tg-agent] setMyCommands failed scope=${t.type}:`,o)}}var L,go,Os,De,Ls,Hs,Vs,de,Dt,Te,Ys,Xs,tt,ei,si,mo,Ao,po,ui,ee,gi,yi,fo,Mo=I(()=>{"use strict";K();lt();dt();Mt();we();xt();At();_e();wt();no();Et();_t();J();dn();L=new Rs(f.telegramToken,{polling:!0}),go=Xt(),Os=Qt(f.maxConcurrent),De=new Map;Ls="image/jpeg";Hs=new Set(["_","*","[","]","(",")","~","`",">","#","+","-","=","|","{","}",".","!"]);Vs=600*1e3,de=new Map,Dt=new Set,Te=new Map;Ys=new Map([["codex","openai-codex"],["claude","anthropic"],["antigravity","google-antigravity"],["gemini","google-gemini-cli"],["gemini-cli","google-gemini-cli"]]),Xs={"codex-mini-latest":"gpt-5.1-codex-mini","codex-max-latest":"gpt-5.1-codex-max","codex-latest":"gpt-5.2-codex"};Zs();C(f.agentDir).catch(e=>{console.warn(`[tg-agent] ensure agentDir failed: ${e instanceof Error?e.message:String(e)}`)});(async()=>{try{await me(f.agentDir,{timeoutMs:3e3,maxBytes:f.fetchMaxBytes,maxChars:2e3}),Pe()}catch(e){let t=e instanceof Error?e.message:String(e);console.warn(`[tg-agent] mcp catalog warmup failed: ${t}`)}})();tt=Fe();console.log(tt?`[tg-agent] fetchProxy=${tt.url} kind=${tt.kind} source=${tt.source}`:"[tg-agent] fetchProxy=(none)");ei=new Set(["openai-codex","google-antigravity","anthropic"]);si=6e4,mo=new Map;Ao=1800*1e3,po=2e3,ui=60,ee=new Map;gi=3900,yi=1200;L.on("callback_query",e=>{let t=e.data??"",n=e.message?.chat.id;if(!e.from?.id||!n){L.answerCallbackQuery(e.id);return}let o=String(e.from.id);if(!xo(o)){vo(o,n),L.answerCallbackQuery(e.id);return}if(!t.startsWith("cmd:")){L.answerCallbackQuery(e.id);return}let r=pi(t);if(!r){L.answerCallbackQuery(e.id,{text:"Command expired."});return}L.answerCallbackQuery(e.id);let i=e.message?.message_thread_id,c=e.message?.is_topic_message??!1,u=ot(n,i,c);if(!u)return;let l=It(r);if(l?.command==="stop"){Ee(u,!1)?g(n,"Operation blocked.",i):wo(n,u,i);return}if(l?.command==="close"){bo(n,u,l.args,i);return}if(l?.command==="approve"){Ee(u,!0)?g(n,"Operation approved.",i):g(n,"No pending audit confirmation.",i);return}go(u,async()=>{if(!l){await g(n,"Invalid command.",i);return}await Bt(n,o,l.command,l.args,i)}).catch(async m=>{console.error("[tg-agent] runModel error",m);let s=ie(m);await g(n,`Error: ${s}`,i)})});L.on("message",e=>{if(!e.from?.id)return;let t=String(e.from.id),n=e.chat.id;if(!xo(t)){vo(t,n);return}let o=e.message_thread_id,r=e.is_topic_message??!1,i=ot(n,o,r);if(!i)return;let c=(e.text??e.caption??"").trim(),u=Ws(e);if(!c&&u.length===0)return;let l=de.get(t);if(l){if(c==="/stop"||c==="/cancel"){Qs(t,"Login cancelled by user."),g(n,"Login cancelled.",o);return}if(!c){g(n,"Login expects a text response.",o);return}ho(t),l.resolve(c);return}let m=It(c);if(m?.command==="stop"){Ee(i,!1),wo(n,i,o);return}if(m?.command==="close"){Ee(i,!1),bo(n,i,m.args,o);return}if(m?.command==="approve"){Ee(i,!0)?g(n,"Operation approved.",o):g(n,"No pending audit confirmation.",o);return}go(i,()=>Si(n,t,c,u,o)).catch(async s=>{console.error("[tg-agent] runModel error",s);let a=ie(s);await g(n,`Error: ${a}`,o)})});L.on("polling_error",e=>{console.error("Polling error",e)});fo=[{command:"new",description:"Create a new session"},{command:"list",description:"List all sessions"},{command:"use",description:"Switch to a session"},{command:"close",description:"Close current session"},{command:"reset",description:"Clear session history"},{command:"stop",description:"Stop current request"},{command:"workspace",description:"View/set workspace directory"},{command:"status",description:"Show session status"},{command:"providers",description:"List available providers"},{command:"models",description:"List models for provider"},{command:"provider",description:"Set provider for session"},{command:"model",description:"Set model for session"},{command:"modelraw",description:"Set custom model id for session"},{command:"mcp",description:"List MCP servers"},{command:"soul",description:"Bind/clear session soul profile"},{command:"memory",description:"Show memory RAG status"},{command:"reindex",description:"Rebuild memory vector index"},{command:"login",description:"Login to OAuth provider"},{command:"logout",description:"Logout from provider"},{command:"accounts",description:"List OAuth accounts (tap to switch)"},{command:"setdefault",description:"Set default OAuth account"},{command:"apikey",description:"Set/list API key for provider"},{command:"endpoint",description:"Set/list custom endpoint"},{command:"useapikey",description:"Use API key mode in session"},{command:"useoauth",description:"Use OAuth mode in session"},{command:"restart",description:"Run restart script (config)"},{command:"approve",description:"Approve security audit"},{command:"help",description:"Show all commands"}];$i();console.log("tg-agent started")});K();dt();_e();Mt();_t();J();import Mi from"node:fs";import ko from"node:path";import ki from"node:readline/promises";import{fileURLToPath as Pi}from"node:url";var te=process.argv.slice(2),_o=(e,t)=>te.includes(e)||(t?te.includes(t):!1),_i=_o("--help","-h"),Ci=_o("--version","-v"),Ri=["Usage: tg-agent [options] [ -c | --cli <prompt> ]","","Options:"," -h, --help Show help"," -v, --version Show version"," -c, --cli <cmd> Run a one-shot CLI task (no Telegram). Task must complete within TG_AGENT_CLI_TIMEOUT_MS (default 30m)."," -p, --provider <name> Model provider for CLI task (e.g. openai-codex)."," -m, --model <id> Model id for CLI task (e.g. gpt-4 or provider/modelId)."," --soul <name> Inject ~/.tg-agent/souls/<name>.md into this one-shot run."].join(`
152
- `),Ti=()=>{if(process.env.npm_package_version)return process.env.npm_package_version;try{let e=Pi(import.meta.url),t=ko.dirname(e),n=ko.join(t,"..","package.json"),o=Mi.readFileSync(n,"utf8"),r=JSON.parse(o);if(r.version)return r.version}catch{}return"dev"};_i&&(console.log(Ri),process.exit(0));Ci&&(console.log(Ti()),process.exit(0));async function Ei(){let e=ki.createInterface({input:process.stdin,output:process.stdout});try{return(await e.question("Enter TELEGRAM_BOT_TOKEN: ")).trim()}finally{e.close()}}function Di(){for(let e=0;e<te.length;e+=1){let t=te[e];if(t==="-c"||t==="--cli"){let n=te[e+1];return n!==void 0&&!n.startsWith("-")?n:null}if(t.startsWith("--cli="))return t.slice(6);if(t.startsWith("-c="))return t.slice(3)}return null}function Jt(e,t=!0){for(let n=0;n<te.length;n+=1){let o=te[n];if(e.includes(o)){let r=te[n+1];return r!==void 0&&!r.startsWith("-")&&r.trim()||null}if(t&&o.startsWith("--")){for(let r of e)if(r.startsWith("--")&&o.startsWith(r+"="))return o.slice(r.length+1).trim()||null}}return null}function Oi(){return Jt(["--provider","-p"])??null}function Ni(){return Jt(["--model","-m"])??null}function ji(){return Jt(["--soul"])??null}function Li(e){return te.includes(e)||te.some(t=>t.startsWith(`${e}=`))}async function Ui(e=!1){let{configPath:t,data:n,exists:o}=Me(),r=rn(),i=o?n:r,c=sn(i,r);if(an(i)){c&&await Ie(t,i);return}if(e){c&&await Ie(t,i);return}process.stdin.isTTY||(console.error(`Missing telegram.bot_token in ${t}.`),process.exit(1));let l=await Ei();l||(console.error("Empty TELEGRAM_BOT_TOKEN."),process.exit(1)),cn(i,l),await Ie(t,i),console.log(`Saved config to ${t}.`)}var Ht="[TG-AGENT-CLI-DONE]",Ii=`This is a one-shot CLI task. Do not reply to the user until the entire task is complete.
151
+ </relevant_memories>`,console.log(`[memory-rag] injected ${$.length} memories into context`)}}catch($){console.warn(`[memory-rag] retrieval failed: ${$}`)}let _=await js(async()=>{let $=await Ge({chatId:u,sessionId:s.id,prompt:y,images:d,systemPrompt:S,modelProvider:s.modelProvider,modelId:s.modelId,accountId:s.accountId,authMode:Ut(s.authMode),workspaceDir:It(u,l),telegram:{chatId:e,sendPhoto:async(b,k)=>{let E={};k&&(E.caption=k),o!==void 0&&(E.message_thread_id=o),await N.sendPhoto(e,b,E)},sendDocument:async(b,k)=>{let E={};k&&(E.caption=k),o!==void 0&&(E.message_thread_id=o),await N.sendDocument(e,b,E)},sendVoice:async(b,k)=>{let E={};k&&(E.caption=k),o!==void 0&&(E.message_thread_id=o),await N.sendVoice(e,b,E)},sendMessage:async b=>{await g(e,b,o)},requestConfirmation:async(b,k)=>await so(u,e,b,k,o)},auditContext:p.audit.enabled?{chatId:u,requestConfirmation:async(b,k)=>await so(u,e,b,k,o),sendNotification:async b=>{await g(e,b,o)}}:void 0,onAbortReady:b=>{M.abort=b,M.abortRequested&&b()},onStatus:x?b=>{let k=vi(b);k&&x?.update(k)}:void 0});return console.log(`[tg-agent] response session=${s.id} model=${$.modelProvider}/${$.modelId} file=${$.sessionFile}`),$.text});if(M.cancelRequested){x?await x.finalize("Cancelled by user."):await g(e,"Cancelled by user.",o);return}let I={role:"assistant",content:_,ts:O()};bt(s,I,p.maxHistoryMessages),await T(l),x?await x.finalize(_):await g(e,_,o)}catch(S){if(console.error("[tg-agent] runModel error",S),M.cancelRequested){x?await x.fail("Cancelled by user."):await g(e,"Cancelled by user.",o);return}let _=ie(S);x?await x.fail(`Error: ${_}`):await g(e,`Error: ${_}`,o)}finally{Ft(u)}}async function Mi(){let e=[{type:"default"},{type:"all_private_chats"},{type:"all_group_chats"}];for(let t of e)try{await N.setMyCommands(fo,{scope:t}),console.log(`[tg-agent] bot commands registered scope=${t.type} count=${fo.length}`)}catch(n){let r=n instanceof Error?n.message:String(n);console.warn(`[tg-agent] setMyCommands failed scope=${t.type}:`,r)}}var N,go,js,De,Is,Vs,Xs,de,Nt,Te,Qs,Zs,tt,ni,ai,mo,Ao,po,mi,te,hi,wi,fo,Mo=F(()=>{"use strict";K();lt();dt();Pt();we();$t();kt();_e();vt();no();Ot();Rt();J();pn();N=new Es(p.telegramToken,{polling:!0}),go=Zt(),js=en(p.maxConcurrent),De=new Map;Is="image/jpeg";Vs=new Set(["_","*","[","]","(",")","~","`",">","#","+","-","=","|","{","}",".","!"]);Xs=600*1e3,de=new Map,Nt=new Set,Te=new Map;Qs=new Map([["codex","openai-codex"],["claude","anthropic"],["antigravity","google-antigravity"],["gemini","google-gemini-cli"],["gemini-cli","google-gemini-cli"]]),Zs={"codex-mini-latest":"gpt-5.1-codex-mini","codex-max-latest":"gpt-5.1-codex-max","codex-latest":"gpt-5.2-codex"};ti();C(p.agentDir).catch(e=>{console.warn(`[tg-agent] ensure agentDir failed: ${e instanceof Error?e.message:String(e)}`)});(async()=>{try{await me(p.agentDir,{timeoutMs:3e3,maxBytes:p.fetchMaxBytes,maxChars:2e3}),Pe()}catch(e){let t=e instanceof Error?e.message:String(e);console.warn(`[tg-agent] mcp catalog warmup failed: ${t}`)}})();tt=Fe();console.log(tt?`[tg-agent] fetchProxy=${tt.url} kind=${tt.kind} source=${tt.source}`:"[tg-agent] fetchProxy=(none)");ni=new Set(["openai-codex","google-antigravity","anthropic"]);ai=6e4,mo=new Map;Ao=1800*1e3,po=2e3,mi=60,te=new Map;hi=3900,wi=1200;N.on("callback_query",e=>{let t=e.data??"",n=e.message?.chat.id;if(!e.from?.id||!n){N.answerCallbackQuery(e.id);return}let r=String(e.from.id);if(!xo(r)){vo(r,n),N.answerCallbackQuery(e.id);return}if(!t.startsWith("cmd:")){N.answerCallbackQuery(e.id);return}let o=gi(t);if(!o){N.answerCallbackQuery(e.id,{text:"Command expired."});return}N.answerCallbackQuery(e.id);let i=e.message?.message_thread_id,c=e.message?.is_topic_message??!1,u=ot(n,i,c);if(!u)return;let l=zt(o);if(l?.command==="stop"){Ee(u,!1)?g(n,"Operation blocked.",i):wo(n,u,i);return}if(l?.command==="close"){bo(n,u,l.args,i);return}if(l?.command==="approve"){Ee(u,!0)?g(n,"Operation approved.",i):g(n,"No pending audit confirmation.",i);return}go(u,async()=>{if(!l){await g(n,"Invalid command.",i);return}await Jt(n,r,l.command,l.args,i)}).catch(async m=>{console.error("[tg-agent] runModel error",m);let s=ie(m);await g(n,`Error: ${s}`,i)})});N.on("message",e=>{if(!e.from?.id)return;let t=String(e.from.id),n=e.chat.id;if(!xo(t)){vo(t,n);return}let r=e.message_thread_id,o=e.is_topic_message??!1,i=ot(n,r,o);if(!i)return;let c=(e.text??e.caption??"").trim(),u=Hs(e);if(!c&&u.length===0)return;let l=de.get(t);if(l){if(c==="/stop"||c==="/cancel"){ei(t,"Login cancelled by user."),g(n,"Login cancelled.",r);return}if(!c){g(n,"Login expects a text response.",r);return}ho(t),l.resolve(c);return}let m=zt(c);if(m?.command==="stop"){Ee(i,!1),wo(n,i,r);return}if(m?.command==="close"){Ee(i,!1),bo(n,i,m.args,r);return}if(m?.command==="approve"){Ee(i,!0)?g(n,"Operation approved.",r):g(n,"No pending audit confirmation.",r);return}go(i,()=>Ai(n,t,c,u,r)).catch(async s=>{console.error("[tg-agent] runModel error",s);let a=ie(s);await g(n,`Error: ${a}`,r)})});N.on("polling_error",e=>{console.error("Polling error",e)});fo=[{command:"new",description:"Create a new session"},{command:"list",description:"List all sessions"},{command:"use",description:"Switch to a session"},{command:"close",description:"Close current session"},{command:"reset",description:"Clear session history"},{command:"stop",description:"Stop current request"},{command:"workspace",description:"View/set workspace directory"},{command:"status",description:"Show session status"},{command:"providers",description:"List available providers"},{command:"models",description:"List models for provider"},{command:"provider",description:"Set provider for session"},{command:"model",description:"Set model for session"},{command:"modelraw",description:"Set custom model id for session"},{command:"mcp",description:"List MCP servers"},{command:"soul",description:"Bind/clear session soul profile"},{command:"memory",description:"Show memory RAG status"},{command:"reindex",description:"Rebuild memory vector index"},{command:"login",description:"Login to OAuth provider"},{command:"logout",description:"Logout from provider"},{command:"accounts",description:"List OAuth accounts (tap to switch)"},{command:"setdefault",description:"Set default OAuth account"},{command:"apikey",description:"Set/list API key for provider"},{command:"endpoint",description:"Set/list custom endpoint"},{command:"useapikey",description:"Use API key mode in session"},{command:"useoauth",description:"Use OAuth mode in session"},{command:"restart",description:"Run restart script (config)"},{command:"approve",description:"Approve security audit"},{command:"help",description:"Show all commands"}];Mi();console.log("tg-agent started")});K();dt();_e();Pt();Rt();J();import Pi from"node:fs";import ko from"node:path";import _i from"node:readline/promises";import{fileURLToPath as Ci}from"node:url";var ne=process.argv.slice(2),_o=(e,t)=>ne.includes(e)||(t?ne.includes(t):!1),Ri=_o("--help","-h"),Ti=_o("--version","-v"),Ei=["Usage: tg-agent [options] [ -c | --cli <prompt> ]","","Options:"," -h, --help Show help"," -v, --version Show version"," -c, --cli <cmd> Run a one-shot CLI task (no Telegram). Task must complete within TG_AGENT_CLI_TIMEOUT_MS (default 30m)."," -p, --provider <name> Model provider for CLI task (e.g. openai-codex)."," -m, --model <id> Model id for CLI task (e.g. gpt-4 or provider/modelId)."," --soul <name> Inject ~/.tg-agent/souls/<name>.md into this one-shot run."].join(`
152
+ `),Di=()=>{if(process.env.npm_package_version)return process.env.npm_package_version;try{let e=Ci(import.meta.url),t=ko.dirname(e),n=ko.join(t,"..","package.json"),r=Pi.readFileSync(n,"utf8"),o=JSON.parse(r);if(o.version)return o.version}catch{}return"dev"};Ri&&(console.log(Ei),process.exit(0));Ti&&(console.log(Di()),process.exit(0));async function Oi(){let e=_i.createInterface({input:process.stdin,output:process.stdout});try{return(await e.question("Enter TELEGRAM_BOT_TOKEN: ")).trim()}finally{e.close()}}function Ni(){for(let e=0;e<ne.length;e+=1){let t=ne[e];if(t==="-c"||t==="--cli"){let n=ne[e+1];return n!==void 0&&!n.startsWith("-")?n:null}if(t.startsWith("--cli="))return t.slice(6);if(t.startsWith("-c="))return t.slice(3)}return null}function qt(e,t=!0){for(let n=0;n<ne.length;n+=1){let r=ne[n];if(e.includes(r)){let o=ne[n+1];return o!==void 0&&!o.startsWith("-")&&o.trim()||null}if(t&&r.startsWith("--")){for(let o of e)if(o.startsWith("--")&&r.startsWith(o+"="))return r.slice(o.length+1).trim()||null}}return null}function ji(){return qt(["--provider","-p"])??null}function Li(){return qt(["--model","-m"])??null}function Ui(){return qt(["--soul"])??null}function Ii(e){return ne.includes(e)||ne.some(t=>t.startsWith(`${e}=`))}async function Fi(e=!1){let{configPath:t,data:n,exists:r}=Me(),o=an(),i=r?n:o,c=cn(i,o);if(ln(i)){c&&await Ie(t,i);return}if(e){c&&await Ie(t,i);return}process.stdin.isTTY||(console.error(`Missing telegram.bot_token in ${t}.`),process.exit(1));let l=await Oi();l||(console.error("Empty TELEGRAM_BOT_TOKEN."),process.exit(1)),un(i,l),await Ie(t,i),console.log(`Saved config to ${t}.`)}var Vt="[TG-AGENT-CLI-DONE]",zi=`This is a one-shot CLI task. Do not reply to the user until the entire task is complete.
153
153
  When you have fully completed the task, end your final reply with exactly the following line (and nothing after it):
154
- ${Ht}`,Po=1800*1e3,Fi=6e4,zi=1440*60*1e3;function Ki(){let e=process.env.TG_AGENT_CLI_TIMEOUT_MS;if(!e?.trim())return Po;let t=Number.parseInt(e.trim(),10);return Number.isFinite(t)?Math.min(zi,Math.max(Fi,t)):Po}function Bi(e){let t=e.trim(),n=Ht.trim();if(t.endsWith(n))return{stripped:t.slice(0,t.length-n.length).trimEnd(),found:!0};if((t.split(/\r?\n/).pop()?.trim()??"")===n){let r=t.split(/\r?\n/);return r.pop(),{stripped:r.join(`
155
- `).trimEnd(),found:!0}}return{stripped:e,found:!1}}function Wi(e,t){if(!e?.trim())return{};let n=e.trim();if(n.includes("/")){let[o,r]=n.split("/",2);if(o?.trim()&&r?.trim())return{modelProvider:o.trim(),modelId:r.trim()}}return{modelProvider:t?.trim()||void 0,modelId:n}}async function Ji(e){let t=Ki(),n=ji();if(Li("--soul")&&!n)return console.error("[tg-agent] Missing value for --soul. Usage: --soul <name>"),1;let r=[f.systemPrompt];if(n)try{let y=await Ce(n);r.push(Xe(n,y)),console.error(`[tg-agent] cli soul loaded name=${n} chars=${y.length}`)}catch(y){let w=y instanceof Error?y.message:String(y);return console.error(`[tg-agent] Failed to load soul "${n}": ${w}`),1}r.push(Ii);let i=r.join(`
154
+ ${Vt}`,Po=1800*1e3,Ki=6e4,Bi=1440*60*1e3;function Wi(){let e=process.env.TG_AGENT_CLI_TIMEOUT_MS;if(!e?.trim())return Po;let t=Number.parseInt(e.trim(),10);return Number.isFinite(t)?Math.min(Bi,Math.max(Ki,t)):Po}function Ji(e){let t=e.trim(),n=Vt.trim();if(t.endsWith(n))return{stripped:t.slice(0,t.length-n.length).trimEnd(),found:!0};if((t.split(/\r?\n/).pop()?.trim()??"")===n){let o=t.split(/\r?\n/);return o.pop(),{stripped:o.join(`
155
+ `).trimEnd(),found:!0}}return{stripped:e,found:!1}}function Hi(e,t){if(!e?.trim())return{};let n=e.trim();if(n.includes("/")){let[r,o]=n.split("/",2);if(r?.trim()&&o?.trim())return{modelProvider:r.trim(),modelId:o.trim()}}return{modelProvider:t?.trim()||void 0,modelId:n}}async function qi(e){let t=Wi(),n=Ui();if(Ii("--soul")&&!n)return console.error("[tg-agent] Missing value for --soul. Usage: --soul <name>"),1;let o=[p.systemPrompt];if(n)try{let y=await Ce(n);o.push(Xe(n,y)),console.error(`[tg-agent] cli soul loaded name=${n} chars=${y.length}`)}catch(y){let w=y instanceof Error?y.message:String(y);return console.error(`[tg-agent] Failed to load soul "${n}": ${w}`),1}o.push(zi);let i=o.join(`
156
156
 
157
- `),{modelProvider:c,modelId:u}=Wi(Ni(),Oi());try{await me(f.agentDir,{timeoutMs:3e3,maxBytes:f.fetchMaxBytes,maxChars:2e3}),Pe()}catch(y){let w=y instanceof Error?y.message:String(y);console.warn(`[tg-agent] mcp catalog warmup failed: ${w}`)}let l=f.audit.enabled?{chatId:"cli",requestConfirmation:async(y,w)=>process.env.TG_AGENT_AUTO_APPROVE==="1",sendNotification:async y=>{console.error(`[tg-agent] ${y}`)}}:void 0,m=()=>{},s=Ve({chatId:"cli",sessionId:oe(),prompt:e,systemPrompt:i,workspaceDir:f.workspaceDir,telegram:void 0,auditContext:l,modelProvider:c||void 0,modelId:u||void 0,onAbortReady:y=>{m=y}}),a=new Promise((y,w)=>{setTimeout(()=>{m(),w(new Error(`CLI timeout (${Math.round(t/6e4)} minutes)`))},t)}),d;try{d=await Promise.race([s,a])}catch(y){let w=y instanceof Error?y.message:String(y);return console.error(`[tg-agent] ${w}`),1}let{stripped:p,found:h}=Bi(d.text);return p.length>0&&console.log(p),h?0:(console.error(`[tg-agent] Task did not end with ${Ht} (incomplete).`),1)}async function Hi(){let{data:e}=Me(),t=typeof e.tls=="object"&&e.tls?e.tls:{},n=typeof t.extra_ca_certs=="string"?t.extra_ca_certs.trim():"";if(n&&(process.env.NODE_EXTRA_CA_CERTS=n),typeof t.reject_unauthorized=="boolean"){process.env.NODE_TLS_REJECT_UNAUTHORIZED=t.reject_unauthorized?"1":"0";return}let o=typeof t.reject_unauthorized=="string"?t.reject_unauthorized.trim():"";o&&(process.env.NODE_TLS_REJECT_UNAUTHORIZED=o)}var Wt=Di();await Ui(Wt!==null);await Hi();un();if(Wt!==null){Fe();let e=await Ji(Wt);process.exit(e)}Promise.resolve().then(()=>Mo());
157
+ `),{modelProvider:c,modelId:u}=Hi(Li(),ji());try{await me(p.agentDir,{timeoutMs:3e3,maxBytes:p.fetchMaxBytes,maxChars:2e3}),Pe()}catch(y){let w=y instanceof Error?y.message:String(y);console.warn(`[tg-agent] mcp catalog warmup failed: ${w}`)}let l=p.audit.enabled?{chatId:"cli",requestConfirmation:async(y,w)=>process.env.TG_AGENT_AUTO_APPROVE==="1",sendNotification:async y=>{console.error(`[tg-agent] ${y}`)}}:void 0,m=()=>{},s=Ge({chatId:"cli",sessionId:re(),prompt:e,systemPrompt:i,workspaceDir:p.workspaceDir,telegram:void 0,auditContext:l,modelProvider:c||void 0,modelId:u||void 0,onAbortReady:y=>{m=y}}),a=new Promise((y,w)=>{setTimeout(()=>{m(),w(new Error(`CLI timeout (${Math.round(t/6e4)} minutes)`))},t)}),d;try{d=await Promise.race([s,a])}catch(y){let w=y instanceof Error?y.message:String(y);return console.error(`[tg-agent] ${w}`),1}let{stripped:f,found:h}=Ji(d.text);return f.length>0&&console.log(f),h?0:(console.error(`[tg-agent] Task did not end with ${Vt} (incomplete).`),1)}async function Vi(){let{data:e}=Me(),t=typeof e.tls=="object"&&e.tls?e.tls:{},n=typeof t.extra_ca_certs=="string"?t.extra_ca_certs.trim():"";if(n&&(process.env.NODE_EXTRA_CA_CERTS=n),typeof t.reject_unauthorized=="boolean"){process.env.NODE_TLS_REJECT_UNAUTHORIZED=t.reject_unauthorized?"1":"0";return}let r=typeof t.reject_unauthorized=="string"?t.reject_unauthorized.trim():"";r&&(process.env.NODE_TLS_REJECT_UNAUTHORIZED=r)}var Ht=Ni();await Fi(Ht!==null);await Vi();mn();if(Ht!==null){Fe();let e=await qi(Ht);process.exit(e)}Promise.resolve().then(()=>Mo());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tg-agent",
3
- "version": "1.9.2",
3
+ "version": "1.9.3",
4
4
  "description": "Telegram Agent Bot",
5
5
  "type": "module",
6
6
  "bin": {