ai-ax 0.2.0 → 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/dist/client.d.ts +26 -1
- package/dist/client.js +2 -1
- package/dist/const.d.ts +1 -9
- package/dist/const.js +1 -1
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -2,6 +2,31 @@ import { ActMeta, ActionDef, Side } from "./types.js";
|
|
|
2
2
|
import { Call, action, actions, bind, data, init, side } from "./action.js";
|
|
3
3
|
import { ALIAS, BINDING } from "./const.js";
|
|
4
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
|
|
5
30
|
//#region src/client.d.ts
|
|
6
31
|
interface Route {
|
|
7
32
|
room?: string;
|
|
@@ -19,4 +44,4 @@ interface Link {
|
|
|
19
44
|
declare const onLeave: (fn: () => void) => undefined;
|
|
20
45
|
declare const connect: (route?: Route) => Link;
|
|
21
46
|
//#endregion
|
|
22
|
-
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{ALIAS as e,BINDING as t}from"./const.js";import{action as
|
|
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};
|
package/dist/const.d.ts
CHANGED
|
@@ -2,17 +2,9 @@
|
|
|
2
2
|
declare const ALIAS = "my-room";
|
|
3
3
|
declare const SUB_HEADER = "x-user-sub";
|
|
4
4
|
declare const PATH_HEADER = "x-user-path";
|
|
5
|
-
declare const SALT = "authjs.mcp-token";
|
|
6
|
-
declare const MAX_AGE: number;
|
|
7
5
|
declare const BINDING = "v1";
|
|
8
6
|
declare const MCP_PATH = "/api/mcp";
|
|
9
7
|
declare const LLM_PATH = "/api/llm";
|
|
10
|
-
declare const MCP_VERSION = "1.0.0";
|
|
11
|
-
declare const CLAUDE_URL = "https://api.anthropic.com/v1/messages";
|
|
12
|
-
declare const CLAUDE_MODEL = "claude-sonnet-5";
|
|
13
|
-
declare const CLAUDE_VERSION = "2023-06-01";
|
|
14
|
-
declare const CLAUDE_BETA = "mcp-client-2025-11-20";
|
|
15
|
-
declare const MAX_TOKENS = 32000;
|
|
16
8
|
declare const MAX_TURNS = 10;
|
|
17
9
|
//#endregion
|
|
18
|
-
export { ALIAS, BINDING,
|
|
10
|
+
export { ALIAS, BINDING, LLM_PATH, MAX_TURNS, MCP_PATH, PATH_HEADER, SUB_HEADER };
|
package/dist/const.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=`my-room`,t=`x-user-sub`,n=`x-user-path`,r=`
|
|
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.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`);u=f.pop()??``;for(let e of f){let c=
|
|
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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-ax",
|
|
3
3
|
"author": "tseijp",
|
|
4
|
-
"version": "0.
|
|
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": [
|