ai-ax 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@ declare const grantOf: (request: Request) => Grant;
12
12
  declare const createAiax: (config: Config) => {
13
13
  config: Config;
14
14
  Server: typeof AiaxServer;
15
- use: () => import("hono").MiddlewareHandler<any, string, {}, Response>;
15
+ all: () => import("hono").MiddlewareHandler<any, string, {}, Response>;
16
16
  auth: () => import("hono").MiddlewareHandler;
17
17
  party: () => import("hono").MiddlewareHandler<any, string, {}, any>;
18
18
  mcp: () => import("hono").MiddlewareHandler<any, string, {}, Response>;
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  import{action as e,actions as t,bind as n,data as r,init as i,side as a}from"./action.js";import{f as o,m as s,n as c,o as l,r as u,t as d}from"./const-DMb65zjR.js";import{AiaxServer as f}from"./server.js";import{createMiddleware as p}from"hono/factory";import m from"@auth/core/providers/google";import{decode as h,encode as g}from"@auth/core/jwt";import{DrizzleAdapter as _}from"@auth/drizzle-adapter";import{getAuthUser as v,initAuthConfig as y}from"@hono/auth-js";import{drizzle as b}from"drizzle-orm/d1";import{env as x}from"hono/adapter";import{streamText as S}from"hono/streaming";import{StreamableHTTPTransport as C}from"@hono/mcp";import{McpServer as w}from"@modelcontextprotocol/sdk/server/mcp.js";import{getServerByName as T,routePartykitRequest as E}from"partyserver";const D=e=>y(t=>{let n=new URL(t.req.url).host,r=!!e.cookie&&e.cookie.services.some(t=>n===`${t}.${e.cookie.apex}`),i={sessionToken:{options:{domain:`.${e.cookie?.apex}`}}},a=e.providers??[m({clientId:t.env.GOOGLE_CLIENT_ID,clientSecret:t.env.GOOGLE_CLIENT_SECRET})];return{...e.database?{adapter:_(b(e.database(t.env)))}:{},providers:a,secret:t.env.AUTH_SECRET,session:{strategy:`jwt`},...r?{cookies:i}:{}}}),O=async e=>(await v(e))?.token?.sub??``,k=(e,t,n,r)=>g({token:{sub:t,path:n},secret:x(e).AUTH_SECRET,salt:r?.salt??`authjs.mcp-token`,maxAge:r?.maxAge??43200}),A=async(e,t)=>{let n=(e.req.header(`Authorization`)??``).replace(/^Bearer\s+/i,``);if(!n)return null;let r=await h({token:n,secret:x(e).AUTH_SECRET,salt:t?.salt??`authjs.mcp-token`}).catch(()=>null);return{sub:r?.sub??``,path:r?.path??``}},j=(e,t=`site`)=>async(n,r,i)=>!r||!i?``:(await e(n).head(`${r}/${i}`))?.customMetadata?.[t]??``,M=()=>(e,t)=>t,N=e=>e.startsWith(`data:`)?JSON.parse(e.slice(5)):null,P=(e,t,n)=>fetch(e.api,{method:`POST`,headers:{"x-api-key":e.key,"anthropic-version":l,"anthropic-beta":u,"content-type":`application/json`},body:JSON.stringify({model:e.model,max_tokens:e.maxTokens,stream:!0,cache_control:{type:`ephemeral`},system:e.system,mcp_servers:[{type:`url`,url:e.url,name:e.name,...t?{authorization_token:t}:{}}],tools:[{type:`mcp_toolset`,mcp_server_name:e.name}],messages:n})}),F=async(e,t)=>{let n=[],r=null,i=0,a=0,o=0,s=``,c=e.body.getReader(),l=new TextDecoder,u=``;for(;;){let{done:e,value:d}=await c.read();if(e)break;u+=l.decode(d,{stream:!0});let f=u.split(`
2
- `);u=f.pop()??``;for(let e of f){let c=N(e);if(c){if(c.type===`message_start`){let e=c.message?.usage??{};i+=(e.input_tokens??0)+(e.cache_creation_input_tokens??0)+(e.cache_read_input_tokens??0),a+=e.cache_read_input_tokens??0}c.type===`message_delta`&&(o=c.usage?.output_tokens??o,s=c.delta?.stop_reason??s),c.type===`content_block_start`&&(r={...c.content_block},n.push(r),r.type===`mcp_tool_use`&&await t(`\n[tool] ${r.name}\n`)),c.type===`content_block_delta`&&c.delta?.type===`text_delta`&&(r.text=(r.text??``)+c.delta.text,await t(c.delta.text)),c.type===`content_block_delta`&&c.delta?.type===`input_json_delta`&&(r.partial=(r.partial??``)+c.delta.partial_json),c.type===`content_block_delta`&&c.delta?.type===`thinking_delta`&&(r.thinking=(r.thinking??``)+c.delta.thinking),c.type===`content_block_delta`&&c.delta?.type===`signature_delta`&&(r.signature=(r.signature??``)+c.delta.signature),c.type===`content_block_stop`&&r?.partial!==void 0&&(r.input=r.partial?JSON.parse(r.partial):{},delete r.partial)}}}return{blocks:n,input:i,cached:a,output:o,stop:s}},I=async(e,t,n,r,i,a=10)=>{let o=r,s=0,c=0,l=0,u=``;for(let r=0;r<a;r++){let r=await F(o,i);if(s+=r.input,c+=r.cached,l+=r.output,u=r.stop||u,u!==`pause_turn`)break;if(n.push({role:`assistant`,content:r.blocks.filter(e=>e.type!==`thinking`||e.thinking||e.signature)}),o=await P(e,await t(),n),!o.ok){await i(await o.text());break}}await i(`\n[usage] input ${s} (cache ${c}) / output ${l} tokens (${u})\n`)},L=e=>p(async t=>{let n=await O(t),{path:r=``,prompt:i}=await t.req.json(),a=!!e.lobby&&!r;if(!a&&!n)return t.text(`Unauthorized`,401);if(!a&&!await e.own(x(t),n,r))return t.text(`Forbidden`,403);let o=t.req.header(`x-original-host`)??t.req.header(`x-forwarded-host`)??new URL(t.req.url).host,s={key:x(t).ANTHROPIC_API_KEY,api:e.claude??`https://api.anthropic.com/v1/messages`,name:e.name,url:`https://${o}${e.endpoint??`/api/mcp`}`,model:e.model??`claude-sonnet-5`,system:e.system??``,maxTokens:e.maxTokens??32e3},c=()=>a?Promise.resolve(``):k(t,n,r,e),l=[{role:`user`,content:i}],u=await P(s,await c(),l);return u.ok?S(t,t=>I(s,c,l,u,e=>t.write(e),e.maxTurns??10)):t.text(await u.text(),500)}),R=e=>({sub:e.headers.get(`x-user-sub`)??``,path:decodeURIComponent(e.headers.get(`x-user-path`)??``)}),z=async(e,t,n,r,i)=>{let a=await T(e,t),c={[s]:n.sub,[o]:encodeURIComponent(n.path)};return(await a.fetch(`https://internal/act`,{method:`POST`,headers:c,body:JSON.stringify({name:r,input:i})})).json()},B=(e,t)=>p(async n=>{let r=await A(n,e),i=r?.sub??``,a=r?.path??``,o=e.lobby??``;if(r||!o){if(!i)return n.text(`Unauthorized`,401);if(o=await e.own(x(n),i,a),!o)return n.text(`Forbidden`,403)}let s=new w({name:e.name,version:e.version??`1.0.0`}),c=new C;return t.forEach((t,r)=>s.registerTool(r,{description:t.description,inputSchema:{...t.input}},async t=>{let s=await z(x(n)[e.binding??`v1`],o,{sub:i,path:a},r,t);return{content:[{type:`text`,text:JSON.stringify(s)}]}})),await s.connect(c),c.handleRequest(n)}),V=async(e,t,n,r)=>{let i=new Headers(e.req.raw.headers);i.set(s,n),i.set(o,encodeURIComponent(r));let a=new URL(e.req.url),c=a.pathname.split(`/`);c[3]=encodeURIComponent(t),a.pathname=c.join(`/`);let l=new Request(a,new Request(e.req.raw,{headers:i}));return await E(l,x(e))??e.text(`Not Found`,404)},H=e=>p(async t=>{let n=decodeURIComponent(t.req.path.split(`/`)[3]??``),r=t.req.query(`path`)??``,i=await O(t);if(e.lobby&&n===e.lobby)return V(t,n,i,r);if(!i)return t.text(`Unauthorized`,401);let a=await e.own(x(t),i,r);return!a||n!==a&&n!==(e.alias??`my-room`)?t.text(`Forbidden`,403):V(t,a,i,r)}),U=e=>{let n={auth:D(e),party:H(e),mcp:B(e,t),llm:L(e)},r=p(async(t,r)=>{let i=()=>t.req.path.startsWith(`/parties/`)?n.party(t,r):t.req.path===(e.endpoint??`/api/mcp`)?n.mcp(t,r):t.req.path===`/api/llm`&&t.req.method===`POST`?n.llm(t,r):r(),a;if(await n.auth(t,async()=>void(a=await i())),a)return a});return{config:e,Server:f,use:()=>r,auth:()=>n.auth,party:()=>n.party,mcp:()=>n.mcp,llm:()=>n.llm}};export{d as ALIAS,f as AiaxServer,c as BINDING,e as action,t as actions,n as bind,U as createAiax,r as data,R as grantOf,i as init,M as ownSelf,j as ownSite,a as side};
2
+ `);u=f.pop()??``;for(let e of f){let c=N(e);if(c){if(c.type===`message_start`){let e=c.message?.usage??{};i+=(e.input_tokens??0)+(e.cache_creation_input_tokens??0)+(e.cache_read_input_tokens??0),a+=e.cache_read_input_tokens??0}c.type===`message_delta`&&(o=c.usage?.output_tokens??o,s=c.delta?.stop_reason??s),c.type===`content_block_start`&&(r={...c.content_block},n.push(r),r.type===`mcp_tool_use`&&await t(`\n[tool] ${r.name}\n`)),c.type===`content_block_delta`&&c.delta?.type===`text_delta`&&(r.text=(r.text??``)+c.delta.text,await t(c.delta.text)),c.type===`content_block_delta`&&c.delta?.type===`input_json_delta`&&(r.partial=(r.partial??``)+c.delta.partial_json),c.type===`content_block_delta`&&c.delta?.type===`thinking_delta`&&(r.thinking=(r.thinking??``)+c.delta.thinking),c.type===`content_block_delta`&&c.delta?.type===`signature_delta`&&(r.signature=(r.signature??``)+c.delta.signature),c.type===`content_block_stop`&&r?.partial!==void 0&&(r.input=r.partial?JSON.parse(r.partial):{},delete r.partial)}}}return{blocks:n,input:i,cached:a,output:o,stop:s}},I=async(e,t,n,r,i,a=10)=>{let o=r,s=0,c=0,l=0,u=``;for(let r=0;r<a;r++){let r=await F(o,i);if(s+=r.input,c+=r.cached,l+=r.output,u=r.stop||u,u!==`pause_turn`)break;if(n.push({role:`assistant`,content:r.blocks.filter(e=>e.type!==`thinking`||e.thinking||e.signature)}),o=await P(e,await t(),n),!o.ok){await i(await o.text());break}}await i(`\n[usage] input ${s} (cache ${c}) / output ${l} tokens (${u})\n`)},L=e=>p(async t=>{let n=await O(t),{path:r=``,prompt:i}=await t.req.json(),a=!!e.lobby&&!r;if(!a&&!n)return t.text(`Unauthorized`,401);if(!a&&!await e.own(x(t),n,r))return t.text(`Forbidden`,403);let o=t.req.header(`x-original-host`)??t.req.header(`x-forwarded-host`)??new URL(t.req.url).host,s={key:x(t).ANTHROPIC_API_KEY,api:e.claude??`https://api.anthropic.com/v1/messages`,name:e.name,url:`https://${o}${e.endpoint??`/api/mcp`}`,model:e.model??`claude-sonnet-5`,system:e.system??``,maxTokens:e.maxTokens??32e3},c=()=>a?Promise.resolve(``):k(t,n,r,e),l=[{role:`user`,content:i}],u=await P(s,await c(),l);return u.ok?S(t,t=>I(s,c,l,u,e=>t.write(e),e.maxTurns??10)):t.text(await u.text(),500)}),R=e=>({sub:e.headers.get(`x-user-sub`)??``,path:decodeURIComponent(e.headers.get(`x-user-path`)??``)}),z=async(e,t,n,r,i)=>{let a=await T(e,t),c={[s]:n.sub,[o]:encodeURIComponent(n.path)};return(await a.fetch(`https://internal/act`,{method:`POST`,headers:c,body:JSON.stringify({name:r,input:i})})).json()},B=(e,t)=>p(async n=>{let r=await A(n,e),i=r?.sub??``,a=r?.path??``,o=e.lobby??``;if(r||!o){if(!i)return n.text(`Unauthorized`,401);if(o=await e.own(x(n),i,a),!o)return n.text(`Forbidden`,403)}let s=new w({name:e.name,version:e.version??`1.0.0`}),c=new C;return t.forEach((t,r)=>s.registerTool(r,{description:t.description,inputSchema:{...t.input}},async t=>{let s=await z(x(n)[e.binding??`v1`],o,{sub:i,path:a},r,t);return{content:[{type:`text`,text:JSON.stringify(s)}]}})),await s.connect(c),c.handleRequest(n)}),V=async(e,t,n,r)=>{let i=new Headers(e.req.raw.headers);i.set(s,n),i.set(o,encodeURIComponent(r));let a=new URL(e.req.url),c=a.pathname.split(`/`);c[3]=encodeURIComponent(t),a.pathname=c.join(`/`);let l=new Request(a,new Request(e.req.raw,{headers:i}));return await E(l,x(e))??e.text(`Not Found`,404)},H=e=>p(async t=>{let n=decodeURIComponent(t.req.path.split(`/`)[3]??``),r=t.req.query(`path`)??``,i=await O(t);if(e.lobby&&n===e.lobby)return V(t,n,i,r);if(!i)return t.text(`Unauthorized`,401);let a=await e.own(x(t),i,r);return!a||n!==a&&n!==(e.alias??`my-room`)?t.text(`Forbidden`,403):V(t,a,i,r)}),U=e=>{let n={auth:D(e),party:H(e),mcp:B(e,t),llm:L(e)},r=p(async(t,r)=>{let i=()=>t.req.path.startsWith(`/parties/`)?n.party(t,r):t.req.path===(e.endpoint??`/api/mcp`)?n.mcp(t,r):t.req.path===`/api/llm`&&t.req.method===`POST`?n.llm(t,r):r(),a;if(await n.auth(t,async()=>void(a=await i())),a)return a});return{config:e,Server:f,all:()=>r,auth:()=>n.auth,party:()=>n.party,mcp:()=>n.mcp,llm:()=>n.llm}};export{d as ALIAS,f as AiaxServer,c as BINDING,e as action,t as actions,n as bind,U as createAiax,r as data,R as grantOf,i as init,M as ownSelf,j as ownSite,a as side};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ai-ax",
3
3
  "author": "tseijp",
4
- "version": "0.1.0",
4
+ "version": "0.1.1",
5
5
  "license": "MIT",
6
6
  "description": "AI Agent Experience (AI/AX) library for Hono + Cloudflare. One act surface for both human UI/UX and LLM MCP tools, with authentication, authorization, realtime sync and Claude API relay.",
7
7
  "keywords": [