@rubrion/agent-kit-server 0.0.0-stage → 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/gateway-entry.d.ts +3 -0
- package/dist/gateway-entry.js +5 -0
- package/dist/gateway-entry.js.map +1 -0
- package/dist/gateway.d.ts +25 -0
- package/dist/gateway.js +102 -0
- package/dist/gateway.js.map +1 -0
- package/dist/headers.d.ts +13 -0
- package/dist/headers.js +31 -0
- package/dist/headers.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/models.d.ts +32 -0
- package/dist/models.js +49 -0
- package/dist/models.js.map +1 -0
- package/dist/stream.d.ts +11 -0
- package/dist/stream.js +49 -0
- package/dist/stream.js.map +1 -0
- package/dist/turns.d.ts +9 -0
- package/dist/turns.js +28 -0
- package/dist/turns.js.map +1 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/worker.d.ts +54 -0
- package/dist/worker.js +186 -0
- package/dist/worker.js.map +1 -0
- package/package.json +49 -4
- package/README.md +0 -3
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// @rubrion/agent-kit-server/gateway: only the gateway, with no Mastra in the
|
|
2
|
+
// bundle. Import this from the app's API Worker.
|
|
3
|
+
export { createAgentGateway } from './gateway.js';
|
|
4
|
+
export { HEADER, readCaller, writeCaller, writeModel } from './headers.js';
|
|
5
|
+
//# sourceMappingURL=gateway-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway-entry.js","sourceRoot":"","sources":["../src/gateway-entry.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,iDAAiD;AACjD,OAAO,EAAE,kBAAkB,EAAqD,MAAM,cAAc,CAAC;AACrG,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Hono, type Context } from 'hono';
|
|
2
|
+
import type { Caller, ModelChoice } from './types.js';
|
|
3
|
+
export type Blocked = {
|
|
4
|
+
status: number;
|
|
5
|
+
reason: string;
|
|
6
|
+
message: string;
|
|
7
|
+
};
|
|
8
|
+
/** ok with an optional model (e.g. the tenant's own key), or why not. */
|
|
9
|
+
export type Preflight = {
|
|
10
|
+
ok: true;
|
|
11
|
+
model?: ModelChoice;
|
|
12
|
+
} | ({
|
|
13
|
+
ok: false;
|
|
14
|
+
} & Blocked);
|
|
15
|
+
export interface GatewayOptions<C extends Context = Context> {
|
|
16
|
+
/** The agent worker's service binding. */
|
|
17
|
+
agent: (c: C) => Fetcher | undefined;
|
|
18
|
+
/** The person from the app's session, or null (401). */
|
|
19
|
+
identify: (c: C) => Caller | null | Promise<Caller | null>;
|
|
20
|
+
/** Runs before /status and /stream: missing key, budget reached… */
|
|
21
|
+
preflight?: (c: C, caller: Caller) => Preflight | Promise<Preflight>;
|
|
22
|
+
/** Per-agent gate (e.g. the thinking agent is only on bigger plans). */
|
|
23
|
+
canUse?: (c: C, caller: Caller, agentId: string) => true | Blocked | Promise<true | Blocked>;
|
|
24
|
+
}
|
|
25
|
+
export declare function createAgentGateway<C extends Context = Context>(o: GatewayOptions<C>): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
package/dist/gateway.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// The gateway: the app's public side of the assistant. It turns the app's own
|
|
2
|
+
// session into a Caller, checks whether the assistant may answer (key set, budget
|
|
3
|
+
// left, plan includes the agent…), and forwards to the agent worker through its
|
|
4
|
+
// service binding. Answers stream back untouched.
|
|
5
|
+
//
|
|
6
|
+
// Mount it under the app's API, e.g. app.route('/api/agent', createAgentGateway(...)):
|
|
7
|
+
// GET /agents agents this caller may use
|
|
8
|
+
// GET /status { ready, reason, message, provider, model }: the UI checks on open
|
|
9
|
+
// POST /stream a question (SSE)
|
|
10
|
+
// GET /threads conversations
|
|
11
|
+
// GET /threads/:id one conversation (?agent=)
|
|
12
|
+
// DELETE /threads/:id
|
|
13
|
+
import { Hono } from 'hono';
|
|
14
|
+
import { writeCaller, writeModel } from './headers.js';
|
|
15
|
+
const OFFLINE = 'The assistant is offline.';
|
|
16
|
+
export function createAgentGateway(o) {
|
|
17
|
+
const app = new Hono();
|
|
18
|
+
async function forward(c, caller, path, init = {}) {
|
|
19
|
+
const binding = o.agent(c);
|
|
20
|
+
if (!binding)
|
|
21
|
+
return c.json({ error: OFFLINE }, 503);
|
|
22
|
+
const headers = new Headers(init.headers);
|
|
23
|
+
writeCaller(headers, caller);
|
|
24
|
+
if (init.model)
|
|
25
|
+
writeModel(headers, init.model);
|
|
26
|
+
try {
|
|
27
|
+
const r = await binding.fetch(new Request(`https://agent${path}`, { method: init.method ?? 'GET', body: init.body, headers, signal: c.req.raw.signal }));
|
|
28
|
+
return new Response(r.body, { status: r.status, headers: r.headers });
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
console.error('agent worker unreachable', e);
|
|
32
|
+
return c.json({ error: OFFLINE }, 503);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const who = async (c) => {
|
|
36
|
+
const caller = await o.identify(c);
|
|
37
|
+
return caller ?? null;
|
|
38
|
+
};
|
|
39
|
+
app.get('/agents', async (c) => {
|
|
40
|
+
const ctx = c;
|
|
41
|
+
const caller = await who(ctx);
|
|
42
|
+
if (!caller)
|
|
43
|
+
return c.json({ error: 'Not signed in.' }, 401);
|
|
44
|
+
const r = await forward(ctx, caller, '/agents');
|
|
45
|
+
if (!r.ok || !o.canUse)
|
|
46
|
+
return r;
|
|
47
|
+
const list = (await r.json());
|
|
48
|
+
const allowed = await Promise.all(list.map(async (a) => (await o.canUse(ctx, caller, a.id)) === true));
|
|
49
|
+
return c.json(list.filter((_, i) => allowed[i]));
|
|
50
|
+
});
|
|
51
|
+
app.get('/status', async (c) => {
|
|
52
|
+
const ctx = c;
|
|
53
|
+
const caller = await who(ctx);
|
|
54
|
+
if (!caller)
|
|
55
|
+
return c.json({ error: 'Not signed in.' }, 401);
|
|
56
|
+
const p = (await o.preflight?.(ctx, caller)) ?? { ok: true };
|
|
57
|
+
return c.json(p.ok
|
|
58
|
+
? { ready: true, reason: null, message: null, provider: p.model?.provider ?? 'workers-ai', model: p.model?.model ?? null }
|
|
59
|
+
: { ready: false, reason: p.reason, message: p.message });
|
|
60
|
+
});
|
|
61
|
+
app.post('/stream', async (c) => {
|
|
62
|
+
const ctx = c;
|
|
63
|
+
const caller = await who(ctx);
|
|
64
|
+
if (!caller)
|
|
65
|
+
return c.json({ error: 'Not signed in.' }, 401);
|
|
66
|
+
const p = (await o.preflight?.(ctx, caller)) ?? { ok: true };
|
|
67
|
+
if (!p.ok)
|
|
68
|
+
return c.json({ error: p.message, reason: p.reason }, p.status);
|
|
69
|
+
const body = await c.req.text();
|
|
70
|
+
let agentId = '';
|
|
71
|
+
try {
|
|
72
|
+
agentId = String(JSON.parse(body).agent ?? '');
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return c.json({ error: 'Invalid body.' }, 400);
|
|
76
|
+
}
|
|
77
|
+
if (agentId && o.canUse) {
|
|
78
|
+
const ok = await o.canUse(ctx, caller, agentId);
|
|
79
|
+
if (ok !== true)
|
|
80
|
+
return c.json({ error: ok.message, reason: ok.reason }, ok.status);
|
|
81
|
+
}
|
|
82
|
+
return forward(ctx, caller, '/stream', { method: 'POST', body, headers: { 'content-type': 'application/json' }, model: p.model });
|
|
83
|
+
});
|
|
84
|
+
app.get('/threads', async (c) => {
|
|
85
|
+
const caller = await who(c);
|
|
86
|
+
return caller ? forward(c, caller, '/threads') : c.json([], 401);
|
|
87
|
+
});
|
|
88
|
+
app.get('/threads/:id', async (c) => {
|
|
89
|
+
const caller = await who(c);
|
|
90
|
+
if (!caller)
|
|
91
|
+
return c.json([], 401);
|
|
92
|
+
return forward(c, caller, `/threads/${encodeURIComponent(c.req.param('id'))}?agent=${encodeURIComponent(c.req.query('agent') ?? '')}`);
|
|
93
|
+
});
|
|
94
|
+
app.delete('/threads/:id', async (c) => {
|
|
95
|
+
const caller = await who(c);
|
|
96
|
+
if (!caller)
|
|
97
|
+
return c.json({ ok: false }, 401);
|
|
98
|
+
return forward(c, caller, `/threads/${encodeURIComponent(c.req.param('id'))}`, { method: 'DELETE' });
|
|
99
|
+
});
|
|
100
|
+
return app;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=gateway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Caller, ModelChoice } from './types.js';
|
|
2
|
+
export declare const HEADER: {
|
|
3
|
+
readonly tenant: "X-Agent-Tenant";
|
|
4
|
+
readonly person: "X-Agent-Person";
|
|
5
|
+
readonly role: "X-Agent-Role";
|
|
6
|
+
/** URI-encoded: names carry accents. */
|
|
7
|
+
readonly name: "X-Agent-Name";
|
|
8
|
+
/** JSON ModelChoice; carries a decrypted key only inside this request. */
|
|
9
|
+
readonly model: "X-Agent-Model";
|
|
10
|
+
};
|
|
11
|
+
export declare function writeCaller(headers: Headers, caller: Caller): void;
|
|
12
|
+
export declare function readCaller(headers: Headers): Caller | null;
|
|
13
|
+
export declare const writeModel: (headers: Headers, choice: ModelChoice) => void;
|
package/dist/headers.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const HEADER = {
|
|
2
|
+
tenant: 'X-Agent-Tenant',
|
|
3
|
+
person: 'X-Agent-Person',
|
|
4
|
+
role: 'X-Agent-Role',
|
|
5
|
+
/** URI-encoded: names carry accents. */
|
|
6
|
+
name: 'X-Agent-Name',
|
|
7
|
+
/** JSON ModelChoice; carries a decrypted key only inside this request. */
|
|
8
|
+
model: 'X-Agent-Model',
|
|
9
|
+
};
|
|
10
|
+
/** Ids are kept to a safe alphabet: they become part of thread ids. */
|
|
11
|
+
const ID = /^[A-Za-z0-9_.@-]{1,64}$/;
|
|
12
|
+
export function writeCaller(headers, caller) {
|
|
13
|
+
headers.set(HEADER.tenant, caller.tenant);
|
|
14
|
+
headers.set(HEADER.person, caller.person);
|
|
15
|
+
headers.set(HEADER.role, caller.role);
|
|
16
|
+
headers.set(HEADER.name, encodeURIComponent(caller.name).slice(0, 300));
|
|
17
|
+
}
|
|
18
|
+
export function readCaller(headers) {
|
|
19
|
+
const tenant = headers.get(HEADER.tenant) ?? '';
|
|
20
|
+
const person = headers.get(HEADER.person) ?? '';
|
|
21
|
+
if (!ID.test(tenant) || !ID.test(person))
|
|
22
|
+
return null;
|
|
23
|
+
let name = headers.get(HEADER.name) ?? '';
|
|
24
|
+
try {
|
|
25
|
+
name = decodeURIComponent(name);
|
|
26
|
+
}
|
|
27
|
+
catch { /* sent raw */ }
|
|
28
|
+
return { tenant, person, role: headers.get(HEADER.role) ?? '', name };
|
|
29
|
+
}
|
|
30
|
+
export const writeModel = (headers, choice) => headers.set(HEADER.model, JSON.stringify(choice));
|
|
31
|
+
//# sourceMappingURL=headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headers.js","sourceRoot":"","sources":["../src/headers.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,MAAM,GAAG;IACrB,MAAM,EAAE,gBAAgB;IACxB,MAAM,EAAE,gBAAgB;IACxB,IAAI,EAAE,cAAc;IACpB,wCAAwC;IACxC,IAAI,EAAE,cAAc;IACpB,0EAA0E;IAC1E,KAAK,EAAE,eAAe;CACb,CAAC;AAEX,uEAAuE;AACvE,MAAM,EAAE,GAAG,yBAAyB,CAAC;AAErC,MAAM,UAAU,WAAW,CAAC,OAAgB,EAAE,MAAc;IAC3D,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAgB;IAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAChD,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC1C,IAAI,CAAC;QAAC,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IACjE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAgB,EAAE,MAAmB,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { createAgentWorker, type AgentWorkerOptions } from './worker.js';
|
|
2
|
+
export { toTurns } from './turns.js';
|
|
3
|
+
export { createAgentGateway, type GatewayOptions, type Preflight, type Blocked } from './gateway.js';
|
|
4
|
+
export { HEADER, readCaller, writeCaller, writeModel } from './headers.js';
|
|
5
|
+
export { DEFAULT_MODEL, PRICES, isWorkersAI, priceOf, readModelChoice, resolveModel, type Providers } from './models.js';
|
|
6
|
+
export { defaultErrorMessage, slim, usageOf } from './stream.js';
|
|
7
|
+
export type { AgentDefinition, Caller, ModelChoice, Price, Provider, StreamEvent, Usage } from './types.js';
|
|
8
|
+
export { createTool, z } from '@rubrion/mastra-cloudflare';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// @rubrion/agent-kit-server: the server half of the agent kit.
|
|
2
|
+
// createAgentWorker the agent worker (Mastra + D1 memory + slim SSE), behind a service binding
|
|
3
|
+
// createAgentGateway the app-side routes: identity, preflight, forwarding
|
|
4
|
+
export { createAgentWorker } from './worker.js';
|
|
5
|
+
export { toTurns } from './turns.js';
|
|
6
|
+
export { createAgentGateway } from './gateway.js';
|
|
7
|
+
export { HEADER, readCaller, writeCaller, writeModel } from './headers.js';
|
|
8
|
+
export { DEFAULT_MODEL, PRICES, isWorkersAI, priceOf, readModelChoice, resolveModel } from './models.js';
|
|
9
|
+
export { defaultErrorMessage, slim, usageOf } from './stream.js';
|
|
10
|
+
// So an agent project needs only this package to declare tools.
|
|
11
|
+
export { createTool, z } from '@rubrion/mastra-cloudflare';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,mGAAmG;AACnG,6EAA6E;AAC7E,OAAO,EAAE,iBAAiB,EAA2B,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAqD,MAAM,cAAc,CAAC;AACrG,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAkB,MAAM,aAAa,CAAC;AACzH,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEjE,gEAAgE;AAChE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,4BAA4B,CAAC"}
|
package/dist/models.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type AiBinding, type Model } from '@rubrion/mastra-cloudflare';
|
|
2
|
+
import type { ModelChoice, Price } from './types.js';
|
|
3
|
+
export declare const DEFAULT_MODEL = "@cf/google/gemma-4-26b-a4b-it";
|
|
4
|
+
/** Dollars per million tokens, used to report the cost of each answer. Extend through options.prices. */
|
|
5
|
+
export declare const PRICES: Record<string, Price>;
|
|
6
|
+
/** The choice in the header; anything malformed becomes the default Workers AI model. */
|
|
7
|
+
export declare function readModelChoice(header: string | null | undefined, fallback?: ModelChoice): ModelChoice;
|
|
8
|
+
export declare const priceOf: (choice: ModelChoice, prices?: Record<string, Price>) => Price;
|
|
9
|
+
/** Only Workers AI takes temperature and the thinking switch; the others decide on their own. */
|
|
10
|
+
export declare const isWorkersAI: (choice: ModelChoice) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Bring-your-own-key providers, opt-in so their SDKs only enter the bundle of
|
|
13
|
+
* apps that offer them:
|
|
14
|
+
*
|
|
15
|
+
* providers: { anthropic: () => import('@ai-sdk/anthropic'), openai: () => import('@ai-sdk/openai') }
|
|
16
|
+
*/
|
|
17
|
+
export interface Providers {
|
|
18
|
+
anthropic?: () => Promise<{
|
|
19
|
+
createAnthropic: (o: {
|
|
20
|
+
apiKey?: string;
|
|
21
|
+
}) => (model: string) => unknown;
|
|
22
|
+
}>;
|
|
23
|
+
openai?: () => Promise<{
|
|
24
|
+
createOpenAI: (o: {
|
|
25
|
+
apiKey?: string;
|
|
26
|
+
}) => {
|
|
27
|
+
chat: (model: string) => unknown;
|
|
28
|
+
};
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
31
|
+
/** The AI SDK model for a choice. A provider not enabled falls back to Workers AI. */
|
|
32
|
+
export declare function resolveModel(choice: ModelChoice, ai: AiBinding, thinking: boolean, providers?: Providers): Promise<Model>;
|
package/dist/models.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Which model answers each request. Workers AI is the default (no key, billed to
|
|
2
|
+
// the account running the worker); a tenant may bring its own Anthropic or OpenAI
|
|
3
|
+
// key, which the gateway sends in X-Agent-Model and only lives in that request.
|
|
4
|
+
import { workersAI } from '@rubrion/mastra-cloudflare';
|
|
5
|
+
export const DEFAULT_MODEL = '@cf/google/gemma-4-26b-a4b-it';
|
|
6
|
+
/** Dollars per million tokens, used to report the cost of each answer. Extend through options.prices. */
|
|
7
|
+
export const PRICES = {
|
|
8
|
+
[DEFAULT_MODEL]: { input: 0.1, output: 0.3 },
|
|
9
|
+
'claude-haiku-5-5': { input: 0.1, output: 0.5 },
|
|
10
|
+
'claude-sonnet-5-5': { input: 2, output: 10 },
|
|
11
|
+
'claude-opus-5-5': { input: 4, output: 20 },
|
|
12
|
+
'gpt-4o-mini': { input: 0.15, output: 0.6 },
|
|
13
|
+
'gpt-4o': { input: 2.5, output: 10 },
|
|
14
|
+
};
|
|
15
|
+
/** Used when a model is not in the table. */
|
|
16
|
+
const PROVIDER_PRICE = {
|
|
17
|
+
'workers-ai': PRICES[DEFAULT_MODEL],
|
|
18
|
+
anthropic: PRICES['claude-sonnet-5-5'],
|
|
19
|
+
openai: PRICES['gpt-4o'],
|
|
20
|
+
};
|
|
21
|
+
/** The choice in the header; anything malformed becomes the default Workers AI model. */
|
|
22
|
+
export function readModelChoice(header, fallback = { provider: 'workers-ai', model: DEFAULT_MODEL }) {
|
|
23
|
+
try {
|
|
24
|
+
const c = JSON.parse(header ?? '');
|
|
25
|
+
if ((c.provider === 'anthropic' || c.provider === 'openai') && typeof c.model === 'string' && c.model && typeof c.key === 'string' && c.key) {
|
|
26
|
+
return { provider: c.provider, model: c.model, key: c.key };
|
|
27
|
+
}
|
|
28
|
+
if (c.provider === 'workers-ai' && typeof c.model === 'string' && c.model.startsWith('@cf/'))
|
|
29
|
+
return { provider: 'workers-ai', model: c.model };
|
|
30
|
+
}
|
|
31
|
+
catch { /* no header */ }
|
|
32
|
+
return fallback;
|
|
33
|
+
}
|
|
34
|
+
export const priceOf = (choice, prices = PRICES) => prices[choice.model] ?? PROVIDER_PRICE[choice.provider];
|
|
35
|
+
/** Only Workers AI takes temperature and the thinking switch; the others decide on their own. */
|
|
36
|
+
export const isWorkersAI = (choice) => choice.provider === 'workers-ai';
|
|
37
|
+
/** The AI SDK model for a choice. A provider not enabled falls back to Workers AI. */
|
|
38
|
+
export async function resolveModel(choice, ai, thinking, providers = {}) {
|
|
39
|
+
if (choice.provider === 'anthropic' && providers.anthropic) {
|
|
40
|
+
const { createAnthropic } = await providers.anthropic();
|
|
41
|
+
return createAnthropic({ apiKey: choice.key })(choice.model);
|
|
42
|
+
}
|
|
43
|
+
if (choice.provider === 'openai' && providers.openai) {
|
|
44
|
+
const { createOpenAI } = await providers.openai();
|
|
45
|
+
return createOpenAI({ apiKey: choice.key }).chat(choice.model);
|
|
46
|
+
}
|
|
47
|
+
return workersAI(ai, isWorkersAI(choice) ? choice.model : DEFAULT_MODEL, { thinking });
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"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"}
|
package/dist/stream.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { StreamEvent } from './types.js';
|
|
2
|
+
export declare function slim(chunk: unknown, errorMessage?: (raw: string) => string): StreamEvent | null;
|
|
3
|
+
/** Token usage reported by a step-finish or finish chunk. */
|
|
4
|
+
export declare function usageOf(chunk: unknown): {
|
|
5
|
+
input: number;
|
|
6
|
+
output: number;
|
|
7
|
+
};
|
|
8
|
+
/** Provider errors the person can act on; the rest pass through. */
|
|
9
|
+
export declare function defaultErrorMessage(m: string): string;
|
|
10
|
+
export declare const sse: (o: unknown) => string;
|
|
11
|
+
export declare const SSE_DONE = "data: [DONE]\n\n";
|
package/dist/stream.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export function slim(chunk, errorMessage = (m) => m) {
|
|
2
|
+
if (!chunk || typeof chunk !== 'object')
|
|
3
|
+
return null;
|
|
4
|
+
const { type, payload = {} } = chunk;
|
|
5
|
+
switch (type) {
|
|
6
|
+
case 'text-delta':
|
|
7
|
+
case 'reasoning-delta':
|
|
8
|
+
return { type, text: String(payload.text ?? '') };
|
|
9
|
+
case 'reasoning-start':
|
|
10
|
+
case 'reasoning-end':
|
|
11
|
+
case 'text-start':
|
|
12
|
+
case 'text-end':
|
|
13
|
+
case 'step-start':
|
|
14
|
+
case 'step-finish':
|
|
15
|
+
case 'finish':
|
|
16
|
+
return { type };
|
|
17
|
+
case 'tool-call-input-streaming-start':
|
|
18
|
+
return { type: 'tool-start', id: String(payload.toolCallId), name: String(payload.toolName) };
|
|
19
|
+
case 'tool-call':
|
|
20
|
+
return { type: 'tool-call', id: String(payload.toolCallId), name: String(payload.toolName), args: payload.args };
|
|
21
|
+
case 'tool-result':
|
|
22
|
+
return { type: 'tool-result', id: String(payload.toolCallId), name: String(payload.toolName), result: payload.result, error: Boolean(payload.isError) };
|
|
23
|
+
case 'tool-error':
|
|
24
|
+
return { type: 'tool-result', id: String(payload.toolCallId), name: String(payload.toolName), result: null, error: true };
|
|
25
|
+
case 'error':
|
|
26
|
+
return { type: 'error', message: errorMessage(String(payload.error?.message ?? payload.error ?? 'error')) };
|
|
27
|
+
default:
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Token usage reported by a step-finish or finish chunk. */
|
|
32
|
+
export function usageOf(chunk) {
|
|
33
|
+
const p = (chunk.payload ?? {});
|
|
34
|
+
const u = p.output?.usage ?? p.totalUsage ?? p.usage ?? {};
|
|
35
|
+
return { input: Number(u.inputTokens ?? u.promptTokens ?? 0), output: Number(u.outputTokens ?? u.completionTokens ?? 0) };
|
|
36
|
+
}
|
|
37
|
+
/** Provider errors the person can act on; the rest pass through. */
|
|
38
|
+
export function defaultErrorMessage(m) {
|
|
39
|
+
if (/\b401\b|unauthori[sz]ed|invalid.{0,20}(api.?key|x-api-key)|authentication|incorrect api key/i.test(m)) {
|
|
40
|
+
return 'The AI provider rejected the access key. Check the key in the AI settings.';
|
|
41
|
+
}
|
|
42
|
+
if (/\b429\b|rate.?limit|quota|credit balance/i.test(m)) {
|
|
43
|
+
return 'The AI provider refused because of a rate limit or account credit. Check the provider account.';
|
|
44
|
+
}
|
|
45
|
+
return m;
|
|
46
|
+
}
|
|
47
|
+
export const sse = (o) => `data: ${JSON.stringify(o)}\n\n`;
|
|
48
|
+
export const SSE_DONE = 'data: [DONE]\n\n';
|
|
49
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,IAAI,CAAC,KAAc,EAAE,eAAwC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpF,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACrD,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,EAAE,EAAE,GAAG,KAA4D,CAAC;IAC5F,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,YAAY,CAAC;QAClB,KAAK,iBAAiB;YACrB,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;QACnD,KAAK,iBAAiB,CAAC;QACvB,KAAK,eAAe,CAAC;QACrB,KAAK,YAAY,CAAC;QAClB,KAAK,UAAU,CAAC;QAChB,KAAK,YAAY,CAAC;QAClB,KAAK,aAAa,CAAC;QACnB,KAAK,QAAQ;YACZ,OAAO,EAAE,IAAI,EAAE,CAAC;QACjB,KAAK,iCAAiC;YACrC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/F,KAAK,WAAW;YACf,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;QAClH,KAAK,aAAa;YACjB,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACzJ,KAAK,YAAY;YAChB,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAC3H,KAAK,OAAO;YACX,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,MAAM,CAAE,OAAO,CAAC,KAAe,EAAE,OAAO,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC;QACxH;YACC,OAAO,IAAI,CAAC;IACd,CAAC;AACF,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,OAAO,CAAC,KAAc;IACrC,MAAM,CAAC,GAAG,CAAE,KAA+C,CAAC,OAAO,IAAI,EAAE,CAAwB,CAAC;IAClG,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IAC3D,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,EAAE,CAAC;AAC3H,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,mBAAmB,CAAC,CAAS;IAC5C,IAAI,8FAA8F,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5G,OAAO,4EAA4E,CAAC;IACrF,CAAC;IACD,IAAI,2CAA2C,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,OAAO,gGAAgG,CAAC;IACzG,CAAC;IACD,OAAO,CAAC,CAAC;AACV,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;AACpE,MAAM,CAAC,MAAM,QAAQ,GAAG,kBAAkB,CAAC"}
|
package/dist/turns.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type StoredMessage = {
|
|
2
|
+
role: string;
|
|
3
|
+
content: {
|
|
4
|
+
parts?: Record<string, any>[];
|
|
5
|
+
content?: string;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
/** Stored Mastra messages → turns. One answer may be stored as several messages (a tool step, then the text). */
|
|
9
|
+
export declare function toTurns(messages: StoredMessage[], agent: string): Record<string, any>[];
|
package/dist/turns.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Stored Mastra messages → turns. One answer may be stored as several messages (a tool step, then the text). */
|
|
2
|
+
export function toTurns(messages, agent) {
|
|
3
|
+
const turns = [];
|
|
4
|
+
for (const m of messages) {
|
|
5
|
+
const parts = m.content.parts ?? [];
|
|
6
|
+
if (m.role === 'user') {
|
|
7
|
+
const text = parts.filter((p) => p.type === 'text').map((p) => p.text).join('\n') || m.content.content || '';
|
|
8
|
+
if (text)
|
|
9
|
+
turns.push({ id: crypto.randomUUID(), role: 'user', text });
|
|
10
|
+
}
|
|
11
|
+
else if (m.role === 'assistant') {
|
|
12
|
+
const steps = parts.flatMap((p) => p.type === 'text' && p.text
|
|
13
|
+
? [{ kind: 'text', text: p.text }]
|
|
14
|
+
: p.type === 'reasoning' && (p.reasoning || p.text)
|
|
15
|
+
? [{ kind: 'think', text: p.reasoning ?? p.text, start: 0, end: 0 }]
|
|
16
|
+
: p.type === 'tool-invocation'
|
|
17
|
+
? [{ kind: 'tool', id: p.toolInvocation.toolCallId, name: p.toolInvocation.toolName, args: p.toolInvocation.args, result: p.toolInvocation.result, state: 'done', start: 0, end: 0 }]
|
|
18
|
+
: []);
|
|
19
|
+
const last = turns[turns.length - 1];
|
|
20
|
+
if (last?.role === 'assistant')
|
|
21
|
+
last.steps.push(...steps);
|
|
22
|
+
else if (steps.length)
|
|
23
|
+
turns.push({ id: crypto.randomUUID(), role: 'assistant', agent, steps, done: true });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return turns;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=turns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turns.js","sourceRoot":"","sources":["../src/turns.ts"],"names":[],"mappings":"AAGA,iHAAiH;AACjH,MAAM,UAAU,OAAO,CAAC,QAAyB,EAAE,KAAa;IAC/D,MAAM,KAAK,GAA0B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QACpC,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;YAC7G,IAAI,IAAI;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACvE,CAAC;aAAM,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAA6B,EAAE,CAC5D,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI;gBAC1B,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBAClC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC;oBAClD,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;oBACpE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB;wBAC7B,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;wBACrL,CAAC,CAAC,EAAE,CACP,CAAC;YACF,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACrC,IAAI,IAAI,EAAE,IAAI,KAAK,WAAW;gBAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;iBACrD,IAAI,KAAK,CAAC,MAAM;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7G,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who is asking. The gateway resolves it from the app's own session and sends it
|
|
3
|
+
* to the agent worker in headers; the agent worker trusts it because it is only
|
|
4
|
+
* reachable through a service binding.
|
|
5
|
+
*/
|
|
6
|
+
export interface Caller {
|
|
7
|
+
/** The account, office, workspace… everything this person's data lives under. */
|
|
8
|
+
tenant: string;
|
|
9
|
+
/** The person inside the tenant. Conversations are private to tenant + person. */
|
|
10
|
+
person: string;
|
|
11
|
+
/** Free-form role, available to tools and context (e.g. to hide financial data). */
|
|
12
|
+
role: string;
|
|
13
|
+
/** Display name, given to the agent so it can address the person. */
|
|
14
|
+
name: string;
|
|
15
|
+
}
|
|
16
|
+
export type Provider = 'workers-ai' | 'anthropic' | 'openai';
|
|
17
|
+
/** The model that answers a request. `key` exists only for bring-your-own-key providers. */
|
|
18
|
+
export interface ModelChoice {
|
|
19
|
+
provider: Provider;
|
|
20
|
+
model: string;
|
|
21
|
+
key?: string;
|
|
22
|
+
}
|
|
23
|
+
/** Dollars per million tokens. */
|
|
24
|
+
export interface Price {
|
|
25
|
+
input: number;
|
|
26
|
+
output: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* One agent the assistant offers. Each becomes a Mastra Agent, built once per
|
|
30
|
+
* isolate; the model is resolved per request (the tenant may bring its own key).
|
|
31
|
+
*/
|
|
32
|
+
export interface AgentDefinition {
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
/** One line for the agent picker. */
|
|
36
|
+
tagline: string;
|
|
37
|
+
/** Reasoning on (Workers AI): slower and pricier, and the UI shows the thinking. */
|
|
38
|
+
thinking?: boolean;
|
|
39
|
+
/** Mastra tools (createTool). Prefer small read-only tools that return facts. */
|
|
40
|
+
tools: Record<string, unknown>;
|
|
41
|
+
/** Output cap on Workers AI. External models get more room, since their thinking counts as output. */
|
|
42
|
+
maxOutputTokens?: number;
|
|
43
|
+
instructions: string;
|
|
44
|
+
}
|
|
45
|
+
/** What one answer cost, reported when the stream ends. */
|
|
46
|
+
export interface Usage {
|
|
47
|
+
caller: Caller;
|
|
48
|
+
agent: string;
|
|
49
|
+
thread: string;
|
|
50
|
+
provider: Provider;
|
|
51
|
+
model: string;
|
|
52
|
+
inputTokens: number;
|
|
53
|
+
outputTokens: number;
|
|
54
|
+
costUsd: number;
|
|
55
|
+
status: 'ok' | 'error';
|
|
56
|
+
error?: string;
|
|
57
|
+
}
|
|
58
|
+
/** A stream event as the browser receives it (`data: {json}` lines, then `data: [DONE]`). */
|
|
59
|
+
export type StreamEvent = {
|
|
60
|
+
type: 'text-delta' | 'reasoning-delta';
|
|
61
|
+
text: string;
|
|
62
|
+
} | {
|
|
63
|
+
type: 'reasoning-start' | 'reasoning-end' | 'text-start' | 'text-end' | 'step-start' | 'step-finish' | 'finish';
|
|
64
|
+
} | {
|
|
65
|
+
type: 'tool-start';
|
|
66
|
+
id: string;
|
|
67
|
+
name: string;
|
|
68
|
+
} | {
|
|
69
|
+
type: 'tool-call';
|
|
70
|
+
id: string;
|
|
71
|
+
name: string;
|
|
72
|
+
args: unknown;
|
|
73
|
+
} | {
|
|
74
|
+
type: 'tool-result';
|
|
75
|
+
id: string;
|
|
76
|
+
name: string;
|
|
77
|
+
result: unknown;
|
|
78
|
+
error: boolean;
|
|
79
|
+
} | {
|
|
80
|
+
type: 'error';
|
|
81
|
+
message: string;
|
|
82
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,wBAAwB"}
|
package/dist/worker.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { type AiBinding } from '@rubrion/mastra-cloudflare';
|
|
3
|
+
import { type Providers } from './models.js';
|
|
4
|
+
import type { AgentDefinition, Caller, ModelChoice, Price, Usage } from './types.js';
|
|
5
|
+
export interface AgentWorkerOptions<E> {
|
|
6
|
+
agents: AgentDefinition[];
|
|
7
|
+
/** The Workers AI binding. */
|
|
8
|
+
ai: (env: E) => AiBinding;
|
|
9
|
+
/** The D1 database for Mastra Memory (tables are created on first use). */
|
|
10
|
+
memory: (env: E) => D1Database;
|
|
11
|
+
/** Messages recalled into each prompt. Default 8. */
|
|
12
|
+
lastMessages?: number;
|
|
13
|
+
/** Conversations kept per person; the oldest is deleted past this. Default 50. */
|
|
14
|
+
maxThreads?: number;
|
|
15
|
+
/** Tool-call rounds per answer. Default 8. */
|
|
16
|
+
maxSteps?: number;
|
|
17
|
+
/** Longest question accepted, in characters. Default 4000. */
|
|
18
|
+
maxQuestion?: number;
|
|
19
|
+
/** The model when the gateway sends none. Default: Workers AI Gemma. */
|
|
20
|
+
defaultModel?: ModelChoice;
|
|
21
|
+
prices?: Record<string, Price>;
|
|
22
|
+
/** Bring-your-own-key providers the gateway may select (see Providers). Off by default. */
|
|
23
|
+
providers?: Providers;
|
|
24
|
+
/**
|
|
25
|
+
* Text appended to the instructions on every question: a snapshot of what
|
|
26
|
+
* exists (projects, team…), so the agent knows the ground before calling tools.
|
|
27
|
+
*/
|
|
28
|
+
context?: (args: {
|
|
29
|
+
caller: Caller;
|
|
30
|
+
env: E;
|
|
31
|
+
agent: AgentDefinition;
|
|
32
|
+
}) => string | Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
* Wraps each request, e.g. to put the tenant in an AsyncLocalStorage that the
|
|
35
|
+
* tools read so every query is scoped. Must return what `next` returns.
|
|
36
|
+
*/
|
|
37
|
+
scope?: (args: {
|
|
38
|
+
caller: Caller;
|
|
39
|
+
env: E;
|
|
40
|
+
}, next: () => Promise<Response>) => Promise<Response>;
|
|
41
|
+
/** Reported when an answer ends: log it, bill it, enforce a monthly cap. */
|
|
42
|
+
onUsage?: (usage: Usage, env: E) => void | Promise<void>;
|
|
43
|
+
/** Turns provider errors into something the person can act on. */
|
|
44
|
+
errorMessage?: (raw: string) => string;
|
|
45
|
+
}
|
|
46
|
+
export declare function createAgentWorker<E extends object = Record<string, unknown>>(o: AgentWorkerOptions<E>): {
|
|
47
|
+
fetch: (request: Request, env?: {} | E | undefined, executionCtx?: import("hono").ExecutionContext) => Response | Promise<Response>;
|
|
48
|
+
app: Hono<{
|
|
49
|
+
Bindings: E;
|
|
50
|
+
Variables: {
|
|
51
|
+
caller: Caller;
|
|
52
|
+
};
|
|
53
|
+
}, import("hono/types").BlankSchema, "/">;
|
|
54
|
+
};
|
package/dist/worker.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// The agent worker: Mastra agents behind a few plain routes, reached only through
|
|
2
|
+
// a service binding from the gateway (no public route).
|
|
3
|
+
//
|
|
4
|
+
// GET /agents the agents (id, name, tagline, thinking)
|
|
5
|
+
// POST /stream one question: Mastra's stream as slim SSE
|
|
6
|
+
// GET /threads the person's recent conversations (all agents)
|
|
7
|
+
// GET /threads/:id one conversation, shaped as the UI draws it (?agent=)
|
|
8
|
+
// DELETE /threads/:id delete a conversation
|
|
9
|
+
//
|
|
10
|
+
// Own routes rather than Mastra's REST server: importing that route table at load
|
|
11
|
+
// costs most of a Worker's startup budget.
|
|
12
|
+
import { Hono } from 'hono';
|
|
13
|
+
import { Agent, Mastra, RequestContext, d1Memory, workersAIOptions } from '@rubrion/mastra-cloudflare';
|
|
14
|
+
import { readCaller, HEADER } from './headers.js';
|
|
15
|
+
import { DEFAULT_MODEL, isWorkersAI, priceOf, readModelChoice, resolveModel, PRICES } from './models.js';
|
|
16
|
+
import { defaultErrorMessage, slim, sse, SSE_DONE, usageOf } from './stream.js';
|
|
17
|
+
import { toTurns } from './turns.js';
|
|
18
|
+
const CLIENT_ID = /^[a-z0-9]{6,32}$/i;
|
|
19
|
+
const TITLE_CHARS = 60;
|
|
20
|
+
export function createAgentWorker(o) {
|
|
21
|
+
const lastMessages = o.lastMessages ?? 8;
|
|
22
|
+
const maxThreads = o.maxThreads ?? 50;
|
|
23
|
+
const maxSteps = o.maxSteps ?? 8;
|
|
24
|
+
const maxQuestion = o.maxQuestion ?? 4000;
|
|
25
|
+
const prices = { ...PRICES, ...o.prices };
|
|
26
|
+
const errorMessage = o.errorMessage ?? defaultErrorMessage;
|
|
27
|
+
const fallback = o.defaultModel ?? { provider: 'workers-ai', model: DEFAULT_MODEL };
|
|
28
|
+
if (!o.agents.length)
|
|
29
|
+
throw new Error('createAgentWorker: at least one agent');
|
|
30
|
+
// Bindings are stable per isolate; memory and agents are built on the first request.
|
|
31
|
+
let current;
|
|
32
|
+
const getMemory = d1Memory(() => o.memory(current), { id: 'agent-kit-memory', lastMessages });
|
|
33
|
+
const built = new Map();
|
|
34
|
+
let mastra;
|
|
35
|
+
const definition = (id) => o.agents.find((a) => a.id === id) ?? o.agents[0];
|
|
36
|
+
function agentOf(def) {
|
|
37
|
+
let agent = built.get(def.id);
|
|
38
|
+
if (!agent) {
|
|
39
|
+
agent = new Agent({
|
|
40
|
+
id: def.id,
|
|
41
|
+
name: def.name,
|
|
42
|
+
instructions: def.instructions,
|
|
43
|
+
// the model is resolved per request: the tenant may bring its own key
|
|
44
|
+
model: (({ requestContext }) => resolveModel(requestContext?.get('model') ?? fallback, o.ai(current), Boolean(def.thinking), o.providers)),
|
|
45
|
+
tools: def.tools,
|
|
46
|
+
memory: () => getMemory(),
|
|
47
|
+
});
|
|
48
|
+
built.set(def.id, agent);
|
|
49
|
+
}
|
|
50
|
+
return agent;
|
|
51
|
+
}
|
|
52
|
+
/** Conversations belong to tenant + person; nobody opens another's. */
|
|
53
|
+
const ownerOf = (c) => `t${c.tenant}-p${c.person}`;
|
|
54
|
+
const clientId = (thread) => (typeof thread === 'string' && CLIENT_ID.test(thread) ? thread : 'default');
|
|
55
|
+
const threadId = (owner, thread, agent) => `${owner}-${clientId(thread)}-${agent}`;
|
|
56
|
+
async function threadsOf(owner) {
|
|
57
|
+
const r = await getMemory()
|
|
58
|
+
.listThreads({ filter: { resourceId: owner }, orderBy: { field: 'updatedAt', direction: 'DESC' }, perPage: false })
|
|
59
|
+
.catch(() => ({ threads: [] }));
|
|
60
|
+
return r.threads;
|
|
61
|
+
}
|
|
62
|
+
/** Creates the thread on its first message, titled by it, and keeps only the newest maxThreads. */
|
|
63
|
+
async function openThread(owner, thread, agent, message) {
|
|
64
|
+
const memory = getMemory();
|
|
65
|
+
const id = threadId(owner, thread, agent);
|
|
66
|
+
if (await memory.getThreadById({ threadId: id }).catch(() => null))
|
|
67
|
+
return id;
|
|
68
|
+
const now = new Date();
|
|
69
|
+
const title = message.replace(/\s+/g, ' ').trim().slice(0, TITLE_CHARS) || '…';
|
|
70
|
+
await memory.saveThread({ thread: { id, resourceId: owner, title, metadata: { agent, client: clientId(thread) }, createdAt: now, updatedAt: now } });
|
|
71
|
+
const old = (await threadsOf(owner)).slice(maxThreads);
|
|
72
|
+
await Promise.all(old.map((t) => memory.deleteThread(t.id).catch(() => undefined)));
|
|
73
|
+
return id;
|
|
74
|
+
}
|
|
75
|
+
const app = new Hono();
|
|
76
|
+
app.use(async (c, next) => {
|
|
77
|
+
current = c.env;
|
|
78
|
+
const caller = readCaller(c.req.raw.headers);
|
|
79
|
+
if (!caller)
|
|
80
|
+
return c.json({ error: 'Unknown caller.' }, 401);
|
|
81
|
+
c.set('caller', caller);
|
|
82
|
+
if (!o.scope)
|
|
83
|
+
return next();
|
|
84
|
+
return o.scope({ caller, env: c.env }, async () => { await next(); return c.res; });
|
|
85
|
+
});
|
|
86
|
+
app.get('/agents', (c) => c.json(o.agents.map(({ id, name, tagline, thinking }) => ({ id, name, tagline, thinking: Boolean(thinking) }))));
|
|
87
|
+
app.post('/stream', async (c) => {
|
|
88
|
+
const caller = c.get('caller');
|
|
89
|
+
const body = (await c.req.json().catch(() => null));
|
|
90
|
+
const message = typeof body?.message === 'string' ? body.message.trim().slice(0, maxQuestion) : '';
|
|
91
|
+
if (!message)
|
|
92
|
+
return c.json({ error: 'Empty question.' }, 400);
|
|
93
|
+
mastra ??= new Mastra({ agents: Object.fromEntries(o.agents.map((a) => [a.id, agentOf(a)])) });
|
|
94
|
+
const def = definition(body?.agent);
|
|
95
|
+
const agent = agentOf(def);
|
|
96
|
+
const asked = readModelChoice(c.req.header(HEADER.model), fallback);
|
|
97
|
+
const choice = asked.provider === 'workers-ai' || o.providers?.[asked.provider] ? asked : fallback;
|
|
98
|
+
const price = priceOf(choice, prices);
|
|
99
|
+
const owner = ownerOf(caller);
|
|
100
|
+
const thread = await openThread(owner, body?.thread, def.id, message);
|
|
101
|
+
const extra = await Promise.resolve(o.context?.({ caller, env: c.env, agent: def })).catch(() => '');
|
|
102
|
+
const who = caller.name ? `The person asking: ${caller.name}.` : '';
|
|
103
|
+
const instructions = [def.instructions, who, extra].filter(Boolean).join('\n\n');
|
|
104
|
+
const result = await agent.stream([{ role: 'user', content: message }], {
|
|
105
|
+
requestContext: new RequestContext([['caller', caller], ['model', choice]]),
|
|
106
|
+
// Mastra Memory recalls the thread's last messages; the UI sends only the new one.
|
|
107
|
+
memory: { thread, resource: owner },
|
|
108
|
+
maxSteps,
|
|
109
|
+
// temperature 0 on Workers AI: the same question over the same data gives the same answer
|
|
110
|
+
modelSettings: isWorkersAI(choice) ? { maxOutputTokens: def.maxOutputTokens ?? 1200, temperature: 0 } : { maxOutputTokens: 8000 },
|
|
111
|
+
providerOptions: (isWorkersAI(choice) ? workersAIOptions(Boolean(def.thinking)) : undefined),
|
|
112
|
+
instructions,
|
|
113
|
+
abortSignal: c.req.raw.signal,
|
|
114
|
+
});
|
|
115
|
+
const { readable, writable } = new TransformStream();
|
|
116
|
+
const writer = writable.getWriter();
|
|
117
|
+
const enc = new TextEncoder();
|
|
118
|
+
const send = (s) => writer.write(enc.encode(s));
|
|
119
|
+
// No await: the response goes out while this keeps writing to it.
|
|
120
|
+
c.executionCtx.waitUntil((async () => {
|
|
121
|
+
const reader = result.fullStream.getReader();
|
|
122
|
+
let input = 0;
|
|
123
|
+
let output = 0;
|
|
124
|
+
let error = '';
|
|
125
|
+
try {
|
|
126
|
+
for (;;) {
|
|
127
|
+
const { done, value } = await reader.read();
|
|
128
|
+
if (done)
|
|
129
|
+
break;
|
|
130
|
+
const ev = slim(value, errorMessage);
|
|
131
|
+
if (!ev)
|
|
132
|
+
continue;
|
|
133
|
+
if (ev.type === 'step-finish') {
|
|
134
|
+
const u = usageOf(value);
|
|
135
|
+
input += u.input;
|
|
136
|
+
output += u.output;
|
|
137
|
+
}
|
|
138
|
+
else if (ev.type === 'finish' && !input && !output) {
|
|
139
|
+
const u = usageOf(value);
|
|
140
|
+
input = u.input;
|
|
141
|
+
output = u.output;
|
|
142
|
+
}
|
|
143
|
+
if (ev.type === 'error')
|
|
144
|
+
error = ev.message;
|
|
145
|
+
await send(sse(ev));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
error = e.message;
|
|
150
|
+
await send(sse({ type: 'error', message: errorMessage(error) })).catch(() => undefined);
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
const usage = {
|
|
154
|
+
caller, agent: def.id, thread, provider: choice.provider, model: choice.model,
|
|
155
|
+
inputTokens: input, outputTokens: output, costUsd: (input * price.input + output * price.output) / 1_000_000,
|
|
156
|
+
status: error ? 'error' : 'ok', ...(error ? { error: error.slice(0, 500) } : {}),
|
|
157
|
+
};
|
|
158
|
+
await Promise.resolve(o.onUsage?.(usage, c.env)).catch((e) => console.error('onUsage failed', e));
|
|
159
|
+
await send(SSE_DONE).catch(() => undefined);
|
|
160
|
+
await writer.close().catch(() => undefined);
|
|
161
|
+
}
|
|
162
|
+
})());
|
|
163
|
+
return new Response(readable, { headers: { 'content-type': 'text/event-stream', 'cache-control': 'no-cache' } });
|
|
164
|
+
});
|
|
165
|
+
app.get('/threads', async (c) => {
|
|
166
|
+
const threads = (await threadsOf(ownerOf(c.get('caller')))).filter((t) => t.metadata?.agent && t.metadata?.client);
|
|
167
|
+
return c.json(threads.slice(0, maxThreads).map((t) => ({ id: t.metadata.client, agent: t.metadata.agent, title: t.title ?? '', updatedAt: t.updatedAt })));
|
|
168
|
+
});
|
|
169
|
+
/** A stored conversation as the UI draws it: the person's text; the agent's steps and text. */
|
|
170
|
+
app.get('/threads/:id', async (c) => {
|
|
171
|
+
const owner = ownerOf(c.get('caller'));
|
|
172
|
+
const agent = definition(c.req.query('agent')).id;
|
|
173
|
+
const { messages } = await getMemory()
|
|
174
|
+
.recall({ threadId: threadId(owner, c.req.param('id'), agent), resourceId: owner, perPage: false })
|
|
175
|
+
.catch(() => ({ messages: [] }));
|
|
176
|
+
return c.json(toTurns(messages, agent));
|
|
177
|
+
});
|
|
178
|
+
app.delete('/threads/:id', async (c) => {
|
|
179
|
+
const owner = ownerOf(c.get('caller'));
|
|
180
|
+
const memory = getMemory();
|
|
181
|
+
await Promise.all(o.agents.map((a) => memory.deleteThread(threadId(owner, c.req.param('id'), a.id)).catch(() => undefined)));
|
|
182
|
+
return c.json({ ok: true });
|
|
183
|
+
});
|
|
184
|
+
return { fetch: app.fetch, app };
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,51 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rubrion/agent-kit-server",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Agent worker (Mastra on Cloudflare Workers, D1 memory, slim SSE) and the gateway that fronts it.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Rubrion",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/rubrion/agent-kit.git",
|
|
10
|
+
"directory": "packages/server"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/rubrion/agent-kit#readme",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./gateway": {
|
|
22
|
+
"types": "./dist/gateway-entry.d.ts",
|
|
23
|
+
"import": "./dist/gateway-entry.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"sideEffects": false,
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"prepublishOnly": "npm run build"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@rubrion/mastra-cloudflare": "^0.3.1",
|
|
38
|
+
"hono": "^4.13.14"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@cloudflare/workers-types": "^5.20260908.1",
|
|
42
|
+
"typescript": "^5.9.3",
|
|
43
|
+
"vitest": "^5.0.5"
|
|
44
|
+
},
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=20"
|
|
50
|
+
}
|
|
51
|
+
}
|
package/README.md
DELETED