@agentuity/runtime 1.0.48 → 2.0.0-beta.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.
Files changed (104) hide show
  1. package/dist/_globals.d.ts +58 -0
  2. package/dist/_globals.d.ts.map +1 -0
  3. package/dist/_globals.js +71 -0
  4. package/dist/_globals.js.map +1 -0
  5. package/dist/_metadata.d.ts.map +1 -1
  6. package/dist/_metadata.js +14 -0
  7. package/dist/_metadata.js.map +1 -1
  8. package/dist/_process-protection.d.ts +2 -0
  9. package/dist/_process-protection.d.ts.map +1 -1
  10. package/dist/_process-protection.js +14 -23
  11. package/dist/_process-protection.js.map +1 -1
  12. package/dist/_server.d.ts +4 -0
  13. package/dist/_server.d.ts.map +1 -1
  14. package/dist/_server.js +4 -0
  15. package/dist/_server.js.map +1 -1
  16. package/dist/_services.d.ts +1 -1
  17. package/dist/_services.d.ts.map +1 -1
  18. package/dist/_services.js +5 -1
  19. package/dist/_services.js.map +1 -1
  20. package/dist/_standalone.d.ts.map +1 -1
  21. package/dist/_standalone.js +3 -9
  22. package/dist/_standalone.js.map +1 -1
  23. package/dist/agent.d.ts.map +1 -1
  24. package/dist/agent.js +1 -0
  25. package/dist/agent.js.map +1 -1
  26. package/dist/app.d.ts +149 -71
  27. package/dist/app.d.ts.map +1 -1
  28. package/dist/app.js +121 -156
  29. package/dist/app.js.map +1 -1
  30. package/dist/bootstrap.d.ts +44 -0
  31. package/dist/bootstrap.d.ts.map +1 -0
  32. package/dist/bootstrap.js +256 -0
  33. package/dist/bootstrap.js.map +1 -0
  34. package/dist/dev-patches/aisdk.d.ts.map +1 -1
  35. package/dist/dev-patches/aisdk.js +6 -8
  36. package/dist/dev-patches/aisdk.js.map +1 -1
  37. package/dist/dev-patches/gateway.d.ts.map +1 -1
  38. package/dist/dev-patches/gateway.js +7 -8
  39. package/dist/dev-patches/gateway.js.map +1 -1
  40. package/dist/handlers/_route-meta.d.ts +20 -0
  41. package/dist/handlers/_route-meta.d.ts.map +1 -0
  42. package/dist/handlers/_route-meta.js +25 -0
  43. package/dist/handlers/_route-meta.js.map +1 -0
  44. package/dist/handlers/cron.d.ts.map +1 -1
  45. package/dist/handlers/cron.js +3 -1
  46. package/dist/handlers/cron.js.map +1 -1
  47. package/dist/handlers/sse.d.ts +3 -3
  48. package/dist/handlers/sse.d.ts.map +1 -1
  49. package/dist/handlers/sse.js +4 -16
  50. package/dist/handlers/sse.js.map +1 -1
  51. package/dist/handlers/stream.d.ts.map +1 -1
  52. package/dist/handlers/stream.js +4 -12
  53. package/dist/handlers/stream.js.map +1 -1
  54. package/dist/handlers/websocket.d.ts +3 -1
  55. package/dist/handlers/websocket.d.ts.map +1 -1
  56. package/dist/handlers/websocket.js +6 -37
  57. package/dist/handlers/websocket.js.map +1 -1
  58. package/dist/index.d.ts +1 -1
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +1 -1
  61. package/dist/index.js.map +1 -1
  62. package/dist/middleware.d.ts +1 -8
  63. package/dist/middleware.d.ts.map +1 -1
  64. package/dist/middleware.js +29 -71
  65. package/dist/middleware.js.map +1 -1
  66. package/dist/otel/logger.d.ts.map +1 -1
  67. package/dist/otel/logger.js +4 -7
  68. package/dist/otel/logger.js.map +1 -1
  69. package/dist/otel/otel.d.ts +4 -1
  70. package/dist/otel/otel.d.ts.map +1 -1
  71. package/dist/otel/otel.js +13 -2
  72. package/dist/otel/otel.js.map +1 -1
  73. package/dist/router.d.ts +10 -62
  74. package/dist/router.d.ts.map +1 -1
  75. package/dist/router.js +9 -146
  76. package/dist/router.js.map +1 -1
  77. package/dist/workbench.d.ts +1 -1
  78. package/dist/workbench.d.ts.map +1 -1
  79. package/dist/workbench.js +120 -12
  80. package/dist/workbench.js.map +1 -1
  81. package/package.json +7 -7
  82. package/src/_globals.ts +92 -0
  83. package/src/_metadata.ts +14 -0
  84. package/src/_process-protection.ts +17 -28
  85. package/src/_server.ts +4 -0
  86. package/src/_services.ts +6 -2
  87. package/src/_standalone.ts +4 -9
  88. package/src/agent.ts +1 -0
  89. package/src/app.ts +294 -195
  90. package/src/bootstrap.ts +316 -0
  91. package/src/dev-patches/aisdk.ts +8 -11
  92. package/src/dev-patches/gateway.ts +9 -11
  93. package/src/globals.d.ts +28 -0
  94. package/src/handlers/_route-meta.ts +31 -0
  95. package/src/handlers/cron.ts +4 -1
  96. package/src/handlers/sse.ts +8 -19
  97. package/src/handlers/stream.ts +5 -12
  98. package/src/handlers/websocket.ts +11 -37
  99. package/src/index.ts +2 -3
  100. package/src/middleware.ts +40 -99
  101. package/src/otel/logger.ts +5 -8
  102. package/src/otel/otel.ts +14 -2
  103. package/src/router.ts +12 -216
  104. package/src/workbench.ts +135 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentuity/runtime",
3
- "version": "1.0.48",
3
+ "version": "2.0.0-beta.0",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Agentuity employees and contributors",
6
6
  "type": "module",
@@ -26,11 +26,11 @@
26
26
  "prepublishOnly": "bun run clean && bun run build"
27
27
  },
28
28
  "dependencies": {
29
- "@agentuity/auth": "1.0.48",
30
- "@agentuity/core": "1.0.48",
31
- "@agentuity/frontend": "1.0.48",
32
- "@agentuity/schema": "1.0.48",
33
- "@agentuity/server": "1.0.48",
29
+ "@agentuity/auth": "2.0.0-beta.0",
30
+ "@agentuity/core": "2.0.0-beta.0",
31
+ "@agentuity/frontend": "2.0.0-beta.0",
32
+ "@agentuity/schema": "2.0.0-beta.0",
33
+ "@agentuity/server": "2.0.0-beta.0",
34
34
  "@opentelemetry/api": "^1.9.0",
35
35
  "@opentelemetry/api-logs": "^0.207.0",
36
36
  "@opentelemetry/auto-instrumentations-node": "^0.66.0",
@@ -50,7 +50,7 @@
50
50
  "zod": "^4.3.5"
51
51
  },
52
52
  "devDependencies": {
53
- "@agentuity/test-utils": "1.0.48",
53
+ "@agentuity/test-utils": "2.0.0-beta.0",
54
54
  "@types/bun": "latest",
55
55
  "@types/react": "^19.2.2",
56
56
  "@types/react-dom": "^19.2.2",
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Type-safe accessors for Symbol.for() global state.
3
+ *
4
+ * These symbols survive bun --hot reloads because globalThis persists
5
+ * across module re-evaluations. Using Symbol.for() ensures the same
6
+ * symbol is returned regardless of which module instance creates it.
7
+ *
8
+ * Each symbol key maps to a specific type — this module centralises
9
+ * the definitions so call-sites don't need casts.
10
+ */
11
+
12
+ import type { OtelResponse } from './otel/otel';
13
+
14
+ /** Shutdown hook function type (duplicated here to avoid circular dep with app.ts) */
15
+ type ShutdownHook = () => Promise<void> | void;
16
+
17
+ // ── Symbol keys ──────────────────────────────────────────────
18
+
19
+ const keys = {
20
+ originalProcessExit: Symbol.for('@agentuity/runtime:original-process-exit'),
21
+ processExitProtected: Symbol.for('@agentuity/runtime:process-exit-protected'),
22
+ otelInstance: Symbol.for('@agentuity/runtime:otel-instance'),
23
+ originalConsole: Symbol.for('agentuity.originalConsole'),
24
+ serverStarted: Symbol.for('@agentuity/runtime:server-started'),
25
+ localServicesLogged: Symbol.for('@agentuity/runtime:local-services-logged'),
26
+ shutdownHooks: Symbol.for('@agentuity/runtime:shutdown-hooks'),
27
+ s3Patched: Symbol.for('agentuity.s3.patched'),
28
+ } as const;
29
+
30
+ export { keys };
31
+
32
+ // ── Typed getter / setter ────────────────────────────────────
33
+
34
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
+ const g = globalThis as any;
36
+
37
+ export function getGlobal<T>(key: symbol): T | undefined {
38
+ return g[key] as T | undefined;
39
+ }
40
+
41
+ export function setGlobal<T>(key: symbol, value: T): void {
42
+ g[key] = value;
43
+ }
44
+
45
+ // ── Convenience accessors for commonly used globals ──────────
46
+
47
+ export const otel = {
48
+ get: (): OtelResponse | undefined => getGlobal<OtelResponse>(keys.otelInstance),
49
+ set: (v: OtelResponse) => setGlobal(keys.otelInstance, v),
50
+ };
51
+
52
+ export const originalProcessExit = {
53
+ get: (): ((code?: number) => never) | undefined =>
54
+ getGlobal<(code?: number) => never>(keys.originalProcessExit),
55
+ set: (v: (code?: number) => never) => setGlobal(keys.originalProcessExit, v),
56
+ };
57
+
58
+ export const processExitProtected = {
59
+ get: (): boolean => getGlobal<boolean>(keys.processExitProtected) ?? false,
60
+ set: (v: boolean) => setGlobal(keys.processExitProtected, v),
61
+ };
62
+
63
+ export const originalConsole = {
64
+ get: (): Console | undefined => getGlobal<Console>(keys.originalConsole),
65
+ set: (v: Console) => setGlobal(keys.originalConsole, v),
66
+ };
67
+
68
+ export const serverStarted = {
69
+ get: (): boolean => getGlobal<boolean>(keys.serverStarted) ?? false,
70
+ set: (v: boolean) => setGlobal(keys.serverStarted, v),
71
+ };
72
+
73
+ export const localServicesLogged = {
74
+ get: (): boolean => getGlobal<boolean>(keys.localServicesLogged) ?? false,
75
+ set: (v: boolean) => setGlobal(keys.localServicesLogged, v),
76
+ };
77
+
78
+ export const shutdownHooks = {
79
+ get: (): ShutdownHook[] => {
80
+ let hooks = getGlobal<ShutdownHook[]>(keys.shutdownHooks);
81
+ if (!hooks) {
82
+ hooks = [];
83
+ setGlobal(keys.shutdownHooks, hooks);
84
+ }
85
+ return hooks;
86
+ },
87
+ };
88
+
89
+ export const s3Patched = {
90
+ get: (): boolean => getGlobal<boolean>(keys.s3Patched) ?? false,
91
+ set: (v: boolean) => setGlobal(keys.s3Patched, v),
92
+ };
package/src/_metadata.ts CHANGED
@@ -136,6 +136,13 @@ export function loadBuildMetadata(): BuildMetadata | undefined {
136
136
 
137
137
  if (!existsSync(metadataPath)) {
138
138
  internal.info('[metadata] agentuity.metadata.json not found at %s', metadataPath);
139
+ // In dev mode, don't cache "not found" — the dev server generates
140
+ // the metadata file after createApp() has already been called.
141
+ // Caching undefined would permanently prevent the workbench from
142
+ // finding agents once the file is later written.
143
+ if (process.env.NODE_ENV === 'development') {
144
+ return undefined;
145
+ }
139
146
  _metadataCache = undefined;
140
147
  return undefined;
141
148
  }
@@ -208,6 +215,13 @@ function ensureAgentMaps(): void {
208
215
  const metadata = loadBuildMetadata();
209
216
  if (!metadata?.agents) {
210
217
  internal.info(`[metadata] ensureAgentMaps: no metadata or no agents found`);
218
+ // In dev mode, don't cache empty maps — metadata file may appear later
219
+ if (process.env.NODE_ENV === 'development') {
220
+ _agentsByName = null;
221
+ _agentsByAgentId = null;
222
+ _evalsByAgentName = null;
223
+ _evalsByAgentId = null;
224
+ }
211
225
  return;
212
226
  }
213
227
 
@@ -3,26 +3,24 @@
3
3
  *
4
4
  * Prevents user code from calling process.exit() which would crash the server.
5
5
  * The runtime can still exit gracefully using the internal exit function.
6
+ *
7
+ * Uses _globals.ts Symbol.for() accessors to store state across hot reloads.
6
8
  */
7
9
 
8
10
  import { StructuredError } from '@agentuity/core';
11
+ import {
12
+ originalProcessExit as exitGlobal,
13
+ processExitProtected as protectedGlobal,
14
+ } from './_globals';
9
15
 
10
- // Store the original process.exit ONLY if not already stored.
11
- // This is critical for hot reload scenarios where this module may be re-imported
12
- // multiple times. We must capture the truly original process.exit, not a previously
13
- // wrapped version.
14
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
- const existingOriginalExit = (globalThis as any).__AGENTUITY_ORIGINAL_PROCESS_EXIT__;
16
- const originalExit: (code?: number) => never = existingOriginalExit ?? process.exit.bind(process);
17
- // Store it globally so subsequent imports get the same original
18
- if (!existingOriginalExit) {
19
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
- (globalThis as any).__AGENTUITY_ORIGINAL_PROCESS_EXIT__ = originalExit;
16
+ // Capture the original process.exit ONLY if not already stored.
17
+ // Critical for hot reload: we must capture the truly original, not a wrapped version.
18
+ const existingExit = exitGlobal.get();
19
+ const originalExit: (code?: number) => never = existingExit ?? process.exit.bind(process);
20
+ if (!existingExit) {
21
+ exitGlobal.set(originalExit);
21
22
  }
22
23
 
23
- // Flag to track if protection is enabled
24
- let protectionEnabled = false;
25
-
26
24
  const ProcessExitAttemptError = StructuredError(
27
25
  'ProcessExitAttemptError',
28
26
  'Calling process.exit() is not allowed in agent code. The server must remain running to handle requests.'
@@ -35,16 +33,11 @@ const ProcessExitAttemptError = StructuredError(
35
33
  * After calling this, user code calling process.exit() will throw an error.
36
34
  */
37
35
  export function enableProcessExitProtection(): void {
38
- if (protectionEnabled) {
36
+ if (protectedGlobal.get()) {
39
37
  return;
40
38
  }
41
-
42
- protectionEnabled = true;
39
+ protectedGlobal.set(true);
43
40
 
44
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
- (globalThis as any).AGENTUITY_PROCESS_EXIT = originalExit;
46
-
47
- // Replace process.exit with a function that throws
48
41
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
42
  (process as any).exit = (code?: number | string | null | undefined): never => {
50
43
  throw new ProcessExitAttemptError({ code });
@@ -55,14 +48,10 @@ export function enableProcessExitProtection(): void {
55
48
  * Disable protection (mainly for testing)
56
49
  */
57
50
  export function disableProcessExitProtection(): void {
58
- if (!protectionEnabled) {
51
+ if (!protectedGlobal.get()) {
59
52
  return;
60
53
  }
61
-
62
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
- (globalThis as any).AGENTUITY_PROCESS_EXIT = undefined;
64
-
65
- protectionEnabled = false;
54
+ protectedGlobal.set(false);
66
55
  process.exit = originalExit;
67
56
  }
68
57
 
@@ -78,5 +67,5 @@ export function internalExit(code?: number): never {
78
67
  * Check if protection is currently enabled
79
68
  */
80
69
  export function isProtectionEnabled(): boolean {
81
- return protectionEnabled;
70
+ return protectedGlobal.get();
82
71
  }
package/src/_server.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  /**
2
2
  * Minimal server globals for Vite-native architecture
3
3
  * The server is managed by Vite (dev) or Bun.serve in the generated entry file (prod)
4
+ *
5
+ * These module-level variables persist across bun --hot reloads (since this
6
+ * module is not re-evaluated unless it changes). createApp() updates them
7
+ * via setters on each reload.
4
8
  */
5
9
 
6
10
  import type { Logger } from './logger';
package/src/_services.ts CHANGED
@@ -43,6 +43,7 @@ import { getTracer } from './_server';
43
43
  import { populateAgentsRegistry } from './agent.js';
44
44
  import { getSDKVersion, isAuthenticated, isProduction } from './_config';
45
45
  import type { AppConfig } from './app';
46
+ import { localServicesLogged } from './_globals';
46
47
  import {
47
48
  DefaultSessionProvider,
48
49
  DefaultThreadProvider,
@@ -200,7 +201,7 @@ const ServerUrlMissingError = StructuredError(
200
201
  );
201
202
 
202
203
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
203
- export function createServices(logger: Logger, config?: AppConfig<any>, serverUrl?: string) {
204
+ export function createServices(logger: Logger, config?: AppConfig, serverUrl?: string) {
204
205
  const authenticated = isAuthenticated();
205
206
  const useLocal = config?.services?.useLocal ?? false;
206
207
  adapter = createFetchAdapter(logger);
@@ -217,7 +218,10 @@ export function createServices(logger: Logger, config?: AppConfig<any>, serverUr
217
218
  throw new ServerUrlMissingError();
218
219
  }
219
220
 
220
- logger.info('Using local services (development only)');
221
+ if (!localServicesLogged.get()) {
222
+ localServicesLogged.set(true);
223
+ logger.info('Using local services (development only)');
224
+ }
221
225
 
222
226
  kv = config?.services?.keyvalue || new LocalKeyValueStorage(db, projectPath);
223
227
  stream = config?.services?.stream || new LocalStreamStorage(db, projectPath, serverUrl);
@@ -26,7 +26,7 @@ import WaitUntilHandler from './_waituntil';
26
26
  import { registerServices, createServices } from './_services';
27
27
  import { getAgentAsyncLocalStorage } from './_context';
28
28
  import { getLogger, getTracer, setGlobalLogger, setGlobalTracer } from './_server';
29
- import { getAppState } from './app';
29
+
30
30
  import { getThreadProvider, getSessionProvider, getSessionEventProvider } from './_services';
31
31
  import * as runtimeConfig from './_config';
32
32
 
@@ -100,12 +100,7 @@ function initializeStandaloneRuntime(): void {
100
100
  setGlobalLogger(logger);
101
101
  setGlobalTracer(tracer);
102
102
 
103
- // Set minimal app state if not already set
104
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
- if (!(globalThis as any).__AGENTUITY_APP_STATE__) {
106
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
107
- (globalThis as any).__AGENTUITY_APP_STATE__ = {};
108
- }
103
+ // App state is already initialized as {} in _server.ts module-level var
109
104
 
110
105
  // Initialize services (will use local services since not authenticated)
111
106
  const serverUrl = `http://127.0.0.1:${process.env.PORT || '3500'}`;
@@ -226,7 +221,7 @@ export class StandaloneAgentContext<
226
221
  // Auto-initialize if not inside agent runtime and globals are not set
227
222
  let logger = getLogger();
228
223
  let tracer = getTracer();
229
- let app = getAppState();
224
+ let app = {} as Record<string, unknown>;
230
225
 
231
226
  if (!logger || !tracer) {
232
227
  // Check if we're inside the agent runtime (dev server or cloud)
@@ -244,7 +239,7 @@ export class StandaloneAgentContext<
244
239
  // Re-fetch globals after initialization
245
240
  logger = getLogger()!;
246
241
  tracer = getTracer()!;
247
- app = getAppState();
242
+ app = {};
248
243
  }
249
244
 
250
245
  this.logger = logger;
package/src/agent.ts CHANGED
@@ -2382,6 +2382,7 @@ export function createAgent<
2382
2382
  inputSchema: inputSchema as TInput,
2383
2383
  outputSchema: outputSchema as TOutput,
2384
2384
  stream: (config.schema?.stream as TStream) || (false as TStream),
2385
+ evals: agent.evals,
2385
2386
  createEval,
2386
2387
  addEventListener: agent.addEventListener,
2387
2388
  removeEventListener: agent.removeEventListener,