ai-ax 0.1.1 → 0.3.0

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/README.md CHANGED
@@ -40,7 +40,7 @@ flowchart TB
40
40
  worker には 4 つの middleware を並べるだけでよい。
41
41
 
42
42
  ```ts
43
- const ax = createAiax({ name: 'demo', own: ownSelf(), database: (e) => e.my_d1_demo, system: PROMPT })
43
+ const ax = createAiax({ name: 'demo', own: ownSelf(), database: (e) => e.my_d1_aiax, system: PROMPT })
44
44
  const app = new Hono().use('*', ax.auth()).use('/parties/*', ax.party()).all('/api/mcp', ax.mcp()).post('/api/llm', ax.llm())
45
45
  ```
46
46
 
package/dist/action.d.ts CHANGED
@@ -1,2 +1,13 @@
1
- import { a as data, i as bind, n as action, o as init, r as actions, s as side, t as Call } from "./action-DItZAgdx.js";
1
+ import { ActMeta, ActionDef, Side } from "./types.js";
2
+ import * as Y from "yjs";
3
+ //#region src/action.d.ts
4
+ type Action<I, R> = (input: I) => R | Promise<R>;
5
+ type Call = (name: string, input: any) => Promise<any>;
6
+ declare const actions: Map<string, ActionDef>;
7
+ declare const side: Side;
8
+ declare const bind: (doc: Y.Doc) => Y.Doc;
9
+ declare const data: <T = any>(name?: string) => Y.Map<T>;
10
+ declare function action<I extends object, R>(load: Action<I, R> | ((input?: I) => any), at: Side, meta: ActMeta): (input: I) => Promise<R>;
11
+ declare const init: (doc: Y.Doc, wrap?: (run: () => Promise<any>) => Promise<any>) => Call;
12
+ //#endregion
2
13
  export { Call, action, actions, bind, data, init, side };
package/dist/client.d.ts CHANGED
@@ -1,6 +1,32 @@
1
- import { a as data, c as ActMeta, i as bind, l as ActionDef, m as Side, n as action, o as init, r as actions, s as side, t as Call } from "./action-DItZAgdx.js";
2
- import { n as BINDING, t as ALIAS } from "./const-Hb5KgSHO.js";
1
+ import { ActMeta, ActionDef, Side } from "./types.js";
2
+ import { Call, action, actions, bind, data, init, side } from "./action.js";
3
+ import { ALIAS, BINDING } from "./const.js";
3
4
  import * as Y from "yjs";
5
+ //#region src/browser/stream.d.ts
6
+ interface StreamTool {
7
+ server: string;
8
+ name: string;
9
+ }
10
+ interface StreamItem {
11
+ text: string;
12
+ tools: StreamTool[];
13
+ }
14
+ interface StreamSend {
15
+ prompt: string;
16
+ path?: string;
17
+ model?: string;
18
+ headers?: Record<string, string>;
19
+ }
20
+ interface StreamUpdate {
21
+ items: StreamItem[];
22
+ delta: string;
23
+ raw: string;
24
+ }
25
+ declare const createStream: (endpoint?: string) => {
26
+ parse: (raw: string) => StreamItem[];
27
+ send: (input: StreamSend, update?: (u: StreamUpdate) => void) => Promise<StreamItem[]>;
28
+ };
29
+ //#endregion
4
30
  //#region src/client.d.ts
5
31
  interface Route {
6
32
  room?: string;
@@ -18,4 +44,4 @@ interface Link {
18
44
  declare const onLeave: (fn: () => void) => undefined;
19
45
  declare const connect: (route?: Route) => Link;
20
46
  //#endregion
21
- export { ALIAS, type ActMeta, type ActionDef, BINDING, Link, Route, type Side, action, actions, bind, connect, data, init, onLeave, side };
47
+ export { ALIAS, type ActMeta, type ActionDef, BINDING, Link, Route, type Side, type StreamItem, type StreamSend, type StreamTool, type StreamUpdate, action, actions, bind, connect, createStream, data, init, onLeave, side };
package/dist/client.js CHANGED
@@ -1 +1,2 @@
1
- import{action as e,actions as t,bind as n,data as r,init as i,side as a}from"./action.js";import{n as o,t as s}from"./const-DMb65zjR.js";import c from"y-partyserver/provider";import*as l from"yjs";let u=null,d=new Set;const f=e=>void d.add(e),p=(e={})=>{u?.leave();let{room:t=``,path:n=``,host:r=location.host,party:a=`v1`,doc:o}=e,s=t?new c(r,t,o,{party:a,params:{path:n}}):null,f=s?.doc??o??new l.Doc;return u={doc:f,call:i(f),synced:e=>{if(!s||s.synced)return void e();s.once(`synced`,()=>e())},leave:()=>{d.forEach(e=>e()),d=new Set,s?.destroy()}}};export{s as ALIAS,o as BINDING,e as action,t as actions,n as bind,p as connect,r as data,i as init,f as onLeave,a as side};
1
+ import{ALIAS as e,BINDING as t,LLM_PATH as n}from"./const.js";import{action as r,actions as i,bind as a,data as o,init as s,side as c}from"./action.js";import l from"y-partyserver/provider";import*as u from"yjs";const d=/^\[tool\] (?:(\S+) )?(\S+)$/,f=(e=n)=>{let t=e=>{let t=[{text:``,tools:[]}],n=!1;for(let r of e.split(`
2
+ `)){if(r.startsWith(`[usage]`))continue;let e=d.exec(r),i=t[t.length-1];if(e){i.tools.push({server:e[1]??``,name:e[2]}),n=!0;continue}if(!(n&&r.trim()===``)){if(n){t.push({text:r,tools:[]}),n=!1;continue}i.text=i.text===``?r:`${i.text}\n${r}`}}return t.map(e=>({...e,text:e.text.trim()})).filter(e=>e.text!==``||e.tools.length>0)};return{parse:t,send:async(n,r)=>{let{headers:i={},...a}=n,o=(await fetch(e,{method:`POST`,headers:{"content-type":`application/json`,...i},body:JSON.stringify(a)})).body.getReader(),s=new TextDecoder,c=``;for(;;){let{done:e,value:n}=await o.read();if(e)break;let i=s.decode(n,{stream:!0});c+=i,r?.({items:t(c),delta:i,raw:c})}return t(c)}}};let p=null,m=new Set;const h=e=>void m.add(e),g=(e={})=>{p?.leave();let{room:t=``,path:n=``,host:r=location.host,party:i=`v1`,doc:a}=e,o=t?new l(r,t,a,{party:i,params:{path:n}}):null,c=o?.doc??a??new u.Doc;return p={doc:c,call:s(c),synced(e){if(!o||o.synced)return void e();o.once(`synced`,()=>e())},leave(){m.forEach(e=>e()),m=new Set,o?.destroy()}}};export{e as ALIAS,t as BINDING,r as action,i as actions,a as bind,g as connect,f as createStream,o as data,s as init,h as onLeave,c as side};
@@ -0,0 +1,10 @@
1
+ //#region src/const.d.ts
2
+ declare const ALIAS = "my-room";
3
+ declare const SUB_HEADER = "x-user-sub";
4
+ declare const PATH_HEADER = "x-user-path";
5
+ declare const BINDING = "v1";
6
+ declare const MCP_PATH = "/api/mcp";
7
+ declare const LLM_PATH = "/api/llm";
8
+ declare const MAX_TURNS = 10;
9
+ //#endregion
10
+ export { ALIAS, BINDING, LLM_PATH, MAX_TURNS, MCP_PATH, PATH_HEADER, SUB_HEADER };
package/dist/const.js ADDED
@@ -0,0 +1 @@
1
+ const e=`my-room`,t=`x-user-sub`,n=`x-user-path`,r=`v1`,i=`/api/mcp`,a=`/api/llm`,o=10;export{e as ALIAS,r as BINDING,a as LLM_PATH,o as MAX_TURNS,i as MCP_PATH,n as PATH_HEADER,t as SUB_HEADER};
package/dist/index.d.ts CHANGED
@@ -1,17 +1,11 @@
1
- import { a as data, c as ActMeta, d as Cookie, f as Grant, i as bind, l as ActionDef, m as Side, n as action, o as init, p as Own, r as actions, s as side, t as Call, u as Config } from "./action-DItZAgdx.js";
2
- import { n as BINDING, t as ALIAS } from "./const-Hb5KgSHO.js";
3
- import { AiaxServer } from "./server.js";
4
- //#region src/auth.d.ts
1
+ import { Config, Own } from "./types.js";
2
+ //#region src/worker/auth.d.ts
5
3
  declare const ownSite: (bucket: (env: any) => any, meta?: string) => Own;
6
4
  declare const ownSelf: () => Own;
7
5
  //#endregion
8
- //#region src/mcp.d.ts
9
- declare const grantOf: (request: Request) => Grant;
10
- //#endregion
11
6
  //#region src/index.d.ts
12
7
  declare const createAiax: (config: Config) => {
13
8
  config: Config;
14
- Server: typeof AiaxServer;
15
9
  all: () => import("hono").MiddlewareHandler<any, string, {}, Response>;
16
10
  auth: () => import("hono").MiddlewareHandler;
17
11
  party: () => import("hono").MiddlewareHandler<any, string, {}, any>;
@@ -19,4 +13,4 @@ declare const createAiax: (config: Config) => {
19
13
  llm: () => import("hono").MiddlewareHandler<any, string, {}, Response>;
20
14
  };
21
15
  //#endregion
22
- export { ALIAS, type ActMeta, type ActionDef, AiaxServer, BINDING, type Call, type Config, type Cookie, type Grant, type Own, type Side, action, actions, bind, createAiax, data, grantOf, init, ownSelf, ownSite, side };
16
+ export { createAiax, ownSelf, ownSite };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
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,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};
1
+ import{PATH_HEADER as e,SUB_HEADER as t}from"./const.js";import{actions as n}from"./action.js";import{createMiddleware as r}from"hono/factory";import i from"@auth/core/providers/google";import{decode as a,encode as o}from"@auth/core/jwt";import{DrizzleAdapter as s}from"@auth/drizzle-adapter";import{getAuthUser as c,initAuthConfig as l}from"@hono/auth-js";import{drizzle as u}from"drizzle-orm/d1";import{env as d}from"hono/adapter";import{streamText as f}from"hono/streaming";import{StreamableHTTPTransport as p}from"@hono/mcp";import{McpServer as m}from"@modelcontextprotocol/sdk/server/mcp.js";import{getServerByName as h,routePartykitRequest as g}from"partyserver";const _=`authjs.mcp-token`,v=e=>l(t=>{let n=new URL(t.req.url).host,r=!!e.cookie&&e.cookie.services.some(t=>n===`${t}.${e.cookie.apex}`),a={sessionToken:{options:{domain:`.${e.cookie?.apex}`}}},o=e.providers??[i({clientId:t.env.GOOGLE_CLIENT_ID,clientSecret:t.env.GOOGLE_CLIENT_SECRET})];return{...e.database?{adapter:s(u(e.database(t.env)))}:{},providers:o,secret:t.env.AUTH_SECRET,session:{strategy:`jwt`},...r?{cookies:a}:{}}}),y=async e=>(await c(e))?.token?.sub??``,b=(e,t,n,r)=>o({token:{sub:t,path:n},secret:d(e).AUTH_SECRET,salt:r?.salt??_,maxAge:r?.maxAge??43200}),x=async(e,t)=>{let n=(e.req.header(`Authorization`)??``).replace(/^Bearer\s+/i,``);if(!n)return null;let r=await a({token:n,secret:d(e).AUTH_SECRET,salt:t?.salt??_}).catch(()=>null);return{sub:r?.sub??``,path:r?.path??``}},S=(e,t=`site`)=>async(n,r,i)=>!r||!i?``:(await e(n).head(`${r}/${i}`))?.customMetadata?.[t]??``,C=()=>(e,t)=>t,w=e=>e.startsWith(`data:`)?JSON.parse(e.slice(5)):null,T=(e,t,n)=>fetch(e.api,{method:`POST`,headers:{"x-api-key":e.key,"anthropic-version":`2023-06-01`,"anthropic-beta":`mcp-client-2025-11-20`,"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})}),E=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=w(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.server_name} ${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}},D=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 E(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 T(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`)},O=e=>r(async t=>{let n=await y(t),{path:r=``,prompt:i,model:a=``}=await t.req.json(),o=!!e.lobby&&!r;if(!o&&!n)return t.text(`Unauthorized`,401);if(!o&&!await e.own(d(t),n,r))return t.text(`Forbidden`,403);let s=t.req.header(`x-original-host`)??t.req.header(`x-forwarded-host`)??new URL(t.req.url).host,c={key:d(t).ANTHROPIC_API_KEY,api:e.claude??`https://api.anthropic.com/v1/messages`,name:e.name,url:`https://${s}${e.endpoint??`/api/mcp`}`,model:a||e.model||`claude-sonnet-5`,system:e.system??``,maxTokens:e.maxTokens??32e3},l=()=>o?Promise.resolve(``):b(t,n,r,e),u=[{role:`user`,content:i}],p=await T(c,await l(),u);return p.ok?f(t,t=>D(c,l,u,p,e=>t.write(e),e.maxTurns??10)):t.text(await p.text(),500)}),k=async(n,r,i,a,o)=>{let s=await h(n,r),c={[t]:i.sub,[e]:encodeURIComponent(i.path)};return(await s.fetch(`https://internal/act`,{method:`POST`,headers:c,body:JSON.stringify({name:a,input:o})})).json()},A=e=>r(async t=>{let r=await x(t,e),i=r?.sub??``,a=r?.path??``,o=e.lobby??``;if(r||!o){if(!i)return t.text(`Unauthorized`,401);if(o=await e.own(d(t),i,a),!o)return t.text(`Forbidden`,403)}let s=new m({name:e.name,version:e.version??`1.0.0`}),c=new p;return n.forEach((n,r)=>s.registerTool(r,{description:n.description,inputSchema:{...n.input}},async n=>{let s=await k(d(t)[e.binding??`v1`],o,{sub:i,path:a},r,n);return{content:[{type:`text`,text:JSON.stringify(s)}]}})),await s.connect(c),c.handleRequest(t)}),j=async(n,r,i,a)=>{let o=new Headers(n.req.raw.headers);o.set(t,i),o.set(e,encodeURIComponent(a));let s=new URL(n.req.url),c=s.pathname.split(`/`);c[3]=encodeURIComponent(r),s.pathname=c.join(`/`);let l=new Request(s,new Request(n.req.raw,{headers:o}));return await g(l,d(n))??n.text(`Not Found`,404)},M=e=>r(async t=>{let n=decodeURIComponent(t.req.path.split(`/`)[3]??``),r=t.req.query(`path`)??``,i=await y(t);if(e.lobby&&n===e.lobby)return j(t,n,i,r);if(!i)return t.text(`Unauthorized`,401);let a=await e.own(d(t),i,r);return!a||n!==a&&n!==(e.alias??`my-room`)?t.text(`Forbidden`,403):j(t,a,i,r)}),N=e=>{let t={auth:v(e),party:M(e),mcp:A(e),llm:O(e)},n=r(async(n,r)=>{let i=()=>n.req.path.startsWith(`/parties/`)?t.party(n,r):n.req.path===(e.endpoint??`/api/mcp`)?t.mcp(n,r):n.req.path===`/api/llm`&&n.req.method===`POST`?t.llm(n,r):r(),a;if(await t.auth(n,async()=>void(a=await i())),a)return a});return{config:e,all:()=>n,auth:()=>t.auth,party:()=>t.party,mcp:()=>t.mcp,llm:()=>t.llm}};export{N as createAiax,C as ownSelf,S as ownSite};
package/dist/server.d.ts CHANGED
@@ -1,11 +1,13 @@
1
- import { t as Call } from "./action-DItZAgdx.js";
1
+ import { Grant } from "./types.js";
2
+ import { Call } from "./action.js";
2
3
  import { YServer } from "y-partyserver";
3
4
  //#region src/server.d.ts
4
5
  declare class AiaxServer extends YServer {
5
6
  wrap: (run: () => Promise<any>) => Promise<any>;
6
7
  call: Call;
7
- onAct(_request: Request): Promise<void>;
8
+ grantOf(request: Request): Grant;
9
+ onAct(_grant: Grant, _request: Request): Promise<void>;
8
10
  onRequest(request: Request): Promise<Response>;
9
11
  }
10
12
  //#endregion
11
- export { AiaxServer };
13
+ export { AiaxServer, type Grant };
package/dist/server.js CHANGED
@@ -1 +1 @@
1
- import{actions as e,bind as t,init as n}from"./action.js";import{YServer as r}from"y-partyserver";var i=class extends r{wrap=e=>e();call=n(this.document,e=>this.wrap(e));async onAct(e){}async onRequest(n){if(t(this.document),n.method!==`POST`)return new Response(`Not Found`,{status:404});let{name:r,input:i}=await n.json();return e.get(r)?.side===`client`?Response.json({ok:!0,result:await this.call(r,i)}):(await this.onAct(n),Response.json({ok:!0,result:await this.wrap(()=>this.call(r,i))}))}};export{i as AiaxServer};
1
+ import"./const.js";import{actions as e,bind as t,init as n}from"./action.js";import{YServer as r}from"y-partyserver";var i=class extends r{wrap=e=>e();call=n(this.document,e=>this.wrap(e));grantOf(e){return{sub:e.headers.get(`x-user-sub`)??``,path:decodeURIComponent(e.headers.get(`x-user-path`)??``)}}async onAct(e,t){}async onRequest(n){if(t(this.document),n.method!==`POST`)return new Response(`Not Found`,{status:404});let{name:r,input:i}=await n.json();return e.get(r)?.side===`client`?Response.json({ok:!0,result:await this.call(r,i)}):(await this.onAct(this.grantOf(n),n),Response.json({ok:!0,result:await this.wrap(()=>this.call(r,i))}))}};export{i as AiaxServer};
@@ -1,4 +1,3 @@
1
- import * as Y from "yjs";
2
1
  import { ZodRawShape } from "zod";
3
2
  //#region src/types.d.ts
4
3
  type Side = 'server' | 'client' | 'both';
@@ -40,14 +39,4 @@ interface Config {
40
39
  providers?: any[];
41
40
  }
42
41
  //#endregion
43
- //#region src/action.d.ts
44
- type Action<I, R> = (input: I) => R | Promise<R>;
45
- type Call = (name: string, input: any) => Promise<any>;
46
- declare const actions: Map<string, ActionDef>;
47
- declare const side: Side;
48
- declare const bind: (doc: Y.Doc) => Y.Doc;
49
- declare const data: <T = any>(name?: string) => Y.Map<T>;
50
- declare function action<I extends object, R>(load: Action<I, R> | ((input?: I) => any), at: Side, meta: ActMeta): (input: I) => Promise<R>;
51
- declare const init: (doc: Y.Doc, wrap?: (run: () => Promise<any>) => Promise<any>) => Call;
52
- //#endregion
53
- export { data as a, ActMeta as c, Cookie as d, Grant as f, bind as i, ActionDef as l, Side as m, action as n, init as o, Own as p, actions as r, side as s, Call as t, Config as u };
42
+ export { ActMeta, ActionDef, Config, Cookie, Grant, Own, Side };
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export{};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ai-ax",
3
3
  "author": "tseijp",
4
- "version": "0.1.1",
4
+ "version": "0.3.0",
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": [
@@ -49,10 +49,6 @@
49
49
  "./src/*": {
50
50
  "types": "./src/*.ts",
51
51
  "default": "./src/*.ts"
52
- },
53
- "./*": {
54
- "types": "./dist/index.d.ts",
55
- "default": "./dist/index.js"
56
52
  }
57
53
  },
58
54
  "files": [
@@ -1 +0,0 @@
1
- const e=`my-room`,t=`x-user-sub`,n=`x-user-path`,r=`authjs.mcp-token`,i=43200,a=`v1`,o=`/api/mcp`,s=`/api/llm`,c=`1.0.0`,l=`https://api.anthropic.com/v1/messages`,u=`claude-sonnet-5`,d=`2023-06-01`,f=`mcp-client-2025-11-20`,p=32e3;export{l as a,i as c,c as d,n as f,u as i,p as l,t as m,a as n,d as o,r as p,f as r,s,e as t,o as u};
@@ -1,5 +0,0 @@
1
- //#region src/const.d.ts
2
- declare const ALIAS = "my-room";
3
- declare const BINDING = "v1";
4
- //#endregion
5
- export { BINDING as n, ALIAS as t };