tg-agent 1.2.6 → 1.2.7
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/dist/cli.js +25 -25
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var H=(e,t)=>()=>(e&&(t=e(e=0)),t);import
|
|
3
|
-
`);s>t*.6&&(r=r.slice(0,s)),n.push(r),o=o.slice(r.length)}return o.length>0&&n.push(o),n}function
|
|
4
|
-
`);return
|
|
5
|
-
(truncated)`),ee=
|
|
6
|
-
`)})};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()-s},timestamp:Date.now(),sessionId:"debug-session",hypothesisId:"B,C"})}).catch(()=>{});let M=await v("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()-s,hasError:!!M.error},timestamp:Date.now(),sessionId:"debug-session",hypothesisId:"B,C"})}).catch(()=>{}),M.error&&typeof M.error=="object"){let b=M.error.message??"MCP initialize failed.";throw l(),new Error(String(b))}let _={jsonrpc:"2.0",method:"notifications/initialized"};
|
|
7
|
-
`),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()-s},timestamp:Date.now(),sessionId:"debug-session",hypothesisId:"C"})}).catch(()=>{});let E=await v(t,n);r.removeEventListener("abort",p),
|
|
2
|
+
var H=(e,t)=>()=>(e&&(t=e(e=0)),t);import Ce from"node:fs/promises";import gn from"node:os";import me from"node:path";import{randomUUID as Je}from"node:crypto";function N(){return Date.now()}function B(e){return e.startsWith("~")?me.join(gn.homedir(),e.slice(1)):e}async function z(e){await Ce.mkdir(e,{recursive:!0})}async function Ge(e,t){let n=me.dirname(e),o=`${me.basename(e)}.${Je()}.tmp`,r=me.join(n,o),s=JSON.stringify(t,null,2);await Ce.writeFile(r,s,"utf8"),await Ce.rename(r,e)}function ie(){return Je().split("-")[0]}function Ve(e,t){if(e.length<=t)return[e];let n=[],o=e;for(;o.length>t;){let r=o.slice(0,t),s=r.lastIndexOf(`
|
|
3
|
+
`);s>t*.6&&(r=r.slice(0,s)),n.push(r),o=o.slice(r.length)}return o.length>0&&n.push(o),n}function Xe(){let e=new Map;return async function(n,o){let s=(e.get(n)??Promise.resolve()).then(o,o);e.set(n,s);try{return await s}finally{e.get(n)===s&&e.delete(n)}}}function Qe(e){let t=0,n=[],o=()=>{if(t>=e)return;let r=n.shift();r&&(t+=1,r())};return async function(s){await new Promise(i=>{n.push(i),o()});try{return await s()}finally{t=Math.max(0,t-1),o()}}}var Y=H(()=>{"use strict"});import Ye from"node:fs";import pe from"node:path";import*as fe from"@iarna/toml";function tt(){let e=B(Ze);return pe.join(e,pn)}function j(e,t){let n=e[t];return n&&typeof n=="object"&&!Array.isArray(n)?n:{}}function O(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 Ae(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 fn(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 yn(e){return new Set(fn(e))}function hn(e){let t=new Map;for(let[n,o]of Object.entries(e))typeof o=="string"&&o.trim()&&t.set(n,pe.resolve(B(o.trim())));return t}function ae(){let e=tt();try{let t=Ye.readFileSync(e,"utf8"),n=fe.parse(t);return{configPath:e,data:n,exists:!0}}catch{return{configPath:e,data:{},exists:!1}}}async function Re(e,t){await z(pe.dirname(e));let n=fe.stringify(t);await Ye.promises.writeFile(e,n,"utf8")}function nt(){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"},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:et},tls:{extra_ca_certs:"",reject_unauthorized:""}}}function ge(e){return!!(e&&typeof e=="object"&&!Array.isArray(e))}function ot(e,t){let n=!1,o=(r,s)=>{for(let[i,l]of Object.entries(s)){if(!(i in r)){r[i]=l,n=!0;continue}let a=r[i];ge(a)&&ge(l)&&o(a,l)}};return ge(e)&&ge(t)&&o(e,t),n}function rt(e){let t=j(e,"telegram");return O(t.bot_token,"").trim()}function st(e,t){let n=j(e,"telegram");n.bot_token=t.trim(),e.telegram=n}function it(e){let t=j(e,"telegram"),n=j(e,"model"),o=j(e,"paths"),r=j(e,"limits"),s=j(e,"timeouts"),i=j(e,"fetch"),l=j(e,"proxy"),a=j(e,"auth"),u=j(e,"logging"),c=j(e,"system"),d=j(e,"tls"),g=j(e,"workspace_mappings"),p=O(o.workspace_dir,process.cwd()),h=O(o.session_dir,"~/.tg-agent/tg-sessions"),v=hn(g),M=O(d.reject_unauthorized,""),_=M===""?null:Ae(M,!0);return{telegramToken:O(t.bot_token,"").trim(),telegramAllowedUsers:yn(t.allowed_user_ids),telegramParseMode:O(t.parse_mode,"").trim(),modelProvider:O(n.provider,"openai-codex").trim(),modelRef:O(n.model,"gpt-5.2").trim(),openaiApiKey:O(n.openai_api_key,"").trim(),sessionDir:B(h),agentDir:B(Ze),workspaceDir:pe.resolve(B(p)),workspaceMappings:v,maxSessions:G(r.max_sessions,5),maxConcurrent:G(r.max_concurrent,5),maxHistoryMessages:G(r.max_history_messages,40),maxOutputTokens:G(r.max_output_tokens,0),fetchMaxBytes:G(i.max_bytes,2e5),fetchTimeoutMs:G(s.fetch_timeout_ms,6e4),modelTimeoutMs:G(s.model_timeout_ms,6e4),modelTimeoutStreamingMs:G(s.model_timeout_stream_ms,3e5),systemPrompt:O(c.prompt,et),proxyUrl:O(l.url,"").trim(),fetchProxyUrl:O(i.proxy_url,"").trim(),codexHome:B(O(a.codex_home,"~/.codex")),logAgentEvents:Ae(u.agent_events,!0),logAgentStream:Ae(u.agent_stream,!0),tlsExtraCaCerts:O(d.extra_ca_certs,"").trim(),tlsRejectUnauthorized:_}}function at(){let{data:e}=ae();return m=it(e),m}function ct(){let e=[];if(m.telegramToken||e.push("telegram.bot_token"),e.length>0)throw new Error(`Missing config values: ${e.join(", ")} (edit ${tt()})`)}var Ze,pn,et,wn,m,V=H(()=>{"use strict";Y();Ze="~/.tg-agent",pn="config.toml",et="You are running in user's personal computer or VPS, using telegram bot to interact with user. Be concise and practical.";({data:wn}=ae()),m=it(wn)});import{createHash as bn}from"node:crypto";import lt from"node:fs";import xn from"node:path";import{execSync as Sn}from"node:child_process";function kn(){return xn.join(m.codexHome,Mn)}function _n(e){return`cli|${bn("sha256").update(e).digest("hex").slice(0,16)}`}function $n(){if(process.platform!=="darwin")return null;let e=m.codexHome,t=_n(e);try{let n=Sn(`security find-generic-password -s "${vn}" -a "${t}" -w`,{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}).trim(),o=JSON.parse(n),r=o.tokens,s=r?.access_token,i=r?.refresh_token;if(typeof s!="string"||!s||typeof i!="string"||!i)return null;let l=o.last_refresh,a=typeof l=="string"||typeof l=="number"?new Date(l).getTime():Date.now(),u=Number.isFinite(a)?a+3600*1e3:Date.now()+3600*1e3;return{accessToken:s,refreshToken:i,expiresAt:u,source:"keychain"}}catch{return null}}function Tn(){let e=kn();try{let t=lt.readFileSync(e,"utf8"),o=JSON.parse(t).tokens,r=o?.access_token,s=o?.refresh_token;if(typeof r!="string"||!r||typeof s!="string"||!s)return null;let i=Date.now()+3600*1e3;try{i=lt.statSync(e).mtimeMs+3600*1e3}catch{}return{accessToken:r,refreshToken:s,expiresAt:i,source:"file"}}catch{return null}}function Z(){return $n()??Tn()}var Mn,vn,ye=H(()=>{"use strict";V();Mn="auth.json",vn="Codex Auth"});function ut(e){let t=e.trim().toLowerCase();if(t==="openai-codex"||t==="codex"){let n=Z();if(n)return{apiKey:n.accessToken,source:`codex:${n.source}`};throw new Error("No Codex OAuth credentials found. Run `codex login`.")}if(m.openaiApiKey)return{apiKey:m.openaiApiKey,source:"config.model.openai_api_key"};throw new Error(`No API key for provider: ${e}`)}function Pn(){return m.proxyUrl?{url:m.proxyUrl,source:"config.proxy.url"}:m.fetchProxyUrl?{url:m.fetchProxyUrl,source:"config.fetch.proxy_url"}:null}function dt(e){let t=e.toLowerCase();return t.startsWith("socks5://")||t.startsWith("socks4://")||t.startsWith("socks://")?"socks":t.startsWith("https://")?"https":"http"}function mt(){let e=Pn();return e?{url:e.url,kind:dt(e.url),source:e.source}:null}function gt(){let e=[{key:"config.fetch.proxy_url",value:m.fetchProxyUrl},{key:"config.proxy.url",value:m.proxyUrl}];for(let t of e){let n=t.value?.trim();if(!n)continue;let o=dt(n);if(o!=="socks")return{url:n,kind:o,source:t.key}}return null}var De=H(()=>{"use strict";V();ye()});import{ProxyAgent as Cn,setGlobalDispatcher as An}from"undici";function ft(){if(pt)return Ee;pt=!0;let e=gt();if(!e)return Ee=null,null;let t=new Cn(e.url);return An(t),Ee=e,e}var pt,Ee,yt=H(()=>{"use strict";De();pt=!1,Ee=null});import Rn from"node:fs";import Dn from"node:fs/promises";import En from"node:path";import On from"node:readline";import{spawn as jn}from"node:child_process";import*as wt from"@iarna/toml";function St(e){return En.join(e,"config.toml")}function he(e){let t=St(e);try{let n=Rn.readFileSync(t,"utf8");return _t(n)}catch{return[]}}async function ce(e){let t=St(e);try{let n=await Dn.readFile(t,"utf8");return _t(n)}catch{return[]}}async function le(e,t={}){if(ee)return ee;let n=await ce(e);if(n.length===0)return ee="","";let o=t.maxTools??zn,r=t.maxChars??Nn,s=t.timeoutMs??4e3,i=t.maxBytes??bt,l=["MCP catalog (auto-discovered):","Use tool 'mcp' with server=<name> method=<tool> params=<object>."];for(let u of n){let c=await Ln(u,{timeoutMs:s,maxBytes:i});if(l.push(`${u.name} (${u.type})`),c.length===0){l.push(" - tools unavailable");continue}let d=c.slice(0,o);for(let g of d){let p=g.description?`: ${g.description}`:"";l.push(` - ${g.name}${p}`)}c.length>d.length&&l.push(` - ...and ${c.length-d.length} more`)}let a=l.join(`
|
|
4
|
+
`);return a.length>r&&(a=`${a.slice(0,r-20)}...
|
|
5
|
+
(truncated)`),ee=a,a}function je(){ee&&(xt=!0)}function Mt(){ee=null,xt=!1,I.clear()}function Q(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 vt(e,t=5e3){let n=Date.now();try{return await we(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 we(e,t,n,o={}){let r=ht(o.timeoutMs??Fn,1e3,12e4),s=ht(o.maxBytes??bt,1024,5e6),i=new AbortController,l=()=>i.abort();o.signal?.addEventListener("abort",l,{once:!0});let a=setTimeout(()=>i.abort(),r);try{return e.type==="http"?(t!=="initialize"&&t!=="notifications/initialized"&&await Wn(e,s,i.signal),await Bn(e,t,n,s,i.signal)):await Kn(e,t,n,s,i.signal)}finally{clearTimeout(a),o.signal?.removeEventListener("abort",l)}}function ht(e,t,n){return Number.isNaN(e)?t:Math.min(n,Math.max(t,e))}async function Ln(e,t){try{let n=await we(e,"tools/list",{},t);return Un(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 Un(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 s=[];for(let i of r){if(!i||typeof i!="object")continue;let l=i,a=typeof l.name=="string"?l.name:"";if(!a)continue;let u=typeof l.description=="string"?l.description:void 0,c=l.inputSchema;s.push({name:a,description:u,inputSchema:c})}return s}async function Bn(e,t,n,o,r){if(!e.url)throw new Error("MCP server url is missing.");let s=Date.now(),i=await Oe(e,t,n,o,r),l=kt(i.parsed);if(l)throw new Error(l);let a=i.bodyText;return i.parsed&&(a=JSON.stringify(i.parsed,null,2)),{ok:i.statusCode>=200&&i.statusCode<300,output:a,durationMs:Date.now()-s,bytes:i.bytes,truncated:i.truncated,statusCode:i.statusCode,statusText:i.statusText,contentType:i.contentType}}async function Oe(e,t,n,o,r){if(!e.url)throw new Error("MCP server url is missing.");let s=I.get(e.name),i={jsonrpc:"2.0",id:`tg-agent-${Date.now()}`,method:t,params:n??{}},l={"content-type":"application/json"};e.auth&&(l.authorization=e.auth.startsWith("Bearer ")?e.auth:`Bearer ${e.auth}`),s?.cookie&&(l.cookie=s.cookie),s?.sessionId&&(l["mcp-session-id"]=s.sessionId);let a=await fetch(e.url,{method:"POST",headers:l,body:JSON.stringify(i),signal:r});Hn(e.name,a);let u=await Jn(a,o,r),c;try{c=JSON.parse(u.text)}catch{c=void 0}return qn(e.name,c),{statusCode:a.status,statusText:a.statusText,contentType:a.headers.get("content-type"),bodyText:u.text,parsed:c,bytes:u.bytes,truncated:u.truncated}}function kt(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 Wn(e,t,n){let o=I.get(e.name);if(o?.initializedAt)return;if(o?.inFlight){await o.inFlight;return}let r=(async()=>{let s=await Oe(e,"initialize",{protocolVersion:"2024-11-05",clientInfo:{name:"tg-agent",version:process.env.npm_package_version??"dev"},capabilities:{}},t,n),i=kt(s.parsed);if(i){let u=i.toLowerCase();if(u.includes("method")&&u.includes("not"))return;throw new Error(i)}let l=new AbortController,a=setTimeout(()=>l.abort(),In);try{await Oe(e,"notifications/initialized",{},t,l.signal)}catch{}finally{clearTimeout(a)}})();I.set(e.name,{initializedAt:Date.now(),inFlight:r});try{await r;let s=I.get(e.name);I.set(e.name,{initializedAt:Date.now(),cookie:s?.cookie,sessionId:s?.sessionId})}catch(s){throw I.delete(e.name),s}}function Hn(e,t){let o=I.get(e)??{initializedAt:0},r=t.headers.get("set-cookie"),s=t.headers.getSetCookie?.(),i=s&&s.length>0?s.join("; "):r;i&&I.set(e,{...o,cookie:i});let l=t.headers.get("mcp-session-id")??t.headers.get("x-mcp-session-id");l&&I.set(e,{...o,sessionId:l})}function qn(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 s=I.get(e)??{initializedAt:0};I.set(e,{...s,sessionId:r})}async function Kn(e,t,n,o,r){if(!e.command)throw new Error("MCP server command is missing.");let s=Date.now(),i=jn(e.command,e.args??[],{stdio:["pipe","pipe","pipe"]}),l=()=>{i.killed||i.kill("SIGTERM")};if(r.aborted)throw l(),new Error("MCP request aborted.");let a=new Map,u=!1,c="",d=new Error("MCP request aborted."),g=On.createInterface({input:i.stdout,terminal:!1});g.on("line",b=>{if(b.length>o){u=!0;return}let S=null;try{S=JSON.parse(b)}catch{return}let k=typeof S.id=="string"?S.id:typeof S.id=="number"?String(S.id):"";if(!k)return;let P=a.get(k);P&&(a.delete(k),P.resolve(S))}),i.stderr?.on("data",b=>{let S=b.toString();if(c.length+S.length>o){u=!0;return}c+=S});let p=()=>{for(let b of a.values())b.reject(d);a.clear(),l()};r.addEventListener("abort",p,{once:!0});let h=b=>{let S=b===0?"MCP stdio exited.":c.trim()||"MCP stdio exited with error.";for(let k of a.values())k.reject(new Error(S));a.clear()};i.once("exit",b=>h(b));let v=async(b,S)=>{let k=`tg-agent-${Date.now()}-${Math.random().toString(16).slice(2,8)}`,P={jsonrpc:"2.0",id:k,method:b,params:S??{}};return await new Promise((y,w)=>{a.set(k,{resolve:y,reject:w}),i.stdin?.write(`${JSON.stringify(P)}
|
|
6
|
+
`)})};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()-s},timestamp:Date.now(),sessionId:"debug-session",hypothesisId:"B,C"})}).catch(()=>{});let M=await v("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()-s,hasError:!!M.error},timestamp:Date.now(),sessionId:"debug-session",hypothesisId:"B,C"})}).catch(()=>{}),M.error&&typeof M.error=="object"){let b=M.error.message??"MCP initialize failed.";throw l(),new Error(String(b))}let _={jsonrpc:"2.0",method:"notifications/initialized"};i.stdin?.write(`${JSON.stringify(_)}
|
|
7
|
+
`),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()-s},timestamp:Date.now(),sessionId:"debug-session",hypothesisId:"C"})}).catch(()=>{});let E=await v(t,n);r.removeEventListener("abort",p),g.close(),i.stdin?.end(),l();let T=new Promise(b=>{i.once("exit",()=>b())});if(await Promise.race([T,new Promise(b=>setTimeout(b,500))]),E.error&&typeof E.error=="object"){let b=E.error.message??"MCP request failed.";throw new Error(String(b))}let $=JSON.stringify(E,null,2),W=$.length>o?$.slice(0,o):$;return $.length>o&&(u=!0),{ok:!0,output:W,durationMs:Date.now()-s,bytes:Math.min($.length,o),truncated:u}}async function Jn(e,t,n){let o=e.body?.getReader?.();if(!o){let d=await e.text(),g=Math.min(d.length,t);return{text:d.slice(0,t),bytes:g,truncated:d.length>t}}let r=new TextDecoder("utf-8"),s=[],i=0,l=!1;for(;;){if(n.aborted){try{await o.cancel()}catch{}throw new Error("MCP request aborted.")}let{done:d,value:g}=await o.read();if(d)break;if(!g)continue;let p=i+g.byteLength;if(p>t){let h=Math.max(0,t-i);h>0&&(s.push(g.slice(0,h)),i+=h),l=!0;try{await o.cancel()}catch{}break}s.push(g),i=p}let a=new Uint8Array(i),u=0;for(let d of s)a.set(d,u),u+=d.byteLength;return{text:r.decode(a),bytes:i,truncated:l}}function _t(e){let t=[],n;try{n=wt.parse(e)}catch{return t}let o=n.mcp_servers;if(!o||typeof o!="object")return t;for(let[r,s]of Object.entries(o)){if(!s||typeof s!="object")continue;let i=s,l=typeof i.type=="string"?i.type.toLowerCase():void 0,a=typeof i.url=="string"?i.url:void 0,u=typeof i.command=="string"?i.command:void 0,c=l==="http"||l==="stdio"?l:a?"http":u?"stdio":void 0;if(!c||c==="http"&&!a||c==="stdio"&&!u)continue;let d;Array.isArray(i.args)&&(d=i.args.filter(p=>typeof p=="string").map(p=>p.trim()));let g=typeof i.auth=="string"?i.auth:typeof i.authorization=="string"?i.authorization:typeof i.token=="string"?i.token:void 0;t.push({name:r,type:c,url:a,command:u,args:d,auth:g})}return t}var Fn,bt,zn,Nn,ee,xt,I,In,be=H(()=>{"use strict";Fn=6e4,bt=2e5,zn=40,Nn=3500,ee=null,xt=!1,I=new Map,In=1500});import J from"node:path";import Gn from"node:fs/promises";import{Type as x}from"@sinclair/typebox";function xe(e,t,n){return Number.isNaN(e)?t:Math.min(n,Math.max(t,e))}function Qn(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 $t(e){let t=m.fetchTimeoutMs>0?m.fetchTimeoutMs:Xn;return xe(e||t,1e3,12e4)}function Tt(e){let t=m.fetchMaxBytes>0?m.fetchMaxBytes:Vn;return xe(e||t,1024,5e6)}function Pt(e,t,n){let o=e.trim();if(!o)return null;let r=B(o),s=J.isAbsolute(r)?r:J.join(n,r),i=J.resolve(s);for(let l of t){let a=J.resolve(l);if(i===a||i.startsWith(`${a}${J.sep}`))return i}return null}async function Ct(e){try{let t=await Gn.stat(e);return t.isFile()?{bytes:t.size}:null}catch{return null}}function Yn(e){try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}function Zn(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 eo(e,t,n){let o=e.body?.getReader?.();if(!o){let c=await e.text?.()??"",d=Math.min(c.length,t),g=c.length>t;return{text:c.slice(0,t),bytes:d,truncated:g}}let r=new TextDecoder("utf-8"),s=[],i=0,l=!1;for(;;){if(n?.aborted){try{await o.cancel?.()}catch{}throw new Error("Fetch aborted")}let{done:c,value:d}=await o.read();if(c)break;if(!d)continue;let g=i+d.byteLength;if(g>t){let p=Math.max(0,t-i);p>0&&(s.push(d.slice(0,p)),i+=p),l=!0;try{await o.cancel?.()}catch{}break}s.push(d),i=g}let a=Zn(s,i);return{text:r.decode(a),bytes:i,truncated:l}}function to(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}
|
|
8
8
|
${o.join(`
|
|
9
9
|
`)}
|
|
10
10
|
|
|
11
|
-
${t}`}function
|
|
11
|
+
${t}`}function oo(){return{name:"fetch",label:"fetch",description:"Fetch a URL via HTTP(S) and return the response body.",parameters:no,execute:async(e,t,n,o,r)=>{if(!Yn(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 s=$t(t.timeoutMs),i=Tt(t.maxBytes),l=new AbortController,a=()=>l.abort();r?.addEventListener("abort",a,{once:!0});let u=setTimeout(()=>l.abort(),s);try{n?.({content:[{type:"text",text:`Fetching ${t.url}...`}],details:{url:t.url,status:0,statusText:"pending",bytes:0,truncated:!1,contentType:null}});let c=await fetch(t.url,{method:t.method?.toUpperCase()??"GET",headers:Qn(t.headers),body:t.body,signal:l.signal}),d=await eo(c,i,r),g=c.headers.get("content-type");return{content:[{type:"text",text:to({url:c.url,status:c.status,statusText:c.statusText,bytes:d.bytes,truncated:d.truncated,contentType:g},d.text)}],details:{url:c.url,status:c.status,statusText:c.statusText,bytes:d.bytes,truncated:d.truncated,contentType:g}}}catch(c){return{content:[{type:"text",text:`Fetch failed: ${c instanceof Error?c.message:String(c)}`}],details:{url:t.url,status:0,statusText:"error",bytes:0,truncated:!1,contentType:null}}}finally{clearTimeout(u),r?.removeEventListener("abort",a)}}}}function so(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}
|
|
12
12
|
${r.join(`
|
|
13
13
|
`)}
|
|
14
14
|
|
|
15
|
-
${n}`}function
|
|
15
|
+
${n}`}function io(e){return{name:"mcp",label:"mcp",description:"Call an MCP endpoint via JSON-RPC.",parameters:ro,execute:async(t,n,o,r,s)=>{let i=await e();if(i.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 l=n.server?.trim()??"";if(!l)if(i.length===1)l=i[0]?.name??"";else return{content:[{type:"text",text:`Multiple MCP servers configured. Provide server name. Available: ${i.map(u=>u.name).join(", ")}`}],details:{server:"",type:"http",target:"",status:0,statusText:"server_required",bytes:0,truncated:!1,contentType:null}};let a=i.find(u=>u.name===l);if(!a)return{content:[{type:"text",text:`MCP server not found: ${l}. Available: ${i.map(u=>u.name).join(", ")}`}],details:{server:l,type:"http",target:"",status:0,statusText:"server_not_found",bytes:0,truncated:!1,contentType:null}};try{o?.({content:[{type:"text",text:`Calling MCP ${a.name} ${n.method}...`}],details:{server:a.name,type:a.type,target:Q(a),status:0,statusText:"pending",bytes:0,truncated:!1,contentType:null}});let u=await we(a,n.method,n.params??{},{timeoutMs:$t(void 0),maxBytes:Tt(void 0),signal:s});return{content:[{type:"text",text:so(a,{server:a.name,type:a.type,target:Q(a),status:u.statusCode??0,statusText:u.statusText??(u.ok?"ok":"error"),bytes:u.bytes,truncated:u.truncated,contentType:u.contentType??null},u.output)}],details:{server:a.name,type:a.type,target:Q(a),status:u.statusCode??0,statusText:u.statusText??(u.ok?"ok":"error"),bytes:u.bytes,truncated:u.truncated,contentType:u.contentType??null}}}catch(u){return{content:[{type:"text",text:`MCP failed: ${u instanceof Error?u.message:String(u)}`}],details:{server:a.name,type:a.type,target:Q(a),status:0,statusText:"error",bytes:0,truncated:!1,contentType:null}}}}}}function lo(e){let t=[m.workspaceDir,J.join(m.agentDir,"uploads")];return{name:"send_photo",label:"send_photo",description:"Send an image file to the current Telegram chat.",parameters:ao,execute:async(n,o)=>{let r=Pt(o.path,t,m.workspaceDir);if(!r)return{content:[{type:"text",text:"Invalid path. Only workspace or uploads are allowed."}],details:{path:o.path,bytes:0}};let s=await Ct(r);return s?(await e.sendPhoto(r,o.caption?.trim()||void 0),{content:[{type:"text",text:`Photo sent: ${J.basename(r)}`}],details:{path:r,bytes:s.bytes}}):{content:[{type:"text",text:`File not found: ${r}`}],details:{path:r,bytes:0}}}}}function uo(e){let t=[m.workspaceDir,J.join(m.agentDir,"uploads")];return{name:"send_file",label:"send_file",description:"Send a file to the current Telegram chat.",parameters:co,execute:async(n,o)=>{let r=Pt(o.path,t,m.workspaceDir);if(!r)return{content:[{type:"text",text:"Invalid path. Only workspace or uploads are allowed."}],details:{path:o.path,bytes:0}};let s=await Ct(r);return s?(await e.sendDocument(r,o.caption?.trim()||void 0),{content:[{type:"text",text:`File sent: ${J.basename(r)}`}],details:{path:r,bytes:s.bytes}}):{content:[{type:"text",text:`File not found: ${r}`}],details:{path:r,bytes:0}}}}}function At(e){let t=[oo()];return e?.telegram&&(t.push(lo(e.telegram)),t.push(uo(e.telegram))),he(m.agentDir).length>0&&t.push(io(()=>ce(m.agentDir))),t}var Vn,Xn,no,ro,ao,co,Rt=H(()=>{"use strict";V();be();Y();Vn=2e5,Xn=6e4;no=x.Object({url:x.String({description:"HTTP or HTTPS URL"}),method:x.Optional(x.String({description:"HTTP method (default: GET)"})),headers:x.Optional(x.Array(x.Object({name:x.String({description:"Header name"}),value:x.String({description:"Header value"})}),{description:"Request headers as name/value pairs"})),body:x.Optional(x.String({description:"Request body (string)"})),timeoutMs:x.Optional(x.Integer({description:"Timeout in milliseconds",minimum:1e3,maximum:12e4})),maxBytes:x.Optional(x.Integer({description:"Max response bytes",minimum:1024,maximum:5e6}))});ro=x.Object({server:x.Optional(x.String({description:"MCP server name"})),method:x.String({description:"MCP method name"}),params:x.Optional(x.Any({description:"MCP params payload"}))});ao=x.Object({path:x.String({description:"Image file path (relative to workspace or uploads)."}),caption:x.Optional(x.String({description:"Caption text (plain text)."}))}),co=x.Object({path:x.String({description:"File path (relative to workspace or uploads)."}),caption:x.Optional(x.String({description:"Caption text (plain text)."}))})});import Ot from"node:fs/promises";import jt from"node:path";function Ft(e){return jt.join(m.sessionDir,`${e}.json`)}function Dt(e){return e.replace(/[^a-zA-Z0-9_-]/g,"_")}function Fe(e,t){let n=Dt(e),o=Dt(t);return jt.join(m.sessionDir,`${n}-${o}.jsonl`)}async function te(e,t){let n=Fe(e,t);try{await Ot.unlink(n)}catch(o){if(o.code==="ENOENT")return;throw o}}function Et(e,t){let n=t?.sessions??{},o=t?.activeSessionId??null,r=t?.workspaceDir,s={chatId:e,workspaceDir:r,activeSessionId:o,sessions:n};return(!o||!n[o])&&(s.activeSessionId=null),s}async function Me(e){await z(m.sessionDir);let t=Se.get(e);if(t)return t;let n=Ft(e);try{let o=await Ot.readFile(n,"utf8"),r=JSON.parse(o),s=Et(e,r);return Se.set(e,s),s}catch(o){if(o.code==="ENOENT"){let r=Et(e,{});return Se.set(e,r),r}throw o}}async function C(e){await z(m.sessionDir);let t=Ft(e.chatId);await Ge(t,e),Se.set(e.chatId,e)}function ze(e){return Object.values(e.sessions).sort((t,n)=>n.updatedAt-t.updatedAt)}function Ne(e){return[]}function ve(e,t){if(Object.keys(e.sessions).length>=m.maxSessions)throw new Error("Max sessions reached");let o=ie(),r=N(),s={id:o,title:t&&t.length>0?t:`session-${o}`,messages:[],createdAt:r,updatedAt:r};return e.sessions[o]=s,e.activeSessionId=o,s}function zt(e,t){return e.sessions[t]?(e.activeSessionId=t,!0):!1}function ne(e){return e.activeSessionId?e.sessions[e.activeSessionId]??null:null}function Ie(e,t){return e.sessions[t]?(delete e.sessions[t],e.activeSessionId===t&&(e.activeSessionId=null),!0):!1}function Nt(e){e.messages=[],e.updatedAt=N()}function Le(e,t,n){e.messages.push(t),e.messages.length>n&&(e.messages=e.messages.slice(-n)),e.updatedAt=N()}function It(e,t){e.workspaceDir=t}var Se,Ue=H(()=>{"use strict";V();Y();Se=new Map});import{createAgentSession as mo,discoverAuthStorage as go,discoverModels as po,SessionManager as fo,SettingsManager as yo}from"@mariozechner/pi-coding-agent";import ke from"node:fs/promises";import Lt from"node:path";function Ut(e){let t=e.trim().toLowerCase();return t==="codex"?"openai-codex":t}function wo(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 bo(e,t){return e!=="openai-codex"?t:ho[t]??t}function xo(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 So(e,t){let n=!!t?.provider?.trim(),o=!!t?.modelId?.trim(),r=Ut(t?.provider||m.modelProvider||"openai-codex"),s=n||o?"":m.modelRef||"",{provider:i,modelId:l}=wo(s,r),a=t?.provider?r:Ut(i),u=o?t?.modelId?.trim()||"":l;if(!u){let g=xo(e,a);return g?{model:g,provider:a,modelId:g.id}:{model:void 0,provider:a,modelId:""}}let c=bo(a,u);return{model:e.find(a,c),provider:a,modelId:c}}function Mo(e){let t=Z();return t?(e.setRuntimeApiKey("openai-codex",t.accessToken),{source:t.source,expiresAt:t.expiresAt}):null}function vo(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(s=>typeof s=="object"&&s&&s.type==="text").map(s=>s.text??"").map(s=>s.trim()).filter(Boolean);if(o.length>0)return o.join(`
|
|
16
16
|
|
|
17
17
|
`);let r=n.filter(s=>typeof s=="object"&&s&&s.type==="thinking").map(s=>s.thinking??"").map(s=>s.trim()).filter(Boolean);return r.length>0?r.join(`
|
|
18
18
|
|
|
19
|
-
`):""}function
|
|
19
|
+
`):""}function ko(e){if(e.length===0)return"messages=0";let t=e.slice(-6).map(n=>{let o=n?.role??"unknown",r=n.content,s=n?.stopReason,i=n?.errorMessage;if(typeof r=="string")return`${o}(text:${r.length}${s?`,stop=${s}`:""})`;if(Array.isArray(r)){let a=[`blocks:${r.map(u=>typeof u=="object"&&u&&"type"in u?String(u.type||"unknown"):typeof u).join(",")||"none"}`,s?`stop=${s}`:null,i?"error=1":null].filter(Boolean).join(",");return`${o}(${a})`}if(r==null){let l=["empty",s?`stop=${s}`:null,i?"error=1":null].filter(Boolean).join(",");return`${o}(${l})`}return`${o}(${typeof r}${s?`,stop=${s}`:""})`});return`messages=${e.length} last=[${t.join(" ")}]`}function _o(e){let t=e.trim();return t.toLowerCase().includes("usage limit")?`${t}
|
|
20
20
|
|
|
21
|
-
Suggestion: wait for the limit to reset or switch to another provider/model.`:t}function
|
|
21
|
+
Suggestion: wait for the limit to reset or switch to another provider/model.`:t}function $o(e,t){let n=t?.getLastAssistantText?.();if(n?.trim())return n.trim();for(let o=e.length-1;o>=0;o-=1){let r=vo(e[o]);if(r)return r}return""}function To(e){for(let t=e.length-1;t>=0;t-=1)if(e[t]?.role==="assistant")return e[t]}async function Bt(e){let t=e.workspaceDir||m.workspaceDir;await z(m.sessionDir),await z(m.agentDir),await z(t);let n=Fe(e.chatId,e.sessionId),o=go(m.agentDir),r=Mo(o);r&&console.log(`[tg-agent] codex oauth source=${r.source} expiresAt=${new Date(r.expiresAt).toISOString()}`);let s=po(o,m.agentDir),{model:i,provider:l,modelId:a}=So(s,{provider:e.modelProvider,modelId:e.modelId});a&&!i&&console.warn(`[tg-agent] model not found: ${l}/${a}`);let u=fo.open(n),c=yo.create(t,m.agentDir);try{let y=Lt.join(m.agentDir,"skills"),w=Lt.join(t,".pi","skills"),A=await ke.access(y).then(()=>!0).catch(()=>!1),R=await ke.access(w).then(()=>!0).catch(()=>!1);if(A){let K=(await ke.readdir(y,{withFileTypes:!0})).filter(U=>U.isDirectory()).map(U=>U.name);console.log(`[tg-agent] skills directory found at ${y} with ${K.length} skill(s): ${K.join(", ")}`)}else console.log(`[tg-agent] skills directory not found at ${y}`);if(R){let K=(await ke.readdir(w,{withFileTypes:!0})).filter(U=>U.isDirectory()).map(U=>U.name);console.log(`[tg-agent] workspace skills directory found at ${w} with ${K.length} skill(s): ${K.join(", ")}`)}let L=c.getSettings?.();if(L){let K=L.skills?.enabled!==!1;console.log(`[tg-agent] skills enabled in settings: ${K}`)}}catch(y){let w=y instanceof Error?y.message:String(y);console.warn(`[tg-agent] skills check failed: ${w}`)}let d="";try{d=await le(m.agentDir,{timeoutMs:4e3,maxBytes:m.fetchMaxBytes,maxChars:3e3})}catch(y){let w=y instanceof Error?y.message:String(y);console.warn(`[tg-agent] mcp catalog error: ${w}`)}let{session:g,modelFallbackMessage:p}=await mo({cwd:t,agentDir:m.agentDir,authStorage:o,modelRegistry:s,model:i??void 0,sessionManager:u,settingsManager:c,customTools:At({telegram:e.telegram}),systemPrompt:y=>{let w=e.systemPrompt?.trim(),A=[y];return w&&A.push(w),d&&A.push(d),A.join(`
|
|
22
22
|
|
|
23
|
-
`)}});try{let y=
|
|
24
|
-
`)}function
|
|
25
|
-
`)}function
|
|
26
|
-
`),p,l)}}function
|
|
23
|
+
`)}});try{let y=g.messages,w=y.some(D=>{let K=D.role,U=D.content;return K==="system"&&typeof U=="string"?U.toLowerCase().includes("compaction")||U.toLowerCase().includes("compact"):D.type==="compaction"||D.compaction!==void 0});console.log(`[tg-agent] session manager type: ${typeof u}`),console.log(`[tg-agent] session messages count: ${y.length}`),console.log(`[tg-agent] compacting support detected: ${w||"unknown (will be detected during runtime)"}`);let R=typeof u.compact=="function",L=typeof u.appendCompaction=="function";console.log(`[tg-agent] SessionManager.compact method: ${R}`),console.log(`[tg-agent] SessionManager.appendCompaction method: ${L}`)}catch(y){let w=y instanceof Error?y.message:String(y);console.warn(`[tg-agent] compacting check failed: ${w}`)}p&&console.warn(`[tg-agent] modelFallback=${p}`);let h=!1,v=()=>{h=!0,g.abort()};e.onAbortReady?.(v);let M=m.logAgentEvents,_=m.logAgentStream,E=new Map,T=g.subscribe(y=>{switch(y.type){case"agent_start":M&&console.log(`[tg-agent] agent start session=${e.sessionId}`),P=Date.now(),e.onStatus?.({type:"agent_start"});break;case"agent_end":M&&console.log(`[tg-agent] agent end session=${e.sessionId}`),e.onStatus?.({type:"agent_end"});break;case"turn_start":M&&console.log(`[tg-agent] turn start session=${e.sessionId}`),P=Date.now(),e.onStatus?.({type:"turn_start"});break;case"turn_end":M&&console.log(`[tg-agent] turn end session=${e.sessionId} toolResults=${y.toolResults.length}`),P=Date.now(),e.onStatus?.({type:"turn_end",toolResults:y.toolResults.length});break;case"message_start":{if(M){let w=y.message.role??"unknown";console.log(`[tg-agent] message start session=${e.sessionId} role=${w}`)}P=Date.now();{let w=y.message.role??"unknown";e.onStatus?.({type:"message_start",role:w})}break}case"message_end":{if(M){let w=y.message.role??"unknown";console.log(`[tg-agent] message end session=${e.sessionId} role=${w}`)}P=Date.now();{let w=y.message.role??"unknown";e.onStatus?.({type:"message_end",role:w})}break}case"message_update":{if(!_)break;if(y.assistantMessageEvent.type==="text_delta"){let A=(y.assistantMessageEvent.delta??"").length;A>0&&console.log(`[tg-agent] stream delta session=${e.sessionId} chars=${A}`),P=Date.now()}y.assistantMessageEvent.type==="thinking_delta"&&(P=Date.now());break}case"tool_execution_start":{E.set(y.toolCallId,Date.now()),console.log(`[tg-agent] tool start name=${y.toolName} id=${y.toolCallId}`),se+=1,P=Date.now(),e.onStatus?.({type:"tool_start",name:y.toolName,id:y.toolCallId,args:y.args});break}case"tool_execution_end":{let w=E.get(y.toolCallId),A=w?Date.now()-w:0;console.log(`[tg-agent] tool end name=${y.toolName} id=${y.toolCallId} ok=${!y.isError} durationMs=${A}`),E.delete(y.toolCallId),se=Math.max(0,se-1),P=Date.now(),e.onStatus?.({type:"tool_end",name:y.toolName,id:y.toolCallId,ok:!y.isError,durationMs:A});break}case"auto_compaction_start":{let w=y.reason??"unknown";console.log(`[tg-agent] auto compaction started session=${e.sessionId} reason=${w}`),P=Date.now();break}case"auto_compaction_end":{let w=y.willRetry??!1;console.log(`[tg-agent] auto compaction ended session=${e.sessionId} willRetry=${w}`),P=Date.now();break}default:break}}),$=null,W=null,b=!1,S=0,k=!1,P=Date.now(),se=0;try{let y=Date.now();$=setInterval(()=>{let R=Date.now()-y;console.log(`[tg-agent] prompt running session=${e.sessionId} elapsedMs=${R} streaming=${g.isStreaming}`),e.onStatus?.({type:"heartbeat",elapsedMs:R,streaming:g.isStreaming})},15e3),W=setInterval(()=>{if(b||se>0)return;let R=Date.now()-P,L=g.isStreaming?m.modelTimeoutStreamingMs:m.modelTimeoutMs,D=Math.max(1e3,L);R>=D&&(b=!0,S=D,k=g.isStreaming,console.warn(`[tg-agent] model timeout session=${e.sessionId} elapsedMs=${R}`),g.abort())},2e3);try{if(await g.prompt(e.prompt,e.images&&e.images.length>0?{images:e.images}:void 0),b)throw new Error(`Model request timed out after ${m.modelTimeoutMs}ms`)}catch(R){if(h)throw new Error("Cancelled by user.");if(b){let L=k?" (streaming)":"",D=S||m.modelTimeoutMs;throw new Error(`Model request timed out after ${D}ms${L}`)}throw R}$&&clearInterval($);let w=To(g.messages);if(w){let R=w?.stopReason,L=w?.errorMessage;if(R==="error"){let D=L?_o(L):"Model error without details.";throw console.warn(`[tg-agent] model error session=${e.sessionId} error=${D}`),new Error(D)}}let A=$o(g.messages,g);if(!A){let R=ko(g.messages);throw console.warn(`[tg-agent] empty response session=${e.sessionId} ${R}`),new Error("No assistant response.")}return{text:A,sessionFile:n,sessionId:g.sessionId,modelProvider:g.model?.provider??l,modelId:g.model?.id??a,modelFallbackMessage:p}}finally{$&&clearInterval($),W&&clearInterval(W),T(),u.flushPendingToolResults?.(),g.dispose()}}var ho,Wt=H(()=>{"use strict";V();ye();Rt();be();Y();Ue();ho={"codex-mini-latest":"gpt-5.1-codex-mini","codex-max-latest":"gpt-5.1-codex-max","codex-latest":"gpt-5.2-codex"}});var Mr={};import $e from"node:path";import Ht from"node:fs/promises";import Po from"node-telegram-bot-api";import{discoverAuthStorage as Co,discoverModels as Ao}from"@mariozechner/pi-coding-agent";import{getOAuthProviders as Ro}from"@mariozechner/pi-ai";function Eo(e,t){de.set(e,t)}function qe(e){de.delete(e)}function Oo(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 Fo(){return $e.join(m.agentDir,"uploads")}function zo(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 No(e){return!!e?.startsWith("image/")}function Io(e){switch($e.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 Lo(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 Uo(e){return e.length===0?"":e.map(t=>{let n=[];t.mimeType&&n.push(t.mimeType),t.bytes>0&&n.push(Lo(t.bytes));let o=n.length>0?` (${n.join(", ")})`:"";return`Attachment saved: ${t.path}${o}`}).join(`
|
|
24
|
+
`)}function Bo(e){let t=[];if(e.photo&&e.photo.length>0){let n=zo(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 Wo(e){if(e.length===0)return{resolved:[],images:[]};let t=Fo();await z(t);let n=[],o=[];for(let r of e)try{let s=await F.downloadFile(r.fileId,t),i=await Ht.stat(s),l=r.fileName??$e.basename(s),a=r.mimeType??Io(s),u=r.kind==="photo"||No(a),c={path:s,name:l,mimeType:a,bytes:i.size,isImage:u};if(n.push(c),u){let d=await Ht.readFile(s);o.push({type:"image",data:d.toString("base64"),mimeType:a??jo})}}catch(s){console.warn("[tg-agent] attachment download failed",s)}return{resolved:n,images:o}}function ue(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 qo(e){if(ue(e,"*")%2!==0||ue(e,"_")%2!==0||ue(e,"`")%2!==0)return!1;let r=ue(e,"["),s=ue(e,"]");return r===s}function Ko(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(n==="\\"){t+=1;continue}if(Ho.has(n))return!1}return!0}function Qt(e){let t=Oo(m.telegramParseMode);return t?[t]:Ko(e)?["MarkdownV2","Markdown"]:qo(e)?["Markdown"]:[]}function re(e){let t=e.trim().toLowerCase();return Go.get(t)??t}function Xo(e,t){return e!=="openai-codex"?t:Vo[t]??t}async function oe(){await z(m.agentDir);let e=Co(m.agentDir),t=Z();t&&e.setRuntimeApiKey("openai-codex",t.accessToken);let n=Ao(e,m.agentDir);return{authStorage:e,modelRegistry:n}}function Yt(e){let t=X.get(e);t&&(clearTimeout(t.timeoutId),X.delete(e))}function Qo(e,t){let n=X.get(e);n&&(clearTimeout(n.timeoutId),X.delete(e),n.reject(new Error(t)))}async function qt(e,t,n,o){if(X.has(e))throw new Error("Login is already awaiting input.");let r=n.placeholder?`${n.message} (${n.placeholder})`:n.message;return await f(t,r,o),await new Promise((s,i)=>{let l=setTimeout(()=>{X.delete(e),i(new Error("Login prompt timed out."))},Jo);X.set(e,{resolve:s,reject:i,timeoutId:l,chatId:t})})}async function Zt(e,t,n){let o=de.get(t);if(!o){await f(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 f(e,"Stopping current request...",n)}async function en(e,t,n,o){let r=await Me(t),s=n||r.activeSessionId;if(!s){await f(e,"No active session to close.",o);return}let i=de.get(t);if(i){if(i.cancelRequested=!0,i.abortRequested=!0,i.status&&i.status.update("Cancelled by user.",!0),i.abort)try{i.abort()}catch(u){console.warn("[tg-agent] abort callback failed during force close",u)}qe(t)}if(!Ie(r,s)){await f(e,`Session not found: ${s}`,o);return}await C(r),await te(t,s).catch(u=>{console.warn(`[tg-agent] delete session file failed id=${s}`,u)});let a=i?`Force-closed session ${s} (interrupted running task).`:`Closed session ${s}.`;await f(e,a,o)}function Yo(){console.log(`[tg-agent] modelProvider=${m.modelProvider} modelRef=${m.modelRef} sessionDir=${m.sessionDir} maxConcurrent=${m.maxConcurrent}`),console.log(`[tg-agent] agentDir=${m.agentDir} workspaceDir=${m.workspaceDir}`);let e=he(m.agentDir),t=e.length>0?`on (${e.length})`:"off";console.log(`[tg-agent] tools fetchMaxBytes=${m.fetchMaxBytes} fetchTimeoutMs=${m.fetchTimeoutMs} mcp=${t}`),console.log(`[tg-agent] proxy url=${m.proxyUrl||"(none)"} fetchProxy=${m.fetchProxyUrl||"(none)"}`),console.log(`[tg-agent] tls extra_ca=${m.tlsExtraCaCerts||"(empty)"} reject_unauthorized=${m.tlsRejectUnauthorized===null?"(unset)":String(m.tlsRejectUnauthorized)}`);try{let{source:o}=ut(m.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=mt();console.log(n?`[tg-agent] proxyUrl=${n.url} kind=${n.kind} source=${n.source}`:"[tg-agent] proxyUrl=(none)")}function Ke(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 Kt(e,t,n){let o=ne(e);return o||(o=ve(e,""),await C(e),await f(t,`Created session ${o.id}.`,n)),o}function Zo(e,t){let n=e.getAll(),o=new Map;for(let r of n){let s=o.get(r.provider)??{count:0,auth:t.hasAuth(r.provider)};s.count+=1,o.set(r.provider,s)}return Array.from(o.entries()).sort((r,s)=>r[0].localeCompare(s[0])).map(([r,s])=>({label:`${r} (${s.count}, ${s.auth?"ok":"no auth"})`,command:`/provider ${r}`}))}function er(e,t,n=[]){let o=e.getAll().filter(l=>l.provider===t).sort((l,a)=>l.id.localeCompare(a.id));if(n.length===0)return o.map(l=>({label:l.id,command:`/model ${t}/${l.id}`}));let r=new Map(o.map(l=>[l.id,l])),s=new Set,i=[];for(let l of n){let a=r.get(l);!a||s.has(a.id)||(s.add(a.id),i.push(a))}for(let l of o)s.has(l.id)||i.push(l);return i.map(l=>({label:l.id,command:`/model ${t}/${l.id}`}))}function tr(e,t,n=3){let o=new Set,r=[],s=ze(e);for(let i of s){if(i.modelProvider!==t)continue;let l=i.modelId;if(!(!l||o.has(l))&&(o.add(l),r.push(l),r.length>=n))break}return r}function nr(e){let t=e.trim();if(!t)return null;if(t.includes("/")){let[n,o]=t.split("/",2);return!n||!o?null:{provider:re(n),modelId:o.trim()}}return{modelId:t}}function tn(e,t){let n=Date.now(),o=Jt.get(e)??0;n-o<or||(Jt.set(e,n),console.warn(`[tg-agent] unauthorized user=${e} chat=${t}`))}function nn(e){let t=m.telegramAllowedUsers;return!t||t.size===0?!0:t.has(e)}function rr(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(`
|
|
25
|
+
`)}function Te(e,t,n){let o=String(e);return t!==void 0&&!n?null:t!==void 0&&n?`${o}_${t}`:o}function He(e,t){if(t.workspaceDir)return t.workspaceDir;let n=m.workspaceMappings.get(e);return n||m.workspaceDir}async function on(e,t,n,o){let r={};return n&&(r.parse_mode=n),o!==void 0&&(r.message_thread_id=o),await F.sendMessage(e,t,r)}async function rn(e,t,n,o,r){let s={chat_id:e,message_id:t};o&&(s.parse_mode=o),r!==void 0&&(s.message_thread_id=r),await F.editMessageText(n,s)}async function sn(e,t){let n;for(let o of t)try{return await e(o)}catch(r){n=r;let s=r instanceof Error?r.message:String(r);console.warn(`[tg-agent] parse_mode ${o} failed, trying fallback: ${s}`)}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 sr(e,t,n){return await sn(o=>on(e,t,o,n),Qt(t))}async function ir(e,t,n,o){await sn(r=>rn(e,t,n,r,o),Qt(n))}async function f(e,t,n){let o=Ve(t,3900);for(let r of o)await sr(e,r,n)}function cr(){let e=N()-an;for(let[o,r]of q)r.createdAt<e&&q.delete(o);if(q.size<=Gt)return;let t=Array.from(q.entries()).sort((o,r)=>o[1].createdAt-r[1].createdAt),n=q.size-Gt;for(let o=0;o<n;o+=1)q.delete(t[o][0])}function lr(e){cr();let t=ie();for(;q.has(t);)t=ie();return q.set(t,{command:e,createdAt:N()}),t}function ur(e){if(!e.startsWith("cmd:"))return null;let t=e.slice(4),n=q.get(t);return n?N()-n.createdAt>an?(q.delete(t),null):n.command:null}function dr(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 mr(e,t){let n=[],o=[];for(let r of e){let s=lr(r.command);o.push({text:r.label,callback_data:`cmd:${s}`}),o.length>=t&&(n.push(o),o=[])}return o.length>0&&n.push(o),n}async function gr(e,t,n,o){let r={reply_markup:{inline_keyboard:n}};return o!==void 0&&(r.message_thread_id=o),await F.sendMessage(e,t,r)}async function Vt(e,t,n,o){let r=o?.perRow??1,s=o?.pageSize??ar,i=o?.footer,l=o?.messageThreadId,a=dr(n,s);for(let u=0;u<a.length;u+=1){let c=a[u],d=a.length>1?` (page ${u+1}/${a.length})`:"",g=[`${t}${d}`];i&&g.push(i);let p=mr(c,r);await gr(e,g.join(`
|
|
26
|
+
`),p,l)}}function We(e,t=pr){return e.length<=t?{text:e,truncated:!1}:{text:`${e.slice(0,Math.max(0,t-15))}...
|
|
27
27
|
|
|
28
|
-
[truncated]`,truncated:!0}}async function
|
|
29
|
-
args: ${
|
|
30
|
-
`)}async function
|
|
31
|
-
`);await f(e,c,r);return}case"new":{try{let
|
|
28
|
+
[truncated]`,truncated:!0}}async function yr(e,t){let n="Working...",r=(await on(e,n,void 0,t)).message_id,s=n,i=0,l=Promise.resolve(),a=(c,d=!1)=>{let g=Date.now();!d&&g-i<fr||c!==s&&(s=c,i=g,l=l.then(async()=>{await rn(e,r,c,void 0,t)}).catch(p=>{console.warn("[tg-agent] status edit failed",p)}))},u=c=>{s=c,i=Date.now(),l=l.then(async()=>{await ir(e,r,c,t)}).catch(d=>{console.warn("[tg-agent] status edit failed",d)})};return{update:(c,d=!1)=>{let g=We(c).text;a(g,d)},finalize:async c=>{let d=We(c).text;u(d),await l},fail:async c=>{let d=We(c).text;u(d),await l}}}function hr(e){switch(e.type){case"agent_start":return"Working...";case"tool_start":return`Running tool: ${e.name}
|
|
29
|
+
args: ${wr(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 wr(e){try{let t=new WeakSet,n=200,o=12,r=12,s=3,i=(u,c)=>{if(u==null)return u;if(typeof u=="string")return u.length>n?`${u.slice(0,n)}...`:u;if(typeof u=="number"||typeof u=="boolean")return u;if(typeof u=="bigint")return u.toString();if(typeof u=="function")return"[function]";if(typeof u!="object")return String(u);if(t.has(u))return"[circular]";if(c>=s)return"[truncated]";if(t.add(u),Array.isArray(u)){let p=u.slice(0,r).map(h=>i(h,c+1));return u.length>r&&p.push("[truncated]"),p}let d=Object.entries(u),g={};for(let[p,h]of d.slice(0,o))g[p]=i(h,c+1);return d.length>o&&(g._truncated=!0),g},l=i(e,0),a=JSON.stringify(l);return a?a.length>700?`${a.slice(0,700)}...`:a:"null"}catch{return"[unavailable]"}}function Pe(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 br(e,t=140){return e.length<=t?e:`${e.slice(0,t-3)}...`}async function xr(){let e=await ce(m.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=>vt(o))),n=["MCP servers:"];for(let o=0;o<e.length;o+=1){let r=e[o],s=t[o],i=s.ok?"ok":`error: ${br(s.error??"unknown")}`;n.push(`- ${r.name} (${r.type}) ${Q(r)} status=${i} (${s.durationMs}ms)`)}return n.join(`
|
|
30
|
+
`)}async function cn(e,t,n,o,r){let s=r,l=Te(e,s,s!==void 0);if(!l)return;let a=await Me(l),u=Ne(a);switch(u.length>0&&(await C(a),await Promise.all(u.map(c=>te(l,c).catch(d=>{console.warn(`[tg-agent] cleanup session file failed id=${c}`,d)})))),n){case"start":case"help":{let c=["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","/mcp - list configured MCP servers","/mcp refresh - reload MCP catalog","/status - show session and workspace settings","/login <provider> - login to OAuth provider","/logout <provider> - logout from provider","/stop - stop the current running request","","Tips:","Send images or files to attach them to the prompt."].join(`
|
|
31
|
+
`);await f(e,c,r);return}case"new":{try{let d=ve(a,o||"");await C(a),await f(e,`Created session ${d.id} (${d.title}).`,r)}catch(c){await f(e,c.message,r)}return}case"list":{await C(a),await f(e,rr(ze(a)),r);return}case"use":{if(!o){await f(e,"Usage: /use <id>",r);return}if(!zt(a,o)){await f(e,`Session not found: ${o}`,r);return}await C(a),await f(e,`Active session set to ${o}.`,r);return}case"close":{let c=o||a.activeSessionId;if(!c){await f(e,"No active session to close.",r);return}let d=de.get(l);if(d){if(d.cancelRequested=!0,d.abortRequested=!0,d.status&&d.status.update("Cancelled by user.",!0),d.abort)try{d.abort()}catch(h){console.warn("[tg-agent] abort callback failed during force close",h)}qe(l)}if(!Ie(a,c)){await f(e,`Session not found: ${c}`,r);return}await C(a),await te(l,c).catch(h=>{console.warn(`[tg-agent] delete session file failed id=${c}`,h)});let p=d?`Force-closed session ${c} (interrupted running task).`:`Closed session ${c}.`;await f(e,p,r);return}case"reset":{let c=ne(a);if(!c){await f(e,"No active session.",r);return}Nt(c),await C(a),await te(l,c.id).catch(d=>{console.warn(`[tg-agent] reset session file failed id=${c.id}`,d)}),await f(e,`Reset session ${c.id}.`,r);return}case"workspace":{if(!o){let d=He(l,a),g=a.workspaceDir?"chat":m.workspaceMappings.has(l)?"config":"default";await f(e,`Workspace: ${d} (source: ${g})`,r);return}let c=$e.resolve(B(o.trim()));It(a,c),await C(a),await f(e,`Workspace set to: ${c}`,r);return}case"providers":{let{authStorage:c,modelRegistry:d}=await oe(),g=d.getError(),p=Zo(d,c);if(p.length===0){let v=g?`Warning: ${g}
|
|
32
32
|
|
|
33
|
-
No providers found.`:"No providers found.";await f(e,v,r);return}let h=[];
|
|
34
|
-
`),p,{perRow:1,footer:"Tap a provider to set it. Use /models <provider> to list models.",messageThreadId:r});return}case"models":{let{authStorage:c,modelRegistry:
|
|
35
|
-
`);await f(e,v,r);return}case"mcp":{if(o.trim().toLowerCase()==="refresh"){
|
|
36
|
-
`),r);return}let
|
|
37
|
-
`),r)},onPrompt:h=>
|
|
33
|
+
No providers found.`:"No providers found.";await f(e,v,r);return}let h=[];g&&h.push(`Warning: ${g}`),h.push("Providers:"),await Vt(e,h.join(`
|
|
34
|
+
`),p,{perRow:1,footer:"Tap a provider to set it. Use /models <provider> to list models.",messageThreadId:r});return}case"models":{let{authStorage:c,modelRegistry:d}=await oe(),g=o?re(o):"";if(!g){let M=ne(a);if(!M?.modelProvider){await f(e,"Usage: /models <provider>",r);return}g=M.modelProvider}let p=c.hasAuth(g),h=tr(a,g),v=er(d,g,h);if(v.length===0){await f(e,`No models found for provider ${g}.`,r);return}await Vt(e,`Models for ${g} (auth: ${p?"ok":"missing"}):`,v,{perRow:1,footer:"Tap a model to set it.",messageThreadId:r});return}case"provider":{if(!o){await f(e,"Usage: /provider <name>",r);return}let c=re(o),{modelRegistry:d}=await oe();if(!d.getAll().some(h=>h.provider===c)){await f(e,`Unknown provider: ${c}`,r);return}let p=await Kt(a,e,r);p.modelProvider=c,p.modelId=void 0,p.updatedAt=N(),await C(a),await f(e,`Session ${p.id} provider set to ${c}.`,r);return}case"model":{let c=nr(o);if(!c){await f(e,"Usage: /model <provider>/<model>",r);return}let d=await Kt(a,e,r),g=re(c.provider??d.modelProvider??"");if(!g){await f(e,"Usage: /model <provider>/<model>",r);return}let{modelRegistry:p}=await oe(),h=Xo(g,c.modelId);if(!p.find(g,h)){await f(e,`Model not found: ${g}/${h}`,r);return}d.modelProvider=g,d.modelId=h,d.updatedAt=N(),await C(a),await f(e,`Session ${d.id} model set to ${g}/${h}.`,r);return}case"status":{let c=ne(a);if(!c){await f(e,"No active session.",r);return}let d=m.modelRef.includes("/")?m.modelRef:`${m.modelProvider}/${m.modelRef}`,g=c.modelProvider||c.modelId?`Model: ${c.modelProvider??"?"}/${c.modelId??"?"}`:`Model: ${d} (default)`,p=He(l,a),h=a.workspaceDir?"chat":m.workspaceMappings.has(l)?"config":"default",v=[`Session: ${c.id} (${c.title})`,g,`Workspace: ${p} (${h})`].join(`
|
|
35
|
+
`);await f(e,v,r);return}case"mcp":{if(o.trim().toLowerCase()==="refresh"){Mt(),await le(m.agentDir,{timeoutMs:5e3,maxBytes:m.fetchMaxBytes,maxChars:3e3}),je(),await f(e,"MCP catalog refreshed.",r);return}let c=await xr();await f(e,c,r);return}case"login":{let c=Ro();if(!o){let p=c.map(h=>`- ${h.id} (${h.name})`);await f(e,["OAuth providers:",...p].join(`
|
|
36
|
+
`),r);return}let d=re(o);if(Be.has(t)){await f(e,"Login already in progress.",r);return}let g=c.find(p=>p.id===d);if(!g){await f(e,`Unknown OAuth provider: ${d}`,r);return}Be.add(t);try{let{authStorage:p}=await oe();await f(e,`Starting login for ${g.id}...`,r),await p.login(g.id,{onAuth:({url:h,instructions:v})=>{let M=["Open this URL in your browser:",h];v&&M.push("",v),f(e,M.join(`
|
|
37
|
+
`),r)},onPrompt:h=>qt(t,e,h,r),onProgress:h=>{f(e,h,r)},onManualCodeInput:()=>qt(t,e,{message:"Paste the authorization code:"},r)}),await f(e,`Login completed for ${g.id}.`,r)}catch(p){let h=Pe(p);await f(e,`Login failed: ${h}`,r)}finally{Be.delete(t),Yt(t)}return}case"logout":{if(!o){await f(e,"Usage: /logout <provider>",r);return}let c=re(o),{authStorage:d}=await oe();d.logout(c),await f(e,`Logged out from ${c}.`,r);return}default:await f(e,`Unknown command: ${n}`,r)}}async function Sr(e,t,n,o=[],r){let s=Ke(n);if(s){await cn(e,t,s.command,s.args,r);return}let l=Te(e,r,r!==void 0);if(!l)return;let a=await Me(l),u=Ne(a);u.length>0&&(await C(a),await Promise.all(u.map(T=>te(l,T).catch($=>{console.warn(`[tg-agent] cleanup session file failed id=${T}`,$)}))));let c=ne(a);if(!c)try{c=ve(a,""),await C(a),await f(e,`Created session ${c.id}.`,r)}catch(T){await f(e,T.message,r);return}let{resolved:d,images:g}=await Wo(o);if(o.length>0&&d.length===0&&!n.trim()){await f(e,"Failed to download attachments.",r);return}let p=Uo(d),h=[];n.trim()&&h.push(n.trim()),p&&h.push(p);let v=h.join(`
|
|
38
38
|
|
|
39
|
-
`)||"Attachment received.",M={role:"user",content:v,ts:N()};
|
|
40
|
-
`),
|
|
39
|
+
`)||"Attachment received.",M={role:"user",content:v,ts:N()};Le(c,M,m.maxHistoryMessages),await C(a),console.log(`[tg-agent] request user=${t} chat=${l} session=${c.id} messages=${c.messages.length} textLen=${v.length} attachments=${d.length} provider=${c.modelProvider??"-"} model=${c.modelId??"-"}`);let _=null;try{_=await yr(e,r)}catch(T){console.warn("[tg-agent] status message failed",T)}let E={sessionId:c.id,chatId:e,messageThreadId:r,status:_,abortRequested:!1,cancelRequested:!1};Eo(l,E);try{let T=await Do(async()=>{let W=await Bt({chatId:l,sessionId:c.id,prompt:v,images:g,systemPrompt:m.systemPrompt,modelProvider:c.modelProvider,modelId:c.modelId,workspaceDir:He(l,a),telegram:{chatId:e,sendPhoto:async(b,S)=>{let k={};S&&(k.caption=S),r!==void 0&&(k.message_thread_id=r),await F.sendPhoto(e,b,k)},sendDocument:async(b,S)=>{let k={};S&&(k.caption=S),r!==void 0&&(k.message_thread_id=r),await F.sendDocument(e,b,k)}},onAbortReady:b=>{E.abort=b,E.abortRequested&&b()},onStatus:_?b=>{let S=hr(b);S&&_?.update(S)}:void 0});return console.log(`[tg-agent] response session=${c.id} model=${W.modelProvider}/${W.modelId} file=${W.sessionFile}`),W.text});if(E.cancelRequested){_?await _.finalize("Cancelled by user."):await f(e,"Cancelled by user.",r);return}let $={role:"assistant",content:T,ts:N()};Le(c,$,m.maxHistoryMessages),await C(a),_?await _.finalize(T):await f(e,T,r)}catch(T){if(console.error("[tg-agent] runModel error",T),E.cancelRequested){_?await _.fail("Cancelled by user."):await f(e,"Cancelled by user.",r);return}let $=Pe(T);_?await _.fail(`Error: ${$}`):await f(e,`Error: ${$}`,r)}finally{qe(l)}}var F,Xt,Do,de,jo,Ho,Jo,X,Be,Go,Vo,_e,or,Jt,an,Gt,ar,q,pr,fr,ln=H(()=>{"use strict";V();De();yt();Wt();ye();be();Ue();Y();ct();F=new Po(m.telegramToken,{polling:!0}),Xt=Xe(),Do=Qe(m.maxConcurrent),de=new Map;jo="image/jpeg";Ho=new Set(["_","*","[","]","(",")","~","`",">","#","+","-","=","|","{","}",".","!"]);Jo=600*1e3,X=new Map,Be=new Set,Go=new Map([["codex","openai-codex"],["antigravity","google-antigravity"],["gemini","google-gemini-cli"],["gemini-cli","google-gemini-cli"]]),Vo={"codex-mini-latest":"gpt-5.1-codex-mini","codex-max-latest":"gpt-5.1-codex-max","codex-latest":"gpt-5.2-codex"};Yo();z(m.agentDir).catch(e=>{console.warn(`[tg-agent] ensure agentDir failed: ${e instanceof Error?e.message:String(e)}`)});(async()=>{try{await le(m.agentDir,{timeoutMs:3e3,maxBytes:m.fetchMaxBytes,maxChars:2e3}),je()}catch(e){let t=e instanceof Error?e.message:String(e);console.warn(`[tg-agent] mcp catalog warmup failed: ${t}`)}})();_e=ft();console.log(_e?`[tg-agent] fetchProxy=${_e.url} kind=${_e.kind} source=${_e.source}`:"[tg-agent] fetchProxy=(none)");or=6e4,Jt=new Map;an=1800*1e3,Gt=2e3,ar=60,q=new Map;pr=3900,fr=1200;F.on("callback_query",e=>{let t=e.data??"",n=e.message?.chat.id;if(!e.from?.id||!n){F.answerCallbackQuery(e.id);return}let o=String(e.from.id);if(!nn(o)){tn(o,n),F.answerCallbackQuery(e.id);return}if(!t.startsWith("cmd:")){F.answerCallbackQuery(e.id);return}let r=ur(t);if(!r){F.answerCallbackQuery(e.id,{text:"Command expired."});return}F.answerCallbackQuery(e.id);let s=e.message?.message_thread_id,i=e.message?.is_topic_message??!1,l=Te(n,s,i);if(!l)return;let a=Ke(r);if(a?.command==="stop"){Zt(n,l,s);return}if(a?.command==="close"){en(n,l,a.args,s);return}Xt(l,async()=>{if(!a){await f(n,"Invalid command.",s);return}await cn(n,o,a.command,a.args,s)}).catch(async u=>{console.error("[tg-agent] runModel error",u);let c=Pe(u);await f(n,`Error: ${c}`,s)})});F.on("message",e=>{if(!e.from?.id)return;let t=String(e.from.id),n=e.chat.id;if(!nn(t)){tn(t,n);return}let o=e.message_thread_id,r=e.is_topic_message??!1,s=Te(n,o,r);if(!s)return;let i=(e.text??e.caption??"").trim(),l=Bo(e);if(!i&&l.length===0)return;let a=X.get(t);if(a){if(i==="/stop"||i==="/cancel"){Qo(t,"Login cancelled by user."),f(n,"Login cancelled.",o);return}if(!i){f(n,"Login expects a text response.",o);return}Yt(t),a.resolve(i);return}let u=Ke(i);if(u?.command==="stop"){Zt(n,s,o);return}if(u?.command==="close"){en(n,s,u.args,o);return}Xt(s,()=>Sr(n,t,i,l,o)).catch(async c=>{console.error("[tg-agent] runModel error",c);let d=Pe(c);await f(n,`Error: ${d}`,o)})});F.on("polling_error",e=>{console.error("Polling error",e)});console.log("tg-agent started")});V();import vr from"node:fs";import un from"node:path";import kr from"node:readline/promises";import{fileURLToPath as _r}from"node:url";var dn=process.argv.slice(2),mn=(e,t)=>dn.includes(e)||(t?dn.includes(t):!1),$r=mn("--help","-h"),Tr=mn("--version","-v"),Pr=["Usage: tg-agent [options]","","Options:"," -h, --help Show help"," -v, --version Show version"].join(`
|
|
40
|
+
`),Cr=()=>{if(process.env.npm_package_version)return process.env.npm_package_version;try{let e=_r(import.meta.url),t=un.dirname(e),n=un.join(t,"..","package.json"),o=vr.readFileSync(n,"utf8"),r=JSON.parse(o);if(r.version)return r.version}catch{}return"dev"};$r&&(console.log(Pr),process.exit(0));Tr&&(console.log(Cr()),process.exit(0));async function Ar(){let e=kr.createInterface({input:process.stdin,output:process.stdout});try{return(await e.question("Enter TELEGRAM_BOT_TOKEN: ")).trim()}finally{e.close()}}async function Rr(){let{configPath:e,data:t,exists:n}=ae(),o=nt(),r=n?t:o,s=ot(r,o);if(rt(r)){s&&await Re(e,r);return}process.stdin.isTTY||(console.error(`Missing telegram.bot_token in ${e}.`),process.exit(1));let l=await Ar();l||(console.error("Empty TELEGRAM_BOT_TOKEN."),process.exit(1)),st(r,l),await Re(e,r),console.log(`Saved config to ${e}.`)}async function Dr(){let{data:e}=ae(),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)}await Rr();await Dr();at();Promise.resolve().then(()=>ln());
|