@rcrsr/rill-agent-foundry 0.18.4

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 (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -0
  3. package/dist/conversations.d.ts +23 -0
  4. package/dist/conversations.d.ts.map +1 -0
  5. package/dist/conversations.js +91 -0
  6. package/dist/conversations.js.map +1 -0
  7. package/dist/errors.d.ts +26 -0
  8. package/dist/errors.d.ts.map +1 -0
  9. package/dist/errors.js +40 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/extract.d.ts +19 -0
  12. package/dist/extract.d.ts.map +1 -0
  13. package/dist/extract.js +109 -0
  14. package/dist/extract.js.map +1 -0
  15. package/dist/harness.d.ts +21 -0
  16. package/dist/harness.d.ts.map +1 -0
  17. package/dist/harness.js +481 -0
  18. package/dist/harness.js.map +1 -0
  19. package/dist/id.d.ts +26 -0
  20. package/dist/id.d.ts.map +1 -0
  21. package/dist/id.js +83 -0
  22. package/dist/id.js.map +1 -0
  23. package/dist/index.d.ts +17 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +22 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/response.d.ts +25 -0
  28. package/dist/response.d.ts.map +1 -0
  29. package/dist/response.js +154 -0
  30. package/dist/response.js.map +1 -0
  31. package/dist/session.d.ts +24 -0
  32. package/dist/session.d.ts.map +1 -0
  33. package/dist/session.js +34 -0
  34. package/dist/session.js.map +1 -0
  35. package/dist/stream.d.ts +47 -0
  36. package/dist/stream.d.ts.map +1 -0
  37. package/dist/stream.js +189 -0
  38. package/dist/stream.js.map +1 -0
  39. package/dist/telemetry.d.ts +21 -0
  40. package/dist/telemetry.d.ts.map +1 -0
  41. package/dist/telemetry.js +53 -0
  42. package/dist/telemetry.js.map +1 -0
  43. package/dist/types.d.ts +161 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +5 -0
  46. package/dist/types.js.map +1 -0
  47. package/package.json +56 -0
@@ -0,0 +1,481 @@
1
+ import { Hono } from 'hono';
2
+ import { serve } from '@hono/node-server';
3
+ import { SpanStatusCode } from '@opentelemetry/api';
4
+ import { DefaultAzureCredential } from '@azure/identity';
5
+ import { CapacityError, CredentialError, InputError } from './errors.js';
6
+ import { extractInput } from './extract.js';
7
+ import { createIdGenerator, generateId } from './id.js';
8
+ import { buildErrorResponse, buildSyncResponse } from './response.js';
9
+ import { createSessionManager } from './session.js';
10
+ import { createFoundryStreamResponse } from './stream.js';
11
+ import { createConversationsClient, PersistenceError, } from './conversations.js';
12
+ import { getTracer, initTelemetry, shutdownTelemetry } from './telemetry.js';
13
+ // ============================================================
14
+ // PARAM VALIDATION
15
+ // ============================================================
16
+ /**
17
+ * Validate extracted params against the handler description for a named agent.
18
+ * Returns a string describing the first violation, or null when valid.
19
+ * Returns null when describe() returns null (no description available).
20
+ */
21
+ function validateParams(params, agentName, router) {
22
+ const desc = router.describe(agentName);
23
+ if (desc === null)
24
+ return null;
25
+ for (const param of desc.params) {
26
+ const value = params[param.name];
27
+ if (param.required && (value === undefined || value === null)) {
28
+ return `Missing required parameter: ${param.name}`;
29
+ }
30
+ if (value !== undefined && value !== null && param.type !== 'any') {
31
+ const actual = typeof value;
32
+ const expected = param.type === 'dict' ? 'object' : param.type;
33
+ if (expected === 'list') {
34
+ if (!Array.isArray(value)) {
35
+ return `Parameter "${param.name}" must be a list, got ${actual}`;
36
+ }
37
+ }
38
+ else if (expected === 'object') {
39
+ if (actual !== 'object' || value === null || Array.isArray(value)) {
40
+ return `Parameter "${param.name}" must be a dict, got ${Array.isArray(value) ? 'list' : actual}`;
41
+ }
42
+ }
43
+ else if (actual !== expected) {
44
+ return `Parameter "${param.name}" must be ${param.type}, got ${actual}`;
45
+ }
46
+ }
47
+ }
48
+ return null;
49
+ }
50
+ // ============================================================
51
+ // DEFAULTS
52
+ // ============================================================
53
+ const DEFAULT_PORT = 8088;
54
+ // ============================================================
55
+ // HELPERS
56
+ // ============================================================
57
+ /**
58
+ * Resolve the port from options or DEFAULT_AD_PORT env var.
59
+ * Throws when the env var value is non-numeric.
60
+ */
61
+ function resolvePort(options) {
62
+ if (options?.port !== undefined) {
63
+ if (!Number.isFinite(options.port)) {
64
+ throw new Error(`Invalid port: "${options.port}"`);
65
+ }
66
+ return options.port;
67
+ }
68
+ const envVal = process.env['DEFAULT_AD_PORT'];
69
+ if (envVal === undefined) {
70
+ return DEFAULT_PORT;
71
+ }
72
+ const parsed = Number(envVal);
73
+ if (!Number.isFinite(parsed) || envVal.trim() === '') {
74
+ throw new Error(`Invalid port: "${envVal}"`);
75
+ }
76
+ return parsed;
77
+ }
78
+ /**
79
+ * Resolve the conversationId from the request body field.
80
+ * Accepts string or {id: string} object.
81
+ */
82
+ function resolveConversationId(conversation) {
83
+ if (conversation === undefined) {
84
+ return undefined;
85
+ }
86
+ if (typeof conversation === 'string') {
87
+ return conversation;
88
+ }
89
+ return conversation.id;
90
+ }
91
+ // ============================================================
92
+ // FACTORY
93
+ // ============================================================
94
+ /**
95
+ * Create a Foundry harness wrapping an AgentRouter.
96
+ *
97
+ * Routes:
98
+ * POST /responses — main Foundry Responses endpoint
99
+ * POST /runs — alias for /responses
100
+ * GET /readiness — 503 before init, 200 after
101
+ * GET /liveness — always 200
102
+ * GET /metrics — FoundryMetrics JSON
103
+ */
104
+ export function createFoundryHarness(router, options) {
105
+ const port = resolvePort(options);
106
+ const debugErrors = options?.debugErrors ??
107
+ process.env['FOUNDRY_AGENT_DEBUG_ERRORS'] === 'true';
108
+ const forceSync = options?.forceSync ?? process.env['FOUNDRY_AGENT_FORCE_SYNC'] === 'true';
109
+ const agentName = options?.agentName ?? process.env['FOUNDRY_AGENT_NAME'];
110
+ const agentVersion = options?.agentVersion ?? process.env['FOUNDRY_AGENT_VERSION'];
111
+ initTelemetry({
112
+ agentName: agentName ?? router.defaultAgent(),
113
+ agentVersion,
114
+ });
115
+ const sessions = createSessionManager();
116
+ const projectEndpoint = process.env['FOUNDRY_PROJECT_ENDPOINT'];
117
+ const azureCredential = projectEndpoint !== undefined ? new DefaultAzureCredential() : undefined;
118
+ const conversationsClient = projectEndpoint !== undefined && azureCredential !== undefined
119
+ ? createConversationsClient(projectEndpoint, azureCredential)
120
+ : undefined;
121
+ let totalRequests = 0;
122
+ let errorCount = 0;
123
+ let server;
124
+ let ready = false;
125
+ const app = new Hono();
126
+ // ============================================================
127
+ // MIDDLEWARE — agent metadata header
128
+ // ============================================================
129
+ const metadataHeader = JSON.stringify({
130
+ package: {
131
+ name: 'azure-ai-agentserver-core',
132
+ version: '1.0.0b17',
133
+ },
134
+ runtime: {
135
+ python_version: '3.11.0',
136
+ platform: 'Linux',
137
+ host_name: '',
138
+ replica_name: '',
139
+ },
140
+ });
141
+ app.use('*', async (c, next) => {
142
+ await next();
143
+ c.res.headers.set('x-aml-foundry-agents-metadata', metadataHeader);
144
+ });
145
+ // ============================================================
146
+ // PROBE ROUTES
147
+ // ============================================================
148
+ app.get('/liveness', (c) => {
149
+ totalRequests++;
150
+ return c.json({ status: 'ok' }, 200);
151
+ });
152
+ app.get('/readiness', (c) => {
153
+ totalRequests++;
154
+ if (!ready) {
155
+ errorCount++;
156
+ return c.json({ status: 'initializing' }, 503);
157
+ }
158
+ return c.json({ status: 'ready' }, 200);
159
+ });
160
+ app.get('/metrics', (c) => {
161
+ totalRequests++;
162
+ return c.json({
163
+ activeSessions: sessions.activeCount(),
164
+ totalRequests,
165
+ errorCount,
166
+ });
167
+ });
168
+ // ============================================================
169
+ // RESPONSE HANDLER
170
+ // ============================================================
171
+ async function handleResponseRequest(c) {
172
+ totalRequests++;
173
+ // Parse body
174
+ let body;
175
+ try {
176
+ const parsed = await c.req.json();
177
+ if (parsed === null ||
178
+ typeof parsed !== 'object' ||
179
+ Array.isArray(parsed)) {
180
+ errorCount++;
181
+ return c.json(buildErrorResponse('INVALID_REQUEST', 'Request body must be a JSON object', debugErrors), 400);
182
+ }
183
+ body = parsed;
184
+ }
185
+ catch {
186
+ errorCount++;
187
+ return c.json(buildErrorResponse('INVALID_REQUEST', 'Invalid JSON in request body', debugErrors), 400);
188
+ }
189
+ // Extract input
190
+ let extracted;
191
+ try {
192
+ extracted = extractInput(body.input);
193
+ }
194
+ catch (err) {
195
+ errorCount++;
196
+ if (err instanceof InputError) {
197
+ return c.json(buildErrorResponse('INVALID_REQUEST', err.message, debugErrors), 400);
198
+ }
199
+ return c.json(buildErrorResponse('SERVER_ERROR', err instanceof Error ? err.message : String(err), debugErrors), 500);
200
+ }
201
+ // Resolve conversation ID
202
+ const conversationId = resolveConversationId(body.conversation);
203
+ // Resolve agent name early so validation can use it
204
+ const agentName_ = extracted.targetAgent ?? router.defaultAgent();
205
+ // Validate params against handler description.
206
+ const validationError = validateParams(extracted.params, agentName_, router);
207
+ if (validationError !== null) {
208
+ errorCount++;
209
+ return c.json(buildErrorResponse('INVALID_REQUEST', validationError, debugErrors), 400);
210
+ }
211
+ // Acquire session
212
+ let sessionId;
213
+ try {
214
+ sessionId = sessions.acquire(conversationId);
215
+ }
216
+ catch (err) {
217
+ errorCount++;
218
+ if (err instanceof CapacityError) {
219
+ return c.json(buildErrorResponse('RATE_LIMITED', err.message, debugErrors), 429);
220
+ }
221
+ return c.json(buildErrorResponse('SERVER_ERROR', err instanceof Error ? err.message : String(err), debugErrors), 500);
222
+ }
223
+ // Use response_id from request metadata (assigned by Foundry gateway)
224
+ // or generate one for direct/test callers.
225
+ const idGen = createIdGenerator(body.metadata?.['response_id'], conversationId);
226
+ const responseId = idGen.responseId;
227
+ // Session and invocation IDs for sidecar stream correlation.
228
+ const invocationId = c.req.header('x-agent-invocation-id') ?? generateId('inv_');
229
+ const agentSessionId = c.req.query('session') ?? c.req.header('x-agent-session-id') ?? sessionId;
230
+ // Build session vars from headers + body fields.
231
+ const sessionVars = {};
232
+ const oid = c.req.header('x-aml-oid');
233
+ if (oid !== undefined)
234
+ sessionVars['AZURE_OID'] = oid;
235
+ const tid = c.req.header('x-aml-tid');
236
+ if (tid !== undefined)
237
+ sessionVars['AZURE_TID'] = tid;
238
+ if (typeof body.user === 'string')
239
+ sessionVars['FOUNDRY_USER'] = body.user;
240
+ if (typeof body.model === 'string')
241
+ sessionVars['FOUNDRY_MODEL'] = body.model;
242
+ if (typeof body.temperature === 'number')
243
+ sessionVars['FOUNDRY_TEMPERATURE'] = String(body.temperature);
244
+ const runContext = {
245
+ sessionVars,
246
+ };
247
+ const runRequest = {
248
+ params: extracted.params,
249
+ };
250
+ // Streaming path.
251
+ if (body.stream === true && !forceSync) {
252
+ const tracer = getTracer();
253
+ const span = tracer.startSpan('foundry.agent.run', {
254
+ attributes: {
255
+ 'foundry.agent.name': agentName_,
256
+ 'foundry.response_id': responseId,
257
+ 'foundry.stream': true,
258
+ },
259
+ });
260
+ // Build a push-based async iterable: the handler calls onChunk
261
+ // for each stream chunk, which pushes into a buffer consumed by
262
+ // the SSE writer.
263
+ let pushChunk;
264
+ let endChunks;
265
+ let failChunks;
266
+ const chunkBuffer = [];
267
+ let done = false;
268
+ let waiting;
269
+ pushChunk = (chunk) => {
270
+ if (waiting !== undefined) {
271
+ const resolve = waiting;
272
+ waiting = undefined;
273
+ resolve({ value: chunk, done: false });
274
+ }
275
+ else {
276
+ chunkBuffer.push(chunk);
277
+ }
278
+ };
279
+ endChunks = () => {
280
+ done = true;
281
+ if (waiting !== undefined) {
282
+ const resolve = waiting;
283
+ waiting = undefined;
284
+ resolve({ value: undefined, done: true });
285
+ }
286
+ };
287
+ let pendingError;
288
+ let rejectWaiting;
289
+ failChunks = (err) => {
290
+ pendingError = err;
291
+ done = true;
292
+ if (rejectWaiting !== undefined) {
293
+ const reject = rejectWaiting;
294
+ rejectWaiting = undefined;
295
+ waiting = undefined;
296
+ reject(err);
297
+ }
298
+ };
299
+ const chunks = {
300
+ [Symbol.asyncIterator]() {
301
+ return {
302
+ next() {
303
+ if (chunkBuffer.length > 0) {
304
+ return Promise.resolve({
305
+ value: chunkBuffer.shift(),
306
+ done: false,
307
+ });
308
+ }
309
+ if (done) {
310
+ if (pendingError !== undefined) {
311
+ return Promise.reject(pendingError);
312
+ }
313
+ return Promise.resolve({
314
+ value: undefined,
315
+ done: true,
316
+ });
317
+ }
318
+ return new Promise((resolve, reject) => {
319
+ waiting = resolve;
320
+ rejectWaiting = reject;
321
+ });
322
+ },
323
+ };
324
+ },
325
+ };
326
+ // The onChunk callback converts handler chunks to strings and
327
+ // pushes them into the async iterable consumed by the SSE stream.
328
+ const onChunk = async (chunk) => {
329
+ const text = typeof chunk === 'string' ? chunk : JSON.stringify(chunk);
330
+ pushChunk(text);
331
+ };
332
+ const streamContext = { ...runContext, onChunk };
333
+ // Start the agent run. When it completes (or errors), signal the
334
+ // chunk iterable so the SSE stream can finalize.
335
+ router
336
+ .run(agentName_, runRequest, streamContext)
337
+ .then((result) => {
338
+ span.setAttribute('foundry.agent.state', result.state);
339
+ span.end();
340
+ sessions.release(sessionId);
341
+ // If the handler did not stream (no onChunk support), emit
342
+ // the flat result as a single chunk.
343
+ if (!result.streamed) {
344
+ if (result.result !== null && result.result !== undefined) {
345
+ const text = typeof result.result === 'string'
346
+ ? result.result
347
+ : JSON.stringify(result.result);
348
+ if (text !== '')
349
+ pushChunk(text);
350
+ }
351
+ }
352
+ endChunks();
353
+ })
354
+ .catch((err) => {
355
+ span.setStatus({
356
+ code: SpanStatusCode.ERROR,
357
+ message: err instanceof Error ? err.message : String(err),
358
+ });
359
+ span.end();
360
+ sessions.release(sessionId);
361
+ failChunks(err);
362
+ });
363
+ return createFoundryStreamResponse(responseId, {
364
+ chunks,
365
+ idGenerator: idGen,
366
+ onError: (_err) => {
367
+ errorCount++;
368
+ },
369
+ sessionId: agentSessionId,
370
+ invocationId,
371
+ metadataHeader,
372
+ debugErrors,
373
+ });
374
+ }
375
+ // Synchronous path
376
+ try {
377
+ let result;
378
+ const tracer = getTracer();
379
+ const span = tracer.startSpan('foundry.agent.run', {
380
+ attributes: {
381
+ 'foundry.agent.name': agentName_,
382
+ 'foundry.response_id': responseId,
383
+ 'foundry.stream': false,
384
+ },
385
+ });
386
+ try {
387
+ result = await router.run(agentName_, runRequest, runContext);
388
+ span.setAttribute('foundry.agent.state', result.state);
389
+ }
390
+ catch (err) {
391
+ span.setStatus({
392
+ code: SpanStatusCode.ERROR,
393
+ message: err instanceof Error ? err.message : String(err),
394
+ });
395
+ span.end();
396
+ errorCount++;
397
+ const msg = err instanceof Error ? err.message : String(err);
398
+ if (msg.includes('not found')) {
399
+ return c.json(buildErrorResponse('NOT_FOUND', msg, debugErrors), 404);
400
+ }
401
+ return c.json(buildErrorResponse('SERVER_ERROR', msg, debugErrors), 500);
402
+ }
403
+ span.end();
404
+ const response = buildSyncResponse(result, responseId);
405
+ // Conversations persistence.
406
+ const shouldStore = body.store === true;
407
+ if (shouldStore &&
408
+ conversationId !== undefined &&
409
+ conversationsClient !== undefined) {
410
+ try {
411
+ await conversationsClient.saveItems(conversationId, response.output);
412
+ }
413
+ catch (err) {
414
+ errorCount++;
415
+ if (err instanceof PersistenceError) {
416
+ return c.json(buildErrorResponse('SERVER_ERROR', err.message, debugErrors), 502);
417
+ }
418
+ return c.json(buildErrorResponse('SERVER_ERROR', err instanceof Error ? err.message : String(err), debugErrors), 502);
419
+ }
420
+ }
421
+ if (result.state === 'error') {
422
+ errorCount++;
423
+ }
424
+ return c.json(response, 200);
425
+ }
426
+ finally {
427
+ sessions.release(sessionId);
428
+ }
429
+ }
430
+ app.post('/responses', (c) => handleResponseRequest(c));
431
+ app.post('/runs', (c) => handleResponseRequest(c));
432
+ // Mark router as ready after routes are registered
433
+ ready = true;
434
+ // ============================================================
435
+ // LIFECYCLE
436
+ // ============================================================
437
+ async function listen() {
438
+ if (azureCredential !== undefined) {
439
+ try {
440
+ const token = await azureCredential.getToken('https://ai.azure.com/.default');
441
+ if (token === null) {
442
+ throw new CredentialError('Failed to acquire token for scope https://ai.azure.com/.default');
443
+ }
444
+ }
445
+ catch (err) {
446
+ if (!(err instanceof CredentialError)) {
447
+ const message = err instanceof Error ? err.message : String(err);
448
+ throw new CredentialError(message);
449
+ }
450
+ process.exit(1);
451
+ }
452
+ }
453
+ return new Promise((resolve) => {
454
+ server = serve({ fetch: app.fetch, port }, () => {
455
+ resolve();
456
+ });
457
+ // Disable server timeouts for long-running SSE streams.
458
+ const srv = server;
459
+ srv['requestTimeout'] = 0;
460
+ srv['headersTimeout'] = 0;
461
+ srv['keepAliveTimeout'] = 0;
462
+ srv['timeout'] = 0;
463
+ });
464
+ }
465
+ async function close() {
466
+ if (server !== undefined) {
467
+ server.close();
468
+ server = undefined;
469
+ }
470
+ await shutdownTelemetry();
471
+ }
472
+ function metrics() {
473
+ return {
474
+ activeSessions: sessions.activeCount(),
475
+ totalRequests,
476
+ errorCount,
477
+ };
478
+ }
479
+ return { listen, close, app, metrics };
480
+ }
481
+ //# sourceMappingURL=harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.js","sourceRoot":"","sources":["../src/harness.ts"],"names":[],"mappings":"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"}
package/dist/id.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ export interface IdGenerator {
2
+ readonly responseId: string;
3
+ generateMessageId(): string;
4
+ generateFunctionCallId(): string;
5
+ generateFunctionOutputId(): string;
6
+ }
7
+ /**
8
+ * Create an IdGenerator scoped to a single request.
9
+ *
10
+ * Partition key extraction priority:
11
+ * 1. conversationId (preferred for conversation-scoped routing)
12
+ * 2. responseId (fallback for response-scoped routing)
13
+ * 3. random 18-char key when neither has a valid format
14
+ *
15
+ * If responseId is not provided, one is generated with prefix `resp`.
16
+ */
17
+ export declare function createIdGenerator(responseId?: string | undefined, conversationId?: string | undefined): IdGenerator;
18
+ /**
19
+ * Generate a prefixed random ID using crypto-secure entropy.
20
+ * Format: {prefix}{32 alphanumeric chars}
21
+ *
22
+ * Kept for backward compatibility with callers that do not need
23
+ * partition-key correlation.
24
+ */
25
+ export declare function generateId(prefix: string): string;
26
+ //# sourceMappingURL=id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,iBAAiB,IAAI,MAAM,CAAC;IAC5B,sBAAsB,IAAI,MAAM,CAAC;IACjC,wBAAwB,IAAI,MAAM,CAAC;CACpC;AAkDD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,EAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,GAClC,WAAW,CAgBb;AAMD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD"}
package/dist/id.js ADDED
@@ -0,0 +1,83 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ // ============================================================
3
+ // HELPERS
4
+ // ============================================================
5
+ const PARTITION_KEY_LENGTH = 18;
6
+ const ENTROPY_LENGTH = 32;
7
+ /**
8
+ * Generate entropy of the given length using crypto-secure random bytes.
9
+ * Base64-encodes the bytes and filters to alphanumeric only [A-Za-z0-9].
10
+ * Retries until enough characters are collected.
11
+ */
12
+ function generateEntropy(length) {
13
+ let result = '';
14
+ while (result.length < length) {
15
+ const bytes = randomBytes(Math.ceil(length * 1.5));
16
+ result += bytes.toString('base64').replace(/[^A-Za-z0-9]/g, '');
17
+ }
18
+ return result.slice(0, length);
19
+ }
20
+ /**
21
+ * Extract an 18-character partition key from a prefixed ID string.
22
+ * The partition key is taken from the first 18 characters of the segment
23
+ * after the first underscore. Returns null when the ID lacks the expected
24
+ * format (no underscore or insufficient characters after it).
25
+ */
26
+ function extractPartitionKey(id) {
27
+ const underscoreIdx = id.indexOf('_');
28
+ if (underscoreIdx === -1)
29
+ return null;
30
+ const segment = id.slice(underscoreIdx + 1);
31
+ if (segment.length < PARTITION_KEY_LENGTH)
32
+ return null;
33
+ return segment.slice(0, PARTITION_KEY_LENGTH);
34
+ }
35
+ /**
36
+ * Produce a compliant Foundry ID.
37
+ * Format: {prefix}_{partitionKey}{entropy}
38
+ */
39
+ function buildId(prefix, partitionKey) {
40
+ const entropy = generateEntropy(ENTROPY_LENGTH);
41
+ return `${prefix}_${partitionKey}${entropy}`;
42
+ }
43
+ // ============================================================
44
+ // FACTORY
45
+ // ============================================================
46
+ /**
47
+ * Create an IdGenerator scoped to a single request.
48
+ *
49
+ * Partition key extraction priority:
50
+ * 1. conversationId (preferred for conversation-scoped routing)
51
+ * 2. responseId (fallback for response-scoped routing)
52
+ * 3. random 18-char key when neither has a valid format
53
+ *
54
+ * If responseId is not provided, one is generated with prefix `resp`.
55
+ */
56
+ export function createIdGenerator(responseId, conversationId) {
57
+ const partitionKey = (conversationId !== undefined
58
+ ? extractPartitionKey(conversationId)
59
+ : null) ??
60
+ (responseId !== undefined ? extractPartitionKey(responseId) : null) ??
61
+ generateEntropy(PARTITION_KEY_LENGTH);
62
+ const resolvedResponseId = responseId ?? buildId('resp', partitionKey);
63
+ return {
64
+ responseId: resolvedResponseId,
65
+ generateMessageId: () => buildId('msg', partitionKey),
66
+ generateFunctionCallId: () => buildId('func', partitionKey),
67
+ generateFunctionOutputId: () => buildId('funcout', partitionKey),
68
+ };
69
+ }
70
+ // ============================================================
71
+ // BACKWARD COMPAT
72
+ // ============================================================
73
+ /**
74
+ * Generate a prefixed random ID using crypto-secure entropy.
75
+ * Format: {prefix}{32 alphanumeric chars}
76
+ *
77
+ * Kept for backward compatibility with callers that do not need
78
+ * partition-key correlation.
79
+ */
80
+ export function generateId(prefix) {
81
+ return prefix + generateEntropy(ENTROPY_LENGTH);
82
+ }
83
+ //# sourceMappingURL=id.js.map
package/dist/id.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.js","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAa1C,+DAA+D;AAC/D,UAAU;AACV,+DAA+D;AAE/D,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAChC,MAAM,cAAc,GAAG,EAAE,CAAC;AAE1B;;;;GAIG;AACH,SAAS,eAAe,CAAC,MAAc;IACrC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,OAAO,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACjC,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,EAAU;IACrC,MAAM,aAAa,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,aAAa,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;IAC5C,IAAI,OAAO,CAAC,MAAM,GAAG,oBAAoB;QAAE,OAAO,IAAI,CAAC;IACvD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CAAC,MAAc,EAAE,YAAoB;IACnD,MAAM,OAAO,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC;IAChD,OAAO,GAAG,MAAM,IAAI,YAAY,GAAG,OAAO,EAAE,CAAC;AAC/C,CAAC;AAED,+DAA+D;AAC/D,UAAU;AACV,+DAA+D;AAE/D;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAC/B,UAA+B,EAC/B,cAAmC;IAEnC,MAAM,YAAY,GAChB,CAAC,cAAc,KAAK,SAAS;QAC3B,CAAC,CAAC,mBAAmB,CAAC,cAAc,CAAC;QACrC,CAAC,CAAC,IAAI,CAAC;QACT,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACnE,eAAe,CAAC,oBAAoB,CAAC,CAAC;IAExC,MAAM,kBAAkB,GAAG,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAEvE,OAAO;QACL,UAAU,EAAE,kBAAkB;QAC9B,iBAAiB,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,CAAC;QACrD,sBAAsB,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC;QAC3D,wBAAwB,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC;KACjE,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,kBAAkB;AAClB,+DAA+D;AAE/D;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,MAAM,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,17 @@
1
+ export type { ContentPart, CreateResponse, ErrorResponse, FoundryHarnessOptions, FoundryMetrics, FoundryResponse, FoundryToolDefinition, InputItem, FunctionCallItem, FunctionCallOutputItem, JSONSchemaObject, JSONSchemaProperty, OutputContentPart, OutputItem, StreamErrorEvent, ToolDefinition, UserMessageItem, } from './types.js';
2
+ export { CapacityError, CredentialError, InputError } from './errors.js';
3
+ export type { IdGenerator } from './id.js';
4
+ export { createIdGenerator, generateId } from './id.js';
5
+ export type { ExtractedInput } from './extract.js';
6
+ export { extractInput } from './extract.js';
7
+ export type { SessionManager } from './session.js';
8
+ export { createSessionManager } from './session.js';
9
+ export { buildErrorResponse, buildSyncResponse, generateToolDefinitions, } from './response.js';
10
+ export { streamFoundryResponse } from './stream.js';
11
+ export type { ConversationsClient } from './conversations.js';
12
+ export { createConversationsClient, PersistenceError, } from './conversations.js';
13
+ export type { TelemetryOptions } from './telemetry.js';
14
+ export { initTelemetry, getTracer, shutdownTelemetry } from './telemetry.js';
15
+ export type { FoundryHarness } from './harness.js';
16
+ export { createFoundryHarness } from './harness.js';
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,YAAY,EACV,WAAW,EACX,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,SAAS,EACT,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,eAAe,GAChB,MAAM,YAAY,CAAC;AAMpB,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAMzE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAMxD,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAM5C,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAMpD,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,eAAe,CAAC;AAMvB,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAMpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EACL,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAM5B,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAM7E,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC"}