Skip to content

Commit 51bb3ee

Browse files
authored
v4 ai improvements (#1863)
* AI SDK sql generator and approval example WIP * Create some nice spans and extract the tools out so we can get the type of the streams * Enable AI SDK telemetry * Adding ai.tool and removing toolTask, 3rd party telemetry spans now wil create partials, better ai SDK telemetry icons * Created a separate d3-chat example, split out from the openai-agents example * Fixed the tool options being passed to metadata in `ai.tool` * Add a link to the run * Slightly improved design * Add a crawler task using crawl4ai * Use a tool to get the userId * Couple of tweaks * Adding markdown rendering to assistant messages and added an e2b based chart rendering task * Backup to anthropic * Add changeset
1 parent e539c7c commit 51bb3ee

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+3865
-515
lines changed

.changeset/honest-files-decide.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@trigger.dev/sdk": patch
3+
---
4+
5+
Deprecate toolTask and replace with `ai.tool(mySchemaTask)`

.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/components/runs/v3/RunIcon.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export function RunIcon({ name, className, spanName }: TaskIconProps) {
7373
case "trigger":
7474
return <TriggerIcon className={cn(className, "text-orange-500")} />;
7575
case "python":
76-
return <PythonLogoIcon />;
76+
return <PythonLogoIcon className={className} />;
7777
//log levels
7878
case "debug":
7979
case "log":

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

0 commit comments

Comments
 (0)