Skip to content

Commit 638baff

Browse files
committed
Adding ai.tool and removing toolTask, 3rd party telemetry spans now wil create partials, better ai SDK telemetry icons
1 parent 5c7cab8 commit 638baff

File tree

16 files changed

+307
-201
lines changed

16 files changed

+307
-201
lines changed

.vscode/launch.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,14 @@
149149
"command": "pnpm run test ./src/run-queue/index.test.ts",
150150
"cwd": "${workspaceFolder}/internal-packages/run-engine",
151151
"sourceMaps": true
152+
},
153+
{
154+
"type": "node-terminal",
155+
"request": "launch",
156+
"name": "Debug d3-demo",
157+
"command": "pnpm exec trigger dev",
158+
"cwd": "${workspaceFolder}/references/d3-demo",
159+
"sourceMaps": true
152160
}
153161
]
154162
}

apps/webapp/app/v3/otlpExporter.server.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class OTLPExporter {
5757

5858
const enrichedEvents = enrichCreatableEvents(events);
5959

60-
this.#logEventsVerbose(enrichedEvents);
60+
this.#logEventsVerbose(enrichedEvents, "exportTraces");
6161

6262
span.setAttribute("event_count", enrichedEvents.length);
6363

@@ -84,7 +84,7 @@ class OTLPExporter {
8484

8585
const enrichedEvents = enrichCreatableEvents(events);
8686

87-
this.#logEventsVerbose(enrichedEvents);
87+
this.#logEventsVerbose(enrichedEvents, "exportLogs");
8888

8989
span.setAttribute("event_count", enrichedEvents.length);
9090

@@ -98,11 +98,11 @@ class OTLPExporter {
9898
});
9999
}
100100

101-
#logEventsVerbose(events: CreatableEvent[]) {
101+
#logEventsVerbose(events: CreatableEvent[], prefix: string) {
102102
if (!this._verbose) return;
103103

104104
events.forEach((event) => {
105-
logger.debug("Exporting event", { event });
105+
logger.debug(`Exporting ${prefix} event`, { event });
106106
});
107107
}
108108

apps/webapp/app/v3/utils/enrichCreatableEvents.server.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function enrichStyle(event: CreatableEvent) {
2323
// GenAI System check
2424
const system = props["gen_ai.system"];
2525
if (typeof system === "string") {
26-
return { ...baseStyle, icon: `tabler-brand-${system}` };
26+
return { ...baseStyle, icon: `tabler-brand-${system.split(".")[0]}` };
2727
}
2828

2929
// Agent workflow check
@@ -32,6 +32,16 @@ function enrichStyle(event: CreatableEvent) {
3232
return { ...baseStyle, icon: "tabler-brain" };
3333
}
3434

35+
const message = event.message;
36+
37+
if (typeof message === "string" && message === "ai.toolCall") {
38+
return { ...baseStyle, icon: "tabler-tool" };
39+
}
40+
41+
if (typeof message === "string" && message.startsWith("ai.")) {
42+
return { ...baseStyle, icon: "tabler-sparkles" };
43+
}
44+
3545
return baseStyle;
3646
}
3747

apps/webapp/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,4 +258,4 @@
258258
"engines": {
259259
"node": ">=16.0.0"
260260
}
261-
}
261+
}

packages/cli-v3/src/entryPoints/dev-run-worker.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,8 @@ const zodIpc = new ZodIpcConnection({
433433
error: {
434434
type: "INTERNAL_ERROR",
435435
code: TaskRunErrorCodes.CONFIGURED_INCORRECTLY,
436+
message: err instanceof Error ? err.message : String(err),
437+
stackTrace: err instanceof Error ? err.stack : undefined,
436438
},
437439
usage: {
438440
durationMs: 0,

packages/core/src/v3/index.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,14 @@ export * from "./utils/imageRef.js";
7070
export * from "./utils/heartbeat.js";
7171

7272
export * from "./config.js";
73-
export { getSchemaParseFn, type AnySchemaParseFn, type SchemaParseFn } from "./types/schemas.js";
73+
export {
74+
getSchemaParseFn,
75+
type AnySchemaParseFn,
76+
type SchemaParseFn,
77+
isSchemaZodEsque,
78+
isSchemaValibotEsque,
79+
isSchemaArkTypeEsque,
80+
} from "./types/schemas.js";
7481

7582
import { VERSION } from "../version.js";
7683

packages/core/src/v3/otel/tracingSDK.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ export class TracingSDK {
142142

143143
traceProvider.addSpanProcessor(
144144
new TaskContextSpanProcessor(
145+
traceProvider.getTracer("trigger-dev-worker", VERSION),
145146
getEnvVar("OTEL_BATCH_PROCESSING_ENABLED") === "1"
146147
? new BatchSpanProcessor(spanExporter, {
147148
maxExportBatchSize: parseInt(getEnvVar("OTEL_SPAN_MAX_EXPORT_BATCH_SIZE") ?? "64"),

packages/core/src/v3/taskContext/otelProcessors.ts

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ import { SemanticInternalAttributes } from "../semanticInternalAttributes.js";
44
import { Context } from "@opentelemetry/api";
55
import { flattenAttributes } from "../utils/flattenAttributes.js";
66
import { taskContext } from "../task-context-api.js";
7+
import { Tracer } from "@opentelemetry/api";
78

89
export class TaskContextSpanProcessor implements SpanProcessor {
910
private _innerProcessor: SpanProcessor;
11+
private _tracer: Tracer;
1012

11-
constructor(innerProcessor: SpanProcessor) {
13+
constructor(tracer: Tracer, innerProcessor: SpanProcessor) {
14+
this._tracer = tracer;
1215
this._innerProcessor = innerProcessor;
1316
}
1417

@@ -26,7 +29,15 @@ export class TaskContextSpanProcessor implements SpanProcessor {
2629
);
2730
}
2831

29-
this._innerProcessor.onStart(span, parentContext);
32+
if (!isPartialSpan(span)) {
33+
const partialSpan = createPartialSpan(this._tracer, span, parentContext);
34+
35+
this._innerProcessor.onStart(span, parentContext);
36+
37+
partialSpan.end();
38+
} else {
39+
this._innerProcessor.onStart(span, parentContext);
40+
}
3041
}
3142

3243
// Delegate the rest of the methods to the wrapped processor
@@ -44,6 +55,44 @@ export class TaskContextSpanProcessor implements SpanProcessor {
4455
}
4556
}
4657

58+
function isPartialSpan(span: Span) {
59+
return span.attributes[SemanticInternalAttributes.SPAN_PARTIAL] === true;
60+
}
61+
62+
function createPartialSpan(tracer: Tracer, span: Span, parentContext: Context) {
63+
const partialSpan = tracer.startSpan(
64+
span.name,
65+
{
66+
attributes: {
67+
[SemanticInternalAttributes.SPAN_PARTIAL]: true,
68+
[SemanticInternalAttributes.SPAN_ID]: span.spanContext().spanId,
69+
...span.attributes,
70+
},
71+
},
72+
parentContext
73+
);
74+
75+
if (taskContext.ctx) {
76+
partialSpan.setAttributes(
77+
flattenAttributes(
78+
{
79+
[SemanticInternalAttributes.ATTEMPT_ID]: taskContext.ctx.attempt.id,
80+
[SemanticInternalAttributes.ATTEMPT_NUMBER]: taskContext.ctx.attempt.number,
81+
},
82+
SemanticInternalAttributes.METADATA
83+
)
84+
);
85+
}
86+
87+
if (span.events) {
88+
for (const event of span.events) {
89+
partialSpan.addEvent(event.name, event.attributes, event.time);
90+
}
91+
}
92+
93+
return partialSpan;
94+
}
95+
4796
export class TaskContextLogProcessor implements LogRecordProcessor {
4897
private _innerProcessor: LogRecordProcessor;
4998

packages/core/src/v3/tracer.ts

Lines changed: 4 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
Attributes,
33
Context,
4-
HrTime,
54
SpanOptions,
65
SpanStatusCode,
76
TimeInput,
@@ -12,12 +11,12 @@ import {
1211
type Tracer,
1312
} from "@opentelemetry/api";
1413
import { Logger, logs } from "@opentelemetry/api-logs";
15-
import { SemanticInternalAttributes } from "./semanticInternalAttributes.js";
1614
import { clock } from "./clock-api.js";
17-
import { usage } from "./usage-api.js";
18-
import { taskContext } from "./task-context-api.js";
19-
import { recordSpanException } from "./otel/utils.js";
2015
import { isCompleteTaskWithOutput } from "./errors.js";
16+
import { recordSpanException } from "./otel/utils.js";
17+
import { SemanticInternalAttributes } from "./semanticInternalAttributes.js";
18+
import { taskContext } from "./task-context-api.js";
19+
import { usage } from "./usage-api.js";
2120

2221
export type TriggerTracerConfig =
2322
| {
@@ -98,29 +97,6 @@ export class TriggerTracer {
9897
}
9998
});
10099

101-
if (taskContext.ctx) {
102-
const partialSpan = this.tracer.startSpan(
103-
name,
104-
{
105-
...options,
106-
attributes: {
107-
...attributes,
108-
[SemanticInternalAttributes.SPAN_PARTIAL]: true,
109-
[SemanticInternalAttributes.SPAN_ID]: span.spanContext().spanId,
110-
},
111-
},
112-
parentContext
113-
);
114-
115-
if (options?.events) {
116-
for (const event of options.events) {
117-
partialSpan.addEvent(event.name, event.attributes, event.startTime);
118-
}
119-
}
120-
121-
partialSpan.end();
122-
}
123-
124100
if (options?.events) {
125101
for (const event of options.events) {
126102
span.addEvent(event.name, event.attributes, event.startTime);
@@ -179,21 +155,6 @@ export class TriggerTracer {
179155

180156
const span = this.tracer.startSpan(name, options, parentContext);
181157

182-
this.tracer
183-
.startSpan(
184-
name,
185-
{
186-
...options,
187-
attributes: {
188-
...attributes,
189-
[SemanticInternalAttributes.SPAN_PARTIAL]: true,
190-
[SemanticInternalAttributes.SPAN_ID]: span.spanContext().spanId,
191-
},
192-
},
193-
parentContext
194-
)
195-
.end();
196-
197158
return span;
198159
}
199160
}

packages/core/src/v3/types/schemas.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@ export type SchemaZodEsque<TInput, TParsedInput> = {
33
_output: TParsedInput;
44
};
55

6+
export function isSchemaZodEsque<TInput, TParsedInput>(
7+
schema: Schema
8+
): schema is SchemaZodEsque<TInput, TParsedInput> {
9+
return (
10+
typeof schema === "object" &&
11+
"_def" in schema &&
12+
"parse" in schema &&
13+
"parseAsync" in schema &&
14+
"safeParse" in schema
15+
);
16+
}
17+
618
export type SchemaValibotEsque<TInput, TParsedInput> = {
719
schema: {
820
_types?: {
@@ -12,11 +24,23 @@ export type SchemaValibotEsque<TInput, TParsedInput> = {
1224
};
1325
};
1426

27+
export function isSchemaValibotEsque<TInput, TParsedInput>(
28+
schema: Schema
29+
): schema is SchemaValibotEsque<TInput, TParsedInput> {
30+
return typeof schema === "object" && "_types" in schema;
31+
}
32+
1533
export type SchemaArkTypeEsque<TInput, TParsedInput> = {
1634
inferIn: TInput;
1735
infer: TParsedInput;
1836
};
1937

38+
export function isSchemaArkTypeEsque<TInput, TParsedInput>(
39+
schema: Schema
40+
): schema is SchemaArkTypeEsque<TInput, TParsedInput> {
41+
return typeof schema === "object" && "_inferIn" in schema && "_infer" in schema;
42+
}
43+
2044
export type SchemaMyZodEsque<TInput> = {
2145
parse: (input: any) => TInput;
2246
};

0 commit comments

Comments
 (0)