@raindrop-ai/deep-agents 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -70,6 +70,34 @@ const raindrop = createRaindropDeepAgents({
70
70
 
71
71
  This sets the `X-Raindrop-Project-Id` header on every event. Omit it (or pass `"default"`) to use your org's default **Production** project — the existing behavior. Single-project orgs need nothing new.
72
72
 
73
+
74
+ ## Application Git identity
75
+
76
+ Each client reports the application commit SHA when it can determine one. Local Git discovery runs in the background and never delays or fails application calls. Automatic branch discovery is off by default.
77
+
78
+ Use `appGit` to override detection or opt out:
79
+
80
+ ```ts
81
+ const raindrop = createRaindropDeepAgents({
82
+ writeKey: "your-write-key",
83
+ appGit: {
84
+ commitSha: "0123456789abcdef0123456789abcdef01234567",
85
+ commitDirty: false,
86
+ branch: "main",
87
+ detectBranch: true,
88
+ sourceDirectory: "/path/to/application",
89
+ },
90
+ });
91
+
92
+ // Disable all application Git reporting.
93
+ const withoutGit = createRaindropDeepAgents({
94
+ writeKey: "your-write-key",
95
+ appGit: false,
96
+ });
97
+ ```
98
+
99
+ `commitSha`, `commitDirty`, and `branch` are explicit overrides. `detectBranch` opts into automatic branch lookup, `sourceDirectory` selects the application repository, and `autoDetect: false` disables automatic sources while retaining explicit values.
100
+
73
101
  ## LangGraph Support
74
102
 
75
103
  Deep Agents is built on LangGraph. The handler automatically:
@@ -120,17 +148,7 @@ The `createRaindropDeepAgents()` factory returns:
120
148
  pnpm test -- tests/handler.test.ts
121
149
  ```
122
150
 
123
- **E2E tests** run REAL Deep Agents workflows via `createDeepAgent()` against a REAL LLM (OpenAI gpt-4o-mini) and verify events / tool calls / traces against the production dashboard TRPC API. They skip automatically when any of `RAINDROP_WRITE_KEY`, `OPENAI_API_KEY`, or `RAINDROP_DASHBOARD_TOKEN` is missing.
124
-
125
- ```bash
126
- # E2E — requires all three keys
127
- RAINDROP_WRITE_KEY=xxx \
128
- OPENAI_API_KEY=sk-... \
129
- RAINDROP_DASHBOARD_TOKEN=eyJ... \
130
- pnpm test -- tests/e2e.test.ts
131
- ```
132
-
133
- The dashboard token comes from `app.raindrop.ai` → DevTools → Network → any `backend.raindrop.ai` request → `Authorization: Bearer ...` (expires every ~30 min, so grab a fresh one immediately before running).
151
+ End-to-end coverage runs through the cross-SDK [conformance harness](https://github.com/invisible-tools/raindrop-sdk-harness). The `deep-agents` conformance driver (`conformance/deep-agents-driver.mjs`) maps the shared scenario corpus onto this package's public API. The fault lane runs locally and on every PR against a fault-injecting fake ingest; the prod lane verifies real ingest through the public Query API readback. See [`conformance/README.md`](../../conformance/README.md) and the harness [README](https://github.com/invisible-tools/raindrop-sdk-harness/blob/main/README.md) / [HOW-IT-WORKS](https://github.com/invisible-tools/raindrop-sdk-harness/blob/main/docs/HOW-IT-WORKS.md).
134
152
 
135
153
  ## Python
136
154
 
package/dist/index.d.mts CHANGED
@@ -42,6 +42,64 @@ type SpanIds = {
42
42
  spanIdB64: string;
43
43
  parentSpanIdB64?: string;
44
44
  };
45
+ /** Kept structural so public integration declarations do not depend on private schemas. */
46
+ type AppGitOptions = {
47
+ commitSha?: string | null;
48
+ commitDirty?: boolean | null;
49
+ branch?: string | null;
50
+ detectBranch?: boolean;
51
+ sourceDirectory?: string;
52
+ autoDetect?: boolean;
53
+ };
54
+ type AppGitSnapshot = Readonly<Record<string, unknown>>;
55
+ type AppGitEnvironment = Readonly<Record<string, string | undefined>>;
56
+ type AppGitLocalResult = {
57
+ commitSha?: string;
58
+ commitDirty?: boolean;
59
+ branch?: string;
60
+ };
61
+ type AppGitOperationOwner = string;
62
+ type AppGitLocalResolver = (sourceDirectory: string | undefined, detectBranch: boolean, completed: (result: AppGitLocalResult) => void) => () => void;
63
+ /** One client owns its defaults; operation snapshots never wait for discovery. */
64
+ declare class AppGitContextImpl {
65
+ private defaults;
66
+ private explicit;
67
+ private explicitKeys;
68
+ private cancel;
69
+ private disposed;
70
+ private operations;
71
+ private operationOverflow;
72
+ private detectBranch;
73
+ private replayBranch;
74
+ private disabled;
75
+ constructor(options: AppGitOptions | false | undefined, runtime?: {
76
+ allowLocalGit?: boolean;
77
+ resolveLocal?: AppGitLocalResolver;
78
+ env?: AppGitEnvironment;
79
+ captureLegacyReplayBranch?: boolean;
80
+ allowDiscovery?: boolean;
81
+ });
82
+ private accept;
83
+ snapshot(properties?: Readonly<Record<string, unknown>>): AppGitSnapshot;
84
+ /** Safe defaults when no operation/span start was observed; never infer identity. */
85
+ snapshotExplicit(properties?: Readonly<Record<string, unknown>>, eventId?: string): AppGitSnapshot;
86
+ /** Existing replay branch reporting stays separate from opt-in event properties. */
87
+ snapshotForReplay(): AppGitSnapshot;
88
+ /** Merge a frozen span snapshot without losing client-authored provenance. */
89
+ mergeSnapshot(base: AppGitSnapshot, properties?: Readonly<Record<string, unknown>>, explicitKeys?: ReadonlySet<string>): AppGitSnapshot;
90
+ /** Shippers belonging to one client share this bounded operation registry. */
91
+ forOperation(eventId: string | undefined, properties?: Readonly<Record<string, unknown>>, owner?: AppGitOperationOwner): AppGitSnapshot;
92
+ releaseOperation(eventId: string, owner: AppGitOperationOwner): void;
93
+ finishOperation(eventId: string): void;
94
+ dispose(): void;
95
+ }
96
+ /** Structural at package boundaries: public SDK bundles contain independent copies of core. */
97
+ type AppGitContext = Pick<AppGitContextImpl, "snapshot" | "snapshotForReplay" | "forOperation" | "finishOperation" | "dispose"> & {
98
+ snapshotExplicit?: AppGitContextImpl["snapshotExplicit"];
99
+ mergeSnapshot?: AppGitContextImpl["mergeSnapshot"];
100
+ releaseOperation?: (eventId: string, owner: AppGitOperationOwner) => void;
101
+ };
102
+ declare const AppGitContext: typeof AppGitContextImpl;
45
103
  type Attachment = {
46
104
  type: string;
47
105
  role: string;
@@ -52,6 +110,10 @@ type IdentifyInput = {
52
110
  userId: string;
53
111
  traits?: Record<string, unknown>;
54
112
  };
113
+ type EventUsage = {
114
+ promptTokens?: number;
115
+ completionTokens?: number;
116
+ };
55
117
  type Patch = {
56
118
  eventName?: string;
57
119
  userId?: string;
@@ -59,6 +121,8 @@ type Patch = {
59
121
  input?: string;
60
122
  output?: string;
61
123
  model?: string;
124
+ usage?: EventUsage;
125
+ error?: unknown;
62
126
  properties?: Record<string, unknown>;
63
127
  featureFlags?: Record<string, string>;
64
128
  attachments?: Attachment[];
@@ -77,6 +141,9 @@ type SignalInput = {
77
141
  after?: string;
78
142
  };
79
143
  type EventShipperOptions = {
144
+ appGit?: AppGitOptions | false;
145
+ /** Share with the trace shipper so one operation uses one source snapshot. */
146
+ appGitContext?: AppGitContext;
80
147
  writeKey?: string;
81
148
  endpoint?: string;
82
149
  enabled?: boolean;
@@ -108,6 +175,9 @@ type EventShipperOptions = {
108
175
  maxTextFieldChars?: number;
109
176
  };
110
177
  declare class EventShipper {
178
+ private appGitContext;
179
+ private ownsAppGitContext;
180
+ private readonly appGitOwner;
111
181
  private baseUrl;
112
182
  private writeKey?;
113
183
  private enabled;
@@ -138,6 +208,7 @@ declare class EventShipper {
138
208
  /** URL of the local debugger / Workshop daemon, when one is reachable. */
139
209
  private localDebuggerUrl;
140
210
  constructor(opts: EventShipperOptions);
211
+ protected ownAppGitContextForShutdown(): void;
141
212
  isDebugEnabled(): boolean;
142
213
  private authHeaders;
143
214
  private requestHeaders;
@@ -157,13 +228,7 @@ declare class EventShipper {
157
228
  */
158
229
  private requestOpts;
159
230
  patch(eventId: string, patch: Patch): Promise<void>;
160
- finish(eventId: string, patch: {
161
- output?: string;
162
- model?: string;
163
- properties?: Record<string, unknown>;
164
- featureFlags?: Record<string, string>;
165
- userId?: string;
166
- }): Promise<void>;
231
+ finish(eventId: string, patch: Pick<Patch, "output" | "model" | "usage" | "error" | "properties" | "featureFlags" | "userId">): Promise<void>;
167
232
  flush(): Promise<void>;
168
233
  shutdown(): Promise<void>;
169
234
  trackSignal(signal: SignalInput): Promise<void>;
@@ -197,6 +262,8 @@ type InternalSpan = {
197
262
  attributes: Array<OtlpKeyValue | undefined>;
198
263
  };
199
264
  type TraceShipperOptions = {
265
+ appGit?: AppGitOptions | false;
266
+ appGitContext?: AppGitContext;
200
267
  writeKey?: string;
201
268
  endpoint?: string;
202
269
  enabled?: boolean;
@@ -265,6 +332,13 @@ type TraceShipperOptions = {
265
332
  maxTextFieldChars?: number;
266
333
  };
267
334
  declare class TraceShipper {
335
+ private appGitContext;
336
+ protected ownsAppGitContext: boolean;
337
+ private readonly appGitOwner;
338
+ private appGitEventIds;
339
+ private appGitActiveSpans;
340
+ private appGitCaptured;
341
+ private appGitAdded;
268
342
  private baseUrl;
269
343
  private writeKey?;
270
344
  private enabled;
@@ -336,6 +410,9 @@ declare class TraceShipper {
336
410
  spanIdB64: string;
337
411
  };
338
412
  eventId: string;
413
+ userId?: string;
414
+ convoId?: string;
415
+ eventName?: string;
339
416
  operationId?: string;
340
417
  attributes?: Array<OtlpKeyValue | undefined>;
341
418
  startTimeUnixNano?: string;
@@ -354,6 +431,9 @@ declare class TraceShipper {
354
431
  spanIdB64: string;
355
432
  };
356
433
  eventId: string;
434
+ userId?: string;
435
+ convoId?: string;
436
+ eventName?: string;
357
437
  startTimeUnixNano: string;
358
438
  endTimeUnixNano: string;
359
439
  attributes?: Array<OtlpKeyValue | undefined>;
@@ -463,6 +543,7 @@ declare class RaindropDeepAgentsHandler extends BaseCallbackHandler {
463
543
  private getParent;
464
544
  private cleanup;
465
545
  private finalizeEventIfRoot;
546
+ private rootErrorPatch;
466
547
  handleLLMStart(llm: Serialized, prompts: string[], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
467
548
  handleChatModelStart(llm: Serialized, messages: BaseMessage[][], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
468
549
  handleLLMEnd(output: LLMResult, runId: string, _parentRunId?: string): Promise<void>;
@@ -506,6 +587,8 @@ interface DeepAgentsOptions {
506
587
  */
507
588
  projectId?: string;
508
589
  traceChains?: boolean;
590
+ /** Application Git identity. Auto-detects commit SHA by default; pass `false` to disable. */
591
+ appGit?: AppGitOptions | false;
509
592
  }
510
593
  type RaindropDeepAgentsClient = {
511
594
  /**
package/dist/index.d.ts CHANGED
@@ -42,6 +42,64 @@ type SpanIds = {
42
42
  spanIdB64: string;
43
43
  parentSpanIdB64?: string;
44
44
  };
45
+ /** Kept structural so public integration declarations do not depend on private schemas. */
46
+ type AppGitOptions = {
47
+ commitSha?: string | null;
48
+ commitDirty?: boolean | null;
49
+ branch?: string | null;
50
+ detectBranch?: boolean;
51
+ sourceDirectory?: string;
52
+ autoDetect?: boolean;
53
+ };
54
+ type AppGitSnapshot = Readonly<Record<string, unknown>>;
55
+ type AppGitEnvironment = Readonly<Record<string, string | undefined>>;
56
+ type AppGitLocalResult = {
57
+ commitSha?: string;
58
+ commitDirty?: boolean;
59
+ branch?: string;
60
+ };
61
+ type AppGitOperationOwner = string;
62
+ type AppGitLocalResolver = (sourceDirectory: string | undefined, detectBranch: boolean, completed: (result: AppGitLocalResult) => void) => () => void;
63
+ /** One client owns its defaults; operation snapshots never wait for discovery. */
64
+ declare class AppGitContextImpl {
65
+ private defaults;
66
+ private explicit;
67
+ private explicitKeys;
68
+ private cancel;
69
+ private disposed;
70
+ private operations;
71
+ private operationOverflow;
72
+ private detectBranch;
73
+ private replayBranch;
74
+ private disabled;
75
+ constructor(options: AppGitOptions | false | undefined, runtime?: {
76
+ allowLocalGit?: boolean;
77
+ resolveLocal?: AppGitLocalResolver;
78
+ env?: AppGitEnvironment;
79
+ captureLegacyReplayBranch?: boolean;
80
+ allowDiscovery?: boolean;
81
+ });
82
+ private accept;
83
+ snapshot(properties?: Readonly<Record<string, unknown>>): AppGitSnapshot;
84
+ /** Safe defaults when no operation/span start was observed; never infer identity. */
85
+ snapshotExplicit(properties?: Readonly<Record<string, unknown>>, eventId?: string): AppGitSnapshot;
86
+ /** Existing replay branch reporting stays separate from opt-in event properties. */
87
+ snapshotForReplay(): AppGitSnapshot;
88
+ /** Merge a frozen span snapshot without losing client-authored provenance. */
89
+ mergeSnapshot(base: AppGitSnapshot, properties?: Readonly<Record<string, unknown>>, explicitKeys?: ReadonlySet<string>): AppGitSnapshot;
90
+ /** Shippers belonging to one client share this bounded operation registry. */
91
+ forOperation(eventId: string | undefined, properties?: Readonly<Record<string, unknown>>, owner?: AppGitOperationOwner): AppGitSnapshot;
92
+ releaseOperation(eventId: string, owner: AppGitOperationOwner): void;
93
+ finishOperation(eventId: string): void;
94
+ dispose(): void;
95
+ }
96
+ /** Structural at package boundaries: public SDK bundles contain independent copies of core. */
97
+ type AppGitContext = Pick<AppGitContextImpl, "snapshot" | "snapshotForReplay" | "forOperation" | "finishOperation" | "dispose"> & {
98
+ snapshotExplicit?: AppGitContextImpl["snapshotExplicit"];
99
+ mergeSnapshot?: AppGitContextImpl["mergeSnapshot"];
100
+ releaseOperation?: (eventId: string, owner: AppGitOperationOwner) => void;
101
+ };
102
+ declare const AppGitContext: typeof AppGitContextImpl;
45
103
  type Attachment = {
46
104
  type: string;
47
105
  role: string;
@@ -52,6 +110,10 @@ type IdentifyInput = {
52
110
  userId: string;
53
111
  traits?: Record<string, unknown>;
54
112
  };
113
+ type EventUsage = {
114
+ promptTokens?: number;
115
+ completionTokens?: number;
116
+ };
55
117
  type Patch = {
56
118
  eventName?: string;
57
119
  userId?: string;
@@ -59,6 +121,8 @@ type Patch = {
59
121
  input?: string;
60
122
  output?: string;
61
123
  model?: string;
124
+ usage?: EventUsage;
125
+ error?: unknown;
62
126
  properties?: Record<string, unknown>;
63
127
  featureFlags?: Record<string, string>;
64
128
  attachments?: Attachment[];
@@ -77,6 +141,9 @@ type SignalInput = {
77
141
  after?: string;
78
142
  };
79
143
  type EventShipperOptions = {
144
+ appGit?: AppGitOptions | false;
145
+ /** Share with the trace shipper so one operation uses one source snapshot. */
146
+ appGitContext?: AppGitContext;
80
147
  writeKey?: string;
81
148
  endpoint?: string;
82
149
  enabled?: boolean;
@@ -108,6 +175,9 @@ type EventShipperOptions = {
108
175
  maxTextFieldChars?: number;
109
176
  };
110
177
  declare class EventShipper {
178
+ private appGitContext;
179
+ private ownsAppGitContext;
180
+ private readonly appGitOwner;
111
181
  private baseUrl;
112
182
  private writeKey?;
113
183
  private enabled;
@@ -138,6 +208,7 @@ declare class EventShipper {
138
208
  /** URL of the local debugger / Workshop daemon, when one is reachable. */
139
209
  private localDebuggerUrl;
140
210
  constructor(opts: EventShipperOptions);
211
+ protected ownAppGitContextForShutdown(): void;
141
212
  isDebugEnabled(): boolean;
142
213
  private authHeaders;
143
214
  private requestHeaders;
@@ -157,13 +228,7 @@ declare class EventShipper {
157
228
  */
158
229
  private requestOpts;
159
230
  patch(eventId: string, patch: Patch): Promise<void>;
160
- finish(eventId: string, patch: {
161
- output?: string;
162
- model?: string;
163
- properties?: Record<string, unknown>;
164
- featureFlags?: Record<string, string>;
165
- userId?: string;
166
- }): Promise<void>;
231
+ finish(eventId: string, patch: Pick<Patch, "output" | "model" | "usage" | "error" | "properties" | "featureFlags" | "userId">): Promise<void>;
167
232
  flush(): Promise<void>;
168
233
  shutdown(): Promise<void>;
169
234
  trackSignal(signal: SignalInput): Promise<void>;
@@ -197,6 +262,8 @@ type InternalSpan = {
197
262
  attributes: Array<OtlpKeyValue | undefined>;
198
263
  };
199
264
  type TraceShipperOptions = {
265
+ appGit?: AppGitOptions | false;
266
+ appGitContext?: AppGitContext;
200
267
  writeKey?: string;
201
268
  endpoint?: string;
202
269
  enabled?: boolean;
@@ -265,6 +332,13 @@ type TraceShipperOptions = {
265
332
  maxTextFieldChars?: number;
266
333
  };
267
334
  declare class TraceShipper {
335
+ private appGitContext;
336
+ protected ownsAppGitContext: boolean;
337
+ private readonly appGitOwner;
338
+ private appGitEventIds;
339
+ private appGitActiveSpans;
340
+ private appGitCaptured;
341
+ private appGitAdded;
268
342
  private baseUrl;
269
343
  private writeKey?;
270
344
  private enabled;
@@ -336,6 +410,9 @@ declare class TraceShipper {
336
410
  spanIdB64: string;
337
411
  };
338
412
  eventId: string;
413
+ userId?: string;
414
+ convoId?: string;
415
+ eventName?: string;
339
416
  operationId?: string;
340
417
  attributes?: Array<OtlpKeyValue | undefined>;
341
418
  startTimeUnixNano?: string;
@@ -354,6 +431,9 @@ declare class TraceShipper {
354
431
  spanIdB64: string;
355
432
  };
356
433
  eventId: string;
434
+ userId?: string;
435
+ convoId?: string;
436
+ eventName?: string;
357
437
  startTimeUnixNano: string;
358
438
  endTimeUnixNano: string;
359
439
  attributes?: Array<OtlpKeyValue | undefined>;
@@ -463,6 +543,7 @@ declare class RaindropDeepAgentsHandler extends BaseCallbackHandler {
463
543
  private getParent;
464
544
  private cleanup;
465
545
  private finalizeEventIfRoot;
546
+ private rootErrorPatch;
466
547
  handleLLMStart(llm: Serialized, prompts: string[], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
467
548
  handleChatModelStart(llm: Serialized, messages: BaseMessage[][], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
468
549
  handleLLMEnd(output: LLMResult, runId: string, _parentRunId?: string): Promise<void>;
@@ -506,6 +587,8 @@ interface DeepAgentsOptions {
506
587
  */
507
588
  projectId?: string;
508
589
  traceChains?: boolean;
590
+ /** Application Git identity. Auto-detects commit SHA by default; pass `false` to disable. */
591
+ appGit?: AppGitOptions | false;
509
592
  }
510
593
  type RaindropDeepAgentsClient = {
511
594
  /**