@openeryc/pi-coding-agent 0.75.11 → 0.75.12
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/CHANGELOG.md +2 -0
- package/dist/modes/web/web-mode.d.ts.map +1 -1
- package/dist/modes/web/web-mode.js +4 -3
- package/dist/modes/web/web-mode.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-mode.d.ts","sourceRoot":"","sources":["../../../src/modes/web/web-mode.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAsG/E,wBAAsB,UAAU,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2E5E","sourcesContent":["import { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { networkInterfaces } from \"node:os\";\nimport type { AgentSessionEvent } from \"../../core/agent-session.ts\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.ts\";\n\nfunction getLocalIP(): string {\n\tconst interfaces = networkInterfaces();\n\tfor (const iface of Object.values(interfaces)) {\n\t\tif (!iface) continue;\n\t\tfor (const addr of iface) {\n\t\t\tif (addr.family === \"IPv4\" && !addr.internal) {\n\t\t\t\treturn addr.address;\n\t\t\t}\n\t\t}\n\t}\n\treturn \"127.0.0.1\";\n}\n\nfunction getPort(): number {\n\tconst env = process.env.PORT;\n\tif (env) {\n\t\tconst p = parseInt(env, 10);\n\t\tif (!Number.isNaN(p) && p > 0 && p < 65536) return p;\n\t}\n\treturn 0;\n}\n\nconst HTML = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>pi</title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font:13px/1.5 system-ui,monospace;background:#0d1117;color:#c9d1d9;height:100vh;display:flex;flex-direction:column}\n#header{background:#161b22;border-bottom:1px solid #30363d;padding:8px 16px;display:flex;justify-content:space-between;align-items:center;flex-shrink:0}\n#header span{color:#8b949e;font-size:12px}\n#msgs{flex:1;overflow-y:auto;padding:16px}\n.msg{margin-bottom:12px;max-width:85%}\n.msg.user{background:#1f6feb22;border:1px solid #1f6feb44;border-radius:8px 8px 0 8px;padding:8px 12px;margin-left:auto}\n.msg.assistant{margin-right:auto}\n.msg.system{color:#8b949e;font-size:11px;margin:4px auto;text-align:center;max-width:100%}\n.tool{border:1px solid #30363d;border-radius:6px;margin:6px 0;overflow:hidden}\n.tool-header{padding:6px 10px;background:#161b22;cursor:pointer;font-size:12px;display:flex;justify-content:space-between}\n.tool-header:hover{background:#21262d}\n.tool-body{padding:6px 10px;background:#0d1117;font-size:12px;white-space:pre-wrap;word-break:break-all;max-height:200px;overflow-y:auto;display:none}\n.tool.expanded .tool-body{display:block}\n.tool-arrow{color:#8b949e;transition:.2s}\n.tool.expanded .tool-arrow{transform:rotate(90deg)}\n.tool-pending{border-color:#d2992266}\n.tool-error .tool-header{color:#f85149}\n.thinking{color:#8b949e;font-size:12px;border-left:2px solid #30363d;padding:4px 8px;margin:4px 0;font-style:italic}\n#input-area{border-top:1px solid #30363d;padding:12px 16px;background:#161b22;flex-shrink:0}\n#input-area form{display:flex;gap:8px}\n#prompt{flex:1;background:#0d1117;border:1px solid #30363d;border-radius:6px;padding:8px 12px;color:#c9d1d9;font:13px system-ui,monospace;outline:none}\n#prompt:focus{border-color:#1f6feb}\nbutton{background:#238636;color:#fff;border:none;border-radius:6px;padding:8px 16px;cursor:pointer;font:13px system-ui;font-weight:500}\nbutton:hover{background:#2ea043}\nbutton:disabled{opacity:.5;cursor:default}\n</style>\n</head>\n<body>\n<div id=\"header\"><b>pi</b><span id=\"stats\"></span></div>\n<div id=\"msgs\"></div>\n<div id=\"input-area\">\n<form id=\"f\" autocomplete=\"off\"><input id=\"prompt\" type=\"text\" placeholder=\"Type a message...\" autofocus><button id=\"send\">Send</button></form>\n</div>\n<script>\nconst msgs=document.getElementById(\"msgs\"),f=document.getElementById(\"f\"),prompt=document.getElementById(\"prompt\"),send=document.getElementById(\"send\"),stats=document.getElementById(\"stats\");\nlet busy=false,toolEls={},curAssistant=null,curTextIdx=null,curThinkIdx=null;\nfunction addMsg(cls,html){const d=document.createElement(\"div\");d.className=\"msg \"+cls;d.innerHTML=html;msgs.appendChild(d);msgs.scrollTop=msgs.scrollHeight;return d}\nfunction addSystem(text){addMsg(\"system\",text)}\nfunction fmtTokens(n){if(n<1e3)return n;if(n<1e4)return(n/1e3).toFixed(1)+\"k\";return Math.round(n/1e3)+\"k\"}\nfunction esc(s){if(!s)return\"\";return s.replace(/&/g,\"&\").replace(/</g,\"<\").replace(/>/g,\">\")}\nfunction handleData(e){\nswitch(e.type){\ncase\"agent_start\":curAssistant=null;curTextIdx=null;curThinkIdx=null;break;\ncase\"text_start\":curTextIdx=e.contentIndex;if(!curAssistant){curAssistant=addMsg(\"assistant\",\"\");curTextIdx=null}break;\ncase\"text_delta\":if(!curAssistant)curAssistant=addMsg(\"assistant\",\"\");curAssistant.innerHTML+=esc(e.delta).replace(/\\\\n/g,\"<br>\");msgs.scrollTop=msgs.scrollHeight;break;\ncase\"thinking_start\":{const d=document.createElement(\"div\");d.className=\"thinking\";d.id=\"think\"+e.contentIndex;msgs.appendChild(d);break}\ncase\"thinking_delta\":{const d=document.getElementById(\"think\"+e.contentIndex);if(d)d.textContent+=e.delta;msgs.scrollTop=msgs.scrollHeight;break}\ncase\"toolcall_start\":break;\ncase\"toolcall_end\":break;\ncase\"tool_execution_start\":{const el=document.createElement(\"div\");el.className=\"tool tool-collapsed tool-pending\";el.id=\"t\"+e.toolCallId;const h=document.createElement(\"div\");h.className=\"tool-header\";h.innerHTML='<span>'+esc(e.toolName)+(e.args?' '+esc(String(e.args.command||e.args.path||e.args.file_path||JSON.stringify(e.args).slice(0,60))):'')+'</span><span class=\"tool-arrow\">▶</span>';h.onclick=()=>el.classList.toggle(\"expanded\");el.appendChild(h);const b=document.createElement(\"div\");b.className=\"tool-body\";el.appendChild(b);msgs.appendChild(el);toolEls[e.toolCallId]=el;msgs.scrollTop=msgs.scrollHeight;break}\ncase\"tool_execution_update\":{const el=toolEls[e.toolCallId];if(el){const b=el.querySelector(\".tool-body\");if(b&&e.result){const texts=Array.isArray(e.result)?e.result:e.result.content||[];b.innerText=texts.filter(c=>c&&c.type===\"text\").map(c=>c.text).join(\"\");el.classList.add(\"expanded\")}}break}\ncase\"tool_execution_end\":{const el=toolEls[e.toolCallId];if(el){el.classList.remove(\"tool-pending\");if(e.isError)el.classList.add(\"tool-error\");const b=el.querySelector(\".tool-body\");if(b&&e.result){const texts=e.result.content||[];b.innerText=texts.filter(c=>c&&c.type===\"text\").map(c=>c.text).join(\"\")}el.classList.add(\"expanded\")}break}\ncase\"agent_end\":{let usage=\"\";if(e.usage){usage=\" — ↑\"+fmtTokens(e.usage.input)+\" ↓\"+fmtTokens(e.usage.output);if(e.usage.cost)usage+=\" $\"+e.usage.cost.total.toFixed(4)}addSystem(\"Done\"+usage);break}\ncase\"compaction\":addSystem(\"Compacting...\");break;\ncase\"error\":addSystem(\"Error: \"+esc(e.message));break;}};\nf.onsubmit=async e=>{e.preventDefault();if(busy)return;const text=prompt.value.trim();if(!text)return;prompt.value=\"\";addMsg(\"user\",esc(text));busy=true;send.disabled=true;\ntry{const r=await fetch(\"/api/prompt\",{method:\"POST\",headers:{\"content-type\":\"application/json\"},body:JSON.stringify({text})});\nconst reader=r.body.getReader(),decoder=new TextDecoder();let buf=\"\";\nwhile(true){const{done,value}=await reader.read();if(done)break;buf+=decoder.decode(value,{stream:true});const lines=buf.split(\"\\\\n\");buf=lines.pop()||\"\";\nfor(const line of lines){if(!line.trim())continue;try{handleData(JSON.parse(line))}catch{}}}}\ncatch(err){addSystem(\"Error: \"+err.message)}finally{busy=false;send.disabled=false}};\nfetch(\"/api/stats\").then(r=>r.json()).then(s=>{stats.textContent=\"sessions: \"+s.sessions+\" | $\"+s.cost.toFixed(2)}).catch(()=>{});\n</script>\n</body>\n</html>`;\n\nfunction sendEvent(res: ServerResponse, data: Record<string, unknown>): void {\n\tres.write(`${JSON.stringify(data)}\\n`);\n}\n\nexport async function runWebMode(runtime: AgentSessionRuntime): Promise<void> {\n\tconst session = runtime.session;\n\tconst port = getPort();\n\n\tconst server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n\t\tconst url = req.url ?? \"/\";\n\n\t\tif (req.method === \"POST\" && url === \"/api/prompt\") {\n\t\t\tconst chunks: Buffer[] = [];\n\t\t\treq.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n\t\t\tawait new Promise<void>((resolve) => req.on(\"end\", resolve));\n\t\t\tconst body = JSON.parse(Buffer.concat(chunks).toString());\n\t\t\tconst text = String(body.text ?? \"\").trim();\n\t\t\tif (!text) {\n\t\t\t\tres.writeHead(400);\n\t\t\t\tres.end(JSON.stringify({ error: \"missing text\" }));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tres.writeHead(200, { \"content-type\": \"text/plain; charset=utf-8\", \"cache-control\": \"no-cache\" });\n\n\t\t\tconst unsubscribe = session.subscribe((event: AgentSessionEvent) => {\n\t\t\t\tconst events = toSerializableEvents(event);\n\t\t\t\tfor (const evt of events) {\n\t\t\t\t\tsendEvent(res, evt);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\tawait session.prompt(text);\n\t\t\t} catch (err) {\n\t\t\t\tsendEvent(res, { type: \"error\", message: String(err) });\n\t\t\t} finally {\n\t\t\t\tunsubscribe();\n\t\t\t\tres.end();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (req.method === \"GET\" && url === \"/api/stats\") {\n\t\t\tconst stats = await session.getUsageStats();\n\t\t\tres.writeHead(200, { \"content-type\": \"application/json\" });\n\t\t\tres.end(\n\t\t\t\tJSON.stringify({ sessions: stats.sessions, cost: stats.cost, input: stats.input, output: stats.output }),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tres.writeHead(200, { \"content-type\": \"text/html; charset=utf-8\" });\n\t\tres.end(HTML);\n\t});\n\n\tawait new Promise<void>((resolve, reject) => {\n\t\tserver.listen(port, \"127.0.0.1\", () => resolve());\n\t\tserver.on(\"error\", reject);\n\t});\n\n\tconst addr = server.address();\n\tif (!addr || typeof addr === \"string\") {\n\t\tconsole.error(\"Failed to start web server\");\n\t\treturn;\n\t}\n\n\tconst host = `http://127.0.0.1:${addr.port}`;\n\tconst lan = getLocalIP();\n\tconsole.log(`\\n pi web UI: ${host}`);\n\tif (lan !== \"127.0.0.1\") {\n\t\tconsole.log(` LAN: http://${lan}:${addr.port}`);\n\t}\n\tconsole.log();\n\n\t// Keep process alive\n\tawait new Promise(() => {});\n\n\tserver.close();\n}\n\nfunction toSerializableEvents(event: AgentSessionEvent): Record<string, unknown>[] {\n\tswitch (event.type) {\n\t\tcase \"agent_start\":\n\t\t\treturn [{ type: \"agent_start\" }];\n\t\tcase \"agent_end\": {\n\t\t\tconst lastAssistant = event.messages.filter((m) => m.role === \"assistant\").at(-1);\n\t\t\tconst usage = lastAssistant && \"usage\" in lastAssistant ? lastAssistant.usage : undefined;\n\t\t\treturn [{ type: \"agent_end\", usage }];\n\t\t}\n\t\tcase \"message_update\": {\n\t\t\tconst ame: Record<string, unknown> = event.assistantMessageEvent;\n\t\t\tconst serialized = serializeAssistantMessageEvent(ame);\n\t\t\treturn serialized;\n\t\t}\n\t\tcase \"tool_execution_start\":\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: \"tool_execution_start\",\n\t\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\t\ttoolName: event.toolName,\n\t\t\t\t\targs: event.args,\n\t\t\t\t},\n\t\t\t];\n\t\tcase \"tool_execution_update\":\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\t\tresult: event.partialResult,\n\t\t\t\t},\n\t\t\t];\n\t\tcase \"tool_execution_end\":\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: \"tool_execution_end\",\n\t\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\t\tresult: event.result,\n\t\t\t\t\tisError: event.isError,\n\t\t\t\t},\n\t\t\t];\n\t\tcase \"compaction_start\":\n\t\tcase \"compaction_end\":\n\t\t\treturn [{ type: \"compaction\" }];\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n\nfunction serializeAssistantMessageEvent(event: Record<string, unknown>): Record<string, unknown>[] {\n\tconst type = event.type as string;\n\tswitch (type) {\n\t\tcase \"start\":\n\t\t\treturn [{ type: \"agent_start\" }];\n\t\tcase \"text_start\":\n\t\t\treturn [{ type: \"text_start\", contentIndex: event.contentIndex }];\n\t\tcase \"text_delta\":\n\t\t\treturn [{ type: \"text_delta\", delta: event.delta, contentIndex: event.contentIndex }];\n\t\tcase \"text_end\":\n\t\t\treturn [{ type: \"text_end\", content: event.content, contentIndex: event.contentIndex }];\n\t\tcase \"thinking_start\":\n\t\t\treturn [{ type: \"thinking_start\", contentIndex: event.contentIndex }];\n\t\tcase \"thinking_delta\":\n\t\t\treturn [{ type: \"thinking_delta\", delta: event.delta, contentIndex: event.contentIndex }];\n\t\tcase \"thinking_end\":\n\t\t\treturn [{ type: \"thinking_end\", content: event.content, contentIndex: event.contentIndex }];\n\t\tcase \"toolcall_start\":\n\t\t\treturn [{ type: \"toolcall_start\", contentIndex: event.contentIndex }];\n\t\tcase \"toolcall_delta\":\n\t\t\treturn [{ type: \"toolcall_delta\", delta: event.delta, contentIndex: event.contentIndex }];\n\t\tcase \"toolcall_end\":\n\t\t\treturn [{ type: \"toolcall_end\", toolCall: event.toolCall, contentIndex: event.contentIndex }];\n\t\tcase \"done\":\n\t\t\treturn [{ type: \"done\", reason: event.reason }];\n\t\tcase \"error\":\n\t\t\treturn [{ type: \"error\", reason: event.reason }];\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"web-mode.d.ts","sourceRoot":"","sources":["../../../src/modes/web/web-mode.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAsG/E,wBAAsB,UAAU,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4E5E","sourcesContent":["import { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { networkInterfaces } from \"node:os\";\nimport type { AgentSessionEvent } from \"../../core/agent-session.ts\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.ts\";\n\nfunction getLocalIP(): string {\n\tconst interfaces = networkInterfaces();\n\tfor (const iface of Object.values(interfaces)) {\n\t\tif (!iface) continue;\n\t\tfor (const addr of iface) {\n\t\t\tif (addr.family === \"IPv4\" && !addr.internal) {\n\t\t\t\treturn addr.address;\n\t\t\t}\n\t\t}\n\t}\n\treturn \"127.0.0.1\";\n}\n\nfunction getPort(): number {\n\tconst env = process.env.PORT;\n\tif (env) {\n\t\tconst p = parseInt(env, 10);\n\t\tif (!Number.isNaN(p) && p > 0 && p < 65536) return p;\n\t}\n\treturn 0;\n}\n\nconst HTML = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>pi</title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font:13px/1.5 system-ui,monospace;background:#0d1117;color:#c9d1d9;height:100vh;display:flex;flex-direction:column}\n#header{background:#161b22;border-bottom:1px solid #30363d;padding:8px 16px;display:flex;justify-content:space-between;align-items:center;flex-shrink:0}\n#header span{color:#8b949e;font-size:12px}\n#msgs{flex:1;overflow-y:auto;padding:16px}\n.msg{margin-bottom:12px;max-width:85%}\n.msg.user{background:#1f6feb22;border:1px solid #1f6feb44;border-radius:8px 8px 0 8px;padding:8px 12px;margin-left:auto}\n.msg.assistant{margin-right:auto}\n.msg.system{color:#8b949e;font-size:11px;margin:4px auto;text-align:center;max-width:100%}\n.tool{border:1px solid #30363d;border-radius:6px;margin:6px 0;overflow:hidden}\n.tool-header{padding:6px 10px;background:#161b22;cursor:pointer;font-size:12px;display:flex;justify-content:space-between}\n.tool-header:hover{background:#21262d}\n.tool-body{padding:6px 10px;background:#0d1117;font-size:12px;white-space:pre-wrap;word-break:break-all;max-height:200px;overflow-y:auto;display:none}\n.tool.expanded .tool-body{display:block}\n.tool-arrow{color:#8b949e;transition:.2s}\n.tool.expanded .tool-arrow{transform:rotate(90deg)}\n.tool-pending{border-color:#d2992266}\n.tool-error .tool-header{color:#f85149}\n.thinking{color:#8b949e;font-size:12px;border-left:2px solid #30363d;padding:4px 8px;margin:4px 0;font-style:italic}\n#input-area{border-top:1px solid #30363d;padding:12px 16px;background:#161b22;flex-shrink:0}\n#input-area form{display:flex;gap:8px}\n#prompt{flex:1;background:#0d1117;border:1px solid #30363d;border-radius:6px;padding:8px 12px;color:#c9d1d9;font:13px system-ui,monospace;outline:none}\n#prompt:focus{border-color:#1f6feb}\nbutton{background:#238636;color:#fff;border:none;border-radius:6px;padding:8px 16px;cursor:pointer;font:13px system-ui;font-weight:500}\nbutton:hover{background:#2ea043}\nbutton:disabled{opacity:.5;cursor:default}\n</style>\n</head>\n<body>\n<div id=\"header\"><b>pi</b><span id=\"stats\"></span></div>\n<div id=\"msgs\"></div>\n<div id=\"input-area\">\n<form id=\"f\" autocomplete=\"off\"><input id=\"prompt\" type=\"text\" placeholder=\"Type a message...\" autofocus><button id=\"send\">Send</button></form>\n</div>\n<script>\nconst msgs=document.getElementById(\"msgs\"),f=document.getElementById(\"f\"),prompt=document.getElementById(\"prompt\"),send=document.getElementById(\"send\"),stats=document.getElementById(\"stats\");\nlet busy=false,toolEls={},curAssistant=null,curTextIdx=null,curThinkIdx=null;\nfunction addMsg(cls,html){const d=document.createElement(\"div\");d.className=\"msg \"+cls;d.innerHTML=html;msgs.appendChild(d);msgs.scrollTop=msgs.scrollHeight;return d}\nfunction addSystem(text){addMsg(\"system\",text)}\nfunction fmtTokens(n){if(n<1e3)return n;if(n<1e4)return(n/1e3).toFixed(1)+\"k\";return Math.round(n/1e3)+\"k\"}\nfunction esc(s){if(!s)return\"\";return s.replace(/&/g,\"&\").replace(/</g,\"<\").replace(/>/g,\">\")}\nfunction handleData(e){\nswitch(e.type){\ncase\"agent_start\":curAssistant=null;curTextIdx=null;curThinkIdx=null;break;\ncase\"text_start\":curTextIdx=e.contentIndex;if(!curAssistant){curAssistant=addMsg(\"assistant\",\"\");curTextIdx=null}break;\ncase\"text_delta\":if(!curAssistant)curAssistant=addMsg(\"assistant\",\"\");curAssistant.innerHTML+=esc(e.delta).replace(/\\\\n/g,\"<br>\");msgs.scrollTop=msgs.scrollHeight;break;\ncase\"thinking_start\":{const d=document.createElement(\"div\");d.className=\"thinking\";d.id=\"think\"+e.contentIndex;msgs.appendChild(d);break}\ncase\"thinking_delta\":{const d=document.getElementById(\"think\"+e.contentIndex);if(d)d.textContent+=e.delta;msgs.scrollTop=msgs.scrollHeight;break}\ncase\"toolcall_start\":break;\ncase\"toolcall_end\":break;\ncase\"tool_execution_start\":{const el=document.createElement(\"div\");el.className=\"tool tool-collapsed tool-pending\";el.id=\"t\"+e.toolCallId;const h=document.createElement(\"div\");h.className=\"tool-header\";h.innerHTML='<span>'+esc(e.toolName)+(e.args?' '+esc(String(e.args.command||e.args.path||e.args.file_path||JSON.stringify(e.args).slice(0,60))):'')+'</span><span class=\"tool-arrow\">▶</span>';h.onclick=()=>el.classList.toggle(\"expanded\");el.appendChild(h);const b=document.createElement(\"div\");b.className=\"tool-body\";el.appendChild(b);msgs.appendChild(el);toolEls[e.toolCallId]=el;msgs.scrollTop=msgs.scrollHeight;break}\ncase\"tool_execution_update\":{const el=toolEls[e.toolCallId];if(el){const b=el.querySelector(\".tool-body\");if(b&&e.result){const texts=Array.isArray(e.result)?e.result:e.result.content||[];b.innerText=texts.filter(c=>c&&c.type===\"text\").map(c=>c.text).join(\"\");el.classList.add(\"expanded\")}}break}\ncase\"tool_execution_end\":{const el=toolEls[e.toolCallId];if(el){el.classList.remove(\"tool-pending\");if(e.isError)el.classList.add(\"tool-error\");const b=el.querySelector(\".tool-body\");if(b&&e.result){const texts=e.result.content||[];b.innerText=texts.filter(c=>c&&c.type===\"text\").map(c=>c.text).join(\"\")}el.classList.add(\"expanded\")}break}\ncase\"agent_end\":{let usage=\"\";if(e.usage){usage=\" — ↑\"+fmtTokens(e.usage.input)+\" ↓\"+fmtTokens(e.usage.output);if(e.usage.cost)usage+=\" $\"+e.usage.cost.total.toFixed(4)}addSystem(\"Done\"+usage);break}\ncase\"compaction\":addSystem(\"Compacting...\");break;\ncase\"error\":addSystem(\"Error: \"+esc(e.message));break;}};\nf.onsubmit=async e=>{e.preventDefault();if(busy)return;const text=prompt.value.trim();if(!text)return;prompt.value=\"\";addMsg(\"user\",esc(text));busy=true;send.disabled=true;\ntry{const r=await fetch(\"/api/prompt\",{method:\"POST\",headers:{\"content-type\":\"application/json\"},body:JSON.stringify({text})});\nconst reader=r.body.getReader(),decoder=new TextDecoder();let buf=\"\";\nwhile(true){const{done,value}=await reader.read();if(done)break;buf+=decoder.decode(value,{stream:true});const lines=buf.split(\"\\\\n\");buf=lines.pop()||\"\";\nfor(const line of lines){if(!line.trim())continue;try{handleData(JSON.parse(line))}catch{}}}}\ncatch(err){addSystem(\"Error: \"+err.message)}finally{busy=false;send.disabled=false}};\nfetch(\"/api/stats\").then(r=>r.json()).then(s=>{stats.textContent=\"sessions: \"+s.sessions+\" | $\"+s.cost.toFixed(2)}).catch(()=>{});\n</script>\n</body>\n</html>`;\n\nfunction sendEvent(res: ServerResponse, data: Record<string, unknown>): void {\n\tres.write(`${JSON.stringify(data)}\\n`);\n}\n\nexport async function runWebMode(runtime: AgentSessionRuntime): Promise<void> {\n\tconst session = runtime.session;\n\tconst port = getPort();\n\n\tconst server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n\t\tconst url = req.url ?? \"/\";\n\n\t\tif (req.method === \"POST\" && url === \"/api/prompt\") {\n\t\t\tconst chunks: Buffer[] = [];\n\t\t\treq.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n\t\t\tawait new Promise<void>((resolve) => req.on(\"end\", resolve));\n\t\t\tconst body = JSON.parse(Buffer.concat(chunks).toString());\n\t\t\tconst text = String(body.text ?? \"\").trim();\n\t\t\tif (!text) {\n\t\t\t\tres.writeHead(400);\n\t\t\t\tres.end(JSON.stringify({ error: \"missing text\" }));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tres.writeHead(200, { \"content-type\": \"text/plain; charset=utf-8\", \"cache-control\": \"no-cache\" });\n\n\t\t\tconst unsubscribe = session.subscribe((event: AgentSessionEvent) => {\n\t\t\t\tconst events = toSerializableEvents(event);\n\t\t\t\tfor (const evt of events) {\n\t\t\t\t\tsendEvent(res, evt);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\tawait session.prompt(text);\n\t\t\t} catch (err) {\n\t\t\t\tsendEvent(res, { type: \"error\", message: String(err) });\n\t\t\t} finally {\n\t\t\t\tunsubscribe();\n\t\t\t\tres.end();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (req.method === \"GET\" && url === \"/api/stats\") {\n\t\t\tconst stats = await session.getUsageStats();\n\t\t\tres.writeHead(200, { \"content-type\": \"application/json\" });\n\t\t\tres.end(\n\t\t\t\tJSON.stringify({ sessions: stats.sessions, cost: stats.cost, input: stats.input, output: stats.output }),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tres.writeHead(200, { \"content-type\": \"text/html; charset=utf-8\" });\n\t\tres.end(HTML);\n\t});\n\n\tawait new Promise<void>((resolve, reject) => {\n\t\tserver.listen(port, \"0.0.0.0\", () => resolve());\n\t\tserver.on(\"error\", reject);\n\t});\n\n\tconst addr = server.address();\n\tif (!addr || typeof addr === \"string\") {\n\t\tconsole.error(\"Failed to start web server\");\n\t\treturn;\n\t}\n\n\tconst consolePort = `http://127.0.0.1:${addr.port}`;\n\tconst lan = getLocalIP();\n\tconsole.log(`\\n pi web UI: ${consolePort}`);\n\tif (lan !== \"127.0.0.1\") {\n\t\tconsole.log(` LAN: http://${lan}:${addr.port}`);\n\t}\n\tconsole.log(\" (listening on all interfaces)\");\n\tconsole.log();\n\n\t// Keep process alive\n\tawait new Promise(() => {});\n\n\tserver.close();\n}\n\nfunction toSerializableEvents(event: AgentSessionEvent): Record<string, unknown>[] {\n\tswitch (event.type) {\n\t\tcase \"agent_start\":\n\t\t\treturn [{ type: \"agent_start\" }];\n\t\tcase \"agent_end\": {\n\t\t\tconst lastAssistant = event.messages.filter((m) => m.role === \"assistant\").at(-1);\n\t\t\tconst usage = lastAssistant && \"usage\" in lastAssistant ? lastAssistant.usage : undefined;\n\t\t\treturn [{ type: \"agent_end\", usage }];\n\t\t}\n\t\tcase \"message_update\": {\n\t\t\tconst ame: Record<string, unknown> = event.assistantMessageEvent;\n\t\t\tconst serialized = serializeAssistantMessageEvent(ame);\n\t\t\treturn serialized;\n\t\t}\n\t\tcase \"tool_execution_start\":\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: \"tool_execution_start\",\n\t\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\t\ttoolName: event.toolName,\n\t\t\t\t\targs: event.args,\n\t\t\t\t},\n\t\t\t];\n\t\tcase \"tool_execution_update\":\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\t\tresult: event.partialResult,\n\t\t\t\t},\n\t\t\t];\n\t\tcase \"tool_execution_end\":\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: \"tool_execution_end\",\n\t\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\t\tresult: event.result,\n\t\t\t\t\tisError: event.isError,\n\t\t\t\t},\n\t\t\t];\n\t\tcase \"compaction_start\":\n\t\tcase \"compaction_end\":\n\t\t\treturn [{ type: \"compaction\" }];\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n\nfunction serializeAssistantMessageEvent(event: Record<string, unknown>): Record<string, unknown>[] {\n\tconst type = event.type as string;\n\tswitch (type) {\n\t\tcase \"start\":\n\t\t\treturn [{ type: \"agent_start\" }];\n\t\tcase \"text_start\":\n\t\t\treturn [{ type: \"text_start\", contentIndex: event.contentIndex }];\n\t\tcase \"text_delta\":\n\t\t\treturn [{ type: \"text_delta\", delta: event.delta, contentIndex: event.contentIndex }];\n\t\tcase \"text_end\":\n\t\t\treturn [{ type: \"text_end\", content: event.content, contentIndex: event.contentIndex }];\n\t\tcase \"thinking_start\":\n\t\t\treturn [{ type: \"thinking_start\", contentIndex: event.contentIndex }];\n\t\tcase \"thinking_delta\":\n\t\t\treturn [{ type: \"thinking_delta\", delta: event.delta, contentIndex: event.contentIndex }];\n\t\tcase \"thinking_end\":\n\t\t\treturn [{ type: \"thinking_end\", content: event.content, contentIndex: event.contentIndex }];\n\t\tcase \"toolcall_start\":\n\t\t\treturn [{ type: \"toolcall_start\", contentIndex: event.contentIndex }];\n\t\tcase \"toolcall_delta\":\n\t\t\treturn [{ type: \"toolcall_delta\", delta: event.delta, contentIndex: event.contentIndex }];\n\t\tcase \"toolcall_end\":\n\t\t\treturn [{ type: \"toolcall_end\", toolCall: event.toolCall, contentIndex: event.contentIndex }];\n\t\tcase \"done\":\n\t\t\treturn [{ type: \"done\", reason: event.reason }];\n\t\tcase \"error\":\n\t\t\treturn [{ type: \"error\", reason: event.reason }];\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n"]}
|
|
@@ -143,7 +143,7 @@ export async function runWebMode(runtime) {
|
|
|
143
143
|
res.end(HTML);
|
|
144
144
|
});
|
|
145
145
|
await new Promise((resolve, reject) => {
|
|
146
|
-
server.listen(port, "
|
|
146
|
+
server.listen(port, "0.0.0.0", () => resolve());
|
|
147
147
|
server.on("error", reject);
|
|
148
148
|
});
|
|
149
149
|
const addr = server.address();
|
|
@@ -151,12 +151,13 @@ export async function runWebMode(runtime) {
|
|
|
151
151
|
console.error("Failed to start web server");
|
|
152
152
|
return;
|
|
153
153
|
}
|
|
154
|
-
const
|
|
154
|
+
const consolePort = `http://127.0.0.1:${addr.port}`;
|
|
155
155
|
const lan = getLocalIP();
|
|
156
|
-
console.log(`\n pi web UI: ${
|
|
156
|
+
console.log(`\n pi web UI: ${consolePort}`);
|
|
157
157
|
if (lan !== "127.0.0.1") {
|
|
158
158
|
console.log(` LAN: http://${lan}:${addr.port}`);
|
|
159
159
|
}
|
|
160
|
+
console.log(" (listening on all interfaces)");
|
|
160
161
|
console.log();
|
|
161
162
|
// Keep process alive
|
|
162
163
|
await new Promise(() => { });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-mode.js","sourceRoot":"","sources":["../../../src/modes/web/web-mode.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { networkInterfaces } from \"node:os\";\nimport type { AgentSessionEvent } from \"../../core/agent-session.ts\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.ts\";\n\nfunction getLocalIP(): string {\n\tconst interfaces = networkInterfaces();\n\tfor (const iface of Object.values(interfaces)) {\n\t\tif (!iface) continue;\n\t\tfor (const addr of iface) {\n\t\t\tif (addr.family === \"IPv4\" && !addr.internal) {\n\t\t\t\treturn addr.address;\n\t\t\t}\n\t\t}\n\t}\n\treturn \"127.0.0.1\";\n}\n\nfunction getPort(): number {\n\tconst env = process.env.PORT;\n\tif (env) {\n\t\tconst p = parseInt(env, 10);\n\t\tif (!Number.isNaN(p) && p > 0 && p < 65536) return p;\n\t}\n\treturn 0;\n}\n\nconst HTML = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>pi</title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font:13px/1.5 system-ui,monospace;background:#0d1117;color:#c9d1d9;height:100vh;display:flex;flex-direction:column}\n#header{background:#161b22;border-bottom:1px solid #30363d;padding:8px 16px;display:flex;justify-content:space-between;align-items:center;flex-shrink:0}\n#header span{color:#8b949e;font-size:12px}\n#msgs{flex:1;overflow-y:auto;padding:16px}\n.msg{margin-bottom:12px;max-width:85%}\n.msg.user{background:#1f6feb22;border:1px solid #1f6feb44;border-radius:8px 8px 0 8px;padding:8px 12px;margin-left:auto}\n.msg.assistant{margin-right:auto}\n.msg.system{color:#8b949e;font-size:11px;margin:4px auto;text-align:center;max-width:100%}\n.tool{border:1px solid #30363d;border-radius:6px;margin:6px 0;overflow:hidden}\n.tool-header{padding:6px 10px;background:#161b22;cursor:pointer;font-size:12px;display:flex;justify-content:space-between}\n.tool-header:hover{background:#21262d}\n.tool-body{padding:6px 10px;background:#0d1117;font-size:12px;white-space:pre-wrap;word-break:break-all;max-height:200px;overflow-y:auto;display:none}\n.tool.expanded .tool-body{display:block}\n.tool-arrow{color:#8b949e;transition:.2s}\n.tool.expanded .tool-arrow{transform:rotate(90deg)}\n.tool-pending{border-color:#d2992266}\n.tool-error .tool-header{color:#f85149}\n.thinking{color:#8b949e;font-size:12px;border-left:2px solid #30363d;padding:4px 8px;margin:4px 0;font-style:italic}\n#input-area{border-top:1px solid #30363d;padding:12px 16px;background:#161b22;flex-shrink:0}\n#input-area form{display:flex;gap:8px}\n#prompt{flex:1;background:#0d1117;border:1px solid #30363d;border-radius:6px;padding:8px 12px;color:#c9d1d9;font:13px system-ui,monospace;outline:none}\n#prompt:focus{border-color:#1f6feb}\nbutton{background:#238636;color:#fff;border:none;border-radius:6px;padding:8px 16px;cursor:pointer;font:13px system-ui;font-weight:500}\nbutton:hover{background:#2ea043}\nbutton:disabled{opacity:.5;cursor:default}\n</style>\n</head>\n<body>\n<div id=\"header\"><b>pi</b><span id=\"stats\"></span></div>\n<div id=\"msgs\"></div>\n<div id=\"input-area\">\n<form id=\"f\" autocomplete=\"off\"><input id=\"prompt\" type=\"text\" placeholder=\"Type a message...\" autofocus><button id=\"send\">Send</button></form>\n</div>\n<script>\nconst msgs=document.getElementById(\"msgs\"),f=document.getElementById(\"f\"),prompt=document.getElementById(\"prompt\"),send=document.getElementById(\"send\"),stats=document.getElementById(\"stats\");\nlet busy=false,toolEls={},curAssistant=null,curTextIdx=null,curThinkIdx=null;\nfunction addMsg(cls,html){const d=document.createElement(\"div\");d.className=\"msg \"+cls;d.innerHTML=html;msgs.appendChild(d);msgs.scrollTop=msgs.scrollHeight;return d}\nfunction addSystem(text){addMsg(\"system\",text)}\nfunction fmtTokens(n){if(n<1e3)return n;if(n<1e4)return(n/1e3).toFixed(1)+\"k\";return Math.round(n/1e3)+\"k\"}\nfunction esc(s){if(!s)return\"\";return s.replace(/&/g,\"&\").replace(/</g,\"<\").replace(/>/g,\">\")}\nfunction handleData(e){\nswitch(e.type){\ncase\"agent_start\":curAssistant=null;curTextIdx=null;curThinkIdx=null;break;\ncase\"text_start\":curTextIdx=e.contentIndex;if(!curAssistant){curAssistant=addMsg(\"assistant\",\"\");curTextIdx=null}break;\ncase\"text_delta\":if(!curAssistant)curAssistant=addMsg(\"assistant\",\"\");curAssistant.innerHTML+=esc(e.delta).replace(/\\\\n/g,\"<br>\");msgs.scrollTop=msgs.scrollHeight;break;\ncase\"thinking_start\":{const d=document.createElement(\"div\");d.className=\"thinking\";d.id=\"think\"+e.contentIndex;msgs.appendChild(d);break}\ncase\"thinking_delta\":{const d=document.getElementById(\"think\"+e.contentIndex);if(d)d.textContent+=e.delta;msgs.scrollTop=msgs.scrollHeight;break}\ncase\"toolcall_start\":break;\ncase\"toolcall_end\":break;\ncase\"tool_execution_start\":{const el=document.createElement(\"div\");el.className=\"tool tool-collapsed tool-pending\";el.id=\"t\"+e.toolCallId;const h=document.createElement(\"div\");h.className=\"tool-header\";h.innerHTML='<span>'+esc(e.toolName)+(e.args?' '+esc(String(e.args.command||e.args.path||e.args.file_path||JSON.stringify(e.args).slice(0,60))):'')+'</span><span class=\"tool-arrow\">▶</span>';h.onclick=()=>el.classList.toggle(\"expanded\");el.appendChild(h);const b=document.createElement(\"div\");b.className=\"tool-body\";el.appendChild(b);msgs.appendChild(el);toolEls[e.toolCallId]=el;msgs.scrollTop=msgs.scrollHeight;break}\ncase\"tool_execution_update\":{const el=toolEls[e.toolCallId];if(el){const b=el.querySelector(\".tool-body\");if(b&&e.result){const texts=Array.isArray(e.result)?e.result:e.result.content||[];b.innerText=texts.filter(c=>c&&c.type===\"text\").map(c=>c.text).join(\"\");el.classList.add(\"expanded\")}}break}\ncase\"tool_execution_end\":{const el=toolEls[e.toolCallId];if(el){el.classList.remove(\"tool-pending\");if(e.isError)el.classList.add(\"tool-error\");const b=el.querySelector(\".tool-body\");if(b&&e.result){const texts=e.result.content||[];b.innerText=texts.filter(c=>c&&c.type===\"text\").map(c=>c.text).join(\"\")}el.classList.add(\"expanded\")}break}\ncase\"agent_end\":{let usage=\"\";if(e.usage){usage=\" — ↑\"+fmtTokens(e.usage.input)+\" ↓\"+fmtTokens(e.usage.output);if(e.usage.cost)usage+=\" $\"+e.usage.cost.total.toFixed(4)}addSystem(\"Done\"+usage);break}\ncase\"compaction\":addSystem(\"Compacting...\");break;\ncase\"error\":addSystem(\"Error: \"+esc(e.message));break;}};\nf.onsubmit=async e=>{e.preventDefault();if(busy)return;const text=prompt.value.trim();if(!text)return;prompt.value=\"\";addMsg(\"user\",esc(text));busy=true;send.disabled=true;\ntry{const r=await fetch(\"/api/prompt\",{method:\"POST\",headers:{\"content-type\":\"application/json\"},body:JSON.stringify({text})});\nconst reader=r.body.getReader(),decoder=new TextDecoder();let buf=\"\";\nwhile(true){const{done,value}=await reader.read();if(done)break;buf+=decoder.decode(value,{stream:true});const lines=buf.split(\"\\\\n\");buf=lines.pop()||\"\";\nfor(const line of lines){if(!line.trim())continue;try{handleData(JSON.parse(line))}catch{}}}}\ncatch(err){addSystem(\"Error: \"+err.message)}finally{busy=false;send.disabled=false}};\nfetch(\"/api/stats\").then(r=>r.json()).then(s=>{stats.textContent=\"sessions: \"+s.sessions+\" | $\"+s.cost.toFixed(2)}).catch(()=>{});\n</script>\n</body>\n</html>`;\n\nfunction sendEvent(res: ServerResponse, data: Record<string, unknown>): void {\n\tres.write(`${JSON.stringify(data)}\\n`);\n}\n\nexport async function runWebMode(runtime: AgentSessionRuntime): Promise<void> {\n\tconst session = runtime.session;\n\tconst port = getPort();\n\n\tconst server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n\t\tconst url = req.url ?? \"/\";\n\n\t\tif (req.method === \"POST\" && url === \"/api/prompt\") {\n\t\t\tconst chunks: Buffer[] = [];\n\t\t\treq.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n\t\t\tawait new Promise<void>((resolve) => req.on(\"end\", resolve));\n\t\t\tconst body = JSON.parse(Buffer.concat(chunks).toString());\n\t\t\tconst text = String(body.text ?? \"\").trim();\n\t\t\tif (!text) {\n\t\t\t\tres.writeHead(400);\n\t\t\t\tres.end(JSON.stringify({ error: \"missing text\" }));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tres.writeHead(200, { \"content-type\": \"text/plain; charset=utf-8\", \"cache-control\": \"no-cache\" });\n\n\t\t\tconst unsubscribe = session.subscribe((event: AgentSessionEvent) => {\n\t\t\t\tconst events = toSerializableEvents(event);\n\t\t\t\tfor (const evt of events) {\n\t\t\t\t\tsendEvent(res, evt);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\tawait session.prompt(text);\n\t\t\t} catch (err) {\n\t\t\t\tsendEvent(res, { type: \"error\", message: String(err) });\n\t\t\t} finally {\n\t\t\t\tunsubscribe();\n\t\t\t\tres.end();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (req.method === \"GET\" && url === \"/api/stats\") {\n\t\t\tconst stats = await session.getUsageStats();\n\t\t\tres.writeHead(200, { \"content-type\": \"application/json\" });\n\t\t\tres.end(\n\t\t\t\tJSON.stringify({ sessions: stats.sessions, cost: stats.cost, input: stats.input, output: stats.output }),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tres.writeHead(200, { \"content-type\": \"text/html; charset=utf-8\" });\n\t\tres.end(HTML);\n\t});\n\n\tawait new Promise<void>((resolve, reject) => {\n\t\tserver.listen(port, \"127.0.0.1\", () => resolve());\n\t\tserver.on(\"error\", reject);\n\t});\n\n\tconst addr = server.address();\n\tif (!addr || typeof addr === \"string\") {\n\t\tconsole.error(\"Failed to start web server\");\n\t\treturn;\n\t}\n\n\tconst host = `http://127.0.0.1:${addr.port}`;\n\tconst lan = getLocalIP();\n\tconsole.log(`\\n pi web UI: ${host}`);\n\tif (lan !== \"127.0.0.1\") {\n\t\tconsole.log(` LAN: http://${lan}:${addr.port}`);\n\t}\n\tconsole.log();\n\n\t// Keep process alive\n\tawait new Promise(() => {});\n\n\tserver.close();\n}\n\nfunction toSerializableEvents(event: AgentSessionEvent): Record<string, unknown>[] {\n\tswitch (event.type) {\n\t\tcase \"agent_start\":\n\t\t\treturn [{ type: \"agent_start\" }];\n\t\tcase \"agent_end\": {\n\t\t\tconst lastAssistant = event.messages.filter((m) => m.role === \"assistant\").at(-1);\n\t\t\tconst usage = lastAssistant && \"usage\" in lastAssistant ? lastAssistant.usage : undefined;\n\t\t\treturn [{ type: \"agent_end\", usage }];\n\t\t}\n\t\tcase \"message_update\": {\n\t\t\tconst ame: Record<string, unknown> = event.assistantMessageEvent;\n\t\t\tconst serialized = serializeAssistantMessageEvent(ame);\n\t\t\treturn serialized;\n\t\t}\n\t\tcase \"tool_execution_start\":\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: \"tool_execution_start\",\n\t\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\t\ttoolName: event.toolName,\n\t\t\t\t\targs: event.args,\n\t\t\t\t},\n\t\t\t];\n\t\tcase \"tool_execution_update\":\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\t\tresult: event.partialResult,\n\t\t\t\t},\n\t\t\t];\n\t\tcase \"tool_execution_end\":\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: \"tool_execution_end\",\n\t\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\t\tresult: event.result,\n\t\t\t\t\tisError: event.isError,\n\t\t\t\t},\n\t\t\t];\n\t\tcase \"compaction_start\":\n\t\tcase \"compaction_end\":\n\t\t\treturn [{ type: \"compaction\" }];\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n\nfunction serializeAssistantMessageEvent(event: Record<string, unknown>): Record<string, unknown>[] {\n\tconst type = event.type as string;\n\tswitch (type) {\n\t\tcase \"start\":\n\t\t\treturn [{ type: \"agent_start\" }];\n\t\tcase \"text_start\":\n\t\t\treturn [{ type: \"text_start\", contentIndex: event.contentIndex }];\n\t\tcase \"text_delta\":\n\t\t\treturn [{ type: \"text_delta\", delta: event.delta, contentIndex: event.contentIndex }];\n\t\tcase \"text_end\":\n\t\t\treturn [{ type: \"text_end\", content: event.content, contentIndex: event.contentIndex }];\n\t\tcase \"thinking_start\":\n\t\t\treturn [{ type: \"thinking_start\", contentIndex: event.contentIndex }];\n\t\tcase \"thinking_delta\":\n\t\t\treturn [{ type: \"thinking_delta\", delta: event.delta, contentIndex: event.contentIndex }];\n\t\tcase \"thinking_end\":\n\t\t\treturn [{ type: \"thinking_end\", content: event.content, contentIndex: event.contentIndex }];\n\t\tcase \"toolcall_start\":\n\t\t\treturn [{ type: \"toolcall_start\", contentIndex: event.contentIndex }];\n\t\tcase \"toolcall_delta\":\n\t\t\treturn [{ type: \"toolcall_delta\", delta: event.delta, contentIndex: event.contentIndex }];\n\t\tcase \"toolcall_end\":\n\t\t\treturn [{ type: \"toolcall_end\", toolCall: event.toolCall, contentIndex: event.contentIndex }];\n\t\tcase \"done\":\n\t\t\treturn [{ type: \"done\", reason: event.reason }];\n\t\tcase \"error\":\n\t\t\treturn [{ type: \"error\", reason: event.reason }];\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"web-mode.js","sourceRoot":"","sources":["../../../src/modes/web/web-mode.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { networkInterfaces } from \"node:os\";\nimport type { AgentSessionEvent } from \"../../core/agent-session.ts\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.ts\";\n\nfunction getLocalIP(): string {\n\tconst interfaces = networkInterfaces();\n\tfor (const iface of Object.values(interfaces)) {\n\t\tif (!iface) continue;\n\t\tfor (const addr of iface) {\n\t\t\tif (addr.family === \"IPv4\" && !addr.internal) {\n\t\t\t\treturn addr.address;\n\t\t\t}\n\t\t}\n\t}\n\treturn \"127.0.0.1\";\n}\n\nfunction getPort(): number {\n\tconst env = process.env.PORT;\n\tif (env) {\n\t\tconst p = parseInt(env, 10);\n\t\tif (!Number.isNaN(p) && p > 0 && p < 65536) return p;\n\t}\n\treturn 0;\n}\n\nconst HTML = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>pi</title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font:13px/1.5 system-ui,monospace;background:#0d1117;color:#c9d1d9;height:100vh;display:flex;flex-direction:column}\n#header{background:#161b22;border-bottom:1px solid #30363d;padding:8px 16px;display:flex;justify-content:space-between;align-items:center;flex-shrink:0}\n#header span{color:#8b949e;font-size:12px}\n#msgs{flex:1;overflow-y:auto;padding:16px}\n.msg{margin-bottom:12px;max-width:85%}\n.msg.user{background:#1f6feb22;border:1px solid #1f6feb44;border-radius:8px 8px 0 8px;padding:8px 12px;margin-left:auto}\n.msg.assistant{margin-right:auto}\n.msg.system{color:#8b949e;font-size:11px;margin:4px auto;text-align:center;max-width:100%}\n.tool{border:1px solid #30363d;border-radius:6px;margin:6px 0;overflow:hidden}\n.tool-header{padding:6px 10px;background:#161b22;cursor:pointer;font-size:12px;display:flex;justify-content:space-between}\n.tool-header:hover{background:#21262d}\n.tool-body{padding:6px 10px;background:#0d1117;font-size:12px;white-space:pre-wrap;word-break:break-all;max-height:200px;overflow-y:auto;display:none}\n.tool.expanded .tool-body{display:block}\n.tool-arrow{color:#8b949e;transition:.2s}\n.tool.expanded .tool-arrow{transform:rotate(90deg)}\n.tool-pending{border-color:#d2992266}\n.tool-error .tool-header{color:#f85149}\n.thinking{color:#8b949e;font-size:12px;border-left:2px solid #30363d;padding:4px 8px;margin:4px 0;font-style:italic}\n#input-area{border-top:1px solid #30363d;padding:12px 16px;background:#161b22;flex-shrink:0}\n#input-area form{display:flex;gap:8px}\n#prompt{flex:1;background:#0d1117;border:1px solid #30363d;border-radius:6px;padding:8px 12px;color:#c9d1d9;font:13px system-ui,monospace;outline:none}\n#prompt:focus{border-color:#1f6feb}\nbutton{background:#238636;color:#fff;border:none;border-radius:6px;padding:8px 16px;cursor:pointer;font:13px system-ui;font-weight:500}\nbutton:hover{background:#2ea043}\nbutton:disabled{opacity:.5;cursor:default}\n</style>\n</head>\n<body>\n<div id=\"header\"><b>pi</b><span id=\"stats\"></span></div>\n<div id=\"msgs\"></div>\n<div id=\"input-area\">\n<form id=\"f\" autocomplete=\"off\"><input id=\"prompt\" type=\"text\" placeholder=\"Type a message...\" autofocus><button id=\"send\">Send</button></form>\n</div>\n<script>\nconst msgs=document.getElementById(\"msgs\"),f=document.getElementById(\"f\"),prompt=document.getElementById(\"prompt\"),send=document.getElementById(\"send\"),stats=document.getElementById(\"stats\");\nlet busy=false,toolEls={},curAssistant=null,curTextIdx=null,curThinkIdx=null;\nfunction addMsg(cls,html){const d=document.createElement(\"div\");d.className=\"msg \"+cls;d.innerHTML=html;msgs.appendChild(d);msgs.scrollTop=msgs.scrollHeight;return d}\nfunction addSystem(text){addMsg(\"system\",text)}\nfunction fmtTokens(n){if(n<1e3)return n;if(n<1e4)return(n/1e3).toFixed(1)+\"k\";return Math.round(n/1e3)+\"k\"}\nfunction esc(s){if(!s)return\"\";return s.replace(/&/g,\"&\").replace(/</g,\"<\").replace(/>/g,\">\")}\nfunction handleData(e){\nswitch(e.type){\ncase\"agent_start\":curAssistant=null;curTextIdx=null;curThinkIdx=null;break;\ncase\"text_start\":curTextIdx=e.contentIndex;if(!curAssistant){curAssistant=addMsg(\"assistant\",\"\");curTextIdx=null}break;\ncase\"text_delta\":if(!curAssistant)curAssistant=addMsg(\"assistant\",\"\");curAssistant.innerHTML+=esc(e.delta).replace(/\\\\n/g,\"<br>\");msgs.scrollTop=msgs.scrollHeight;break;\ncase\"thinking_start\":{const d=document.createElement(\"div\");d.className=\"thinking\";d.id=\"think\"+e.contentIndex;msgs.appendChild(d);break}\ncase\"thinking_delta\":{const d=document.getElementById(\"think\"+e.contentIndex);if(d)d.textContent+=e.delta;msgs.scrollTop=msgs.scrollHeight;break}\ncase\"toolcall_start\":break;\ncase\"toolcall_end\":break;\ncase\"tool_execution_start\":{const el=document.createElement(\"div\");el.className=\"tool tool-collapsed tool-pending\";el.id=\"t\"+e.toolCallId;const h=document.createElement(\"div\");h.className=\"tool-header\";h.innerHTML='<span>'+esc(e.toolName)+(e.args?' '+esc(String(e.args.command||e.args.path||e.args.file_path||JSON.stringify(e.args).slice(0,60))):'')+'</span><span class=\"tool-arrow\">▶</span>';h.onclick=()=>el.classList.toggle(\"expanded\");el.appendChild(h);const b=document.createElement(\"div\");b.className=\"tool-body\";el.appendChild(b);msgs.appendChild(el);toolEls[e.toolCallId]=el;msgs.scrollTop=msgs.scrollHeight;break}\ncase\"tool_execution_update\":{const el=toolEls[e.toolCallId];if(el){const b=el.querySelector(\".tool-body\");if(b&&e.result){const texts=Array.isArray(e.result)?e.result:e.result.content||[];b.innerText=texts.filter(c=>c&&c.type===\"text\").map(c=>c.text).join(\"\");el.classList.add(\"expanded\")}}break}\ncase\"tool_execution_end\":{const el=toolEls[e.toolCallId];if(el){el.classList.remove(\"tool-pending\");if(e.isError)el.classList.add(\"tool-error\");const b=el.querySelector(\".tool-body\");if(b&&e.result){const texts=e.result.content||[];b.innerText=texts.filter(c=>c&&c.type===\"text\").map(c=>c.text).join(\"\")}el.classList.add(\"expanded\")}break}\ncase\"agent_end\":{let usage=\"\";if(e.usage){usage=\" — ↑\"+fmtTokens(e.usage.input)+\" ↓\"+fmtTokens(e.usage.output);if(e.usage.cost)usage+=\" $\"+e.usage.cost.total.toFixed(4)}addSystem(\"Done\"+usage);break}\ncase\"compaction\":addSystem(\"Compacting...\");break;\ncase\"error\":addSystem(\"Error: \"+esc(e.message));break;}};\nf.onsubmit=async e=>{e.preventDefault();if(busy)return;const text=prompt.value.trim();if(!text)return;prompt.value=\"\";addMsg(\"user\",esc(text));busy=true;send.disabled=true;\ntry{const r=await fetch(\"/api/prompt\",{method:\"POST\",headers:{\"content-type\":\"application/json\"},body:JSON.stringify({text})});\nconst reader=r.body.getReader(),decoder=new TextDecoder();let buf=\"\";\nwhile(true){const{done,value}=await reader.read();if(done)break;buf+=decoder.decode(value,{stream:true});const lines=buf.split(\"\\\\n\");buf=lines.pop()||\"\";\nfor(const line of lines){if(!line.trim())continue;try{handleData(JSON.parse(line))}catch{}}}}\ncatch(err){addSystem(\"Error: \"+err.message)}finally{busy=false;send.disabled=false}};\nfetch(\"/api/stats\").then(r=>r.json()).then(s=>{stats.textContent=\"sessions: \"+s.sessions+\" | $\"+s.cost.toFixed(2)}).catch(()=>{});\n</script>\n</body>\n</html>`;\n\nfunction sendEvent(res: ServerResponse, data: Record<string, unknown>): void {\n\tres.write(`${JSON.stringify(data)}\\n`);\n}\n\nexport async function runWebMode(runtime: AgentSessionRuntime): Promise<void> {\n\tconst session = runtime.session;\n\tconst port = getPort();\n\n\tconst server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n\t\tconst url = req.url ?? \"/\";\n\n\t\tif (req.method === \"POST\" && url === \"/api/prompt\") {\n\t\t\tconst chunks: Buffer[] = [];\n\t\t\treq.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n\t\t\tawait new Promise<void>((resolve) => req.on(\"end\", resolve));\n\t\t\tconst body = JSON.parse(Buffer.concat(chunks).toString());\n\t\t\tconst text = String(body.text ?? \"\").trim();\n\t\t\tif (!text) {\n\t\t\t\tres.writeHead(400);\n\t\t\t\tres.end(JSON.stringify({ error: \"missing text\" }));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tres.writeHead(200, { \"content-type\": \"text/plain; charset=utf-8\", \"cache-control\": \"no-cache\" });\n\n\t\t\tconst unsubscribe = session.subscribe((event: AgentSessionEvent) => {\n\t\t\t\tconst events = toSerializableEvents(event);\n\t\t\t\tfor (const evt of events) {\n\t\t\t\t\tsendEvent(res, evt);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\tawait session.prompt(text);\n\t\t\t} catch (err) {\n\t\t\t\tsendEvent(res, { type: \"error\", message: String(err) });\n\t\t\t} finally {\n\t\t\t\tunsubscribe();\n\t\t\t\tres.end();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (req.method === \"GET\" && url === \"/api/stats\") {\n\t\t\tconst stats = await session.getUsageStats();\n\t\t\tres.writeHead(200, { \"content-type\": \"application/json\" });\n\t\t\tres.end(\n\t\t\t\tJSON.stringify({ sessions: stats.sessions, cost: stats.cost, input: stats.input, output: stats.output }),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tres.writeHead(200, { \"content-type\": \"text/html; charset=utf-8\" });\n\t\tres.end(HTML);\n\t});\n\n\tawait new Promise<void>((resolve, reject) => {\n\t\tserver.listen(port, \"0.0.0.0\", () => resolve());\n\t\tserver.on(\"error\", reject);\n\t});\n\n\tconst addr = server.address();\n\tif (!addr || typeof addr === \"string\") {\n\t\tconsole.error(\"Failed to start web server\");\n\t\treturn;\n\t}\n\n\tconst consolePort = `http://127.0.0.1:${addr.port}`;\n\tconst lan = getLocalIP();\n\tconsole.log(`\\n pi web UI: ${consolePort}`);\n\tif (lan !== \"127.0.0.1\") {\n\t\tconsole.log(` LAN: http://${lan}:${addr.port}`);\n\t}\n\tconsole.log(\" (listening on all interfaces)\");\n\tconsole.log();\n\n\t// Keep process alive\n\tawait new Promise(() => {});\n\n\tserver.close();\n}\n\nfunction toSerializableEvents(event: AgentSessionEvent): Record<string, unknown>[] {\n\tswitch (event.type) {\n\t\tcase \"agent_start\":\n\t\t\treturn [{ type: \"agent_start\" }];\n\t\tcase \"agent_end\": {\n\t\t\tconst lastAssistant = event.messages.filter((m) => m.role === \"assistant\").at(-1);\n\t\t\tconst usage = lastAssistant && \"usage\" in lastAssistant ? lastAssistant.usage : undefined;\n\t\t\treturn [{ type: \"agent_end\", usage }];\n\t\t}\n\t\tcase \"message_update\": {\n\t\t\tconst ame: Record<string, unknown> = event.assistantMessageEvent;\n\t\t\tconst serialized = serializeAssistantMessageEvent(ame);\n\t\t\treturn serialized;\n\t\t}\n\t\tcase \"tool_execution_start\":\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: \"tool_execution_start\",\n\t\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\t\ttoolName: event.toolName,\n\t\t\t\t\targs: event.args,\n\t\t\t\t},\n\t\t\t];\n\t\tcase \"tool_execution_update\":\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\t\tresult: event.partialResult,\n\t\t\t\t},\n\t\t\t];\n\t\tcase \"tool_execution_end\":\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: \"tool_execution_end\",\n\t\t\t\t\ttoolCallId: event.toolCallId,\n\t\t\t\t\tresult: event.result,\n\t\t\t\t\tisError: event.isError,\n\t\t\t\t},\n\t\t\t];\n\t\tcase \"compaction_start\":\n\t\tcase \"compaction_end\":\n\t\t\treturn [{ type: \"compaction\" }];\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n\nfunction serializeAssistantMessageEvent(event: Record<string, unknown>): Record<string, unknown>[] {\n\tconst type = event.type as string;\n\tswitch (type) {\n\t\tcase \"start\":\n\t\t\treturn [{ type: \"agent_start\" }];\n\t\tcase \"text_start\":\n\t\t\treturn [{ type: \"text_start\", contentIndex: event.contentIndex }];\n\t\tcase \"text_delta\":\n\t\t\treturn [{ type: \"text_delta\", delta: event.delta, contentIndex: event.contentIndex }];\n\t\tcase \"text_end\":\n\t\t\treturn [{ type: \"text_end\", content: event.content, contentIndex: event.contentIndex }];\n\t\tcase \"thinking_start\":\n\t\t\treturn [{ type: \"thinking_start\", contentIndex: event.contentIndex }];\n\t\tcase \"thinking_delta\":\n\t\t\treturn [{ type: \"thinking_delta\", delta: event.delta, contentIndex: event.contentIndex }];\n\t\tcase \"thinking_end\":\n\t\t\treturn [{ type: \"thinking_end\", content: event.content, contentIndex: event.contentIndex }];\n\t\tcase \"toolcall_start\":\n\t\t\treturn [{ type: \"toolcall_start\", contentIndex: event.contentIndex }];\n\t\tcase \"toolcall_delta\":\n\t\t\treturn [{ type: \"toolcall_delta\", delta: event.delta, contentIndex: event.contentIndex }];\n\t\tcase \"toolcall_end\":\n\t\t\treturn [{ type: \"toolcall_end\", toolCall: event.toolCall, contentIndex: event.contentIndex }];\n\t\tcase \"done\":\n\t\t\treturn [{ type: \"done\", reason: event.reason }];\n\t\tcase \"error\":\n\t\t\treturn [{ type: \"error\", reason: event.reason }];\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n"]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-custom-provider",
|
|
3
|
-
"version": "0.75.
|
|
3
|
+
"version": "0.75.12",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-custom-provider",
|
|
9
|
-
"version": "0.75.
|
|
9
|
+
"version": "0.75.12",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.52.0"
|
|
12
12
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-sandbox",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.12",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-sandbox",
|
|
9
|
-
"version": "1.5.
|
|
9
|
+
"version": "1.5.12",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sandbox-runtime": "^0.0.26"
|
|
12
12
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-with-deps",
|
|
3
|
-
"version": "0.75.
|
|
3
|
+
"version": "0.75.12",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-with-deps",
|
|
9
|
-
"version": "0.75.
|
|
9
|
+
"version": "0.75.12",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"ms": "^2.1.3"
|
|
12
12
|
},
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openeryc/pi-coding-agent",
|
|
3
|
-
"version": "0.75.
|
|
3
|
+
"version": "0.75.12",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openeryc/pi-coding-agent",
|
|
9
|
-
"version": "0.75.
|
|
9
|
+
"version": "0.75.12",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@openeryc/pi-agent-core": "^0.75.
|
|
13
|
-
"@openeryc/pi-ai": "^0.75.
|
|
14
|
-
"@openeryc/pi-tui": "^0.75.
|
|
12
|
+
"@openeryc/pi-agent-core": "^0.75.12",
|
|
13
|
+
"@openeryc/pi-ai": "^0.75.12",
|
|
14
|
+
"@openeryc/pi-tui": "^0.75.12",
|
|
15
15
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
16
16
|
"chalk": "5.6.2",
|
|
17
17
|
"cross-spawn": "7.0.6",
|
|
@@ -699,11 +699,11 @@
|
|
|
699
699
|
]
|
|
700
700
|
},
|
|
701
701
|
"node_modules/@openeryc/pi-agent-core": {
|
|
702
|
-
"version": "0.75.
|
|
703
|
-
"resolved": "https://registry.npmjs.org/@openeryc/pi-agent-core/-/pi-agent-core-0.75.
|
|
702
|
+
"version": "0.75.12",
|
|
703
|
+
"resolved": "https://registry.npmjs.org/@openeryc/pi-agent-core/-/pi-agent-core-0.75.12.tgz",
|
|
704
704
|
"license": "MIT",
|
|
705
705
|
"dependencies": {
|
|
706
|
-
"@openeryc/pi-ai": "^0.75.
|
|
706
|
+
"@openeryc/pi-ai": "^0.75.12",
|
|
707
707
|
"ignore": "7.0.5",
|
|
708
708
|
"typebox": "1.1.38",
|
|
709
709
|
"yaml": "2.9.0"
|
|
@@ -713,8 +713,8 @@
|
|
|
713
713
|
}
|
|
714
714
|
},
|
|
715
715
|
"node_modules/@openeryc/pi-ai": {
|
|
716
|
-
"version": "0.75.
|
|
717
|
-
"resolved": "https://registry.npmjs.org/@openeryc/pi-ai/-/pi-ai-0.75.
|
|
716
|
+
"version": "0.75.12",
|
|
717
|
+
"resolved": "https://registry.npmjs.org/@openeryc/pi-ai/-/pi-ai-0.75.12.tgz",
|
|
718
718
|
"license": "MIT",
|
|
719
719
|
"dependencies": {
|
|
720
720
|
"@anthropic-ai/sdk": "0.91.1",
|
|
@@ -735,8 +735,8 @@
|
|
|
735
735
|
}
|
|
736
736
|
},
|
|
737
737
|
"node_modules/@openeryc/pi-tui": {
|
|
738
|
-
"version": "0.75.
|
|
739
|
-
"resolved": "https://registry.npmjs.org/@openeryc/pi-tui/-/pi-tui-0.75.
|
|
738
|
+
"version": "0.75.12",
|
|
739
|
+
"resolved": "https://registry.npmjs.org/@openeryc/pi-tui/-/pi-tui-0.75.12.tgz",
|
|
740
740
|
"license": "MIT",
|
|
741
741
|
"dependencies": {
|
|
742
742
|
"get-east-asian-width": "1.6.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openeryc/pi-coding-agent",
|
|
3
|
-
"version": "0.75.
|
|
3
|
+
"version": "0.75.12",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"piConfig": {
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"prepublishOnly": "npm run clean && npm run build && npm run shrinkwrap"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@openeryc/pi-agent-core": "^0.75.
|
|
43
|
-
"@openeryc/pi-ai": "^0.75.
|
|
44
|
-
"@openeryc/pi-tui": "^0.75.
|
|
42
|
+
"@openeryc/pi-agent-core": "^0.75.12",
|
|
43
|
+
"@openeryc/pi-ai": "^0.75.12",
|
|
44
|
+
"@openeryc/pi-tui": "^0.75.12",
|
|
45
45
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
46
46
|
"chalk": "5.6.2",
|
|
47
47
|
"cross-spawn": "7.0.6",
|