@stacksjs/ai 0.70.72 → 0.70.74

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.
@@ -24,6 +24,11 @@ export declare function prompt(text: string, options?: ChatCompletionOptions & {
24
24
  export declare function estimateTokens(text: string): number;
25
25
  export declare const anthropicDriver: { create: typeof createAnthropicDriver };
26
26
  export declare const anthropic: {
27
+ configure: typeof configure;
28
+ chat: typeof chat;
29
+ streamChat: typeof streamChat;
30
+ prompt: typeof prompt;
31
+ estimateTokens: typeof estimateTokens;
27
32
  createDriver: unknown
28
33
  };
29
34
  export declare interface AnthropicDriverConfig extends AIDriverConfig {
@@ -21,7 +21,11 @@ export declare function getLastSessionId(): string | undefined;
21
21
  export declare function clearSession(): void;
22
22
  // Export the driver creator and utilities
23
23
  export declare const claudeAgentSDK: {
24
- createDriver: unknown
24
+ createDriver: unknown;
25
+ processStreaming: typeof processStreaming;
26
+ resumeSession: typeof resumeSession;
27
+ getLastSessionId: typeof getLastSessionId;
28
+ clearSession: typeof clearSession
25
29
  };
26
30
  export declare interface ClaudeAgentSDKConfig extends AIDriverConfig {
27
31
  maxTurns?: number
@@ -73,6 +73,16 @@ export declare function showModel(_name: string): Promise<{
73
73
  export declare function isRunning(): Promise<boolean>;
74
74
  export declare const ollamaDriver: { create: typeof createOllamaDriver };
75
75
  export declare const ollama: {
76
+ configure: typeof configure;
77
+ chat: typeof chat;
78
+ streamChat: typeof streamChat;
79
+ generate: typeof generate;
80
+ embed: typeof embed;
81
+ listModels: typeof listModels;
82
+ pullModel: typeof pullModel;
83
+ deleteModel: typeof deleteModel;
84
+ showModel: typeof showModel;
85
+ isRunning: typeof isRunning;
76
86
  createDriver: unknown
77
87
  };
78
88
  export declare interface OllamaDriverConfig extends AIDriverConfig {
@@ -47,6 +47,13 @@ export declare function textToSpeech(input: string, options?: {
47
47
  }): Promise<ArrayBuffer>;
48
48
  export declare const openaiDriver: { create: typeof createOpenAIDriver };
49
49
  export declare const openai: {
50
+ configure: typeof configure;
51
+ chat: typeof chat;
52
+ streamChat: typeof streamChat;
53
+ embed: typeof embed;
54
+ generateImage: typeof generateImage;
55
+ transcribe: typeof transcribe;
56
+ textToSpeech: typeof textToSpeech;
50
57
  createDriver: unknown
51
58
  };
52
59
  export declare interface OpenAIDriverConfig extends AIDriverConfig {
package/dist/index.js CHANGED
@@ -1,16 +1,16 @@
1
1
  // @bun
2
2
  var M=import.meta.require;var IQ={maxRetries:3,baseDelayMs:500,maxDelayMs:30000};async function S(Q,Z,Y={}){let H={...IQ,...Y},X;for(let G=0;G<=H.maxRetries;G++){if(X=await fetch(Q,Z),X.ok)return X;if(X.status<500&&X.status!==429)return X;if(G===H.maxRetries)return X;let V=TQ(X.headers.get("Retry-After"))??DQ(G,H),$=Math.min(V,H.maxDelayMs);try{await X.text().catch(()=>{})}catch{}await new Promise((W)=>setTimeout(W,$))}return X}function TQ(Q){if(!Q)return null;let Z=Number.parseInt(Q,10);if(Number.isFinite(Z)&&String(Z)===Q.trim())return Math.max(0,Z*1000);let Y=Date.parse(Q);if(Number.isFinite(Y))return Math.max(0,Y-Date.now());return null}function DQ(Q,Z){let Y=Math.min(Z.baseDelayMs*2**Q,Z.maxDelayMs);return Math.random()*Y}var P=[];function CQ(Q){return P.push(Q),()=>{let Z=P.indexOf(Q);if(Z>=0)P.splice(Z,1)}}function xQ(){P.length=0}function h(Q){for(let Z of P)try{let Y=Z(Q);if(Y&&typeof Y.then==="function")Y.catch((H)=>{console.error("[ai/usage] reporter rejected:",H)})}catch(Y){console.error("[ai/usage] reporter threw:",Y)}}function SQ(){return P}function PQ(Q){if(Q.type==="text")return{type:"text",text:Q.text??""};if(Q.type==="image_url")return{type:"image_url",image_url:Q.image_url};if(Q.type==="image"&&Q.source){if(Q.source.type==="base64")return{type:"image_url",image_url:{url:`data:${Q.source.media_type};base64,${Q.source.data}`}}}return Q}function kQ(Q){if(Q.type==="text")return{type:"text",text:Q.text??""};if(Q.type==="image"&&Q.source)return{type:"image",source:Q.source};if(Q.type==="image_url"&&Q.image_url){let Z=Q.image_url.url,Y=Z.match(/^data:([^;]+);base64,(.+)$/);if(Y)return{type:"image",source:{type:"base64",media_type:Y[1],data:Y[2]}};return{type:"image",source:{type:"url",url:Z}}}return Q}function I(Q,Z){return Q.map((Y)=>{if(typeof Y.content==="string")return Y;let H=Z==="openai"?PQ:kQ;return{role:Y.role,content:Y.content.map(H)}})}function vQ(Q,Z){let Y=[];for(let H of Z)if(H.dataBase64&&H.mediaType)Y.push({type:"image",source:{type:"base64",media_type:H.mediaType,data:H.dataBase64}});else if(H.url)Y.push({type:"image_url",image_url:{url:H.url,detail:H.detail}});return Y.push({type:"text",text:Q}),Y}var o="claude-sonnet-4-20250514",t=4096,e="2023-06-01",p="https://api.anthropic.com/v1",WQ=null;function yQ(Q){WQ=Q}function qQ(Q){let Z={...WQ,...Q};if(!Z.apiKey)Z.apiKey=process.env.ANTHROPIC_API_KEY||"";return Z}function f(Q){let{apiKey:Z,model:Y=o,maxTokens:H=t,anthropicVersion:X=e}=Q;return{name:"Claude API",async process(G,J,V){if(!Z)throw Error("Anthropic API key not set. Configure your API key in settings.");let $=await S(`${p}/messages`,{method:"POST",headers:{"Content-Type":"application/json","x-api-key":Z,"anthropic-version":X},body:JSON.stringify({model:Y,max_tokens:H,system:J,messages:[...V,{role:"user",content:G}]})});if(!$.ok){let q=await $.text();throw Error(`Claude API error: ${q}`)}let W=await $.json();if(!W.content||W.content.length===0)throw Error("Claude API returned empty content");return W.content[0].text},async*stream(G,J,V){if(!Z)throw Error("Anthropic API key not set. Configure your API key in settings.");let $=await fetch(`${p}/messages`,{method:"POST",headers:{"Content-Type":"application/json","x-api-key":Z,"anthropic-version":X},body:JSON.stringify({model:Y,max_tokens:H,system:J,stream:!0,messages:[...V,{role:"user",content:G}]})});if(!$.ok){let w=await $.text();throw Error(`Claude API error: ${w}`)}let W=$.body?.getReader();if(!W)throw Error("No response body");let q=new TextDecoder,z="",B=function*(w){if(w==="[DONE]")return;let O;try{O=JSON.parse(w)}catch{return}if(O.type==="error"){let U=O.error?.message??JSON.stringify(O.error??O);throw Error(`[anthropic/stream] mid-stream error: ${U}`)}if(O.type==="content_block_delta"&&O.delta?.text)yield O.delta.text};while(!0){let{done:w,value:O}=await W.read();if(w)break;z+=q.decode(O,{stream:!0});let U=z.split(`
3
- `);z=U.pop()||"";for(let j of U)if(j.startsWith("data: "))yield*B(j.slice(6))}if(z.startsWith("data: "))yield*B(z.slice(6))}}}async function zQ(Q,Z={}){let Y=qQ(),{model:H=o,maxTokens:X=t,temperature:G,topP:J,stop:V,system:$,tools:W,toolChoice:q,responseFormat:z}=Z,B=I(Q,"anthropic"),w=Date.now(),O={model:H,max_tokens:X,temperature:G,top_p:J,stop_sequences:V?Array.isArray(V)?V:[V]:void 0,system:$,messages:B};if(W&&W.length>0){if(O.tools=W.map((R)=>({name:R.name,description:R.description,input_schema:R.parameters??{type:"object",properties:{}}})),q!==void 0)O.tool_choice=bQ(q)}if(z&&z.type!=="text"){let R=hQ(z),x=Array.isArray(O.tools)?O.tools:[];if(O.tools=[...x,R],q===void 0)O.tool_choice={type:"tool",name:R.name}}let U=await fetch(`${p}/messages`,{method:"POST",headers:{"Content-Type":"application/json","x-api-key":Y.apiKey,"anthropic-version":Y.anthropicVersion||e},body:JSON.stringify(O)});if(!U.ok){let R=await U.text();throw Error(`Claude API error: ${R}`)}let j=await U.json();if(!j.content||j.content.length===0)throw Error("Claude API returned empty content");let K=j.content.find((R)=>R.type==="tool_use")??j.content.find((R)=>R.type==="text")??j.content[0],L={content:K?.type==="tool_use"?JSON.stringify(K.input):K?.text??"",model:j.model,usage:{promptTokens:j.usage?.input_tokens||0,completionTokens:j.usage?.output_tokens||0,totalTokens:(j.usage?.input_tokens||0)+(j.usage?.output_tokens||0)},finishReason:j.stop_reason};return h({provider:"anthropic",model:j.model,promptTokens:L.usage.promptTokens,completionTokens:L.usage.completionTokens,totalTokens:L.usage.totalTokens,durationMs:Date.now()-w,timestamp:Date.now()}),L}function bQ(Q){if(Q==="auto")return{type:"auto"};if(Q==="required")return{type:"any"};if(Q==="none")return{type:"auto",disable_parallel_tool_use:!0};return{type:"tool",name:Q.name}}function hQ(Q){if(Q.type==="json_schema")return{name:Q.json_schema.name,description:`Returns the result as JSON matching the '${Q.json_schema.name}' schema.`,input_schema:Q.json_schema.schema};return{name:"structured_output",description:"Returns the result as a JSON object.",input_schema:{type:"object",additionalProperties:!0}}}async function*fQ(Q,Z={}){let Y=qQ(),{model:H=o,maxTokens:X=t,temperature:G,topP:J,stop:V,system:$}=Z,W=await fetch(`${p}/messages`,{method:"POST",headers:{"Content-Type":"application/json","x-api-key":Y.apiKey,"anthropic-version":Y.anthropicVersion||e},body:JSON.stringify({model:H,max_tokens:X,temperature:G,top_p:J,stop_sequences:V?Array.isArray(V)?V:[V]:void 0,system:$,stream:!0,messages:I(Q,"anthropic")})});if(!W.ok){let w=await W.text();throw Error(`Claude API error: ${w}`)}let q=W.body?.getReader();if(!q)throw Error("No response body");let z=new TextDecoder,B="";while(!0){let{done:w,value:O}=await q.read();if(w)break;B+=z.decode(O,{stream:!0});let U=B.split(`
4
- `);B=U.pop()||"";for(let j of U)if(j.startsWith("data: ")){let K=j.slice(6);if(K==="[DONE]")continue;try{let N=JSON.parse(K);if(N.type==="content_block_delta"&&N.delta?.text)yield N.delta.text}catch{}}}}async function gQ(Q,Z={}){return(await zQ([{role:"user",content:Q}],Z)).content}function jQ(Q){return Math.ceil(Q.length/4)}var uQ={create:f},cQ={configure:yQ,chat:zQ,streamChat:fQ,prompt:gQ,estimateTokens:jQ,createDriver:f};var QQ="gpt-4o",ZQ=4096,BQ="text-embedding-3-small",T="https://api.openai.com/v1",OQ=null;function dQ(Q){OQ=Q}function k(Q){let Z={...OQ,...Q};if(!Z.apiKey)Z.apiKey=process.env.OPENAI_API_KEY||"";return Z}function g(Q){let{apiKey:Z,model:Y=QQ,maxTokens:H=ZQ,baseUrl:X=T,embeddingModel:G=BQ}=Q;return{name:"OpenAI",async process(J,V,$){if(!Z)throw Error("OpenAI API key not set. Configure your API key in settings.");let W=await S(`${X}/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Z}`},body:JSON.stringify({model:Y,max_tokens:H,messages:[{role:"system",content:V},...$,{role:"user",content:J}]})});if(!W.ok){let z=await W.text();throw Error(`OpenAI API error: ${z}`)}let q=await W.json();if(!q.choices||q.choices.length===0)throw Error("OpenAI API returned empty choices");return q.choices[0].message.content},async*stream(J,V,$){if(!Z)throw Error("OpenAI API key not set. Configure your API key in settings.");let W=await fetch(`${X}/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Z}`},body:JSON.stringify({model:Y,max_tokens:H,stream:!0,messages:[{role:"system",content:V},...$,{role:"user",content:J}]})});if(!W.ok){let O=await W.text();throw Error(`OpenAI API error: ${O}`)}let q=W.body?.getReader();if(!q)throw Error("No response body");let z=new TextDecoder,B="",w=function*(O){if(O==="[DONE]")return;let U;try{U=JSON.parse(O)}catch{return}if(U?.error){let K=U.error.message||JSON.stringify(U.error);throw Error(`[openai/stream] mid-stream error: ${K}`)}let j=U.choices?.[0]?.delta?.content;if(j)yield j};while(!0){let{done:O,value:U}=await q.read();if(O)break;B+=z.decode(U,{stream:!0});let j=B.split(`
3
+ `);z=U.pop()||"";for(let j of U)if(j.startsWith("data: "))yield*B(j.slice(6))}if(z.startsWith("data: "))yield*B(z.slice(6))}}}async function zQ(Q,Z={}){let Y=qQ(),{model:H=o,maxTokens:X=t,temperature:G,topP:J,stop:V,system:$,tools:W,toolChoice:q,responseFormat:z}=Z,B=I(Q,"anthropic"),w=Date.now(),O={model:H,max_tokens:X,temperature:G,top_p:J,stop_sequences:V?Array.isArray(V)?V:[V]:void 0,system:$,messages:B};if(W&&W.length>0){if(O.tools=W.map((R)=>({name:R.name,description:R.description,input_schema:R.parameters??{type:"object",properties:{}}})),q!==void 0)O.tool_choice=bQ(q)}if(z&&z.type!=="text"){let R=hQ(z),x=Array.isArray(O.tools)?O.tools:[];if(O.tools=[...x,R],q===void 0)O.tool_choice={type:"tool",name:R.name}}let U=await fetch(`${p}/messages`,{method:"POST",headers:{"Content-Type":"application/json","x-api-key":Y.apiKey,"anthropic-version":Y.anthropicVersion||e},body:JSON.stringify(O)});if(!U.ok){let R=await U.text();throw Error(`Claude API error: ${R}`)}let j=await U.json();if(!j.content||j.content.length===0)throw Error("Claude API returned empty content");let K=j.content.find((R)=>R.type==="tool_use")??j.content.find((R)=>R.type==="text")??j.content[0],N={content:K?.type==="tool_use"?JSON.stringify(K.input):K?.text??"",model:j.model,usage:{promptTokens:j.usage?.input_tokens||0,completionTokens:j.usage?.output_tokens||0,totalTokens:(j.usage?.input_tokens||0)+(j.usage?.output_tokens||0)},finishReason:j.stop_reason};return h({provider:"anthropic",model:j.model,promptTokens:N.usage.promptTokens,completionTokens:N.usage.completionTokens,totalTokens:N.usage.totalTokens,durationMs:Date.now()-w,timestamp:Date.now()}),N}function bQ(Q){if(Q==="auto")return{type:"auto"};if(Q==="required")return{type:"any"};if(Q==="none")return{type:"auto",disable_parallel_tool_use:!0};return{type:"tool",name:Q.name}}function hQ(Q){if(Q.type==="json_schema")return{name:Q.json_schema.name,description:`Returns the result as JSON matching the '${Q.json_schema.name}' schema.`,input_schema:Q.json_schema.schema};return{name:"structured_output",description:"Returns the result as a JSON object.",input_schema:{type:"object",additionalProperties:!0}}}async function*fQ(Q,Z={}){let Y=qQ(),{model:H=o,maxTokens:X=t,temperature:G,topP:J,stop:V,system:$}=Z,W=await fetch(`${p}/messages`,{method:"POST",headers:{"Content-Type":"application/json","x-api-key":Y.apiKey,"anthropic-version":Y.anthropicVersion||e},body:JSON.stringify({model:H,max_tokens:X,temperature:G,top_p:J,stop_sequences:V?Array.isArray(V)?V:[V]:void 0,system:$,stream:!0,messages:I(Q,"anthropic")})});if(!W.ok){let w=await W.text();throw Error(`Claude API error: ${w}`)}let q=W.body?.getReader();if(!q)throw Error("No response body");let z=new TextDecoder,B="";while(!0){let{done:w,value:O}=await q.read();if(w)break;B+=z.decode(O,{stream:!0});let U=B.split(`
4
+ `);B=U.pop()||"";for(let j of U)if(j.startsWith("data: ")){let K=j.slice(6);if(K==="[DONE]")continue;try{let L=JSON.parse(K);if(L.type==="content_block_delta"&&L.delta?.text)yield L.delta.text}catch{}}}}async function gQ(Q,Z={}){return(await zQ([{role:"user",content:Q}],Z)).content}function jQ(Q){return Math.ceil(Q.length/4)}var uQ={create:f},cQ={configure:yQ,chat:zQ,streamChat:fQ,prompt:gQ,estimateTokens:jQ,createDriver:f};var QQ="gpt-4o",ZQ=4096,BQ="text-embedding-3-small",T="https://api.openai.com/v1",OQ=null;function dQ(Q){OQ=Q}function k(Q){let Z={...OQ,...Q};if(!Z.apiKey)Z.apiKey=process.env.OPENAI_API_KEY||"";return Z}function g(Q){let{apiKey:Z,model:Y=QQ,maxTokens:H=ZQ,baseUrl:X=T,embeddingModel:G=BQ}=Q;return{name:"OpenAI",async process(J,V,$){if(!Z)throw Error("OpenAI API key not set. Configure your API key in settings.");let W=await S(`${X}/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Z}`},body:JSON.stringify({model:Y,max_tokens:H,messages:[{role:"system",content:V},...$,{role:"user",content:J}]})});if(!W.ok){let z=await W.text();throw Error(`OpenAI API error: ${z}`)}let q=await W.json();if(!q.choices||q.choices.length===0)throw Error("OpenAI API returned empty choices");return q.choices[0].message.content},async*stream(J,V,$){if(!Z)throw Error("OpenAI API key not set. Configure your API key in settings.");let W=await fetch(`${X}/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Z}`},body:JSON.stringify({model:Y,max_tokens:H,stream:!0,messages:[{role:"system",content:V},...$,{role:"user",content:J}]})});if(!W.ok){let O=await W.text();throw Error(`OpenAI API error: ${O}`)}let q=W.body?.getReader();if(!q)throw Error("No response body");let z=new TextDecoder,B="",w=function*(O){if(O==="[DONE]")return;let U;try{U=JSON.parse(O)}catch{return}if(U?.error){let K=U.error.message||JSON.stringify(U.error);throw Error(`[openai/stream] mid-stream error: ${K}`)}let j=U.choices?.[0]?.delta?.content;if(j)yield j};while(!0){let{done:O,value:U}=await q.read();if(O)break;B+=z.decode(U,{stream:!0});let j=B.split(`
5
5
  `);B=j.pop()||"";for(let K of j)if(K.startsWith("data: "))yield*w(K.slice(6))}if(B.startsWith("data: "))yield*w(B.slice(6))},async embed(J){if(!Z)throw Error("OpenAI API key not set. Configure your API key in settings.");let V=await fetch(`${X}/embeddings`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Z}`},body:JSON.stringify({model:G,input:J})});if(!V.ok){let W=await V.text();throw Error(`OpenAI Embeddings API error: ${W}`)}let $=await V.json();if(Array.isArray(J))return $.data.map((W)=>W.embedding);return $.data[0].embedding}}}async function lQ(Q,Z={}){let Y=k(),{model:H=QQ,maxTokens:X=ZQ,temperature:G,topP:J,stop:V}=Z,$=I(Q,"openai"),W=Date.now(),q=await S(`${Y.baseUrl||T}/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Y.apiKey}`},body:JSON.stringify({model:H,max_tokens:X,temperature:G,top_p:J,stop:V,messages:$})});if(!q.ok){let w=await q.text();throw Error(`OpenAI API error: ${w}`)}let z=await q.json();if(!z.choices||z.choices.length===0)throw Error("OpenAI API returned empty choices");let B={content:z.choices[0].message.content,model:z.model,usage:{promptTokens:z.usage?.prompt_tokens||0,completionTokens:z.usage?.completion_tokens||0,totalTokens:z.usage?.total_tokens||0},finishReason:z.choices[0].finish_reason};return h({provider:"openai",model:z.model,promptTokens:B.usage.promptTokens,completionTokens:B.usage.completionTokens,totalTokens:B.usage.totalTokens,durationMs:Date.now()-W,timestamp:Date.now()}),B}async function*mQ(Q,Z={}){let Y=k(),{model:H=QQ,maxTokens:X=ZQ,temperature:G,topP:J,stop:V}=Z,$=await fetch(`${Y.baseUrl||T}/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Y.apiKey}`},body:JSON.stringify({model:H,max_tokens:X,temperature:G,top_p:J,stop:V,stream:!0,messages:I(Q,"openai")})});if(!$.ok){let B=await $.text();throw Error(`OpenAI API error: ${B}`)}let W=$.body?.getReader();if(!W)throw Error("No response body");let q=new TextDecoder,z="";while(!0){let{done:B,value:w}=await W.read();if(B)break;z+=q.decode(w,{stream:!0});let O=z.split(`
6
- `);z=O.pop()||"";for(let U of O)if(U.startsWith("data: ")){let j=U.slice(6);if(j==="[DONE]")continue;try{let N=JSON.parse(j).choices[0]?.delta?.content;if(N)yield N}catch{}}}}async function pQ(Q,Z=BQ){let Y=k(),H=await fetch(`${Y.baseUrl||T}/embeddings`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Y.apiKey}`},body:JSON.stringify({model:Z,input:Q})});if(!H.ok){let G=await H.text();throw Error(`OpenAI Embeddings API error: ${G}`)}let X=await H.json();if(Array.isArray(Q))return X.data.map((G)=>G.embedding);return X.data[0].embedding}async function iQ(Q,Z={}){let Y=k(),{model:H="dall-e-3",size:X="1024x1024",quality:G="standard",n:J=1,responseFormat:V="url"}=Z,$=await fetch(`${Y.baseUrl||T}/images/generations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Y.apiKey}`},body:JSON.stringify({model:H,prompt:Q,size:X,quality:G,n:J,response_format:V})});if(!$.ok){let q=await $.text();throw Error(`OpenAI Image API error: ${q}`)}return(await $.json()).data}async function aQ(Q,Z={}){let Y=k(),H=new FormData;if(H.append("file",Q),H.append("model",Z.model||"whisper-1"),Z.language)H.append("language",Z.language);if(Z.prompt)H.append("prompt",Z.prompt);if(Z.responseFormat)H.append("response_format",Z.responseFormat);if(Z.temperature!==void 0)H.append("temperature",String(Z.temperature));let X=await fetch(`${Y.baseUrl||T}/audio/transcriptions`,{method:"POST",headers:{Authorization:`Bearer ${Y.apiKey}`},body:H});if(!X.ok){let G=await X.text();throw Error(`OpenAI Whisper API error: ${G}`)}return X.json()}async function nQ(Q,Z={}){let Y=k(),{model:H="tts-1",voice:X="alloy",responseFormat:G="mp3",speed:J=1}=Z,V=await fetch(`${Y.baseUrl||T}/audio/speech`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Y.apiKey}`},body:JSON.stringify({model:H,input:Q,voice:X,response_format:G,speed:J})});if(!V.ok){let $=await V.text();throw Error(`OpenAI TTS API error: ${$}`)}return V.arrayBuffer()}var rQ={create:g},sQ={configure:dQ,chat:lQ,streamChat:mQ,embed:pQ,generateImage:iQ,transcribe:aQ,textToSpeech:nQ,createDriver:g};var u={};function oQ(Q){u={...u,...Q}}function E(Q){return{host:Q?.host||u.host||process.env.OLLAMA_HOST||"http://localhost:11434",model:Q?.model||u.model||process.env.OLLAMA_MODEL||"llama3.2",embeddingModel:Q?.embeddingModel||u.embeddingModel||"nomic-embed-text"}}function c(Q={}){let{host:Z=process.env.OLLAMA_HOST||"http://localhost:11434",model:Y=process.env.OLLAMA_MODEL||"llama3.2",embeddingModel:H="nomic-embed-text"}=Q;return{name:"Ollama",async process(X,G,J){let V=await fetch(`${Z}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:Y,messages:[{role:"system",content:G},...J,{role:"user",content:X}],stream:!1})});if(!V.ok){let W=await V.text();throw Error(`Ollama API error: ${W}`)}return(await V.json()).message.content},async*stream(X,G,J){let V=await fetch(`${Z}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:Y,messages:[{role:"system",content:G},...J,{role:"user",content:X}],stream:!0})});if(!V.ok){let z=await V.text();throw Error(`Ollama API error: ${z}`)}let $=V.body?.getReader();if(!$)throw Error("No response body");let W=new TextDecoder,q="";while(!0){let{done:z,value:B}=await $.read();if(z)break;q+=W.decode(B,{stream:!0});let w=q.split(`
6
+ `);z=O.pop()||"";for(let U of O)if(U.startsWith("data: ")){let j=U.slice(6);if(j==="[DONE]")continue;try{let L=JSON.parse(j).choices[0]?.delta?.content;if(L)yield L}catch{}}}}async function pQ(Q,Z=BQ){let Y=k(),H=await fetch(`${Y.baseUrl||T}/embeddings`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Y.apiKey}`},body:JSON.stringify({model:Z,input:Q})});if(!H.ok){let G=await H.text();throw Error(`OpenAI Embeddings API error: ${G}`)}let X=await H.json();if(Array.isArray(Q))return X.data.map((G)=>G.embedding);return X.data[0].embedding}async function iQ(Q,Z={}){let Y=k(),{model:H="dall-e-3",size:X="1024x1024",quality:G="standard",n:J=1,responseFormat:V="url"}=Z,$=await fetch(`${Y.baseUrl||T}/images/generations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Y.apiKey}`},body:JSON.stringify({model:H,prompt:Q,size:X,quality:G,n:J,response_format:V})});if(!$.ok){let q=await $.text();throw Error(`OpenAI Image API error: ${q}`)}return(await $.json()).data}async function aQ(Q,Z={}){let Y=k(),H=new FormData;if(H.append("file",Q),H.append("model",Z.model||"whisper-1"),Z.language)H.append("language",Z.language);if(Z.prompt)H.append("prompt",Z.prompt);if(Z.responseFormat)H.append("response_format",Z.responseFormat);if(Z.temperature!==void 0)H.append("temperature",String(Z.temperature));let X=await fetch(`${Y.baseUrl||T}/audio/transcriptions`,{method:"POST",headers:{Authorization:`Bearer ${Y.apiKey}`},body:H});if(!X.ok){let G=await X.text();throw Error(`OpenAI Whisper API error: ${G}`)}return X.json()}async function nQ(Q,Z={}){let Y=k(),{model:H="tts-1",voice:X="alloy",responseFormat:G="mp3",speed:J=1}=Z,V=await fetch(`${Y.baseUrl||T}/audio/speech`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Y.apiKey}`},body:JSON.stringify({model:H,input:Q,voice:X,response_format:G,speed:J})});if(!V.ok){let $=await V.text();throw Error(`OpenAI TTS API error: ${$}`)}return V.arrayBuffer()}var rQ={create:g},sQ={configure:dQ,chat:lQ,streamChat:mQ,embed:pQ,generateImage:iQ,transcribe:aQ,textToSpeech:nQ,createDriver:g};var u={};function oQ(Q){u={...u,...Q}}function E(Q){return{host:Q?.host||u.host||process.env.OLLAMA_HOST||"http://localhost:11434",model:Q?.model||u.model||process.env.OLLAMA_MODEL||"llama3.2",embeddingModel:Q?.embeddingModel||u.embeddingModel||"nomic-embed-text"}}function c(Q={}){let{host:Z=process.env.OLLAMA_HOST||"http://localhost:11434",model:Y=process.env.OLLAMA_MODEL||"llama3.2",embeddingModel:H="nomic-embed-text"}=Q;return{name:"Ollama",async process(X,G,J){let V=await fetch(`${Z}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:Y,messages:[{role:"system",content:G},...J,{role:"user",content:X}],stream:!1})});if(!V.ok){let W=await V.text();throw Error(`Ollama API error: ${W}`)}return(await V.json()).message.content},async*stream(X,G,J){let V=await fetch(`${Z}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:Y,messages:[{role:"system",content:G},...J,{role:"user",content:X}],stream:!0})});if(!V.ok){let z=await V.text();throw Error(`Ollama API error: ${z}`)}let $=V.body?.getReader();if(!$)throw Error("No response body");let W=new TextDecoder,q="";while(!0){let{done:z,value:B}=await $.read();if(z)break;q+=W.decode(B,{stream:!0});let w=q.split(`
7
7
  `);q=w.pop()||"";for(let O of w){if(!O.trim())continue;try{let U=JSON.parse(O);if(U.message?.content)yield U.message.content}catch{}}}},async embed(X){let G=Array.isArray(X)?X:[X],J=[];for(let V of G){let $=await fetch(`${Z}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:H,prompt:V})});if(!$.ok){let q=await $.text();throw Error(`Ollama Embeddings API error: ${q}`)}let W=await $.json();J.push(W.embedding)}return Array.isArray(X)?J:J[0]}}}async function tQ(Q,Z={}){let Y=E(),{model:H=Y.model,temperature:X,topP:G,stop:J}=Z,V=await fetch(`${Y.host}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:H,messages:Q,stream:!1,options:{temperature:X,top_p:G,stop:J}})});if(!V.ok){let W=await V.text();throw Error(`Ollama API error: ${W}`)}let $=await V.json();return{content:$.message.content,model:$.model,usage:{promptTokens:$.prompt_eval_count||0,completionTokens:$.eval_count||0,totalTokens:($.prompt_eval_count||0)+($.eval_count||0)},finishReason:$.done_reason||"stop"}}async function*eQ(Q,Z={}){let Y=E(),{model:H=Y.model,temperature:X,topP:G,stop:J}=Z,V=await fetch(`${Y.host}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:H,messages:Q,stream:!0,options:{temperature:X,top_p:G,stop:J}})});if(!V.ok){let z=await V.text();throw Error(`Ollama API error: ${z}`)}let $=V.body?.getReader();if(!$)throw Error("No response body");let W=new TextDecoder,q="";while(!0){let{done:z,value:B}=await $.read();if(z)break;q+=W.decode(B,{stream:!0});let w=q.split(`
8
8
  `);q=w.pop()||"";for(let O of w){if(!O.trim())continue;try{let U=JSON.parse(O);if(U.message?.content)yield U.message.content}catch{}}}}async function QZ(Q,Z={}){let Y=E(),H=await fetch(`${Y.host}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:Z.model||Y.model,prompt:Q,system:Z.system,template:Z.template,context:Z.context,raw:Z.raw,format:Z.format,images:Z.images,stream:!1})});if(!H.ok){let G=await H.text();throw Error(`Ollama API error: ${G}`)}let X=await H.json();return{content:X.response,model:X.model,usage:{promptTokens:X.prompt_eval_count||0,completionTokens:X.eval_count||0,totalTokens:(X.prompt_eval_count||0)+(X.eval_count||0)}}}async function ZZ(Q,Z){let Y=E(),H=Z||Y.embeddingModel,X=Array.isArray(Q)?Q:[Q],G=[];for(let J of X){let V=await fetch(`${Y.host}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:H,prompt:J})});if(!V.ok){let W=await V.text();throw Error(`Ollama Embeddings API error: ${W}`)}let $=await V.json();G.push($.embedding)}return Array.isArray(Q)?G:G[0]}async function YZ(){let Q=E(),Z=await fetch(`${Q.host}/api/tags`,{method:"GET"});if(!Z.ok){let H=await Z.text();throw Error(`Ollama API error: ${H}`)}return(await Z.json()).models}async function HZ(Q,Z){let Y=E(),H=await fetch(`${Y.host}/api/pull`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:Q,stream:!0})});if(!H.ok){let V=await H.text();throw Error(`Ollama API error: ${V}`)}let X=H.body?.getReader();if(!X)return;let G=new TextDecoder,J="";while(!0){let{done:V,value:$}=await X.read();if(V)break;J+=G.decode($,{stream:!0});let W=J.split(`
9
- `);J=W.pop()||"";for(let q of W){if(!q.trim())continue;try{let z=JSON.parse(q);if(Z)Z(z.status,z.completed,z.total)}catch{}}}}async function XZ(Q){let Z=E(),Y=await fetch(`${Z.host}/api/delete`,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:Q})});if(!Y.ok){let H=await Y.text();throw Error(`Ollama API error: ${H}`)}}async function JZ(Q){let Z=E(),Y=await fetch(`${Z.host}/api/show`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:Q})});if(!Y.ok){let H=await Y.text();throw Error(`Ollama API error: ${H}`)}return Y.json()}async function VZ(){let Q=E();try{return(await fetch(`${Q.host}/api/tags`,{method:"GET"})).ok}catch{return!1}}var GZ={create:c},$Z={configure:oQ,chat:tQ,streamChat:eQ,generate:QZ,embed:ZZ,listModels:YZ,pullModel:HZ,deleteModel:XZ,showModel:JZ,isRunning:VZ,createDriver:c};var YQ=null;async function i(){if(!YQ)try{YQ=await import("@anthropic-ai/claude-agent-sdk")}catch{throw Error("Claude Agent SDK not installed. Run: bun add @anthropic-ai/claude-agent-sdk")}return YQ}var A={lastSessionId:void 0},v={maxTurns:25,allowedTools:["Read","Write","Edit","Bash","Glob","Grep"],permissionMode:"bypassPermissions"};function a(Q={}){let{maxTurns:Z=v.maxTurns,cwd:Y,allowedTools:H=v.allowedTools,disallowedTools:X,permissionMode:G=v.permissionMode,customSystemPrompt:J,appendSystemPrompt:V,resumeSessionId:$}=Q;return{name:"Claude Agent SDK",async process(W,q,z){let B=await i(),{query:w}=B,O=q?`${q}
9
+ `);J=W.pop()||"";for(let q of W){if(!q.trim())continue;try{let z=JSON.parse(q);if(Z)Z(z.status??"",z.completed,z.total)}catch{}}}}async function XZ(Q){let Z=E(),Y=await fetch(`${Z.host}/api/delete`,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:Q})});if(!Y.ok){let H=await Y.text();throw Error(`Ollama API error: ${H}`)}}async function JZ(Q){let Z=E(),Y=await fetch(`${Z.host}/api/show`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:Q})});if(!Y.ok){let H=await Y.text();throw Error(`Ollama API error: ${H}`)}return Y.json()}async function VZ(){let Q=E();try{return(await fetch(`${Q.host}/api/tags`,{method:"GET"})).ok}catch{return!1}}var GZ={create:c},$Z={configure:oQ,chat:tQ,streamChat:eQ,generate:QZ,embed:ZZ,listModels:YZ,pullModel:HZ,deleteModel:XZ,showModel:JZ,isRunning:VZ,createDriver:c};var YQ=null;async function i(){if(!YQ)try{YQ=await import("@anthropic-ai/claude-agent-sdk")}catch{throw Error("Claude Agent SDK not installed. Run: bun add @anthropic-ai/claude-agent-sdk")}return YQ}var A={lastSessionId:void 0},v={maxTurns:25,allowedTools:["Read","Write","Edit","Bash","Glob","Grep"],permissionMode:"bypassPermissions"};function a(Q={}){let{maxTurns:Z=v.maxTurns,cwd:Y,allowedTools:H=v.allowedTools,disallowedTools:X,permissionMode:G=v.permissionMode,customSystemPrompt:J,appendSystemPrompt:V,resumeSessionId:$}=Q;return{name:"Claude Agent SDK",async process(W,q,z){let B=await i(),{query:w}=B,O=q?`${q}
10
10
 
11
- User request: ${W}`:W,U={allowedTools:H,permissionMode:G,maxTurns:Z};if(X)U.disallowedTools=X;if(J)U.customSystemPrompt=J;if(V)U.appendSystemPrompt=V;if(Y)U.cwd=Y;if($||A.lastSessionId)U.resume=$||A.lastSessionId;let j="";try{for await(let K of w({prompt:O,options:U})){if(K.type==="system"&&K.subtype==="init")A.lastSessionId=K.session_id;if("result"in K&&typeof K.result==="string")j=K.result}return j||"No response from Claude Agent SDK"}catch(K){let N=K;if(N.message.includes("ANTHROPIC_API_KEY"))throw Error("Claude Agent SDK requires ANTHROPIC_API_KEY environment variable or Claude Code authentication.");throw Error(`Claude Agent SDK error: ${N.message}`)}},async*stream(W,q,z){let B=await i(),{query:w}=B,O=q?`${q}
11
+ User request: ${W}`:W,U={allowedTools:H,permissionMode:G,maxTurns:Z};if(X)U.disallowedTools=X;if(J)U.customSystemPrompt=J;if(V)U.appendSystemPrompt=V;if(Y)U.cwd=Y;if($||A.lastSessionId)U.resume=$||A.lastSessionId;let j="";try{for await(let K of w({prompt:O,options:U})){if(K.type==="system"&&K.subtype==="init")A.lastSessionId=K.session_id;if("result"in K&&typeof K.result==="string")j=K.result}return j||"No response from Claude Agent SDK"}catch(K){let L=K;if(L.message.includes("ANTHROPIC_API_KEY"))throw Error("Claude Agent SDK requires ANTHROPIC_API_KEY environment variable or Claude Code authentication.");throw Error(`Claude Agent SDK error: ${L.message}`)}},async*stream(W,q,z){let B=await i(),{query:w}=B,O=q?`${q}
12
12
 
13
- User request: ${W}`:W,U={allowedTools:H,permissionMode:G,maxTurns:Z};if(X)U.disallowedTools=X;if(J)U.customSystemPrompt=J;if(V)U.appendSystemPrompt=V;if(Y)U.cwd=Y;if($||A.lastSessionId)U.resume=$||A.lastSessionId;try{for await(let j of w({prompt:O,options:U})){if(j.type==="system"&&j.subtype==="init")A.lastSessionId=j.session_id;if(j.type==="assistant"){let K=j;if(K.message?.content){for(let N of K.message.content)if(N.type==="text"&&N.text)yield N.text}}if("result"in j&&typeof j.result==="string")yield j.result}}catch(j){let K=j;if(K.message.includes("ANTHROPIC_API_KEY"))throw Error("Claude Agent SDK requires ANTHROPIC_API_KEY environment variable or Claude Code authentication.");throw Error(`Claude Agent SDK error: ${K.message}`)}}}}async function WZ(Q,Z,Y={}){let H=await i(),{query:X}=H,{maxTurns:G=v.maxTurns,allowedTools:J=v.allowedTools,disallowedTools:V,permissionMode:$=v.permissionMode,customSystemPrompt:W,appendSystemPrompt:q,resumeSessionId:z}=Y,B={allowedTools:J,permissionMode:$,maxTurns:G};if(V)B.disallowedTools=V;if(W)B.customSystemPrompt=W;if(q)B.appendSystemPrompt=q;if(Z)B.cwd=Z;if(z||A.lastSessionId)B.resume=z||A.lastSessionId;let w=new TextEncoder,O="",U,j=new Promise((N)=>{U=N});return{stream:new ReadableStream({async start(N){try{for await(let L of X({prompt:Q,options:B})){if(L.type==="system"&&L.subtype==="init")A.lastSessionId=L.session_id;if(L.type==="assistant"){let R=L;if(R.message?.content){for(let x of R.message.content)if(x.type==="text"&&x.text)O+=x.text,N.enqueue(w.encode(x.text))}}if("result"in L&&typeof L.result==="string"){if(!O)O=L.result,N.enqueue(w.encode(L.result))}}U(O),N.close()}catch(L){U(O),N.error(L)}}}),fullResponse:j}}async function qZ(Q,Z){let Y=await i(),{query:H}=Y,X="";for await(let G of H({prompt:Z,options:{resume:Q,permissionMode:"bypassPermissions"}}))if("result"in G&&typeof G.result==="string")X=G.result;return X||"No response from resumed session"}function UQ(){return A.lastSessionId}function KQ(){A.lastSessionId=void 0}var zZ={createDriver:a,processStreaming:WZ,resumeSession:qZ,getLastSessionId:UQ,clearSession:KQ};var wQ=0;function jZ(Q,Z){switch(Q){case"Read":{let Y=Z.file_path||"";return`
13
+ User request: ${W}`:W,U={allowedTools:H,permissionMode:G,maxTurns:Z};if(X)U.disallowedTools=X;if(J)U.customSystemPrompt=J;if(V)U.appendSystemPrompt=V;if(Y)U.cwd=Y;if($||A.lastSessionId)U.resume=$||A.lastSessionId;try{for await(let j of w({prompt:O,options:U})){if(j.type==="system"&&j.subtype==="init")A.lastSessionId=j.session_id;if(j.type==="assistant"){let K=j;if(K.message?.content){for(let L of K.message.content)if(L.type==="text"&&L.text)yield L.text}}if("result"in j&&typeof j.result==="string")yield j.result}}catch(j){let K=j;if(K.message.includes("ANTHROPIC_API_KEY"))throw Error("Claude Agent SDK requires ANTHROPIC_API_KEY environment variable or Claude Code authentication.");throw Error(`Claude Agent SDK error: ${K.message}`)}}}}async function WZ(Q,Z,Y={}){let H=await i(),{query:X}=H,{maxTurns:G=v.maxTurns,allowedTools:J=v.allowedTools,disallowedTools:V,permissionMode:$=v.permissionMode,customSystemPrompt:W,appendSystemPrompt:q,resumeSessionId:z}=Y,B={allowedTools:J,permissionMode:$,maxTurns:G};if(V)B.disallowedTools=V;if(W)B.customSystemPrompt=W;if(q)B.appendSystemPrompt=q;if(Z)B.cwd=Z;if(z||A.lastSessionId)B.resume=z||A.lastSessionId;let w=new TextEncoder,O="",U,j=new Promise((L)=>{U=L});return{stream:new ReadableStream({async start(L){try{for await(let N of X({prompt:Q,options:B})){if(N.type==="system"&&N.subtype==="init")A.lastSessionId=N.session_id;if(N.type==="assistant"){let R=N;if(R.message?.content){for(let x of R.message.content)if(x.type==="text"&&x.text)O+=x.text,L.enqueue(w.encode(x.text))}}if("result"in N&&typeof N.result==="string"){if(!O)O=N.result,L.enqueue(w.encode(N.result))}}U(O),L.close()}catch(N){U(O),L.error(N)}}}),fullResponse:j}}async function qZ(Q,Z){let Y=await i(),{query:H}=Y,X="";for await(let G of H({prompt:Z,options:{resume:Q,permissionMode:"bypassPermissions"}}))if("result"in G&&typeof G.result==="string")X=G.result;return X||"No response from resumed session"}function UQ(){return A.lastSessionId}function KQ(){A.lastSessionId=void 0}var zZ={createDriver:a,processStreaming:WZ,resumeSession:qZ,getLastSessionId:UQ,clearSession:KQ};var wQ=0;function jZ(Q,Z){switch(Q){case"Read":{let Y=Z.file_path||"";return`
14
14
  \uD83D\uDCD6 Reading: ${Y.split("/").pop()||Y}
15
15
  `}case"Glob":return`
16
16
  \uD83D\uDD0D Searching files: ${Z.pattern||""}
@@ -33,8 +33,8 @@ User request: ${Z}`:Z,V=Q.cwd||process.cwd();try{return(await X`cd ${V} && claud
33
33
  ${G}
34
34
 
35
35
  User request: ${X}`:X).replace(/'/g,"'\\''"),q=H?`-i ${H}`:"",z=`${Y}@${Z}`;try{return(await V`ssh ${q} ${z} "claude --print '${W}'"`.quiet()).text().trim()}catch(B){throw Error(`EC2 Claude CLI error: ${B.message}. Make sure SSH is configured and claude CLI is installed on EC2.`)}}}}async function UZ(Q,Z){let{spawn:Y}=awaitPromise.resolve(globalThis.Bun),H=Y(["claude","--print","--verbose","--output-format","stream-json","--dangerously-skip-permissions",Q],{cwd:Z,stdout:"pipe",stderr:"pipe"}),X="",G=new TextDecoder,J=new TextEncoder,V=new ReadableStream({async start(W){try{let q=H.stdout.getReader(),z="",B="",w=await q.read();while(!w.done){z+=G.decode(w.value,{stream:!0});let O=z.split(`
36
- `);z=O.pop()||"";for(let U of O){if(!U.trim())continue;try{let j=JSON.parse(U),K="";if(j.type==="system"&&j.subtype==="init")wQ++;else if(j.type==="content_block_start"&&j.content_block?.text)K=j.content_block.text;else if(j.type==="content_block_delta"&&j.delta?.text)K=j.delta.text;else if(j.type==="assistant"&&j.message?.content){for(let N of j.message.content)if(N.type==="text"&&N.text)K+=N.text;else if(N.type==="tool_use"&&N.name)K+=jZ(N.name,N.input||{})}else if(j.type==="user"&&j.message?.content){for(let N of j.message.content)if(N.type==="tool_result")K+=` \u2713 done
37
- `}else if(j.type==="result"&&j.result){X=j.result;let N=j.result.substring(0,Math.min(50,j.result.length));if(!B.includes(N))K=j.result}if(K){if(j.type==="content_block_delta")B+=K,W.enqueue(J.encode(K));else if(!B.endsWith(K))B+=K,W.enqueue(J.encode(K))}}catch{if(!B.includes(U))B+=U,X+=U,W.enqueue(J.encode(U))}}w=await q.read()}if(z.trim())try{let O=JSON.parse(z);if(O.result&&!X)X=O.result}catch{if(!B.includes(z))X+=z,W.enqueue(J.encode(z))}await H.exited,W.close()}catch(q){W.error(q)}}}),$=(async()=>{return await H.exited,X.trim()})();return{stream:V,fullResponse:$}}function KZ(){wQ=0}var n={createLocal:BZ,createEC2:OZ,processStreaming:UZ,resetPromptCount:KZ};import{existsSync as C,mkdirSync as LQ,readFileSync as NQ,writeFileSync as wZ}from"fs";import{homedir as RQ}from"os";import{dirname as NZ,join as y}from"path";var b={workDir:y(RQ(),"Code",".buddy-repos"),commitMessage:"chore: wip",ollamaHost:process.env.OLLAMA_HOST||"http://localhost:11434",ollamaModel:process.env.OLLAMA_MODEL||"llama3.2"},D={anthropic:process.env.ANTHROPIC_API_KEY,openai:process.env.OPENAI_API_KEY,claudeCliHost:process.env.BUDDY_EC2_HOST},_={repo:null,conversationHistory:[],currentDriver:"claude-cli-local",github:null};if(!C(b.workDir))LQ(b.workDir,{recursive:!0});var F={getState:()=>_,setRepo:(Q)=>{_.repo=Q},setCurrentDriver:(Q)=>{_.currentDriver=Q},setGitHub:(Q)=>{_.github=Q},addToHistory:(Q)=>{_.conversationHistory.push(Q)},clearHistory:()=>{_.conversationHistory=[]}};function LZ(Q){return`You are Buddy, an AI code assistant that helps users modify codebases through voice commands.
36
+ `);z=O.pop()||"";for(let U of O){if(!U.trim())continue;try{let j=JSON.parse(U),K="";if(j.type==="system"&&j.subtype==="init")wQ++;else if(j.type==="content_block_start"&&j.content_block?.text)K=j.content_block.text;else if(j.type==="content_block_delta"&&j.delta?.text)K=j.delta.text;else if(j.type==="assistant"&&j.message?.content){for(let L of j.message.content)if(L.type==="text"&&L.text)K+=L.text;else if(L.type==="tool_use"&&L.name)K+=jZ(L.name,L.input||{})}else if(j.type==="user"&&j.message?.content){for(let L of j.message.content)if(L.type==="tool_result")K+=` \u2713 done
37
+ `}else if(j.type==="result"&&j.result){X=j.result;let L=j.result.substring(0,Math.min(50,j.result.length));if(!B.includes(L))K=j.result}if(K){if(j.type==="content_block_delta")B+=K,W.enqueue(J.encode(K));else if(!B.endsWith(K))B+=K,W.enqueue(J.encode(K))}}catch{if(!B.includes(U))B+=U,X+=U,W.enqueue(J.encode(U))}}w=await q.read()}if(z.trim())try{let O=JSON.parse(z);if(O.result&&!X)X=O.result}catch{if(!B.includes(z))X+=z,W.enqueue(J.encode(z))}await H.exited,W.close()}catch(q){W.error(q)}}}),$=(async()=>{return await H.exited,X.trim()})();return{stream:V,fullResponse:$}}function KZ(){wQ=0}var n={createLocal:BZ,createEC2:OZ,processStreaming:UZ,resetPromptCount:KZ};import{existsSync as C,mkdirSync as NQ,readFileSync as LQ,writeFileSync as wZ}from"fs";import{homedir as RQ}from"os";import{dirname as LZ,join as y}from"path";var b={workDir:y(RQ(),"Code",".buddy-repos"),commitMessage:"chore: wip",ollamaHost:process.env.OLLAMA_HOST||"http://localhost:11434",ollamaModel:process.env.OLLAMA_MODEL||"llama3.2"},D={anthropic:process.env.ANTHROPIC_API_KEY,openai:process.env.OPENAI_API_KEY,claudeCliHost:process.env.BUDDY_EC2_HOST},_={repo:null,conversationHistory:[],currentDriver:"claude-cli-local",github:null};if(!C(b.workDir))NQ(b.workDir,{recursive:!0});var F={getState:()=>_,setRepo:(Q)=>{_.repo=Q},setCurrentDriver:(Q)=>{_.currentDriver=Q},setGitHub:(Q)=>{_.github=Q},addToHistory:(Q)=>{_.conversationHistory.push(Q)},clearHistory:()=>{_.conversationHistory=[]}};function NZ(Q){return`You are Buddy, an AI code assistant that helps users modify codebases through voice commands.
38
38
 
39
39
  ${_.repo?`You are working on the repository: ${_.repo.name}
40
40
  Branch: ${_.repo.branch}
@@ -105,7 +105,7 @@ export function main() {
105
105
  }
106
106
  \`\`\`
107
107
 
108
- Files modified: 1`}}}function FZ(Q){let Z=F.getState();switch(Q){case"claude-cli-local":return n.createLocal({cwd:Z.repo?.path});case"claude-cli-ec2":return n.createEC2({cwd:Z.repo?.path,ec2Host:D.claudeCliHost});case"claude":case"anthropic":if(!D.anthropic)throw Error("Anthropic API key not set. Configure your API key in settings.");return f({apiKey:D.anthropic});case"openai":if(!D.openai)throw Error("OpenAI API key not set. Configure your API key in settings.");return g({apiKey:D.openai});case"ollama":return c({host:b.ollamaHost,model:b.ollamaModel});case"claude-sdk":case"claude-agent-sdk":return a({cwd:Z.repo?.path,maxTurns:25,permissionMode:"bypassPermissions"});case"mock":return RZ();default:throw Error(`Unknown driver: ${Q}. Available: claude-cli-local, claude-cli-ec2, claude, claude-sdk, openai, ollama, mock`)}}function v6(){return["claude-cli-local","claude-cli-ec2","claude","claude-sdk","openai","ollama","mock"]}async function MZ(Q){let{$:Z}=awaitPromise.resolve(globalThis.Bun),H=(await Z`cd ${Q} && find . -type f -not -path "*/node_modules/*" -not -path "*/.git/*" -not -name "*.lock" | head -50`.quiet()).text().trim(),X="",G=y(Q,"README.md");if(C(G))X=NQ(G,"utf-8").slice(0,2000);let J="",V=y(Q,"package.json");if(C(V))J=NQ(V,"utf-8");return`
108
+ Files modified: 1`}}}function FZ(Q){let Z=F.getState();switch(Q){case"claude-cli-local":return n.createLocal({cwd:Z.repo?.path});case"claude-cli-ec2":return n.createEC2({cwd:Z.repo?.path,ec2Host:D.claudeCliHost});case"claude":case"anthropic":if(!D.anthropic)throw Error("Anthropic API key not set. Configure your API key in settings.");return f({apiKey:D.anthropic});case"openai":if(!D.openai)throw Error("OpenAI API key not set. Configure your API key in settings.");return g({apiKey:D.openai});case"ollama":return c({host:b.ollamaHost,model:b.ollamaModel});case"claude-sdk":case"claude-agent-sdk":return a({cwd:Z.repo?.path,maxTurns:25,permissionMode:"bypassPermissions"});case"mock":return RZ();default:throw Error(`Unknown driver: ${Q}. Available: claude-cli-local, claude-cli-ec2, claude, claude-sdk, openai, ollama, mock`)}}function v6(){return["claude-cli-local","claude-cli-ec2","claude","claude-sdk","openai","ollama","mock"]}async function MZ(Q){let{$:Z}=awaitPromise.resolve(globalThis.Bun),H=(await Z`cd ${Q} && find . -type f -not -path "*/node_modules/*" -not -path "*/.git/*" -not -name "*.lock" | head -50`.quiet()).text().trim(),X="",G=y(Q,"README.md");if(C(G))X=LQ(G,"utf-8").slice(0,2000);let J="",V=y(Q,"package.json");if(C(V))J=LQ(V,"utf-8");return`
109
109
  Repository Structure:
110
110
  ${H}
111
111
 
@@ -115,7 +115,7 @@ ${X}
115
115
  ${J?`package.json:
116
116
  ${J}
117
117
  `:""}
118
- `.trim()}async function y6(Q){let{$:Z}=awaitPromise.resolve(globalThis.Bun),Y,H;if(Q.includes("github.com")||Q.startsWith("git@"))if(H=Q.split("/").pop()?.replace(".git","")||"repo",Y=y(b.workDir,H),C(Y))await Z`cd ${Y} && git pull --rebase`.quiet();else await Z`git clone ${Q} ${Y}`.quiet();else{if(Y=Q.startsWith("~")?Q.replace("~",RQ()):Q,!C(Y))throw Error(`Local path does not exist: ${Y}`);if(!C(y(Y,".git")))throw Error(`Not a git repository: ${Y}`);H=Y.split("/").pop()||"repo"}let G=(await Z`cd ${Y} && git branch --show-current`.quiet()).text().trim(),V=(await Z`cd ${Y} && git status --porcelain`.quiet()).text().trim().length>0,W=(await Z`cd ${Y} && git log -1 --format="%h %s"`.quiet()).text().trim(),q={path:Y,name:H,branch:G,hasChanges:V,lastCommit:W};return F.setRepo(q),F.clearHistory(),q}async function b6(Q){let Z=F.getState();if(!Z.repo)throw Error("No repository opened");let Y=[],H=/FILE:\s*([^\n]+)\n```\w*\n([\s\S]*?)```/g;for(let X of Q.matchAll(H)){let G=X[1].trim(),J=X[2],V=y(Z.repo.path,G),$=NZ(V);if(!C($))LQ($,{recursive:!0});wZ(V,J),Y.push(G)}if(Y.length>0&&Z.repo)Z.repo.hasChanges=!0;return Y}async function AZ(){let Q=F.getState();if(!Q.repo||!Q.github)return;let{$:Z}=awaitPromise.resolve(globalThis.Bun),{name:Y,email:H}=Q.github;await Z`cd ${Q.repo.path} && git config user.name ${Y}`.quiet(),await Z`cd ${Q.repo.path} && git config user.email ${H}`.quiet()}async function h6(){let Q=F.getState();if(!Q.repo)throw Error("No repository opened");let{$:Z}=awaitPromise.resolve(globalThis.Bun);if(Q.github)await AZ();await Z`cd ${Q.repo.path} && git add -A`.quiet(),await Z`cd ${Q.repo.path} && git commit -m ${b.commitMessage}`.quiet();let H=(await Z`cd ${Q.repo.path} && git rev-parse --short HEAD`.quiet()).text().trim();return Q.repo.hasChanges=!1,Q.repo.lastCommit=H,H}async function f6(){let Q=F.getState();if(!Q.repo)throw Error("No repository opened");let{$:Z}=awaitPromise.resolve(globalThis.Bun);await Z`cd ${Q.repo.path} && git push`.quiet()}async function g6(Q,Z){let Y=F.getState();if(!Y.repo)throw Error("No repository opened");let H=Z||Y.currentDriver,X=FZ(H);if(Z)F.setCurrentDriver(Z);let G=await MZ(Y.repo.path),J=LZ(G),V=await X.process(Q,J,Y.conversationHistory);return F.addToHistory({role:"user",content:Q}),F.addToHistory({role:"assistant",content:V}),V}async function u6(Q,Z,Y){let H=F.getState();if(!H.repo)throw Error("No repository opened");let X=Z||H.currentDriver,G=["claude-cli-local","claude-sdk"];if(!G.includes(X))throw Error(`Streaming only supported for ${G.join(", ")} drivers. Current: ${X}`);if(Z)F.setCurrentDriver(Z);let J=Q;if(Y&&Y.length>0){let $=`## Previous Conversation
118
+ `.trim()}async function y6(Q){let{$:Z}=awaitPromise.resolve(globalThis.Bun),Y,H;if(Q.includes("github.com")||Q.startsWith("git@"))if(H=Q.split("/").pop()?.replace(".git","")||"repo",Y=y(b.workDir,H),C(Y))await Z`cd ${Y} && git pull --rebase`.quiet();else await Z`git clone ${Q} ${Y}`.quiet();else{if(Y=Q.startsWith("~")?Q.replace("~",RQ()):Q,!C(Y))throw Error(`Local path does not exist: ${Y}`);if(!C(y(Y,".git")))throw Error(`Not a git repository: ${Y}`);H=Y.split("/").pop()||"repo"}let G=(await Z`cd ${Y} && git branch --show-current`.quiet()).text().trim(),V=(await Z`cd ${Y} && git status --porcelain`.quiet()).text().trim().length>0,W=(await Z`cd ${Y} && git log -1 --format="%h %s"`.quiet()).text().trim(),q={path:Y,name:H,branch:G,hasChanges:V,lastCommit:W};return F.setRepo(q),F.clearHistory(),q}async function b6(Q){let Z=F.getState();if(!Z.repo)throw Error("No repository opened");let Y=[],H=/FILE:\s*([^\n]+)\n```\w*\n([\s\S]*?)```/g;for(let X of Q.matchAll(H)){let G=X[1].trim(),J=X[2],V=y(Z.repo.path,G),$=LZ(V);if(!C($))NQ($,{recursive:!0});wZ(V,J),Y.push(G)}if(Y.length>0&&Z.repo)Z.repo.hasChanges=!0;return Y}async function AZ(){let Q=F.getState();if(!Q.repo||!Q.github)return;let{$:Z}=awaitPromise.resolve(globalThis.Bun),{name:Y,email:H}=Q.github;await Z`cd ${Q.repo.path} && git config user.name ${Y}`.quiet(),await Z`cd ${Q.repo.path} && git config user.email ${H}`.quiet()}async function h6(){let Q=F.getState();if(!Q.repo)throw Error("No repository opened");let{$:Z}=awaitPromise.resolve(globalThis.Bun);if(Q.github)await AZ();await Z`cd ${Q.repo.path} && git add -A`.quiet(),await Z`cd ${Q.repo.path} && git commit -m ${b.commitMessage}`.quiet();let H=(await Z`cd ${Q.repo.path} && git rev-parse --short HEAD`.quiet()).text().trim();return Q.repo.hasChanges=!1,Q.repo.lastCommit=H,H}async function f6(){let Q=F.getState();if(!Q.repo)throw Error("No repository opened");let{$:Z}=awaitPromise.resolve(globalThis.Bun);await Z`cd ${Q.repo.path} && git push`.quiet()}async function g6(Q,Z){let Y=F.getState();if(!Y.repo)throw Error("No repository opened");let H=Z||Y.currentDriver,X=FZ(H);if(Z)F.setCurrentDriver(Z);let G=await MZ(Y.repo.path),J=NZ(G),V=await X.process(Q,J,Y.conversationHistory);return F.addToHistory({role:"user",content:Q}),F.addToHistory({role:"assistant",content:V}),V}async function u6(Q,Z,Y){let H=F.getState();if(!H.repo)throw Error("No repository opened");let X=Z||H.currentDriver,G=["claude-cli-local","claude-sdk"];if(!G.includes(X))throw Error(`Streaming only supported for ${G.join(", ")} drivers. Current: ${X}`);if(Z)F.setCurrentDriver(Z);let J=Q;if(Y&&Y.length>0){let $=`## Previous Conversation
119
119
  Here is our conversation so far:
120
120
 
121
121
  `;for(let W of Y){let q=W.role==="user"?"User":"Assistant";$+=`**${q}:** ${W.content}
@@ -126,7 +126,7 @@ Here is our conversation so far:
126
126
  `,J=$+Q}let V=await n.processStreaming(J,H.repo.path);return V.fullResponse.then(($)=>{F.addToHistory({role:"user",content:Q}),F.addToHistory({role:"assistant",content:$})}),V}async function c6(Q,Z){if(!D.anthropic)throw Error("Anthropic API key not set. Configure your API key in settings.");let Y=[];if(Z&&Z.length>0)for(let W of Z)Y.push({role:W.role,content:W.content});Y.push({role:"user",content:Q});let H=`You are a helpful AI assistant. Answer questions naturally and conversationally.
127
127
  You can discuss any topic - technology, science, philosophy, everyday questions, or anything else the user asks about.
128
128
  Be concise but thorough. If the user asks about coding or their project specifically, help with that too.`,X=new TextEncoder,G="",J,V=new Promise((W)=>{J=W});return{stream:new ReadableStream({async start(W){try{let q=await fetch("https://api.anthropic.com/v1/messages",{method:"POST",headers:{"Content-Type":"application/json","x-api-key":D.anthropic,"anthropic-version":"2023-06-01"},body:JSON.stringify({model:"claude-sonnet-4-20250514",max_tokens:4096,system:H,stream:!0,messages:Y})});if(!q.ok){let O=await q.text();throw Error(`Claude API error: ${O}`)}let z=q.body?.getReader();if(!z)throw Error("No response body");let B=new TextDecoder,w="";while(!0){let{done:O,value:U}=await z.read();if(O)break;w+=B.decode(U,{stream:!0});let j=w.split(`
129
- `);w=j.pop()||"";for(let K of j)if(K.startsWith("data: ")){let N=K.slice(6);if(N==="[DONE]")continue;try{let L=JSON.parse(N);if(L.type==="content_block_delta"&&L.delta?.text){let R=L.delta.text;G+=R,W.enqueue(X.encode(R))}}catch{}}}F.addToHistory({role:"user",content:Q}),F.addToHistory({role:"assistant",content:G}),J(G),W.close()}catch(q){J(G),W.error(q)}}}),fullResponse:V}}import _Z from"process";var r=null;async function FQ(){if(r)return r;let Q=await import("@stacksjs/ts-cloud/aws");if(!Q?.BedrockRuntimeClient)throw Error("@stacksjs/ts-cloud/aws does not export BedrockRuntimeClient \u2014 rebuild ts-cloud or remove the AI dependency.");return r=new Q.BedrockRuntimeClient(_Z.env.REGION||"us-east-1"),r}async function HQ(Q){return(await FQ()).invokeModel(Q)}async function m6(Q){return(await FQ()).invokeModelWithResponseStream(Q)}var EZ="amazon.titan-text-express-v1";function MQ(Q){if(Q)return Q;return globalThis.config?.ai?.bedrock?.model||process.env.BEDROCK_MODEL_ID||EZ}async function a6(Q,Z={}){let{maxTokenCount:Y=512,temperature:H=0,topP:X=0.9,modelId:G}=Z;try{let J=await HQ({modelId:MQ(G),contentType:"application/json",accept:"*/*",body:JSON.stringify({inputText:`Summarize the following text: ${Q}`,textGenerationConfig:{maxTokenCount:Y,stopSequences:[],temperature:H,topP:X}})});return JSON.parse(new TextDecoder().decode(J.body)).results[0].outputText}catch(J){throw Error(`Error summarizing text: ${J.message}`)}}async function n6(Q,Z={}){let{maxTokenCount:Y=512,temperature:H=0,topP:X=0.9,modelId:G}=Z;try{let J=await HQ({modelId:MQ(G),contentType:"application/json",accept:"*/*",body:JSON.stringify({inputText:Q,textGenerationConfig:{maxTokenCount:Y,stopSequences:[],temperature:H,topP:X}})});return JSON.parse(new TextDecoder().decode(J.body)).results[0].outputText}catch(J){throw Error(`Error asking question: ${J.message}`)}}async function IZ(Q,Z={}){let{provider:Y="openai",model:H="dall-e-3",size:X="1024x1024",quality:G="standard",n:J=1,responseFormat:V="url",style:$="vivid"}=Z;if(Y==="openai")return TZ(Q,{model:H,size:X,quality:G,n:J,responseFormat:V,style:$});throw Error(`Image generation not supported for provider: ${Y}. Use 'openai'.`)}async function TZ(Q,Z){let Y=process.env.OPENAI_API_KEY;if(!Y)throw Error("OPENAI_API_KEY environment variable is required for image generation.");let H=await fetch("https://api.openai.com/v1/images/generations",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Y}`},body:JSON.stringify({model:Z.model,prompt:Q,size:Z.size,quality:Z.quality,n:Z.n,response_format:Z.responseFormat,style:Z.style})});if(!H.ok){let G=await H.text();throw Error(`OpenAI Image API error: ${G}`)}return{images:(await H.json()).data.map((G)=>({url:G.url,b64_json:G.b64_json,revisedPrompt:G.revised_prompt})),provider:"openai",model:Z.model}}async function DZ(Q,Z,Y={}){let H=process.env.OPENAI_API_KEY;if(!H)throw Error("OPENAI_API_KEY environment variable is required for image editing.");let X=new FormData;if(X.append("image",Q),X.append("prompt",Z),X.append("model",Y.model||"dall-e-2"),Y.mask)X.append("mask",Y.mask);if(Y.n)X.append("n",String(Y.n));if(Y.size)X.append("size",Y.size);if(Y.responseFormat)X.append("response_format",Y.responseFormat);let G=await fetch("https://api.openai.com/v1/images/edits",{method:"POST",headers:{Authorization:`Bearer ${H}`},body:X});if(!G.ok){let V=await G.text();throw Error(`OpenAI Image Edit API error: ${V}`)}return{images:(await G.json()).data.map((V)=>({url:V.url,b64_json:V.b64_json})),provider:"openai",model:Y.model||"dall-e-2"}}async function CZ(Q,Z={}){let Y=process.env.OPENAI_API_KEY;if(!Y)throw Error("OPENAI_API_KEY environment variable is required for image variations.");let H=new FormData;if(H.append("image",Q),H.append("model",Z.model||"dall-e-2"),Z.n)H.append("n",String(Z.n));if(Z.size)H.append("size",Z.size);if(Z.responseFormat)H.append("response_format",Z.responseFormat);let X=await fetch("https://api.openai.com/v1/images/variations",{method:"POST",headers:{Authorization:`Bearer ${Y}`},body:H});if(!X.ok){let J=await X.text();throw Error(`OpenAI Image Variations API error: ${J}`)}return{images:(await X.json()).data.map((J)=>({url:J.url,b64_json:J.b64_json})),provider:"openai",model:Z.model||"dall-e-2"}}async function xZ(Q,Z,Y={}){let{provider:H="anthropic"}=Y;switch(H){case"anthropic":return SZ(Q,Z,Y);case"openai":return PZ(Q,Z,Y);case"ollama":return kZ(Q,Z,Y);default:throw Error(`Vision not supported for provider: ${H}`)}}async function d(Q){if(Q.type==="base64")return{data:Q.data,mediaType:Q.mediaType};if(Q.type==="url"){let Z=await fetch(Q.url);if(!Z.ok)throw Error(`Failed to fetch image from URL: ${Q.url}`);let Y=await Z.arrayBuffer(),H=Buffer.from(Y).toString("base64"),X=Z.headers.get("content-type")||"image/png";return{data:H,mediaType:X}}if(Q.type==="file"){let{readFile:Z}=await import("fs/promises"),H=(await Z(Q.path)).toString("base64"),X=Q.path.split(".").pop()?.toLowerCase()||"png";return{data:H,mediaType:{png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp"}[X]||"image/png"}}throw Error("Invalid image input type")}async function SZ(Q,Z,Y){let H=process.env.ANTHROPIC_API_KEY;if(!H)throw Error("ANTHROPIC_API_KEY environment variable is required for Claude vision.");let{data:X,mediaType:G}=await d(Q),J=Y.model||"claude-sonnet-4-20250514",V=Y.maxTokens||4096,$=[{role:"user",content:[{type:"image",source:{type:"base64",media_type:G,data:X}},{type:"text",text:Z}]}],W=await fetch("https://api.anthropic.com/v1/messages",{method:"POST",headers:{"Content-Type":"application/json","x-api-key":H,"anthropic-version":"2023-06-01"},body:JSON.stringify({model:J,max_tokens:V,temperature:Y.temperature,messages:$})});if(!W.ok){let z=await W.text();throw Error(`Claude Vision API error: ${z}`)}let q=await W.json();return{content:q.content[0].text,model:q.model,provider:"anthropic",usage:{promptTokens:q.usage?.input_tokens||0,completionTokens:q.usage?.output_tokens||0,totalTokens:(q.usage?.input_tokens||0)+(q.usage?.output_tokens||0)},finishReason:q.stop_reason}}async function PZ(Q,Z,Y){let H=process.env.OPENAI_API_KEY;if(!H)throw Error("OPENAI_API_KEY environment variable is required for GPT-4 vision.");let X=Y.model||"gpt-4o",G=Y.maxTokens||4096,J=Y.detail||"auto",V;if(Q.type==="url")V={type:"image_url",image_url:{url:Q.url,detail:J}};else{let{data:q,mediaType:z}=await d(Q);V={type:"image_url",image_url:{url:`data:${z};base64,${q}`,detail:J}}}let $=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${H}`},body:JSON.stringify({model:X,max_tokens:G,temperature:Y.temperature,messages:[{role:"user",content:[V,{type:"text",text:Z}]}]})});if(!$.ok){let q=await $.text();throw Error(`OpenAI Vision API error: ${q}`)}let W=await $.json();return{content:W.choices[0].message.content,model:W.model,provider:"openai",usage:{promptTokens:W.usage?.prompt_tokens||0,completionTokens:W.usage?.completion_tokens||0,totalTokens:W.usage?.total_tokens||0},finishReason:W.choices[0].finish_reason}}async function kZ(Q,Z,Y){let H=process.env.OLLAMA_HOST||"http://localhost:11434",X=Y.model||"llava",{data:G}=await d(Q),J=await fetch(`${H}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:X,prompt:Z,images:[G],stream:!1})});if(!J.ok){let $=await J.text();throw Error(`Ollama Vision API error: ${$}`)}let V=await J.json();return{content:V.response,model:V.model,provider:"ollama",usage:{promptTokens:V.prompt_eval_count||0,completionTokens:V.eval_count||0,totalTokens:(V.prompt_eval_count||0)+(V.eval_count||0)}}}async function vZ(Q,Z,Y={}){let{provider:H="anthropic"}=Y;if(H==="anthropic"){let X=process.env.ANTHROPIC_API_KEY;if(!X)throw Error("ANTHROPIC_API_KEY required for multi-image analysis.");let G=Y.model||"claude-sonnet-4-20250514",J=[];for(let W of Q){let{data:q,mediaType:z}=await d(W);J.push({type:"image",source:{type:"base64",media_type:z,data:q}})}J.push({type:"text",text:Z});let V=await fetch("https://api.anthropic.com/v1/messages",{method:"POST",headers:{"Content-Type":"application/json","x-api-key":X,"anthropic-version":"2023-06-01"},body:JSON.stringify({model:G,max_tokens:Y.maxTokens||4096,temperature:Y.temperature,messages:[{role:"user",content:J}]})});if(!V.ok){let W=await V.text();throw Error(`Claude Vision API error: ${W}`)}let $=await V.json();return{content:$.content[0].text,model:$.model,provider:"anthropic",usage:{promptTokens:$.usage?.input_tokens||0,completionTokens:$.usage?.output_tokens||0,totalTokens:($.usage?.input_tokens||0)+($.usage?.output_tokens||0)},finishReason:$.stop_reason}}if(H==="openai"){let X=process.env.OPENAI_API_KEY;if(!X)throw Error("OPENAI_API_KEY required for multi-image analysis.");let G=Y.model||"gpt-4o",J=Y.detail||"auto",V=[];for(let q of Q)if(q.type==="url")V.push({type:"image_url",image_url:{url:q.url,detail:J}});else{let{data:z,mediaType:B}=await d(q);V.push({type:"image_url",image_url:{url:`data:${B};base64,${z}`,detail:J}})}V.push({type:"text",text:Z});let $=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${X}`},body:JSON.stringify({model:G,max_tokens:Y.maxTokens||4096,temperature:Y.temperature,messages:[{role:"user",content:V}]})});if(!$.ok){let q=await $.text();throw Error(`OpenAI Vision API error: ${q}`)}let W=await $.json();return{content:W.choices[0].message.content,model:W.model,provider:"openai",usage:{promptTokens:W.usage?.prompt_tokens||0,completionTokens:W.usage?.completion_tokens||0,totalTokens:W.usage?.total_tokens||0},finishReason:W.choices[0].finish_reason}}throw Error(`Multi-image analysis not supported for provider: ${H}`)}var s6={generate:IZ,edit:DZ,variation:CZ,analyze:xZ,analyzeMultiple:vZ};async function XQ(Q,Z={}){let{provider:Y="openai"}=Z;if(Y==="openai")return yZ(Q,Z.model||"text-embedding-3-small");if(Y==="ollama")return bZ(Q,Z.model||"nomic-embed-text");throw Error(`Embedding provider not supported: ${Y}`)}async function yZ(Q,Z){let Y=process.env.OPENAI_API_KEY;if(!Y)throw Error("OPENAI_API_KEY environment variable is required for embeddings.");let H=await fetch("https://api.openai.com/v1/embeddings",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Y}`},body:JSON.stringify({model:Z,input:Q})});if(!H.ok){let G=await H.text();throw Error(`OpenAI Embeddings API error: ${G}`)}let X=await H.json();if(Array.isArray(Q))return X.data.map((G)=>G.embedding);return X.data[0].embedding}async function bZ(Q,Z){let Y=process.env.OLLAMA_HOST||"http://localhost:11434",H=Array.isArray(Q)?Q:[Q],X=[];for(let G of H){let J=await fetch(`${Y}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:Z,prompt:G})});if(!J.ok){let $=await J.text();throw Error(`Ollama Embeddings API error: ${$}`)}let V=await J.json();X.push(V.embedding)}return Array.isArray(Q)?X:X[0]}function AQ(Q,Z){if(Q.length!==Z.length)throw Error(`Vector dimensions must match: ${Q.length} vs ${Z.length}`);let Y=0,H=0,X=0;for(let J=0;J<Q.length;J++)Y+=Q[J]*Z[J],H+=Q[J]*Q[J],X+=Z[J]*Z[J];let G=Math.sqrt(H)*Math.sqrt(X);if(G===0)return 0;return Y/G}function hZ(Q,Z){if(Q.length!==Z.length)throw Error(`Vector dimensions must match: ${Q.length} vs ${Z.length}`);let Y=0;for(let H=0;H<Q.length;H++)Y+=Q[H]*Z[H];return Y}function fZ(Q,Z){if(Q.length!==Z.length)throw Error(`Vector dimensions must match: ${Q.length} vs ${Z.length}`);let Y=0;for(let H=0;H<Q.length;H++){let X=Q[H]-Z[H];Y+=X*X}return Math.sqrt(Y)}class JQ{documents=[];embeddingOptions;constructor(Q={}){this.embeddingOptions=Q}async add(Q){if(Q.length===0)return;let Z=Q.map((X)=>X.content),Y=await XQ(Z,this.embeddingOptions),H=Z.length===1?[Y]:Y;for(let X=0;X<Q.length;X++)this.documents.push({...Q[X],embedding:H[X]})}addWithEmbedding(Q,Z){this.documents.push({...Q,embedding:Z})}async search(Q,Z=5){if(this.documents.length===0)return[];let Y=await XQ(Q,this.embeddingOptions);return this.searchByVector(Y,Z)}searchByVector(Q,Z=5){if(this.documents.length===0)return[];let Y=this.documents.map((H)=>({document:{id:H.id,content:H.content,metadata:H.metadata},score:AQ(Q,H.embedding)}));return Y.sort((H,X)=>X.score-H.score),Y.slice(0,Z).map((H,X)=>({...H,rank:X+1}))}remove(Q){let Z=this.documents.length;return this.documents=this.documents.filter((Y)=>Y.id!==Q),this.documents.length<Z}clear(){this.documents=[]}get size(){return this.documents.length}get ids(){return this.documents.map((Q)=>Q.id)}}async function gZ(Q,Z,Y={}){let{provider:H="anthropic",topK:X=5,maxTokens:G=4096,temperature:J,systemPrompt:V}=Y,$=await Z.search(Q,X),W=$.map((B,w)=>`[Source ${w+1}] (score: ${B.score.toFixed(3)})
129
+ `);w=j.pop()||"";for(let K of j)if(K.startsWith("data: ")){let L=K.slice(6);if(L==="[DONE]")continue;try{let N=JSON.parse(L);if(N.type==="content_block_delta"&&N.delta?.text){let R=N.delta.text;G+=R,W.enqueue(X.encode(R))}}catch{}}}F.addToHistory({role:"user",content:Q}),F.addToHistory({role:"assistant",content:G}),J(G),W.close()}catch(q){J(G),W.error(q)}}}),fullResponse:V}}import _Z from"process";var r=null;async function FQ(){if(r)return r;let Q=await import("@stacksjs/ts-cloud/aws");if(!Q?.BedrockRuntimeClient)throw Error("@stacksjs/ts-cloud/aws does not export BedrockRuntimeClient \u2014 rebuild ts-cloud or remove the AI dependency.");return r=new Q.BedrockRuntimeClient(_Z.env.REGION||"us-east-1"),r}async function HQ(Q){return(await FQ()).invokeModel(Q)}async function m6(Q){return(await FQ()).invokeModelWithResponseStream(Q)}var EZ="amazon.titan-text-express-v1";function MQ(Q){if(Q)return Q;return globalThis.config?.ai?.bedrock?.model||process.env.BEDROCK_MODEL_ID||EZ}async function a6(Q,Z={}){let{maxTokenCount:Y=512,temperature:H=0,topP:X=0.9,modelId:G}=Z;try{let J=await HQ({modelId:MQ(G),contentType:"application/json",accept:"*/*",body:JSON.stringify({inputText:`Summarize the following text: ${Q}`,textGenerationConfig:{maxTokenCount:Y,stopSequences:[],temperature:H,topP:X}})});return JSON.parse(new TextDecoder().decode(J.body)).results[0].outputText}catch(J){throw Error(`Error summarizing text: ${J.message}`)}}async function n6(Q,Z={}){let{maxTokenCount:Y=512,temperature:H=0,topP:X=0.9,modelId:G}=Z;try{let J=await HQ({modelId:MQ(G),contentType:"application/json",accept:"*/*",body:JSON.stringify({inputText:Q,textGenerationConfig:{maxTokenCount:Y,stopSequences:[],temperature:H,topP:X}})});return JSON.parse(new TextDecoder().decode(J.body)).results[0].outputText}catch(J){throw Error(`Error asking question: ${J.message}`)}}async function IZ(Q,Z={}){let{provider:Y="openai",model:H="dall-e-3",size:X="1024x1024",quality:G="standard",n:J=1,responseFormat:V="url",style:$="vivid"}=Z;if(Y==="openai")return TZ(Q,{model:H,size:X,quality:G,n:J,responseFormat:V,style:$});throw Error(`Image generation not supported for provider: ${Y}. Use 'openai'.`)}async function TZ(Q,Z){let Y=process.env.OPENAI_API_KEY;if(!Y)throw Error("OPENAI_API_KEY environment variable is required for image generation.");let H=await fetch("https://api.openai.com/v1/images/generations",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Y}`},body:JSON.stringify({model:Z.model,prompt:Q,size:Z.size,quality:Z.quality,n:Z.n,response_format:Z.responseFormat,style:Z.style})});if(!H.ok){let G=await H.text();throw Error(`OpenAI Image API error: ${G}`)}return{images:(await H.json()).data.map((G)=>({url:G.url,b64_json:G.b64_json,revisedPrompt:G.revised_prompt})),provider:"openai",model:Z.model}}async function DZ(Q,Z,Y={}){let H=process.env.OPENAI_API_KEY;if(!H)throw Error("OPENAI_API_KEY environment variable is required for image editing.");let X=new FormData;if(X.append("image",Q),X.append("prompt",Z),X.append("model",Y.model||"dall-e-2"),Y.mask)X.append("mask",Y.mask);if(Y.n)X.append("n",String(Y.n));if(Y.size)X.append("size",Y.size);if(Y.responseFormat)X.append("response_format",Y.responseFormat);let G=await fetch("https://api.openai.com/v1/images/edits",{method:"POST",headers:{Authorization:`Bearer ${H}`},body:X});if(!G.ok){let V=await G.text();throw Error(`OpenAI Image Edit API error: ${V}`)}return{images:(await G.json()).data.map((V)=>({url:V.url,b64_json:V.b64_json})),provider:"openai",model:Y.model||"dall-e-2"}}async function CZ(Q,Z={}){let Y=process.env.OPENAI_API_KEY;if(!Y)throw Error("OPENAI_API_KEY environment variable is required for image variations.");let H=new FormData;if(H.append("image",Q),H.append("model",Z.model||"dall-e-2"),Z.n)H.append("n",String(Z.n));if(Z.size)H.append("size",Z.size);if(Z.responseFormat)H.append("response_format",Z.responseFormat);let X=await fetch("https://api.openai.com/v1/images/variations",{method:"POST",headers:{Authorization:`Bearer ${Y}`},body:H});if(!X.ok){let J=await X.text();throw Error(`OpenAI Image Variations API error: ${J}`)}return{images:(await X.json()).data.map((J)=>({url:J.url,b64_json:J.b64_json})),provider:"openai",model:Z.model||"dall-e-2"}}async function xZ(Q,Z,Y={}){let{provider:H="anthropic"}=Y;switch(H){case"anthropic":return SZ(Q,Z,Y);case"openai":return PZ(Q,Z,Y);case"ollama":return kZ(Q,Z,Y);default:throw Error(`Vision not supported for provider: ${H}`)}}async function d(Q){if(Q.type==="base64")return{data:Q.data,mediaType:Q.mediaType};if(Q.type==="url"){let Z=await fetch(Q.url);if(!Z.ok)throw Error(`Failed to fetch image from URL: ${Q.url}`);let Y=await Z.arrayBuffer(),H=Buffer.from(Y).toString("base64"),X=Z.headers.get("content-type")||"image/png";return{data:H,mediaType:X}}if(Q.type==="file"){let{readFile:Z}=await import("fs/promises"),H=(await Z(Q.path)).toString("base64"),X=Q.path.split(".").pop()?.toLowerCase()||"png";return{data:H,mediaType:{png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp"}[X]||"image/png"}}throw Error("Invalid image input type")}async function SZ(Q,Z,Y){let H=process.env.ANTHROPIC_API_KEY;if(!H)throw Error("ANTHROPIC_API_KEY environment variable is required for Claude vision.");let{data:X,mediaType:G}=await d(Q),J=Y.model||"claude-sonnet-4-20250514",V=Y.maxTokens||4096,$=[{role:"user",content:[{type:"image",source:{type:"base64",media_type:G,data:X}},{type:"text",text:Z}]}],W=await fetch("https://api.anthropic.com/v1/messages",{method:"POST",headers:{"Content-Type":"application/json","x-api-key":H,"anthropic-version":"2023-06-01"},body:JSON.stringify({model:J,max_tokens:V,temperature:Y.temperature,messages:$})});if(!W.ok){let z=await W.text();throw Error(`Claude Vision API error: ${z}`)}let q=await W.json();return{content:q.content[0].text,model:q.model,provider:"anthropic",usage:{promptTokens:q.usage?.input_tokens||0,completionTokens:q.usage?.output_tokens||0,totalTokens:(q.usage?.input_tokens||0)+(q.usage?.output_tokens||0)},finishReason:q.stop_reason}}async function PZ(Q,Z,Y){let H=process.env.OPENAI_API_KEY;if(!H)throw Error("OPENAI_API_KEY environment variable is required for GPT-4 vision.");let X=Y.model||"gpt-4o",G=Y.maxTokens||4096,J=Y.detail||"auto",V;if(Q.type==="url")V={type:"image_url",image_url:{url:Q.url,detail:J}};else{let{data:q,mediaType:z}=await d(Q);V={type:"image_url",image_url:{url:`data:${z};base64,${q}`,detail:J}}}let $=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${H}`},body:JSON.stringify({model:X,max_tokens:G,temperature:Y.temperature,messages:[{role:"user",content:[V,{type:"text",text:Z}]}]})});if(!$.ok){let q=await $.text();throw Error(`OpenAI Vision API error: ${q}`)}let W=await $.json();return{content:W.choices[0].message.content,model:W.model,provider:"openai",usage:{promptTokens:W.usage?.prompt_tokens||0,completionTokens:W.usage?.completion_tokens||0,totalTokens:W.usage?.total_tokens||0},finishReason:W.choices[0].finish_reason}}async function kZ(Q,Z,Y){let H=process.env.OLLAMA_HOST||"http://localhost:11434",X=Y.model||"llava",{data:G}=await d(Q),J=await fetch(`${H}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:X,prompt:Z,images:[G],stream:!1})});if(!J.ok){let $=await J.text();throw Error(`Ollama Vision API error: ${$}`)}let V=await J.json();return{content:V.response,model:V.model,provider:"ollama",usage:{promptTokens:V.prompt_eval_count||0,completionTokens:V.eval_count||0,totalTokens:(V.prompt_eval_count||0)+(V.eval_count||0)}}}async function vZ(Q,Z,Y={}){let{provider:H="anthropic"}=Y;if(H==="anthropic"){let X=process.env.ANTHROPIC_API_KEY;if(!X)throw Error("ANTHROPIC_API_KEY required for multi-image analysis.");let G=Y.model||"claude-sonnet-4-20250514",J=[];for(let W of Q){let{data:q,mediaType:z}=await d(W);J.push({type:"image",source:{type:"base64",media_type:z,data:q}})}J.push({type:"text",text:Z});let V=await fetch("https://api.anthropic.com/v1/messages",{method:"POST",headers:{"Content-Type":"application/json","x-api-key":X,"anthropic-version":"2023-06-01"},body:JSON.stringify({model:G,max_tokens:Y.maxTokens||4096,temperature:Y.temperature,messages:[{role:"user",content:J}]})});if(!V.ok){let W=await V.text();throw Error(`Claude Vision API error: ${W}`)}let $=await V.json();return{content:$.content[0].text,model:$.model,provider:"anthropic",usage:{promptTokens:$.usage?.input_tokens||0,completionTokens:$.usage?.output_tokens||0,totalTokens:($.usage?.input_tokens||0)+($.usage?.output_tokens||0)},finishReason:$.stop_reason}}if(H==="openai"){let X=process.env.OPENAI_API_KEY;if(!X)throw Error("OPENAI_API_KEY required for multi-image analysis.");let G=Y.model||"gpt-4o",J=Y.detail||"auto",V=[];for(let q of Q)if(q.type==="url")V.push({type:"image_url",image_url:{url:q.url,detail:J}});else{let{data:z,mediaType:B}=await d(q);V.push({type:"image_url",image_url:{url:`data:${B};base64,${z}`,detail:J}})}V.push({type:"text",text:Z});let $=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${X}`},body:JSON.stringify({model:G,max_tokens:Y.maxTokens||4096,temperature:Y.temperature,messages:[{role:"user",content:V}]})});if(!$.ok){let q=await $.text();throw Error(`OpenAI Vision API error: ${q}`)}let W=await $.json();return{content:W.choices[0].message.content,model:W.model,provider:"openai",usage:{promptTokens:W.usage?.prompt_tokens||0,completionTokens:W.usage?.completion_tokens||0,totalTokens:W.usage?.total_tokens||0},finishReason:W.choices[0].finish_reason}}throw Error(`Multi-image analysis not supported for provider: ${H}`)}var s6={generate:IZ,edit:DZ,variation:CZ,analyze:xZ,analyzeMultiple:vZ};async function XQ(Q,Z={}){let{provider:Y="openai"}=Z;if(Y==="openai")return yZ(Q,Z.model||"text-embedding-3-small");if(Y==="ollama")return bZ(Q,Z.model||"nomic-embed-text");throw Error(`Embedding provider not supported: ${Y}`)}async function yZ(Q,Z){let Y=process.env.OPENAI_API_KEY;if(!Y)throw Error("OPENAI_API_KEY environment variable is required for embeddings.");let H=await fetch("https://api.openai.com/v1/embeddings",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${Y}`},body:JSON.stringify({model:Z,input:Q})});if(!H.ok){let J=await H.text();throw Error(`OpenAI Embeddings API error: ${J}`)}let X=await H.json();if(Array.isArray(Q))return X.data.map((J)=>J.embedding);let G=X.data[0];if(!G)throw Error("OpenAI Embeddings API returned no embedding");return G.embedding}async function bZ(Q,Z){let Y=process.env.OLLAMA_HOST||"http://localhost:11434",H=Array.isArray(Q)?Q:[Q],X=[];for(let J of H){let V=await fetch(`${Y}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:Z,prompt:J})});if(!V.ok){let W=await V.text();throw Error(`Ollama Embeddings API error: ${W}`)}let $=await V.json();X.push($.embedding)}if(Array.isArray(Q))return X;let G=X[0];if(!G)throw Error("Ollama Embeddings API returned no embedding");return G}function AQ(Q,Z){if(Q.length!==Z.length)throw Error(`Vector dimensions must match: ${Q.length} vs ${Z.length}`);let Y=0,H=0,X=0;for(let J=0;J<Q.length;J++){let V=Q[J],$=Z[J];Y+=V*$,H+=V*V,X+=$*$}let G=Math.sqrt(H)*Math.sqrt(X);if(G===0)return 0;return Y/G}function hZ(Q,Z){if(Q.length!==Z.length)throw Error(`Vector dimensions must match: ${Q.length} vs ${Z.length}`);let Y=0;for(let H=0;H<Q.length;H++)Y+=Q[H]*Z[H];return Y}function fZ(Q,Z){if(Q.length!==Z.length)throw Error(`Vector dimensions must match: ${Q.length} vs ${Z.length}`);let Y=0;for(let H=0;H<Q.length;H++){let X=Q[H]-Z[H];Y+=X*X}return Math.sqrt(Y)}class JQ{documents=[];embeddingOptions;constructor(Q={}){this.embeddingOptions=Q}async add(Q){if(Q.length===0)return;let Z=Q.map((H)=>H.content),Y=await XQ(Z,this.embeddingOptions);for(let H=0;H<Q.length;H++){let X=Q[H],G=Y[H];if(!X||!G)continue;this.documents.push({...X,embedding:G})}}addWithEmbedding(Q,Z){this.documents.push({...Q,embedding:Z})}async search(Q,Z=5){if(this.documents.length===0)return[];let Y=await XQ(Q,this.embeddingOptions);return this.searchByVector(Y,Z)}searchByVector(Q,Z=5){if(this.documents.length===0)return[];let Y=this.documents.map((H)=>({document:{id:H.id,content:H.content,metadata:H.metadata},score:AQ(Q,H.embedding)}));return Y.sort((H,X)=>X.score-H.score),Y.slice(0,Z).map((H,X)=>({...H,rank:X+1}))}remove(Q){let Z=this.documents.length;return this.documents=this.documents.filter((Y)=>Y.id!==Q),this.documents.length<Z}clear(){this.documents=[]}get size(){return this.documents.length}get ids(){return this.documents.map((Q)=>Q.id)}}async function gZ(Q,Z,Y={}){let{provider:H="anthropic",topK:X=5,maxTokens:G=4096,temperature:J,systemPrompt:V}=Y,$=await Z.search(Q,X),W=$.map((B,w)=>`[Source ${w+1}] (score: ${B.score.toFixed(3)})
130
130
  ${B.document.content}`).join(`
131
131
 
132
132
  ---
@@ -151,7 +151,7 @@ Respond with ONLY valid JSON in this exact format:
151
151
  "allLabels": [{"label": "<label>", "confidence": <number>}]
152
152
  }
153
153
 
154
- Include ALL provided labels in allLabels with their confidence scores, sorted by confidence descending.`,J=await l(H,G,Q,Y.model);try{return JSON.parse(J.content)}catch{return{label:Z[0],confidence:0.5,allLabels:Z.map((V)=>({label:V,confidence:1/Z.length}))}}}async function iZ(Q,Z={}){let{provider:Y="anthropic",style:H="concise",maxLength:X,language:G}=Z,J;switch(H){case"bullet-points":J="Use bullet points to organize the key points.";break;case"detailed":J="Provide a detailed summary covering all major points.";break;default:J="Be concise and focus on the most important points."}let V=X?` Keep the summary under ${X} words.`:"",$=G?` Write the summary in ${G}.`:"",W=`You are an expert summarizer. ${J}${V}${$}`;return l(Y,W,`Summarize the following text:
154
+ Include ALL provided labels in allLabels with their confidence scores, sorted by confidence descending.`,J=await l(H,G,Q,Y.model);try{return JSON.parse(J.content)}catch{return{label:Z[0]??"",confidence:0.5,allLabels:Z.map((V)=>({label:V,confidence:1/Z.length}))}}}async function iZ(Q,Z={}){let{provider:Y="anthropic",style:H="concise",maxLength:X,language:G}=Z,J;switch(H){case"bullet-points":J="Use bullet points to organize the key points.";break;case"detailed":J="Provide a detailed summary covering all major points.";break;default:J="Be concise and focus on the most important points."}let V=X?` Keep the summary under ${X} words.`:"",$=G?` Write the summary in ${G}.`:"",W=`You are an expert summarizer. ${J}${V}${$}`;return l(Y,W,`Summarize the following text:
155
155
 
156
156
  ${Q}`,Z.model)}async function aZ(Q,Z,Y={}){let{provider:H="anthropic",limit:X=5}=Y,G=nZ(Q),J=Z.map((q)=>`ID: ${q.id} | Category: ${q.category||"none"} | Tags: ${q.tags?.join(", ")||"none"} | Content: ${q.content.slice(0,200)}`).join(`
157
157
  `),V=`You are a recommendation engine. Based on the user profile, recommend the most relevant items. Respond with ONLY valid JSON:
@@ -172,4 +172,4 @@ Recent Interactions: ${Y||"none"}`}function rZ(Q,Z=[]){return{id:Q,preferences:{
172
172
  `),$=await l(H,`Extract the main interests/topics from the user's interaction history. Return ONLY a JSON array of strings, e.g. ["technology", "cooking", "travel"]. Maximum 10 interests.`,J,Y.model);try{return JSON.parse($.content)}catch{return Q.segments}}async function l(Q,Z,Y,H){if(Q==="anthropic"){let X=process.env.ANTHROPIC_API_KEY;if(!X)throw Error("ANTHROPIC_API_KEY required.");let G=await fetch("https://api.anthropic.com/v1/messages",{method:"POST",headers:{"Content-Type":"application/json","x-api-key":X,"anthropic-version":"2023-06-01"},body:JSON.stringify({model:H||"claude-sonnet-4-20250514",max_tokens:4096,system:Z,messages:[{role:"user",content:Y}]})});if(!G.ok){let V=await G.text();throw Error(`Claude API error: ${V}`)}let J=await G.json();return{content:J.content[0].text,model:J.model,usage:{promptTokens:J.usage?.input_tokens||0,completionTokens:J.usage?.output_tokens||0,totalTokens:(J.usage?.input_tokens||0)+(J.usage?.output_tokens||0)},finishReason:J.stop_reason}}if(Q==="openai"){let X=process.env.OPENAI_API_KEY;if(!X)throw Error("OPENAI_API_KEY required.");let G=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${X}`},body:JSON.stringify({model:H||"gpt-4o",max_tokens:4096,messages:[{role:"system",content:Z},{role:"user",content:Y}]})});if(!G.ok){let V=await G.text();throw Error(`OpenAI API error: ${V}`)}let J=await G.json();return{content:J.choices[0].message.content,model:J.model,usage:{promptTokens:J.usage?.prompt_tokens||0,completionTokens:J.usage?.completion_tokens||0,totalTokens:J.usage?.total_tokens||0},finishReason:J.choices[0].finish_reason}}if(Q==="ollama"){let X=process.env.OLLAMA_HOST||"http://localhost:11434",G=await fetch(`${X}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:H||"llama3.2",messages:[{role:"system",content:Z},{role:"user",content:Y}],stream:!1})});if(!G.ok){let V=await G.text();throw Error(`Ollama API error: ${V}`)}let J=await G.json();return{content:J.message.content,model:J.model,usage:{promptTokens:J.prompt_eval_count||0,completionTokens:J.eval_count||0,totalTokens:(J.prompt_eval_count||0)+(J.eval_count||0)},finishReason:J.done_reason||"stop"}}throw Error(`Provider not supported: ${Q}`)}var Q9={analyzeSentiment:mZ,classifyText:pZ,summarize:iZ,recommend:aZ,createProfile:rZ,recordInteraction:sZ,extractUserInterests:oZ};class m{config;process=null;requestId=0;pendingRequests=new Map;tools=[];resources=[];prompts=[];initialized=!1;buffer="";constructor(Q){this.config=Q}async connect(){if(this.config.transport.type==="stdio")await this.connectStdio();else if(this.config.transport.type==="sse"||this.config.transport.type==="streamable-http")await this.connectHTTP();else throw Error(`Unsupported transport type: ${this.config.transport.type}`);this.initialized=!0}async connectStdio(){let Q=this.config.transport,{spawn:Z}=awaitPromise.resolve(globalThis.Bun);this.process=Z([Q.command,...Q.args||[]],{stdin:"pipe",stdout:"pipe",stderr:"pipe",env:{...process.env,...Q.env}}),this.readStdout(),await this.sendRequest("initialize",{protocolVersion:"2024-11-05",capabilities:{},clientInfo:{name:"stacks-ai",version:"1.0.0"}}),await this.sendNotification("notifications/initialized",{}),await this.discoverCapabilities()}async connectHTTP(){let Q=this.config.transport,Z=await fetch(Q.url,{method:"POST",headers:{"Content-Type":"application/json",...Q.headers},body:JSON.stringify({jsonrpc:"2.0",id:this.nextId(),method:"initialize",params:{protocolVersion:"2024-11-05",capabilities:{},clientInfo:{name:"stacks-ai",version:"1.0.0"}}})});if(!Z.ok){let Y=await Z.text();throw Error(`MCP HTTP connection error: ${Y}`)}await this.discoverCapabilities()}async readStdout(){if(!this.process)return;let Q=this.process.stdout?.getReader();if(!Q)return;let Z=new TextDecoder;try{while(!0){let{done:Y,value:H}=await Q.read();if(Y)break;this.buffer+=Z.decode(H,{stream:!0}),this.processBuffer()}}catch{}}processBuffer(){let Q=this.buffer.split(`
173
173
  `);this.buffer=Q.pop()||"";for(let Z of Q){if(!Z.trim())continue;try{let Y=JSON.parse(Z);if(Y.id!==void 0&&this.pendingRequests.has(Y.id)){let H=this.pendingRequests.get(Y.id);if(this.pendingRequests.delete(Y.id),Y.error)H.reject(Error(Y.error.message||"MCP error"));else H.resolve(Y.result)}}catch{}}}nextId(){return++this.requestId}async sendRequest(Q,Z={}){let Y=this.nextId(),H=JSON.stringify({jsonrpc:"2.0",id:Y,method:Q,params:Z})+`
174
174
  `;if(this.config.transport.type==="stdio"&&this.process){let X=this.process.stdin?.getWriter();if(X)await X.write(new TextEncoder().encode(H)),X.releaseLock();return new Promise((G,J)=>{let V=setTimeout(()=>{this.pendingRequests.delete(Y),J(Error(`MCP request timeout: ${Q}`))},30000);this.pendingRequests.set(Y,{resolve:($)=>{clearTimeout(V),G($)},reject:($)=>{clearTimeout(V),J($)}})})}if(this.config.transport.type==="sse"||this.config.transport.type==="streamable-http"){let X=this.config.transport,G=await fetch(X.url,{method:"POST",headers:{"Content-Type":"application/json",...X.headers},body:H});if(!G.ok){let V=await G.text();throw Error(`MCP request error: ${V}`)}let J=await G.json();if(J.error)throw Error(J.error.message||"MCP error");return J.result}throw Error("No transport available")}async sendNotification(Q,Z={}){let Y=JSON.stringify({jsonrpc:"2.0",method:Q,params:Z})+`
175
- `;if(this.config.transport.type==="stdio"&&this.process){let H=this.process.stdin?.getWriter();if(H)await H.write(new TextEncoder().encode(Y)),H.releaseLock()}}async discoverCapabilities(){let Q=this.config.capabilities||{tools:!0,resources:!0,prompts:!0};if(Q.tools!==!1)try{let Z=await this.sendRequest("tools/list");this.tools=Z?.tools||[]}catch{this.tools=[]}if(Q.resources!==!1)try{let Z=await this.sendRequest("resources/list");this.resources=Z?.resources||[]}catch{this.resources=[]}if(Q.prompts!==!1)try{let Z=await this.sendRequest("prompts/list");this.prompts=Z?.prompts||[]}catch{this.prompts=[]}}listTools(){return this.tools}listResources(){return this.resources}listPrompts(){return this.prompts}async callTool(Q,Z={}){if(!this.initialized)throw Error("MCP client not connected. Call connect() first.");return await this.sendRequest("tools/call",{name:Q,arguments:Z})}async readResource(Q){if(!this.initialized)throw Error("MCP client not connected. Call connect() first.");let Y=(await this.sendRequest("resources/read",{uri:Q}))?.contents?.[0];return{uri:Y?.uri||Q,mimeType:Y?.mimeType,text:Y?.text,blob:Y?.blob}}async getPrompt(Q,Z={}){if(!this.initialized)throw Error("MCP client not connected. Call connect() first.");return this.sendRequest("prompts/get",{name:Q,arguments:Z})}toAnthropicTools(){return this.tools.map((Q)=>({name:Q.name,description:Q.description,input_schema:Q.inputSchema}))}toOpenAITools(){return this.tools.map((Q)=>({type:"function",function:{name:Q.name,description:Q.description,parameters:Q.inputSchema}}))}async disconnect(){if(this.process)this.process.kill(),this.process=null;for(let Q of this.pendingRequests.values())try{Q.reject(Error("MCP client disconnected"))}catch{}this.pendingRequests.clear(),this.initialized=!1,this.tools=[],this.resources=[],this.prompts=[]}get isConnected(){return this.initialized}get serverName(){return this.config.name}}class EQ{clients=new Map;async addServer(Q){if(this.clients.has(Q.name))throw Error(`MCP server already registered: ${Q.name}`);let Z=new m(Q);return await Z.connect(),this.clients.set(Q.name,Z),Z}async removeServer(Q){let Z=this.clients.get(Q);if(Z)await Z.disconnect(),this.clients.delete(Q)}getServer(Q){return this.clients.get(Q)}listServers(){return Array.from(this.clients.keys())}getAllTools(){let Q=[];for(let[Z,Y]of this.clients)for(let H of Y.listTools())Q.push({...H,serverName:Z});return Q}async callTool(Q,Z={}){if(Q.includes("/")){let[Y,H]=Q.split("/",2),X=this.clients.get(Y);if(!X)throw Error(`MCP server not found: ${Y}`);return X.callTool(H,Z)}for(let[,Y]of this.clients)if(Y.listTools().some((X)=>X.name===Q))return Y.callTool(Q,Z);throw Error(`MCP tool not found: ${Q}`)}toAnthropicTools(){let Q=[];for(let[Z,Y]of this.clients)for(let H of Y.listTools())Q.push({name:`${Z}__${H.name}`,description:`[${Z}] ${H.description}`,input_schema:H.inputSchema});return Q}toOpenAITools(){let Q=[];for(let[Z,Y]of this.clients)for(let H of Y.listTools())Q.push({type:"function",function:{name:`${Z}__${H.name}`,description:`[${Z}] ${H.description}`,parameters:H.inputSchema}});return Q}async disconnectAll(){let Q=Array.from(this.clients.values()).map((Z)=>Z.disconnect());await Promise.all(Q),this.clients.clear()}}async function tZ(Q,Z,Y,H){let X=new m({name:Q,transport:{type:"stdio",command:Z,args:Y,env:H}});return await X.connect(),X}async function eZ(Q,Z,Y){let H=new m({name:Q,transport:{type:"streamable-http",url:Z,headers:Y}});return await H.connect(),H}var Y9={MCPClient:m,MCPManager:EQ,connectStdio:tZ,connectHTTP:eZ};import Q6 from"process";var s=null;async function VQ(){if(s)return s;let Q=await import("@stacksjs/ts-cloud/aws");if(!Q?.BedrockClient)throw Error("@stacksjs/ts-cloud/aws does not export BedrockClient \u2014 rebuild ts-cloud or remove the AI dependency.");return s=new Q.BedrockClient(Q6.env.REGION||"us-east-1"),s}async function J9(Q){return(await VQ()).createModelCustomizationJob(Q)}async function V9(Q){return(await VQ()).getModelCustomizationJob(Q)}async function G9(Q){return(await VQ()).listFoundationModels(Q)}function Z6(Q){let Z=Q.toLowerCase();if(Z.startsWith("gpt-"))return 3.5;if(Z.startsWith("claude"))return 3.5;return 3.5}function GQ(Q,Z="gpt-4o"){if(!Q)return 0;let Y=Z6(Z);return Math.max(1,Math.ceil(Q.length/Y))}function Y6(Q,Z="gpt-4o"){let X=2;for(let G of Q)if(X+=4,typeof G.content==="string")X+=GQ(G.content,Z);else if(Array.isArray(G.content)){for(let J of G.content)if(J.type==="text"&&J.text)X+=GQ(J.text,Z);else if(J.type==="image"||J.type==="image_url")X+=100}return X}var H6=[/\bignore\s+(?:all\s+)?(?:previous|prior|above)\s+instructions?\b/i,/\bdisregard\s+(?:all\s+)?(?:previous|prior|above)\b/i,/\bforget\s+(?:everything|all)\s+(?:you|i)\b/i,/\byou\s+are\s+now\s+a\s+\w+/i,/\bnew\s+instructions?:\s*/i,/\bsystem\s*[:>]\s*/i,/\b(?:reveal|show|print|output|display)\s+(?:your|the)\s+(?:system\s+)?prompt\b/i,/<\s*\/?\s*system\s*>/i,/\[INST\]|\[\/INST\]/i,/^\s*###\s+(?:instruction|system)/im];function X6(Q){if(!Q)return{ok:!0,matched:[],cleaned:Q};let Z=[],Y=Q;for(let H of H6)if(H.test(Y))Z.push(H.toString()),Y=Y.replace(H,"[redacted]");return{ok:Z.length===0,matched:Z,cleaned:Y}}import{log as $Q}from"@stacksjs/cli";import{ai as J6}from"@stacksjs/config";async function V6(){let Q=await import("@stacksjs/ts-cloud/aws");if(!Q?.BedrockClient)throw Error("@stacksjs/ts-cloud/aws does not export BedrockClient \u2014 rebuild ts-cloud or remove the AI dependency.");return new Q.BedrockClient("us-east-1")}async function j9(){let Q=await V6(),Z=J6.models;if(!Z)throw Error("No AI models found. Please set ./config/ai.ts values.");for(let Y of Z)try{$Q.info(`Requesting access to model ${Y}`);let H=await Q.requestModelAccess({modelId:Y});$Q.info(`Response for model ${Y}:`,H)}catch(H){$Q.error(`Error requesting access to model ${Y}:`,H)}}export{a6 as summarize,t6 as search,X6 as sanitizePrompt,KZ as resetPromptCount,j9 as requestModelAccess,h as recordUsage,sZ as recordInteraction,aZ as recommend,gZ as rag,f6 as pushChanges,UZ as processCommandStreaming,g6 as processCommand,Q9 as personalization,rQ as openaiDriver,sQ as openai,y6 as openRepository,CQ as onUsage,GZ as ollamaDriver,$Z as ollama,I as normalizeMessagesForProvider,Y9 as mcp,SQ as listUsageReporters,G9 as listFoundationModels,m6 as invokeModelWithResponseStream,HQ as invokeModel,lZ as indexText,s6 as image,MZ as getRepoContext,V9 as getModelCustomizationJob,UQ as getLastSessionId,FZ as getDriver,v6 as getAvailableDrivers,IZ as generateImage,S as fetchWithRetry,oZ as extractUserInterests,fZ as euclideanDistance,GQ as estimateTokens,Y6 as estimateMessageTokens,DZ as editImage,hZ as dotProduct,rZ as createProfile,g as createOpenAIDriver,c as createOllamaDriver,J9 as createModelCustomizationJob,CZ as createImageVariation,XQ as createEmbedding,BZ as createClaudeLocalAgent,OZ as createClaudeEC2Agent,a as createClaudeAgentSDKDriver,f as createAnthropicDriver,AQ as cosineSimilarity,tZ as connectStdio,eZ as connectHTTP,AZ as configureGitUser,h6 as commitChanges,xQ as clearUsageReporters,KQ as clearSession,zZ as claudeAgentSDK,n as claudeAgent,pZ as classifyText,_Q as chunkText,LZ as buildSystemPrompt,vQ as buildMessageWithImages,c6 as buddyStreamSimple,F as buddyState,u6 as buddyProcessStreaming,n6 as ask,b6 as applyChanges,D as apiKeys,uQ as anthropicDriver,cQ as anthropic,mZ as analyzeSentiment,vZ as analyzeImages,xZ as analyzeImage,JQ as VectorIndex,EQ as MCPManager,m as MCPClient,b as CONFIG};
175
+ `;if(this.config.transport.type==="stdio"&&this.process){let H=this.process.stdin?.getWriter();if(H)await H.write(new TextEncoder().encode(Y)),H.releaseLock()}}async discoverCapabilities(){let Q=this.config.capabilities||{tools:!0,resources:!0,prompts:!0};if(Q.tools!==!1)try{let Z=await this.sendRequest("tools/list");this.tools=Z?.tools||[]}catch{this.tools=[]}if(Q.resources!==!1)try{let Z=await this.sendRequest("resources/list");this.resources=Z?.resources||[]}catch{this.resources=[]}if(Q.prompts!==!1)try{let Z=await this.sendRequest("prompts/list");this.prompts=Z?.prompts||[]}catch{this.prompts=[]}}listTools(){return this.tools}listResources(){return this.resources}listPrompts(){return this.prompts}async callTool(Q,Z={}){if(!this.initialized)throw Error("MCP client not connected. Call connect() first.");return await this.sendRequest("tools/call",{name:Q,arguments:Z})}async readResource(Q){if(!this.initialized)throw Error("MCP client not connected. Call connect() first.");let Y=(await this.sendRequest("resources/read",{uri:Q}))?.contents?.[0];return{uri:Y?.uri||Q,mimeType:Y?.mimeType,text:Y?.text,blob:Y?.blob}}async getPrompt(Q,Z={}){if(!this.initialized)throw Error("MCP client not connected. Call connect() first.");return this.sendRequest("prompts/get",{name:Q,arguments:Z})}toAnthropicTools(){return this.tools.map((Q)=>({name:Q.name,description:Q.description,input_schema:Q.inputSchema}))}toOpenAITools(){return this.tools.map((Q)=>({type:"function",function:{name:Q.name,description:Q.description,parameters:Q.inputSchema}}))}async disconnect(){if(this.process)this.process.kill(),this.process=null;for(let Q of this.pendingRequests.values())try{Q.reject(Error("MCP client disconnected"))}catch{}this.pendingRequests.clear(),this.initialized=!1,this.tools=[],this.resources=[],this.prompts=[]}get isConnected(){return this.initialized}get serverName(){return this.config.name}}class EQ{clients=new Map;async addServer(Q){if(this.clients.has(Q.name))throw Error(`MCP server already registered: ${Q.name}`);let Z=new m(Q);return await Z.connect(),this.clients.set(Q.name,Z),Z}async removeServer(Q){let Z=this.clients.get(Q);if(Z)await Z.disconnect(),this.clients.delete(Q)}getServer(Q){return this.clients.get(Q)}listServers(){return Array.from(this.clients.keys())}getAllTools(){let Q=[];for(let[Z,Y]of this.clients)for(let H of Y.listTools())Q.push({...H,serverName:Z});return Q}async callTool(Q,Z={}){if(Q.includes("/")){let[Y,H]=Q.split("/",2);if(!Y||!H)throw Error(`Invalid MCP tool path: ${Q}`);let X=this.clients.get(Y);if(!X)throw Error(`MCP server not found: ${Y}`);return X.callTool(H,Z)}for(let[,Y]of this.clients)if(Y.listTools().some((X)=>X.name===Q))return Y.callTool(Q,Z);throw Error(`MCP tool not found: ${Q}`)}toAnthropicTools(){let Q=[];for(let[Z,Y]of this.clients)for(let H of Y.listTools())Q.push({name:`${Z}__${H.name}`,description:`[${Z}] ${H.description}`,input_schema:H.inputSchema});return Q}toOpenAITools(){let Q=[];for(let[Z,Y]of this.clients)for(let H of Y.listTools())Q.push({type:"function",function:{name:`${Z}__${H.name}`,description:`[${Z}] ${H.description}`,parameters:H.inputSchema}});return Q}async disconnectAll(){let Q=Array.from(this.clients.values()).map((Z)=>Z.disconnect());await Promise.all(Q),this.clients.clear()}}async function tZ(Q,Z,Y,H){let X=new m({name:Q,transport:{type:"stdio",command:Z,args:Y,env:H}});return await X.connect(),X}async function eZ(Q,Z,Y){let H=new m({name:Q,transport:{type:"streamable-http",url:Z,headers:Y}});return await H.connect(),H}var Y9={MCPClient:m,MCPManager:EQ,connectStdio:tZ,connectHTTP:eZ};import Q6 from"process";var s=null;async function VQ(){if(s)return s;let Q=await import("@stacksjs/ts-cloud/aws");if(!Q?.BedrockClient)throw Error("@stacksjs/ts-cloud/aws does not export BedrockClient \u2014 rebuild ts-cloud or remove the AI dependency.");return s=new Q.BedrockClient(Q6.env.REGION||"us-east-1"),s}async function J9(Q){return(await VQ()).createModelCustomizationJob(Q)}async function V9(Q){return(await VQ()).getModelCustomizationJob(Q)}async function G9(Q){return(await VQ()).listFoundationModels(Q)}function Z6(Q){let Z=Q.toLowerCase();if(Z.startsWith("gpt-"))return 3.5;if(Z.startsWith("claude"))return 3.5;return 3.5}function GQ(Q,Z="gpt-4o"){if(!Q)return 0;let Y=Z6(Z);return Math.max(1,Math.ceil(Q.length/Y))}function Y6(Q,Z="gpt-4o"){let X=2;for(let G of Q)if(X+=4,typeof G.content==="string")X+=GQ(G.content,Z);else if(Array.isArray(G.content)){for(let J of G.content)if(J.type==="text"&&J.text)X+=GQ(J.text,Z);else if(J.type==="image"||J.type==="image_url")X+=100}return X}var H6=[/\bignore\s+(?:all\s+)?(?:previous|prior|above)\s+instructions?\b/i,/\bdisregard\s+(?:all\s+)?(?:previous|prior|above)\b/i,/\bforget\s+(?:everything|all)\s+(?:you|i)\b/i,/\byou\s+are\s+now\s+a\s+\w+/i,/\bnew\s+instructions?:\s*/i,/\bsystem\s*[:>]\s*/i,/\b(?:reveal|show|print|output|display)\s+(?:your|the)\s+(?:system\s+)?prompt\b/i,/<\s*\/?\s*system\s*>/i,/\[INST\]|\[\/INST\]/i,/^\s*###\s+(?:instruction|system)/im];function X6(Q){if(!Q)return{ok:!0,matched:[],cleaned:Q};let Z=[],Y=Q;for(let H of H6)if(H.test(Y))Z.push(H.toString()),Y=Y.replace(H,"[redacted]");return{ok:Z.length===0,matched:Z,cleaned:Y}}import{log as $Q}from"@stacksjs/cli";import{ai as J6}from"@stacksjs/config";async function V6(){let Q=await import("@stacksjs/ts-cloud/aws");if(!Q?.BedrockClient)throw Error("@stacksjs/ts-cloud/aws does not export BedrockClient \u2014 rebuild ts-cloud or remove the AI dependency.");return new Q.BedrockClient("us-east-1")}async function j9(){let Q=await V6(),Z=J6.models;if(!Z)throw Error("No AI models found. Please set ./config/ai.ts values.");for(let Y of Z)try{$Q.info(`Requesting access to model ${Y}`);let H=await Q.requestModelAccess({modelId:Y});$Q.info(`Response for model ${Y}:`,H)}catch(H){$Q.error(`Error requesting access to model ${Y}:`,H)}}export{a6 as summarize,t6 as search,X6 as sanitizePrompt,KZ as resetPromptCount,j9 as requestModelAccess,h as recordUsage,sZ as recordInteraction,aZ as recommend,gZ as rag,f6 as pushChanges,UZ as processCommandStreaming,g6 as processCommand,Q9 as personalization,rQ as openaiDriver,sQ as openai,y6 as openRepository,CQ as onUsage,GZ as ollamaDriver,$Z as ollama,I as normalizeMessagesForProvider,Y9 as mcp,SQ as listUsageReporters,G9 as listFoundationModels,m6 as invokeModelWithResponseStream,HQ as invokeModel,lZ as indexText,s6 as image,MZ as getRepoContext,V9 as getModelCustomizationJob,UQ as getLastSessionId,FZ as getDriver,v6 as getAvailableDrivers,IZ as generateImage,S as fetchWithRetry,oZ as extractUserInterests,fZ as euclideanDistance,GQ as estimateTokens,Y6 as estimateMessageTokens,DZ as editImage,hZ as dotProduct,rZ as createProfile,g as createOpenAIDriver,c as createOllamaDriver,J9 as createModelCustomizationJob,CZ as createImageVariation,XQ as createEmbedding,BZ as createClaudeLocalAgent,OZ as createClaudeEC2Agent,a as createClaudeAgentSDKDriver,f as createAnthropicDriver,AQ as cosineSimilarity,tZ as connectStdio,eZ as connectHTTP,AZ as configureGitUser,h6 as commitChanges,xQ as clearUsageReporters,KQ as clearSession,zZ as claudeAgentSDK,n as claudeAgent,pZ as classifyText,_Q as chunkText,NZ as buildSystemPrompt,vQ as buildMessageWithImages,c6 as buddyStreamSimple,F as buddyState,u6 as buddyProcessStreaming,n6 as ask,b6 as applyChanges,D as apiKeys,uQ as anthropicDriver,cQ as anthropic,mZ as analyzeSentiment,vZ as analyzeImages,xZ as analyzeImage,JQ as VectorIndex,EQ as MCPManager,m as MCPClient,b as CONFIG};
package/dist/mcp.d.ts CHANGED
@@ -10,7 +10,10 @@ export declare function connectHTTP(name: string, url: string, headers?: Record<
10
10
  // Exports
11
11
  // ============================================================================
12
12
  export declare const mcp: {
13
-
13
+ MCPClient: typeof MCPClient;
14
+ MCPManager: typeof MCPManager;
15
+ connectStdio: typeof connectStdio;
16
+ connectHTTP: typeof connectHTTP
14
17
  };
15
18
  /**
16
19
  * MCP (Model Context Protocol) Module
@@ -14,6 +14,15 @@ export declare function classifyText(text: string, labels: string[], options?: {
14
14
  model?: string
15
15
  multiLabel?: boolean
16
16
  }): Promise<ClassificationResult>;
17
+ /**
18
+ * Generate an intelligent summary of text.
19
+ *
20
+ * Not exported as a bare top-level identifier because `text.ts` already
21
+ * exposes `summarize`, and `index.ts` re-exports both via `export *`.
22
+ * Reach this multi-provider variant through the `personalization`
23
+ * namespace export below: `personalization.summarize(...)`.
24
+ */
25
+ declare function summarize(text: string, options?: SummaryOptions): Promise<AIResult>;
17
26
  /**
18
27
  * Generate personalized content recommendations based on user profile and available items.
19
28
  */
@@ -34,7 +43,13 @@ export declare function extractUserInterests(profile: UserProfile, items: Conten
34
43
  // Exports
35
44
  // ============================================================================
36
45
  export declare const personalization: {
37
-
46
+ analyzeSentiment: typeof analyzeSentiment;
47
+ classifyText: typeof classifyText;
48
+ summarize: typeof summarize;
49
+ recommend: typeof recommend;
50
+ createProfile: typeof createProfile;
51
+ recordInteraction: typeof recordInteraction;
52
+ extractUserInterests: typeof extractUserInterests
38
53
  };
39
54
  // ============================================================================
40
55
  // Types
package/dist/search.d.ts CHANGED
@@ -2,7 +2,10 @@ import type { AIResult } from './types';
2
2
  /**
3
3
  * Generate embeddings for text input.
4
4
  */
5
- export declare function createEmbedding(input: string | string[], options?: EmbeddingOptions): Promise<number[] | number[][]>;
5
+ // eslint-disable-next-line pickier/no-unused-vars
6
+ export declare function createEmbedding(input: string, options?: EmbeddingOptions): Promise<number[]>;
7
+ // eslint-disable-next-line pickier/no-unused-vars
8
+ export declare function createEmbedding(input: string[], options?: EmbeddingOptions): Promise<number[][]>;
6
9
  /**
7
10
  * Calculate cosine similarity between two vectors.
8
11
  */
@@ -31,7 +34,14 @@ export declare function indexText(text: string, options?: ChunkOptions & Embeddi
31
34
  // Exports
32
35
  // ============================================================================
33
36
  export declare const search: {
34
-
37
+ createEmbedding: typeof createEmbedding;
38
+ cosineSimilarity: typeof cosineSimilarity;
39
+ dotProduct: typeof dotProduct;
40
+ euclideanDistance: typeof euclideanDistance;
41
+ VectorIndex: typeof VectorIndex;
42
+ rag: typeof rag;
43
+ chunkText: typeof chunkText;
44
+ indexText: typeof indexText
35
45
  };
36
46
  // ============================================================================
37
47
  // Types
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/ai",
3
3
  "type": "module",
4
- "version": "0.70.72",
4
+ "version": "0.70.74",
5
5
  "description": "Stacks Artificial Intelligence.",
6
6
  "author": "Chris Breuer",
7
7
  "contributors": [
@@ -59,7 +59,7 @@
59
59
  "prepublishOnly": "bun run build"
60
60
  },
61
61
  "dependencies": {
62
- "@stacksjs/ts-cloud": "^0.7.12"
62
+ "@stacksjs/ts-cloud": "^0.7.14"
63
63
  },
64
64
  "peerDependencies": {
65
65
  "@anthropic-ai/claude-agent-sdk": "^0.2.79"
@@ -70,6 +70,7 @@
70
70
  }
71
71
  },
72
72
  "devDependencies": {
73
- "better-dx": "^0.2.12"
73
+ "@anthropic-ai/claude-agent-sdk": "^0.2.79",
74
+ "better-dx": "^0.2.16"
74
75
  }
75
76
  }