@junejs/server 0.1.0 → 0.1.2-dev.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/agent-durable.d.ts +6 -4
- package/dist/agent-durable.js +23 -6
- package/dist/agent-native.js +2 -1
- package/package.json +3 -3
- package/src/agent-durable.ts +34 -6
- package/src/agent-native.ts +1 -1
package/dist/agent-durable.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { Channel, ChannelFactory } from "@junejs/core/agent-config";
|
|
2
|
-
import { Model, Msg, SessionStore, Tool } from "@junejs/core/agent-runtime";
|
|
2
|
+
import { InboundEvent, Model, Msg, SessionStore, Tool } from "@junejs/core/agent-runtime";
|
|
3
3
|
import { Resources } from "@junejs/core/resources";
|
|
4
4
|
//#region src/agent-durable.d.ts
|
|
5
|
-
|
|
5
|
+
type SqlStorageValue = ArrayBuffer | string | number | null;
|
|
6
|
+
interface SqlStorageCursor<T extends Record<string, SqlStorageValue> = Record<string, SqlStorageValue>> {
|
|
6
7
|
toArray(): T[];
|
|
7
8
|
one(): T;
|
|
8
9
|
}
|
|
9
10
|
interface SqlStorage {
|
|
10
|
-
exec<T = Record<string,
|
|
11
|
+
exec<T extends Record<string, SqlStorageValue> = Record<string, SqlStorageValue>>(query: string, ...bindings: unknown[]): SqlStorageCursor<T>;
|
|
11
12
|
}
|
|
12
13
|
interface DurableStorage {
|
|
13
14
|
sql: SqlStorage;
|
|
@@ -53,6 +54,7 @@ declare class AgentDurableObject {
|
|
|
53
54
|
turn(input: {
|
|
54
55
|
turnId?: string;
|
|
55
56
|
userText: string;
|
|
57
|
+
event?: InboundEvent;
|
|
56
58
|
}): Promise<string>;
|
|
57
59
|
transcript(): import("@junejs/core/agent-runtime").Turn[];
|
|
58
60
|
fetch(req: Request): Promise<Response>;
|
|
@@ -69,4 +71,4 @@ declare function durableChannelSurface(getNamespace: () => DurableObjectNamespac
|
|
|
69
71
|
waitUntil?: (p: Promise<unknown>) => void;
|
|
70
72
|
}): (req: Request) => Promise<Response | null>;
|
|
71
73
|
//#endregion
|
|
72
|
-
export { AgentDurableObject, DoAgentDef, DoSessionStore, DurableObjectNamespace, DurableObjectState, DurableObjectStub, DurableStorage, SqlStorage, SqlStorageCursor, durableAgentSurface, durableChannelSurface, durableFetch };
|
|
74
|
+
export { AgentDurableObject, DoAgentDef, DoSessionStore, DurableObjectNamespace, DurableObjectState, DurableObjectStub, DurableStorage, SqlStorage, SqlStorageCursor, SqlStorageValue, durableAgentSurface, durableChannelSurface, durableFetch };
|
package/dist/agent-durable.js
CHANGED
|
@@ -85,10 +85,11 @@ var AgentDurableObject = class {
|
|
|
85
85
|
async fetch(req) {
|
|
86
86
|
const url = new URL(req.url);
|
|
87
87
|
if (req.method === "POST" && url.pathname.endsWith("/turn")) {
|
|
88
|
-
const { userText, turnId } = await req.json();
|
|
88
|
+
const { userText, turnId, event } = await req.json();
|
|
89
89
|
return Response.json({ text: await this.turn({
|
|
90
90
|
userText,
|
|
91
|
-
turnId
|
|
91
|
+
turnId,
|
|
92
|
+
event
|
|
92
93
|
}) });
|
|
93
94
|
}
|
|
94
95
|
if (url.pathname.endsWith("/transcript")) return Response.json({ transcript: this.transcript() });
|
|
@@ -128,14 +129,30 @@ function durableChannelSurface(getNamespace, opts) {
|
|
|
128
129
|
if (!namespace) throw new Error("durableChannelSurface: no Durable Object namespace bound (env.AGENT)");
|
|
129
130
|
const { text } = await (await durableFetch(namespace, opts.agentName, o?.session ?? "default", new Request("https://do/turn", {
|
|
130
131
|
method: "POST",
|
|
131
|
-
body:
|
|
132
|
-
userText: message,
|
|
133
|
-
turnId: o?.turnId
|
|
134
|
-
})
|
|
132
|
+
body: serializeTurn(message, o)
|
|
135
133
|
}))).json();
|
|
136
134
|
return text;
|
|
137
135
|
}
|
|
138
136
|
});
|
|
139
137
|
}
|
|
138
|
+
function serializeTurn(userText, o) {
|
|
139
|
+
const payload = {
|
|
140
|
+
userText,
|
|
141
|
+
turnId: o?.turnId,
|
|
142
|
+
event: o?.event
|
|
143
|
+
};
|
|
144
|
+
try {
|
|
145
|
+
return JSON.stringify(payload);
|
|
146
|
+
} catch {
|
|
147
|
+
const event = o?.event ? {
|
|
148
|
+
...o.event,
|
|
149
|
+
raw: void 0
|
|
150
|
+
} : void 0;
|
|
151
|
+
return JSON.stringify({
|
|
152
|
+
...payload,
|
|
153
|
+
event
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
140
157
|
//#endregion
|
|
141
158
|
export { AgentDurableObject, DoSessionStore, durableAgentSurface, durableChannelSurface, durableFetch };
|
package/dist/agent-native.js
CHANGED
|
@@ -154,7 +154,8 @@ function mountAgent(agent, runtime, opts = {}) {
|
|
|
154
154
|
agent,
|
|
155
155
|
run: (message, o) => runtime.session(agent.name, o?.session ?? "default").turn({
|
|
156
156
|
turnId: o?.turnId,
|
|
157
|
-
userText: message
|
|
157
|
+
userText: message,
|
|
158
|
+
event: o?.event
|
|
158
159
|
})
|
|
159
160
|
};
|
|
160
161
|
const channels = channelFetch(agent, ctx);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@junejs/server",
|
|
3
|
-
"version": "0.1.0",
|
|
3
|
+
"version": "0.1.2-dev.0",
|
|
4
4
|
"description": "June host adapters + dev server. Host-coupled; depends on the pure @junejs/core contract layer.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -125,8 +125,8 @@
|
|
|
125
125
|
"build": "tsdown"
|
|
126
126
|
},
|
|
127
127
|
"dependencies": {
|
|
128
|
-
"@junejs/core": ">=0.1.0",
|
|
129
|
-
"@junejs/db": ">=0.0.
|
|
128
|
+
"@junejs/core": ">=0.1.1-dev.0",
|
|
129
|
+
"@junejs/db": ">=0.0.34-dev.0",
|
|
130
130
|
"@momiji-rs/sparkdown": "^0.0.4",
|
|
131
131
|
"lightningcss": "^1.27.0",
|
|
132
132
|
"oxc-parser": "^0.137.0",
|
package/src/agent-durable.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
type Model,
|
|
23
23
|
type Msg,
|
|
24
24
|
type Runtime,
|
|
25
|
+
type InboundEvent,
|
|
25
26
|
type SessionStore,
|
|
26
27
|
type Tool,
|
|
27
28
|
} from "@junejs/core/agent-runtime";
|
|
@@ -37,12 +38,23 @@ import {
|
|
|
37
38
|
import { ensureScope, runInScope } from "@junejs/db";
|
|
38
39
|
|
|
39
40
|
// ── minimal structural Cloudflare surface (no @cloudflare/workers-types dep) ──
|
|
40
|
-
|
|
41
|
+
// SqlStorage row values are exactly what workerd's SQLite returns. Mirroring
|
|
42
|
+
// @cloudflare/workers-types' `T extends Record<string, SqlStorageValue>` constraint
|
|
43
|
+
// STRUCTURALLY (not importing it) makes `this.ctx.storage` directly assignable to
|
|
44
|
+
// these interfaces, so a DO shell needs no `as unknown as JuneDoState` cast. The
|
|
45
|
+
// constraint (not just a default) is what lets the two `exec` signatures unify:
|
|
46
|
+
// an unconstrained `T` promises `toArray(): T[]` for arbitrary T, which workerd's
|
|
47
|
+
// cursor — only ever `Record<string, SqlStorageValue>` rows — cannot satisfy.
|
|
48
|
+
export type SqlStorageValue = ArrayBuffer | string | number | null;
|
|
49
|
+
export interface SqlStorageCursor<T extends Record<string, SqlStorageValue> = Record<string, SqlStorageValue>> {
|
|
41
50
|
toArray(): T[];
|
|
42
51
|
one(): T;
|
|
43
52
|
}
|
|
44
53
|
export interface SqlStorage {
|
|
45
|
-
exec<T
|
|
54
|
+
exec<T extends Record<string, SqlStorageValue> = Record<string, SqlStorageValue>>(
|
|
55
|
+
query: string,
|
|
56
|
+
...bindings: unknown[]
|
|
57
|
+
): SqlStorageCursor<T>;
|
|
46
58
|
}
|
|
47
59
|
export interface DurableStorage {
|
|
48
60
|
sql: SqlStorage;
|
|
@@ -179,7 +191,7 @@ export class AgentDurableObject {
|
|
|
179
191
|
// Juno's batch-loader registry) can't leak across turns on a long-lived DO.
|
|
180
192
|
// ensureScope() lazily wires node:async_hooks (workerd via nodejs_compat), as the
|
|
181
193
|
// pipeline does; without it runInScope is a pass-through and ambient reads throw.
|
|
182
|
-
async turn(input: { turnId?: string; userText: string }): Promise<string> {
|
|
194
|
+
async turn(input: { turnId?: string; userText: string; event?: InboundEvent }): Promise<string> {
|
|
183
195
|
await ensureScope();
|
|
184
196
|
return runInScope({ resources: this.resources, services: this.services }, () => this.session.turn(input));
|
|
185
197
|
}
|
|
@@ -191,8 +203,8 @@ export class AgentDurableObject {
|
|
|
191
203
|
async fetch(req: Request): Promise<Response> {
|
|
192
204
|
const url = new URL(req.url);
|
|
193
205
|
if (req.method === "POST" && url.pathname.endsWith("/turn")) {
|
|
194
|
-
const { userText, turnId } = (await req.json()) as { userText: string; turnId?: string };
|
|
195
|
-
return Response.json({ text: await this.turn({ userText, turnId }) });
|
|
206
|
+
const { userText, turnId, event } = (await req.json()) as { userText: string; turnId?: string; event?: InboundEvent };
|
|
207
|
+
return Response.json({ text: await this.turn({ userText, turnId, event }) });
|
|
196
208
|
}
|
|
197
209
|
if (url.pathname.endsWith("/transcript")) return Response.json({ transcript: this.transcript() });
|
|
198
210
|
return new Response("agent DO — POST /turn or GET /transcript", { status: 404 });
|
|
@@ -282,7 +294,7 @@ export function durableChannelSurface(
|
|
|
282
294
|
namespace,
|
|
283
295
|
opts.agentName,
|
|
284
296
|
o?.session ?? "default",
|
|
285
|
-
new Request("https://do/turn", { method: "POST", body:
|
|
297
|
+
new Request("https://do/turn", { method: "POST", body: serializeTurn(message, o) }),
|
|
286
298
|
);
|
|
287
299
|
const { text } = (await res.json()) as { text: string };
|
|
288
300
|
return text;
|
|
@@ -290,3 +302,19 @@ export function durableChannelSurface(
|
|
|
290
302
|
};
|
|
291
303
|
return channelDispatch(resolved, ctx);
|
|
292
304
|
}
|
|
305
|
+
|
|
306
|
+
// Serialize a turn for the /turn RPC body. InboundEvent.raw is `unknown` — the
|
|
307
|
+
// untouched platform payload — so a (third-party) channel could attach something
|
|
308
|
+
// JSON.stringify chokes on (a circular object, a BigInt). raw isn't needed to route or
|
|
309
|
+
// run the turn, so on a serialization failure we drop it rather than let an
|
|
310
|
+
// unserializable payload take down turn forwarding entirely. (raw is optional on
|
|
311
|
+
// InboundEvent precisely because it may not survive this boundary.)
|
|
312
|
+
function serializeTurn(userText: string, o?: { turnId?: string; event?: InboundEvent }): string {
|
|
313
|
+
const payload = { userText, turnId: o?.turnId, event: o?.event };
|
|
314
|
+
try {
|
|
315
|
+
return JSON.stringify(payload);
|
|
316
|
+
} catch {
|
|
317
|
+
const event = o?.event ? { ...o.event, raw: undefined } : undefined;
|
|
318
|
+
return JSON.stringify({ ...payload, event });
|
|
319
|
+
}
|
|
320
|
+
}
|
package/src/agent-native.ts
CHANGED
|
@@ -207,7 +207,7 @@ export function mountAgent(
|
|
|
207
207
|
const ctx: ChannelContext = {
|
|
208
208
|
agent,
|
|
209
209
|
run: (message, o) =>
|
|
210
|
-
runtime.session(agent.name, o?.session ?? "default").turn({ turnId: o?.turnId, userText: message }),
|
|
210
|
+
runtime.session(agent.name, o?.session ?? "default").turn({ turnId: o?.turnId, userText: message, event: o?.event }),
|
|
211
211
|
};
|
|
212
212
|
const channels = channelFetch(agent, ctx);
|
|
213
213
|
const surface = async (req: Request): Promise<Response | null> => {
|