@cloudbase/agent-server 0.0.9 → 0.0.12

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @cloudbase/agent-server
2
2
 
3
+ ## 1.0.1-alpha.6
4
+
5
+ ### Patch Changes
6
+
7
+ - alpha release 0.1.2-alpha.1
8
+ - Update all public packages to version 0.1.2-alpha.1
9
+ - Trigger automated alpha release workflow
10
+ - Includes latest features and improvements
11
+
12
+ - Updated dependencies
13
+ - @cloudbase/agent-shared@1.0.1-alpha.6
14
+
3
15
  ## 1.0.1-alpha.5
4
16
 
5
17
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { CreateCopilotRuntimeServerOptions } from '@copilotkit/runtime';
2
2
  import { CopilotRuntimeOptions } from '@copilotkit/runtime/v2';
3
- import express, { Express } from 'express';
3
+ import expressLib, { Express } from 'express';
4
4
  import * as _ag_ui_client from '@ag-ui/client';
5
5
  import { AbstractAgent, RunAgentInput } from '@ag-ui/client';
6
6
  import cors from 'cors';
@@ -9,13 +9,25 @@ import { Repeater } from '@repeaterjs/repeater';
9
9
  import * as _whatwg_node_server from '@whatwg-node/server';
10
10
  import { OpenAI } from 'openai';
11
11
 
12
+ /**
13
+ * Context passed to the agent factory function.
14
+ * Contains request information for per-request agent configuration.
15
+ */
16
+ interface AgentCreatorContext {
17
+ /** The incoming HTTP request (Web Standard Request) */
18
+ request: Request;
19
+ }
12
20
  type AgentCreatorRet = {
13
21
  agent: AbstractAgent | {
14
22
  toAGUIAgent(): AbstractAgent;
15
23
  };
16
24
  cleanup?: () => void;
17
25
  };
18
- type AgentCreator = () => AgentCreatorRet | Promise<AgentCreatorRet>;
26
+ /**
27
+ * Factory function to create an agent.
28
+ * Can optionally receive request context for per-request configuration.
29
+ */
30
+ type AgentCreator = ((context: AgentCreatorContext) => AgentCreatorRet | Promise<AgentCreatorRet>) | (() => AgentCreatorRet | Promise<AgentCreatorRet>);
19
31
  interface ICreateServer {
20
32
  createAgent: AgentCreator;
21
33
  basePath?: `/${string}/`;
@@ -31,7 +43,7 @@ interface ICreateExpressRoutes extends Omit<ICreateServer, "cors"> {
31
43
  }
32
44
  declare function run(props: IRun): void;
33
45
  declare function createExpressServer(props: ICreateServer): Express;
34
- declare function createExpressRoutes({ createAgent, basePath: _basePath, express, useAGUI: _useAGUI, aguiOptions, }: ICreateExpressRoutes): express.Express;
46
+ declare function createExpressRoutes({ createAgent, basePath: _basePath, express, useAGUI: _useAGUI, aguiOptions, }: ICreateExpressRoutes): expressLib.Express;
35
47
  interface AGUIOptions {
36
48
  runtimeOptions?: Partial<CopilotRuntimeOptions>;
37
49
  endpointOptions?: Partial<CreateCopilotRuntimeServerOptions>;
@@ -107,4 +119,4 @@ declare namespace index {
107
119
  export { index$2 as healthz, index$1 as openai, index$4 as sendMessage, index$3 as sendMessageAGUI };
108
120
  }
109
121
 
110
- export { type AgentCreator, index as agui, createExpressRoutes, createExpressServer, run };
122
+ export { type AgentCreator, type AgentCreatorContext, index as agui, createExpressRoutes, createExpressServer, run };
package/dist/index.js CHANGED
@@ -166,7 +166,9 @@ var import_agent_shared = require("@cloudbase/agent-shared");
166
166
  function createServerAdapter(createAgent) {
167
167
  return (0, import_server.createServerAdapter)(async (request) => {
168
168
  const input = import_agent_shared.sendMessageInputSchema.parse(await request.json());
169
- const { agent: unknownAgent, cleanup } = await Promise.resolve(createAgent());
169
+ const { agent: unknownAgent, cleanup } = await Promise.resolve(
170
+ createAgent({ request })
171
+ );
170
172
  const agent = "toAGUIAgent" in unknownAgent ? unknownAgent.toAGUIAgent() : unknownAgent;
171
173
  const events = handler(input, agent);
172
174
  let heartbeat;
@@ -229,13 +231,68 @@ function handler2(input, agent) {
229
231
  // src/agui/sendMessageAGUI/server.ts
230
232
  var import_server3 = require("@whatwg-node/server");
231
233
  var import_client2 = require("@ag-ui/client");
234
+ var import_uuid2 = require("uuid");
232
235
  function createServerAdapter2(createAgent) {
233
236
  return (0, import_server3.createServerAdapter)(async (request) => {
234
- const input = import_client2.RunAgentInputSchema.parse(await request.json());
235
- const { agent: unknownAgent, cleanup } = await Promise.resolve(createAgent());
236
- const agent = "toAGUIAgent" in unknownAgent ? unknownAgent.toAGUIAgent() : unknownAgent;
237
- const events = handler2(input, agent);
237
+ const inputRes = await safeAsync(async () => {
238
+ const rawInput = await request.json();
239
+ const inputWithDefaults = {
240
+ tools: [],
241
+ context: [],
242
+ state: {},
243
+ forwardedProps: {},
244
+ ...rawInput,
245
+ runId: typeof rawInput.runId === "string" && rawInput.runId ? rawInput.runId : (0, import_uuid2.v4)()
246
+ };
247
+ return import_client2.RunAgentInputSchema.parse(inputWithDefaults);
248
+ });
249
+ if ("error" in inputRes) {
250
+ const { error } = inputRes;
251
+ console.error("[AGUI Server] Pre-stream error:", error);
252
+ return new Response(
253
+ JSON.stringify({
254
+ error: error instanceof Error ? error.message : String(error)
255
+ }),
256
+ {
257
+ status: 400,
258
+ headers: { "Content-Type": "application/json" }
259
+ }
260
+ );
261
+ }
262
+ const createAgentRes = await safeAsync(async () => {
263
+ const res = await Promise.resolve(createAgent({ request }));
264
+ return {
265
+ cleanup: res.cleanup,
266
+ agent: "toAGUIAgent" in res.agent ? res.agent.toAGUIAgent() : res.agent
267
+ };
268
+ });
269
+ if ("error" in createAgentRes) {
270
+ const { error } = createAgentRes;
271
+ console.error("[AGUI Server] Pre-stream error:", error);
272
+ return new Response(
273
+ JSON.stringify({
274
+ error: error instanceof Error ? error.message : String(error)
275
+ }),
276
+ {
277
+ status: 500,
278
+ headers: { "Content-Type": "application/json" }
279
+ }
280
+ );
281
+ }
282
+ const events = handler2(inputRes.result, createAgentRes.result.agent);
238
283
  let heartbeat;
284
+ let cleanupCalled = false;
285
+ const safeCleanup = () => {
286
+ var _a, _b;
287
+ if (!cleanupCalled) {
288
+ cleanupCalled = true;
289
+ try {
290
+ (_b = (_a = createAgentRes.result).cleanup) == null ? void 0 : _b.call(_a);
291
+ } catch (e) {
292
+ console.error(e);
293
+ }
294
+ }
295
+ };
239
296
  const stream = new ReadableStream({
240
297
  async start(controller) {
241
298
  const encoder = new TextEncoder();
@@ -249,14 +306,26 @@ function createServerAdapter2(createAgent) {
249
306
  `;
250
307
  controller.enqueue(encoder.encode(sseChunk));
251
308
  }
309
+ } catch (error) {
310
+ console.error("[AGUI Server] Stream error:", error);
311
+ const errorEvent = {
312
+ type: import_client2.EventType.RUN_ERROR,
313
+ message: error instanceof Error ? error.message : String(error)
314
+ };
315
+ controller.enqueue(
316
+ encoder.encode(`data: ${JSON.stringify(errorEvent)}
317
+
318
+ `)
319
+ );
252
320
  } finally {
253
321
  if (heartbeat) clearInterval(heartbeat);
254
322
  controller.close();
255
- cleanup == null ? void 0 : cleanup();
323
+ safeCleanup();
256
324
  }
257
325
  },
258
326
  cancel() {
259
327
  if (heartbeat) clearInterval(heartbeat);
328
+ safeCleanup();
260
329
  }
261
330
  });
262
331
  const headers = new Headers({
@@ -267,6 +336,15 @@ function createServerAdapter2(createAgent) {
267
336
  return new Response(stream, { status: 200, headers });
268
337
  });
269
338
  }
339
+ async function safeAsync(fn) {
340
+ try {
341
+ return {
342
+ result: await fn()
343
+ };
344
+ } catch (error) {
345
+ return { error };
346
+ }
347
+ }
270
348
 
271
349
  // src/agui/healthz/index.ts
272
350
  var healthz_exports = {};
@@ -284,7 +362,7 @@ __export(openai_exports, {
284
362
  });
285
363
 
286
364
  // src/agui/openai/handler.ts
287
- var import_uuid2 = require("uuid");
365
+ var import_uuid3 = require("uuid");
288
366
  var import_repeater3 = require("@repeaterjs/repeater");
289
367
  function handler3(input, agent) {
290
368
  var _a;
@@ -296,12 +374,12 @@ function handler3(input, agent) {
296
374
  description: tool.function.description,
297
375
  parameters: tool.function.parameters
298
376
  })),
299
- conversationId: (0, import_uuid2.v4)()
377
+ conversationId: (0, import_uuid3.v4)()
300
378
  },
301
379
  agent
302
380
  );
303
381
  return new import_repeater3.Repeater(async (push, stop) => {
304
- const id = (0, import_uuid2.v4)();
382
+ const id = (0, import_uuid3.v4)();
305
383
  let tools = [];
306
384
  let lastWithToolCall = false;
307
385
  let maxIndex = 0;
@@ -430,7 +508,9 @@ var import_server6 = require("@whatwg-node/server");
430
508
  function createServerAdapter3(createAgent) {
431
509
  return (0, import_server6.createServerAdapter)(async (request) => {
432
510
  const input = await request.json();
433
- const { agent: unknownAgent, cleanup } = await Promise.resolve(createAgent());
511
+ const { agent: unknownAgent, cleanup } = await Promise.resolve(
512
+ createAgent({ request })
513
+ );
434
514
  const agent = "toAGUIAgent" in unknownAgent ? unknownAgent.toAGUIAgent() : unknownAgent;
435
515
  const events = handler3(input, agent);
436
516
  const stream = new ReadableStream({
@@ -460,6 +540,19 @@ function createServerAdapter3(createAgent) {
460
540
  var import_runtime = require("@copilotkit/runtime");
461
541
  var import_express = __toESM(require("express"));
462
542
  var import_cors = __toESM(require("cors"));
543
+ var import_async_hooks = require("async_hooks");
544
+ var import_server8 = require("@whatwg-node/server");
545
+ var DefaultFetchAPI = __toESM(require("@whatwg-node/fetch"));
546
+ var preparedAgentStorage = new import_async_hooks.AsyncLocalStorage();
547
+ function agentCloneFn() {
548
+ const preparedAgent = preparedAgentStorage.getStore();
549
+ if (preparedAgent) {
550
+ return preparedAgent;
551
+ }
552
+ throw new Error(
553
+ "agent.clone() called outside of request context. This should not happen in normal operation."
554
+ );
555
+ }
463
556
  function run(props) {
464
557
  const { port, ...rest } = props;
465
558
  createExpressServer(rest).listen(
@@ -481,7 +574,7 @@ function createExpressServer(props) {
481
574
  function createExpressRoutes({
482
575
  createAgent,
483
576
  basePath: _basePath,
484
- express: express2,
577
+ express,
485
578
  useAGUI: _useAGUI,
486
579
  aguiOptions
487
580
  }) {
@@ -491,32 +584,34 @@ function createExpressRoutes({
491
584
  if (useAGUI) {
492
585
  createAGUIRoute({
493
586
  basePath,
494
- express: express2,
587
+ express,
495
588
  createAgent,
496
589
  ...aguiOptions || {}
497
590
  });
498
591
  }
499
592
  const openaiServerAdapter = openai_exports.createServerAdapter(createAgent);
500
593
  const healthzServerAdapter = healthz_exports.serverAdapter;
501
- express2.use(`${basePath}send-message`, sendMessageServerAdapter);
502
- express2.use(`${basePath}healthz`, healthzServerAdapter);
503
- express2.use(`${basePath}chat/completions`, openaiServerAdapter);
504
- return express2;
594
+ express.use(`${basePath}send-message`, sendMessageServerAdapter);
595
+ express.use(`${basePath}healthz`, healthzServerAdapter);
596
+ express.use(`${basePath}chat/completions`, openaiServerAdapter);
597
+ return express;
505
598
  }
506
599
  var AGUIRpcHandlerPromise = null;
507
600
  function getAGUIRpcHandler({
508
601
  createAgent,
509
602
  runtimeOptions,
510
603
  basePath,
511
- endpointOptions
604
+ endpointOptions,
605
+ request
512
606
  }) {
513
607
  if (AGUIRpcHandlerPromise) return AGUIRpcHandlerPromise;
514
608
  AGUIRpcHandlerPromise = (async () => {
515
- const agent = (await createAgent()).agent;
516
- const aguiAgent = "toAGUIAgent" in agent ? agent.toAGUIAgent() : agent;
609
+ const { agent } = await createAgent({ request });
610
+ const templateAgent = "toAGUIAgent" in agent ? agent.toAGUIAgent() : agent;
611
+ templateAgent.clone = agentCloneFn;
517
612
  const runtime = new import_runtime.CopilotRuntime({
518
613
  agents: {
519
- default: aguiAgent
614
+ default: templateAgent
520
615
  },
521
616
  ...runtimeOptions || {}
522
617
  });
@@ -530,20 +625,32 @@ function getAGUIRpcHandler({
530
625
  return AGUIRpcHandlerPromise;
531
626
  }
532
627
  function createAGUIRoute({
533
- express: express2,
628
+ express,
534
629
  basePath,
535
630
  createAgent,
536
631
  runtimeOptions,
537
632
  endpointOptions
538
633
  }) {
539
- express2.post(`${basePath}agui`, async (req, res) => {
634
+ express.post(`${basePath}agui`, import_express.default.json(), async (req, res) => {
635
+ const webRequest = (0, import_server8.normalizeNodeRequest)(req, DefaultFetchAPI);
636
+ const { agent: rawAgent, cleanup } = await createAgent({
637
+ request: webRequest
638
+ });
639
+ const preparedAgent = "toAGUIAgent" in rawAgent ? rawAgent.toAGUIAgent() : rawAgent;
640
+ preparedAgent.clone = agentCloneFn;
540
641
  const rpcHandler = await getAGUIRpcHandler({
541
642
  createAgent,
542
643
  basePath,
543
644
  runtimeOptions,
544
- endpointOptions
645
+ endpointOptions,
646
+ request: webRequest
647
+ });
648
+ preparedAgentStorage.run(preparedAgent, () => {
649
+ rpcHandler(req, res);
545
650
  });
546
- rpcHandler(req, res);
651
+ if (cleanup) {
652
+ res.on("close", cleanup);
653
+ }
547
654
  });
548
655
  }
549
656
  function isCorsOptions(cors2) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/agent-server",
3
- "version": "0.0.9",
3
+ "version": "0.0.12",
4
4
  "main": "dist/index.js",
5
5
  "files": [
6
6
  "dist/",
@@ -14,13 +14,14 @@
14
14
  "@ag-ui/client": "0.0.42",
15
15
  "@copilotkit/runtime": "^1.50.1",
16
16
  "@repeaterjs/repeater": "^3.0.6",
17
+ "@whatwg-node/fetch": "^0.10.13",
17
18
  "@whatwg-node/server": "^0.10.12",
18
19
  "cors": "^2.8.5",
19
20
  "express": "^5.1.0",
20
21
  "openai": "6.3.0",
21
22
  "uuid": "^10.0.0",
22
23
  "zod": "^4.1.12",
23
- "@cloudbase/agent-shared": "^0.0.9"
24
+ "@cloudbase/agent-shared": "^0.0.12"
24
25
  },
25
26
  "devDependencies": {
26
27
  "@types/cors": "^2.8.19",