@gammatech/aijsx 0.9.3-dev.2024-05-31 → 0.10.0-dev.2024-06-04

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/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { L as LogChatCompletionRequest, A as AINode, C as ChatMessage, R as RenderContext, a as LogImplementation, S as SpanProcessor, b as ContextValues, c as Context, T as Tracer, d as ReadableSpan, e as SpanExporter, f as AIComponent, g as SpanAttributes, P as Prompt, h as ChatCompletionRequestPayloads, D as DebugMessage, E as EvaluatorResult, i as EvaluatorFn, j as PromptParsed, N as NotAsyncGenerator, F as FunctionChain, k as StreamChain, J as JSX } from './jsx-dev-runtime-uCZBuaDe.mjs';
2
- export { G as AIElement, m as AIFragment, B as BoundLogger, o as ChatRole, w as CombinedLogger, v as ConsoleLogger, I as ImagePart, p as ImagePartProps, x as Literal, q as LogChatCompletionResponse, r as LogLevel, s as Logger, u as NoopLogImplementation, Y as OutputParser, K as PropsOfAIComponent, y as RenderResult, H as Renderable, Q as Span, M as SpanContext, U as SpanEvent, O as SpanStatus, W as TracingContext, V as TracingContextKey, X as TracingContextManager, z as attachedContextSymbol, l as createAIElement, n as createContext, t as toDebugMessage } from './jsx-dev-runtime-uCZBuaDe.mjs';
1
+ import { L as LogChatCompletionRequest, A as AINode, C as ChatMessage, R as RenderContext, a as LogImplementation, S as SpanProcessor, b as ContextValues, c as Context, T as Tracer, d as ReadableSpan, e as SpanExporter, f as AIComponent, g as SpanAttributes, P as Prompt, h as ChatCompletionRequestPayloads, D as DebugMessage, E as EvaluatorResult, i as EvaluatorFn, j as PromptParsed, J as JSX } from './jsx-dev-runtime-vXV-PExh.mjs';
2
+ export { y as AIElement, l as AIFragment, B as BoundLogger, n as ChatRole, u as CombinedLogger, s as ConsoleLogger, I as ImagePart, o as ImagePartProps, v as Literal, p as LogChatCompletionResponse, q as LogLevel, r as Logger, N as NoopLogImplementation, V as OutputParser, F as PropsOfAIComponent, w as RenderResult, z as Renderable, K as Span, G as SpanContext, M as SpanEvent, H as SpanStatus, Q as TracingContext, O as TracingContextKey, U as TracingContextManager, x as attachedContextSymbol, k as createAIElement, m as createContext, t as toDebugMessage } from './jsx-dev-runtime-vXV-PExh.mjs';
3
3
  import { ZodObject, ZodRawShape, ZodTypeAny, ZodString, z } from 'zod';
4
4
  import { OpenAI } from 'openai';
5
5
  export { OpenAI as OpenAIClient } from 'openai';
@@ -85,6 +85,24 @@ declare class AITraceAPI {
85
85
  }
86
86
  declare const tracing: AITraceAPI;
87
87
 
88
+ declare class SpanTree {
89
+ roots: SpanTreeNode[];
90
+ findSpan: any;
91
+ addSpan(span: ReadableSpan): boolean;
92
+ findNode(id: string): SpanTreeNode | null;
93
+ }
94
+ declare class SpanTreeNode {
95
+ readonly id: string;
96
+ readonly name: string;
97
+ readonly parent: SpanTreeNode | null;
98
+ readonly children: SpanTreeNode[];
99
+ readonly attrs: Record<string, any>;
100
+ constructor(id: string, name: string, parent: SpanTreeNode | null, children: SpanTreeNode[], attrs: Record<string, any>);
101
+ addChild(child: SpanTreeNode): void;
102
+ getNearestAttribute<K>(key: string): K | null;
103
+ getRootAttribute<K>(key: string): K | null;
104
+ }
105
+
88
106
  type CostFn = (tokensUsed: {
89
107
  prompt: number;
90
108
  completion: number;
@@ -109,6 +127,7 @@ declare abstract class EnrichingSpanProcessor implements SpanProcessor {
109
127
  }[];
110
128
  protected onAllDonePromise: Promise<void> | null;
111
129
  protected onAllDonePromiseResolve: (() => void) | null;
130
+ protected spanTree: SpanTree;
112
131
  constructor(exporter: SpanExporter);
113
132
  onStart(span: ReadableSpan): Promise<void>;
114
133
  onEnd(span: ReadableSpan): Promise<void>;
@@ -125,6 +144,7 @@ declare class AISpanProcessor extends EnrichingSpanProcessor {
125
144
  };
126
145
  onTraceComplete(rootSpan: ReadableSpan): Promise<void>;
127
146
  enrichSpan(span: ReadableSpan): Promise<ReadableSpan>;
147
+ protected addPromptKeys(span: ReadableSpan): Promise<ReadableSpan>;
128
148
  protected updateCost(span: ReadableSpan): Promise<ReadableSpan>;
129
149
  protected updateUsage(span: ReadableSpan): Promise<ReadableSpan>;
130
150
  protected evaluatePrompt(span: ReadableSpan): Promise<ReadableSpan>;
@@ -151,11 +171,6 @@ declare namespace AISpanAttributes {
151
171
  output: string;
152
172
  parsedOutput?: any;
153
173
  };
154
- type Chain = {
155
- chainKey: string;
156
- chainType: string;
157
- variables: Record<string, any>;
158
- };
159
174
  type ChatCompletion<K extends keyof ChatCompletionRequestPayloads = keyof ChatCompletionRequestPayloads> = {
160
175
  model: string;
161
176
  cost?: number;
@@ -178,12 +193,13 @@ declare namespace ProcessedAISpanAttributes {
178
193
  evaluatorError?: string;
179
194
  totalUsage?: Usage;
180
195
  totalCost?: Cost;
196
+ parentPromptKey?: string;
197
+ rootPromptKey?: string;
181
198
  };
182
- type Chain = AISpanAttributes.Chain & {
183
- totalUsage?: Usage;
184
- totalCost?: Cost;
199
+ type ChatCompletion<K extends keyof ChatCompletionRequestPayloads = keyof ChatCompletionRequestPayloads> = AISpanAttributes.ChatCompletion<K> & {
200
+ parentPromptKey?: string;
201
+ rootPromptKey?: string;
185
202
  };
186
- type ChatCompletion<K extends keyof ChatCompletionRequestPayloads = keyof ChatCompletionRequestPayloads> = AISpanAttributes.ChatCompletion<K>;
187
203
  }
188
204
 
189
205
  /**
@@ -208,19 +224,6 @@ declare function createPrompt<K extends string, I extends ZodObject<ZodRawShape>
208
224
  metadata?: Record<string, any>;
209
225
  }): Prompt<z.infer<I>>;
210
226
 
211
- declare function createFunctionChain<I extends ZodObject<ZodRawShape>, R extends NotAsyncGenerator<any>>(chain: {
212
- key: string;
213
- run: (variables: z.infer<I>, context: RenderContext) => R;
214
- outputSchema?: ZodTypeAny;
215
- schema: I;
216
- }): FunctionChain<z.infer<I>, R>;
217
- declare function createStreamChain<I extends ZodObject<ZodRawShape>, M extends ZodTypeAny, R extends AsyncGenerator<any, any, any>>(chain: {
218
- key: string;
219
- run: (variables: z.infer<I>, context: RenderContext) => R;
220
- schema: I;
221
- messageSchema?: M;
222
- }): StreamChain<z.infer<I>, R>;
223
-
224
227
  declare class ParseVariablesError extends Error {
225
228
  }
226
229
  declare class PromptInvalidOutputError extends Error {
@@ -299,4 +302,4 @@ type GoogleChatCompletionProps = {
299
302
  };
300
303
  declare function GoogleChatCompletion(props: GoogleChatCompletionProps, ctx: RenderContext): JSX.Element;
301
304
 
302
- export { AIComponent, AINode, AISpanAttributes, AISpanProcessor, AnthropicChatCompletion, type AnthropicChatCompletionRequest, AnthropicClientContext, AssistantMessage, type ChatCompletionClientAndProvider, ChatCompletionError, type ChatCompletionRequestPayloads, ChatMessage, Context, type CostFn, DebugMessage, DefaultMaxRetriesContext, EnrichingSpanProcessor, EvaluatorFn, EvaluatorResult, Fallback, FunctionChain, GoogleChatCompletion, type GoogleChatCompletionRequest, GoogleClientContext, LogChatCompletionRequest, LogImplementation, NotAsyncGenerator, OpenAIChatCompletion, type OpenAIChatCompletionRequest, type OpenAIChatMessage, OpenAIClientContext, ParseVariablesError, ProcessedAISpanAttributes, type Prompt, PromptInvalidOutputError, PromptParsed, ReadableSpan, RenderContext, Retry, RetryCountContext, SpanAttributes, SpanExporter, SpanProcessor, StreamChain, SystemMessage, type TokenizerFn, Trace, Tracer, UserMessage, type ValidAnthropicChatModel, type ValidGoogleChatModel, type ValidOpenAIChatModel, type ValidOpenAIVisionModel, anthropicTokenizer, computeUsage, createFunctionChain, createPrompt, createRenderContext, createStreamChain, evaluatePrompt, openaiTokenizer, tracing };
305
+ export { AIComponent, AINode, AISpanAttributes, AISpanProcessor, AnthropicChatCompletion, type AnthropicChatCompletionRequest, AnthropicClientContext, AssistantMessage, type ChatCompletionClientAndProvider, ChatCompletionError, type ChatCompletionRequestPayloads, ChatMessage, Context, type CostFn, DebugMessage, DefaultMaxRetriesContext, EnrichingSpanProcessor, EvaluatorFn, EvaluatorResult, Fallback, GoogleChatCompletion, type GoogleChatCompletionRequest, GoogleClientContext, LogChatCompletionRequest, LogImplementation, OpenAIChatCompletion, type OpenAIChatCompletionRequest, type OpenAIChatMessage, OpenAIClientContext, ParseVariablesError, ProcessedAISpanAttributes, type Prompt, PromptInvalidOutputError, PromptParsed, ReadableSpan, RenderContext, Retry, RetryCountContext, SpanAttributes, SpanExporter, SpanProcessor, SystemMessage, type TokenizerFn, Trace, Tracer, UserMessage, type ValidAnthropicChatModel, type ValidGoogleChatModel, type ValidOpenAIChatModel, type ValidOpenAIVisionModel, anthropicTokenizer, computeUsage, createPrompt, createRenderContext, evaluatePrompt, openaiTokenizer, tracing };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { L as LogChatCompletionRequest, A as AINode, C as ChatMessage, R as RenderContext, a as LogImplementation, S as SpanProcessor, b as ContextValues, c as Context, T as Tracer, d as ReadableSpan, e as SpanExporter, f as AIComponent, g as SpanAttributes, P as Prompt, h as ChatCompletionRequestPayloads, D as DebugMessage, E as EvaluatorResult, i as EvaluatorFn, j as PromptParsed, N as NotAsyncGenerator, F as FunctionChain, k as StreamChain, J as JSX } from './jsx-dev-runtime-uCZBuaDe.js';
2
- export { G as AIElement, m as AIFragment, B as BoundLogger, o as ChatRole, w as CombinedLogger, v as ConsoleLogger, I as ImagePart, p as ImagePartProps, x as Literal, q as LogChatCompletionResponse, r as LogLevel, s as Logger, u as NoopLogImplementation, Y as OutputParser, K as PropsOfAIComponent, y as RenderResult, H as Renderable, Q as Span, M as SpanContext, U as SpanEvent, O as SpanStatus, W as TracingContext, V as TracingContextKey, X as TracingContextManager, z as attachedContextSymbol, l as createAIElement, n as createContext, t as toDebugMessage } from './jsx-dev-runtime-uCZBuaDe.js';
1
+ import { L as LogChatCompletionRequest, A as AINode, C as ChatMessage, R as RenderContext, a as LogImplementation, S as SpanProcessor, b as ContextValues, c as Context, T as Tracer, d as ReadableSpan, e as SpanExporter, f as AIComponent, g as SpanAttributes, P as Prompt, h as ChatCompletionRequestPayloads, D as DebugMessage, E as EvaluatorResult, i as EvaluatorFn, j as PromptParsed, J as JSX } from './jsx-dev-runtime-vXV-PExh.js';
2
+ export { y as AIElement, l as AIFragment, B as BoundLogger, n as ChatRole, u as CombinedLogger, s as ConsoleLogger, I as ImagePart, o as ImagePartProps, v as Literal, p as LogChatCompletionResponse, q as LogLevel, r as Logger, N as NoopLogImplementation, V as OutputParser, F as PropsOfAIComponent, w as RenderResult, z as Renderable, K as Span, G as SpanContext, M as SpanEvent, H as SpanStatus, Q as TracingContext, O as TracingContextKey, U as TracingContextManager, x as attachedContextSymbol, k as createAIElement, m as createContext, t as toDebugMessage } from './jsx-dev-runtime-vXV-PExh.js';
3
3
  import { ZodObject, ZodRawShape, ZodTypeAny, ZodString, z } from 'zod';
4
4
  import { OpenAI } from 'openai';
5
5
  export { OpenAI as OpenAIClient } from 'openai';
@@ -85,6 +85,24 @@ declare class AITraceAPI {
85
85
  }
86
86
  declare const tracing: AITraceAPI;
87
87
 
88
+ declare class SpanTree {
89
+ roots: SpanTreeNode[];
90
+ findSpan: any;
91
+ addSpan(span: ReadableSpan): boolean;
92
+ findNode(id: string): SpanTreeNode | null;
93
+ }
94
+ declare class SpanTreeNode {
95
+ readonly id: string;
96
+ readonly name: string;
97
+ readonly parent: SpanTreeNode | null;
98
+ readonly children: SpanTreeNode[];
99
+ readonly attrs: Record<string, any>;
100
+ constructor(id: string, name: string, parent: SpanTreeNode | null, children: SpanTreeNode[], attrs: Record<string, any>);
101
+ addChild(child: SpanTreeNode): void;
102
+ getNearestAttribute<K>(key: string): K | null;
103
+ getRootAttribute<K>(key: string): K | null;
104
+ }
105
+
88
106
  type CostFn = (tokensUsed: {
89
107
  prompt: number;
90
108
  completion: number;
@@ -109,6 +127,7 @@ declare abstract class EnrichingSpanProcessor implements SpanProcessor {
109
127
  }[];
110
128
  protected onAllDonePromise: Promise<void> | null;
111
129
  protected onAllDonePromiseResolve: (() => void) | null;
130
+ protected spanTree: SpanTree;
112
131
  constructor(exporter: SpanExporter);
113
132
  onStart(span: ReadableSpan): Promise<void>;
114
133
  onEnd(span: ReadableSpan): Promise<void>;
@@ -125,6 +144,7 @@ declare class AISpanProcessor extends EnrichingSpanProcessor {
125
144
  };
126
145
  onTraceComplete(rootSpan: ReadableSpan): Promise<void>;
127
146
  enrichSpan(span: ReadableSpan): Promise<ReadableSpan>;
147
+ protected addPromptKeys(span: ReadableSpan): Promise<ReadableSpan>;
128
148
  protected updateCost(span: ReadableSpan): Promise<ReadableSpan>;
129
149
  protected updateUsage(span: ReadableSpan): Promise<ReadableSpan>;
130
150
  protected evaluatePrompt(span: ReadableSpan): Promise<ReadableSpan>;
@@ -151,11 +171,6 @@ declare namespace AISpanAttributes {
151
171
  output: string;
152
172
  parsedOutput?: any;
153
173
  };
154
- type Chain = {
155
- chainKey: string;
156
- chainType: string;
157
- variables: Record<string, any>;
158
- };
159
174
  type ChatCompletion<K extends keyof ChatCompletionRequestPayloads = keyof ChatCompletionRequestPayloads> = {
160
175
  model: string;
161
176
  cost?: number;
@@ -178,12 +193,13 @@ declare namespace ProcessedAISpanAttributes {
178
193
  evaluatorError?: string;
179
194
  totalUsage?: Usage;
180
195
  totalCost?: Cost;
196
+ parentPromptKey?: string;
197
+ rootPromptKey?: string;
181
198
  };
182
- type Chain = AISpanAttributes.Chain & {
183
- totalUsage?: Usage;
184
- totalCost?: Cost;
199
+ type ChatCompletion<K extends keyof ChatCompletionRequestPayloads = keyof ChatCompletionRequestPayloads> = AISpanAttributes.ChatCompletion<K> & {
200
+ parentPromptKey?: string;
201
+ rootPromptKey?: string;
185
202
  };
186
- type ChatCompletion<K extends keyof ChatCompletionRequestPayloads = keyof ChatCompletionRequestPayloads> = AISpanAttributes.ChatCompletion<K>;
187
203
  }
188
204
 
189
205
  /**
@@ -208,19 +224,6 @@ declare function createPrompt<K extends string, I extends ZodObject<ZodRawShape>
208
224
  metadata?: Record<string, any>;
209
225
  }): Prompt<z.infer<I>>;
210
226
 
211
- declare function createFunctionChain<I extends ZodObject<ZodRawShape>, R extends NotAsyncGenerator<any>>(chain: {
212
- key: string;
213
- run: (variables: z.infer<I>, context: RenderContext) => R;
214
- outputSchema?: ZodTypeAny;
215
- schema: I;
216
- }): FunctionChain<z.infer<I>, R>;
217
- declare function createStreamChain<I extends ZodObject<ZodRawShape>, M extends ZodTypeAny, R extends AsyncGenerator<any, any, any>>(chain: {
218
- key: string;
219
- run: (variables: z.infer<I>, context: RenderContext) => R;
220
- schema: I;
221
- messageSchema?: M;
222
- }): StreamChain<z.infer<I>, R>;
223
-
224
227
  declare class ParseVariablesError extends Error {
225
228
  }
226
229
  declare class PromptInvalidOutputError extends Error {
@@ -299,4 +302,4 @@ type GoogleChatCompletionProps = {
299
302
  };
300
303
  declare function GoogleChatCompletion(props: GoogleChatCompletionProps, ctx: RenderContext): JSX.Element;
301
304
 
302
- export { AIComponent, AINode, AISpanAttributes, AISpanProcessor, AnthropicChatCompletion, type AnthropicChatCompletionRequest, AnthropicClientContext, AssistantMessage, type ChatCompletionClientAndProvider, ChatCompletionError, type ChatCompletionRequestPayloads, ChatMessage, Context, type CostFn, DebugMessage, DefaultMaxRetriesContext, EnrichingSpanProcessor, EvaluatorFn, EvaluatorResult, Fallback, FunctionChain, GoogleChatCompletion, type GoogleChatCompletionRequest, GoogleClientContext, LogChatCompletionRequest, LogImplementation, NotAsyncGenerator, OpenAIChatCompletion, type OpenAIChatCompletionRequest, type OpenAIChatMessage, OpenAIClientContext, ParseVariablesError, ProcessedAISpanAttributes, type Prompt, PromptInvalidOutputError, PromptParsed, ReadableSpan, RenderContext, Retry, RetryCountContext, SpanAttributes, SpanExporter, SpanProcessor, StreamChain, SystemMessage, type TokenizerFn, Trace, Tracer, UserMessage, type ValidAnthropicChatModel, type ValidGoogleChatModel, type ValidOpenAIChatModel, type ValidOpenAIVisionModel, anthropicTokenizer, computeUsage, createFunctionChain, createPrompt, createRenderContext, createStreamChain, evaluatePrompt, openaiTokenizer, tracing };
305
+ export { AIComponent, AINode, AISpanAttributes, AISpanProcessor, AnthropicChatCompletion, type AnthropicChatCompletionRequest, AnthropicClientContext, AssistantMessage, type ChatCompletionClientAndProvider, ChatCompletionError, type ChatCompletionRequestPayloads, ChatMessage, Context, type CostFn, DebugMessage, DefaultMaxRetriesContext, EnrichingSpanProcessor, EvaluatorFn, EvaluatorResult, Fallback, GoogleChatCompletion, type GoogleChatCompletionRequest, GoogleClientContext, LogChatCompletionRequest, LogImplementation, OpenAIChatCompletion, type OpenAIChatCompletionRequest, type OpenAIChatMessage, OpenAIClientContext, ParseVariablesError, ProcessedAISpanAttributes, type Prompt, PromptInvalidOutputError, PromptParsed, ReadableSpan, RenderContext, Retry, RetryCountContext, SpanAttributes, SpanExporter, SpanProcessor, SystemMessage, type TokenizerFn, Trace, Tracer, UserMessage, type ValidAnthropicChatModel, type ValidGoogleChatModel, type ValidOpenAIChatModel, type ValidOpenAIVisionModel, anthropicTokenizer, computeUsage, createPrompt, createRenderContext, evaluatePrompt, openaiTokenizer, tracing };
package/dist/index.js CHANGED
@@ -63,10 +63,8 @@ __export(src_exports, {
63
63
  computeUsage: () => computeUsage,
64
64
  createAIElement: () => createAIElement,
65
65
  createContext: () => createContext,
66
- createFunctionChain: () => createFunctionChain,
67
66
  createPrompt: () => createPrompt,
68
67
  createRenderContext: () => createRenderContext,
69
- createStreamChain: () => createStreamChain,
70
68
  evaluatePrompt: () => evaluatePrompt,
71
69
  openaiTokenizer: () => openaiTokenizer,
72
70
  toDebugMessage: () => toDebugMessage,
@@ -1326,7 +1324,6 @@ var StreamRenderContext = class _StreamRenderContext {
1326
1324
  this.logger = new BoundLogger(logImpl, this);
1327
1325
  this.render = this.render.bind(this);
1328
1326
  this.renderElement = async function* (renderable, opts = {}) {
1329
- const span = self.tracer.getActiveSpan();
1330
1327
  const preserveTags = opts.preserveTags ?? false;
1331
1328
  const renderedProps = opts.renderedProps || {};
1332
1329
  const renderEscaped = (val) => {
@@ -1386,64 +1383,63 @@ var StreamRenderContext = class _StreamRenderContext {
1386
1383
  renderElement;
1387
1384
  logger;
1388
1385
  // Implementation of the overloaded function
1389
- render(arg1, arg2, arg3) {
1390
- switch (true) {
1391
- case (isPromptParsed(arg1) && !!arg2): {
1392
- return this.tracer.trace(
1393
- "ai.prompt",
1394
- {
1395
- prompt: arg1,
1396
- promptKey: arg1.key,
1397
- variables: arg2
1398
- },
1399
- () => this.renderPromptParsed(arg1, arg2, arg3 || {})
1400
- );
1401
- }
1402
- case (isPrompt(arg1) && !!arg2): {
1403
- return this.tracer.trace(
1404
- "ai.prompt",
1405
- {
1406
- prompt: arg1,
1407
- promptKey: arg1.key,
1408
- variables: arg2
1409
- },
1410
- () => this.renderPrompt(arg1, arg2)
1411
- );
1412
- }
1413
- case (isFunctionChain(arg1) && !!arg2): {
1414
- return this.tracer.trace(
1415
- "ai.chain",
1416
- { chainKey: arg1.key, chainType: arg1.chainType, variables: arg2 },
1417
- () => this.runChain(arg1, arg2)
1418
- );
1419
- }
1420
- case (isStreamChain(arg1) && !!arg2): {
1421
- return this.tracer.trace(
1422
- "ai.chain",
1423
- { chainKey: arg1.key, chainType: arg1.chainType, variables: arg2 },
1424
- () => this.runChain(arg1, arg2)
1425
- );
1426
- }
1427
- default: {
1428
- const currentSpan = this.tracer.getActiveSpan();
1429
- const stream = this.renderElement(
1430
- arg1,
1431
- arg2 || { preserveTags: false }
1432
- );
1433
- if (currentSpan) {
1434
- return new GeneratorRenderResult(stream);
1386
+ render(toRender, options) {
1387
+ if (isPrompt(toRender)) {
1388
+ return this.tracer.trace(
1389
+ "ai.prompt",
1390
+ {
1391
+ prompt: toRender,
1392
+ promptKey: toRender.key,
1393
+ variables: options
1394
+ },
1395
+ () => this.renderPrompt(toRender, options)
1396
+ );
1397
+ }
1398
+ const currentSpan = this.tracer.getActiveSpan();
1399
+ const stream = this.renderElement(
1400
+ toRender,
1401
+ options || { preserveTags: false }
1402
+ );
1403
+ if (currentSpan) {
1404
+ return new GeneratorRenderResult(stream);
1405
+ }
1406
+ return this.tracer.trace(
1407
+ "ai.component",
1408
+ {},
1409
+ (span) => new AccumulatedRenderResult(stream, (output) => {
1410
+ span.setAttributes({
1411
+ output
1412
+ });
1413
+ })
1414
+ );
1415
+ }
1416
+ async renderPromptParsed(prompt, variables, options = { validateOutput: true }) {
1417
+ return this.tracer.trace(
1418
+ "ai.prompt",
1419
+ {
1420
+ prompt,
1421
+ promptKey: prompt.key,
1422
+ variables
1423
+ },
1424
+ async (span) => {
1425
+ const output = await this.renderPrompt(prompt, variables);
1426
+ const parsedOutput = prompt.parse(output);
1427
+ span?.setAttributes({
1428
+ output,
1429
+ parsedOutput
1430
+ });
1431
+ if (options.validateOutput) {
1432
+ try {
1433
+ prompt.outputSchema.parse(parsedOutput);
1434
+ } catch (e) {
1435
+ const err = e;
1436
+ const errors = JSON.stringify(err.flatten());
1437
+ throw new PromptInvalidOutputError("Invalid output: " + errors);
1438
+ }
1435
1439
  }
1436
- return this.tracer.trace(
1437
- "ai.component",
1438
- {},
1439
- (span) => new AccumulatedRenderResult(stream, (output) => {
1440
- span.setAttributes({
1441
- output
1442
- });
1443
- })
1444
- );
1440
+ return parsedOutput;
1445
1441
  }
1446
- }
1442
+ );
1447
1443
  }
1448
1444
  renderPrompt(prompt, variables) {
1449
1445
  const { schema, component: Component } = prompt;
@@ -1458,54 +1454,6 @@ var StreamRenderContext = class _StreamRenderContext {
1458
1454
  });
1459
1455
  });
1460
1456
  }
1461
- async renderPromptParsed(prompt, variables, options) {
1462
- const span = this.tracer.getActiveSpan();
1463
- const { validateOutput } = options;
1464
- const { schema, component: Component } = prompt;
1465
- const { error, parsedVariables } = parseVariables(schema, variables);
1466
- if (error) {
1467
- throw error;
1468
- }
1469
- const stream = this.renderElement(/* @__PURE__ */ jsx(Component, { ...parsedVariables }));
1470
- const output = await accumResults(stream);
1471
- const parsedOutput = prompt.parse(output);
1472
- span?.setAttributes({
1473
- output,
1474
- parsedOutput
1475
- });
1476
- if (validateOutput) {
1477
- try {
1478
- prompt.outputSchema.parse(parsedOutput);
1479
- } catch (e) {
1480
- const err = e;
1481
- const errors = JSON.stringify(err.flatten());
1482
- throw new PromptInvalidOutputError("Invalid output: " + errors);
1483
- }
1484
- }
1485
- return parsedOutput;
1486
- }
1487
- runChain(chain, variables) {
1488
- const { error, parsedVariables } = parseVariables(chain.schema, variables);
1489
- if (error) {
1490
- throw error;
1491
- }
1492
- if (chain.chainType === "function") {
1493
- const span = this.tracer.getActiveSpan();
1494
- const onOutput = (output) => {
1495
- span?.setAttributes({ output });
1496
- return output;
1497
- };
1498
- const result = chain.run(parsedVariables, this);
1499
- if (result && typeof result === "object" && "then" in result) {
1500
- return result.then(onOutput);
1501
- }
1502
- return onOutput(result);
1503
- }
1504
- if (chain.chainType === "stream") {
1505
- return chain.run(parsedVariables, this);
1506
- }
1507
- throw new Error("Invalid chain type");
1508
- }
1509
1457
  getContext = (context) => {
1510
1458
  return this.contextValues[context.key] ?? context.defaultValue;
1511
1459
  };
@@ -1568,19 +1516,6 @@ function attachedContextValues(element) {
1568
1516
  function isPrompt(value) {
1569
1517
  return Boolean(value && typeof value === "object" && "component" in value);
1570
1518
  }
1571
- function isPromptParsed(value) {
1572
- return Boolean(isPrompt(value) && "parse" in value);
1573
- }
1574
- function isStreamChain(value) {
1575
- return Boolean(
1576
- value && typeof value === "object" && "run" in value && "chainType" in value && value.chainType === "stream"
1577
- );
1578
- }
1579
- function isFunctionChain(value) {
1580
- return Boolean(
1581
- value && typeof value === "object" && "run" in value && "chainType" in value && value.chainType === "function"
1582
- );
1583
- }
1584
1519
  function renderOpenTag(element, renderedProps) {
1585
1520
  const propsToRender = Object.entries(element.props).reduce(
1586
1521
  // create an array of escaped + json serialized key="{value}"s for attributes
@@ -1648,6 +1583,99 @@ async function* Fallback({ shouldFallback = () => true, fallback, children }, ct
1648
1583
  }
1649
1584
  }
1650
1585
 
1586
+ // src/tracing/SpanTree.ts
1587
+ var SpanTree = class {
1588
+ roots = [];
1589
+ findSpan;
1590
+ addSpan(span) {
1591
+ const parentId = span.parentSpanId;
1592
+ if (!parentId) {
1593
+ this.roots.push(
1594
+ new SpanTreeNode(
1595
+ span.spanContext.spanId,
1596
+ span.name,
1597
+ null,
1598
+ [],
1599
+ span.attributes
1600
+ )
1601
+ );
1602
+ return true;
1603
+ }
1604
+ const parent = this.findNode(parentId);
1605
+ if (!parent) {
1606
+ return false;
1607
+ }
1608
+ parent.addChild(
1609
+ new SpanTreeNode(
1610
+ span.spanContext.spanId,
1611
+ span.name,
1612
+ parent,
1613
+ [],
1614
+ span.attributes
1615
+ )
1616
+ );
1617
+ return true;
1618
+ }
1619
+ findNode(id) {
1620
+ for (const root of this.roots) {
1621
+ const found = findSpanNode(root, id);
1622
+ if (found) {
1623
+ return found;
1624
+ }
1625
+ }
1626
+ return null;
1627
+ }
1628
+ };
1629
+ function findSpanNode(root, id) {
1630
+ if (root.id === id) {
1631
+ return root;
1632
+ }
1633
+ for (const child of root.children) {
1634
+ const found = findSpanNode(child, id);
1635
+ if (found) {
1636
+ return found;
1637
+ }
1638
+ }
1639
+ return null;
1640
+ }
1641
+ var SpanTreeNode = class {
1642
+ constructor(id, name, parent, children, attrs) {
1643
+ this.id = id;
1644
+ this.name = name;
1645
+ this.parent = parent;
1646
+ this.children = children;
1647
+ this.attrs = attrs;
1648
+ }
1649
+ addChild(child) {
1650
+ this.children.push(child);
1651
+ }
1652
+ getNearestAttribute(key) {
1653
+ return getNearestAttribute(this.parent, key);
1654
+ }
1655
+ getRootAttribute(key) {
1656
+ return getFarthestAttribute(this, key);
1657
+ }
1658
+ };
1659
+ var getNearestAttribute = (node, key) => {
1660
+ while (node) {
1661
+ if (key in node.attrs) {
1662
+ return node.attrs[key];
1663
+ }
1664
+ node = node.parent;
1665
+ }
1666
+ return null;
1667
+ };
1668
+ var getFarthestAttribute = (node, key) => {
1669
+ let found = null;
1670
+ while (node) {
1671
+ if (key in node.attrs) {
1672
+ found = node.attrs[key];
1673
+ }
1674
+ node = node.parent;
1675
+ }
1676
+ return found;
1677
+ };
1678
+
1651
1679
  // src/prompt/evaluatePrompt.ts
1652
1680
  async function evaluatePrompt(prompt, variables, result) {
1653
1681
  const { error, parsedVariables } = parseVariables(prompt.schema, variables);
@@ -1672,7 +1700,9 @@ var EnrichingSpanProcessor = class {
1672
1700
  finalSpans = [];
1673
1701
  onAllDonePromise = null;
1674
1702
  onAllDonePromiseResolve = null;
1703
+ spanTree = new SpanTree();
1675
1704
  async onStart(span) {
1705
+ this.spanTree.addSpan(span);
1676
1706
  this.finalSpans.push({
1677
1707
  status: "running",
1678
1708
  span
@@ -1717,7 +1747,29 @@ var AISpanProcessor = class extends EnrichingSpanProcessor {
1717
1747
  const result1 = await this.evaluatePrompt(span);
1718
1748
  const result2 = await this.updateCost(result1);
1719
1749
  const result3 = await this.updateUsage(result2);
1720
- return result3;
1750
+ const result4 = await this.addPromptKeys(result3);
1751
+ return result4;
1752
+ }
1753
+ async addPromptKeys(span) {
1754
+ if (!isChatCompletionSpan(span) && !isPromptSpan(span)) {
1755
+ return span;
1756
+ }
1757
+ const node = this.spanTree.findNode(span.spanContext.spanId);
1758
+ if (!node) {
1759
+ return span;
1760
+ }
1761
+ const extraAttributes = {
1762
+ parentPromptKey: node.getNearestAttribute("promptKey"),
1763
+ rootPromptKey: node.getRootAttribute("promptKey")
1764
+ };
1765
+ const final = {
1766
+ ...span,
1767
+ attributes: {
1768
+ ...span.attributes,
1769
+ ...extraAttributes
1770
+ }
1771
+ };
1772
+ return final;
1721
1773
  }
1722
1774
  async updateCost(span) {
1723
1775
  if (!isChatCompletionSpan(span)) {
@@ -1743,15 +1795,20 @@ var AISpanProcessor = class extends EnrichingSpanProcessor {
1743
1795
  return span;
1744
1796
  }
1745
1797
  async evaluatePrompt(span) {
1746
- const { prompt, variables, output } = span.attributes;
1747
- if (!isPrompt2(prompt)) {
1798
+ if (!isPrompt2(span.attributes.prompt)) {
1748
1799
  return span;
1749
1800
  }
1801
+ const { prompt, variables, output, parsedOutput } = span.attributes;
1750
1802
  delete span.attributes["prompt"];
1803
+ const outputToEvaluate = isPromptParsed(prompt) ? parsedOutput : output;
1751
1804
  let evaluatorResults = {};
1752
1805
  let extraAttributes = {};
1753
1806
  try {
1754
- const evaluators = await evaluatePrompt(prompt, variables, output);
1807
+ const evaluators = await evaluatePrompt(
1808
+ prompt,
1809
+ variables,
1810
+ outputToEvaluate
1811
+ );
1755
1812
  evaluatorResults = evaluators.reduce(
1756
1813
  (accum, result) => {
1757
1814
  accum[result.key] = result;
@@ -1783,11 +1840,19 @@ var isChatCompletionSpan = (value) => {
1783
1840
  value && typeof value == "object" && "name" in value && value.name === "ai.chatCompletion"
1784
1841
  );
1785
1842
  };
1843
+ var isPromptSpan = (value) => {
1844
+ return Boolean(
1845
+ value && typeof value == "object" && "name" in value && value.name === "ai.prompt"
1846
+ );
1847
+ };
1786
1848
  var isPrompt2 = (value) => {
1787
1849
  return Boolean(
1788
1850
  value && typeof value == "object" && "schema" in value && "evaluators" in value
1789
1851
  );
1790
1852
  };
1853
+ function isPromptParsed(value) {
1854
+ return Boolean(isPrompt2(value) && "parse" in value);
1855
+ }
1791
1856
 
1792
1857
  // src/tracing/Trace.tsx
1793
1858
  var Trace = ({ name, attributes, children }, { tracer, render }) => {
@@ -1814,7 +1879,6 @@ function createPrompt(config) {
1814
1879
  component: component2,
1815
1880
  parse: outputParser.parse,
1816
1881
  outputSchema: outputParser.schema,
1817
- messageSchema: null,
1818
1882
  schema: schema2,
1819
1883
  metadata: metadata2,
1820
1884
  evaluators: evaluators2
@@ -1827,37 +1891,10 @@ function createPrompt(config) {
1827
1891
  schema,
1828
1892
  metadata,
1829
1893
  evaluators,
1830
- messageSchema: import_zod.z.string(),
1831
1894
  outputSchema: import_zod.z.string()
1832
1895
  };
1833
1896
  }
1834
1897
 
1835
- // src/prompt/createChain.ts
1836
- var import_zod2 = require("zod");
1837
- function createFunctionChain(chain) {
1838
- const { key, run, schema, outputSchema = import_zod2.z.any() } = chain;
1839
- return {
1840
- chainType: "function",
1841
- key,
1842
- schema,
1843
- messageSchema: null,
1844
- outputSchema,
1845
- // always make it async so RenderContext doesnt have a to guess
1846
- run
1847
- };
1848
- }
1849
- function createStreamChain(chain) {
1850
- const { key, run, messageSchema = import_zod2.z.any(), schema } = chain;
1851
- return {
1852
- chainType: "stream",
1853
- key,
1854
- schema,
1855
- run,
1856
- outputSchema: null,
1857
- messageSchema
1858
- };
1859
- }
1860
-
1861
1898
  // src/lib/openai/OpenAI.tsx
1862
1899
  var import_openai2 = require("openai");
1863
1900
 
@@ -2860,10 +2897,8 @@ var import_vertexai2 = require("@google-cloud/vertexai");
2860
2897
  computeUsage,
2861
2898
  createAIElement,
2862
2899
  createContext,
2863
- createFunctionChain,
2864
2900
  createPrompt,
2865
2901
  createRenderContext,
2866
- createStreamChain,
2867
2902
  evaluatePrompt,
2868
2903
  openaiTokenizer,
2869
2904
  toDebugMessage,
package/dist/index.mjs CHANGED
@@ -1225,7 +1225,6 @@ var StreamRenderContext = class _StreamRenderContext {
1225
1225
  this.logger = new BoundLogger(logImpl, this);
1226
1226
  this.render = this.render.bind(this);
1227
1227
  this.renderElement = async function* (renderable, opts = {}) {
1228
- const span = self.tracer.getActiveSpan();
1229
1228
  const preserveTags = opts.preserveTags ?? false;
1230
1229
  const renderedProps = opts.renderedProps || {};
1231
1230
  const renderEscaped = (val) => {
@@ -1285,64 +1284,63 @@ var StreamRenderContext = class _StreamRenderContext {
1285
1284
  renderElement;
1286
1285
  logger;
1287
1286
  // Implementation of the overloaded function
1288
- render(arg1, arg2, arg3) {
1289
- switch (true) {
1290
- case (isPromptParsed(arg1) && !!arg2): {
1291
- return this.tracer.trace(
1292
- "ai.prompt",
1293
- {
1294
- prompt: arg1,
1295
- promptKey: arg1.key,
1296
- variables: arg2
1297
- },
1298
- () => this.renderPromptParsed(arg1, arg2, arg3 || {})
1299
- );
1300
- }
1301
- case (isPrompt(arg1) && !!arg2): {
1302
- return this.tracer.trace(
1303
- "ai.prompt",
1304
- {
1305
- prompt: arg1,
1306
- promptKey: arg1.key,
1307
- variables: arg2
1308
- },
1309
- () => this.renderPrompt(arg1, arg2)
1310
- );
1311
- }
1312
- case (isFunctionChain(arg1) && !!arg2): {
1313
- return this.tracer.trace(
1314
- "ai.chain",
1315
- { chainKey: arg1.key, chainType: arg1.chainType, variables: arg2 },
1316
- () => this.runChain(arg1, arg2)
1317
- );
1318
- }
1319
- case (isStreamChain(arg1) && !!arg2): {
1320
- return this.tracer.trace(
1321
- "ai.chain",
1322
- { chainKey: arg1.key, chainType: arg1.chainType, variables: arg2 },
1323
- () => this.runChain(arg1, arg2)
1324
- );
1325
- }
1326
- default: {
1327
- const currentSpan = this.tracer.getActiveSpan();
1328
- const stream = this.renderElement(
1329
- arg1,
1330
- arg2 || { preserveTags: false }
1331
- );
1332
- if (currentSpan) {
1333
- return new GeneratorRenderResult(stream);
1287
+ render(toRender, options) {
1288
+ if (isPrompt(toRender)) {
1289
+ return this.tracer.trace(
1290
+ "ai.prompt",
1291
+ {
1292
+ prompt: toRender,
1293
+ promptKey: toRender.key,
1294
+ variables: options
1295
+ },
1296
+ () => this.renderPrompt(toRender, options)
1297
+ );
1298
+ }
1299
+ const currentSpan = this.tracer.getActiveSpan();
1300
+ const stream = this.renderElement(
1301
+ toRender,
1302
+ options || { preserveTags: false }
1303
+ );
1304
+ if (currentSpan) {
1305
+ return new GeneratorRenderResult(stream);
1306
+ }
1307
+ return this.tracer.trace(
1308
+ "ai.component",
1309
+ {},
1310
+ (span) => new AccumulatedRenderResult(stream, (output) => {
1311
+ span.setAttributes({
1312
+ output
1313
+ });
1314
+ })
1315
+ );
1316
+ }
1317
+ async renderPromptParsed(prompt, variables, options = { validateOutput: true }) {
1318
+ return this.tracer.trace(
1319
+ "ai.prompt",
1320
+ {
1321
+ prompt,
1322
+ promptKey: prompt.key,
1323
+ variables
1324
+ },
1325
+ async (span) => {
1326
+ const output = await this.renderPrompt(prompt, variables);
1327
+ const parsedOutput = prompt.parse(output);
1328
+ span?.setAttributes({
1329
+ output,
1330
+ parsedOutput
1331
+ });
1332
+ if (options.validateOutput) {
1333
+ try {
1334
+ prompt.outputSchema.parse(parsedOutput);
1335
+ } catch (e) {
1336
+ const err = e;
1337
+ const errors = JSON.stringify(err.flatten());
1338
+ throw new PromptInvalidOutputError("Invalid output: " + errors);
1339
+ }
1334
1340
  }
1335
- return this.tracer.trace(
1336
- "ai.component",
1337
- {},
1338
- (span) => new AccumulatedRenderResult(stream, (output) => {
1339
- span.setAttributes({
1340
- output
1341
- });
1342
- })
1343
- );
1341
+ return parsedOutput;
1344
1342
  }
1345
- }
1343
+ );
1346
1344
  }
1347
1345
  renderPrompt(prompt, variables) {
1348
1346
  const { schema, component: Component } = prompt;
@@ -1357,54 +1355,6 @@ var StreamRenderContext = class _StreamRenderContext {
1357
1355
  });
1358
1356
  });
1359
1357
  }
1360
- async renderPromptParsed(prompt, variables, options) {
1361
- const span = this.tracer.getActiveSpan();
1362
- const { validateOutput } = options;
1363
- const { schema, component: Component } = prompt;
1364
- const { error, parsedVariables } = parseVariables(schema, variables);
1365
- if (error) {
1366
- throw error;
1367
- }
1368
- const stream = this.renderElement(/* @__PURE__ */ jsx(Component, { ...parsedVariables }));
1369
- const output = await accumResults(stream);
1370
- const parsedOutput = prompt.parse(output);
1371
- span?.setAttributes({
1372
- output,
1373
- parsedOutput
1374
- });
1375
- if (validateOutput) {
1376
- try {
1377
- prompt.outputSchema.parse(parsedOutput);
1378
- } catch (e) {
1379
- const err = e;
1380
- const errors = JSON.stringify(err.flatten());
1381
- throw new PromptInvalidOutputError("Invalid output: " + errors);
1382
- }
1383
- }
1384
- return parsedOutput;
1385
- }
1386
- runChain(chain, variables) {
1387
- const { error, parsedVariables } = parseVariables(chain.schema, variables);
1388
- if (error) {
1389
- throw error;
1390
- }
1391
- if (chain.chainType === "function") {
1392
- const span = this.tracer.getActiveSpan();
1393
- const onOutput = (output) => {
1394
- span?.setAttributes({ output });
1395
- return output;
1396
- };
1397
- const result = chain.run(parsedVariables, this);
1398
- if (result && typeof result === "object" && "then" in result) {
1399
- return result.then(onOutput);
1400
- }
1401
- return onOutput(result);
1402
- }
1403
- if (chain.chainType === "stream") {
1404
- return chain.run(parsedVariables, this);
1405
- }
1406
- throw new Error("Invalid chain type");
1407
- }
1408
1358
  getContext = (context) => {
1409
1359
  return this.contextValues[context.key] ?? context.defaultValue;
1410
1360
  };
@@ -1467,19 +1417,6 @@ function attachedContextValues(element) {
1467
1417
  function isPrompt(value) {
1468
1418
  return Boolean(value && typeof value === "object" && "component" in value);
1469
1419
  }
1470
- function isPromptParsed(value) {
1471
- return Boolean(isPrompt(value) && "parse" in value);
1472
- }
1473
- function isStreamChain(value) {
1474
- return Boolean(
1475
- value && typeof value === "object" && "run" in value && "chainType" in value && value.chainType === "stream"
1476
- );
1477
- }
1478
- function isFunctionChain(value) {
1479
- return Boolean(
1480
- value && typeof value === "object" && "run" in value && "chainType" in value && value.chainType === "function"
1481
- );
1482
- }
1483
1420
  function renderOpenTag(element, renderedProps) {
1484
1421
  const propsToRender = Object.entries(element.props).reduce(
1485
1422
  // create an array of escaped + json serialized key="{value}"s for attributes
@@ -1547,6 +1484,99 @@ async function* Fallback({ shouldFallback = () => true, fallback, children }, ct
1547
1484
  }
1548
1485
  }
1549
1486
 
1487
+ // src/tracing/SpanTree.ts
1488
+ var SpanTree = class {
1489
+ roots = [];
1490
+ findSpan;
1491
+ addSpan(span) {
1492
+ const parentId = span.parentSpanId;
1493
+ if (!parentId) {
1494
+ this.roots.push(
1495
+ new SpanTreeNode(
1496
+ span.spanContext.spanId,
1497
+ span.name,
1498
+ null,
1499
+ [],
1500
+ span.attributes
1501
+ )
1502
+ );
1503
+ return true;
1504
+ }
1505
+ const parent = this.findNode(parentId);
1506
+ if (!parent) {
1507
+ return false;
1508
+ }
1509
+ parent.addChild(
1510
+ new SpanTreeNode(
1511
+ span.spanContext.spanId,
1512
+ span.name,
1513
+ parent,
1514
+ [],
1515
+ span.attributes
1516
+ )
1517
+ );
1518
+ return true;
1519
+ }
1520
+ findNode(id) {
1521
+ for (const root of this.roots) {
1522
+ const found = findSpanNode(root, id);
1523
+ if (found) {
1524
+ return found;
1525
+ }
1526
+ }
1527
+ return null;
1528
+ }
1529
+ };
1530
+ function findSpanNode(root, id) {
1531
+ if (root.id === id) {
1532
+ return root;
1533
+ }
1534
+ for (const child of root.children) {
1535
+ const found = findSpanNode(child, id);
1536
+ if (found) {
1537
+ return found;
1538
+ }
1539
+ }
1540
+ return null;
1541
+ }
1542
+ var SpanTreeNode = class {
1543
+ constructor(id, name, parent, children, attrs) {
1544
+ this.id = id;
1545
+ this.name = name;
1546
+ this.parent = parent;
1547
+ this.children = children;
1548
+ this.attrs = attrs;
1549
+ }
1550
+ addChild(child) {
1551
+ this.children.push(child);
1552
+ }
1553
+ getNearestAttribute(key) {
1554
+ return getNearestAttribute(this.parent, key);
1555
+ }
1556
+ getRootAttribute(key) {
1557
+ return getFarthestAttribute(this, key);
1558
+ }
1559
+ };
1560
+ var getNearestAttribute = (node, key) => {
1561
+ while (node) {
1562
+ if (key in node.attrs) {
1563
+ return node.attrs[key];
1564
+ }
1565
+ node = node.parent;
1566
+ }
1567
+ return null;
1568
+ };
1569
+ var getFarthestAttribute = (node, key) => {
1570
+ let found = null;
1571
+ while (node) {
1572
+ if (key in node.attrs) {
1573
+ found = node.attrs[key];
1574
+ }
1575
+ node = node.parent;
1576
+ }
1577
+ return found;
1578
+ };
1579
+
1550
1580
  // src/prompt/evaluatePrompt.ts
1551
1581
  async function evaluatePrompt(prompt, variables, result) {
1552
1582
  const { error, parsedVariables } = parseVariables(prompt.schema, variables);
@@ -1571,7 +1601,9 @@ var EnrichingSpanProcessor = class {
1571
1601
  finalSpans = [];
1572
1602
  onAllDonePromise = null;
1573
1603
  onAllDonePromiseResolve = null;
1604
+ spanTree = new SpanTree();
1574
1605
  async onStart(span) {
1606
+ this.spanTree.addSpan(span);
1575
1607
  this.finalSpans.push({
1576
1608
  status: "running",
1577
1609
  span
@@ -1616,7 +1648,29 @@ var AISpanProcessor = class extends EnrichingSpanProcessor {
1616
1648
  const result1 = await this.evaluatePrompt(span);
1617
1649
  const result2 = await this.updateCost(result1);
1618
1650
  const result3 = await this.updateUsage(result2);
1619
- return result3;
1651
+ const result4 = await this.addPromptKeys(result3);
1652
+ return result4;
1653
+ }
1654
+ async addPromptKeys(span) {
1655
+ if (!isChatCompletionSpan(span) && !isPromptSpan(span)) {
1656
+ return span;
1657
+ }
1658
+ const node = this.spanTree.findNode(span.spanContext.spanId);
1659
+ if (!node) {
1660
+ return span;
1661
+ }
1662
+ const extraAttributes = {
1663
+ parentPromptKey: node.getNearestAttribute("promptKey"),
1664
+ rootPromptKey: node.getRootAttribute("promptKey")
1665
+ };
1666
+ const final = {
1667
+ ...span,
1668
+ attributes: {
1669
+ ...span.attributes,
1670
+ ...extraAttributes
1671
+ }
1672
+ };
1673
+ return final;
1620
1674
  }
1621
1675
  async updateCost(span) {
1622
1676
  if (!isChatCompletionSpan(span)) {
@@ -1642,15 +1696,20 @@ var AISpanProcessor = class extends EnrichingSpanProcessor {
1642
1696
  return span;
1643
1697
  }
1644
1698
  async evaluatePrompt(span) {
1645
- const { prompt, variables, output } = span.attributes;
1646
- if (!isPrompt2(prompt)) {
1699
+ if (!isPrompt2(span.attributes.prompt)) {
1647
1700
  return span;
1648
1701
  }
1702
+ const { prompt, variables, output, parsedOutput } = span.attributes;
1649
1703
  delete span.attributes["prompt"];
1704
+ const outputToEvaluate = isPromptParsed(prompt) ? parsedOutput : output;
1650
1705
  let evaluatorResults = {};
1651
1706
  let extraAttributes = {};
1652
1707
  try {
1653
- const evaluators = await evaluatePrompt(prompt, variables, output);
1708
+ const evaluators = await evaluatePrompt(
1709
+ prompt,
1710
+ variables,
1711
+ outputToEvaluate
1712
+ );
1654
1713
  evaluatorResults = evaluators.reduce(
1655
1714
  (accum, result) => {
1656
1715
  accum[result.key] = result;
@@ -1682,11 +1741,19 @@ var isChatCompletionSpan = (value) => {
1682
1741
  value && typeof value == "object" && "name" in value && value.name === "ai.chatCompletion"
1683
1742
  );
1684
1743
  };
1744
+ var isPromptSpan = (value) => {
1745
+ return Boolean(
1746
+ value && typeof value == "object" && "name" in value && value.name === "ai.prompt"
1747
+ );
1748
+ };
1685
1749
  var isPrompt2 = (value) => {
1686
1750
  return Boolean(
1687
1751
  value && typeof value == "object" && "schema" in value && "evaluators" in value
1688
1752
  );
1689
1753
  };
1754
+ function isPromptParsed(value) {
1755
+ return Boolean(isPrompt2(value) && "parse" in value);
1756
+ }
1690
1757
 
1691
1758
  // src/tracing/Trace.tsx
1692
1759
  var Trace = ({ name, attributes, children }, { tracer, render }) => {
@@ -1713,7 +1780,6 @@ function createPrompt(config) {
1713
1780
  component: component2,
1714
1781
  parse: outputParser.parse,
1715
1782
  outputSchema: outputParser.schema,
1716
- messageSchema: null,
1717
1783
  schema: schema2,
1718
1784
  metadata: metadata2,
1719
1785
  evaluators: evaluators2
@@ -1726,37 +1792,10 @@ function createPrompt(config) {
1726
1792
  schema,
1727
1793
  metadata,
1728
1794
  evaluators,
1729
- messageSchema: z.string(),
1730
1795
  outputSchema: z.string()
1731
1796
  };
1732
1797
  }
1733
1798
 
1734
- // src/prompt/createChain.ts
1735
- import { z as z2 } from "zod";
1736
- function createFunctionChain(chain) {
1737
- const { key, run, schema, outputSchema = z2.any() } = chain;
1738
- return {
1739
- chainType: "function",
1740
- key,
1741
- schema,
1742
- messageSchema: null,
1743
- outputSchema,
1744
- // always make it async so RenderContext doesnt have a to guess
1745
- run
1746
- };
1747
- }
1748
- function createStreamChain(chain) {
1749
- const { key, run, messageSchema = z2.any(), schema } = chain;
1750
- return {
1751
- chainType: "stream",
1752
- key,
1753
- schema,
1754
- run,
1755
- outputSchema: null,
1756
- messageSchema
1757
- };
1758
- }
1759
-
1760
1799
  // src/lib/openai/OpenAI.tsx
1761
1800
  import { OpenAI as OpenAIClient2 } from "openai";
1762
1801
 
@@ -2763,10 +2802,8 @@ export {
2763
2802
  computeUsage,
2764
2803
  createAIElement,
2765
2804
  createContext,
2766
- createFunctionChain,
2767
2805
  createPrompt,
2768
2806
  createRenderContext,
2769
- createStreamChain,
2770
2807
  evaluatePrompt,
2771
2808
  openaiTokenizer,
2772
2809
  toDebugMessage,
@@ -103,33 +103,13 @@ interface Prompt<V extends Record<string, any> = Record<string, any>> {
103
103
  component: AIComponent<V>;
104
104
  schema: ZodObject<ZodRawShape>;
105
105
  evaluators: EvaluatorFn<V>[];
106
- messageSchema: ZodTypeAny | null;
107
106
  outputSchema: ZodTypeAny;
108
107
  metadata: Record<string, any>;
109
108
  }
110
109
  interface PromptParsed<V extends Record<string, any> = Record<string, any>, O = any> extends Prompt<V> {
111
110
  evaluators: EvaluatorFn<V, O>[];
112
- messageSchema: null;
113
111
  parse: (result: string) => O;
114
112
  }
115
- interface FunctionChain<V extends Record<string, any> = Record<string, any>, R extends NotAsyncGenerator<any> = any> {
116
- key: string;
117
- chainType: 'function';
118
- run: (vars: V, context: RenderContext) => R;
119
- schema: ZodObject<ZodRawShape>;
120
- messageSchema: null;
121
- outputSchema: ZodTypeAny;
122
- }
123
- interface StreamChain<V extends Record<string, any> = Record<string, any>, R extends AsyncGenerator<any, any, any> = AsyncGenerator<any, any, any>> {
124
- key: string;
125
- chainType: 'stream';
126
- run: (vars: V, context: RenderContext) => R;
127
- schema: ZodObject<ZodRawShape>;
128
- messageSchema: ZodTypeAny;
129
- outputSchema: null;
130
- }
131
- type IsAsyncGenerator<T> = T extends AsyncGenerator<any, any, any> ? true : false;
132
- type NotAsyncGenerator<T> = IsAsyncGenerator<T> extends true ? never : T;
133
113
 
134
114
  type SpanContext = {
135
115
  traceId: string;
@@ -254,10 +234,8 @@ interface RenderContext {
254
234
  logger: Logger;
255
235
  getContext<T>(context: Context<T>): T;
256
236
  render(renderable: Renderable, opts?: RenderOptions): RenderResult;
257
- render<V extends Record<string, any>, O>(prompt: PromptParsed<V, O>, variables: V, options?: RenderPromptOptions): Promise<O>;
258
237
  render<V extends Record<string, any>>(prompt: Prompt<V>, variables: V): RenderResult;
259
- render<V extends Record<string, any>, O extends AsyncGenerator<any>>(chain: StreamChain<V, O>, variables: V): AsyncGenerator<O, void>;
260
- render<V extends Record<string, any>, O>(chain: FunctionChain<V, O>, variables: V): O;
238
+ renderPromptParsed<V extends Record<string, any>, O>(prompt: PromptParsed<V, O>, variables: V, options?: RenderPromptOptions): Promise<O>;
261
239
  }
262
240
  type RenderPromptOptions = {
263
241
  validateOutput?: boolean;
@@ -376,4 +354,4 @@ declare const jsxs: typeof jsx;
376
354
  /** @hidden */
377
355
  declare const Fragment: typeof AIFragment;
378
356
 
379
- export { jsxs as $, type AINode as A, BoundLogger as B, type ChatMessage as C, type DebugMessage as D, type EvaluatorResult as E, type FunctionChain as F, type AIElement as G, type Renderable as H, ImagePart as I, JSX as J, type PropsOfAIComponent as K, type LogChatCompletionRequest as L, type SpanContext as M, type NotAsyncGenerator as N, type SpanStatus as O, type Prompt as P, type Span as Q, type RenderContext as R, type SpanProcessor as S, type Tracer as T, type SpanEvent as U, type TracingContextKey as V, type TracingContext as W, type TracingContextManager as X, type OutputParser as Y, jsx as Z, jsxDEV as _, LogImplementation as a, Fragment as a0, type ContextValues as b, type Context as c, type ReadableSpan as d, type SpanExporter as e, type AIComponent as f, type SpanAttributes as g, type ChatCompletionRequestPayloads as h, type EvaluatorFn as i, type PromptParsed as j, type StreamChain as k, createAIElement as l, AIFragment as m, createContext as n, type ChatRole as o, type ImagePartProps as p, type LogChatCompletionResponse as q, type LogLevel as r, type Logger as s, toDebugMessage as t, NoopLogImplementation as u, ConsoleLogger as v, CombinedLogger as w, type Literal as x, type RenderResult as y, attachedContextSymbol as z };
357
+ export { type AINode as A, BoundLogger as B, type ChatMessage as C, type DebugMessage as D, type EvaluatorResult as E, type PropsOfAIComponent as F, type SpanContext as G, type SpanStatus as H, ImagePart as I, JSX as J, type Span as K, type LogChatCompletionRequest as L, type SpanEvent as M, NoopLogImplementation as N, type TracingContextKey as O, type Prompt as P, type TracingContext as Q, type RenderContext as R, type SpanProcessor as S, type Tracer as T, type TracingContextManager as U, type OutputParser as V, jsx as W, jsxDEV as X, jsxs as Y, Fragment as Z, LogImplementation as a, type ContextValues as b, type Context as c, type ReadableSpan as d, type SpanExporter as e, type AIComponent as f, type SpanAttributes as g, type ChatCompletionRequestPayloads as h, type EvaluatorFn as i, type PromptParsed as j, createAIElement as k, AIFragment as l, createContext as m, type ChatRole as n, type ImagePartProps as o, type LogChatCompletionResponse as p, type LogLevel as q, type Logger as r, ConsoleLogger as s, toDebugMessage as t, CombinedLogger as u, type Literal as v, type RenderResult as w, attachedContextSymbol as x, type AIElement as y, type Renderable as z };
@@ -103,33 +103,13 @@ interface Prompt<V extends Record<string, any> = Record<string, any>> {
103
103
  component: AIComponent<V>;
104
104
  schema: ZodObject<ZodRawShape>;
105
105
  evaluators: EvaluatorFn<V>[];
106
- messageSchema: ZodTypeAny | null;
107
106
  outputSchema: ZodTypeAny;
108
107
  metadata: Record<string, any>;
109
108
  }
110
109
  interface PromptParsed<V extends Record<string, any> = Record<string, any>, O = any> extends Prompt<V> {
111
110
  evaluators: EvaluatorFn<V, O>[];
112
- messageSchema: null;
113
111
  parse: (result: string) => O;
114
112
  }
115
- interface FunctionChain<V extends Record<string, any> = Record<string, any>, R extends NotAsyncGenerator<any> = any> {
116
- key: string;
117
- chainType: 'function';
118
- run: (vars: V, context: RenderContext) => R;
119
- schema: ZodObject<ZodRawShape>;
120
- messageSchema: null;
121
- outputSchema: ZodTypeAny;
122
- }
123
- interface StreamChain<V extends Record<string, any> = Record<string, any>, R extends AsyncGenerator<any, any, any> = AsyncGenerator<any, any, any>> {
124
- key: string;
125
- chainType: 'stream';
126
- run: (vars: V, context: RenderContext) => R;
127
- schema: ZodObject<ZodRawShape>;
128
- messageSchema: ZodTypeAny;
129
- outputSchema: null;
130
- }
131
- type IsAsyncGenerator<T> = T extends AsyncGenerator<any, any, any> ? true : false;
132
- type NotAsyncGenerator<T> = IsAsyncGenerator<T> extends true ? never : T;
133
113
 
134
114
  type SpanContext = {
135
115
  traceId: string;
@@ -254,10 +234,8 @@ interface RenderContext {
254
234
  logger: Logger;
255
235
  getContext<T>(context: Context<T>): T;
256
236
  render(renderable: Renderable, opts?: RenderOptions): RenderResult;
257
- render<V extends Record<string, any>, O>(prompt: PromptParsed<V, O>, variables: V, options?: RenderPromptOptions): Promise<O>;
258
237
  render<V extends Record<string, any>>(prompt: Prompt<V>, variables: V): RenderResult;
259
- render<V extends Record<string, any>, O extends AsyncGenerator<any>>(chain: StreamChain<V, O>, variables: V): AsyncGenerator<O, void>;
260
- render<V extends Record<string, any>, O>(chain: FunctionChain<V, O>, variables: V): O;
238
+ renderPromptParsed<V extends Record<string, any>, O>(prompt: PromptParsed<V, O>, variables: V, options?: RenderPromptOptions): Promise<O>;
261
239
  }
262
240
  type RenderPromptOptions = {
263
241
  validateOutput?: boolean;
@@ -376,4 +354,4 @@ declare const jsxs: typeof jsx;
376
354
  /** @hidden */
377
355
  declare const Fragment: typeof AIFragment;
378
356
 
379
- export { jsxs as $, type AINode as A, BoundLogger as B, type ChatMessage as C, type DebugMessage as D, type EvaluatorResult as E, type FunctionChain as F, type AIElement as G, type Renderable as H, ImagePart as I, JSX as J, type PropsOfAIComponent as K, type LogChatCompletionRequest as L, type SpanContext as M, type NotAsyncGenerator as N, type SpanStatus as O, type Prompt as P, type Span as Q, type RenderContext as R, type SpanProcessor as S, type Tracer as T, type SpanEvent as U, type TracingContextKey as V, type TracingContext as W, type TracingContextManager as X, type OutputParser as Y, jsx as Z, jsxDEV as _, LogImplementation as a, Fragment as a0, type ContextValues as b, type Context as c, type ReadableSpan as d, type SpanExporter as e, type AIComponent as f, type SpanAttributes as g, type ChatCompletionRequestPayloads as h, type EvaluatorFn as i, type PromptParsed as j, type StreamChain as k, createAIElement as l, AIFragment as m, createContext as n, type ChatRole as o, type ImagePartProps as p, type LogChatCompletionResponse as q, type LogLevel as r, type Logger as s, toDebugMessage as t, NoopLogImplementation as u, ConsoleLogger as v, CombinedLogger as w, type Literal as x, type RenderResult as y, attachedContextSymbol as z };
357
+ export { type AINode as A, BoundLogger as B, type ChatMessage as C, type DebugMessage as D, type EvaluatorResult as E, type PropsOfAIComponent as F, type SpanContext as G, type SpanStatus as H, ImagePart as I, JSX as J, type Span as K, type LogChatCompletionRequest as L, type SpanEvent as M, NoopLogImplementation as N, type TracingContextKey as O, type Prompt as P, type TracingContext as Q, type RenderContext as R, type SpanProcessor as S, type Tracer as T, type TracingContextManager as U, type OutputParser as V, jsx as W, jsxDEV as X, jsxs as Y, Fragment as Z, LogImplementation as a, type ContextValues as b, type Context as c, type ReadableSpan as d, type SpanExporter as e, type AIComponent as f, type SpanAttributes as g, type ChatCompletionRequestPayloads as h, type EvaluatorFn as i, type PromptParsed as j, createAIElement as k, AIFragment as l, createContext as m, type ChatRole as n, type ImagePartProps as o, type LogChatCompletionResponse as p, type LogLevel as q, type Logger as r, ConsoleLogger as s, toDebugMessage as t, CombinedLogger as u, type Literal as v, type RenderResult as w, attachedContextSymbol as x, type AIElement as y, type Renderable as z };
@@ -1,2 +1,2 @@
1
- export { a0 as Fragment, J as JSX, Z as jsx, _ as jsxDEV, $ as jsxs } from './jsx-dev-runtime-uCZBuaDe.mjs';
1
+ export { Z as Fragment, J as JSX, W as jsx, X as jsxDEV, Y as jsxs } from './jsx-dev-runtime-vXV-PExh.mjs';
2
2
  import 'zod';
@@ -1,2 +1,2 @@
1
- export { a0 as Fragment, J as JSX, Z as jsx, _ as jsxDEV, $ as jsxs } from './jsx-dev-runtime-uCZBuaDe.js';
1
+ export { Z as Fragment, J as JSX, W as jsx, X as jsxDEV, Y as jsxs } from './jsx-dev-runtime-vXV-PExh.js';
2
2
  import 'zod';
@@ -1,2 +1,2 @@
1
- export { a0 as Fragment, J as JSX, Z as jsx, _ as jsxDEV, $ as jsxs } from './jsx-dev-runtime-uCZBuaDe.mjs';
1
+ export { Z as Fragment, J as JSX, W as jsx, X as jsxDEV, Y as jsxs } from './jsx-dev-runtime-vXV-PExh.mjs';
2
2
  import 'zod';
@@ -1,2 +1,2 @@
1
- export { a0 as Fragment, J as JSX, Z as jsx, _ as jsxDEV, $ as jsxs } from './jsx-dev-runtime-uCZBuaDe.js';
1
+ export { Z as Fragment, J as JSX, W as jsx, X as jsxDEV, Y as jsxs } from './jsx-dev-runtime-vXV-PExh.js';
2
2
  import 'zod';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gammatech/aijsx",
3
- "version": "0.9.3-dev.2024-05-31",
3
+ "version": "0.10.0-dev.2024-06-04",
4
4
  "description": "Rewrite of aijsx",
5
5
  "author": "Jordan Garcia",
6
6
  "license": "MIT",