playingpack 0.5.0 → 0.5.2

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.
Files changed (2) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{program as C}from"commander";import mt from"open";import et from"fastify";import tt from"@fastify/cors";import nt from"@fastify/websocket";import{fastifyTRPCPlugin as ot}from"@trpc/server/adapters/fastify";import st from"get-port";import{createHash as ve}from"crypto";function M(t){if(t==null)return null;if(Array.isArray(t))return t.map(M);if(typeof t=="object"){let e=t,o={},n=Object.keys(e).filter(s=>!["stream","request_id","timestamp"].includes(s)).sort();for(let s of n)o[s]=M(e[s]);return o}return t}function v(t){let e=M(t),o=JSON.stringify(e);return ve("sha256").update(o).digest("hex")}var R=class{sessions=new Map;settings;listeners=new Set;point1Resolvers=new Map;point2Resolvers=new Map;constructor(e){this.settings={cache:"read-write",intervene:!0,...e}}createSession(e,o){let n=o,s=typeof n?.model=="string"?n.model:"unknown",a=Array.isArray(n?.messages)?n.messages:[],i=n?.stream!==!1,c={id:e,state:this.settings.intervene?"pending":"processing",timestamp:new Date().toISOString(),request:{model:s,messages:a,stream:i},cacheKey:v(o),cacheHit:!1};return this.sessions.set(e,c),this.emit({type:"request_update",session:c}),c}getSession(e){return this.sessions.get(e)}getAllSessions(){return Array.from(this.sessions.values())}updateState(e,o){let n=this.sessions.get(e);n&&(n.state=o,this.emit({type:"request_update",session:n}))}setProcessing(e){this.updateState(e,"processing")}setReviewing(e){this.updateState(e,"reviewing")}setCacheHit(e,o){let n=this.sessions.get(e);n&&(n.cacheHit=o,this.emit({type:"request_update",session:n}))}setResponse(e,o,n,s=[]){let a=this.sessions.get(e);a&&(a.response={status:o,content:n,toolCalls:s},this.emit({type:"request_update",session:a}))}addToolCall(e,o){let n=this.sessions.get(e);n&&(n.response||(n.response={status:200,content:"",toolCalls:[]}),n.response.toolCalls.push(o),this.emit({type:"request_update",session:n}))}appendContent(e,o){let n=this.sessions.get(e);n&&(n.response||(n.response={status:200,content:"",toolCalls:[]}),n.response.content+=o)}complete(e){let o=this.sessions.get(e);o&&(o.state="complete",o.completedAt=new Date().toISOString(),this.emit({type:"request_update",session:o}))}error(e,o){let n=this.sessions.get(e);n&&(n.state="complete",n.error=o,n.completedAt=new Date().toISOString(),this.emit({type:"request_update",session:n}))}shouldIntervene(){return this.settings.intervene}async waitForPoint1(e){if(!this.sessions.get(e))throw new Error(`Session ${e} not found`);return new Promise(n=>{this.point1Resolvers.set(e,{resolve:n})})}async waitForPoint2(e){if(!this.sessions.get(e))throw new Error(`Session ${e} not found`);return this.updateState(e,"reviewing"),new Promise(n=>{this.point2Resolvers.set(e,{resolve:n})})}resolvePoint1(e,o){let n=this.point1Resolvers.get(e);return n?(this.point1Resolvers.delete(e),this.updateState(e,"processing"),n.resolve(o),!0):!1}resolvePoint2(e,o){let n=this.point2Resolvers.get(e);return n?(this.point2Resolvers.delete(e),n.resolve(o),!0):!1}getSettings(){return{...this.settings}}updateSettings(e){this.settings={...this.settings,...e}}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}emit(e){for(let o of this.listeners)try{o(e)}catch{}}cleanup(){let e=Array.from(this.sessions.entries());if(e.length>100){let o=e.filter(([n,s])=>s.state==="complete").slice(0,e.length-100);for(let[n]of o)this.sessions.delete(n)}}removeSession(e){this.sessions.delete(e),this.point1Resolvers.delete(e),this.point2Resolvers.delete(e)}},S=null;function J(t){return S=new R(t),S}function f(){return S||(S=new R),S}function W(t){return{sessionManager:f(),req:t?.req,res:t?.res}}import{initTRPC as Re}from"@trpc/server";import{z as w}from"zod";import{createRequire as xe}from"module";import{z as r}from"zod";var G=r.enum(["off","read","read-write"]),A=r.object({cache:G.optional(),intervene:r.boolean().optional(),upstream:r.string().url().optional(),port:r.number().int().min(1).max(65535).optional(),host:r.string().optional(),cachePath:r.string().optional(),logPath:r.string().optional(),headless:r.boolean().optional()}),we=r.object({cache:G,intervene:r.boolean()}),z=r.object({settings:we.partial()}),Pt=r.object({model:r.string(),messages:r.array(r.object({role:r.enum(["system","user","assistant","tool"]),content:r.union([r.string(),r.null(),r.array(r.any())]).optional(),name:r.string().optional(),tool_calls:r.array(r.any()).optional(),tool_call_id:r.string().optional()})),temperature:r.number().optional(),top_p:r.number().optional(),n:r.number().optional(),stream:r.boolean().optional(),stop:r.union([r.string(),r.array(r.string())]).optional(),max_tokens:r.number().optional(),presence_penalty:r.number().optional(),frequency_penalty:r.number().optional(),logit_bias:r.record(r.number()).optional(),user:r.string().optional(),tools:r.array(r.object({type:r.literal("function"),function:r.object({name:r.string(),description:r.string().optional(),parameters:r.any().optional()})})).optional(),tool_choice:r.union([r.literal("none"),r.literal("auto"),r.literal("required"),r.object({type:r.literal("function"),function:r.object({name:r.string()})})]).optional(),response_format:r.object({type:r.enum(["text","json_object"])}).optional(),seed:r.number().optional()}).passthrough(),Se=r.object({data:r.string(),delay:r.number()}),Rt=r.object({hash:r.string(),timestamp:r.string(),request:r.object({model:r.string(),messages:r.array(r.unknown())}),response:r.object({status:r.number(),body:r.unknown().optional(),chunks:r.array(Se).optional()})}),j=r.discriminatedUnion("action",[r.object({action:r.literal("llm")}),r.object({action:r.literal("cache")}),r.object({action:r.literal("mock"),content:r.string()})]),T=r.discriminatedUnion("action",[r.object({action:r.literal("return")}),r.object({action:r.literal("modify"),content:r.string()})]),Ce=r.object({type:r.literal("point1_action"),requestId:r.string(),action:j}),Pe=r.object({type:r.literal("point2_action"),requestId:r.string(),action:T}),B=r.discriminatedUnion("type",[Ce,Pe]);var _e=xe(import.meta.url),Ee=_e("../../package.json"),b=Re.context().create(),K=b.router({getSessions:b.procedure.query(({ctx:t})=>({sessions:t.sessionManager.getAllSessions()})),getSession:b.procedure.input(w.object({id:w.string()})).query(({ctx:t,input:e})=>({session:t.sessionManager.getSession(e.id)||null})),getSettings:b.procedure.query(({ctx:t})=>({settings:t.sessionManager.getSettings(),version:Ee.version})),updateSettings:b.procedure.input(z).mutation(({ctx:t,input:e})=>(t.sessionManager.updateSettings(e.settings),{settings:t.sessionManager.getSettings()})),point1Action:b.procedure.input(w.object({requestId:w.string(),action:j})).mutation(({ctx:t,input:e})=>({success:t.sessionManager.resolvePoint1(e.requestId,e.action)})),point2Action:b.procedure.input(w.object({requestId:w.string(),action:T})).mutation(({ctx:t,input:e})=>({success:t.sessionManager.resolvePoint2(e.requestId,e.action)})),health:b.procedure.query(()=>({status:"ok",timestamp:new Date().toISOString()}))});import{createParser as Me}from"eventsource-parser";var I=class{callbacks;toolCalls=new Map;accumulatedContent="";parser;constructor(e={}){this.callbacks=e,this.parser=Me(o=>{o.type==="event"&&this.handleEvent(o.data)})}feed(e){this.parser.feed(e)}getContent(){return this.accumulatedContent}getToolCalls(){return Array.from(this.toolCalls.values())}hasToolCalls(){return this.toolCalls.size>0}getAssembledMessage(){let e=this.getToolCalls();return e.length>0?{role:"assistant",content:null,tool_calls:e.map(o=>({id:o.id,type:"function",function:{name:o.name,arguments:o.arguments}}))}:{role:"assistant",content:this.accumulatedContent||null}}reset(){this.toolCalls.clear(),this.accumulatedContent="",this.parser.reset()}handleEvent(e){if(e==="[DONE]"){this.callbacks.onDone?.();return}try{let o=JSON.parse(e);for(let n of o.choices){let s=n.delta;if(s.content&&(this.accumulatedContent+=s.content,this.callbacks.onContent?.(s.content)),s.tool_calls)for(let a of s.tool_calls){let i=this.toolCalls.get(a.index);if(i)a.function?.arguments&&(i.arguments+=a.function.arguments,this.callbacks.onToolCallUpdate?.(a.index,a.function.arguments));else{let c={index:a.index,id:a.id||"",name:a.function?.name||"",arguments:a.function?.arguments||""};this.toolCalls.set(a.index,c),this.callbacks.onToolCall?.(c)}}}}catch(o){this.callbacks.onError?.(o instanceof Error?o:new Error(String(o)))}}};function O(t){return new I(t)}var Ae="https://api.openai.com";function V(t){return!t||t.length<8?"****":`${t.substring(0,4)}...${t.substring(t.length-4)}`}function je(t,e=!0){let o=new Headers,n=["authorization","content-type","accept","openai-organization","openai-project","user-agent"];for(let s of n){let a=t[s];if(a){let i=Array.isArray(a)?a[0]:a;i&&o.set(s,i)}}return e?o.set("accept","text/event-stream"):o.set("accept","application/json"),o}async function q(t){let o=`${t.upstreamUrl||Ae}${t.path}`,n=typeof t.body=="object"&&t.body!==null&&"stream"in t.body&&typeof t.body.stream=="boolean"?t.body.stream:!0,s=je(t.headers,n),a=await fetch(o,{method:t.method,headers:s,body:JSON.stringify(t.body)});return{status:a.status,headers:a.headers,body:a.body,ok:a.ok}}async function*Z(t){let e=t.getReader(),o=new TextDecoder;try{for(;;){let{done:s,value:a}=await e.read();if(s)break;yield o.decode(a,{stream:!0})}let n=o.decode();n&&(yield n)}finally{e.releaseLock()}}import{mkdir as Te,writeFile as Ie,readFile as Oe,access as qe}from"fs/promises";import{dirname as Fe,join as N}from"path";var U=".playingpack/cache";async function Q(t,e=U){let o=v(t),n=N(e,`${o}.json`);try{return await qe(n),!0}catch{return!1}}async function Ne(t,e=U){let o=v(t),n=N(e,`${o}.json`);try{let s=await Oe(n,"utf-8");return JSON.parse(s)}catch{return null}}var x=class{cachePath;chunks=[];lastChunkTime=0;requestBody;model="unknown";hash="";constructor(e=U){this.cachePath=e}start(e){if(this.requestBody=e,this.chunks=[],this.lastChunkTime=Date.now(),this.hash=v(e),typeof e=="object"&&e!==null){let o=e;typeof o.model=="string"&&(this.model=o.model)}}recordChunk(e){let o=Date.now(),n=this.chunks.length===0?0:o-this.lastChunkTime;this.chunks.push({data:e,delay:n}),this.lastChunkTime=o}async save(e=200){let o={hash:this.hash,timestamp:new Date().toISOString(),request:{model:this.model,messages:this.requestBody?.messages??[]},response:{status:e,chunks:this.chunks}},n=this.getCachePath();return await Te(Fe(n),{recursive:!0}),await Ie(n,JSON.stringify(o,null,2),"utf-8"),n}getCachePath(){return N(this.cachePath,`${this.hash}.json`)}getHash(){return this.hash}getChunkCount(){return this.chunks.length}},F=class{cached;aborted=!1;constructor(e){this.cached=e}getStatus(){return this.cached.response.status}getHash(){return this.cached.hash}abort(){this.aborted=!0}async*replay(){this.aborted=!1;let e=this.cached.response.chunks??[];for(let o of e){if(this.aborted||(o.delay>0&&await this.delay(o.delay),this.aborted))break;yield o.data}}async*replayFast(){let e=this.cached.response.chunks??[];for(let o of e){if(this.aborted)break;yield o.data}}delay(e){return new Promise(o=>setTimeout(o,e))}};async function X(t,e){let o=await Ne(t,e);return o?new F(o):null}function $(){return`chatcmpl-mock-${Date.now()}`}function te(t,e=4){let o=[];for(let n=0;n<t.length;n+=e)o.push(t.slice(n,n+e));return o}function y(t){return`data: ${t}
2
+ import{program as C}from"commander";import mt from"open";import et from"fastify";import tt from"@fastify/cors";import nt from"@fastify/websocket";import{fastifyTRPCPlugin as ot}from"@trpc/server/adapters/fastify";import st from"get-port";import{createHash as ve}from"crypto";function M(t){if(t==null)return null;if(Array.isArray(t))return t.map(M);if(typeof t=="object"){let e=t,o={},n=Object.keys(e).filter(s=>!["stream","request_id","timestamp"].includes(s)).sort();for(let s of n)o[s]=M(e[s]);return o}return t}function v(t){let e=M(t),o=JSON.stringify(e);return ve("sha256").update(o).digest("hex")}var R=class{sessions=new Map;settings;listeners=new Set;point1Resolvers=new Map;point2Resolvers=new Map;constructor(e){this.settings={cache:"read-write",intervene:!0,...e}}createSession(e,o){let n=o,s=typeof n?.model=="string"?n.model:"unknown",a=Array.isArray(n?.messages)?n.messages:[],i=n?.stream!==!1,c={id:e,state:this.settings.intervene?"pending":"processing",timestamp:new Date().toISOString(),request:{model:s,messages:a,stream:i},cacheKey:v(o),cacheHit:!1};return this.sessions.set(e,c),this.emit({type:"request_update",session:c}),c}getSession(e){return this.sessions.get(e)}getAllSessions(){return Array.from(this.sessions.values())}updateState(e,o){let n=this.sessions.get(e);n&&(n.state=o,this.emit({type:"request_update",session:n}))}setProcessing(e){this.updateState(e,"processing")}setReviewing(e){this.updateState(e,"reviewing")}setCacheHit(e,o){let n=this.sessions.get(e);n&&(n.cacheHit=o,this.emit({type:"request_update",session:n}))}setResponse(e,o,n,s=[]){let a=this.sessions.get(e);a&&(a.response={status:o,content:n,toolCalls:s},this.emit({type:"request_update",session:a}))}addToolCall(e,o){let n=this.sessions.get(e);n&&(n.response||(n.response={status:200,content:"",toolCalls:[]}),n.response.toolCalls.push(o),this.emit({type:"request_update",session:n}))}appendContent(e,o){let n=this.sessions.get(e);n&&(n.response||(n.response={status:200,content:"",toolCalls:[]}),n.response.content+=o)}complete(e){let o=this.sessions.get(e);o&&(o.state="complete",o.completedAt=new Date().toISOString(),this.emit({type:"request_update",session:o}))}error(e,o){let n=this.sessions.get(e);n&&(n.state="complete",n.error=o,n.completedAt=new Date().toISOString(),this.emit({type:"request_update",session:n}))}shouldIntervene(){return this.settings.intervene}async waitForPoint1(e){if(!this.sessions.get(e))throw new Error(`Session ${e} not found`);return new Promise(n=>{this.point1Resolvers.set(e,{resolve:n})})}async waitForPoint2(e){if(!this.sessions.get(e))throw new Error(`Session ${e} not found`);return this.updateState(e,"reviewing"),new Promise(n=>{this.point2Resolvers.set(e,{resolve:n})})}resolvePoint1(e,o){let n=this.point1Resolvers.get(e);return n?(this.point1Resolvers.delete(e),this.updateState(e,"processing"),n.resolve(o),!0):!1}resolvePoint2(e,o){let n=this.point2Resolvers.get(e);return n?(this.point2Resolvers.delete(e),n.resolve(o),!0):!1}getSettings(){return{...this.settings}}updateSettings(e){this.settings={...this.settings,...e}}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}emit(e){for(let o of this.listeners)try{o(e)}catch{}}cleanup(){let e=Array.from(this.sessions.entries());if(e.length>100){let o=e.filter(([n,s])=>s.state==="complete").slice(0,e.length-100);for(let[n]of o)this.sessions.delete(n)}}removeSession(e){this.sessions.delete(e),this.point1Resolvers.delete(e),this.point2Resolvers.delete(e)}},S=null;function J(t){return S=new R(t),S}function f(){return S||(S=new R),S}function W(t){return{sessionManager:f(),req:t?.req,res:t?.res}}import{initTRPC as Re}from"@trpc/server";import{z as w}from"zod";import{createRequire as xe}from"module";import{z as r}from"zod";var G=r.enum(["off","read","read-write"]),A=r.object({cache:G.optional(),intervene:r.boolean().optional(),upstream:r.string().url().optional(),port:r.number().int().min(1).max(65535).optional(),host:r.string().optional(),cachePath:r.string().optional(),logPath:r.string().optional(),headless:r.boolean().optional()}),we=r.object({cache:G,intervene:r.boolean()}),z=r.object({settings:we.partial()}),Pt=r.object({model:r.string(),messages:r.array(r.object({role:r.enum(["system","user","assistant","tool"]),content:r.union([r.string(),r.null(),r.array(r.any())]).optional(),name:r.string().optional(),tool_calls:r.array(r.any()).optional(),tool_call_id:r.string().optional()})),temperature:r.number().optional(),top_p:r.number().optional(),n:r.number().optional(),stream:r.boolean().optional(),stop:r.union([r.string(),r.array(r.string())]).optional(),max_tokens:r.number().optional(),presence_penalty:r.number().optional(),frequency_penalty:r.number().optional(),logit_bias:r.record(r.number()).optional(),user:r.string().optional(),tools:r.array(r.object({type:r.literal("function"),function:r.object({name:r.string(),description:r.string().optional(),parameters:r.any().optional()})})).optional(),tool_choice:r.union([r.literal("none"),r.literal("auto"),r.literal("required"),r.object({type:r.literal("function"),function:r.object({name:r.string()})})]).optional(),response_format:r.object({type:r.enum(["text","json_object"])}).optional(),seed:r.number().optional()}).passthrough(),Se=r.object({data:r.string(),delay:r.number()}),Rt=r.object({hash:r.string(),timestamp:r.string(),request:r.object({model:r.string(),messages:r.array(r.unknown())}),response:r.object({status:r.number(),body:r.unknown().optional(),chunks:r.array(Se).optional()})}),j=r.discriminatedUnion("action",[r.object({action:r.literal("llm")}),r.object({action:r.literal("cache")}),r.object({action:r.literal("mock"),content:r.string()})]),T=r.discriminatedUnion("action",[r.object({action:r.literal("return")}),r.object({action:r.literal("modify"),content:r.string()})]),Ce=r.object({type:r.literal("point1_action"),requestId:r.string(),action:j}),Pe=r.object({type:r.literal("point2_action"),requestId:r.string(),action:T}),B=r.discriminatedUnion("type",[Ce,Pe]);var _e=xe(import.meta.url),Ee=_e("../package.json"),b=Re.context().create(),K=b.router({getSessions:b.procedure.query(({ctx:t})=>({sessions:t.sessionManager.getAllSessions()})),getSession:b.procedure.input(w.object({id:w.string()})).query(({ctx:t,input:e})=>({session:t.sessionManager.getSession(e.id)||null})),getSettings:b.procedure.query(({ctx:t})=>({settings:t.sessionManager.getSettings(),version:Ee.version})),updateSettings:b.procedure.input(z).mutation(({ctx:t,input:e})=>(t.sessionManager.updateSettings(e.settings),{settings:t.sessionManager.getSettings()})),point1Action:b.procedure.input(w.object({requestId:w.string(),action:j})).mutation(({ctx:t,input:e})=>({success:t.sessionManager.resolvePoint1(e.requestId,e.action)})),point2Action:b.procedure.input(w.object({requestId:w.string(),action:T})).mutation(({ctx:t,input:e})=>({success:t.sessionManager.resolvePoint2(e.requestId,e.action)})),health:b.procedure.query(()=>({status:"ok",timestamp:new Date().toISOString()}))});import{createParser as Me}from"eventsource-parser";var I=class{callbacks;toolCalls=new Map;accumulatedContent="";parser;constructor(e={}){this.callbacks=e,this.parser=Me(o=>{o.type==="event"&&this.handleEvent(o.data)})}feed(e){this.parser.feed(e)}getContent(){return this.accumulatedContent}getToolCalls(){return Array.from(this.toolCalls.values())}hasToolCalls(){return this.toolCalls.size>0}getAssembledMessage(){let e=this.getToolCalls();return e.length>0?{role:"assistant",content:null,tool_calls:e.map(o=>({id:o.id,type:"function",function:{name:o.name,arguments:o.arguments}}))}:{role:"assistant",content:this.accumulatedContent||null}}reset(){this.toolCalls.clear(),this.accumulatedContent="",this.parser.reset()}handleEvent(e){if(e==="[DONE]"){this.callbacks.onDone?.();return}try{let o=JSON.parse(e);for(let n of o.choices){let s=n.delta;if(s.content&&(this.accumulatedContent+=s.content,this.callbacks.onContent?.(s.content)),s.tool_calls)for(let a of s.tool_calls){let i=this.toolCalls.get(a.index);if(i)a.function?.arguments&&(i.arguments+=a.function.arguments,this.callbacks.onToolCallUpdate?.(a.index,a.function.arguments));else{let c={index:a.index,id:a.id||"",name:a.function?.name||"",arguments:a.function?.arguments||""};this.toolCalls.set(a.index,c),this.callbacks.onToolCall?.(c)}}}}catch(o){this.callbacks.onError?.(o instanceof Error?o:new Error(String(o)))}}};function O(t){return new I(t)}var Ae="https://api.openai.com";function V(t){return!t||t.length<8?"****":`${t.substring(0,4)}...${t.substring(t.length-4)}`}function je(t,e=!0){let o=new Headers,n=["authorization","content-type","accept","openai-organization","openai-project","user-agent"];for(let s of n){let a=t[s];if(a){let i=Array.isArray(a)?a[0]:a;i&&o.set(s,i)}}return e?o.set("accept","text/event-stream"):o.set("accept","application/json"),o}async function q(t){let o=`${t.upstreamUrl||Ae}${t.path}`,n=typeof t.body=="object"&&t.body!==null&&"stream"in t.body&&typeof t.body.stream=="boolean"?t.body.stream:!0,s=je(t.headers,n),a=await fetch(o,{method:t.method,headers:s,body:JSON.stringify(t.body)});return{status:a.status,headers:a.headers,body:a.body,ok:a.ok}}async function*Z(t){let e=t.getReader(),o=new TextDecoder;try{for(;;){let{done:s,value:a}=await e.read();if(s)break;yield o.decode(a,{stream:!0})}let n=o.decode();n&&(yield n)}finally{e.releaseLock()}}import{mkdir as Te,writeFile as Ie,readFile as Oe,access as qe}from"fs/promises";import{dirname as Fe,join as N}from"path";var U=".playingpack/cache";async function Q(t,e=U){let o=v(t),n=N(e,`${o}.json`);try{return await qe(n),!0}catch{return!1}}async function Ne(t,e=U){let o=v(t),n=N(e,`${o}.json`);try{let s=await Oe(n,"utf-8");return JSON.parse(s)}catch{return null}}var x=class{cachePath;chunks=[];lastChunkTime=0;requestBody;model="unknown";hash="";constructor(e=U){this.cachePath=e}start(e){if(this.requestBody=e,this.chunks=[],this.lastChunkTime=Date.now(),this.hash=v(e),typeof e=="object"&&e!==null){let o=e;typeof o.model=="string"&&(this.model=o.model)}}recordChunk(e){let o=Date.now(),n=this.chunks.length===0?0:o-this.lastChunkTime;this.chunks.push({data:e,delay:n}),this.lastChunkTime=o}async save(e=200){let o={hash:this.hash,timestamp:new Date().toISOString(),request:{model:this.model,messages:this.requestBody?.messages??[]},response:{status:e,chunks:this.chunks}},n=this.getCachePath();return await Te(Fe(n),{recursive:!0}),await Ie(n,JSON.stringify(o,null,2),"utf-8"),n}getCachePath(){return N(this.cachePath,`${this.hash}.json`)}getHash(){return this.hash}getChunkCount(){return this.chunks.length}},F=class{cached;aborted=!1;constructor(e){this.cached=e}getStatus(){return this.cached.response.status}getHash(){return this.cached.hash}abort(){this.aborted=!0}async*replay(){this.aborted=!1;let e=this.cached.response.chunks??[];for(let o of e){if(this.aborted||(o.delay>0&&await this.delay(o.delay),this.aborted))break;yield o.data}}async*replayFast(){let e=this.cached.response.chunks??[];for(let o of e){if(this.aborted)break;yield o.data}}delay(e){return new Promise(o=>setTimeout(o,e))}};async function X(t,e){let o=await Ne(t,e);return o?new F(o):null}function $(){return`chatcmpl-mock-${Date.now()}`}function te(t,e=4){let o=[];for(let n=0;n<t.length;n+=e)o.push(t.slice(n,n+e));return o}function y(t){return`data: ${t}
3
3
 
4
4
  `}function Y(t,e,o,n=null){let s={id:t,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:e,choices:[{index:0,delta:o!==null?{content:o}:{},finish_reason:n}]};return JSON.stringify(s)}function ee(t,e,o,n,s,a=!1,i=null){let c={index:0};a?(c.id=o,c.type="function",c.function={name:n,arguments:s}):c.function={arguments:s};let u={id:t,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:e,choices:[{index:0,delta:{tool_calls:[c]},finish_reason:i}]};return JSON.stringify(u)}async function*ne(t,e={}){let{model:o="gpt-4",delayMs:n=20}=e,s=$(),a=te(t),i={id:s,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:o,choices:[{index:0,delta:{role:"assistant",content:""},finish_reason:null}]};yield y(JSON.stringify(i));for(let c of a)n>0&&await ie(n),yield y(Y(s,o,c));yield y(Y(s,o,null,"stop")),yield y("[DONE]")}async function*oe(t,e,o={}){let{model:n="gpt-4",delayMs:s=10}=o,a=$(),i=`call_mock_${Date.now()}`,c=te(e,10),u={id:a,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:n,choices:[{index:0,delta:{role:"assistant",content:null},finish_reason:null}]};yield y(JSON.stringify(u)),yield y(ee(a,n,i,t,c[0]||"",!0));for(let g=1;g<c.length;g++)s>0&&await ie(s),yield y(ee(a,n,i,t,c[g]||""));let p={id:a,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:n,choices:[{index:0,delta:{},finish_reason:"tool_calls"}]};yield y(JSON.stringify(p)),yield y("[DONE]")}function se(t,e="invalid_request_error",o=null){return JSON.stringify({error:{message:t,type:e,param:null,code:o}})}function re(t,e,o="gpt-4"){let n=$(),s=Math.floor(Date.now()/1e3),a={role:"assistant",content:e?null:t};e&&e.length>0&&(a.tool_calls=e);let i=e&&e.length>0?"tool_calls":"stop";return{id:n,object:"chat.completion",created:s,model:o,choices:[{index:0,message:a,finish_reason:i}],usage:{prompt_tokens:0,completion_tokens:0,total_tokens:0}}}function ae(t){let e=t.trim();if(e.startsWith("ERROR:"))return{type:"error",content:e.slice(6).trim()};try{let o=JSON.parse(e);if(o&&typeof o=="object"&&"function"in o)return{type:"tool_call",functionName:o.function,content:JSON.stringify(o.arguments||{})}}catch{}return{type:"text",content:e}}function ie(t){return new Promise(e=>setTimeout(e,t))}import{appendFile as Ue,mkdir as $e}from"fs/promises";import{join as Le}from"path";var L=null,D=null;async function ce(t){L=t,await $e(L,{recursive:!0});let e=new Date().toISOString().split("T")[0];D=Le(L,`server-${e}.log`)}function De(t){let e=`[${t.timestamp}] [${t.level.toUpperCase()}] ${t.message}`;return t.data!==void 0?`${e} ${JSON.stringify(t.data)}
5
5
  `:`${e}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playingpack",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Chrome DevTools for AI Agents - Local reverse proxy and debugger for LLM API calls",
5
5
  "type": "module",
6
6
  "bin": {