@strands-agents/sdk 1.8.0 → 1.10.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.
Files changed (127) hide show
  1. package/dist/src/agent/agent.d.ts +31 -1
  2. package/dist/src/agent/agent.d.ts.map +1 -1
  3. package/dist/src/agent/agent.js +92 -4
  4. package/dist/src/agent/agent.js.map +1 -1
  5. package/dist/src/conversation-manager/sliding-window-conversation-manager.d.ts.map +1 -1
  6. package/dist/src/conversation-manager/sliding-window-conversation-manager.js +2 -0
  7. package/dist/src/conversation-manager/sliding-window-conversation-manager.js.map +1 -1
  8. package/dist/src/errors.d.ts +22 -0
  9. package/dist/src/errors.d.ts.map +1 -1
  10. package/dist/src/errors.js +28 -0
  11. package/dist/src/errors.js.map +1 -1
  12. package/dist/src/experimental/checkpoint.d.ts +118 -0
  13. package/dist/src/experimental/checkpoint.d.ts.map +1 -0
  14. package/dist/src/experimental/checkpoint.js +108 -0
  15. package/dist/src/experimental/checkpoint.js.map +1 -0
  16. package/dist/src/experimental/index.d.ts +10 -0
  17. package/dist/src/experimental/index.d.ts.map +1 -0
  18. package/dist/src/experimental/index.js +9 -0
  19. package/dist/src/experimental/index.js.map +1 -0
  20. package/dist/src/index.d.ts +2 -1
  21. package/dist/src/index.d.ts.map +1 -1
  22. package/dist/src/index.js +1 -1
  23. package/dist/src/index.js.map +1 -1
  24. package/dist/src/injection/message-injection.d.ts.map +1 -1
  25. package/dist/src/injection/message-injection.js +2 -0
  26. package/dist/src/injection/message-injection.js.map +1 -1
  27. package/dist/src/models/bedrock.d.ts.map +1 -1
  28. package/dist/src/models/bedrock.js +23 -1
  29. package/dist/src/models/bedrock.js.map +1 -1
  30. package/dist/src/models/openai/mantle.d.ts +6 -2
  31. package/dist/src/models/openai/mantle.d.ts.map +1 -1
  32. package/dist/src/models/openai/mantle.js +17 -3
  33. package/dist/src/models/openai/mantle.js.map +1 -1
  34. package/dist/src/models/openai/model.d.ts.map +1 -1
  35. package/dist/src/models/openai/model.js +4 -3
  36. package/dist/src/models/openai/model.js.map +1 -1
  37. package/dist/src/multiagent/graph.d.ts.map +1 -1
  38. package/dist/src/multiagent/graph.js +1 -1
  39. package/dist/src/multiagent/graph.js.map +1 -1
  40. package/dist/src/multiagent/multiagent.d.ts +2 -1
  41. package/dist/src/multiagent/multiagent.d.ts.map +1 -1
  42. package/dist/src/multiagent/multiagent.js.map +1 -1
  43. package/dist/src/{multiagent/queue.d.ts → queue.d.ts} +12 -27
  44. package/dist/src/queue.d.ts.map +1 -0
  45. package/dist/src/{multiagent/queue.js → queue.js} +4 -2
  46. package/dist/src/queue.js.map +1 -0
  47. package/dist/src/session/file-storage.d.ts +3 -0
  48. package/dist/src/session/file-storage.d.ts.map +1 -1
  49. package/dist/src/session/file-storage.js +3 -0
  50. package/dist/src/session/file-storage.js.map +1 -1
  51. package/dist/src/session/s3-storage.d.ts +3 -0
  52. package/dist/src/session/s3-storage.d.ts.map +1 -1
  53. package/dist/src/session/s3-storage.js +3 -0
  54. package/dist/src/session/s3-storage.js.map +1 -1
  55. package/dist/src/session/session-manager.d.ts +11 -2
  56. package/dist/src/session/session-manager.d.ts.map +1 -1
  57. package/dist/src/session/session-manager.js +19 -8
  58. package/dist/src/session/session-manager.js.map +1 -1
  59. package/dist/src/session/snapshot-storage-adapter.d.ts +93 -0
  60. package/dist/src/session/snapshot-storage-adapter.d.ts.map +1 -0
  61. package/dist/src/session/snapshot-storage-adapter.js +157 -0
  62. package/dist/src/session/snapshot-storage-adapter.js.map +1 -0
  63. package/dist/src/session/storage.d.ts +3 -6
  64. package/dist/src/session/storage.d.ts.map +1 -1
  65. package/dist/src/storage/in-memory-storage.d.ts +64 -0
  66. package/dist/src/storage/in-memory-storage.d.ts.map +1 -0
  67. package/dist/src/storage/in-memory-storage.js +85 -0
  68. package/dist/src/storage/in-memory-storage.js.map +1 -0
  69. package/dist/src/storage/index.d.ts +20 -0
  70. package/dist/src/storage/index.d.ts.map +1 -0
  71. package/dist/src/storage/index.js +18 -0
  72. package/dist/src/storage/index.js.map +1 -0
  73. package/dist/src/storage/local-file-storage.d.ts +81 -0
  74. package/dist/src/storage/local-file-storage.d.ts.map +1 -0
  75. package/dist/src/storage/local-file-storage.js +244 -0
  76. package/dist/src/storage/local-file-storage.js.map +1 -0
  77. package/dist/src/storage/s3-storage.d.ts +73 -0
  78. package/dist/src/storage/s3-storage.d.ts.map +1 -0
  79. package/dist/src/storage/s3-storage.js +146 -0
  80. package/dist/src/storage/s3-storage.js.map +1 -0
  81. package/dist/src/storage/storage.d.ts +102 -0
  82. package/dist/src/storage/storage.d.ts.map +1 -0
  83. package/dist/src/storage/storage.js +68 -0
  84. package/dist/src/storage/storage.js.map +1 -0
  85. package/dist/src/telemetry/tracer.d.ts +18 -0
  86. package/dist/src/telemetry/tracer.d.ts.map +1 -1
  87. package/dist/src/telemetry/tracer.js +31 -11
  88. package/dist/src/telemetry/tracer.js.map +1 -1
  89. package/dist/src/tsconfig.tsbuildinfo +1 -1
  90. package/dist/src/types/agent.d.ts +19 -1
  91. package/dist/src/types/agent.d.ts.map +1 -1
  92. package/dist/src/types/agent.js +12 -0
  93. package/dist/src/types/agent.js.map +1 -1
  94. package/dist/src/types/messages.d.ts +22 -1
  95. package/dist/src/types/messages.d.ts.map +1 -1
  96. package/dist/src/types/messages.js +22 -0
  97. package/dist/src/types/messages.js.map +1 -1
  98. package/dist/src/vended-memory-stores/test-memory-store/index.d.ts +2 -0
  99. package/dist/src/vended-memory-stores/test-memory-store/index.d.ts.map +1 -0
  100. package/dist/src/vended-memory-stores/test-memory-store/index.js +2 -0
  101. package/dist/src/vended-memory-stores/test-memory-store/index.js.map +1 -0
  102. package/dist/src/vended-memory-stores/{local → test-memory-store}/store.d.ts +10 -10
  103. package/dist/src/vended-memory-stores/test-memory-store/store.d.ts.map +1 -0
  104. package/dist/src/vended-memory-stores/{local → test-memory-store}/store.js +15 -15
  105. package/dist/src/vended-memory-stores/test-memory-store/store.js.map +1 -0
  106. package/dist/src/vended-plugins/context-offloader/plugin.d.ts +37 -5
  107. package/dist/src/vended-plugins/context-offloader/plugin.d.ts.map +1 -1
  108. package/dist/src/vended-plugins/context-offloader/plugin.js +116 -17
  109. package/dist/src/vended-plugins/context-offloader/plugin.js.map +1 -1
  110. package/dist/src/vended-plugins/context-offloader/storage.d.ts +23 -9
  111. package/dist/src/vended-plugins/context-offloader/storage.d.ts.map +1 -1
  112. package/dist/src/vended-plugins/context-offloader/storage.js +17 -6
  113. package/dist/src/vended-plugins/context-offloader/storage.js.map +1 -1
  114. package/dist/src/vended-tools/notebook/notebook.d.ts +1 -1
  115. package/package.json +31 -24
  116. package/dist/src/conversation-manager/index.d.ts +0 -10
  117. package/dist/src/conversation-manager/index.d.ts.map +0 -1
  118. package/dist/src/conversation-manager/index.js +0 -10
  119. package/dist/src/conversation-manager/index.js.map +0 -1
  120. package/dist/src/multiagent/queue.d.ts.map +0 -1
  121. package/dist/src/multiagent/queue.js.map +0 -1
  122. package/dist/src/vended-memory-stores/local/index.d.ts +0 -2
  123. package/dist/src/vended-memory-stores/local/index.d.ts.map +0 -1
  124. package/dist/src/vended-memory-stores/local/index.js +0 -2
  125. package/dist/src/vended-memory-stores/local/index.js.map +0 -1
  126. package/dist/src/vended-memory-stores/local/store.d.ts.map +0 -1
  127. package/dist/src/vended-memory-stores/local/store.js.map +0 -1
@@ -0,0 +1,146 @@
1
+ import { StorageError } from '../errors.js';
2
+ import { namespace, normalizeKey, normalizePrefix } from './storage.js';
3
+ const S3_PAGE_SIZE = 1000;
4
+ /**
5
+ * Amazon S3 {@link Storage} backend.
6
+ *
7
+ * Stores each key as an S3 object under an optional prefix. The AWS SDK is loaded
8
+ * lazily on first use and declared as an optional peer dependency, so consumers that
9
+ * never construct an `S3Storage` are not required to install `@aws-sdk/client-s3`.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { S3Storage } from '@strands-agents/sdk/storage'
14
+ *
15
+ * const storage = new S3Storage('my-bucket', { prefix: 'agents/' })
16
+ * await storage.write('sessions/abc/snapshot.json', bytes)
17
+ * ```
18
+ */
19
+ export class S3Storage {
20
+ _bucket;
21
+ _prefix;
22
+ _region;
23
+ _client;
24
+ /**
25
+ * @param bucket - Target S3 bucket name
26
+ * @param config - Optional prefix, region, or pre-configured client
27
+ * @throws {@link StorageError} if both `region` and `s3Client` are provided
28
+ */
29
+ constructor(bucket, config) {
30
+ if (config?.s3Client && config.region) {
31
+ throw new StorageError('Cannot specify both s3Client and region. Configure the region on the S3Client instead.');
32
+ }
33
+ this._bucket = bucket;
34
+ this._prefix = config?.prefix ? config.prefix.split('/').filter(Boolean).join('/') + '/' : '';
35
+ this._region = config?.region;
36
+ this._client = config?.s3Client;
37
+ }
38
+ /**
39
+ * Stores `data` under `key`, overwriting any existing value.
40
+ *
41
+ * @param key - Opaque, `/`-separated key identifying the value
42
+ * @param data - Raw bytes to persist
43
+ * @throws {@link StorageError} if the key is invalid or the upload fails
44
+ */
45
+ async write(key, data) {
46
+ const normalized = normalizeKey(key);
47
+ const client = await this._getClient();
48
+ const { PutObjectCommand } = await import('@aws-sdk/client-s3');
49
+ try {
50
+ await client.send(new PutObjectCommand({ Bucket: this._bucket, Key: this._objectKey(normalized), Body: data }));
51
+ }
52
+ catch (error) {
53
+ throw new StorageError(`Failed to write '${normalized}' to S3 bucket '${this._bucket}'`, { cause: error });
54
+ }
55
+ }
56
+ /**
57
+ * Retrieves the bytes previously stored under `key`.
58
+ *
59
+ * @param key - The key to read
60
+ * @returns The stored bytes, or `null` if no value exists for `key`
61
+ * @throws {@link StorageError} if the key is invalid or the download fails
62
+ */
63
+ async read(key) {
64
+ const normalized = normalizeKey(key);
65
+ const client = await this._getClient();
66
+ const { GetObjectCommand } = await import('@aws-sdk/client-s3');
67
+ try {
68
+ const response = await client.send(new GetObjectCommand({ Bucket: this._bucket, Key: this._objectKey(normalized) }));
69
+ const body = await response.Body?.transformToByteArray();
70
+ return body ? new Uint8Array(body) : null;
71
+ }
72
+ catch (error) {
73
+ if (error instanceof Error && (error.name === 'NoSuchKey' || error.name === 'NotFound')) {
74
+ return null;
75
+ }
76
+ throw new StorageError(`Failed to read '${normalized}' from S3 bucket '${this._bucket}'`, { cause: error });
77
+ }
78
+ }
79
+ /**
80
+ * Deletes the value stored under `key`. A no-op if the key does not exist.
81
+ *
82
+ * @param key - The key to delete
83
+ * @throws {@link StorageError} if the key is invalid or the delete request fails
84
+ */
85
+ async delete(key) {
86
+ const normalized = normalizeKey(key);
87
+ const client = await this._getClient();
88
+ const { DeleteObjectCommand } = await import('@aws-sdk/client-s3');
89
+ try {
90
+ await client.send(new DeleteObjectCommand({ Bucket: this._bucket, Key: this._objectKey(normalized) }));
91
+ }
92
+ catch (error) {
93
+ throw new StorageError(`Failed to delete '${normalized}' from S3 bucket '${this._bucket}'`, { cause: error });
94
+ }
95
+ }
96
+ /**
97
+ * Lists the keys whose names begin with `prefix`, sorted lexicographically.
98
+ *
99
+ * @param prefix - Key prefix to match. An empty string matches all keys.
100
+ * @returns The matching keys, sorted ascending
101
+ * @throws {@link StorageError} if the prefix is invalid or the list request fails
102
+ */
103
+ async list(prefix) {
104
+ const normalized = normalizePrefix(prefix);
105
+ const client = await this._getClient();
106
+ const { ListObjectsV2Command } = await import('@aws-sdk/client-s3');
107
+ const listPrefix = `${this._prefix}${normalized}`;
108
+ const keys = [];
109
+ let continuationToken;
110
+ try {
111
+ do {
112
+ const response = await client.send(new ListObjectsV2Command({
113
+ Bucket: this._bucket,
114
+ Prefix: listPrefix,
115
+ MaxKeys: S3_PAGE_SIZE,
116
+ ContinuationToken: continuationToken,
117
+ }));
118
+ for (const object of response.Contents ?? []) {
119
+ if (object.Key === undefined)
120
+ continue;
121
+ keys.push(this._prefix ? object.Key.slice(this._prefix.length) : object.Key);
122
+ }
123
+ continuationToken = response.IsTruncated ? response.NextContinuationToken : undefined;
124
+ } while (continuationToken);
125
+ }
126
+ catch (error) {
127
+ throw new StorageError(`Failed to list S3 bucket '${this._bucket}' under '${normalized}'`, { cause: error });
128
+ }
129
+ return keys.sort();
130
+ }
131
+ async _getClient() {
132
+ if (this._client)
133
+ return this._client;
134
+ const { S3Client } = await import('@aws-sdk/client-s3');
135
+ this._client = new S3Client(this._region ? { region: this._region } : {});
136
+ return this._client;
137
+ }
138
+ /** Returns a prefixed view of this storage without mutating the original. */
139
+ namespace(prefix) {
140
+ return namespace(this, prefix);
141
+ }
142
+ _objectKey(key) {
143
+ return `${this._prefix}${key}`;
144
+ }
145
+ }
146
+ //# sourceMappingURL=s3-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-storage.js","sourceRoot":"","sources":["../../../src/storage/s3-storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Symbol present on namespaced storage views. Constructs use this to detect
3
+ * whether the caller already scoped the storage, skipping the default prefix.
4
+ *
5
+ * @internal
6
+ */
7
+ export declare const NAMESPACED: unique symbol;
8
+ /**
9
+ * Validates and normalizes a storage key: collapses runs of `/`, strips leading
10
+ * and trailing `/`, and rejects empty keys and any `..` segment.
11
+ *
12
+ * @param key - The raw key to normalize
13
+ * @returns The normalized key
14
+ * @throws {@link StorageError} if the key is empty or contains a `..` segment
15
+ */
16
+ export declare function normalizeKey(key: string): string;
17
+ /**
18
+ * Normalizes a list prefix: collapses slash runs, strips leading slashes.
19
+ * Unlike a key, an empty prefix is valid and matches everything.
20
+ *
21
+ * @param prefix - The raw prefix to normalize
22
+ * @returns The normalized prefix
23
+ * @throws {@link StorageError} if the prefix contains a `..` segment
24
+ */
25
+ export declare function normalizePrefix(prefix: string): string;
26
+ /**
27
+ * A backend for storing and retrieving raw bytes under string keys.
28
+ *
29
+ * The interface is deliberately minimal — four operations over opaque `Uint8Array`
30
+ * values. Implementations must treat keys as opaque path-like strings (segments
31
+ * separated by `/`) and must round-trip the bytes they are given unchanged.
32
+ *
33
+ * The `ListQuery` type parameter controls what `list` accepts. It defaults to
34
+ * `string` (a key prefix), which every backend supports. Implementations may
35
+ * widen it to accept a richer query object (e.g. a DynamoDB partition/sort-key
36
+ * filter) while still accepting a plain string for SDK-internal callers.
37
+ *
38
+ * Implement this to add a custom backend; the SDK ships {@link InMemoryStorage},
39
+ * {@link LocalFileStorage}, and {@link S3Storage}.
40
+ */
41
+ export interface Storage<ListQuery = string> {
42
+ /**
43
+ * Stores `data` under `key`, overwriting any existing value.
44
+ *
45
+ * @param key - Opaque, `/`-separated key identifying the value
46
+ * @param data - Raw bytes to persist
47
+ * @throws {@link StorageError} if the write fails
48
+ */
49
+ write(key: string, data: Uint8Array): Promise<void>;
50
+ /**
51
+ * Retrieves the bytes previously stored under `key`.
52
+ *
53
+ * @param key - The key to read
54
+ * @returns The stored bytes, or `null` if no value exists for `key`
55
+ * @throws {@link StorageError} if the read fails for a reason other than a missing key
56
+ */
57
+ read(key: string): Promise<Uint8Array | null>;
58
+ /**
59
+ * Deletes the value stored under `key`. A no-op if the key does not exist.
60
+ *
61
+ * @param key - The key to delete
62
+ * @throws {@link StorageError} if the delete fails
63
+ */
64
+ delete(key: string): Promise<void>;
65
+ /**
66
+ * Lists keys matching the given query.
67
+ *
68
+ * When `ListQuery` is `string` (the default), this is a prefix match — returns
69
+ * full keys (not the suffix after the prefix), sorted lexicographically. An empty
70
+ * string lists every key.
71
+ *
72
+ * Implementations may accept richer query objects (e.g. partition + sort-key filters)
73
+ * while still supporting a plain string prefix for SDK-internal callers.
74
+ *
75
+ * @param query - A string prefix or backend-specific query object
76
+ * @returns The matching keys, sorted ascending
77
+ * @throws {@link StorageError} if the listing fails
78
+ */
79
+ list(query: ListQuery): Promise<string[]>;
80
+ /**
81
+ * Returns a view of this storage with all keys prefixed by `prefix`.
82
+ * The original storage is not mutated.
83
+ *
84
+ * Optional — shipped backends implement this, custom backends may omit it.
85
+ *
86
+ * @param prefix - Prefix to prepend to all keys
87
+ * @returns A Storage view scoped to the given prefix
88
+ */
89
+ namespace?(prefix: string): Storage;
90
+ }
91
+ /**
92
+ * Returns a {@link Storage} view with all keys prefixed by `prefix`.
93
+ *
94
+ * Composable — calling `namespace()` on the result nests prefixes.
95
+ *
96
+ * @internal
97
+ * @param storage - The underlying storage to delegate to
98
+ * @param prefix - Prefix to prepend to all keys
99
+ * @returns A namespaced Storage view
100
+ */
101
+ export declare function namespace(storage: Storage, prefix: string): Storage;
102
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/storage/storage.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,UAAU,EAAE,OAAO,MAAiD,CAAA;AAEjF;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAShD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAStD;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,OAAO,CAAC,SAAS,GAAG,MAAM;IACzC;;;;;;OAMG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEnD;;;;;;OAMG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;IAE7C;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAElC;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IAEzC;;;;;;;;OAQG;IACH,SAAS,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;CACpC;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAYnE"}
@@ -0,0 +1,68 @@
1
+ import { StorageError } from '../errors.js';
2
+ /**
3
+ * Symbol present on namespaced storage views. Constructs use this to detect
4
+ * whether the caller already scoped the storage, skipping the default prefix.
5
+ *
6
+ * @internal
7
+ */
8
+ export const NAMESPACED = Symbol.for('strands.storage.namespaced');
9
+ /**
10
+ * Validates and normalizes a storage key: collapses runs of `/`, strips leading
11
+ * and trailing `/`, and rejects empty keys and any `..` segment.
12
+ *
13
+ * @param key - The raw key to normalize
14
+ * @returns The normalized key
15
+ * @throws {@link StorageError} if the key is empty or contains a `..` segment
16
+ */
17
+ export function normalizeKey(key) {
18
+ const segments = key.split('/').filter(Boolean);
19
+ if (segments.length === 0) {
20
+ throw new StorageError('Storage key must not be empty');
21
+ }
22
+ if (segments.includes('..')) {
23
+ throw new StorageError(`Invalid storage key '${key}': '..' path segments are not allowed`);
24
+ }
25
+ return segments.join('/');
26
+ }
27
+ /**
28
+ * Normalizes a list prefix: collapses slash runs, strips leading slashes.
29
+ * Unlike a key, an empty prefix is valid and matches everything.
30
+ *
31
+ * @param prefix - The raw prefix to normalize
32
+ * @returns The normalized prefix
33
+ * @throws {@link StorageError} if the prefix contains a `..` segment
34
+ */
35
+ export function normalizePrefix(prefix) {
36
+ const parts = prefix.split('/');
37
+ const segments = parts.filter(Boolean);
38
+ if (segments.includes('..')) {
39
+ throw new StorageError(`Invalid storage prefix '${prefix}': '..' path segments are not allowed`);
40
+ }
41
+ const joined = segments.join('/');
42
+ const normalized = parts[parts.length - 1] === '' && joined ? joined + '/' : joined;
43
+ return normalized;
44
+ }
45
+ /**
46
+ * Returns a {@link Storage} view with all keys prefixed by `prefix`.
47
+ *
48
+ * Composable — calling `namespace()` on the result nests prefixes.
49
+ *
50
+ * @internal
51
+ * @param storage - The underlying storage to delegate to
52
+ * @param prefix - Prefix to prepend to all keys
53
+ * @returns A namespaced Storage view
54
+ */
55
+ export function namespace(storage, prefix) {
56
+ const normalized = normalizePrefix(prefix);
57
+ const p = normalized ? `${normalized}/` : '';
58
+ const view = {
59
+ write: (key, data) => storage.write(`${p}${key}`, data),
60
+ read: (key) => storage.read(`${p}${key}`),
61
+ delete: (key) => storage.delete(`${p}${key}`),
62
+ list: (query) => storage.list(`${p}${query}`).then((keys) => keys.map((key) => key.slice(p.length))),
63
+ namespace: (sub) => namespace(storage, `${p}${sub}`),
64
+ [NAMESPACED]: true,
65
+ };
66
+ return view;
67
+ }
68
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/storage/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE3C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAkB,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAA;AAEjF;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC/C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,YAAY,CAAC,+BAA+B,CAAC,CAAA;IACzD,CAAC;IACD,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,YAAY,CAAC,wBAAwB,GAAG,uCAAuC,CAAC,CAAA;IAC5F,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC3B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACtC,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,YAAY,CAAC,2BAA2B,MAAM,uCAAuC,CAAC,CAAA;IAClG,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACjC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAA;IACnF,OAAO,UAAU,CAAA;AACnB,CAAC;AAwED;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,OAAgB,EAAE,MAAc;IACxD,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,CAAA;IAC1C,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;IAC5C,MAAM,IAAI,GAAqC;QAC7C,KAAK,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,EAAE,IAAI,CAAC;QACvD,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC;QACzC,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC;QAC7C,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QACpG,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC;QACpD,CAAC,UAAU,CAAC,EAAE,IAAI;KACnB,CAAA;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -135,6 +135,20 @@ export declare class Tracer {
135
135
  * or LANGFUSE_BASE_URL environment variables.
136
136
  */
137
137
  private readonly _isLangfuse;
138
+ /**
139
+ * Whether to record message content as span attributes instead of span events.
140
+ *
141
+ * True when the backend cannot read span events (Langfuse) or the opt-in is set via
142
+ * `OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_span_attributes_only`. Per OpenTelemetry the span-event
143
+ * recording API is deprecated, and non-timestamped span details such as the canonical
144
+ * `gen_ai.*.messages` attributes should be recorded as span attributes instead. This flag is
145
+ * passed by the aggregated content paths (latest-convention `gen_ai.*` messages and the
146
+ * `memory.query`/`memory.content` events); it never reaches the legacy per-message events
147
+ * (which reuse a `content` key and would collide as attributes).
148
+ *
149
+ * @see https://opentelemetry.io/blog/2026/deprecating-span-events/
150
+ */
151
+ private readonly _spanAttributesOnly;
138
152
  /** In-memory execution trace state, collected independently of OTEL. */
139
153
  private readonly _traceState;
140
154
  /**
@@ -337,6 +351,10 @@ export declare class Tracer {
337
351
  private _endSpan;
338
352
  /**
339
353
  * Add an event to a span.
354
+ *
355
+ * Per OpenTelemetry the span-event recording API is deprecated. When `toSpanAttributes` is set,
356
+ * the attributes are recorded directly on the span and the event is skipped, so the content is
357
+ * recorded once rather than duplicated across both; otherwise the event is emitted.
340
358
  */
341
359
  private _addEvent;
342
360
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tracer.d.ts","sourceRoot":"","sources":["../../../src/telemetry/tracer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tracer.d.ts","sourceRoot":"","sources":["../../../src/telemetry/tracer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAqC,cAAc,EAAQ,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEpH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,EAC3B,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,EAC1B,wBAAwB,EACxB,oBAAoB,EACpB,kBAAkB,EAClB,4BAA4B,EAC5B,0BAA0B,EAC1B,yBAAyB,EACzB,uBAAuB,EACvB,4BAA4B,EAC5B,0BAA0B,EAC1B,6BAA6B,EAC7B,2BAA2B,EAG5B,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAgB,OAAO,EAAgB,MAAM,sBAAsB,CAAA;AAC/E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAIxD;;GAEG;AACH,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;CACxB;AAED;;;;GAIG;AACH,qBAAa,UAAW,YAAW,gBAAgB,CAAC,cAAc,CAAC;IACjE,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,sFAAsF;IACtF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,uEAAuE;IACvE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAO;IAC7B,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAI;IACpB,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAK;IACpC,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAK;IAC9C,uFAAuF;IACvF,OAAO,EAAE,OAAO,GAAG,IAAI,CAAO;IAE9B;;;OAGG;gBACS,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,UAAU,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;IAW/E;;OAEG;IACH,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAK3B,MAAM,IAAI,cAAc;CAazB;AAiBD;;;;;;;;;GASG;AACH,qBAAa,MAAM;IACjB;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAY;IAEpC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAE/C;;;;;;;;;OASG;IACH,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAS;IAEjD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAgC;IAEjE,kDAAkD;IAClD,OAAO,CAAC,UAAU,CAAkB;IAEpC,kFAAkF;IAClF,OAAO,CAAC,SAAS,CAAkB;IAEnC,sFAAsF;IACtF,OAAO,CAAC,eAAe,CAAkB;IAEzC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IAErC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAE7C,wEAAwE;IACxE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;IAE9D;;;;;;;OAOG;gBACS,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC;IAe5D;;OAEG;IACH,IAAI,WAAW,IAAI,UAAU,EAAE,CAE9B;IAED;;;;;;OAMG;IACH,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,GAAG,IAAI;IA4C3D;;;;;OAKG;IACH,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,GAAE,mBAAwB,GAAG,IAAI;IA+BxE;;;;;OAKG;IACH,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,IAAI,GAAG,IAAI;IA6BvE;;;;;OAKG;IACH,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,GAAE,mBAAwB,GAAG,IAAI;IA6B9E;;;;;OAKG;IACH,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,GAAG,IAAI;IAwDjE;;;;;OAKG;IACH,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,GAAE,sBAA2B,GAAG,IAAI;IAgD9E;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,IAAI,GAAG,IAAI;IAuBrE;;;;;OAKG;IACH,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,GAAE,wBAA6B,GAAG,IAAI;IAgBlF;;;;;;OAMG;IACH,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,GAAG,IAAI;IAyBzD;;;;;OAKG;IACH,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,GAAE,kBAAuB,GAAG,IAAI;IAetE;;;;;;;;OAQG;IACH,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,IAAI,GAAG,IAAI;IAgBzE;;;;;;;;OAQG;IACH,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,GAAE,0BAA+B,GAAG,IAAI;IA+BtF;;;;;;;;OAQG;IACH,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,IAAI,GAAG,IAAI;IAoBnE;;;;;OAKG;IACH,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,GAAE,uBAA4B,GAAG,IAAI;IAYhF;;;;OAIG;IACH,qBAAqB,CAAC,OAAO,GAAE,4BAAiC,GAAG,IAAI,GAAG,IAAI;IAY9E;;;;;;;;OAQG;IACH,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,EAAE,0BAA0B,GAAG,IAAI;IAcjF;;;;;;;;OAQG;IACH,sBAAsB,CAAC,OAAO,EAAE,6BAA6B,GAAG,IAAI,GAAG,IAAI;IAiC3E;;;;;OAKG;IACH,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,GAAE,2BAAgC,GAAG,IAAI;IAWxF;;;;;;;;OAQG;IACH,kBAAkB,IAAI,WAAW,GAAG,SAAS;IAY7C;;;;;;;;OAQG;IACH,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAKrD;;;;;OAKG;IACH,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,IAAI,GAAG,IAAI;IAyBnE;;;;;OAKG;IACH,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,GAAE,uBAA4B,GAAG,IAAI;IAgBhF;;OAEG;IACH,OAAO,CAAC,UAAU;IA4ClB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAoBhB;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IA2BjB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAc5B;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IA6BzB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAc/B;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAM7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgCzB;;OAEG;IACH,OAAO,CAAC,eAAe;IAiCvB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAUjC;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IAW9B;;;;;;;;OAQG;IACH,OAAO,CAAC,qBAAqB;IAsB7B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,2BAA2B;IAgB1C;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,4BAA4B;IAiB3C;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,+BAA+B;CAkB/C"}
@@ -141,6 +141,20 @@ export class Tracer {
141
141
  * or LANGFUSE_BASE_URL environment variables.
142
142
  */
143
143
  _isLangfuse;
144
+ /**
145
+ * Whether to record message content as span attributes instead of span events.
146
+ *
147
+ * True when the backend cannot read span events (Langfuse) or the opt-in is set via
148
+ * `OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_span_attributes_only`. Per OpenTelemetry the span-event
149
+ * recording API is deprecated, and non-timestamped span details such as the canonical
150
+ * `gen_ai.*.messages` attributes should be recorded as span attributes instead. This flag is
151
+ * passed by the aggregated content paths (latest-convention `gen_ai.*` messages and the
152
+ * `memory.query`/`memory.content` events); it never reaches the legacy per-message events
153
+ * (which reuse a `content` key and would collide as attributes).
154
+ *
155
+ * @see https://opentelemetry.io/blog/2026/deprecating-span-events/
156
+ */
157
+ _spanAttributesOnly;
144
158
  /** In-memory execution trace state, collected independently of OTEL. */
145
159
  _traceState = { traces: [] };
146
160
  /**
@@ -158,6 +172,7 @@ export class Tracer {
158
172
  this._useLatestConventions = optInValues.has('gen_ai_latest_experimental');
159
173
  this._includeToolDefinitions = optInValues.has('gen_ai_tool_definitions');
160
174
  this._isLangfuse = Tracer._detectLangfuse();
175
+ this._spanAttributesOnly = this._isLangfuse || optInValues.has('gen_ai_span_attributes_only');
161
176
  // Get tracer from global API to ensure ground truth
162
177
  this._tracer = trace.getTracer(getServiceName());
163
178
  }
@@ -340,7 +355,7 @@ export class Tracer {
340
355
  parts: [{ type: 'tool_call', name: tool.name, id: tool.toolUseId, arguments: tool.input }],
341
356
  },
342
357
  ], jsonReplacer),
343
- });
358
+ }, this._spanAttributesOnly);
344
359
  }
345
360
  else {
346
361
  this._addEvent(span, 'gen_ai.tool.message', {
@@ -384,7 +399,7 @@ export class Tracer {
384
399
  parts: [{ type: 'tool_call_response', id: toolResult.toolUseId, response: toolResult.content }],
385
400
  },
386
401
  ], jsonReplacer),
387
- });
402
+ }, this._spanAttributesOnly);
388
403
  }
389
404
  else {
390
405
  this._addEvent(span, 'gen_ai.choice', {
@@ -520,7 +535,7 @@ export class Tracer {
520
535
  if (options.maxSearchResults !== undefined)
521
536
  attributes['memory.max_search_results'] = options.maxSearchResults;
522
537
  const span = this._startSpan({ name: 'memory.search', attributes, spanKind: SpanKind.INTERNAL });
523
- this._addEvent(span, 'memory.query', { content: options.query }, this._isLangfuse);
538
+ this._addEvent(span, 'memory.query', { content: options.query }, this._spanAttributesOnly);
524
539
  return span;
525
540
  }
526
541
  catch (error) {
@@ -553,7 +568,7 @@ export class Tracer {
553
568
  storeName: entry.storeName,
554
569
  metadata: entry.metadata,
555
570
  })), jsonReplacer),
556
- }, this._isLangfuse);
571
+ }, this._spanAttributesOnly);
557
572
  }
558
573
  this._endSpan(span, attributes, options.error);
559
574
  }
@@ -581,7 +596,7 @@ export class Tracer {
581
596
  spanKind: SpanKind.INTERNAL,
582
597
  ...(options.forceRoot && { forceRoot: true }),
583
598
  });
584
- this._addEvent(span, 'memory.content', { content: options.content }, this._isLangfuse);
599
+ this._addEvent(span, 'memory.content', { content: options.content }, this._spanAttributesOnly);
585
600
  return span;
586
601
  }
587
602
  catch (error) {
@@ -851,6 +866,10 @@ export class Tracer {
851
866
  }
852
867
  /**
853
868
  * Add an event to a span.
869
+ *
870
+ * Per OpenTelemetry the span-event recording API is deprecated. When `toSpanAttributes` is set,
871
+ * the attributes are recorded directly on the span and the event is skipped, so the content is
872
+ * recorded once rather than duplicated across both; otherwise the event is emitted.
854
873
  */
855
874
  _addEvent(span, eventName, eventAttributes, toSpanAttributes = false) {
856
875
  try {
@@ -863,10 +882,11 @@ export class Tracer {
863
882
  if (value !== undefined && value !== null)
864
883
  otelAttributes[key] = value;
865
884
  }
866
- // Some backends (e.g. Langfuse) don't surface span events, so optionally promote the
867
- // attributes onto the span where they remain visible.
885
+ // Some backends (e.g. Langfuse) don't surface span events, so record the attributes on the
886
+ // span instead of as an event.
868
887
  if (toSpanAttributes) {
869
888
  span.setAttributes(otelAttributes);
889
+ return;
870
890
  }
871
891
  span.addEvent(eventName, otelAttributes);
872
892
  }
@@ -909,7 +929,7 @@ export class Tracer {
909
929
  }));
910
930
  this._addEvent(span, 'gen_ai.client.inference.operation.details', {
911
931
  'gen_ai.input.messages': JSON.stringify(inputMessages, jsonReplacer),
912
- });
932
+ }, this._spanAttributesOnly);
913
933
  }
914
934
  else {
915
935
  for (const message of messages) {
@@ -982,7 +1002,7 @@ export class Tracer {
982
1002
  if (this._useLatestConventions) {
983
1003
  this._addEvent(span, 'gen_ai.client.inference.operation.details', {
984
1004
  'gen_ai.output.messages': JSON.stringify([{ role: 'assistant', parts: [{ type: 'text', content: messageText }], finish_reason: finishReason }], jsonReplacer),
985
- });
1005
+ }, this._spanAttributesOnly);
986
1006
  }
987
1007
  else {
988
1008
  this._addEvent(span, 'gen_ai.choice', { message: messageText, finish_reason: finishReason });
@@ -1007,7 +1027,7 @@ export class Tracer {
1007
1027
  finish_reason: finishReason,
1008
1028
  },
1009
1029
  ], jsonReplacer),
1010
- });
1030
+ }, this._spanAttributesOnly);
1011
1031
  }
1012
1032
  else {
1013
1033
  this._addEvent(span, 'gen_ai.choice', {
@@ -1061,7 +1081,7 @@ export class Tracer {
1061
1081
  const parts = Tracer._mapSystemPromptToOtelParts(systemPrompt);
1062
1082
  this._addEvent(span, 'gen_ai.client.inference.operation.details', {
1063
1083
  'gen_ai.system_instructions': JSON.stringify(parts, jsonReplacer),
1064
- });
1084
+ }, this._spanAttributesOnly);
1065
1085
  }
1066
1086
  else {
1067
1087
  // Normalize string prompts to an array of text blocks for consistent format