@raindrop-ai/ai-sdk 0.2.1 → 0.3.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.
@@ -9,6 +9,196 @@ type FeatureFlags = string[] | Record<string, FeatureFlagValue>;
9
9
  */
10
10
  declare function normalizeFeatureFlags(input: FeatureFlags): Record<string, string>;
11
11
 
12
+ /**
13
+ * Detached sub-agent hand-off contract (`raindrop.handoff.*`).
14
+ *
15
+ * A detached hand-off is a sub-agent that runs outside the caller's process and
16
+ * reports as its OWN Raindrop event with its OWN lifecycle, rather than as spans
17
+ * nested inside the caller's trace. It crosses both the OTel trace boundary and
18
+ * the Raindrop event boundary, so nothing implicit links the two — the link is
19
+ * carried explicitly on span attributes.
20
+ *
21
+ * This is deliberately distinct from a *continuation*, where the remote process
22
+ * joins the caller's event by reusing its `eventId`. Continuations need none of
23
+ * these attributes: event-id grouping already merges those traces.
24
+ *
25
+ * Written by the caller, on the exact dispatch span:
26
+ * raindrop.handoff.mode = "detached"
27
+ * raindrop.handoff.childEventId = <the child's event id>
28
+ * raindrop.handoff.name = <sub-agent name>
29
+ *
30
+ * Written by the child, on every span it emits:
31
+ * raindrop.handoff.parentEventId = <the caller's event id>
32
+ * raindrop.handoff.parentSpanId = <the dispatch span id, hex>
33
+ * raindrop.handoff.name = <sub-agent name>
34
+ * raindrop.agent.role = "subagent"
35
+ * raindrop.handoff.terminal = "cancelled", when that happened
36
+ *
37
+ * Status is NOT part of this contract. The child event owns its own lifecycle,
38
+ * so a status attribute written by the caller would be a second writer of a
39
+ * field the child already determines: the caller returned a job handle and moved
40
+ * on, so anything it wrote would be a guess that goes stale. Readers derive
41
+ * status from the child event itself. `cancelled` is the one exception, because
42
+ * a cancelled run is span-for-span identical to a finished one, and it is
43
+ * written BY THE CHILD on itself so the child stays the only writer.
44
+ *
45
+ * Every attribute name lives here and nowhere else, mirroring the reader on the
46
+ * Raindrop backend. Nothing downstream re-spells these strings.
47
+ */
48
+ /** Bare attribute suffixes — the contract's canonical names. */
49
+ declare const HANDOFF_ATTRIBUTE_SUFFIXES: {
50
+ readonly mode: "raindrop.handoff.mode";
51
+ readonly childEventId: "raindrop.handoff.childEventId";
52
+ readonly parentEventId: "raindrop.handoff.parentEventId";
53
+ readonly parentSpanId: "raindrop.handoff.parentSpanId";
54
+ readonly name: "raindrop.handoff.name";
55
+ readonly terminal: "raindrop.handoff.terminal";
56
+ readonly agentRole: "raindrop.agent.role";
57
+ };
58
+ /**
59
+ * The Vercel AI SDK nests user metadata, so the same logical field can land
60
+ * bare, under `ai.telemetry.metadata.`, or under `ai.settings.context.`. The
61
+ * backend reader tries all three; this list is the same one it uses, kept here
62
+ * so a test can assert that every key this SDK emits is a form that reader
63
+ * accepts.
64
+ */
65
+ declare const HANDOFF_ATTRIBUTE_PREFIXES: readonly ["ai.telemetry.metadata.", "ai.settings.context.", ""];
66
+ declare const DETACHED_MODE = "detached";
67
+ declare const SUBAGENT_AGENT_ROLE = "subagent";
68
+ declare const HANDOFF_TERMINAL_CANCELLED = "cancelled";
69
+ declare const TOOL_EVENTS_ALLOW = "allow";
70
+ /** The terminal marker as it appears on an event's `properties`. */
71
+ declare const HANDOFF_TERMINAL_PROPERTY_KEY: "raindrop.handoff.terminal";
72
+ /** What a caller records when it launches a detached sub-agent. */
73
+ type DetachedDispatch = {
74
+ /** The child's event id, allocated by the caller BEFORE dispatching. */
75
+ childEventId: string;
76
+ /** Sub-agent name, so caller and child label the run identically. */
77
+ name?: string;
78
+ };
79
+ /** The reverse reference a detached child carries on its own spans. */
80
+ type DetachedChildLink = {
81
+ /** The caller's event id. */
82
+ parentEventId: string;
83
+ /** The dispatch span id, hex-encoded as the backend stores span ids. */
84
+ parentSpanId?: string;
85
+ name?: string;
86
+ };
87
+
88
+ /**
89
+ * Portable trace-context carrier for cross-process sub-agents.
90
+ *
91
+ * `toHeaders()` / `fromHeaders()` mirror LangSmith's
92
+ * `RunTree.toHeaders()` / `tracing_context(parent=headers)` so migrating from
93
+ * LangSmith is a rename rather than a redesign.
94
+ *
95
+ * Two carriers are understood:
96
+ *
97
+ * 1. Native — `x-raindrop-handoff`, plus W3C `traceparent` and a `baggage` of
98
+ * `raindrop-*` keys. The standard pair is what other readers understand;
99
+ * the Raindrop header is what survives an instrumented caller, and wins
100
+ * where they disagree. See {@link HANDOFF_HEADER}.
101
+ * 2. LangSmith — `langsmith-trace` (dotted order) plus LangSmith's `baggage`.
102
+ * Accepted on READ so a service already propagating LangSmith headers links
103
+ * correctly with no call-site change.
104
+ *
105
+ * ## Trust boundary
106
+ *
107
+ * A carrier names the event a child will be attributed to, so accepting one from
108
+ * an untrusted caller lets that caller write into another tenant's trace. Only
109
+ * accept carriers from services inside your own trust boundary — the same
110
+ * constraint LangSmith documents for distributed tracing. Never take a carrier
111
+ * off a public, unauthenticated request.
112
+ *
113
+ * Trace and span ids are hex here, as W3C `traceparent` and the Raindrop backend
114
+ * both represent them. Use `base64ToHex` when converting from the base64 ids
115
+ * used inside the trace shippers.
116
+ */
117
+ type TraceCarrier = {
118
+ /** Hex trace id (32 chars for a W3C-conformant id). */
119
+ traceId: string;
120
+ /** Hex span id of the dispatching span (16 chars for a W3C-conformant id). */
121
+ spanId: string;
122
+ /** Event the child should join (continuation) or reference (detached). */
123
+ eventId: string;
124
+ /** Set only for a detached hand-off: the child's OWN event id. */
125
+ childEventId?: string;
126
+ /** Sub-agent name, carried so the child can label its own run identically. */
127
+ name?: string;
128
+ convoId?: string;
129
+ userId?: string;
130
+ };
131
+ /**
132
+ * Native carrier: `x-raindrop-handoff`, plus standard `traceparent` and
133
+ * `raindrop-*` baggage.
134
+ *
135
+ * Three headers, not two. The standard pair is what other readers understand,
136
+ * and `x-raindrop-handoff` is what survives a fully instrumented caller —
137
+ * instrumentation owns `traceparent` and the baggage propagator owns `baggage`,
138
+ * so neither is ours to rely on. See {@link HANDOFF_HEADER}.
139
+ *
140
+ * Send all of them. `fromHeaders` does not care whether they arrived as request
141
+ * headers or as fields of a queue payload.
142
+ *
143
+ * `baggage` is REPLACED, not merged: spreading this over a header bag that
144
+ * already carries baggage of its own drops those entries. Merge the two field
145
+ * lists when the caller propagates baggage.
146
+ *
147
+ * `traceparent` is emitted only for W3C-conformant ids. A carrier read back from
148
+ * a LangSmith dotted order holds UUIDs, and a UUID contains `-`, so spelling one
149
+ * into `00-<trace>-<span>-01` yields a header whose next reader takes UUID
150
+ * fragments for the ids. The Raindrop header and the baggage carry the whole
151
+ * carrier either way, so the link survives the omission and does not survive the
152
+ * corruption.
153
+ */
154
+ declare function toHeaders(carrier: TraceCarrier): Record<string, string>;
155
+ /**
156
+ * LangSmith-shaped carrier, for a fleet that is mid-migration and has services
157
+ * on both sides. Prefer {@link toHeaders} — both of its headers are W3C
158
+ * standards, so gateways and proxies pass them through untouched.
159
+ *
160
+ * `langsmith-trace` is a dotted order: segments of `<stamp>Z<run id>` from the
161
+ * trace root to the current run, and LangSmith packs metadata into `baggage`
162
+ * under `langsmith-metadata`. Two segments are emitted — the root run (whose id
163
+ * IS the trace id) and the dispatching run — because a single segment would say
164
+ * "this run is its own trace root" and collapse the two ids on read.
165
+ */
166
+ declare function toLangSmithHeaders(carrier: TraceCarrier): Record<string, string>;
167
+ /**
168
+ * A header container that answers by name rather than by property.
169
+ *
170
+ * A WHATWG `Headers` — what fetch, Next.js route handlers, Hono, Remix and
171
+ * Cloudflare Workers all call `request.headers` — keeps its fields in an
172
+ * internal slot, so `headers["baggage"]` is `undefined` and `Object.entries()`
173
+ * on one yields nothing. Next.js's `headers()` returns a `ReadonlyHeaders`,
174
+ * which is that object sealed behind a Proxy. `get()` is the only way in, and it
175
+ * is also where the spec puts case-insensitivity and the joining of repeated
176
+ * fields — so the container does that work rather than {@link readHeader}
177
+ * reimplementing it.
178
+ */
179
+ type HeaderLookup = {
180
+ get(name: string): string | null | undefined;
181
+ };
182
+ type CarrierHeaders = Readonly<Record<string, string | string[] | undefined>> | HeaderLookup;
183
+ /**
184
+ * Resume a parent context from either carrier.
185
+ *
186
+ * Returns `null` when no carrier is present. That is a legitimate state — the
187
+ * child was invoked directly rather than dispatched — not an error.
188
+ *
189
+ * Read the trust-boundary note at the top of this file before calling this on
190
+ * request headers.
191
+ */
192
+ declare function fromHeaders(headers: CarrierHeaders): TraceCarrier | null;
193
+ /**
194
+ * Allow the next {@link warnUnresolvedCarrier} to speak again.
195
+ *
196
+ * For tests: a once-per-process latch that no test can clear makes every
197
+ * assertion after the first depend on which test ran first, so a suite would
198
+ * pass purely because an earlier case consumed the one warning.
199
+ */
200
+ declare function resetUnresolvedCarrierWarning(): void;
201
+
12
202
  type OtlpAnyValue = {
13
203
  stringValue?: string;
14
204
  intValue?: string;
@@ -509,6 +699,251 @@ declare class TraceShipper extends TraceShipper$1 {
509
699
  constructor(opts: ConstructorParameters<typeof TraceShipper$1>[0]);
510
700
  }
511
701
 
702
+ /**
703
+ * Detached sub-agent hand-offs for the AI SDK integration.
704
+ *
705
+ * A detached sub-agent runs in another process (a queue worker, a container, a
706
+ * different machine) and does NOT block the caller. It reports as its own
707
+ * Raindrop event with its own lifecycle, so nothing implicit links the two —
708
+ * neither the OTel trace nor the event id survives the boundary. The link is
709
+ * carried explicitly: the caller stamps `raindrop.handoff.*` on the exact span
710
+ * that dispatched, the child stamps the reverse reference on every span it
711
+ * emits, and a carrier on the request/message body ties them together.
712
+ *
713
+ * The attribute names live in `@raindrop-ai/core`'s hand-off contract and are
714
+ * never re-spelled here.
715
+ *
716
+ * ## Trust boundary
717
+ *
718
+ * `resume()` reads a carrier that names the event the child will be attributed
719
+ * to, so accepting one from an untrusted caller lets that caller write into
720
+ * another tenant's trace. Only pass headers that came from inside your own trust
721
+ * boundary.
722
+ */
723
+
724
+ /**
725
+ * Output recorded for a child that ended without producing an answer.
726
+ *
727
+ * An event is created only from a run that reported something, so "nothing" is
728
+ * the one outcome a child cannot leave implicit.
729
+ */
730
+ declare const SUBAGENT_CANCELLED_OUTPUT = "Cancelled before producing a result.";
731
+ declare const SUBAGENT_ABORTED_OUTPUT = "Aborted before producing a result.";
732
+ /**
733
+ * The turn a launch is happening inside.
734
+ *
735
+ * Supplied by whatever holds spans open — the telemetry integration. Absent when
736
+ * a launch happens outside any instrumented generation (a plain queue producer),
737
+ * in which case the launch records its own dispatch span.
738
+ */
739
+ type ActiveDispatch = {
740
+ /** The caller's event id. */
741
+ eventId: string;
742
+ userId?: string;
743
+ convoId?: string;
744
+ /**
745
+ * The model's own tool-call span — the exact span that dispatched. Present
746
+ * only while a tool's `execute` is running on the AI SDK v7 native-telemetry
747
+ * path, which is the only place the dispatching span is still open.
748
+ */
749
+ dispatchSpan?: InternalSpan;
750
+ /** The turn's still-open spans, which carry the tool-events opt-in. */
751
+ turnSpans: InternalSpan[];
752
+ /**
753
+ * The turn's input-capture setting (`experimental_telemetry.recordInputs`).
754
+ * A dispatch span synthesized inside this turn records its `input` only when
755
+ * the turn allows input capture — the same gate every other span of the turn
756
+ * applies to what the caller sends.
757
+ */
758
+ recordInputs?: boolean;
759
+ };
760
+ /** What the hand-off API needs from whatever holds spans open. */
761
+ type HandoffSpanSource = {
762
+ activeDispatch(): ActiveDispatch | undefined;
763
+ /** Spans still open for a child's own event, for the terminal marker. */
764
+ openSpansForEvent(eventId: string): InternalSpan[];
765
+ };
766
+ type SubagentDispatchOptions = {
767
+ /** Sub-agent name. The child labels its own run with the same value. */
768
+ name?: string;
769
+ /**
770
+ * Name for the dispatch span, when this SDK has to synthesize one because no
771
+ * tool call was open. Defaults to `launch_subagent`. Dispatching from inside a
772
+ * tool's `execute` uses the model's own tool span, so this is ignored there.
773
+ */
774
+ toolName?: string;
775
+ /**
776
+ * Reuse an id the caller already has (a queue job id, say) instead of minting
777
+ * one. Either way the id is known BEFORE dispatch, which is what makes the
778
+ * link resolvable while the child is still queued.
779
+ */
780
+ childEventId?: string;
781
+ /** The caller's event id, when no instrumented turn is active to read it from. */
782
+ eventId?: string;
783
+ userId?: string;
784
+ convoId?: string;
785
+ /** Dispatch arguments, recorded on the dispatch span this call synthesizes. */
786
+ input?: unknown;
787
+ };
788
+ type SubagentDispatch = {
789
+ /** The child's event id. Send it with the job; the child reports under it. */
790
+ childEventId: string;
791
+ name?: string;
792
+ /** Headers to put on the dispatch. Empty when there was no caller context. */
793
+ headers: Record<string, string>;
794
+ /**
795
+ * The carrier behind {@link headers}, for transports that are not HTTP (a
796
+ * queue message body, a workflow input). `null` when no caller event id could
797
+ * be resolved, in which case the child still runs — it just has nothing to be
798
+ * attributed to.
799
+ */
800
+ carrier: TraceCarrier | null;
801
+ };
802
+ /**
803
+ * Fallbacks for a run with no carrier, i.e. a child invoked directly.
804
+ *
805
+ * These do NOT override a carrier. Every field here names something the caller
806
+ * already recorded on its dispatch span, so a local value winning would put the
807
+ * child somewhere the link does not reach: its own event id instead of the one
808
+ * the caller minted, or its own conversation instead of the supervisor's.
809
+ */
810
+ type SubagentResumeOptions = {
811
+ /** Used when the carrier supplied no name. */
812
+ name?: string;
813
+ /** Used when the carrier supplied no child event id. */
814
+ eventId?: string;
815
+ userId?: string;
816
+ convoId?: string;
817
+ };
818
+ /** Metadata for a child's generations. Spread straight into `eventMetadata()`. */
819
+ type SubagentRunMetadata = {
820
+ eventId: string;
821
+ userId?: string;
822
+ convoId?: string;
823
+ subagent?: DetachedChildLink;
824
+ };
825
+ type SubagentRun = {
826
+ /** The child's OWN event id, adopted from the carrier when it supplied one. */
827
+ eventId: string;
828
+ name?: string;
829
+ userId?: string;
830
+ convoId?: string;
831
+ /** The caller that dispatched this run, or `null` when invoked directly. */
832
+ parent: DetachedChildLink | null;
833
+ /** Pass to `eventMetadata()` on every generation this run makes. */
834
+ metadata: SubagentRunMetadata;
835
+ /**
836
+ * Report that the run was cancelled.
837
+ *
838
+ * A cancelled run is span-for-span identical to a finished one — spans close,
839
+ * nothing errors, there is just no answer — so it is the one outcome that
840
+ * needs stating explicitly. Written by the child on itself, never by the
841
+ * caller. The reason is recorded as the run's output, because a child that
842
+ * ends without output produces no event at all and leaves the caller unable
843
+ * to tell a failure from a job that never started.
844
+ */
845
+ cancel(reason?: string): Promise<void>;
846
+ /**
847
+ * Report that the run failed, recording `reason` as its output for the same
848
+ * reason {@link cancel} does. Use this when the failure happens outside a
849
+ * generation (the job died before reaching the model); a generation that
850
+ * throws already reports itself.
851
+ */
852
+ fail(reason: unknown): Promise<void>;
853
+ };
854
+ type SubagentApiOptions = {
855
+ traceShipper: TraceShipper;
856
+ eventShipper: EventShipper;
857
+ sendTraces: boolean;
858
+ sendEvents: boolean;
859
+ debug: boolean;
860
+ spanSource?: HandoffSpanSource;
861
+ defaultContext?: {
862
+ userId?: string;
863
+ convoId?: string;
864
+ eventId?: string;
865
+ };
866
+ /**
867
+ * Which child events have already reported an outcome, shared across every
868
+ * `SubagentApi` built from one client.
869
+ *
870
+ * A client exposes `subagents` and each telemetry integration owns another
871
+ * instance, but a child settles on one and finishes its generation on the
872
+ * other. Keeping this per-instance let the integration's finalizer overwrite
873
+ * an explicit `cancel()` with a generic finish, dropping the terminal marker
874
+ * and deriving `finished` for a run that was cancelled.
875
+ */
876
+ settledEventIds?: Set<string>;
877
+ };
878
+ declare class SubagentApi {
879
+ private readonly opts;
880
+ /**
881
+ * Child events whose outcome `cancel()` / `fail()` already reported, so the
882
+ * generation finalizer does not overwrite an explicit reason with a generic
883
+ * one when the run also ends through the AI SDK.
884
+ */
885
+ private readonly settledEventIds;
886
+ constructor(opts: SubagentApiOptions);
887
+ /** True when this child's outcome has already been reported. */
888
+ wasSettledExplicitly(eventId: string): boolean;
889
+ /**
890
+ * Record an outcome reported somewhere other than `cancel()` / `fail()`, so
891
+ * first-outcome-wins holds across every path that can state one.
892
+ *
893
+ * An aborted generation is such a path: an AbortSignal cancellation IS the
894
+ * run's outcome, and the `fail(err)` that a catch block around the aborted
895
+ * call naturally reports would otherwise error the child's spans — which is
896
+ * the only thing separating `failed` from `cancelled`.
897
+ */
898
+ noteSettled(eventId: string): void;
899
+ private remember;
900
+ /**
901
+ * Record a detached sub-agent on this turn: allocate the child's event id,
902
+ * stamp the dispatch, and return the headers to send with the job.
903
+ *
904
+ * This dispatches nothing — you do, moments later, with the returned headers.
905
+ * Nothing here waits for the child either, or claims to know how it is doing.
906
+ * Readers derive that from the child's own event.
907
+ */
908
+ subagent(options?: SubagentDispatchOptions): SubagentDispatch;
909
+ private recordLaunch;
910
+ /**
911
+ * Record a dispatch span for a launch with no open tool-call span to decorate:
912
+ * a launch from outside a tool's `execute`, or from a caller that is not an
913
+ * LLM turn at all (an HTTP handler that enqueues jobs). Shaped as a tool call
914
+ * so it reads identically to a model-issued launch.
915
+ */
916
+ private synthesizeDispatchSpan;
917
+ /**
918
+ * Adopt a carrier as the current run's parent reference.
919
+ *
920
+ * A missing carrier is a legitimate state — the child was invoked directly
921
+ * rather than dispatched — so this always returns a usable run and leaves
922
+ * `parent` null. Call sites stay unconditional.
923
+ */
924
+ resume(carrierOrHeaders: CarrierHeaders | TraceCarrier | null | undefined, options?: SubagentResumeOptions): SubagentRun;
925
+ /**
926
+ * A carrier arrives from outside this process, so a hostile or merely broken
927
+ * header bag must cost the job its link, never its run.
928
+ */
929
+ private readCarrier;
930
+ /**
931
+ * Mark a failed child's own spans as errored.
932
+ *
933
+ * Reporting the reason as output is what gets the child an event at all, but
934
+ * output alone is not enough: status is derived from span shape, and a child
935
+ * with final output and no error spans derives `finished`. A failed job
936
+ * reporting success is worse than one reporting nothing, so the failure has
937
+ * to land on the telemetry too, not just in the text.
938
+ *
939
+ * This is the child describing its own run, not a caller writing a status it
940
+ * cannot observe — the child's own spans are exactly where the contract puts
941
+ * failure.
942
+ */
943
+ private recordFailureOnSpans;
944
+ private settle;
945
+ }
946
+
512
947
  /**
513
948
  * Raindrop telemetry integration for AI SDK v7+
514
949
  *
@@ -607,6 +1042,8 @@ type RaindropTelemetryIntegrationOptions = {
607
1042
  */
608
1043
  subagentWrapping?: boolean;
609
1044
  debug?: boolean;
1045
+ /** See {@link SubagentApiOptions.settledEventIds}. */
1046
+ settledEventIds?: Set<string>;
610
1047
  context?: {
611
1048
  userId?: string;
612
1049
  eventId?: string;
@@ -641,7 +1078,51 @@ declare class RaindropTelemetryIntegration implements TelemetryIntegration {
641
1078
  * (the `event.callId` can be the same for parallel sibling tools).
642
1079
  */
643
1080
  private readonly priorParentContexts;
1081
+ /**
1082
+ * Detached sub-agent hand-offs: record a sub-agent that runs in another
1083
+ * process and reports as its own event, or resume one here from a carrier.
1084
+ *
1085
+ * @see {@link SubagentApi}
1086
+ */
1087
+ readonly subagents: SubagentApi;
1088
+ /**
1089
+ * Record a detached sub-agent on the turn that is live right now.
1090
+ *
1091
+ * Returns the dispatch — the child's event id and the headers to send with
1092
+ * the job. Dispatching is still yours to do; this only states that you are
1093
+ * about to, so a reader can follow the link before the child exists.
1094
+ */
1095
+ subagent(options?: SubagentDispatchOptions): SubagentDispatch;
644
1096
  constructor(opts: RaindropTelemetryIntegrationOptions);
1097
+ /**
1098
+ * The turn a `subagent()` dispatch is happening inside.
1099
+ *
1100
+ * Resolved from the parent-tool context first, which is the only way to reach
1101
+ * the EXACT span that dispatched: the tool call the model itself issued, still
1102
+ * open while its `execute` runs. Falling back to the event id lets a launch
1103
+ * from elsewhere in the turn (a queue producer called mid-generation) still
1104
+ * find the turn's spans, which is where the tool-events opt-in has to land.
1105
+ */
1106
+ private activeDispatch;
1107
+ /** Spans still open for an event, so a late outcome can still be stated. */
1108
+ private openSpansForEvent;
1109
+ /**
1110
+ * End-attributes that keep a detached child legible when it ends without an
1111
+ * answer — an error, an abort, a cancellation.
1112
+ *
1113
+ * An event is created from an LLM span only when it has a finish reason and
1114
+ * non-empty output, so a child that dies silently produces NO event, and the
1115
+ * caller's hand-off pill stays on `queued` forever — indistinguishable from a
1116
+ * job that never started. Reporting the abort reason as the run's output is
1117
+ * what makes the outcome visible. Only detached children get this: an inline
1118
+ * generation's failure is already legible from its caller's own event.
1119
+ *
1120
+ * And only the run's OUTERMOST generation gets it (see `nestedInEvent`): an
1121
+ * inner sub-call ending badly is not the run ending, and since an event is
1122
+ * created from an LLM span with output, `ai.response.text` here would state
1123
+ * the run's outcome through the span while the turn is still working.
1124
+ */
1125
+ private abortOutcomeAttrs;
645
1126
  /** Flush any buffered events and trace spans to their destinations. */
646
1127
  flush: () => Promise<void>;
647
1128
  /** Flush and stop the background flush timers. */
@@ -892,6 +1373,30 @@ type EventMetadataOptions = {
892
1373
  properties?: Record<string, unknown>;
893
1374
  /** Feature flags to attach to this event (merged with wrap-time flags; call-time wins) */
894
1375
  featureFlags?: FeatureFlags;
1376
+ /**
1377
+ * Marks this generation as a DETACHED sub-agent's own run and references the
1378
+ * caller that dispatched it. Pass `run.parent` from
1379
+ * `subagents.resume(headers)`, or spread `run.metadata` in place of this whole
1380
+ * options object.
1381
+ *
1382
+ * The reference is what links a child that shares neither trace nor event with
1383
+ * its caller. It lands on every span the run emits, because spans are ingested
1384
+ * and projected independently.
1385
+ */
1386
+ subagent?: DetachedChildLink;
1387
+ /**
1388
+ * Opt this turn in to producing an event even when its entire content is tool
1389
+ * calls.
1390
+ *
1391
+ * A turn that only dispatches work finishes with
1392
+ * `ai.response.finishReason = "tool-calls"` and no assistant text, and ingest
1393
+ * drops such turns by default as intermediate steps. For a dispatch-only turn
1394
+ * the tool calls ARE the content, so without this the caller's event is never
1395
+ * created and a hand-off has nothing to attach to. `subagent()` sets it on
1396
+ * the live turn; pass it here when the dispatch happens outside a turn this
1397
+ * SDK instruments (the AI SDK v4-v6 `wrap()` path).
1398
+ */
1399
+ toolEvents?: typeof TOOL_EVENTS_ALLOW;
895
1400
  };
896
1401
  /**
897
1402
  * Creates metadata for use with the AI SDK's `experimental_telemetry.metadata` option.
@@ -1311,6 +1816,32 @@ type RaindropAISDKClient = {
1311
1816
  context?: RaindropTelemetryIntegrationOptions["context"];
1312
1817
  subagentWrapping?: boolean;
1313
1818
  }): RaindropTelemetryIntegration;
1819
+ /**
1820
+ * Detached sub-agent hand-offs: record a sub-agent that runs in another
1821
+ * process and reports as its own event, or resume one here from a carrier.
1822
+ *
1823
+ * On the AI SDK v7 native-telemetry path prefer
1824
+ * `createTelemetryIntegration().subagents`. An integration knows which turn is
1825
+ * live, so it can stamp the hand-off on the exact span the model dispatched
1826
+ * from and put the tool-events opt-in on the caller's turn. This one records
1827
+ * its own dispatch span instead, and the opt-in has to come from
1828
+ * `eventMetadata({ toolEvents: "allow" })` on the caller's call.
1829
+ *
1830
+ * TRUST BOUNDARY: `resume()` reads a carrier that names the event the child
1831
+ * will be attributed to. Only pass headers from inside your own trust
1832
+ * boundary.
1833
+ */
1834
+ subagents: SubagentApi;
1835
+ /**
1836
+ * Record a detached sub-agent: allocate the child's event id, stamp the
1837
+ * dispatch, and hand back the headers to send with the job.
1838
+ *
1839
+ * Named for what it records, not for an action it performs — dispatching the
1840
+ * job stays yours. Mirrors `interaction.subagent()` in `raindrop-ai` and the
1841
+ * Python SDK. On the v7 native-telemetry path prefer
1842
+ * `createTelemetryIntegration().subagent()`, which knows which turn is live.
1843
+ */
1844
+ subagent(options?: SubagentDispatchOptions): SubagentDispatch;
1314
1845
  events: {
1315
1846
  patch(eventId: string, patch: EventPatch): Promise<void>;
1316
1847
  addAttachments(eventId: string, attachments: Attachment[]): Promise<void>;
@@ -1431,4 +1962,4 @@ type RaindropTelemetryOptions = RaindropAISDKOptions & {
1431
1962
  */
1432
1963
  declare function raindrop(options?: RaindropTelemetryOptions): RaindropTelemetryIntegration;
1433
1964
 
1434
- export { type AISDKChatRequestLike, type AISDKChatRequestMessageLike, type AISDKMessage, type AgentCallMetadata, type AgentWithMetadata, type Attachment, type BuildEventPatch, ContextManager, type ContextSpan, type CreateSpanArgs, DEFAULT_MAX_TEXT_FIELD_CHARS, DEFAULT_REDACT_ATTRIBUTE_KEYS, DEFAULT_SECRET_KEY_NAMES, type EndSpanArgs, type EventBuilder, type EventMetadataOptions, type FeatureFlagValue, type FeatureFlags, type IdentifyInput, type OtlpAnyValue, type OtlpSpan, type ParentToolContext, REDACTED_PLACEHOLDER, type RaindropAISDKClient, type RaindropAISDKContext, type RaindropAISDKOptions, type RaindropCallMetadata, RaindropTelemetryIntegration, type RaindropTelemetryIntegrationOptions, type RaindropTelemetryOptions, type SelfDiagnosticsOptions, type SelfDiagnosticsSignalDefinition, type SelfDiagnosticsSignalDefinitions, type SelfDiagnosticsTool, type SelfDiagnosticsToolInput, type SelfDiagnosticsToolOptions, type SelfDiagnosticsToolResult, type StartSpanArgs, TRUNCATION_MARKER, type TraceSpan, type TransformSpanHook, type WrapAISDKOptions, type WrappedAI, type WrappedAISDK, _resetParentToolContextStorage, _resetRaindropCallMetadataStorage, _resetWarnedMissingUserId, boundedStringify, capText, clearParentToolContext, createRaindropAISDK, currentSpan, defaultTransformSpan, enterParentToolContext, eventMetadata, eventMetadataFromChatRequest, getContextManager, getCurrentParentToolContext, getCurrentRaindropCallMetadata, normalizeFeatureFlags, raindrop, readRaindropCallMetadataFromArgs, redactJsonAttributeValue, redactSecretsInObject, runWithParentToolContext, runWithRaindropCallMetadata, withCurrent };
1965
+ export { type AISDKChatRequestLike, type AISDKChatRequestMessageLike, type AISDKMessage, type AgentCallMetadata, type AgentWithMetadata, type Attachment, type BuildEventPatch, type CarrierHeaders, ContextManager, type ContextSpan, type CreateSpanArgs, DEFAULT_MAX_TEXT_FIELD_CHARS, DEFAULT_REDACT_ATTRIBUTE_KEYS, DEFAULT_SECRET_KEY_NAMES, DETACHED_MODE, type DetachedChildLink, type DetachedDispatch, type EndSpanArgs, type EventBuilder, type EventMetadataOptions, type FeatureFlagValue, type FeatureFlags, HANDOFF_ATTRIBUTE_PREFIXES, HANDOFF_ATTRIBUTE_SUFFIXES, HANDOFF_TERMINAL_CANCELLED, HANDOFF_TERMINAL_PROPERTY_KEY, type IdentifyInput, type OtlpAnyValue, type OtlpSpan, type ParentToolContext, REDACTED_PLACEHOLDER, type RaindropAISDKClient, type RaindropAISDKContext, type RaindropAISDKOptions, type RaindropCallMetadata, RaindropTelemetryIntegration, type RaindropTelemetryIntegrationOptions, type RaindropTelemetryOptions, SUBAGENT_ABORTED_OUTPUT, SUBAGENT_AGENT_ROLE, SUBAGENT_CANCELLED_OUTPUT, type SelfDiagnosticsOptions, type SelfDiagnosticsSignalDefinition, type SelfDiagnosticsSignalDefinitions, type SelfDiagnosticsTool, type SelfDiagnosticsToolInput, type SelfDiagnosticsToolOptions, type SelfDiagnosticsToolResult, type StartSpanArgs, SubagentApi, type SubagentDispatch, type SubagentDispatchOptions, type SubagentResumeOptions, type SubagentRun, type SubagentRunMetadata, TOOL_EVENTS_ALLOW, TRUNCATION_MARKER, type TraceCarrier, type TraceSpan, type TransformSpanHook, type WrapAISDKOptions, type WrappedAI, type WrappedAISDK, _resetParentToolContextStorage, _resetRaindropCallMetadataStorage, _resetWarnedMissingUserId, boundedStringify, capText, clearParentToolContext, createRaindropAISDK, currentSpan, defaultTransformSpan, enterParentToolContext, eventMetadata, eventMetadataFromChatRequest, fromHeaders, getContextManager, getCurrentParentToolContext, getCurrentRaindropCallMetadata, normalizeFeatureFlags, raindrop, readRaindropCallMetadataFromArgs, redactJsonAttributeValue, redactSecretsInObject, resetUnresolvedCarrierWarning, runWithParentToolContext, runWithRaindropCallMetadata, toHeaders, toLangSmithHeaders, withCurrent };