@agentuity/runtime 0.0.95 → 0.0.96
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/AGENTS.md +3 -1
- package/dist/_events.d.ts +64 -0
- package/dist/_events.d.ts.map +1 -0
- package/dist/_events.js +92 -0
- package/dist/_events.js.map +1 -0
- package/dist/_idle.d.ts +1 -1
- package/dist/_idle.d.ts.map +1 -1
- package/dist/_idle.js +2 -16
- package/dist/_idle.js.map +1 -1
- package/dist/_server.d.ts +30 -13
- package/dist/_server.d.ts.map +1 -1
- package/dist/_server.js +39 -572
- package/dist/_server.js.map +1 -1
- package/dist/_services.d.ts.map +1 -1
- package/dist/_services.js +4 -2
- package/dist/_services.js.map +1 -1
- package/dist/_standalone.d.ts.map +1 -1
- package/dist/_standalone.js +2 -1
- package/dist/_standalone.js.map +1 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +13 -17
- package/dist/agent.js.map +1 -1
- package/dist/app.d.ts +58 -171
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +119 -218
- package/dist/app.js.map +1 -1
- package/dist/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -3
- package/dist/index.js.map +1 -1
- package/dist/middleware.d.ts +29 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +200 -0
- package/dist/middleware.js.map +1 -0
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +5 -2
- package/dist/router.js.map +1 -1
- package/dist/services/local/vector.d.ts.map +1 -1
- package/dist/services/local/vector.js +3 -2
- package/dist/services/local/vector.js.map +1 -1
- package/dist/services/thread/local.d.ts +20 -0
- package/dist/services/thread/local.d.ts.map +1 -0
- package/dist/services/thread/local.js +76 -0
- package/dist/services/thread/local.js.map +1 -0
- package/dist/session.d.ts +60 -8
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +186 -54
- package/dist/session.js.map +1 -1
- package/dist/web.d.ts +8 -0
- package/dist/web.d.ts.map +1 -0
- package/dist/web.js +66 -0
- package/dist/web.js.map +1 -0
- package/dist/workbench.d.ts +2 -0
- package/dist/workbench.d.ts.map +1 -1
- package/dist/workbench.js +192 -39
- package/dist/workbench.js.map +1 -1
- package/package.json +10 -10
- package/src/_events.ts +142 -0
- package/src/_idle.ts +2 -18
- package/src/_server.ts +48 -681
- package/src/_services.ts +4 -2
- package/src/_standalone.ts +2 -1
- package/src/agent.ts +11 -14
- package/src/app.ts +164 -246
- package/src/index.ts +42 -4
- package/src/middleware.ts +252 -0
- package/src/router.ts +6 -2
- package/src/services/local/vector.ts +3 -2
- package/src/services/thread/local.ts +106 -0
- package/src/session.ts +238 -59
- package/src/web.ts +75 -0
- package/src/workbench.ts +226 -38
package/src/_services.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
JSONEvalRunEventProvider,
|
|
29
29
|
HTTPEvalRunEventProvider,
|
|
30
30
|
} from './services/evalrun';
|
|
31
|
+
import { LocalThreadProvider } from './services/thread/local';
|
|
31
32
|
import { injectTraceContextToHeaders } from './otel/http';
|
|
32
33
|
import { getTracer } from './_server';
|
|
33
34
|
import { populateAgentsRegistry } from './agent.js';
|
|
@@ -52,7 +53,8 @@ const userAgent = `Agentuity SDK/${getSDKVersion()}`;
|
|
|
52
53
|
const sdkKey = process.env.AGENTUITY_SDK_KEY;
|
|
53
54
|
const bearerKey = `Bearer ${sdkKey}`;
|
|
54
55
|
|
|
55
|
-
const
|
|
56
|
+
const region = process.env.AGENTUITY_REGION ?? 'usc';
|
|
57
|
+
const serviceUrls = getServiceUrls(region);
|
|
56
58
|
const kvBaseUrl = serviceUrls.keyvalue;
|
|
57
59
|
const streamBaseUrl = serviceUrls.stream;
|
|
58
60
|
const vectorBaseUrl = serviceUrls.vector;
|
|
@@ -200,7 +202,7 @@ export function createServices(logger: Logger, config?: AppConfig<any>, serverUr
|
|
|
200
202
|
stream = config?.services?.stream || new LocalStreamStorage(db, projectPath, serverUrl);
|
|
201
203
|
vector = config?.services?.vector || new LocalVectorStorage(db, projectPath);
|
|
202
204
|
session = config?.services?.session || new DefaultSessionProvider();
|
|
203
|
-
thread = config?.services?.thread || new
|
|
205
|
+
thread = config?.services?.thread || new LocalThreadProvider();
|
|
204
206
|
sessionEvent = config?.services?.sessionEvent
|
|
205
207
|
? new CompositeSessionEventProvider(
|
|
206
208
|
new LocalSessionEventProvider(),
|
package/src/_standalone.ts
CHANGED
|
@@ -9,7 +9,8 @@ import { generateId } from './session';
|
|
|
9
9
|
import WaitUntilHandler from './_waituntil';
|
|
10
10
|
import { registerServices } from './_services';
|
|
11
11
|
import { getAgentAsyncLocalStorage } from './_context';
|
|
12
|
-
import { getLogger, getTracer
|
|
12
|
+
import { getLogger, getTracer } from './_server';
|
|
13
|
+
import { getAppState } from './app';
|
|
13
14
|
import { getThreadProvider, getSessionProvider, getSessionEventProvider } from './_services';
|
|
14
15
|
import * as runtimeConfig from './_config';
|
|
15
16
|
|
package/src/agent.ts
CHANGED
|
@@ -19,14 +19,15 @@ import {
|
|
|
19
19
|
inHTTPContext,
|
|
20
20
|
getHTTPContext,
|
|
21
21
|
setupRequestAgentContext,
|
|
22
|
+
getAgentAsyncLocalStorage,
|
|
22
23
|
type RequestAgentContextArgs,
|
|
23
24
|
} from './_context';
|
|
24
25
|
import type { Logger } from './logger';
|
|
25
26
|
import type { Eval, EvalContext, EvalRunResult, EvalFunction } from './eval';
|
|
26
27
|
import { internal } from './logger/internal';
|
|
27
|
-
import {
|
|
28
|
+
import { fireEvent } from './_events';
|
|
28
29
|
import type { Thread, Session } from './session';
|
|
29
|
-
import { privateContext
|
|
30
|
+
import { privateContext } from './_server';
|
|
30
31
|
import { generateId } from './session';
|
|
31
32
|
import { getEvalRunEventProvider } from './_services';
|
|
32
33
|
import * as runtimeConfig from './_config';
|
|
@@ -1214,16 +1215,13 @@ async function fireAgentEvent(
|
|
|
1214
1215
|
}
|
|
1215
1216
|
}
|
|
1216
1217
|
|
|
1217
|
-
// Fire app-level
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
} else if (eventName === 'completed') {
|
|
1225
|
-
await app.fireEvent('agent.completed', agent, context);
|
|
1226
|
-
}
|
|
1218
|
+
// Fire global app-level events
|
|
1219
|
+
if (eventName === 'errored' && data) {
|
|
1220
|
+
await fireEvent('agent.errored', agent, context, data);
|
|
1221
|
+
} else if (eventName === 'started') {
|
|
1222
|
+
await fireEvent('agent.started', agent, context);
|
|
1223
|
+
} else if (eventName === 'completed') {
|
|
1224
|
+
await fireEvent('agent.completed', agent, context);
|
|
1227
1225
|
}
|
|
1228
1226
|
}
|
|
1229
1227
|
|
|
@@ -2284,7 +2282,7 @@ export const runAgentSetups = async (appState: AppState): Promise<void> => {
|
|
|
2284
2282
|
setAgentConfig(name as AgentName, config);
|
|
2285
2283
|
}
|
|
2286
2284
|
}
|
|
2287
|
-
|
|
2285
|
+
// Note: Server readiness is managed by Vite (dev) or Bun.serve (prod)
|
|
2288
2286
|
};
|
|
2289
2287
|
|
|
2290
2288
|
export const runAgentShutdowns = async (appState: AppState): Promise<void> => {
|
|
@@ -2346,7 +2344,6 @@ export async function runInAgentContext<TInput, TOutput>(
|
|
|
2346
2344
|
agent: AgentRunner<any, any, any>,
|
|
2347
2345
|
input?: TInput
|
|
2348
2346
|
): Promise<TOutput> {
|
|
2349
|
-
const { getAgentAsyncLocalStorage } = await import('./_context');
|
|
2350
2347
|
const storage = getAgentAsyncLocalStorage();
|
|
2351
2348
|
|
|
2352
2349
|
// Register agent in runtime state so events fire (lookup by metadata.name)
|
package/src/app.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
|
|
3
|
-
import { type Env as HonoEnv, Hono } from 'hono';
|
|
2
|
+
import { type Env as HonoEnv } from 'hono';
|
|
4
3
|
import type { cors } from 'hono/cors';
|
|
5
|
-
import type { BunWebSocketData } from 'hono/bun';
|
|
6
4
|
import type { Logger } from './logger';
|
|
7
|
-
import { createServer, getLogger } from './_server';
|
|
8
5
|
import type { Meter, Tracer } from '@opentelemetry/api';
|
|
9
|
-
import { internal } from './logger/internal';
|
|
10
6
|
import type {
|
|
11
7
|
KeyValueStorage,
|
|
12
8
|
SessionEventProvider,
|
|
@@ -16,7 +12,6 @@ import type {
|
|
|
16
12
|
SessionStartEvent,
|
|
17
13
|
} from '@agentuity/core';
|
|
18
14
|
import type { Email } from './io/email';
|
|
19
|
-
import type { Agent, AgentContext } from './agent';
|
|
20
15
|
import type { ThreadProvider, SessionProvider, Session, Thread } from './session';
|
|
21
16
|
import type WaitUntilHandler from './_waituntil';
|
|
22
17
|
|
|
@@ -113,235 +108,97 @@ export interface Env<TAppState = Record<string, never>> extends HonoEnv {
|
|
|
113
108
|
Variables: Variables<TAppState>;
|
|
114
109
|
}
|
|
115
110
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
];
|
|
124
|
-
'session.started': [Session];
|
|
125
|
-
'session.completed': [Session];
|
|
126
|
-
'thread.created': [Thread];
|
|
127
|
-
'thread.destroyed': [Thread];
|
|
128
|
-
};
|
|
111
|
+
/**
|
|
112
|
+
* Get the global app instance (stub for backwards compatibility)
|
|
113
|
+
* Returns null in Vite-native architecture
|
|
114
|
+
*/
|
|
115
|
+
export function getApp(): null {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
129
118
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
119
|
+
// Re-export event functions from _events
|
|
120
|
+
export { fireEvent } from './_events';
|
|
121
|
+
import {
|
|
122
|
+
addEventListener as globalAddEventListener,
|
|
123
|
+
removeEventListener as globalRemoveEventListener,
|
|
124
|
+
} from './_events';
|
|
125
|
+
import type { AppEventMap } from './_events';
|
|
126
|
+
import { getLogger, getRouter } from './_server';
|
|
127
|
+
import type { Hono } from 'hono';
|
|
128
|
+
|
|
129
|
+
// ============================================================================
|
|
130
|
+
// Vite-native createApp implementation
|
|
131
|
+
// ============================================================================
|
|
134
132
|
|
|
135
133
|
/**
|
|
136
|
-
*
|
|
137
|
-
* Provides access to the router, server, logger, and app state.
|
|
138
|
-
*
|
|
139
|
-
* @template TAppState - The type of application state returned from setup function
|
|
140
|
-
*
|
|
141
|
-
* @example
|
|
142
|
-
* ```typescript
|
|
143
|
-
* const app = await createApp({
|
|
144
|
-
* setup: async () => ({ db: await connectDB() })
|
|
145
|
-
* });
|
|
146
|
-
*
|
|
147
|
-
* // Access state
|
|
148
|
-
* console.log(app.state.db);
|
|
149
|
-
*
|
|
150
|
-
* // Add routes
|
|
151
|
-
* app.router.get('/health', (c) => c.text('OK'));
|
|
152
|
-
*
|
|
153
|
-
* // Listen to events
|
|
154
|
-
* app.addEventListener('agent.started', (eventName, agent, ctx) => {
|
|
155
|
-
* console.log(`Agent ${agent.metadata.name} started`);
|
|
156
|
-
* });
|
|
157
|
-
* ```
|
|
134
|
+
* Simple server interface for backwards compatibility
|
|
158
135
|
*/
|
|
159
|
-
export
|
|
136
|
+
export interface Server {
|
|
160
137
|
/**
|
|
161
|
-
* The
|
|
138
|
+
* The server URL (e.g., "http://localhost:3500")
|
|
162
139
|
*/
|
|
163
|
-
|
|
140
|
+
url: string;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export interface AppResult<TAppState = Record<string, never>> {
|
|
164
144
|
/**
|
|
165
|
-
* The
|
|
145
|
+
* The application state returned from setup
|
|
166
146
|
*/
|
|
167
|
-
|
|
147
|
+
state: TAppState;
|
|
168
148
|
/**
|
|
169
|
-
*
|
|
149
|
+
* Shutdown function to call when server stops
|
|
170
150
|
*/
|
|
171
|
-
|
|
151
|
+
shutdown?: (state: TAppState) => Promise<void> | void;
|
|
172
152
|
/**
|
|
173
|
-
*
|
|
174
|
-
* Available in all agents via ctx.app.
|
|
153
|
+
* App configuration (for middleware setup)
|
|
175
154
|
*/
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
private eventListeners = new Map<
|
|
179
|
-
keyof AppEventMap<TAppState>,
|
|
180
|
-
Set<AppEventCallback<any, TAppState>>
|
|
181
|
-
>();
|
|
182
|
-
|
|
183
|
-
constructor(
|
|
184
|
-
state: TAppState,
|
|
185
|
-
router: Hono<Env<TAppState>>,
|
|
186
|
-
server: Bun.Server<BunWebSocketData>
|
|
187
|
-
) {
|
|
188
|
-
this.state = state;
|
|
189
|
-
this.router = router;
|
|
190
|
-
this.server = server;
|
|
191
|
-
this.logger = getLogger() as Logger;
|
|
192
|
-
setGlobalApp(this);
|
|
193
|
-
}
|
|
194
|
-
|
|
155
|
+
config?: AppConfig<TAppState>;
|
|
195
156
|
/**
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
* Available events:
|
|
199
|
-
* - `agent.started` - Fired when an agent begins execution
|
|
200
|
-
* - `agent.completed` - Fired when an agent completes successfully
|
|
201
|
-
* - `agent.errored` - Fired when an agent throws an error
|
|
202
|
-
* - `session.started` - Fired when a new session starts
|
|
203
|
-
* - `session.completed` - Fired when a session completes
|
|
204
|
-
* - `thread.created` - Fired when a thread is created
|
|
205
|
-
* - `thread.destroyed` - Fired when a thread is destroyed
|
|
206
|
-
*
|
|
207
|
-
* @param eventName - The event name to listen for
|
|
208
|
-
* @param callback - The callback function to execute when the event fires
|
|
209
|
-
*
|
|
210
|
-
* @example
|
|
211
|
-
* ```typescript
|
|
212
|
-
* app.addEventListener('agent.started', (eventName, agent, ctx) => {
|
|
213
|
-
* console.log(`${agent.metadata.name} started for session ${ctx.sessionId}`);
|
|
214
|
-
* });
|
|
215
|
-
*
|
|
216
|
-
* app.addEventListener('agent.errored', (eventName, agent, ctx, error) => {
|
|
217
|
-
* console.error(`${agent.metadata.name} failed:`, error.message);
|
|
218
|
-
* });
|
|
219
|
-
*
|
|
220
|
-
* app.addEventListener('session.started', (eventName, session) => {
|
|
221
|
-
* console.log(`New session: ${session.id}`);
|
|
222
|
-
* });
|
|
223
|
-
* ```
|
|
157
|
+
* The router instance (for backwards compatibility)
|
|
224
158
|
*/
|
|
225
|
-
|
|
226
|
-
eventName: K,
|
|
227
|
-
callback: AppEventCallback<K, TAppState>
|
|
228
|
-
): void {
|
|
229
|
-
let callbacks = this.eventListeners.get(eventName);
|
|
230
|
-
if (!callbacks) {
|
|
231
|
-
callbacks = new Set();
|
|
232
|
-
this.eventListeners.set(eventName, callbacks);
|
|
233
|
-
}
|
|
234
|
-
callbacks.add(callback);
|
|
235
|
-
}
|
|
236
|
-
|
|
159
|
+
router: import('hono').Hono<Env<TAppState>>;
|
|
237
160
|
/**
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
* @param eventName - The event name to stop listening for
|
|
241
|
-
* @param callback - The callback function to remove
|
|
242
|
-
*
|
|
243
|
-
* @example
|
|
244
|
-
* ```typescript
|
|
245
|
-
* const handler = (eventName, agent, ctx) => {
|
|
246
|
-
* console.log('Agent started:', agent.metadata.name);
|
|
247
|
-
* };
|
|
248
|
-
*
|
|
249
|
-
* app.addEventListener('agent.started', handler);
|
|
250
|
-
* // Later...
|
|
251
|
-
* app.removeEventListener('agent.started', handler);
|
|
252
|
-
* ```
|
|
161
|
+
* Server information (for backwards compatibility)
|
|
253
162
|
*/
|
|
254
|
-
|
|
163
|
+
server: Server;
|
|
164
|
+
/**
|
|
165
|
+
* Logger instance (for backwards compatibility)
|
|
166
|
+
*/
|
|
167
|
+
logger: Logger;
|
|
168
|
+
/**
|
|
169
|
+
* Add an event listener for app events
|
|
170
|
+
*/
|
|
171
|
+
addEventListener<K extends keyof AppEventMap<TAppState>>(
|
|
255
172
|
eventName: K,
|
|
256
|
-
callback:
|
|
257
|
-
): void
|
|
258
|
-
const callbacks = this.eventListeners.get(eventName);
|
|
259
|
-
if (!callbacks) return;
|
|
260
|
-
callbacks.delete(callback);
|
|
261
|
-
}
|
|
262
|
-
|
|
173
|
+
callback: (eventName: K, ...args: AppEventMap<TAppState>[K]) => void | Promise<void>
|
|
174
|
+
): void;
|
|
263
175
|
/**
|
|
264
|
-
*
|
|
265
|
-
* Typically used internally by the runtime, but can be used for custom events.
|
|
266
|
-
*
|
|
267
|
-
* @param eventName - The event name to fire
|
|
268
|
-
* @param args - The arguments to pass to event listeners
|
|
269
|
-
*
|
|
270
|
-
* @example
|
|
271
|
-
* ```typescript
|
|
272
|
-
* // Fire a session completed event
|
|
273
|
-
* await app.fireEvent('session.completed', session);
|
|
274
|
-
* ```
|
|
176
|
+
* Remove an event listener for app events
|
|
275
177
|
*/
|
|
276
|
-
|
|
178
|
+
removeEventListener<K extends keyof AppEventMap<TAppState>>(
|
|
277
179
|
eventName: K,
|
|
278
|
-
...args: AppEventMap<TAppState>[K]
|
|
279
|
-
):
|
|
280
|
-
const callbacks = this.eventListeners.get(eventName);
|
|
281
|
-
if (!callbacks || callbacks.size === 0) return;
|
|
282
|
-
|
|
283
|
-
for (const callback of callbacks) {
|
|
284
|
-
try {
|
|
285
|
-
await callback(eventName, ...args);
|
|
286
|
-
} catch (error) {
|
|
287
|
-
// Log but don't re-throw - event listener errors should not crash the server
|
|
288
|
-
internal.error(`Error in app event listener for '${eventName}':`, error);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
let globalApp: App<any> | null = null;
|
|
295
|
-
|
|
296
|
-
function setGlobalApp(app: App<any>): void {
|
|
297
|
-
globalApp = app;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* Get the global app instance.
|
|
302
|
-
* Returns null if createApp() has not been called yet.
|
|
303
|
-
*
|
|
304
|
-
* @returns The global App instance or null
|
|
305
|
-
*
|
|
306
|
-
* @example
|
|
307
|
-
* ```typescript
|
|
308
|
-
* const app = getApp();
|
|
309
|
-
* if (app) {
|
|
310
|
-
* console.log('Server running on port:', app.server.port);
|
|
311
|
-
* }
|
|
312
|
-
* ```
|
|
313
|
-
*/
|
|
314
|
-
export function getApp(): App<any> | null {
|
|
315
|
-
return globalApp;
|
|
180
|
+
callback: (eventName: K, ...args: AppEventMap<TAppState>[K]) => void | Promise<void>
|
|
181
|
+
): void;
|
|
316
182
|
}
|
|
317
183
|
|
|
318
184
|
/**
|
|
319
|
-
*
|
|
185
|
+
* Create an Agentuity application with lifecycle management.
|
|
320
186
|
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
187
|
+
* In Vite-native architecture:
|
|
188
|
+
* - This only handles setup/shutdown lifecycle
|
|
189
|
+
* - Router creation and middleware are handled by the generated entry file
|
|
190
|
+
* - Server is managed by Vite (dev) or Bun.serve (prod)
|
|
325
191
|
*
|
|
326
|
-
* @template TAppState -
|
|
327
|
-
*
|
|
328
|
-
* @param config - Optional application configuration
|
|
329
|
-
* @param config.setup - Function to initialize app state, runs before server starts
|
|
330
|
-
* @param config.shutdown - Function to clean up resources when server stops
|
|
331
|
-
* @param config.cors - CORS configuration for HTTP routes
|
|
332
|
-
* @param config.services - Override default storage and service providers
|
|
333
|
-
*
|
|
334
|
-
* @returns Promise resolving to App instance with running server
|
|
192
|
+
* @template TAppState - Type of application state from setup()
|
|
335
193
|
*
|
|
336
194
|
* @example
|
|
337
195
|
* ```typescript
|
|
338
|
-
* //
|
|
339
|
-
*
|
|
196
|
+
* // app.ts
|
|
197
|
+
* import { createApp } from '@agentuity/runtime';
|
|
340
198
|
*
|
|
341
|
-
* // App with database connection
|
|
342
199
|
* const app = await createApp({
|
|
343
200
|
* setup: async () => {
|
|
344
|
-
* const db = await
|
|
201
|
+
* const db = await connectDB();
|
|
345
202
|
* return { db };
|
|
346
203
|
* },
|
|
347
204
|
* shutdown: async (state) => {
|
|
@@ -349,57 +206,118 @@ export function getApp(): App<any> | null {
|
|
|
349
206
|
* }
|
|
350
207
|
* });
|
|
351
208
|
*
|
|
352
|
-
* // Access state in agents
|
|
353
|
-
* const agent = createAgent('user-query', {
|
|
354
|
-
* handler: async (ctx, input) => {
|
|
355
|
-
* const db = ctx.app.db; // Strongly typed!
|
|
356
|
-
* return db.query('SELECT * FROM users');
|
|
357
|
-
* }
|
|
358
|
-
* });
|
|
359
|
-
*
|
|
360
|
-
* // App with custom services
|
|
361
|
-
* const app = await createApp({
|
|
362
|
-
* services: {
|
|
363
|
-
* useLocal: true, // Use local in-memory storage for development
|
|
364
|
-
* }
|
|
365
|
-
* });
|
|
209
|
+
* // Access state in agents via ctx.app.db
|
|
366
210
|
* ```
|
|
367
211
|
*/
|
|
368
212
|
export async function createApp<TAppState = Record<string, never>>(
|
|
369
213
|
config?: AppConfig<TAppState>
|
|
370
|
-
): Promise<
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
214
|
+
): Promise<AppResult<TAppState>> {
|
|
215
|
+
// Run setup to get app state
|
|
216
|
+
const state = config?.setup ? await config.setup() : ({} as TAppState);
|
|
217
|
+
|
|
218
|
+
// Store state and config globally for generated entry file to access
|
|
219
|
+
(globalThis as any).__AGENTUITY_APP_STATE__ = state;
|
|
220
|
+
(globalThis as any).__AGENTUITY_APP_CONFIG__ = config;
|
|
221
|
+
|
|
222
|
+
// Store shutdown function for cleanup
|
|
223
|
+
const shutdown = config?.shutdown;
|
|
224
|
+
if (shutdown) {
|
|
225
|
+
(globalThis as any).__AGENTUITY_SHUTDOWN__ = shutdown;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Return a logger proxy that lazily resolves to the global logger
|
|
229
|
+
// This is necessary because Vite bundling inlines and reorders module code,
|
|
230
|
+
// causing app.ts to execute before entry file sets the global logger.
|
|
231
|
+
// The proxy ensures logger works correctly when actually used (in handlers/callbacks).
|
|
232
|
+
const logger: Logger = {
|
|
233
|
+
trace: (...args) => {
|
|
234
|
+
const gl = getLogger();
|
|
235
|
+
if (gl) gl.trace(...args);
|
|
236
|
+
},
|
|
237
|
+
debug: (...args) => {
|
|
238
|
+
const gl = getLogger();
|
|
239
|
+
if (gl) gl.debug(...args);
|
|
240
|
+
},
|
|
241
|
+
info: (...args) => {
|
|
242
|
+
const gl = getLogger();
|
|
243
|
+
if (gl) gl.info(...args);
|
|
244
|
+
else console.log('[INFO]', ...args);
|
|
245
|
+
},
|
|
246
|
+
warn: (...args) => {
|
|
247
|
+
const gl = getLogger();
|
|
248
|
+
if (gl) gl.warn(...args);
|
|
249
|
+
else console.warn('[WARN]', ...args);
|
|
250
|
+
},
|
|
251
|
+
error: (...args) => {
|
|
252
|
+
const gl = getLogger();
|
|
253
|
+
if (gl) gl.error(...args);
|
|
254
|
+
else console.error('[ERROR]', ...args);
|
|
255
|
+
},
|
|
256
|
+
fatal: (...args): never => {
|
|
257
|
+
const gl = getLogger();
|
|
258
|
+
if (gl) return gl.fatal(...args);
|
|
259
|
+
// Fallback: log to console but let the real logger handle exit
|
|
260
|
+
console.error('[FATAL]', ...args);
|
|
261
|
+
throw new Error('Fatal error');
|
|
262
|
+
},
|
|
263
|
+
child: (bindings) => {
|
|
264
|
+
const gl = getLogger();
|
|
265
|
+
return gl ? gl.child(bindings) : logger;
|
|
266
|
+
},
|
|
378
267
|
};
|
|
379
268
|
|
|
380
|
-
|
|
381
|
-
const
|
|
269
|
+
// Create server info from environment
|
|
270
|
+
const port = process.env.PORT || '3500';
|
|
271
|
+
const server: Server = {
|
|
272
|
+
url: `http://127.0.0.1:${port}`,
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// Get router from global (set by entry file before app.ts import)
|
|
276
|
+
// In dev mode, router may not be available during bundling
|
|
277
|
+
const globalRouter = getRouter();
|
|
278
|
+
if (!globalRouter) {
|
|
279
|
+
throw new Error(
|
|
280
|
+
'Router is not available. Ensure router is initialized before calling createApp(). This typically happens during bundling or when the entry file has not properly set up the router.'
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
const router = globalRouter as Hono<Env<TAppState>>;
|
|
382
284
|
|
|
383
|
-
return
|
|
285
|
+
return {
|
|
286
|
+
state,
|
|
287
|
+
shutdown,
|
|
288
|
+
config,
|
|
289
|
+
router,
|
|
290
|
+
server,
|
|
291
|
+
logger,
|
|
292
|
+
addEventListener: globalAddEventListener,
|
|
293
|
+
removeEventListener: globalRemoveEventListener,
|
|
294
|
+
};
|
|
384
295
|
}
|
|
385
296
|
|
|
386
297
|
/**
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
*
|
|
396
|
-
*
|
|
397
|
-
* await fireEvent('agent.completed', agent, ctx);
|
|
398
|
-
* ```
|
|
298
|
+
* Get the global app state
|
|
299
|
+
* Used by generated entry file and middleware
|
|
300
|
+
*/
|
|
301
|
+
export function getAppState<TAppState = any>(): TAppState {
|
|
302
|
+
return (globalThis as any).__AGENTUITY_APP_STATE__ || ({} as TAppState);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Get the global app config
|
|
307
|
+
* Used by generated entry file for middleware setup
|
|
399
308
|
*/
|
|
400
|
-
export
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
309
|
+
export function getAppConfig<TAppState = any>(): AppConfig<TAppState> | undefined {
|
|
310
|
+
return (globalThis as any).__AGENTUITY_APP_CONFIG__;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Run the global shutdown function
|
|
315
|
+
* Called by generated entry file on cleanup
|
|
316
|
+
*/
|
|
317
|
+
export async function runShutdown(): Promise<void> {
|
|
318
|
+
const shutdown = (globalThis as any).__AGENTUITY_SHUTDOWN__;
|
|
319
|
+
if (shutdown) {
|
|
320
|
+
const state = getAppState();
|
|
321
|
+
await shutdown(state);
|
|
322
|
+
}
|
|
405
323
|
}
|
package/src/index.ts
CHANGED
|
@@ -25,7 +25,7 @@ export {
|
|
|
25
25
|
runInAgentContext,
|
|
26
26
|
} from './agent';
|
|
27
27
|
|
|
28
|
-
// app.ts exports
|
|
28
|
+
// app.ts exports (all app-related functionality)
|
|
29
29
|
export {
|
|
30
30
|
type WorkbenchInstance,
|
|
31
31
|
type AppConfig,
|
|
@@ -33,11 +33,26 @@ export {
|
|
|
33
33
|
type TriggerType,
|
|
34
34
|
type PrivateVariables,
|
|
35
35
|
type Env,
|
|
36
|
-
|
|
37
|
-
getApp,
|
|
36
|
+
type AppResult,
|
|
38
37
|
createApp,
|
|
38
|
+
getApp,
|
|
39
|
+
getAppState,
|
|
40
|
+
getAppConfig,
|
|
41
|
+
runShutdown,
|
|
39
42
|
fireEvent,
|
|
40
43
|
} from './app';
|
|
44
|
+
export { addEventListener, removeEventListener } from './_events';
|
|
45
|
+
|
|
46
|
+
// middleware.ts exports (Vite-native)
|
|
47
|
+
export { createBaseMiddleware, createCorsMiddleware, createOtelMiddleware } from './middleware';
|
|
48
|
+
|
|
49
|
+
// Internal exports needed by generated entry files
|
|
50
|
+
export { register } from './otel/config';
|
|
51
|
+
export { createServices } from './_services';
|
|
52
|
+
export { enableProcessExitProtection } from './_process-protection';
|
|
53
|
+
|
|
54
|
+
// Internal exports (not in main index, imported by CLI only)
|
|
55
|
+
export { internalExit } from './_process-protection';
|
|
41
56
|
|
|
42
57
|
// devmode.ts exports
|
|
43
58
|
export { registerDevModeRoutes } from './devmode';
|
|
@@ -74,6 +89,9 @@ export {
|
|
|
74
89
|
DefaultThread,
|
|
75
90
|
} from './session';
|
|
76
91
|
|
|
92
|
+
// services/thread/local exports
|
|
93
|
+
export { LocalThreadProvider } from './services/thread/local';
|
|
94
|
+
|
|
77
95
|
// workbench.ts exports
|
|
78
96
|
export {
|
|
79
97
|
createWorkbenchExecutionRoute,
|
|
@@ -82,6 +100,9 @@ export {
|
|
|
82
100
|
createWorkbenchWebsocketRoute,
|
|
83
101
|
} from './workbench';
|
|
84
102
|
|
|
103
|
+
// web.ts exports
|
|
104
|
+
export { createWebRouter } from './web';
|
|
105
|
+
|
|
85
106
|
// validator.ts exports
|
|
86
107
|
export { type RouteValidator, validator } from './validator';
|
|
87
108
|
|
|
@@ -89,7 +110,24 @@ export { type RouteValidator, validator } from './validator';
|
|
|
89
110
|
export type { Logger } from './logger';
|
|
90
111
|
|
|
91
112
|
// _server.ts exports
|
|
92
|
-
export {
|
|
113
|
+
export {
|
|
114
|
+
getRouter,
|
|
115
|
+
setGlobalRouter,
|
|
116
|
+
createLogger,
|
|
117
|
+
getLogger,
|
|
118
|
+
setGlobalLogger,
|
|
119
|
+
getTracer,
|
|
120
|
+
setGlobalTracer,
|
|
121
|
+
addSpanProcessor,
|
|
122
|
+
getSpanProcessors,
|
|
123
|
+
privateContext,
|
|
124
|
+
notifyReady,
|
|
125
|
+
getServer,
|
|
126
|
+
AGENT_CONTEXT_PROPERTIES,
|
|
127
|
+
} from './_server';
|
|
128
|
+
|
|
129
|
+
// _waituntil.ts exports
|
|
130
|
+
export { hasWaitUntilPending } from './_waituntil';
|
|
93
131
|
|
|
94
132
|
// _standalone.ts exports
|
|
95
133
|
export {
|