@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
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ // ============================================================
2
+ // TYPES
3
+ // ============================================================
4
+ // ============================================================
5
+ // ERRORS
6
+ // ============================================================
7
+ export { CapacityError, CredentialError, InputError } from './errors.js';
8
+ export { createIdGenerator, generateId } from './id.js';
9
+ export { extractInput } from './extract.js';
10
+ export { createSessionManager } from './session.js';
11
+ // ============================================================
12
+ // RESPONSE BUILDERS
13
+ // ============================================================
14
+ export { buildErrorResponse, buildSyncResponse, generateToolDefinitions, } from './response.js';
15
+ // ============================================================
16
+ // SSE STREAM EMITTER
17
+ // ============================================================
18
+ export { streamFoundryResponse } from './stream.js';
19
+ export { createConversationsClient, PersistenceError, } from './conversations.js';
20
+ export { initTelemetry, getTracer, shutdownTelemetry } from './telemetry.js';
21
+ export { createFoundryHarness } from './harness.js';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,QAAQ;AACR,+DAA+D;AAsB/D,+DAA+D;AAC/D,SAAS;AACT,+DAA+D;AAE/D,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAOzE,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAOxD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAO5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,+DAA+D;AAC/D,oBAAoB;AACpB,+DAA+D;AAE/D,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,eAAe,CAAC;AAEvB,+DAA+D;AAC/D,qBAAqB;AACrB,+DAA+D;AAE/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAOpD,OAAO,EACL,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAO5B,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAO7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { AgentRouter, RunResponse } from '@rcrsr/rill-agent';
2
+ import type { ErrorResponse, FoundryResponse, FoundryToolDefinition } from './types.js';
3
+ /**
4
+ * Build a synchronous FoundryResponse from a RunResponse.
5
+ *
6
+ * State mapping: 'completed' → 'completed', 'error' → 'failed'.
7
+ * Result is coerced to string; errors are encoded in the response body.
8
+ */
9
+ export declare function buildSyncResponse(result: RunResponse, responseId: string): FoundryResponse;
10
+ /**
11
+ * Build a non-streaming JSON error response body.
12
+ *
13
+ * When debug is true, the original message is passed through verbatim.
14
+ * When debug is false or absent, a generic message is returned based on
15
+ * the error code per IR-10 (FOUNDRY_AGENT_DEBUG_ERRORS=false behavior).
16
+ */
17
+ export declare function buildErrorResponse(code: string, message: string, debug?: boolean): ErrorResponse;
18
+ /**
19
+ * Generate Foundry tool definitions from the default agent's handler descriptions.
20
+ *
21
+ * Only the default agent's handlers are exposed (AC-21).
22
+ * Returns an empty array when describe() returns null.
23
+ */
24
+ export declare function generateToolDefinitions(router: AgentRouter): FoundryToolDefinition[];
25
+ //# sourceMappingURL=response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAElE,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,qBAAqB,EAGtB,MAAM,YAAY,CAAC;AA8BpB;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,MAAM,GACjB,eAAe,CA+BjB;AAmBD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,OAAO,GACd,aAAa,CAOf;AAsBD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,WAAW,GAClB,qBAAqB,EAAE,CA0CzB"}
@@ -0,0 +1,154 @@
1
+ import { generateId } from './id.js';
2
+ // ============================================================
3
+ // RESULT COERCION
4
+ // ============================================================
5
+ /**
6
+ * Coerce a RunResponse result to a string.
7
+ * - string → passthrough
8
+ * - number | boolean → String()
9
+ * - object (non-null) → JSON.stringify()
10
+ * - null | undefined → empty string
11
+ */
12
+ function coerceResult(result) {
13
+ if (result === null || result === undefined) {
14
+ return '';
15
+ }
16
+ if (typeof result === 'string') {
17
+ return result;
18
+ }
19
+ if (typeof result === 'number' || typeof result === 'boolean') {
20
+ return String(result);
21
+ }
22
+ return JSON.stringify(result);
23
+ }
24
+ // ============================================================
25
+ // SYNC RESPONSE BUILDER
26
+ // ============================================================
27
+ /**
28
+ * Build a synchronous FoundryResponse from a RunResponse.
29
+ *
30
+ * State mapping: 'completed' → 'completed', 'error' → 'failed'.
31
+ * Result is coerced to string; errors are encoded in the response body.
32
+ */
33
+ export function buildSyncResponse(result, responseId) {
34
+ const status = result.state === 'completed' ? 'completed' : 'failed';
35
+ const text = coerceResult(result.result);
36
+ const msgId = generateId('msg_');
37
+ return {
38
+ id: responseId,
39
+ object: 'response',
40
+ created_at: Math.floor(Date.now() / 1000),
41
+ status,
42
+ output: [
43
+ {
44
+ id: msgId,
45
+ type: 'message',
46
+ role: 'assistant',
47
+ status: 'completed',
48
+ content: [
49
+ {
50
+ type: 'text',
51
+ text,
52
+ annotations: [],
53
+ },
54
+ ],
55
+ },
56
+ ],
57
+ error: status === 'failed' ? { code: 'SERVER_ERROR', message: text } : null,
58
+ metadata: {},
59
+ temperature: 0,
60
+ top_p: 0,
61
+ user: '',
62
+ };
63
+ }
64
+ // ============================================================
65
+ // GENERIC ERROR MESSAGES
66
+ // ============================================================
67
+ const GENERIC_MESSAGES = {
68
+ INVALID_REQUEST: 'Invalid request',
69
+ NOT_FOUND: 'Not found',
70
+ RATE_LIMITED: 'Rate limited',
71
+ SERVER_ERROR: 'Internal server error',
72
+ };
73
+ const FALLBACK_MESSAGE = 'An error occurred';
74
+ // ============================================================
75
+ // ERROR RESPONSE BUILDER
76
+ // ============================================================
77
+ /**
78
+ * Build a non-streaming JSON error response body.
79
+ *
80
+ * When debug is true, the original message is passed through verbatim.
81
+ * When debug is false or absent, a generic message is returned based on
82
+ * the error code per IR-10 (FOUNDRY_AGENT_DEBUG_ERRORS=false behavior).
83
+ */
84
+ export function buildErrorResponse(code, message, debug) {
85
+ const safeMessage = debug
86
+ ? message
87
+ : (GENERIC_MESSAGES[code] ?? FALLBACK_MESSAGE);
88
+ return {
89
+ error: { code, message: safeMessage },
90
+ };
91
+ }
92
+ // ============================================================
93
+ // TOOL DEFINITION GENERATOR
94
+ // ============================================================
95
+ /**
96
+ * Map a rill param type string to a JSON Schema type string.
97
+ * Falls back to 'string' for unrecognized types.
98
+ */
99
+ function mapParamType(rillType) {
100
+ switch (rillType) {
101
+ case 'number':
102
+ case 'integer':
103
+ return rillType;
104
+ case 'boolean':
105
+ return 'boolean';
106
+ default:
107
+ return 'string';
108
+ }
109
+ }
110
+ /**
111
+ * Generate Foundry tool definitions from the default agent's handler descriptions.
112
+ *
113
+ * Only the default agent's handlers are exposed (AC-21).
114
+ * Returns an empty array when describe() returns null.
115
+ */
116
+ export function generateToolDefinitions(router) {
117
+ const defaultAgent = router.defaultAgent();
118
+ const description = router.describe(defaultAgent);
119
+ if (description === null) {
120
+ return [];
121
+ }
122
+ const properties = {};
123
+ const required = [];
124
+ for (const param of description.params) {
125
+ const property = {
126
+ type: mapParamType(param.type),
127
+ ...(param.description !== undefined
128
+ ? { description: param.description }
129
+ : {}),
130
+ ...(param.defaultValue !== undefined
131
+ ? { default: param.defaultValue }
132
+ : {}),
133
+ };
134
+ properties[param.name] = property;
135
+ if (param.required) {
136
+ required.push(param.name);
137
+ }
138
+ }
139
+ const parameters = {
140
+ type: 'object',
141
+ properties,
142
+ ...(required.length > 0 ? { required } : {}),
143
+ };
144
+ return [
145
+ {
146
+ type: 'function',
147
+ name: description.name,
148
+ description: description.description ?? '',
149
+ parameters,
150
+ strict: true,
151
+ },
152
+ ];
153
+ }
154
+ //# sourceMappingURL=response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export interface SessionManager {
2
+ /**
3
+ * Acquire a session for the given conversation ID.
4
+ * When conversationId is provided, it is used directly as the session ID.
5
+ * When absent, a new random session ID is generated.
6
+ * Throws CapacityError when the pool is at maximum capacity.
7
+ */
8
+ acquire(conversationId: string | undefined): string;
9
+ /**
10
+ * Release a session by ID. No-op if the session ID is not tracked.
11
+ */
12
+ release(sessionId: string): void;
13
+ /**
14
+ * Return the number of currently open sessions.
15
+ */
16
+ activeCount(): number;
17
+ }
18
+ /**
19
+ * Create a bounded pool manager for concurrent rill sessions.
20
+ *
21
+ * Max capacity reads from MAX_CONCURRENT_SESSIONS env var, default 10.
22
+ */
23
+ export declare function createSessionManager(): SessionManager;
24
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,OAAO,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;IAEpD;;OAEG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAEjC;;OAEG;IACH,WAAW,IAAI,MAAM,CAAC;CACvB;AAQD;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAyBrD"}
@@ -0,0 +1,34 @@
1
+ import { CapacityError } from './errors.js';
2
+ import { generateId } from './id.js';
3
+ // ============================================================
4
+ // FACTORY
5
+ // ============================================================
6
+ const DEFAULT_MAX_SESSIONS = 10;
7
+ /**
8
+ * Create a bounded pool manager for concurrent rill sessions.
9
+ *
10
+ * Max capacity reads from MAX_CONCURRENT_SESSIONS env var, default 10.
11
+ */
12
+ export function createSessionManager() {
13
+ const raw = process.env['MAX_CONCURRENT_SESSIONS'];
14
+ const parsed = raw !== undefined ? parseInt(raw, 10) : NaN;
15
+ const max = Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_MAX_SESSIONS;
16
+ const active = new Set();
17
+ return {
18
+ acquire(conversationId) {
19
+ if (active.size >= max) {
20
+ throw new CapacityError(max);
21
+ }
22
+ const sessionId = conversationId ?? generateId('sess_');
23
+ active.add(sessionId);
24
+ return sessionId;
25
+ },
26
+ release(sessionId) {
27
+ active.delete(sessionId);
28
+ },
29
+ activeCount() {
30
+ return active.size;
31
+ },
32
+ };
33
+ }
34
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AA0BrC,+DAA+D;AAC/D,UAAU;AACV,+DAA+D;AAE/D,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEhC;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC3D,MAAM,GAAG,GACP,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC;IACxE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IAEjC,OAAO;QACL,OAAO,CAAC,cAAkC;YACxC,IAAI,MAAM,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;gBACvB,MAAM,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;YACD,MAAM,SAAS,GAAG,cAAc,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;YACxD,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACtB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO,CAAC,SAAiB;YACvB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;QAED,WAAW;YACT,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,47 @@
1
+ import type { IdGenerator } from './id.js';
2
+ interface StreamOptions {
3
+ readonly onError?: ((err: unknown) => void) | undefined;
4
+ /** IdGenerator scoped to the request for correlated message IDs. */
5
+ readonly idGenerator?: IdGenerator | undefined;
6
+ /** Session ID echoed back in x-agent-session-id response header. */
7
+ readonly sessionId?: string | undefined;
8
+ /** Invocation ID echoed back in x-agent-invocation-id response header. */
9
+ readonly invocationId?: string | undefined;
10
+ /** Pre-built x-aml-foundry-agents-metadata JSON string. */
11
+ readonly metadataHeader?: string | undefined;
12
+ /**
13
+ * When true, raw error messages are forwarded to clients. When false
14
+ * (default), error events emit a generic message to avoid leaking
15
+ * internal details. Mirrors the harness `debugErrors` option used by
16
+ * `buildErrorResponse`.
17
+ */
18
+ readonly debugErrors?: boolean | undefined;
19
+ }
20
+ export interface StreamResponseOptions extends StreamOptions {
21
+ /** Promise that resolves with the agent result text (flat mode). */
22
+ readonly resultPromise?: Promise<string> | undefined;
23
+ /** Async iterable of text chunks for real-time delta streaming. */
24
+ readonly chunks?: AsyncIterable<string> | undefined;
25
+ /** Called when the agent promise rejects. */
26
+ readonly onError?: ((err: unknown) => void) | undefined;
27
+ }
28
+ /**
29
+ * Create a streaming SSE Response matching the Python SDK's minimal
30
+ * event format: only response.output_text.delta, response.output_text.done,
31
+ * and response.completed events are emitted.
32
+ *
33
+ * No envelope events (response.created, response.in_progress, etc.)
34
+ * are sent — the Python SDK does not inject them.
35
+ */
36
+ export declare function createFoundryStreamResponse(responseId: string, options: StreamResponseOptions): Response;
37
+ /**
38
+ * Stream a Foundry Responses lifecycle via SSE.
39
+ * Delegates to createFoundryStreamResponse for all paths.
40
+ */
41
+ export declare function streamFoundryResponse(_c: unknown, responseId: string, resultStream: AsyncIterable<{
42
+ value?: unknown;
43
+ }>, options: StreamOptions & {
44
+ resultPromise?: Promise<string>;
45
+ }): Response;
46
+ export {};
47
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAM3C,UAAU,aAAa;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACxD,oEAAoE;IACpE,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/C,oEAAoE;IACpE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,0EAA0E;IAC1E,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,2DAA2D;IAC3D,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC5C;AAwDD,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IAC1D,oEAAoE;IACpE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACrD,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACpD,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACzD;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,qBAAqB,GAC7B,QAAQ,CA0IV;AAMD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,OAAO,EACX,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,aAAa,CAAC;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EAChD,OAAO,EAAE,aAAa,GAAG;IAAE,aAAa,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,GAC3D,QAAQ,CAqBV"}
package/dist/stream.js ADDED
@@ -0,0 +1,189 @@
1
+ const REDACTED_ERROR_MESSAGE = 'Internal server error';
2
+ // ============================================================
3
+ // HELPERS
4
+ // ============================================================
5
+ const encoder = new TextEncoder();
6
+ /**
7
+ * Format a named SSE event as a string.
8
+ */
9
+ function sseChunk(event, data) {
10
+ return `event: ${event}\ndata: ${data}\n\n`;
11
+ }
12
+ // ============================================================
13
+ // RESPONSE HEADERS
14
+ // ============================================================
15
+ /**
16
+ * Build the common SSE response headers.
17
+ * Matches the Python SDK's create_response_headers() plus
18
+ * Starlette StreamingResponse defaults.
19
+ */
20
+ function sseHeaders(options) {
21
+ const headers = {
22
+ 'content-type': 'text/event-stream; charset=utf-8',
23
+ 'cache-control': 'no-store',
24
+ 'x-accel-buffering': 'no',
25
+ 'x-aml-foundry-agents-metadata': options?.metadataHeader ??
26
+ JSON.stringify({
27
+ package: { name: 'azure-ai-agentserver-core', version: '1.0.0b17' },
28
+ runtime: {
29
+ python_version: '3.11.0',
30
+ platform: 'Linux',
31
+ host_name: '',
32
+ replica_name: '',
33
+ },
34
+ }),
35
+ };
36
+ if (options?.sessionId !== undefined) {
37
+ headers['x-agent-session-id'] = options.sessionId;
38
+ }
39
+ if (options?.invocationId !== undefined) {
40
+ headers['x-agent-invocation-id'] = options.invocationId;
41
+ }
42
+ return headers;
43
+ }
44
+ /**
45
+ * Create a streaming SSE Response matching the Python SDK's minimal
46
+ * event format: only response.output_text.delta, response.output_text.done,
47
+ * and response.completed events are emitted.
48
+ *
49
+ * No envelope events (response.created, response.in_progress, etc.)
50
+ * are sent — the Python SDK does not inject them.
51
+ */
52
+ export function createFoundryStreamResponse(responseId, options) {
53
+ let seq = 0;
54
+ let closed = false;
55
+ let keepAliveTimer;
56
+ const clearKeepAlive = () => {
57
+ if (keepAliveTimer !== undefined) {
58
+ clearInterval(keepAliveTimer);
59
+ keepAliveTimer = undefined;
60
+ }
61
+ };
62
+ function ev(event, payload) {
63
+ payload['sequence_number'] = seq++;
64
+ return encoder.encode(sseChunk(event, JSON.stringify(payload)));
65
+ }
66
+ function emitDeltas(controller, fullText) {
67
+ const tokens = fullText.split(' ');
68
+ for (let i = 0; i < tokens.length; i++) {
69
+ const piece = i === tokens.length - 1 ? tokens[i] : tokens[i] + ' ';
70
+ controller.enqueue(ev('response.output_text.delta', {
71
+ type: 'response.output_text.delta',
72
+ delta: piece,
73
+ }));
74
+ }
75
+ }
76
+ function emitCompletion(controller, fullText) {
77
+ controller.enqueue(ev('response.output_text.done', {
78
+ type: 'response.output_text.done',
79
+ text: fullText,
80
+ }));
81
+ controller.enqueue(ev('response.completed', {
82
+ type: 'response.completed',
83
+ response: {
84
+ object: 'response',
85
+ id: responseId,
86
+ status: 'completed',
87
+ created_at: Math.floor(Date.now() / 1000),
88
+ output: [],
89
+ },
90
+ }));
91
+ closed = true;
92
+ controller.close();
93
+ }
94
+ function emitError(controller, err) {
95
+ clearKeepAlive();
96
+ options.onError?.(err);
97
+ const rawMessage = err instanceof Error ? err.message : String(err);
98
+ const message = options.debugErrors === true ? rawMessage : REDACTED_ERROR_MESSAGE;
99
+ controller.enqueue(encoder.encode(sseChunk('error', JSON.stringify({
100
+ type: 'error',
101
+ sequence_number: seq++,
102
+ code: 'SERVER_ERROR',
103
+ message,
104
+ param: '',
105
+ }))));
106
+ closed = true;
107
+ controller.close();
108
+ }
109
+ const body = new ReadableStream({
110
+ start(controller) {
111
+ keepAliveTimer = setInterval(() => {
112
+ if (!closed) {
113
+ controller.enqueue(encoder.encode(': keep-alive\n\n'));
114
+ }
115
+ }, 15_000);
116
+ if (options.chunks !== undefined) {
117
+ // Chunk streaming: emit each chunk as a delta event in real time.
118
+ (async () => {
119
+ let fullText = '';
120
+ for await (const chunk of options.chunks) {
121
+ if (closed)
122
+ break;
123
+ fullText += chunk;
124
+ controller.enqueue(ev('response.output_text.delta', {
125
+ type: 'response.output_text.delta',
126
+ delta: chunk,
127
+ }));
128
+ }
129
+ if (closed)
130
+ return;
131
+ clearKeepAlive();
132
+ emitCompletion(controller, fullText);
133
+ })().catch((err) => emitError(controller, err));
134
+ }
135
+ else if (options.resultPromise !== undefined) {
136
+ // Flat mode: wait for full text, then emit word-by-word deltas.
137
+ options.resultPromise
138
+ .then((resultText) => {
139
+ if (closed)
140
+ return;
141
+ clearKeepAlive();
142
+ emitDeltas(controller, resultText);
143
+ emitCompletion(controller, resultText);
144
+ })
145
+ .catch((err) => emitError(controller, err));
146
+ }
147
+ else {
148
+ clearKeepAlive();
149
+ emitCompletion(controller, '');
150
+ }
151
+ },
152
+ cancel() {
153
+ closed = true;
154
+ clearKeepAlive();
155
+ },
156
+ });
157
+ return new Response(body, {
158
+ status: 200,
159
+ headers: sseHeaders(options),
160
+ });
161
+ }
162
+ // ============================================================
163
+ // LEGACY EXPORTS (kept for test compatibility)
164
+ // ============================================================
165
+ /**
166
+ * Stream a Foundry Responses lifecycle via SSE.
167
+ * Delegates to createFoundryStreamResponse for all paths.
168
+ */
169
+ export function streamFoundryResponse(_c, responseId, resultStream, options) {
170
+ // Convert resultStream to a promise if resultPromise not provided
171
+ const resultPromise = options.resultPromise ??
172
+ (async () => {
173
+ let text = '';
174
+ for await (const chunk of resultStream) {
175
+ if (chunk.value !== null && chunk.value !== undefined) {
176
+ text +=
177
+ typeof chunk.value === 'string'
178
+ ? chunk.value
179
+ : JSON.stringify(chunk.value);
180
+ }
181
+ }
182
+ return text;
183
+ })();
184
+ return createFoundryStreamResponse(responseId, {
185
+ ...options,
186
+ resultPromise,
187
+ });
188
+ }
189
+ //# sourceMappingURL=stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type Tracer } from '@opentelemetry/api';
2
+ export interface TelemetryOptions {
3
+ agentName?: string | undefined;
4
+ agentVersion?: string | undefined;
5
+ }
6
+ /**
7
+ * Initialize the OpenTelemetry SDK when OTEL_EXPORTER_OTLP_ENDPOINT is set.
8
+ * No-op when the env var is absent. Safe to call multiple times.
9
+ */
10
+ export declare function initTelemetry(options?: TelemetryOptions): void;
11
+ /**
12
+ * Return a tracer for the foundry harness instrumentation scope.
13
+ * Returns a no-op tracer when the SDK is not initialized.
14
+ */
15
+ export declare function getTracer(): Tracer;
16
+ /**
17
+ * Gracefully shut down the OpenTelemetry SDK and flush pending spans.
18
+ * No-op when the SDK was never initialized.
19
+ */
20
+ export declare function shutdownTelemetry(): Promise<void>;
21
+ //# sourceMappingURL=telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AASxD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAYD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAa9D;AAMD;;;GAGG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAMD;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKvD"}
@@ -0,0 +1,53 @@
1
+ import { trace } from '@opentelemetry/api';
2
+ import { NodeSDK } from '@opentelemetry/sdk-node';
3
+ import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
4
+ import { Resource } from '@opentelemetry/resources';
5
+ // ============================================================
6
+ // STATE
7
+ // ============================================================
8
+ let sdk;
9
+ // ============================================================
10
+ // FACTORY
11
+ // ============================================================
12
+ /**
13
+ * Initialize the OpenTelemetry SDK when OTEL_EXPORTER_OTLP_ENDPOINT is set.
14
+ * No-op when the env var is absent. Safe to call multiple times.
15
+ */
16
+ export function initTelemetry(options) {
17
+ if (!process.env['OTEL_EXPORTER_OTLP_ENDPOINT'])
18
+ return;
19
+ if (sdk !== undefined)
20
+ return;
21
+ const resource = new Resource({
22
+ 'service.name': options?.agentName ?? 'rill-foundry-harness',
23
+ 'service.version': options?.agentVersion ?? '0.0.0',
24
+ });
25
+ const traceExporter = new OTLPTraceExporter();
26
+ sdk = new NodeSDK({ resource, traceExporter });
27
+ sdk.start();
28
+ }
29
+ // ============================================================
30
+ // HELPERS
31
+ // ============================================================
32
+ /**
33
+ * Return a tracer for the foundry harness instrumentation scope.
34
+ * Returns a no-op tracer when the SDK is not initialized.
35
+ */
36
+ export function getTracer() {
37
+ return trace.getTracer('rill-foundry-harness');
38
+ }
39
+ // ============================================================
40
+ // DISPOSE
41
+ // ============================================================
42
+ /**
43
+ * Gracefully shut down the OpenTelemetry SDK and flush pending spans.
44
+ * No-op when the SDK was never initialized.
45
+ */
46
+ export async function shutdownTelemetry() {
47
+ if (sdk === undefined)
48
+ return;
49
+ const instance = sdk;
50
+ sdk = undefined;
51
+ await instance.shutdown();
52
+ }
53
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAe,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAWpD,+DAA+D;AAC/D,QAAQ;AACR,+DAA+D;AAE/D,IAAI,GAAwB,CAAC;AAE7B,+DAA+D;AAC/D,UAAU;AACV,+DAA+D;AAE/D;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAA0B;IACtD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC;QAAE,OAAO;IACxD,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO;IAE9B,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;QAC5B,cAAc,EAAE,OAAO,EAAE,SAAS,IAAI,sBAAsB;QAC5D,iBAAiB,EAAE,OAAO,EAAE,YAAY,IAAI,OAAO;KACpD,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,IAAI,iBAAiB,EAAE,CAAC;IAE9C,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC;IAC/C,GAAG,CAAC,KAAK,EAAE,CAAC;AACd,CAAC;AAED,+DAA+D;AAC/D,UAAU;AACV,+DAA+D;AAE/D;;;GAGG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;AACjD,CAAC;AAED,+DAA+D;AAC/D,UAAU;AACV,+DAA+D;AAE/D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO;IAC9B,MAAM,QAAQ,GAAG,GAAG,CAAC;IACrB,GAAG,GAAG,SAAS,CAAC;IAChB,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;AAC5B,CAAC"}