@junejs/server 0.1.2-dev.0 → 0.1.2-dev.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.
@@ -43,6 +43,9 @@ type DoAgentDef = {
43
43
  model: Model;
44
44
  tools: Tool[];
45
45
  instructions?: string;
46
+ channelInstructions?: Record<string, string>;
47
+ channels?: (Channel | ChannelFactory)[];
48
+ env?: unknown;
46
49
  resources?: Resources;
47
50
  services?: unknown;
48
51
  };
@@ -70,7 +70,15 @@ var AgentDurableObject = class {
70
70
  const model = def.instructions ? withSystem(def.model, def.instructions) : def.model;
71
71
  this.resources = def.resources ?? {};
72
72
  this.services = def.services;
73
- this.session = new AgentSession(def.name ?? "agent", "self", store, new InProcBroadcaster(), model, def.tools, crossDoUnsupported);
73
+ const channelTools = (def.channels ?? []).flatMap((c) => resolveChannel(c, def.env).tools?.() ?? []);
74
+ const tools = [...def.tools];
75
+ const seen = new Set(tools.map((t) => t.spec.name));
76
+ for (const t of channelTools) {
77
+ if (seen.has(t.spec.name)) throw new Error(`AgentDurableObject(${def.name ?? "agent"}): duplicate tool name "${t.spec.name}" from a channel — rename so dispatch is unambiguous.`);
78
+ seen.add(t.spec.name);
79
+ tools.push(t);
80
+ }
81
+ this.session = new AgentSession(def.name ?? "agent", "self", store, new InProcBroadcaster(), model, tools, crossDoUnsupported, def.channelInstructions);
74
82
  }
75
83
  async turn(input) {
76
84
  await ensureScope();
@@ -6,6 +6,7 @@ type AgentDef = {
6
6
  model: Model;
7
7
  tools: Tool[];
8
8
  instructions?: string;
9
+ channelInstructions?: Record<string, string>;
9
10
  };
10
11
  declare class NativeRuntime implements Runtime {
11
12
  private actors;
@@ -81,7 +81,7 @@ var NativeRuntime = class {
81
81
  const def = this.agents[agent];
82
82
  if (!def) throw new Error(`unknown agent: ${agent}`);
83
83
  const model = def.instructions ? withSystem(def.model, def.instructions) : def.model;
84
- a = new AgentSession(agent, id, new SqliteSessionStore(this.db, key), new InProcBroadcaster(), model, def.tools, this);
84
+ a = new AgentSession(agent, id, new SqliteSessionStore(this.db, key), new InProcBroadcaster(), model, def.tools, this, def.channelInstructions);
85
85
  this.actors.set(key, a);
86
86
  }
87
87
  return a;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@junejs/server",
3
- "version": "0.1.2-dev.0",
3
+ "version": "0.1.2-dev.1",
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,7 +125,7 @@
125
125
  "build": "tsdown"
126
126
  },
127
127
  "dependencies": {
128
- "@junejs/core": ">=0.1.1-dev.0",
128
+ "@junejs/core": ">=0.1.1-dev.3",
129
129
  "@junejs/db": ">=0.0.34-dev.0",
130
130
  "@momiji-rs/sparkdown": "^0.0.4",
131
131
  "lightningcss": "^1.27.0",
@@ -153,6 +153,16 @@ export type DoAgentDef = {
153
153
  model: Model;
154
154
  tools: Tool[];
155
155
  instructions?: string;
156
+ // Per-channel-source system overlays (see AgentDefinition.channelInstructions) — the
157
+ // shared agent branches by real inbound source, no userText marker.
158
+ channelInstructions?: Record<string, string>;
159
+ // Channels whose CAPABILITY tools should be available to this session's turns. Their
160
+ // tools are built HERE, in the DO isolate, from `env` — because a channel's tool `run`
161
+ // is a closure (over the bot token, etc.) that can't cross the worker→DO RPC. This is
162
+ // the edge equivalent of defineAgent merging channel.tools() on native: pass the same
163
+ // channel factories you mount on the worker, plus this DO's env.
164
+ channels?: (Channel | ChannelFactory)[];
165
+ env?: unknown;
156
166
  resources?: Resources;
157
167
  services?: unknown;
158
168
  };
@@ -182,7 +192,18 @@ export class AgentDurableObject {
182
192
  const model = def.instructions ? withSystem(def.model, def.instructions) : def.model;
183
193
  this.resources = def.resources ?? {};
184
194
  this.services = def.services;
185
- this.session = new AgentSession(def.name ?? "agent", "self", store, new InProcBroadcaster(), model, def.tools, crossDoUnsupported);
195
+ // Merge the mounted channels' capability tools (built here from this DO's env, since a
196
+ // tool's `run` closure can't cross the RPC). The cross-channel source gate on each tool
197
+ // keeps a Slack tool inert during a Crisp turn, so merging all of them is safe.
198
+ const channelTools = (def.channels ?? []).flatMap((c) => resolveChannel(c, def.env).tools?.() ?? []);
199
+ const tools: Tool[] = [...def.tools];
200
+ const seen = new Set(tools.map((t) => t.spec.name));
201
+ for (const t of channelTools) {
202
+ if (seen.has(t.spec.name)) throw new Error(`AgentDurableObject(${def.name ?? "agent"}): duplicate tool name "${t.spec.name}" from a channel — rename so dispatch is unambiguous.`);
203
+ seen.add(t.spec.name);
204
+ tools.push(t);
205
+ }
206
+ this.session = new AgentSession(def.name ?? "agent", "self", store, new InProcBroadcaster(), model, tools, crossDoUnsupported, def.channelInstructions);
186
207
  }
187
208
  // Run the whole turn inside a request scope seeded from this DO's env, so ambient
188
209
  // `db`/`kv`/`blob` and `currentServices()` resolve inside a tool exactly as in a
@@ -85,7 +85,7 @@ class InProcBroadcaster implements Broadcaster {
85
85
 
86
86
  // `instructions` (the agent's system prompt) is injected into the model per turn
87
87
  // by the runtime (withSystem) — single-sourced on the def, not baked into `model`.
88
- export type AgentDef = { model: Model; tools: Tool[]; instructions?: string };
88
+ export type AgentDef = { model: Model; tools: Tool[]; instructions?: string; channelInstructions?: Record<string, string> };
89
89
 
90
90
  // The native Runtime: a registry of agent definitions over one SQLite handle,
91
91
  // handing out (and memoizing) an AgentSession actor per (agent, id).
@@ -107,7 +107,7 @@ export class NativeRuntime implements Runtime {
107
107
  const def = this.agents[agent];
108
108
  if (!def) throw new Error(`unknown agent: ${agent}`);
109
109
  const model = def.instructions ? withSystem(def.model, def.instructions) : def.model;
110
- a = new AgentSession(agent, id, new SqliteSessionStore(this.db, key), new InProcBroadcaster(), model, def.tools, this);
110
+ a = new AgentSession(agent, id, new SqliteSessionStore(this.db, key), new InProcBroadcaster(), model, def.tools, this, def.channelInstructions);
111
111
  this.actors.set(key, a);
112
112
  }
113
113
  return a;