@economic/agents 2.14.0 → 2.14.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/index.d.mts CHANGED
@@ -226,6 +226,16 @@ interface TurnSnapshot {
226
226
  frameworkToolNames: string[];
227
227
  messages: ModelMessage[];
228
228
  }
229
+ type CurrentTurnState<RequestContext extends Record<string, unknown>, UserContext extends Record<string, unknown>> = {
230
+ context?: ToolContext<RequestContext, UserContext>;
231
+ inputTools: ToolSet;
232
+ preparedTools: ToolSet;
233
+ unavailableSkillIds: Set<string>;
234
+ skillsSystemBlock: string;
235
+ visibleSkillNames: string[];
236
+ authorizedSkillNames: Set<string>;
237
+ baseSystem: string;
238
+ };
229
239
  type Authentication<UserContext> = {
230
240
  success: true;
231
241
  userContext?: UserContext;
@@ -249,8 +259,9 @@ declare abstract class Agent<RequestContext extends Record<string, unknown> = Re
249
259
  onStart(): Promise<void>;
250
260
  configureSession(session: Session): Session;
251
261
  onConnect(connection: Connection, ctx: ConnectionContext): Promise<void>;
252
- private _turn;
253
- private getToolContextForCurrentTurn;
262
+ protected _turn: CurrentTurnState<RequestContext, UserContext>;
263
+ protected createToolContextForCurrentTurn(requestContext?: RequestContext): ToolContext<RequestContext, UserContext>;
264
+ protected getToolContextForCurrentTurn(): ToolContext<RequestContext, UserContext> | undefined;
254
265
  /**
255
266
  * Merges the client request `body` into `experimental_context` for tools
256
267
  * returned from {@link getTools} only (Think-internal tools are unchanged).
package/dist/index.mjs CHANGED
@@ -1158,13 +1158,17 @@ var Agent = class extends Think {
1158
1158
  authorizedSkillNames: /* @__PURE__ */ new Set(),
1159
1159
  baseSystem: ""
1160
1160
  };
1161
- getToolContextForCurrentTurn(requestContext = {}) {
1161
+ createToolContextForCurrentTurn(requestContext = {}) {
1162
1162
  const connectionState = getCurrentAgent().connection?.state;
1163
1163
  return {
1164
+ ...this._turn.context,
1164
1165
  ...requestContext,
1165
1166
  _userContext: connectionState?.userContext ?? this.userContext
1166
1167
  };
1167
1168
  }
1169
+ getToolContextForCurrentTurn() {
1170
+ return this._turn.context;
1171
+ }
1168
1172
  /**
1169
1173
  * Merges the client request `body` into `experimental_context` for tools
1170
1174
  * returned from {@link getTools} only (Think-internal tools are unchanged).
@@ -1175,8 +1179,11 @@ var Agent = class extends Think {
1175
1179
  async beforeTurn(ctx) {
1176
1180
  this.analytics.promptReceived(ctx.messages, ctx.continuation);
1177
1181
  this.registerInstanceActivity();
1178
- const body = await this._applyTokenExchange(ctx.body);
1179
- this._turn.context = this.getToolContextForCurrentTurn(body);
1182
+ const body = await this._applyTokenExchange({
1183
+ ...this._turn.context,
1184
+ ...ctx.body
1185
+ });
1186
+ this._turn.context = this.createToolContextForCurrentTurn(body);
1180
1187
  this._turn.inputTools = ctx.tools;
1181
1188
  const activeSkillName = this._getLastActivatedSkillName(ctx.messages);
1182
1189
  const { tools, activeTools } = await this._prepareTools(ctx.tools, activeSkillName, true);
@@ -2851,38 +2858,48 @@ var ChatAgent = class extends Agent {
2851
2858
  * returned immediately and each event reaches the client as it is produced.
2852
2859
  */
2853
2860
  async streamMessage(request) {
2854
- let message;
2861
+ let payload;
2855
2862
  try {
2856
- ({message} = await request.json());
2863
+ payload = await request.json();
2857
2864
  } catch {
2858
- return Response.json({ error: "Invalid request body" }, { status: 400 });
2865
+ return Response.json({ error: "Request body must be valid JSON" }, { status: 400 });
2859
2866
  }
2860
- if (typeof message === "string") message = {
2861
- id: crypto.randomUUID(),
2862
- role: "user",
2863
- parts: [{
2864
- type: "text",
2865
- text: message
2866
- }]
2867
- };
2868
- else if (!message || message.role !== "user" || !Array.isArray(message.parts)) return Response.json({ error: "message must be a user message" }, { status: 400 });
2867
+ if (!payload || typeof payload !== "object" || Array.isArray(payload)) return Response.json({ error: "Request body must be an object" }, { status: 400 });
2868
+ let { message, context } = payload;
2869
+ if (context !== void 0 && (context === null || typeof context !== "object" || Array.isArray(context))) return Response.json({ error: "Context must be an object" }, { status: 400 });
2870
+ if (typeof message === "string") {
2871
+ if (!message.trim()) return Response.json({ error: "Message must not be empty" }, { status: 400 });
2872
+ message = {
2873
+ id: crypto.randomUUID(),
2874
+ role: "user",
2875
+ parts: [{
2876
+ type: "text",
2877
+ text: message
2878
+ }]
2879
+ };
2880
+ } else if (!message || typeof message !== "object" || Array.isArray(message) || typeof message.id !== "string" || !message.id || message.role !== "user" || !Array.isArray(message.parts)) return Response.json({ error: "Message must be a non-empty string or a user UIMessage" }, { status: 400 });
2881
+ const input = context ? () => {
2882
+ this._turn.context = this.createToolContextForCurrentTurn(context);
2883
+ return [message];
2884
+ } : message;
2869
2885
  const encoder = new TextEncoder();
2870
2886
  const readable = new ReadableStream({ start: async (controller) => {
2871
2887
  const send = (event, data) => controller.enqueue(encoder.encode(`event: ${event}\ndata: ${data}\n\n`));
2888
+ const sendError = (error) => send("error", JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
2872
2889
  try {
2873
2890
  await this.runTurn({
2874
2891
  mode: "stream",
2875
- input: message,
2892
+ input,
2876
2893
  callback: {
2877
2894
  onStart: (event) => send("start", JSON.stringify(event)),
2878
2895
  onEvent: (json) => send("chunk", json),
2879
2896
  onDone: () => send("done", "{}"),
2880
- onError: (error) => send("error", JSON.stringify({ error })),
2897
+ onError: sendError,
2881
2898
  onInterrupted: () => send("interrupted", "{}")
2882
2899
  }
2883
2900
  });
2884
2901
  } catch (error) {
2885
- send("error", JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
2902
+ sendError(error);
2886
2903
  } finally {
2887
2904
  controller.close();
2888
2905
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@economic/agents",
3
- "version": "2.14.0",
3
+ "version": "2.14.1",
4
4
  "description": "A starter for creating a TypeScript package.",
5
5
  "license": "MIT",
6
6
  "files": [