retrace-sdk 0.5.2 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/recorder.js CHANGED
@@ -129,16 +129,18 @@ export class TraceRecorder {
129
129
  export function record(opts) {
130
130
  const cfg = getConfig();
131
131
  if (!cfg.enabled || !shouldSample(cfg.sampleRate, cfg.sampleSeed, opts?.name)) {
132
- // Return a typed no-op stub (preserves type safety unlike Proxy)
133
- return {
134
- get traceId() { return ""; },
135
- output: undefined,
136
- start() { return this; },
137
- end() { },
138
- addSpan() { },
139
- startSpan(name) { const { SpanBuilder } = require("./trace.js"); return new SpanBuilder(name, "llm_call"); },
140
- endSpan() { },
141
- };
132
+ // Return a properly-typed no-op recorder that satisfies the TraceRecorder interface
133
+ const noop = Object.create(TraceRecorder.prototype);
134
+ Object.defineProperties(noop, {
135
+ traceId: { get: () => "" },
136
+ output: { value: undefined, writable: true },
137
+ });
138
+ noop.start = () => noop;
139
+ noop.end = () => { };
140
+ noop.addSpan = () => { };
141
+ noop.startSpan = (name) => new SpanBuilder(name, "llm_call");
142
+ noop.endSpan = () => { };
143
+ return noop;
142
144
  }
143
145
  return new TraceRecorder(opts);
144
146
  }
package/dist/resume.d.ts CHANGED
@@ -17,7 +17,7 @@ export interface ResumeCommand {
17
17
  }
18
18
  export declare function registerResumable(name: string, fn: (...args: unknown[]) => unknown): void;
19
19
  export declare function getResumable(name: string): ((...args: unknown[]) => unknown) | undefined;
20
- export declare function handleResume(command: ResumeCommand): boolean;
20
+ export declare function handleResume(command: ResumeCommand): Promise<boolean>;
21
21
  export declare function parseResumeMessage(msg: {
22
22
  type: string;
23
23
  data?: Record<string, unknown>;
package/dist/resume.js CHANGED
@@ -15,46 +15,41 @@ export function registerResumable(name, fn) {
15
15
  export function getResumable(name) {
16
16
  return resumableFunctions.get(name);
17
17
  }
18
- export function handleResume(command) {
18
+ export async function handleResume(command) {
19
19
  const fn = getResumable(command.traceName);
20
20
  if (!fn)
21
21
  return false;
22
- // Re-execute async in background
23
- (async () => {
24
- try {
25
- const { TraceRecorder } = await import("./recorder.js");
26
- const { TraceStatus } = await import("./trace.js");
27
- const recorder = new TraceRecorder({
28
- name: `Fork: ${command.traceName}`,
29
- input: command.modifiedInput,
30
- metadata: {
31
- _fork_id: command.forkId,
32
- _fork_of: command.traceId,
33
- _fork_point: command.forkPointSpanId,
34
- _cascade_replay: true,
35
- },
36
- // Signal the recorder to skip spans until the fork point is reached.
37
- // Pre-fork spans are copied server-side; the SDK only needs to emit
38
- // spans from the fork point onward.
39
- forkPointSpanId: command.forkPointSpanId,
40
- });
41
- recorder.start(`Fork: ${command.traceName}`, command.modifiedInput);
42
- // Determine args for re-execution
43
- let args = command.originalArgs || [];
44
- if (typeof command.modifiedInput === "string") {
45
- args = [command.modifiedInput, ...args.slice(1)];
46
- }
47
- else if (typeof command.modifiedInput === "object" && !Array.isArray(command.modifiedInput)) {
48
- args = [command.modifiedInput];
49
- }
50
- const result = await Promise.resolve(fn(...args));
51
- recorder.end(result, TraceStatus.COMPLETED);
22
+ try {
23
+ const { TraceRecorder } = await import("./recorder.js");
24
+ const { TraceStatus } = await import("./trace.js");
25
+ const recorder = new TraceRecorder({
26
+ name: `Fork: ${command.traceName}`,
27
+ input: command.modifiedInput,
28
+ metadata: {
29
+ _fork_id: command.forkId,
30
+ _fork_of: command.traceId,
31
+ _fork_point: command.forkPointSpanId,
32
+ _cascade_replay: true,
33
+ },
34
+ forkPointSpanId: command.forkPointSpanId,
35
+ });
36
+ recorder.start(`Fork: ${command.traceName}`, command.modifiedInput);
37
+ // Determine args for re-execution
38
+ let args = command.originalArgs || [];
39
+ if (typeof command.modifiedInput === "string") {
40
+ args = [command.modifiedInput, ...args.slice(1)];
52
41
  }
53
- catch (err) {
54
- console.error("[retrace] Cascade replay failed:", err);
42
+ else if (typeof command.modifiedInput === "object" && !Array.isArray(command.modifiedInput)) {
43
+ args = [command.modifiedInput];
55
44
  }
56
- })().catch((err) => console.error("[retrace] Replay IIFE unhandled:", err));
57
- return true;
45
+ const result = await Promise.resolve(fn(...args));
46
+ recorder.end(result, TraceStatus.COMPLETED);
47
+ return true;
48
+ }
49
+ catch (err) {
50
+ console.error("[retrace] Cascade replay failed:", err);
51
+ return false;
52
+ }
58
53
  }
59
54
  export function parseResumeMessage(msg) {
60
55
  if (msg.type !== "resume" || !msg.data)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "retrace-sdk",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "description": "The execution replay engine for AI agents. Record, replay, fork, and share agent executions.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",