assistant-cloud 0.1.42 → 0.2.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.
- package/README.md +40 -0
- package/dist/AssistantCloud.d.ts +4 -0
- package/dist/AssistantCloud.d.ts.map +1 -1
- package/dist/AssistantCloud.js +11 -5
- package/dist/AssistantCloud.js.map +1 -1
- package/dist/AssistantCloudAPI.d.ts +17 -1
- package/dist/AssistantCloudAPI.d.ts.map +1 -1
- package/dist/AssistantCloudAPI.js +20 -9
- package/dist/AssistantCloudAPI.js.map +1 -1
- package/dist/AssistantCloudAuthStrategy.d.ts +4 -1
- package/dist/AssistantCloudAuthStrategy.d.ts.map +1 -1
- package/dist/AssistantCloudAuthStrategy.js +79 -18
- package/dist/AssistantCloudAuthStrategy.js.map +1 -1
- package/dist/AssistantCloudEvents.d.ts +32 -0
- package/dist/AssistantCloudEvents.d.ts.map +1 -0
- package/dist/AssistantCloudEvents.js +115 -0
- package/dist/AssistantCloudEvents.js.map +1 -0
- package/dist/AssistantCloudFiles.d.ts +12 -1
- package/dist/AssistantCloudFiles.d.ts.map +1 -1
- package/dist/AssistantCloudFiles.js +13 -1
- package/dist/AssistantCloudFiles.js.map +1 -1
- package/dist/AssistantCloudRuns.d.ts +11 -0
- package/dist/AssistantCloudRuns.d.ts.map +1 -1
- package/dist/AssistantCloudRuns.js.map +1 -1
- package/dist/AssistantCloudScores.d.ts +27 -0
- package/dist/AssistantCloudScores.d.ts.map +1 -0
- package/dist/AssistantCloudScores.js +30 -0
- package/dist/AssistantCloudScores.js.map +1 -0
- package/dist/AssistantCloudThreadMessages.d.ts +11 -1
- package/dist/AssistantCloudThreadMessages.d.ts.map +1 -1
- package/dist/AssistantCloudThreadMessages.js +12 -1
- package/dist/AssistantCloudThreadMessages.js.map +1 -1
- package/dist/AssistantCloudThreads.d.ts +8 -0
- package/dist/AssistantCloudThreads.d.ts.map +1 -1
- package/dist/AssistantCloudThreads.js +9 -1
- package/dist/AssistantCloudThreads.js.map +1 -1
- package/dist/CloudMessagePersistence.d.ts +4 -0
- package/dist/CloudMessagePersistence.d.ts.map +1 -1
- package/dist/CloudMessagePersistence.js +53 -18
- package/dist/CloudMessagePersistence.js.map +1 -1
- package/dist/cloudResponse.d.ts +4 -1
- package/dist/cloudResponse.d.ts.map +1 -1
- package/dist/cloudResponse.js +14 -1
- package/dist/cloudResponse.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.js +5 -2
- package/dist/runTelemetry.d.ts +79 -9
- package/dist/runTelemetry.d.ts.map +1 -1
- package/dist/runTelemetry.js +152 -6
- package/dist/runTelemetry.js.map +1 -1
- package/dist/telemetry/index.d.ts +32 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +62 -0
- package/dist/telemetry/index.js.map +1 -0
- package/package.json +28 -4
- package/src/AssistantCloud.ts +20 -8
- package/src/AssistantCloudAPI.ts +42 -10
- package/src/AssistantCloudAuthStrategy.ts +153 -46
- package/src/AssistantCloudEvents.test.ts +124 -0
- package/src/AssistantCloudEvents.ts +185 -0
- package/src/AssistantCloudFiles.test.ts +59 -0
- package/src/AssistantCloudFiles.ts +39 -0
- package/src/AssistantCloudRuns.ts +12 -1
- package/src/AssistantCloudScores.test.ts +113 -0
- package/src/AssistantCloudScores.ts +61 -0
- package/src/AssistantCloudThreadMessages.test.ts +51 -0
- package/src/AssistantCloudThreadMessages.ts +33 -0
- package/src/AssistantCloudThreads.test.ts +21 -0
- package/src/AssistantCloudThreads.ts +21 -0
- package/src/CloudMessagePersistence.ts +65 -29
- package/src/cloudResponse.test.ts +34 -1
- package/src/cloudResponse.ts +30 -0
- package/src/index.ts +24 -1
- package/src/runTelemetry.test.ts +366 -0
- package/src/runTelemetry.ts +271 -16
- package/src/telemetry/index.test.ts +252 -0
- package/src/telemetry/index.ts +98 -0
- package/src/tests/AssistantCloud.test.ts +22 -0
- package/src/tests/AssistantCloudAPI.test.ts +44 -4
- package/src/tests/AssistantCloudAuthStrategy.test.ts +354 -11
- package/src/tests/CloudMessagePersistence.test.ts +208 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
//#region src/CloudMessagePersistence.ts
|
|
2
|
+
const CLOUD_MESSAGE_PAGE_SIZE = 200;
|
|
2
3
|
/**
|
|
3
4
|
* Shared persistence logic for cloud message storage.
|
|
4
5
|
*
|
|
@@ -11,7 +12,7 @@
|
|
|
11
12
|
* to get its remote ID before creating B.
|
|
12
13
|
*/
|
|
13
14
|
var CloudMessagePersistence = class {
|
|
14
|
-
idMapping =
|
|
15
|
+
idMapping = /* @__PURE__ */ new Map();
|
|
15
16
|
getCloud;
|
|
16
17
|
constructor(cloud) {
|
|
17
18
|
this.getCloud = typeof cloud === "function" ? cloud : () => cloud;
|
|
@@ -27,20 +28,29 @@ var CloudMessagePersistence = class {
|
|
|
27
28
|
*/
|
|
28
29
|
async append(threadId, messageId, parentId, format, content) {
|
|
29
30
|
const cloud = this.getCloud();
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
this.idMapping
|
|
31
|
+
const existing = this.idMapping.get(messageId);
|
|
32
|
+
if (existing instanceof Promise) {
|
|
33
|
+
await existing;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const task = (async () => {
|
|
37
|
+
const parentEntry = parentId ? this.idMapping.get(parentId) : void 0;
|
|
38
|
+
const resolvedParentId = parentId ? await parentEntry ?? parentId : null;
|
|
39
|
+
const { message_id } = await cloud.threads.messages.create(threadId, {
|
|
40
|
+
parent_id: resolvedParentId,
|
|
41
|
+
format,
|
|
42
|
+
content
|
|
43
|
+
});
|
|
37
44
|
return message_id;
|
|
38
|
-
})
|
|
39
|
-
|
|
45
|
+
})();
|
|
46
|
+
this.idMapping.set(messageId, task);
|
|
47
|
+
try {
|
|
48
|
+
const remoteId = await task;
|
|
49
|
+
if (this.idMapping.get(messageId) === task) this.idMapping.set(messageId, remoteId);
|
|
50
|
+
} catch (err) {
|
|
51
|
+
if (this.idMapping.get(messageId) === task) this.idMapping.delete(messageId);
|
|
40
52
|
throw err;
|
|
41
|
-
}
|
|
42
|
-
this.idMapping[messageId] = task;
|
|
43
|
-
return task.then(() => {});
|
|
53
|
+
}
|
|
44
54
|
}
|
|
45
55
|
/**
|
|
46
56
|
* Update an already-persisted message in the cloud.
|
|
@@ -58,20 +68,27 @@ var CloudMessagePersistence = class {
|
|
|
58
68
|
* Check if a message has been persisted (or is currently being persisted).
|
|
59
69
|
*/
|
|
60
70
|
isPersisted(messageId) {
|
|
61
|
-
return
|
|
71
|
+
return this.idMapping.has(messageId);
|
|
62
72
|
}
|
|
63
73
|
/**
|
|
64
74
|
* Get the remote ID for a local message ID (resolved).
|
|
65
75
|
* Returns undefined if not persisted.
|
|
66
76
|
*/
|
|
67
77
|
async getRemoteId(messageId) {
|
|
68
|
-
const entry = this.idMapping
|
|
78
|
+
const entry = this.idMapping.get(messageId);
|
|
69
79
|
if (!entry) return void 0;
|
|
70
80
|
return entry;
|
|
71
81
|
}
|
|
82
|
+
getResolvedRemoteId(messageId) {
|
|
83
|
+
const entry = this.idMapping.get(messageId);
|
|
84
|
+
return typeof entry === "string" ? entry : void 0;
|
|
85
|
+
}
|
|
72
86
|
/**
|
|
73
87
|
* Load messages from the cloud and populate the ID mapping.
|
|
74
88
|
*
|
|
89
|
+
* The list endpoint caps a response at 200 rows, so pages are followed by
|
|
90
|
+
* message ID cursor until a short page and concatenated in server order.
|
|
91
|
+
*
|
|
75
92
|
* The ID mapping is populated so that `isPersisted()` returns true for
|
|
76
93
|
* loaded messages, preventing re-persistence of already-stored messages.
|
|
77
94
|
*
|
|
@@ -80,15 +97,33 @@ var CloudMessagePersistence = class {
|
|
|
80
97
|
* @returns Array of cloud messages
|
|
81
98
|
*/
|
|
82
99
|
async load(threadId, format) {
|
|
83
|
-
const
|
|
84
|
-
|
|
100
|
+
const cloud = this.getCloud();
|
|
101
|
+
const messages = [];
|
|
102
|
+
const seen = /* @__PURE__ */ new Set();
|
|
103
|
+
let after;
|
|
104
|
+
while (true) {
|
|
105
|
+
const page = await cloud.threads.messages.list(threadId, {
|
|
106
|
+
...format ? { format } : void 0,
|
|
107
|
+
limit: CLOUD_MESSAGE_PAGE_SIZE,
|
|
108
|
+
...after ? { after } : void 0
|
|
109
|
+
});
|
|
110
|
+
const last = page.messages.at(-1);
|
|
111
|
+
if (!last) break;
|
|
112
|
+
const fresh = page.messages.filter((m) => !seen.has(m.id));
|
|
113
|
+
if (fresh.length === 0) break;
|
|
114
|
+
for (const m of fresh) seen.add(m.id);
|
|
115
|
+
messages.push(...fresh);
|
|
116
|
+
if (page.messages.length < CLOUD_MESSAGE_PAGE_SIZE) break;
|
|
117
|
+
after = last.id;
|
|
118
|
+
}
|
|
119
|
+
for (const m of messages) this.idMapping.set(m.id, m.id);
|
|
85
120
|
return messages;
|
|
86
121
|
}
|
|
87
122
|
/**
|
|
88
123
|
* Reset the ID mapping (call when switching threads).
|
|
89
124
|
*/
|
|
90
125
|
reset() {
|
|
91
|
-
this.idMapping
|
|
126
|
+
this.idMapping.clear();
|
|
92
127
|
}
|
|
93
128
|
};
|
|
94
129
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CloudMessagePersistence.js","names":[],"sources":["../src/CloudMessagePersistence.ts"],"sourcesContent":["import type { ReadonlyJSONObject } from \"assistant-stream/utils\";\nimport type { AssistantCloud } from \"./AssistantCloud\";\n\n/**\n * Shared persistence logic for cloud message storage.\n *\n * Handles ID mapping (local → remote) and parent_id chaining for both:\n * - AssistantCloudThreadHistoryAdapter (assistant-ui runtime)\n * - useCloudChat (standalone AI SDK hook)\n *\n * The promise-based ID resolution handles concurrent appends — if message B's\n * parent is message A, and A is still being created, we await A's promise\n * to get its remote ID before creating B.\n */\nexport class CloudMessagePersistence {\n private idMapping
|
|
1
|
+
{"version":3,"file":"CloudMessagePersistence.js","names":[],"sources":["../src/CloudMessagePersistence.ts"],"sourcesContent":["import type { ReadonlyJSONObject } from \"assistant-stream/utils\";\nimport type { AssistantCloud } from \"./AssistantCloud\";\nimport type { CloudMessage } from \"./AssistantCloudThreadMessages\";\n\nconst CLOUD_MESSAGE_PAGE_SIZE = 200;\n\n/**\n * Shared persistence logic for cloud message storage.\n *\n * Handles ID mapping (local → remote) and parent_id chaining for both:\n * - AssistantCloudThreadHistoryAdapter (assistant-ui runtime)\n * - useCloudChat (standalone AI SDK hook)\n *\n * The promise-based ID resolution handles concurrent appends — if message B's\n * parent is message A, and A is still being created, we await A's promise\n * to get its remote ID before creating B.\n */\nexport class CloudMessagePersistence {\n private idMapping = new Map<string, string | Promise<string>>();\n private getCloud: () => AssistantCloud;\n\n constructor(cloud: AssistantCloud);\n constructor(getCloud: () => AssistantCloud);\n constructor(cloud: AssistantCloud | (() => AssistantCloud)) {\n this.getCloud = typeof cloud === \"function\" ? cloud : () => cloud;\n }\n\n /**\n * Persist a message to the cloud.\n *\n * @param threadId - Remote thread ID\n * @param messageId - Local message ID (used for tracking)\n * @param parentId - Local parent message ID (or null for first message)\n * @param format - Message format (e.g., \"aui/v0\", \"ai-sdk/v6\")\n * @param content - Message content (format-specific)\n */\n async append(\n threadId: string,\n messageId: string,\n parentId: string | null,\n format: string,\n content: ReadonlyJSONObject,\n ): Promise<void> {\n const cloud = this.getCloud();\n const existing = this.idMapping.get(messageId);\n if (existing instanceof Promise) {\n await existing;\n return;\n }\n\n const task = (async () => {\n const parentEntry = parentId ? this.idMapping.get(parentId) : undefined;\n const resolvedParentId = parentId\n ? ((await parentEntry) ?? parentId)\n : null;\n const { message_id } = await cloud.threads.messages.create(threadId, {\n parent_id: resolvedParentId,\n format,\n content,\n });\n return message_id;\n })();\n\n this.idMapping.set(messageId, task);\n try {\n const remoteId = await task;\n if (this.idMapping.get(messageId) === task) {\n this.idMapping.set(messageId, remoteId);\n }\n } catch (err) {\n if (this.idMapping.get(messageId) === task) {\n this.idMapping.delete(messageId);\n }\n throw err;\n }\n }\n\n /**\n * Update an already-persisted message in the cloud.\n */\n async update(\n threadId: string,\n messageId: string,\n _format: string,\n content: ReadonlyJSONObject,\n ): Promise<void> {\n const cloud = this.getCloud();\n const remoteId = await this.getRemoteId(messageId);\n if (!remoteId) {\n console.warn(\n `Skipping update for message ${messageId}: no remote id is mapped.`,\n );\n return;\n }\n await cloud.threads.messages.update(threadId, remoteId, { content });\n }\n\n /**\n * Check if a message has been persisted (or is currently being persisted).\n */\n isPersisted(messageId: string): boolean {\n return this.idMapping.has(messageId);\n }\n\n /**\n * Get the remote ID for a local message ID (resolved).\n * Returns undefined if not persisted.\n */\n async getRemoteId(messageId: string): Promise<string | undefined> {\n const entry = this.idMapping.get(messageId);\n if (!entry) return undefined;\n return entry;\n }\n\n getResolvedRemoteId(messageId: string): string | undefined {\n const entry = this.idMapping.get(messageId);\n return typeof entry === \"string\" ? entry : undefined;\n }\n\n /**\n * Load messages from the cloud and populate the ID mapping.\n *\n * The list endpoint caps a response at 200 rows, so pages are followed by\n * message ID cursor until a short page and concatenated in server order.\n *\n * The ID mapping is populated so that `isPersisted()` returns true for\n * loaded messages, preventing re-persistence of already-stored messages.\n *\n * @param threadId - Remote thread ID\n * @param format - Optional format filter\n * @returns Array of cloud messages\n */\n async load(threadId: string, format?: string) {\n const cloud = this.getCloud();\n const messages: CloudMessage[] = [];\n const seen = new Set<string>();\n let after: string | undefined;\n\n while (true) {\n const page = await cloud.threads.messages.list(threadId, {\n ...(format ? { format } : undefined),\n limit: CLOUD_MESSAGE_PAGE_SIZE,\n ...(after ? { after } : undefined),\n });\n const last = page.messages.at(-1);\n if (!last) break;\n\n // A cursor the server cannot resolve drops the keyset filter and replays\n // an earlier page, so already-seen rows end the walk instead of repeating.\n const fresh = page.messages.filter((m) => !seen.has(m.id));\n if (fresh.length === 0) break;\n for (const m of fresh) seen.add(m.id);\n\n messages.push(...fresh);\n if (page.messages.length < CLOUD_MESSAGE_PAGE_SIZE) break;\n after = last.id;\n }\n\n // Populate ID mapping so isPersisted() recognizes loaded messages\n for (const m of messages) {\n this.idMapping.set(m.id, m.id);\n }\n return messages;\n }\n\n /**\n * Reset the ID mapping (call when switching threads).\n */\n reset() {\n this.idMapping.clear();\n }\n}\n"],"mappings":";AAIA,MAAM,0BAA0B;;;;;;;;;;;;AAahC,IAAa,0BAAb,MAAqC;CACnC,4BAAoB,IAAI,IAAsC;CAC9D;CAIA,YAAY,OAAgD;EAC1D,KAAK,WAAW,OAAO,UAAU,aAAa,cAAc;CAC9D;;;;;;;;;;CAWA,MAAM,OACJ,UACA,WACA,UACA,QACA,SACe;EACf,MAAM,QAAQ,KAAK,SAAS;EAC5B,MAAM,WAAW,KAAK,UAAU,IAAI,SAAS;EAC7C,IAAI,oBAAoB,SAAS;GAC/B,MAAM;GACN;EACF;EAEA,MAAM,QAAQ,YAAY;GACxB,MAAM,cAAc,WAAW,KAAK,UAAU,IAAI,QAAQ,IAAI,KAAA;GAC9D,MAAM,mBAAmB,WACnB,MAAM,eAAgB,WACxB;GACJ,MAAM,EAAE,eAAe,MAAM,MAAM,QAAQ,SAAS,OAAO,UAAU;IACnE,WAAW;IACX;IACA;GACF,CAAC;GACD,OAAO;EACT,EAAA,CAAG;EAEH,KAAK,UAAU,IAAI,WAAW,IAAI;EAClC,IAAI;GACF,MAAM,WAAW,MAAM;GACvB,IAAI,KAAK,UAAU,IAAI,SAAS,MAAM,MACpC,KAAK,UAAU,IAAI,WAAW,QAAQ;EAE1C,SAAS,KAAK;GACZ,IAAI,KAAK,UAAU,IAAI,SAAS,MAAM,MACpC,KAAK,UAAU,OAAO,SAAS;GAEjC,MAAM;EACR;CACF;;;;CAKA,MAAM,OACJ,UACA,WACA,SACA,SACe;EACf,MAAM,QAAQ,KAAK,SAAS;EAC5B,MAAM,WAAW,MAAM,KAAK,YAAY,SAAS;EACjD,IAAI,CAAC,UAAU;GACb,QAAQ,KACN,+BAA+B,UAAU,0BAC3C;GACA;EACF;EACA,MAAM,MAAM,QAAQ,SAAS,OAAO,UAAU,UAAU,EAAE,QAAQ,CAAC;CACrE;;;;CAKA,YAAY,WAA4B;EACtC,OAAO,KAAK,UAAU,IAAI,SAAS;CACrC;;;;;CAMA,MAAM,YAAY,WAAgD;EAChE,MAAM,QAAQ,KAAK,UAAU,IAAI,SAAS;EAC1C,IAAI,CAAC,OAAO,OAAO,KAAA;EACnB,OAAO;CACT;CAEA,oBAAoB,WAAuC;EACzD,MAAM,QAAQ,KAAK,UAAU,IAAI,SAAS;EAC1C,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAA;CAC7C;;;;;;;;;;;;;;CAeA,MAAM,KAAK,UAAkB,QAAiB;EAC5C,MAAM,QAAQ,KAAK,SAAS;EAC5B,MAAM,WAA2B,CAAC;EAClC,MAAM,uBAAO,IAAI,IAAY;EAC7B,IAAI;EAEJ,OAAO,MAAM;GACX,MAAM,OAAO,MAAM,MAAM,QAAQ,SAAS,KAAK,UAAU;IACvD,GAAI,SAAS,EAAE,OAAO,IAAI,KAAA;IAC1B,OAAO;IACP,GAAI,QAAQ,EAAE,MAAM,IAAI,KAAA;GAC1B,CAAC;GACD,MAAM,OAAO,KAAK,SAAS,GAAG,EAAE;GAChC,IAAI,CAAC,MAAM;GAIX,MAAM,QAAQ,KAAK,SAAS,QAAQ,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;GACzD,IAAI,MAAM,WAAW,GAAG;GACxB,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,EAAE,EAAE;GAEpC,SAAS,KAAK,GAAG,KAAK;GACtB,IAAI,KAAK,SAAS,SAAS,yBAAyB;GACpD,QAAQ,KAAK;EACf;EAGA,KAAK,MAAM,KAAK,UACd,KAAK,UAAU,IAAI,EAAE,IAAI,EAAE,EAAE;EAE/B,OAAO;CACT;;;;CAKA,QAAQ;EACN,KAAK,UAAU,MAAM;CACvB;AACF"}
|
package/dist/cloudResponse.d.ts
CHANGED
|
@@ -6,11 +6,14 @@ declare class CloudResponseError extends Error {
|
|
|
6
6
|
declare const readCloudRecord: (value: unknown, field: string) => Record<string, unknown>;
|
|
7
7
|
declare const readCloudArray: (value: unknown, field: string) => unknown[];
|
|
8
8
|
declare const readCloudString: (value: unknown, field: string) => string;
|
|
9
|
+
declare const readCloudNumber: (value: unknown, field: string) => number;
|
|
10
|
+
declare const readCloudNullableNumber: (value: unknown, field: string) => number | null;
|
|
11
|
+
declare const readCloudEnum: <const T extends readonly string[]>(value: unknown, field: string, allowed: T) => T[number];
|
|
9
12
|
declare const readCloudNullableString: (value: unknown, field: string) => string | null;
|
|
10
13
|
declare const readCloudBoolean: (value: unknown, field: string) => boolean;
|
|
11
14
|
declare const readCloudInteger: (value: unknown, field: string) => number;
|
|
12
15
|
declare const readCloudTimestamp: (value: unknown, field: string) => Date;
|
|
13
16
|
declare const readCloudJSONObject: (value: unknown, field: string) => ReadonlyJSONObject;
|
|
14
17
|
//#endregion
|
|
15
|
-
export { CloudResponseError, readCloudArray, readCloudBoolean, readCloudInteger, readCloudJSONObject, readCloudNullableString, readCloudRecord, readCloudString, readCloudTimestamp };
|
|
18
|
+
export { CloudResponseError, readCloudArray, readCloudBoolean, readCloudEnum, readCloudInteger, readCloudJSONObject, readCloudNullableNumber, readCloudNullableString, readCloudNumber, readCloudRecord, readCloudString, readCloudTimestamp };
|
|
16
19
|
//# sourceMappingURL=cloudResponse.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudResponse.d.ts","names":[],"sources":["../src/cloudResponse.ts"],"mappings":";;cAEa,2BAA2B;EAC1B,YAAA;;cAWD,kBACX,gBACA,kBACC;cAOU,iBAAkB,gBAAgB;cAKlC,kBAAmB,gBAAgB;cAKnC,0BACX,gBACA;cAMW,mBAAoB,gBAAgB;cAOpC,mBAAoB,gBAAgB;cAKpC,qBAAsB,gBAAgB,kBAAgB;cActD,sBACX,gBACA,kBACC"}
|
|
1
|
+
{"version":3,"file":"cloudResponse.d.ts","names":[],"sources":["../src/cloudResponse.ts"],"mappings":";;cAEa,2BAA2B;EAC1B,YAAA;;cAWD,kBACX,gBACA,kBACC;cAOU,iBAAkB,gBAAgB;cAKlC,kBAAmB,gBAAgB;cAKnC,kBAAmB,gBAAgB;cAOnC,0BACX,gBACA;cAMW,sBAAuB,6BAClC,gBACA,eACA,SAAS,MACR;cAWU,0BACX,gBACA;cAMW,mBAAoB,gBAAgB;cAOpC,mBAAoB,gBAAgB;cAKpC,qBAAsB,gBAAgB,kBAAgB;cActD,sBACX,gBACA,kBACC"}
|
package/dist/cloudResponse.js
CHANGED
|
@@ -18,6 +18,19 @@ const readCloudString = (value, field) => {
|
|
|
18
18
|
if (typeof value !== "string") throw invalidCloudResponse(field, "a string");
|
|
19
19
|
return value;
|
|
20
20
|
};
|
|
21
|
+
const readCloudNumber = (value, field) => {
|
|
22
|
+
if (typeof value !== "number" || !Number.isFinite(value)) throw invalidCloudResponse(field, "a number");
|
|
23
|
+
return value;
|
|
24
|
+
};
|
|
25
|
+
const readCloudNullableNumber = (value, field) => {
|
|
26
|
+
if (value === null) return null;
|
|
27
|
+
return readCloudNumber(value, field);
|
|
28
|
+
};
|
|
29
|
+
const readCloudEnum = (value, field, allowed) => {
|
|
30
|
+
const text = readCloudString(value, field);
|
|
31
|
+
if (!allowed.includes(text)) throw invalidCloudResponse(field, `one of ${allowed.map((entry) => `"${entry}"`).join(", ")}`);
|
|
32
|
+
return text;
|
|
33
|
+
};
|
|
21
34
|
const readCloudNullableString = (value, field) => {
|
|
22
35
|
if (value === null) return null;
|
|
23
36
|
return readCloudString(value, field);
|
|
@@ -38,6 +51,6 @@ const readCloudTimestamp = (value, field) => {
|
|
|
38
51
|
};
|
|
39
52
|
const readCloudJSONObject = (value, field) => readCloudRecord(value, field);
|
|
40
53
|
//#endregion
|
|
41
|
-
export { CloudResponseError, readCloudArray, readCloudBoolean, readCloudInteger, readCloudJSONObject, readCloudNullableString, readCloudRecord, readCloudString, readCloudTimestamp };
|
|
54
|
+
export { CloudResponseError, readCloudArray, readCloudBoolean, readCloudEnum, readCloudInteger, readCloudJSONObject, readCloudNullableNumber, readCloudNullableString, readCloudNumber, readCloudRecord, readCloudString, readCloudTimestamp };
|
|
42
55
|
|
|
43
56
|
//# sourceMappingURL=cloudResponse.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudResponse.js","names":[],"sources":["../src/cloudResponse.ts"],"sourcesContent":["import type { ReadonlyJSONObject } from \"assistant-stream/utils\";\n\nexport class CloudResponseError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CloudResponseError\";\n }\n}\n\nconst invalidCloudResponse = (field: string, expected: string) =>\n new CloudResponseError(\n `Invalid Assistant Cloud response for \"${field}\": expected ${expected}`,\n );\n\nexport const readCloudRecord = (\n value: unknown,\n field: string,\n): Record<string, unknown> => {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw invalidCloudResponse(field, \"an object\");\n }\n return value as Record<string, unknown>;\n};\n\nexport const readCloudArray = (value: unknown, field: string): unknown[] => {\n if (!Array.isArray(value)) throw invalidCloudResponse(field, \"an array\");\n return value;\n};\n\nexport const readCloudString = (value: unknown, field: string): string => {\n if (typeof value !== \"string\") throw invalidCloudResponse(field, \"a string\");\n return value;\n};\n\nexport const readCloudNullableString = (\n value: unknown,\n field: string,\n): string | null => {\n if (value === null) return null;\n return readCloudString(value, field);\n};\n\nexport const readCloudBoolean = (value: unknown, field: string): boolean => {\n if (typeof value !== \"boolean\") {\n throw invalidCloudResponse(field, \"a boolean\");\n }\n return value;\n};\n\nexport const readCloudInteger = (value: unknown, field: string): number => {\n if (!Number.isInteger(value)) throw invalidCloudResponse(field, \"an integer\");\n return value as number;\n};\n\nexport const readCloudTimestamp = (value: unknown, field: string): Date => {\n if (typeof value !== \"string\") {\n throw invalidCloudResponse(field, \"a canonical ISO timestamp\");\n }\n\n const date = new Date(value);\n // The round trip pins the backend DTO's Date#toISOString() wire contract.\n if (Number.isNaN(date.getTime()) || date.toISOString() !== value) {\n throw invalidCloudResponse(field, \"a canonical ISO timestamp\");\n }\n\n return date;\n};\n\nexport const readCloudJSONObject = (\n value: unknown,\n field: string,\n): ReadonlyJSONObject => readCloudRecord(value, field) as ReadonlyJSONObject;\n"],"mappings":";AAEA,IAAa,qBAAb,cAAwC,MAAM;CAC5C,YAAY,SAAiB;EAC3B,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;AAEA,MAAM,wBAAwB,OAAe,aAC3C,IAAI,mBACF,yCAAyC,MAAM,cAAc,UAC/D;AAEF,MAAa,mBACX,OACA,UAC4B;CAC5B,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GACpE,MAAM,qBAAqB,OAAO,WAAW;CAE/C,OAAO;AACT;AAEA,MAAa,kBAAkB,OAAgB,UAA6B;CAC1E,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,MAAM,qBAAqB,OAAO,UAAU;CACvE,OAAO;AACT;AAEA,MAAa,mBAAmB,OAAgB,UAA0B;CACxE,IAAI,OAAO,UAAU,UAAU,MAAM,qBAAqB,OAAO,UAAU;CAC3E,OAAO;AACT;AAEA,MAAa,2BACX,OACA,UACkB;CAClB,IAAI,UAAU,MAAM,OAAO;CAC3B,OAAO,gBAAgB,OAAO,KAAK;AACrC;AAEA,MAAa,oBAAoB,OAAgB,UAA2B;CAC1E,IAAI,OAAO,UAAU,WACnB,MAAM,qBAAqB,OAAO,WAAW;CAE/C,OAAO;AACT;AAEA,MAAa,oBAAoB,OAAgB,UAA0B;CACzE,IAAI,CAAC,OAAO,UAAU,KAAK,GAAG,MAAM,qBAAqB,OAAO,YAAY;CAC5E,OAAO;AACT;AAEA,MAAa,sBAAsB,OAAgB,UAAwB;CACzE,IAAI,OAAO,UAAU,UACnB,MAAM,qBAAqB,OAAO,2BAA2B;CAG/D,MAAM,OAAO,IAAI,KAAK,KAAK;CAE3B,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,YAAY,MAAM,OACzD,MAAM,qBAAqB,OAAO,2BAA2B;CAG/D,OAAO;AACT;AAEA,MAAa,uBACX,OACA,UACuB,gBAAgB,OAAO,KAAK"}
|
|
1
|
+
{"version":3,"file":"cloudResponse.js","names":[],"sources":["../src/cloudResponse.ts"],"sourcesContent":["import type { ReadonlyJSONObject } from \"assistant-stream/utils\";\n\nexport class CloudResponseError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CloudResponseError\";\n }\n}\n\nconst invalidCloudResponse = (field: string, expected: string) =>\n new CloudResponseError(\n `Invalid Assistant Cloud response for \"${field}\": expected ${expected}`,\n );\n\nexport const readCloudRecord = (\n value: unknown,\n field: string,\n): Record<string, unknown> => {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw invalidCloudResponse(field, \"an object\");\n }\n return value as Record<string, unknown>;\n};\n\nexport const readCloudArray = (value: unknown, field: string): unknown[] => {\n if (!Array.isArray(value)) throw invalidCloudResponse(field, \"an array\");\n return value;\n};\n\nexport const readCloudString = (value: unknown, field: string): string => {\n if (typeof value !== \"string\") throw invalidCloudResponse(field, \"a string\");\n return value;\n};\n\nexport const readCloudNumber = (value: unknown, field: string): number => {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw invalidCloudResponse(field, \"a number\");\n }\n return value;\n};\n\nexport const readCloudNullableNumber = (\n value: unknown,\n field: string,\n): number | null => {\n if (value === null) return null;\n return readCloudNumber(value, field);\n};\n\nexport const readCloudEnum = <const T extends readonly string[]>(\n value: unknown,\n field: string,\n allowed: T,\n): T[number] => {\n const text = readCloudString(value, field);\n if (!allowed.includes(text)) {\n throw invalidCloudResponse(\n field,\n `one of ${allowed.map((entry) => `\"${entry}\"`).join(\", \")}`,\n );\n }\n return text;\n};\n\nexport const readCloudNullableString = (\n value: unknown,\n field: string,\n): string | null => {\n if (value === null) return null;\n return readCloudString(value, field);\n};\n\nexport const readCloudBoolean = (value: unknown, field: string): boolean => {\n if (typeof value !== \"boolean\") {\n throw invalidCloudResponse(field, \"a boolean\");\n }\n return value;\n};\n\nexport const readCloudInteger = (value: unknown, field: string): number => {\n if (!Number.isInteger(value)) throw invalidCloudResponse(field, \"an integer\");\n return value as number;\n};\n\nexport const readCloudTimestamp = (value: unknown, field: string): Date => {\n if (typeof value !== \"string\") {\n throw invalidCloudResponse(field, \"a canonical ISO timestamp\");\n }\n\n const date = new Date(value);\n // The round trip pins the backend DTO's Date#toISOString() wire contract.\n if (Number.isNaN(date.getTime()) || date.toISOString() !== value) {\n throw invalidCloudResponse(field, \"a canonical ISO timestamp\");\n }\n\n return date;\n};\n\nexport const readCloudJSONObject = (\n value: unknown,\n field: string,\n): ReadonlyJSONObject => readCloudRecord(value, field) as ReadonlyJSONObject;\n"],"mappings":";AAEA,IAAa,qBAAb,cAAwC,MAAM;CAC5C,YAAY,SAAiB;EAC3B,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;AAEA,MAAM,wBAAwB,OAAe,aAC3C,IAAI,mBACF,yCAAyC,MAAM,cAAc,UAC/D;AAEF,MAAa,mBACX,OACA,UAC4B;CAC5B,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GACpE,MAAM,qBAAqB,OAAO,WAAW;CAE/C,OAAO;AACT;AAEA,MAAa,kBAAkB,OAAgB,UAA6B;CAC1E,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,MAAM,qBAAqB,OAAO,UAAU;CACvE,OAAO;AACT;AAEA,MAAa,mBAAmB,OAAgB,UAA0B;CACxE,IAAI,OAAO,UAAU,UAAU,MAAM,qBAAqB,OAAO,UAAU;CAC3E,OAAO;AACT;AAEA,MAAa,mBAAmB,OAAgB,UAA0B;CACxE,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GACrD,MAAM,qBAAqB,OAAO,UAAU;CAE9C,OAAO;AACT;AAEA,MAAa,2BACX,OACA,UACkB;CAClB,IAAI,UAAU,MAAM,OAAO;CAC3B,OAAO,gBAAgB,OAAO,KAAK;AACrC;AAEA,MAAa,iBACX,OACA,OACA,YACc;CACd,MAAM,OAAO,gBAAgB,OAAO,KAAK;CACzC,IAAI,CAAC,QAAQ,SAAS,IAAI,GACxB,MAAM,qBACJ,OACA,UAAU,QAAQ,KAAK,UAAU,IAAI,MAAM,EAAE,CAAC,CAAC,KAAK,IAAI,GAC1D;CAEF,OAAO;AACT;AAEA,MAAa,2BACX,OACA,UACkB;CAClB,IAAI,UAAU,MAAM,OAAO;CAC3B,OAAO,gBAAgB,OAAO,KAAK;AACrC;AAEA,MAAa,oBAAoB,OAAgB,UAA2B;CAC1E,IAAI,OAAO,UAAU,WACnB,MAAM,qBAAqB,OAAO,WAAW;CAE/C,OAAO;AACT;AAEA,MAAa,oBAAoB,OAAgB,UAA0B;CACzE,IAAI,CAAC,OAAO,UAAU,KAAK,GAAG,MAAM,qBAAqB,OAAO,YAAY;CAC5E,OAAO;AACT;AAEA,MAAa,sBAAsB,OAAgB,UAAwB;CACzE,IAAI,OAAO,UAAU,UACnB,MAAM,qBAAqB,OAAO,2BAA2B;CAG/D,MAAM,OAAO,IAAI,KAAK,KAAK;CAE3B,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,YAAY,MAAM,OACzD,MAAM,qBAAqB,OAAO,2BAA2B;CAG/D,OAAO;AACT;AAEA,MAAa,uBACX,OACA,UACuB,gBAAgB,OAAO,KAAK"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
import { readAnonymousRefreshToken } from "./AssistantCloudAuthStrategy.js";
|
|
1
2
|
import { McpSamplingHandler, SamplingCallData, createSamplingCollector, wrapSamplingHandler } from "./instrumentMcpSampling.js";
|
|
2
|
-
import { AssistantCloudRunReportToolCall, RunTelemetryToolCallInit, RunTelemetryUsage, RunTelemetryUsageInit, createRunTelemetryToolCall, normalizeRunTelemetryUsage, truncateRunTelemetryText } from "./runTelemetry.js";
|
|
3
|
+
import { AssistantCloudRunReportToolCall, RunReportInit, RunReportOutcome, RunReportStepInit, RunTelemetryToolCallInit, RunTelemetryUsage, RunTelemetryUsageInit, createRunReport, createRunTelemetryToolCall, deriveRunOutcome, describeRunError, extractRunTelemetryModelId, normalizeRunTelemetryUsage, truncateRunTelemetryText } from "./runTelemetry.js";
|
|
3
4
|
import { AssistantCloudRunReport } from "./AssistantCloudRuns.js";
|
|
4
5
|
import { AssistantCloudTelemetryConfig, CloudAPIError } from "./AssistantCloudAPI.js";
|
|
5
|
-
import { CloudMessage } from "./AssistantCloudThreadMessages.js";
|
|
6
|
+
import { AssistantCloudThreadMessageFeedbackBody, AssistantCloudThreadMessageFeedbackResponse, CloudMessage } from "./AssistantCloudThreadMessages.js";
|
|
7
|
+
import { GeneratePresignedDownloadUrlResponse } from "./AssistantCloudFiles.js";
|
|
8
|
+
import { AssistantCloudEvent, AssistantCloudEventKind, AssistantCloudEvents } from "./AssistantCloudEvents.js";
|
|
9
|
+
import { AssistantCloudScoreBody, AssistantCloudScoreResponse, AssistantCloudScores } from "./AssistantCloudScores.js";
|
|
6
10
|
import { AssistantCloud } from "./AssistantCloud.js";
|
|
7
11
|
import { CloudMessagePersistence } from "./CloudMessagePersistence.js";
|
|
8
12
|
import { MessageFormatAdapter, createFormattedPersistence } from "./FormattedCloudPersistence.js";
|
|
9
13
|
import { CloudResponseError } from "./cloudResponse.js";
|
|
10
14
|
import { generateThreadTitle } from "./generateThreadTitle.js";
|
|
11
|
-
export { AssistantCloud, type AssistantCloudRunReport, type AssistantCloudRunReportToolCall, type AssistantCloudTelemetryConfig, CloudAPIError, type CloudMessage, CloudMessagePersistence, CloudResponseError, type McpSamplingHandler, type MessageFormatAdapter, type RunTelemetryToolCallInit, type RunTelemetryUsage, type RunTelemetryUsageInit, type SamplingCallData, createFormattedPersistence, createRunTelemetryToolCall, createSamplingCollector, generateThreadTitle, normalizeRunTelemetryUsage, truncateRunTelemetryText, wrapSamplingHandler };
|
|
15
|
+
export { AssistantCloud, type AssistantCloudEvent, type AssistantCloudEventKind, AssistantCloudEvents, type AssistantCloudRunReport, type AssistantCloudRunReportToolCall, type AssistantCloudScoreBody, type AssistantCloudScoreResponse, AssistantCloudScores, type AssistantCloudTelemetryConfig, type AssistantCloudThreadMessageFeedbackBody, type AssistantCloudThreadMessageFeedbackResponse, CloudAPIError, type CloudMessage, CloudMessagePersistence, CloudResponseError, type GeneratePresignedDownloadUrlResponse, type McpSamplingHandler, type MessageFormatAdapter, type RunReportInit, type RunReportOutcome, type RunReportStepInit, type RunTelemetryToolCallInit, type RunTelemetryUsage, type RunTelemetryUsageInit, type SamplingCallData, createFormattedPersistence, createRunReport, createRunTelemetryToolCall, createSamplingCollector, deriveRunOutcome, describeRunError, extractRunTelemetryModelId, generateThreadTitle, normalizeRunTelemetryUsage, readAnonymousRefreshToken, truncateRunTelemetryText, wrapSamplingHandler };
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { CloudResponseError } from "./cloudResponse.js";
|
|
2
|
+
import { readAnonymousRefreshToken } from "./AssistantCloudAuthStrategy.js";
|
|
2
3
|
import { CloudAPIError } from "./AssistantCloudAPI.js";
|
|
4
|
+
import { AssistantCloudEvents } from "./AssistantCloudEvents.js";
|
|
5
|
+
import { AssistantCloudScores } from "./AssistantCloudScores.js";
|
|
3
6
|
import { AssistantCloud } from "./AssistantCloud.js";
|
|
4
7
|
import { CloudMessagePersistence } from "./CloudMessagePersistence.js";
|
|
5
8
|
import { createFormattedPersistence } from "./FormattedCloudPersistence.js";
|
|
6
9
|
import { generateThreadTitle } from "./generateThreadTitle.js";
|
|
7
|
-
import { createRunTelemetryToolCall, normalizeRunTelemetryUsage, truncateRunTelemetryText } from "./runTelemetry.js";
|
|
10
|
+
import { createRunReport, createRunTelemetryToolCall, deriveRunOutcome, describeRunError, extractRunTelemetryModelId, normalizeRunTelemetryUsage, truncateRunTelemetryText } from "./runTelemetry.js";
|
|
8
11
|
import { createSamplingCollector, wrapSamplingHandler } from "./instrumentMcpSampling.js";
|
|
9
|
-
export { AssistantCloud, CloudAPIError, CloudMessagePersistence, CloudResponseError, createFormattedPersistence, createRunTelemetryToolCall, createSamplingCollector, generateThreadTitle, normalizeRunTelemetryUsage, truncateRunTelemetryText, wrapSamplingHandler };
|
|
12
|
+
export { AssistantCloud, AssistantCloudEvents, AssistantCloudScores, CloudAPIError, CloudMessagePersistence, CloudResponseError, createFormattedPersistence, createRunReport, createRunTelemetryToolCall, createSamplingCollector, deriveRunOutcome, describeRunError, extractRunTelemetryModelId, generateThreadTitle, normalizeRunTelemetryUsage, readAnonymousRefreshToken, truncateRunTelemetryText, wrapSamplingHandler };
|
package/dist/runTelemetry.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SamplingCallData } from "./instrumentMcpSampling.js";
|
|
2
|
+
import { AssistantCloudRunReport } from "./AssistantCloudRuns.js";
|
|
2
3
|
//#region src/runTelemetry.d.ts
|
|
3
4
|
type AssistantCloudRunReportToolCall = {
|
|
4
5
|
tool_name: string;
|
|
@@ -10,6 +11,28 @@ type AssistantCloudRunReportToolCall = {
|
|
|
10
11
|
end_ms?: number;
|
|
11
12
|
sampling_calls?: SamplingCallData[];
|
|
12
13
|
};
|
|
14
|
+
type RunReportOutcome = "aborted" | "disconnected" | "length" | "content_filter";
|
|
15
|
+
/**
|
|
16
|
+
* Maps a finish event to the report status and outcome. `fallbackStatus`
|
|
17
|
+
* applies when the event carries neither a finish reason nor a failure flag.
|
|
18
|
+
*/
|
|
19
|
+
declare function deriveRunOutcome(input: {
|
|
20
|
+
finishReason?: string | undefined;
|
|
21
|
+
isAbort?: boolean | undefined;
|
|
22
|
+
isDisconnect?: boolean | undefined;
|
|
23
|
+
isError?: boolean | undefined;
|
|
24
|
+
}, fallbackStatus?: "completed" | "incomplete"): {
|
|
25
|
+
status: "completed" | "incomplete" | "error";
|
|
26
|
+
outcome?: RunReportOutcome;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Reads the message and code the runs endpoint stores for a failed run. The
|
|
30
|
+
* code is the error's `code` when it has one, else its class name.
|
|
31
|
+
*/
|
|
32
|
+
declare function describeRunError(error: unknown): {
|
|
33
|
+
error?: string;
|
|
34
|
+
errorCode?: string;
|
|
35
|
+
};
|
|
13
36
|
/**
|
|
14
37
|
* Clamps a string to the size the runs endpoint accepts for a single span
|
|
15
38
|
* field.
|
|
@@ -33,22 +56,69 @@ type RunTelemetryToolCallInit = {
|
|
|
33
56
|
* base64 image and audio payloads that would otherwise dominate the report.
|
|
34
57
|
*/
|
|
35
58
|
declare function createRunTelemetryToolCall(init: RunTelemetryToolCallInit): AssistantCloudRunReportToolCall;
|
|
59
|
+
/**
|
|
60
|
+
* Resolves the model ID a run reports, in the order an app can supply it: an
|
|
61
|
+
* explicit `modelId`, the `custom` bag, then the per-step `response.modelId`
|
|
62
|
+
* that a `messageMetadata` callback copies off the AI SDK's finish-step part.
|
|
63
|
+
* The AI SDK puts no model ID on a UI message part, so message metadata is the
|
|
64
|
+
* only channel one arrives on.
|
|
65
|
+
*/
|
|
66
|
+
declare function extractRunTelemetryModelId(metadata: Record<string, unknown> | undefined): string | undefined;
|
|
36
67
|
type RunTelemetryUsage = {
|
|
37
|
-
inputTokens?: number;
|
|
38
|
-
outputTokens?: number;
|
|
39
|
-
reasoningTokens?: number;
|
|
40
|
-
cachedInputTokens?: number;
|
|
68
|
+
inputTokens?: number | undefined;
|
|
69
|
+
outputTokens?: number | undefined;
|
|
70
|
+
reasoningTokens?: number | undefined;
|
|
71
|
+
cachedInputTokens?: number | undefined;
|
|
41
72
|
};
|
|
42
73
|
type RunTelemetryUsageInit = RunTelemetryUsage & {
|
|
43
|
-
promptTokens?: number;
|
|
44
|
-
completionTokens?: number;
|
|
74
|
+
promptTokens?: number | undefined;
|
|
75
|
+
completionTokens?: number | undefined;
|
|
76
|
+
inputTokenDetails?: {
|
|
77
|
+
cacheReadTokens?: number;
|
|
78
|
+
};
|
|
79
|
+
outputTokenDetails?: {
|
|
80
|
+
reasoningTokens?: number;
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
type RunReportStepInit = {
|
|
84
|
+
usage?: RunTelemetryUsageInit | undefined;
|
|
85
|
+
toolCalls?: AssistantCloudRunReportToolCall[] | undefined;
|
|
86
|
+
startMs?: number | undefined;
|
|
87
|
+
endMs?: number | undefined;
|
|
88
|
+
finishReason?: string | undefined;
|
|
89
|
+
};
|
|
90
|
+
type RunReportInit = {
|
|
91
|
+
threadId: string;
|
|
92
|
+
status: AssistantCloudRunReport["status"];
|
|
93
|
+
outcome?: RunReportOutcome | undefined;
|
|
94
|
+
errorCode?: string | undefined;
|
|
95
|
+
error?: string | undefined;
|
|
96
|
+
messageId?: string | undefined;
|
|
97
|
+
traceId?: string | undefined;
|
|
98
|
+
modelId?: string | undefined;
|
|
99
|
+
provider?: string | undefined;
|
|
100
|
+
usage?: RunTelemetryUsageInit | undefined;
|
|
101
|
+
steps?: RunReportStepInit[] | undefined;
|
|
102
|
+
totalSteps?: number | undefined;
|
|
103
|
+
toolCalls?: AssistantCloudRunReportToolCall[] | undefined;
|
|
104
|
+
durationMs?: number | undefined;
|
|
105
|
+
firstTokenMs?: number | undefined;
|
|
106
|
+
outputText?: string | undefined;
|
|
107
|
+
metadata?: Record<string, unknown> | undefined;
|
|
108
|
+
telemetry?: {
|
|
109
|
+
environment?: string | undefined;
|
|
110
|
+
release?: string | undefined;
|
|
111
|
+
tags?: readonly string[] | undefined;
|
|
112
|
+
};
|
|
45
113
|
};
|
|
114
|
+
declare function createRunReport(init: RunReportInit): AssistantCloudRunReport;
|
|
46
115
|
/**
|
|
47
|
-
* Resolves the token counts a provider reports under
|
|
48
|
-
*
|
|
116
|
+
* Resolves the token counts a provider reports under any of the names the AI
|
|
117
|
+
* SDK has used: the current top-level ones, the legacy prompt/completion pair,
|
|
118
|
+
* and the v7 token detail objects. Returns undefined when no count is present,
|
|
49
119
|
* so callers can tell an empty usage object from a zeroed one.
|
|
50
120
|
*/
|
|
51
121
|
declare function normalizeRunTelemetryUsage(usage: RunTelemetryUsageInit): RunTelemetryUsage | undefined;
|
|
52
122
|
//#endregion
|
|
53
|
-
export { AssistantCloudRunReportToolCall, RunTelemetryToolCallInit, RunTelemetryUsage, RunTelemetryUsageInit, createRunTelemetryToolCall, normalizeRunTelemetryUsage, truncateRunTelemetryText };
|
|
123
|
+
export { AssistantCloudRunReportToolCall, RunReportInit, RunReportOutcome, RunReportStepInit, RunTelemetryToolCallInit, RunTelemetryUsage, RunTelemetryUsageInit, createRunReport, createRunTelemetryToolCall, deriveRunOutcome, describeRunError, extractRunTelemetryModelId, normalizeRunTelemetryUsage, truncateRunTelemetryText };
|
|
54
124
|
//# sourceMappingURL=runTelemetry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runTelemetry.d.ts","names":[],"sources":["../src/runTelemetry.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"runTelemetry.d.ts","names":[],"sources":["../src/runTelemetry.ts"],"mappings":";;;KAOY;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA,iBAAiB;;KAGP;;;;;iBAUI,iBACd;EACE;EACA;EACA;EACA;GAEF;EAEA;EACA,UAAU;;;;;;iBA+BI,iBAAiB;EAC/B;EACA;;;;;;iBA+Bc,yBAAyB;KAwC7B;EACV;EACA;EACA;;;;;EAKA;EACA;EACA;;;;;;;iBAQc,2BACd,MAAM,2BACL;;;;;;;;iBAuBa,2BACd,UAAU;KAmBA;EACV;EACA;EACA;EACA;;KAGU,wBAAwB;EAClC;EACA;EACA;IAAsB;;EACtB;IAAuB;;;KAGb;EACV,QAAQ;EACR,YAAY;EACZ;EACA;EACA;;KAGU;EACV;EACA,QAAQ;EACR,UAAU;EACV;EACA;EACA;EACA;EACA;EACA;EACA,QAAQ;EACR,QAAQ;EACR;EACA,YAAY;EACZ;EACA;EACA;EACA,WAAW;EACX;IACE;IACA;IACA;;;iBAuEY,gBAAgB,MAAM,gBAAgB;;;;;;;iBAiDtC,2BACd,OAAO,wBACN"}
|
package/dist/runTelemetry.js
CHANGED
|
@@ -2,6 +2,54 @@
|
|
|
2
2
|
const MAX_TELEMETRY_TEXT_LENGTH = 5e4;
|
|
3
3
|
const BASE64_PATTERN = /^[A-Za-z0-9+/]{100,}={0,2}$/;
|
|
4
4
|
/**
|
|
5
|
+
* Maps a finish event to the report status and outcome. `fallbackStatus`
|
|
6
|
+
* applies when the event carries neither a finish reason nor a failure flag.
|
|
7
|
+
*/
|
|
8
|
+
function deriveRunOutcome(input, fallbackStatus = "completed") {
|
|
9
|
+
if (input.isError) return { status: "error" };
|
|
10
|
+
if (input.isAbort) return {
|
|
11
|
+
status: "incomplete",
|
|
12
|
+
outcome: "aborted"
|
|
13
|
+
};
|
|
14
|
+
if (input.isDisconnect) return {
|
|
15
|
+
status: "incomplete",
|
|
16
|
+
outcome: "disconnected"
|
|
17
|
+
};
|
|
18
|
+
switch (input.finishReason) {
|
|
19
|
+
case "length": return {
|
|
20
|
+
status: "incomplete",
|
|
21
|
+
outcome: "length"
|
|
22
|
+
};
|
|
23
|
+
case "content-filter":
|
|
24
|
+
case "content_filter": return {
|
|
25
|
+
status: "incomplete",
|
|
26
|
+
outcome: "content_filter"
|
|
27
|
+
};
|
|
28
|
+
case "cancelled": return {
|
|
29
|
+
status: "incomplete",
|
|
30
|
+
outcome: "aborted"
|
|
31
|
+
};
|
|
32
|
+
case "error": return { status: "error" };
|
|
33
|
+
default: return { status: input.finishReason === void 0 ? fallbackStatus : "completed" };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const MAX_RUN_ERROR_CODE_LENGTH = 64;
|
|
37
|
+
const MAX_RUN_ERROR_LENGTH = 2048;
|
|
38
|
+
/**
|
|
39
|
+
* Reads the message and code the runs endpoint stores for a failed run. The
|
|
40
|
+
* code is the error's `code` when it has one, else its class name.
|
|
41
|
+
*/
|
|
42
|
+
function describeRunError(error) {
|
|
43
|
+
if (error == null) return {};
|
|
44
|
+
const record = typeof error === "object" ? error : void 0;
|
|
45
|
+
const message = typeof error === "string" ? error : typeof record?.message === "string" ? record.message : void 0;
|
|
46
|
+
const code = typeof record?.code === "string" ? record.code : typeof record?.name === "string" && record.name !== "Error" ? record.name : void 0;
|
|
47
|
+
return {
|
|
48
|
+
...message ? { error: message.slice(0, MAX_RUN_ERROR_LENGTH) } : void 0,
|
|
49
|
+
...code ? { errorCode: code.slice(0, MAX_RUN_ERROR_CODE_LENGTH) } : void 0
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
5
53
|
* Clamps a string to the size the runs endpoint accepts for a single span
|
|
6
54
|
* field.
|
|
7
55
|
*/
|
|
@@ -58,22 +106,120 @@ function createRunTelemetryToolCall(init) {
|
|
|
58
106
|
return call;
|
|
59
107
|
}
|
|
60
108
|
/**
|
|
61
|
-
* Resolves the
|
|
62
|
-
*
|
|
109
|
+
* Resolves the model ID a run reports, in the order an app can supply it: an
|
|
110
|
+
* explicit `modelId`, the `custom` bag, then the per-step `response.modelId`
|
|
111
|
+
* that a `messageMetadata` callback copies off the AI SDK's finish-step part.
|
|
112
|
+
* The AI SDK puts no model ID on a UI message part, so message metadata is the
|
|
113
|
+
* only channel one arrives on.
|
|
114
|
+
*/
|
|
115
|
+
function extractRunTelemetryModelId(metadata) {
|
|
116
|
+
if (!metadata) return void 0;
|
|
117
|
+
if (typeof metadata.modelId === "string") return metadata.modelId;
|
|
118
|
+
const custom = metadata.custom;
|
|
119
|
+
if (typeof custom?.modelId === "string") return custom.modelId;
|
|
120
|
+
const steps = metadata.steps;
|
|
121
|
+
if (!Array.isArray(steps)) return void 0;
|
|
122
|
+
for (const step of steps) {
|
|
123
|
+
if (!step || typeof step !== "object") continue;
|
|
124
|
+
const response = step.response;
|
|
125
|
+
if (!response || typeof response !== "object") continue;
|
|
126
|
+
const modelId = response.modelId;
|
|
127
|
+
if (typeof modelId === "string") return modelId;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function assignUsage(report, usage) {
|
|
131
|
+
if (!usage) return;
|
|
132
|
+
const normalized = normalizeRunTelemetryUsage(usage);
|
|
133
|
+
if (!normalized) return;
|
|
134
|
+
if (normalized.inputTokens !== void 0) report.input_tokens = normalized.inputTokens;
|
|
135
|
+
if (normalized.outputTokens !== void 0) report.output_tokens = normalized.outputTokens;
|
|
136
|
+
if (normalized.reasoningTokens !== void 0) report.reasoning_tokens = normalized.reasoningTokens;
|
|
137
|
+
if (normalized.cachedInputTokens !== void 0) report.cached_input_tokens = normalized.cachedInputTokens;
|
|
138
|
+
}
|
|
139
|
+
function createRunReportStep(init) {
|
|
140
|
+
const step = {};
|
|
141
|
+
const usage = init.usage ? normalizeRunTelemetryUsage(init.usage) : void 0;
|
|
142
|
+
if (usage?.inputTokens !== void 0) step.input_tokens = usage.inputTokens;
|
|
143
|
+
if (usage?.outputTokens !== void 0) step.output_tokens = usage.outputTokens;
|
|
144
|
+
if (usage?.reasoningTokens !== void 0) step.reasoning_tokens = usage.reasoningTokens;
|
|
145
|
+
if (usage?.cachedInputTokens !== void 0) step.cached_input_tokens = usage.cachedInputTokens;
|
|
146
|
+
if (init.toolCalls !== void 0) step.tool_calls = init.toolCalls;
|
|
147
|
+
if (init.startMs !== void 0) step.start_ms = init.startMs;
|
|
148
|
+
if (init.endMs !== void 0) step.end_ms = init.endMs;
|
|
149
|
+
if (init.finishReason !== void 0) step.finish_reason = init.finishReason.slice(0, 32);
|
|
150
|
+
return step;
|
|
151
|
+
}
|
|
152
|
+
function normalizeRunReportTags(tags) {
|
|
153
|
+
if (!tags) return void 0;
|
|
154
|
+
const result = [];
|
|
155
|
+
const seen = /* @__PURE__ */ new Set();
|
|
156
|
+
for (const tag of tags) {
|
|
157
|
+
const normalized = tag.trim().slice(0, 64).trim();
|
|
158
|
+
if (!normalized || seen.has(normalized)) continue;
|
|
159
|
+
seen.add(normalized);
|
|
160
|
+
result.push(normalized);
|
|
161
|
+
if (result.length === 20) break;
|
|
162
|
+
}
|
|
163
|
+
return result.length > 0 ? result : void 0;
|
|
164
|
+
}
|
|
165
|
+
function normalizeRunReportMilliseconds(value) {
|
|
166
|
+
if (value === void 0 || !Number.isFinite(value)) return void 0;
|
|
167
|
+
return Math.max(0, Math.round(value));
|
|
168
|
+
}
|
|
169
|
+
function createRunReport(init) {
|
|
170
|
+
const report = {
|
|
171
|
+
thread_id: init.threadId,
|
|
172
|
+
status: init.status
|
|
173
|
+
};
|
|
174
|
+
const traceId = init.traceId?.toLowerCase();
|
|
175
|
+
if (traceId && /^[0-9a-f]{32}$/.test(traceId)) report.trace_id = traceId;
|
|
176
|
+
if (init.outcome !== void 0) report.outcome_type = init.outcome;
|
|
177
|
+
if (init.errorCode !== void 0) report.error_code = init.errorCode;
|
|
178
|
+
if (init.error !== void 0) report.error = init.error;
|
|
179
|
+
if (init.messageId !== void 0) report.message_id = init.messageId;
|
|
180
|
+
if (init.modelId !== void 0) report.model_id = init.modelId;
|
|
181
|
+
if (init.provider !== void 0) {
|
|
182
|
+
report.provider = init.provider;
|
|
183
|
+
report.provider_type = init.provider;
|
|
184
|
+
}
|
|
185
|
+
assignUsage(report, init.usage);
|
|
186
|
+
if (init.steps !== void 0) {
|
|
187
|
+
report.steps = init.steps.map(createRunReportStep);
|
|
188
|
+
report.total_steps = init.steps.length;
|
|
189
|
+
} else if (init.totalSteps !== void 0) report.total_steps = init.totalSteps;
|
|
190
|
+
if (init.toolCalls !== void 0) report.tool_calls = init.toolCalls;
|
|
191
|
+
const durationMs = normalizeRunReportMilliseconds(init.durationMs);
|
|
192
|
+
if (durationMs !== void 0) report.duration_ms = durationMs;
|
|
193
|
+
const firstTokenMs = normalizeRunReportMilliseconds(init.firstTokenMs);
|
|
194
|
+
if (firstTokenMs !== void 0) report.first_token_ms = firstTokenMs;
|
|
195
|
+
if (init.outputText !== void 0) report.output_text = truncateRunTelemetryText(init.outputText);
|
|
196
|
+
if (init.metadata !== void 0) report.metadata = init.metadata;
|
|
197
|
+
if (init.telemetry?.environment !== void 0) report.environment = init.telemetry.environment;
|
|
198
|
+
if (init.telemetry?.release !== void 0) report.release = init.telemetry.release;
|
|
199
|
+
const tags = normalizeRunReportTags(init.telemetry?.tags);
|
|
200
|
+
if (tags !== void 0) report.tags = tags;
|
|
201
|
+
return report;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Resolves the token counts a provider reports under any of the names the AI
|
|
205
|
+
* SDK has used: the current top-level ones, the legacy prompt/completion pair,
|
|
206
|
+
* and the v7 token detail objects. Returns undefined when no count is present,
|
|
63
207
|
* so callers can tell an empty usage object from a zeroed one.
|
|
64
208
|
*/
|
|
65
209
|
function normalizeRunTelemetryUsage(usage) {
|
|
66
210
|
const inputTokens = usage.inputTokens ?? usage.promptTokens;
|
|
67
211
|
const outputTokens = usage.outputTokens ?? usage.completionTokens;
|
|
68
|
-
|
|
212
|
+
const reasoningTokens = usage.reasoningTokens ?? usage.outputTokenDetails?.reasoningTokens;
|
|
213
|
+
const cachedInputTokens = usage.cachedInputTokens ?? usage.inputTokenDetails?.cacheReadTokens;
|
|
214
|
+
if (inputTokens == null && outputTokens == null && reasoningTokens == null && cachedInputTokens == null) return;
|
|
69
215
|
return {
|
|
70
216
|
...inputTokens != null ? { inputTokens } : void 0,
|
|
71
217
|
...outputTokens != null ? { outputTokens } : void 0,
|
|
72
|
-
...
|
|
73
|
-
...
|
|
218
|
+
...reasoningTokens != null ? { reasoningTokens } : void 0,
|
|
219
|
+
...cachedInputTokens != null ? { cachedInputTokens } : void 0
|
|
74
220
|
};
|
|
75
221
|
}
|
|
76
222
|
//#endregion
|
|
77
|
-
export { createRunTelemetryToolCall, normalizeRunTelemetryUsage, truncateRunTelemetryText };
|
|
223
|
+
export { createRunReport, createRunTelemetryToolCall, deriveRunOutcome, describeRunError, extractRunTelemetryModelId, normalizeRunTelemetryUsage, truncateRunTelemetryText };
|
|
78
224
|
|
|
79
225
|
//# sourceMappingURL=runTelemetry.js.map
|