@temporalio/langsmith 1.20.0

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.
@@ -0,0 +1,319 @@
1
+ "use strict";
2
+ /**
3
+ * Replay-safe LangSmith run construction for workflow code, plus the pure
4
+ * run-name builders shared by every interceptor.
5
+ *
6
+ * Inside the workflow isolate LangSmith's default `RunTree` is unsafe on two
7
+ * counts that {@link ReplaySafeRunTree} fixes:
8
+ *
9
+ * 1. **Non-deterministic ids.** Its default random-tailed uuid7 would mint a
10
+ * fresh id on every replay, flooding the backend with duplicates.
11
+ * 2. **Network I/O on replay.** `postRun` / `patchRun` would re-POST runs on
12
+ * every history replay.
13
+ *
14
+ * Internal: every export here is consumed only by sibling modules in this
15
+ * package; none is reachable through a package entry point.
16
+ *
17
+ * @module
18
+ * @internal
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports._RootReplaySafeRunTreeFactory = exports.ReplaySafeRunTree = exports.startUpdateWithStartRunName = exports.startWorkflowUpdateRunName = exports.queryWorkflowRunName = exports.signalWithStartRunName = exports.signalExternalWorkflowRunName = exports.signalChildWorkflowRunName = exports.signalWorkflowRunName = exports.validateUpdateRunName = exports.handleUpdateRunName = exports.handleQueryRunName = exports.handleSignalRunName = exports.runCancelNexusHandlerRunName = exports.runStartNexusHandlerRunName = exports.startNexusOperationRunName = exports.startChildWorkflowRunName = exports.runActivityRunName = exports.startActivityRunName = exports.runWorkflowRunName = exports.startWorkflowRunName = exports.RUN_TYPE = void 0;
22
+ exports.describeError = describeError;
23
+ exports.asOutputs = asOutputs;
24
+ exports.runHeaders = runHeaders;
25
+ exports.emitMarkerRun = emitMarkerRun;
26
+ exports.runTreeFromContext = runTreeFromContext;
27
+ exports.buildRunTree = buildRunTree;
28
+ const run_trees_1 = require("langsmith/run_trees");
29
+ const common_1 = require("@temporalio/common");
30
+ const workflow_1 = require("@temporalio/workflow");
31
+ const propagation_1 = require("./propagation");
32
+ const sinks_1 = require("./sinks");
33
+ /** Named random stream for recorded-path run ids; isolated from the workflow's main RNG. */
34
+ const LANGSMITH_RUN_TREE_STREAM = 'package-langsmith-tracing';
35
+ /** LangSmith run-type constants used for Temporal-operation runs. */
36
+ exports.RUN_TYPE = {
37
+ /** Workflow / child-workflow / scheduling / handler spans. */
38
+ CHAIN: 'chain',
39
+ /** Activity-body execution spans. */
40
+ TOOL: 'tool',
41
+ };
42
+ /** `StartWorkflow:<type>` — client/parent-side workflow-start marker. */
43
+ const startWorkflowRunName = (workflowType) => `StartWorkflow:${workflowType}`;
44
+ exports.startWorkflowRunName = startWorkflowRunName;
45
+ /** `RunWorkflow:<type>` — the workflow-execution span (inbound). */
46
+ const runWorkflowRunName = (workflowType) => `RunWorkflow:${workflowType}`;
47
+ exports.runWorkflowRunName = runWorkflowRunName;
48
+ /** `StartActivity:<name>` — workflow-side activity-schedule marker. */
49
+ const startActivityRunName = (activityType) => `StartActivity:${activityType}`;
50
+ exports.startActivityRunName = startActivityRunName;
51
+ /** `RunActivity:<name>` — the activity-execution span (activity inbound). */
52
+ const runActivityRunName = (activityType) => `RunActivity:${activityType}`;
53
+ exports.runActivityRunName = runActivityRunName;
54
+ /** `StartChildWorkflow:<type>` — workflow-side child-start marker. */
55
+ const startChildWorkflowRunName = (workflowType) => `StartChildWorkflow:${workflowType}`;
56
+ exports.startChildWorkflowRunName = startChildWorkflowRunName;
57
+ /** `StartNexusOperation:<service>/<op>` — workflow-side Nexus-start marker. */
58
+ const startNexusOperationRunName = (service, operation) => `StartNexusOperation:${service}/${operation}`;
59
+ exports.startNexusOperationRunName = startNexusOperationRunName;
60
+ /** `RunStartNexusOperationHandler:<service>/<op>` — Nexus start-handler span. */
61
+ const runStartNexusHandlerRunName = (service, operation) => `RunStartNexusOperationHandler:${service}/${operation}`;
62
+ exports.runStartNexusHandlerRunName = runStartNexusHandlerRunName;
63
+ /** `RunCancelNexusOperationHandler:<service>/<op>` — Nexus cancel-handler span. */
64
+ const runCancelNexusHandlerRunName = (service, operation) => `RunCancelNexusOperationHandler:${service}/${operation}`;
65
+ exports.runCancelNexusHandlerRunName = runCancelNexusHandlerRunName;
66
+ /** `HandleSignal:<name>` — inbound signal handler span. */
67
+ const handleSignalRunName = (signalName) => `HandleSignal:${signalName}`;
68
+ exports.handleSignalRunName = handleSignalRunName;
69
+ /** `HandleQuery:<name>` — inbound query handler span. */
70
+ const handleQueryRunName = (queryName) => `HandleQuery:${queryName}`;
71
+ exports.handleQueryRunName = handleQueryRunName;
72
+ /** `HandleUpdate:<name>` — inbound update handler span. */
73
+ const handleUpdateRunName = (updateName) => `HandleUpdate:${updateName}`;
74
+ exports.handleUpdateRunName = handleUpdateRunName;
75
+ /** `ValidateUpdate:<name>` — inbound update validator span. */
76
+ const validateUpdateRunName = (updateName) => `ValidateUpdate:${updateName}`;
77
+ exports.validateUpdateRunName = validateUpdateRunName;
78
+ /** `SignalWorkflow:<name>` — client/outbound signal marker. */
79
+ const signalWorkflowRunName = (signalName) => `SignalWorkflow:${signalName}`;
80
+ exports.signalWorkflowRunName = signalWorkflowRunName;
81
+ /** `SignalChildWorkflow:<name>` — workflow-side signal-child marker. */
82
+ const signalChildWorkflowRunName = (signalName) => `SignalChildWorkflow:${signalName}`;
83
+ exports.signalChildWorkflowRunName = signalChildWorkflowRunName;
84
+ /** `SignalExternalWorkflow:<name>` — workflow-side signal-external marker. */
85
+ const signalExternalWorkflowRunName = (signalName) => `SignalExternalWorkflow:${signalName}`;
86
+ exports.signalExternalWorkflowRunName = signalExternalWorkflowRunName;
87
+ /** `SignalWithStartWorkflow:<type>` — client signal-with-start marker. */
88
+ const signalWithStartRunName = (workflowType) => `SignalWithStartWorkflow:${workflowType}`;
89
+ exports.signalWithStartRunName = signalWithStartRunName;
90
+ /** `QueryWorkflow:<name>` — client query marker. */
91
+ const queryWorkflowRunName = (queryName) => `QueryWorkflow:${queryName}`;
92
+ exports.queryWorkflowRunName = queryWorkflowRunName;
93
+ /** `StartWorkflowUpdate:<name>` — client update-start marker. */
94
+ const startWorkflowUpdateRunName = (updateName) => `StartWorkflowUpdate:${updateName}`;
95
+ exports.startWorkflowUpdateRunName = startWorkflowUpdateRunName;
96
+ /** `StartUpdateWithStartWorkflow:<name>` — client update-with-start marker. */
97
+ const startUpdateWithStartRunName = (updateName) => `StartUpdateWithStartWorkflow:${updateName}`;
98
+ exports.startUpdateWithStartRunName = startUpdateWithStartRunName;
99
+ /**
100
+ * True only while replaying genuine history events, when emission must be
101
+ * suppressed. Deliberately `isReplayingHistoryEvents`, NOT `isReplaying`: for
102
+ * live read-only handlers (queries, update validators) `isReplaying` is `true`
103
+ * but `isReplayingHistoryEvents` is `false`, so their runs still emit. Matches
104
+ * how the SDK gates `callDuringReplay: false` sinks.
105
+ */
106
+ function isReplaying() {
107
+ return (0, workflow_1.workflowInfo)().unsafe.isReplayingHistoryEvents;
108
+ }
109
+ let cachedSinks;
110
+ /** Lazily-resolved workflow Sink proxy (must be called inside a workflow). */
111
+ function sinks() {
112
+ if (cachedSinks === undefined) {
113
+ cachedSinks = (0, workflow_1.proxySinks)();
114
+ }
115
+ return cachedSinks;
116
+ }
117
+ /**
118
+ * A no-op LangSmith client. {@link ReplaySafeRunTree} never lets the underlying
119
+ * `RunTree` perform network I/O — emission goes through the Sink — so the
120
+ * client it carries must do nothing and must never read env / open sockets
121
+ * inside the isolate.
122
+ */
123
+ const NOOP_CLIENT = {
124
+ createRun: async () => { },
125
+ updateRun: async () => { },
126
+ };
127
+ /** Flatten a {@link RunTree} into the plain wire shape consumed by the Sink. */
128
+ function serializeRun(run) {
129
+ const extra = run.extra ? { ...run.extra } : undefined;
130
+ if (extra && extra.metadata && typeof extra.metadata === 'object') {
131
+ extra.metadata = (0, propagation_1.scrubSensitive)(extra.metadata);
132
+ }
133
+ return {
134
+ id: run.id,
135
+ trace_id: run.trace_id,
136
+ dotted_order: run.dotted_order,
137
+ parent_run_id: run.parent_run_id,
138
+ name: run.name,
139
+ run_type: run.run_type,
140
+ start_time: run.start_time,
141
+ end_time: run.end_time,
142
+ inputs: run.inputs,
143
+ outputs: run.outputs,
144
+ error: run.error,
145
+ extra,
146
+ tags: run.tags,
147
+ project_name: run.project_name,
148
+ events: run.events,
149
+ };
150
+ }
151
+ /**
152
+ * Render an error into the LangSmith `error` string, honoring Temporal's
153
+ * benign-failure category.
154
+ *
155
+ * A `BENIGN`-category `ApplicationFailure` is an expected, non-alarming outcome
156
+ * (e.g. a control-flow signal), so it leaves the run's `error` unset. All other
157
+ * failures produce `"<type>: <message>"`.
158
+ */
159
+ function describeError(err) {
160
+ if (err instanceof common_1.ApplicationFailure) {
161
+ if (err.category === common_1.ApplicationFailureCategory.BENIGN) {
162
+ return undefined;
163
+ }
164
+ return `${err.type ?? 'ApplicationError'}: ${err.message}`;
165
+ }
166
+ if (err instanceof Error) {
167
+ return `${err.name}: ${err.message}`;
168
+ }
169
+ return String(err);
170
+ }
171
+ /** Coerce an arbitrary operation result into a LangSmith outputs object. */
172
+ function asOutputs(result) {
173
+ if (result !== null && typeof result === 'object' && !Array.isArray(result)) {
174
+ return result;
175
+ }
176
+ return { result };
177
+ }
178
+ /** The trace context to propagate for `run`, or `undefined` when absent. */
179
+ function runHeaders(run) {
180
+ return run ? run.toHeaders() : undefined;
181
+ }
182
+ /** Emit a short-lived marker run. */
183
+ async function emitMarkerRun(marker) {
184
+ await marker.postRun();
185
+ await marker.end({});
186
+ await marker.patchRun();
187
+ }
188
+ /** Reconstruct a propagated parent {@link RunTree} from a trace context; never throws. */
189
+ function runTreeFromContext(ctx) {
190
+ if (!ctx) {
191
+ return undefined;
192
+ }
193
+ try {
194
+ return run_trees_1.RunTree.fromHeaders(ctx) ?? undefined;
195
+ }
196
+ catch {
197
+ return undefined;
198
+ }
199
+ }
200
+ /**
201
+ * Build an emitter-side {@link RunTree} (client / activity / Nexus); force-enables
202
+ * tracing so nested body `traceable` runs emit — tracing gate is `isTracingEnabled()`.
203
+ */
204
+ function buildRunTree(config, params) {
205
+ return new run_trees_1.RunTree({
206
+ name: params.name,
207
+ run_type: params.runType,
208
+ inputs: params.inputs ?? {},
209
+ parent_run: params.parent,
210
+ client: config.client,
211
+ project_name: config.projectName ?? params.parent?.project_name,
212
+ tags: config.tags,
213
+ extra: { metadata: (0, propagation_1.scrubSensitive)(config.metadata) ?? {} },
214
+ tracingEnabled: true,
215
+ });
216
+ }
217
+ /**
218
+ * A {@link RunTree} subclass safe to construct and drive from workflow code.
219
+ *
220
+ * Subclasses rather than wraps because LangSmith's `traceable` resolves its
221
+ * parent with `instanceof RunTree` before calling `parent.createChild(...)`, so
222
+ * a plain wrapper would refuse to nest under it.
223
+ *
224
+ * @internal
225
+ */
226
+ class ReplaySafeRunTree extends run_trees_1.RunTree {
227
+ // Per-invocation run-id factory. Supplied by read-only handlers (queries, update
228
+ // validators) so their ids don't draw from the Workflow main PRNG; left
229
+ // undefined on recorded paths, where id minting falls back to the isolated
230
+ // LANGSMITH_RUN_TREE_STREAM named stream. Propagated to every child so the whole
231
+ // subtree mints from one factory.
232
+ generateNewUuid4;
233
+ constructor(config, generateNewUuid4) {
234
+ super(ReplaySafeRunTree.fill(config, generateNewUuid4));
235
+ this.generateNewUuid4 = generateNewUuid4;
236
+ }
237
+ static fill(config, generateNewUuid4) {
238
+ const id = config.id ?? (generateNewUuid4 ? generateNewUuid4() : (0, workflow_1.getRandomStream)(LANGSMITH_RUN_TREE_STREAM).uuid4());
239
+ const start_time = config.start_time ?? Date.now();
240
+ const trace_id = config.trace_id ?? config.parent_run?.trace_id ?? id;
241
+ let dotted_order = config.dotted_order;
242
+ if (dotted_order == null) {
243
+ const startMs = typeof start_time === 'number' ? start_time : Date.parse(String(start_time));
244
+ const { dottedOrder } = (0, run_trees_1.convertToDottedOrderFormat)(startMs, id);
245
+ const parentDotted = config.parent_run?.dotted_order;
246
+ dotted_order = parentDotted ? `${parentDotted}.${dottedOrder}` : dottedOrder;
247
+ }
248
+ return {
249
+ ...config,
250
+ id,
251
+ start_time,
252
+ trace_id,
253
+ dotted_order,
254
+ parent_run_id: config.parent_run_id ?? config.parent_run?.id,
255
+ client: NOOP_CLIENT,
256
+ tracingEnabled: config.tracingEnabled ?? true,
257
+ };
258
+ }
259
+ /** Produce a replay-safe child so deeply-nested `traceable` runs stay deterministic. */
260
+ createChild(config) {
261
+ const child = new ReplaySafeRunTree({
262
+ ...config,
263
+ run_type: config.run_type ?? exports.RUN_TYPE.CHAIN,
264
+ parent_run: this,
265
+ parent_run_id: this.id,
266
+ trace_id: this.trace_id,
267
+ project_name: config.project_name ?? this.project_name,
268
+ }, this.generateNewUuid4);
269
+ this.child_runs.push(child);
270
+ return child;
271
+ }
272
+ /** Emit a `createRun` via the Sink, unless replaying. */
273
+ async postRun() {
274
+ if (isReplaying()) {
275
+ return;
276
+ }
277
+ sinks()[sinks_1.LANGSMITH_SINK_NAME].createRun(serializeRun(this));
278
+ }
279
+ /** Record outputs/end-time locally then emit an `updateRun` via the Sink, unless replaying. */
280
+ async patchRun() {
281
+ if (isReplaying()) {
282
+ return;
283
+ }
284
+ sinks()[sinks_1.LANGSMITH_SINK_NAME].updateRun(serializeRun(this));
285
+ }
286
+ /** Record end-time / outputs / error on the run object (pure, replay-safe). */
287
+ async end(outputs, error, endTime) {
288
+ if (outputs !== undefined) {
289
+ this.outputs = outputs;
290
+ }
291
+ if (error !== undefined) {
292
+ this.error = error;
293
+ }
294
+ this.end_time = endTime ?? Date.now();
295
+ }
296
+ }
297
+ exports.ReplaySafeRunTree = ReplaySafeRunTree;
298
+ /**
299
+ * A placeholder, never-emitted parent whose {@link createChild} produces
300
+ * independent root children. Installed as the ambient so a workflow-body
301
+ * `traceable` takes LangSmith's `createChild` branch (deterministic id) instead
302
+ * of the no-parent branch that mints a uuid via `crypto`, which the isolate lacks.
303
+ *
304
+ * @internal
305
+ */
306
+ class _RootReplaySafeRunTreeFactory extends ReplaySafeRunTree {
307
+ /** Produce a replay-safe child with no link back to this factory. */
308
+ createChild(config) {
309
+ return new ReplaySafeRunTree({
310
+ ...config,
311
+ run_type: config.run_type ?? exports.RUN_TYPE.CHAIN,
312
+ project_name: config.project_name ?? this.project_name,
313
+ }, this.generateNewUuid4);
314
+ }
315
+ async postRun() { }
316
+ async patchRun() { }
317
+ }
318
+ exports._RootReplaySafeRunTreeFactory = _RootReplaySafeRunTreeFactory;
319
+ //# sourceMappingURL=run-tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-tree.js","sourceRoot":"","sources":["../src/run-tree.ts"],"names":[],"mappings":"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"}
package/lib/sinks.d.ts ADDED
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Worker-side LangSmith emission, exposed as a Temporal {@link InjectedSinks}.
3
+ *
4
+ * @module
5
+ */
6
+ import { type Client } from 'langsmith';
7
+ import type { Sinks } from '@temporalio/workflow';
8
+ import type { InjectedSinks } from '@temporalio/worker';
9
+ /** Plain-JSON description of a LangSmith run crossing the isolate→worker boundary. */
10
+ export interface SerializedRun {
11
+ id: string;
12
+ trace_id: string;
13
+ dotted_order: string;
14
+ parent_run_id?: string;
15
+ name: string;
16
+ run_type: string;
17
+ start_time: number;
18
+ /** End time (epoch ms); present only on the update record. */
19
+ end_time?: number;
20
+ inputs?: Record<string, unknown>;
21
+ outputs?: Record<string, unknown>;
22
+ /** Error string; non-null marks the run errored. */
23
+ error?: string;
24
+ extra?: Record<string, unknown>;
25
+ tags?: string[];
26
+ project_name?: string;
27
+ events?: Record<string, unknown>[];
28
+ }
29
+ /** Runtime configuration shared by the client and activity interceptors. */
30
+ export interface EmitterConfig {
31
+ /** The LangSmith client runs are emitted to. */
32
+ client: Client;
33
+ /** When false, no Temporal-operation runs are emitted (propagation only). */
34
+ addTemporalRuns: boolean;
35
+ /** Target LangSmith project. */
36
+ projectName?: string;
37
+ /** Tags attached to every emitted run. */
38
+ tags?: string[];
39
+ /** Metadata merged into every emitted run. */
40
+ metadata?: Record<string, unknown>;
41
+ }
42
+ /** The injected sink's wire name. Reserved-prefixed; allowlisted in `@temporalio/common`. */
43
+ export declare const LANGSMITH_SINK_NAME: "__temporal_langsmith";
44
+ /** The Temporal sink surface this plugin injects. */
45
+ export interface LangSmithSinks extends Sinks {
46
+ [LANGSMITH_SINK_NAME]: {
47
+ /** Emit a `createRun` for a newly started run. */
48
+ createRun(run: SerializedRun): void;
49
+ /** Emit an `updateRun` (end / outputs / error / events) for a run. */
50
+ updateRun(run: SerializedRun): void;
51
+ };
52
+ }
53
+ /** Build the worker-side {@link InjectedSinks} routing serialized runs to a real LangSmith client. */
54
+ export declare function createLangSmithSinks(client: Client): InjectedSinks<LangSmithSinks>;
package/lib/sinks.js ADDED
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ /**
3
+ * Worker-side LangSmith emission, exposed as a Temporal {@link InjectedSinks}.
4
+ *
5
+ * @module
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.LANGSMITH_SINK_NAME = void 0;
9
+ exports.createLangSmithSinks = createLangSmithSinks;
10
+ const langsmith_1 = require("langsmith");
11
+ /** The injected sink's wire name. Reserved-prefixed; allowlisted in `@temporalio/common`. */
12
+ exports.LANGSMITH_SINK_NAME = '__temporal_langsmith';
13
+ // langsmith's CreateRunParams omits tags, but createRun spreads them into the request at runtime.
14
+ function toCreateParams(run) {
15
+ return {
16
+ id: run.id,
17
+ trace_id: run.trace_id,
18
+ dotted_order: run.dotted_order,
19
+ parent_run_id: run.parent_run_id,
20
+ name: run.name,
21
+ run_type: run.run_type,
22
+ start_time: run.start_time,
23
+ inputs: run.inputs ?? {},
24
+ extra: run.extra,
25
+ tags: run.tags,
26
+ project_name: run.project_name,
27
+ };
28
+ }
29
+ function toUpdateParams(run) {
30
+ return {
31
+ end_time: run.end_time,
32
+ outputs: run.outputs,
33
+ error: run.error,
34
+ extra: run.extra,
35
+ tags: run.tags,
36
+ events: run.events,
37
+ dotted_order: run.dotted_order,
38
+ trace_id: run.trace_id,
39
+ parent_run_id: run.parent_run_id,
40
+ };
41
+ }
42
+ /** Build the worker-side {@link InjectedSinks} routing serialized runs to a real LangSmith client. */
43
+ function createLangSmithSinks(client) {
44
+ return {
45
+ [exports.LANGSMITH_SINK_NAME]: {
46
+ createRun: {
47
+ fn: (_info, run) => {
48
+ // Honor the LangSmith tracing gate at the real-env emission point.
49
+ if (!(0, langsmith_1.isTracingEnabled)()) {
50
+ return;
51
+ }
52
+ void Promise.resolve(client.createRun(toCreateParams(run))).catch(() => {
53
+ /* swallow: emission must never fail the workflow */
54
+ });
55
+ },
56
+ callDuringReplay: false,
57
+ },
58
+ updateRun: {
59
+ fn: (_info, run) => {
60
+ if (!(0, langsmith_1.isTracingEnabled)()) {
61
+ return;
62
+ }
63
+ void Promise.resolve(client.updateRun(run.id, toUpdateParams(run))).catch(() => {
64
+ /* swallow: emission must never fail the workflow */
65
+ });
66
+ },
67
+ callDuringReplay: false,
68
+ },
69
+ },
70
+ };
71
+ }
72
+ //# sourceMappingURL=sinks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sinks.js","sourceRoot":"","sources":["../src/sinks.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAsFH,oDA4BC;AAhHD,yCAA0D;AAuC1D,6FAA6F;AAChF,QAAA,mBAAmB,GAAG,sBAA+B,CAAC;AAYnE,kGAAkG;AAClG,SAAS,cAAc,CAAC,GAAkB;IACxC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE;QACxB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,YAAY,EAAE,GAAG,CAAC,YAAY;KAC/B,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,GAAkB;IACxC,OAAO;QACL,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,aAAa,EAAE,GAAG,CAAC,aAAa;KACjC,CAAC;AACJ,CAAC;AAED,sGAAsG;AACtG,SAAgB,oBAAoB,CAAC,MAAc;IACjD,OAAO;QACL,CAAC,2BAAmB,CAAC,EAAE;YACrB,SAAS,EAAE;gBACT,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;oBACjB,mEAAmE;oBACnE,IAAI,CAAC,IAAA,4BAAgB,GAAE,EAAE,CAAC;wBACxB,OAAO;oBACT,CAAC;oBACD,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;wBACrE,oDAAoD;oBACtD,CAAC,CAAC,CAAC;gBACL,CAAC;gBACD,gBAAgB,EAAE,KAAK;aACxB;YACD,SAAS,EAAE;gBACT,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;oBACjB,IAAI,CAAC,IAAA,4BAAgB,GAAE,EAAE,CAAC;wBACxB,OAAO;oBACT,CAAC;oBACD,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;wBAC7E,oDAAoD;oBACtD,CAAC,CAAC,CAAC;gBACL,CAAC;gBACD,gBAAgB,EAAE,KAAK;aACxB;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Workflow-isolate interceptors and the deterministic LangSmith context
3
+ * provider. Loaded into the workflow bundle (via the plugin's `workflowModules`)
4
+ * and runs entirely inside the V8 isolate, where `node:async_hooks` is
5
+ * unavailable so a synchronous stack-based context provider stands in for
6
+ * LangSmith's async-context store.
7
+ *
8
+ * Internal: the worker loads this module by specifier and the bundler aliases
9
+ * `node:async_hooks` to it — it is not a hand-import API.
10
+ *
11
+ * @module
12
+ * @internal
13
+ */
14
+ export {};