@introspection-sdk/introspection-browser 0.5.2 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api/index.js CHANGED
@@ -12,8 +12,8 @@
12
12
  *
13
13
  * const client = new IntrospectionApiClient({
14
14
  * dpUrl: "https://dp.us.introspection.dev",
15
- * projectId: "proj_…",
16
- * // your backend mints the Introspection access token
15
+ * // your backend mints the Introspection access token (the session's
16
+ * // project is derived from its claims — no projectId option needed)
17
17
  * getToken: () => fetch("/api/introspection/token").then((r) => r.text()),
18
18
  * });
19
19
  *
@@ -28,6 +28,9 @@
28
28
  */
29
29
  export { IntrospectionApiClient, } from "./client.js";
30
30
  export { TasksClient, TaskRunsClient, RunHandle, } from "./tasks.js";
31
+ export { FilesClient, FileVersionsClient, } from "./files.js";
32
+ export { ConversationsClient, ConversationItemsClient, } from "./conversations.js";
33
+ export { SharesClient } from "./shares.js";
31
34
  export { BrowserHttpClient } from "./http.js";
32
35
  export { parseSse } from "./sse.js";
33
36
  export { Paginator, cursorPaginate, } from "@introspection-sdk/http";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EACL,sBAAsB,GAEvB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,GAGV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAA0B,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EACL,SAAS,EACT,cAAc,GAEf,MAAM,yBAAyB,CAAC;AAiBjC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,YAAY,GACb,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EACL,sBAAsB,GAEvB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,GAGV,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,WAAW,EACX,kBAAkB,GAEnB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAA0B,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EACL,SAAS,EACT,cAAc,GAEf,MAAM,yBAAyB,CAAC;AAiCjC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,YAAY,GACb,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Cookie-authenticated Resource Shares client for the browser (`/v1/shares`).
3
+ *
4
+ * Read-sharing grants for files and conversations: `create` / `list` / `get` /
5
+ * `delete` (revoke). A grant carries a `url` (with the `?share_id` capability) —
6
+ * read the shared resource via `client.files.get(id, { shareId })` or
7
+ * `client.conversations.items(id, { shareId })`. To fork a new task from a
8
+ * shared conversation, pass `fork_share_id` to `client.tasks.create(...)`.
9
+ */
10
+ import type { ResourceShare, ShareCreateParams, ShareListParams } from "@introspection-sdk/types";
11
+ import { Paginator } from "@introspection-sdk/http";
12
+ import { BrowserHttpClient } from "./http.js";
13
+ /** Cookie-authenticated `/v1/shares` client. */
14
+ export declare class SharesClient {
15
+ private readonly http;
16
+ constructor(http: BrowserHttpClient);
17
+ /**
18
+ * List grants the caller created or that target them. `await` for the first
19
+ * page, or `for await` to stream every grant across pages.
20
+ */
21
+ list(params?: ShareListParams): Paginator<ResourceShare>;
22
+ /** Create a read-sharing grant. The caller must own the target resource. */
23
+ create(body: ShareCreateParams): Promise<ResourceShare>;
24
+ /** Read a single grant (carries the `url` to the shared resource). */
25
+ get(shareId: string): Promise<ResourceShare>;
26
+ /** Revoke a grant. Only the grantor (or an admin/owner) may revoke. */
27
+ delete(shareId: string): Promise<void>;
28
+ }
29
+ //# sourceMappingURL=shares.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shares.d.ts","sourceRoot":"","sources":["../../src/api/shares.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAEV,aAAa,EACb,iBAAiB,EACjB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,EAAkB,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,gDAAgD;AAChD,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,iBAAiB;IAEpD;;;OAGG;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,aAAa,CAAC;IAYxD,4EAA4E;IAC5E,MAAM,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC;IAQvD,sEAAsE;IACtE,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAO5C,uEAAuE;IACvE,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAOvC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Cookie-authenticated Resource Shares client for the browser (`/v1/shares`).
3
+ *
4
+ * Read-sharing grants for files and conversations: `create` / `list` / `get` /
5
+ * `delete` (revoke). A grant carries a `url` (with the `?share_id` capability) —
6
+ * read the shared resource via `client.files.get(id, { shareId })` or
7
+ * `client.conversations.items(id, { shareId })`. To fork a new task from a
8
+ * shared conversation, pass `fork_share_id` to `client.tasks.create(...)`.
9
+ */
10
+ import { cursorPaginate } from "@introspection-sdk/http";
11
+ /** Cookie-authenticated `/v1/shares` client. */
12
+ export class SharesClient {
13
+ http;
14
+ constructor(http) {
15
+ this.http = http;
16
+ }
17
+ /**
18
+ * List grants the caller created or that target them. `await` for the first
19
+ * page, or `for await` to stream every grant across pages.
20
+ */
21
+ list(params) {
22
+ return cursorPaginate((next) => this.http.request({
23
+ method: "GET",
24
+ path: "/v1/shares",
25
+ query: { ...params, next },
26
+ }), params?.next);
27
+ }
28
+ /** Create a read-sharing grant. The caller must own the target resource. */
29
+ create(body) {
30
+ return this.http.request({
31
+ method: "POST",
32
+ path: "/v1/shares",
33
+ body,
34
+ });
35
+ }
36
+ /** Read a single grant (carries the `url` to the shared resource). */
37
+ get(shareId) {
38
+ return this.http.request({
39
+ method: "GET",
40
+ path: `/v1/shares/${encodeURIComponent(shareId)}`,
41
+ });
42
+ }
43
+ /** Revoke a grant. Only the grantor (or an admin/owner) may revoke. */
44
+ delete(shareId) {
45
+ return this.http.request({
46
+ method: "DELETE",
47
+ path: `/v1/shares/${encodeURIComponent(shareId)}`,
48
+ expect: "empty",
49
+ });
50
+ }
51
+ }
52
+ //# sourceMappingURL=shares.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shares.js","sourceRoot":"","sources":["../../src/api/shares.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,OAAO,EAAa,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGpE,gDAAgD;AAChD,MAAM,OAAO,YAAY;IACM;IAA7B,YAA6B,IAAuB;QAAvB,SAAI,GAAJ,IAAI,CAAmB;IAAG,CAAC;IAExD;;;OAGG;IACH,IAAI,CAAC,MAAwB;QAC3B,OAAO,cAAc,CACnB,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,IAAI,CAAC,OAAO,CAA2B;YAC1C,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,IAAI,EAA6B;SACtD,CAAC,EACJ,MAAM,EAAE,IAAI,CACb,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,MAAM,CAAC,IAAuB;QAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAgB;YACtC,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,YAAY;YAClB,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED,sEAAsE;IACtE,GAAG,CAAC,OAAe;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAgB;YACtC,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,cAAc,kBAAkB,CAAC,OAAO,CAAC,EAAE;SAClD,CAAC,CAAC;IACL,CAAC;IAED,uEAAuE;IACvE,MAAM,CAAC,OAAe;QACpB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAO;YAC7B,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,cAAc,kBAAkB,CAAC,OAAO,CAAC,EAAE;YACjD,MAAM,EAAE,OAAO;SAChB,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -1,4 +1,4 @@
1
- import type { RunIdentityInput, SseEvent, Task, TaskCancelResponse, TaskCreateResponse, TaskListParams, TaskRun, TaskRunCreateParams, TaskUpdateParams, TaskVisibility } from "@introspection-sdk/types";
1
+ import type { RunIdentityInput, SseEvent, Task, TaskCancelResponse, TaskCreateResponse, TaskListParams, TaskRun, TaskRunCreateParams, TaskUpdateParams } from "@introspection-sdk/types";
2
2
  import { Paginator } from "@introspection-sdk/http";
3
3
  import { BrowserHttpClient } from "./http.js";
4
4
  /**
@@ -19,7 +19,6 @@ export interface CreateTaskParams {
19
19
  agent_name?: string;
20
20
  title?: string;
21
21
  metadata?: Record<string, unknown>;
22
- visibility?: TaskVisibility;
23
22
  /**
24
23
  * Override the interactive idle window (seconds) before the sandbox is
25
24
  * torn down. `0` tears down as soon as it's provisioned; omit to use the
@@ -28,6 +27,13 @@ export interface CreateTaskParams {
28
27
  idle_timeout_seconds?: number;
29
28
  /** Caller identity for attribution; merged into `metadata.identity`. */
30
29
  identity?: RunIdentityInput;
30
+ /**
31
+ * Fork from a shared conversation: the `/v1/shares` grant id for the source
32
+ * conversation. Its presence makes this create a fork — the server seeds the
33
+ * new task with that conversation's history, read via the share (the
34
+ * permissions boundary).
35
+ */
36
+ fork_share_id?: string;
31
37
  }
32
38
  export interface StartTaskParams extends CreateTaskParams {
33
39
  /** Required for the `start()` sugar that returns a run handle. */
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/api/tasks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/api/tasks.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/api/tasks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/api/tasks.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@introspection-sdk/introspection-browser",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Introspection observability SDK for the browser",
6
6
  "engines": {
@@ -20,7 +20,7 @@
20
20
  }
21
21
  },
22
22
  "devDependencies": {
23
- "@types/node": "^22.19.20",
23
+ "@types/node": "^22.19.21",
24
24
  "eslint": "^9.39.4",
25
25
  "typescript": "5.9.3",
26
26
  "@repo/eslint-config": "0.0.0",
@@ -31,8 +31,8 @@
31
31
  "@opentelemetry/api-logs": "^0.219.0",
32
32
  "@opentelemetry/sdk-logs": "^0.219.0",
33
33
  "@opentelemetry/exporter-logs-otlp-http": "^0.219.0",
34
- "@introspection-sdk/http": "0.5.2",
35
- "@introspection-sdk/types": "0.5.2"
34
+ "@introspection-sdk/http": "0.5.4",
35
+ "@introspection-sdk/types": "0.5.4"
36
36
  },
37
37
  "scripts": {
38
38
  "lint": "eslint . --max-warnings 0",
package/src/api/client.ts CHANGED
@@ -21,16 +21,19 @@
21
21
 
22
22
  import { BrowserHttpClient, stripTrailingSlash, toApiError } from "./http.js";
23
23
  import { TasksClient } from "./tasks.js";
24
+ import { FilesClient } from "./files.js";
25
+ import { ConversationsClient } from "./conversations.js";
26
+ import { SharesClient } from "./shares.js";
24
27
 
25
28
  export interface IntrospectionApiClientOptions {
26
29
  /** Data Plane REST base URL (e.g. `https://dp.us.introspection.dev`). */
27
30
  dpUrl: string;
28
- /** Project the session is scoped to. */
29
- projectId: string;
30
31
  /**
31
32
  * Returns a fresh Introspection access token from the app's broker
32
33
  * (its own backend). Called on `connect()` and again whenever the DP
33
- * session cookie needs re-minting after a 401.
34
+ * session cookie needs re-minting after a 401. The session's project is
35
+ * derived from this token's claims server-side — there is no separate
36
+ * project option.
34
37
  */
35
38
  getToken: () => string | Promise<string>;
36
39
  /** Custom `fetch` (for tests or non-standard runtimes). */
@@ -42,6 +45,12 @@ export interface IntrospectionApiClientOptions {
42
45
  export class IntrospectionApiClient {
43
46
  /** `/v1/tasks` operations bound to the DP session cookie. */
44
47
  readonly tasks: TasksClient;
48
+ /** `/v1/files` operations bound to the DP session cookie. */
49
+ readonly files: FilesClient;
50
+ /** Read-only `/v1/conversations` projection bound to the session cookie. */
51
+ readonly conversations: ConversationsClient;
52
+ /** `/v1/shares` read-sharing grants bound to the session cookie. */
53
+ readonly shares: SharesClient;
45
54
 
46
55
  private readonly fetchImpl: typeof fetch;
47
56
 
@@ -59,6 +68,9 @@ export class IntrospectionApiClient {
59
68
  onUnauthorized: () => this.reexchange(),
60
69
  });
61
70
  this.tasks = new TasksClient(http);
71
+ this.files = new FilesClient(http);
72
+ this.conversations = new ConversationsClient(http);
73
+ this.shares = new SharesClient(http);
62
74
  }
63
75
 
64
76
  /**
@@ -79,7 +91,7 @@ export class IntrospectionApiClient {
79
91
  "Content-Type": "application/json",
80
92
  ...(this.opts.additionalHeaders ?? {}),
81
93
  },
82
- body: JSON.stringify({ token, project_id: this.opts.projectId }),
94
+ body: JSON.stringify({ token }),
83
95
  credentials: "include",
84
96
  },
85
97
  );
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Cookie-authenticated, read-only Conversations client for the browser
3
+ * (`/v1/conversations`).
4
+ *
5
+ * Mirrors the Node SDK's runner-bound `ConversationsApi`, but rides the
6
+ * DP `intro_dp_session` cookie via {@link BrowserHttpClient} instead of a
7
+ * bearer token — so a single-page app reads conversation history with the
8
+ * same identity session it uses for tasks and files. Conversations are a
9
+ * projection over the immutable telemetry store: list summaries, walk a
10
+ * conversation's items, or `retrieve()` the resolved state of one turn.
11
+ */
12
+
13
+ import type {
14
+ ConversationItem,
15
+ ConversationItemInclude,
16
+ ConversationItemList,
17
+ ConversationItemListParams,
18
+ ConversationListParams,
19
+ ConversationResponse,
20
+ ConversationSummary,
21
+ MessagePart,
22
+ Paginated,
23
+ ToolCallResponsePart,
24
+ } from "@introspection-sdk/types";
25
+ import { Paginator, cursorPaginate } from "@introspection-sdk/http";
26
+ import { BrowserHttpClient } from "./http.js";
27
+
28
+ /** Includes requested when building a {@link ConversationResponse}. */
29
+ const RESPONSE_INCLUDES: ConversationItemInclude[] = [
30
+ "gen_ai.input.messages",
31
+ "gen_ai.system_instructions",
32
+ "gen_ai.tool.definitions",
33
+ ];
34
+
35
+ /**
36
+ * Items of a conversation (`/v1/conversations/{id}/items`). Read-only.
37
+ *
38
+ * Paging is OpenAI-style underneath: the envelope has NO `next` token —
39
+ * `list()` drives `after` = the previous page's `last_id` while
40
+ * `has_more` is true.
41
+ */
42
+ export class ConversationItemsClient {
43
+ constructor(private readonly http: BrowserHttpClient) {}
44
+
45
+ /**
46
+ * List items of a conversation. `await` the result for the first page
47
+ * (an OpenAI-style {@link ConversationItemList} envelope), or
48
+ * `for await` it to stream every item across pages (fetched lazily —
49
+ * `limit` sets the page size, `after` the starting cursor; stop early to
50
+ * stop fetching). Pass `order: "asc"` to walk the transcript from the
51
+ * start.
52
+ *
53
+ * Items carry the turn-local delta in `input_messages` — only the
54
+ * messages new to that turn. Use `get()` for the full input history.
55
+ */
56
+ list(
57
+ conversationId: string,
58
+ params?: ConversationItemListParams,
59
+ ): Paginator<ConversationItem, ConversationItemList> {
60
+ return new Paginator(
61
+ {
62
+ fetch: (after) =>
63
+ this.http.request<ConversationItemList>({
64
+ method: "GET",
65
+ path: `/v1/conversations/${encodeURIComponent(conversationId)}/items`,
66
+ query: { ...params, after } as Record<string, unknown>,
67
+ }),
68
+ items: (page) => page.data,
69
+ next: (page) =>
70
+ page.has_more && page.last_id !== null ? page.last_id : undefined,
71
+ },
72
+ params?.after,
73
+ );
74
+ }
75
+
76
+ /**
77
+ * Fetch a single conversation item. Unlike the list route, the
78
+ * detail's `input_messages` is the FULL input history for that span.
79
+ */
80
+ get(
81
+ conversationId: string,
82
+ itemId: string,
83
+ params?: { include?: ConversationItemInclude[] },
84
+ ): Promise<ConversationItem> {
85
+ return this.http.request<ConversationItem>({
86
+ method: "GET",
87
+ path: `/v1/conversations/${encodeURIComponent(conversationId)}/items/${encodeURIComponent(itemId)}`,
88
+ query: params as Record<string, unknown> | undefined,
89
+ });
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Read-only Conversations client (`/v1/conversations`).
95
+ *
96
+ * Both `list()` and `items.list()` are auto-paging, but they drive
97
+ * different wire protocols underneath: `list()` walks the standard
98
+ * Introspection cursor envelope's opaque `next` token, while
99
+ * `items.list()` walks an OpenAI-style envelope via `after` = the
100
+ * previous page's `last_id` while `has_more` is true.
101
+ */
102
+ export class ConversationsClient {
103
+ /** Items of a conversation — `conversations.items.list(...)` etc. */
104
+ readonly items: ConversationItemsClient;
105
+
106
+ constructor(private readonly http: BrowserHttpClient) {
107
+ this.items = new ConversationItemsClient(http);
108
+ }
109
+
110
+ /**
111
+ * List conversation summaries matching `params`. `await` the result for
112
+ * the first page, or `for await` it to stream every summary across
113
+ * pages (fetched lazily — `limit` sets the page size, `next` the
114
+ * starting cursor; stop early to stop fetching).
115
+ */
116
+ list(params?: ConversationListParams): Paginator<ConversationSummary> {
117
+ return cursorPaginate(
118
+ (next) =>
119
+ this.http.request<Paginated<ConversationSummary>>({
120
+ method: "GET",
121
+ path: "/v1/conversations",
122
+ query: { ...params, next } as Record<string, unknown>,
123
+ }),
124
+ params?.next,
125
+ );
126
+ }
127
+
128
+ /**
129
+ * Responses-API-style retrieve: load the state of a conversation as of
130
+ * one item — the full input history, output, system instructions, and
131
+ * tool definitions of that turn.
132
+ *
133
+ * When `itemId` is omitted, the latest LLM turn is used: the first
134
+ * item (in descending order) whose `node_type` is `"assistant"` or
135
+ * whose `operation_name` is `"chat"`, falling back to the first item
136
+ * with a non-null `output_message`. Returns `null` when the
137
+ * conversation has no items.
138
+ *
139
+ * For the full per-turn transcript instead, iterate
140
+ * `items.list(conversationId, { order: "asc" })`.
141
+ */
142
+ async retrieve(
143
+ conversationId: string,
144
+ itemId?: string,
145
+ ): Promise<ConversationResponse | null> {
146
+ const targetId = itemId ?? (await this.findLatestTurnId(conversationId));
147
+ if (targetId === null) return null;
148
+
149
+ const detail = await this.items.get(conversationId, targetId, {
150
+ include: RESPONSE_INCLUDES,
151
+ });
152
+ const outputMessages =
153
+ detail.gen_ai_output_messages ??
154
+ (detail.output_message ? [detail.output_message] : []);
155
+ return {
156
+ conversation_id: conversationId,
157
+ response_id: detail.response_id ?? null,
158
+ item_id: detail.id,
159
+ created_at: detail.created_at,
160
+ model:
161
+ detail.model_name ??
162
+ detail.response_model ??
163
+ detail.request_model ??
164
+ null,
165
+ provider_name: detail.provider_name ?? null,
166
+ // The single-item route returns the FULL input history here.
167
+ input_messages: normalizeMessages(detail.input_messages),
168
+ output_messages: normalizeMessages(outputMessages),
169
+ system_instructions: detail.system_instructions ?? null,
170
+ tool_definitions: detail.tool_definitions ?? null,
171
+ };
172
+ }
173
+
174
+ /** Scan items in descending order for the most recent LLM turn. */
175
+ private async findLatestTurnId(
176
+ conversationId: string,
177
+ ): Promise<string | null> {
178
+ let fallback: ConversationItem | null = null;
179
+ for await (const item of this.items.list(conversationId, {
180
+ order: "desc",
181
+ })) {
182
+ if (item.node_type === "assistant" || item.operation_name === "chat") {
183
+ return item.id;
184
+ }
185
+ if (fallback === null && item.output_message != null) fallback = item;
186
+ }
187
+ return fallback?.id ?? null;
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Defensive normalization for {@link ConversationsClient.retrieve} only:
193
+ * older DP deployments emitted `tool_call_response` parts with a legacy
194
+ * `result` key instead of the semconv `response` key. Map it across so
195
+ * replayed history is always semconv-shaped.
196
+ */
197
+ function normalizeMessages<T extends { parts: MessagePart[] }>(
198
+ messages: T[],
199
+ ): T[] {
200
+ return messages.map((message) => ({
201
+ ...message,
202
+ parts: message.parts.map(normalizePart),
203
+ }));
204
+ }
205
+
206
+ function normalizePart(part: MessagePart): MessagePart {
207
+ if (part.type !== "tool_call_response") return part;
208
+ const legacy = part as ToolCallResponsePart & { result?: unknown };
209
+ if (legacy.response !== undefined || legacy.result === undefined) {
210
+ return part;
211
+ }
212
+ const { result, ...rest } = legacy;
213
+ return { ...rest, response: result };
214
+ }
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Cookie-authenticated Files client for the browser (`/v1/files`).
3
+ *
4
+ * Mirrors the Node SDK's runner-bound `FilesApi`, but rides the DP
5
+ * `intro_dp_session` cookie via {@link BrowserHttpClient} instead of a
6
+ * bearer token — so a single-page app reads and writes files with the
7
+ * same identity session it uses for tasks and conversations. The DP
8
+ * derives the owning `identity_key` from the session JWT; per-identity
9
+ * file ownership and access are enforced server-side.
10
+ */
11
+
12
+ import type {
13
+ File as FileResource,
14
+ FileCreateTextParams,
15
+ FileListParams,
16
+ FileType,
17
+ FileUpdateParams,
18
+ ListParams,
19
+ Paginated,
20
+ } from "@introspection-sdk/types";
21
+ import { Paginator, cursorPaginate } from "@introspection-sdk/http";
22
+ import { BrowserHttpClient } from "./http.js";
23
+
24
+ export type FileUploadBody =
25
+ | { file: Blob; name?: string; file_type?: FileType }
26
+ | {
27
+ file: Uint8Array;
28
+ name: string;
29
+ file_type?: FileType;
30
+ contentType?: string;
31
+ };
32
+
33
+ /** Versions of a file (`/v1/files/{id}/versions`). */
34
+ export class FileVersionsClient {
35
+ constructor(private readonly http: BrowserHttpClient) {}
36
+
37
+ /**
38
+ * List versions of a file. `await` the result for the first page, or
39
+ * `for await` it to stream every version across pages (fetched lazily;
40
+ * stop early to stop fetching).
41
+ */
42
+ list(fileId: string, params?: ListParams): Paginator<FileResource> {
43
+ return cursorPaginate(
44
+ (next) =>
45
+ this.http.request<Paginated<FileResource>>({
46
+ method: "GET",
47
+ path: `/v1/files/${encodeURIComponent(fileId)}/versions`,
48
+ query: { ...params, next } as Record<string, unknown>,
49
+ }),
50
+ params?.next,
51
+ );
52
+ }
53
+
54
+ get(fileId: string, versionId: string): Promise<FileResource> {
55
+ return this.http.request<FileResource>({
56
+ method: "GET",
57
+ path: `/v1/files/${encodeURIComponent(fileId)}/versions/${encodeURIComponent(versionId)}`,
58
+ });
59
+ }
60
+
61
+ create(fileId: string, body: FileUploadBody): Promise<FileResource> {
62
+ const form = toFormData(body);
63
+ return this.http.request<FileResource>({
64
+ method: "POST",
65
+ path: `/v1/files/${encodeURIComponent(fileId)}/versions`,
66
+ body: form,
67
+ });
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Cookie-authenticated `/v1/files` client. Mirrors the Node SDK's
73
+ * `FilesApi` shape but is bound to a DP session cookie rather than a
74
+ * bearer token.
75
+ */
76
+ export class FilesClient {
77
+ readonly versions: FileVersionsClient;
78
+
79
+ constructor(private readonly http: BrowserHttpClient) {
80
+ this.versions = new FileVersionsClient(http);
81
+ }
82
+
83
+ /**
84
+ * List files matching `params`. `await` the result for the first page,
85
+ * or `for await` it to stream every file across pages (fetched lazily —
86
+ * `limit` sets the page size, `next` the starting cursor; stop early to
87
+ * stop fetching).
88
+ */
89
+ list(params?: FileListParams): Paginator<FileResource> {
90
+ return cursorPaginate(
91
+ (next) =>
92
+ this.http.request<Paginated<FileResource>>({
93
+ method: "GET",
94
+ path: "/v1/files",
95
+ query: { ...params, next } as Record<string, unknown>,
96
+ }),
97
+ params?.next,
98
+ );
99
+ }
100
+
101
+ upload(body: FileUploadBody): Promise<FileResource> {
102
+ const form = toFormData(body);
103
+ return this.http.request<FileResource>({
104
+ method: "POST",
105
+ path: "/v1/files",
106
+ body: form,
107
+ });
108
+ }
109
+
110
+ createText(body: FileCreateTextParams): Promise<FileResource> {
111
+ return this.http.request<FileResource>({
112
+ method: "POST",
113
+ path: "/v1/files",
114
+ body,
115
+ });
116
+ }
117
+
118
+ get(fileId: string): Promise<FileResource> {
119
+ return this.http.request<FileResource>({
120
+ method: "GET",
121
+ path: `/v1/files/${encodeURIComponent(fileId)}`,
122
+ });
123
+ }
124
+
125
+ update(fileId: string, body: FileUpdateParams): Promise<FileResource> {
126
+ return this.http.request<FileResource>({
127
+ method: "PATCH",
128
+ path: `/v1/files/${encodeURIComponent(fileId)}`,
129
+ body,
130
+ });
131
+ }
132
+
133
+ delete(fileId: string): Promise<void> {
134
+ return this.http.request<void>({
135
+ method: "DELETE",
136
+ path: `/v1/files/${encodeURIComponent(fileId)}`,
137
+ expect: "empty",
138
+ });
139
+ }
140
+
141
+ download(fileId: string): Promise<Uint8Array> {
142
+ return this.http.request<Uint8Array>({
143
+ method: "GET",
144
+ path: `/v1/files/${encodeURIComponent(fileId)}/content`,
145
+ expect: "bytes",
146
+ });
147
+ }
148
+
149
+ downloadStream(fileId: string): Promise<ReadableStream<Uint8Array>> {
150
+ return this.http.request<ReadableStream<Uint8Array>>({
151
+ method: "GET",
152
+ path: `/v1/files/${encodeURIComponent(fileId)}/content`,
153
+ expect: "stream",
154
+ });
155
+ }
156
+ }
157
+
158
+ function toFormData(body: FileUploadBody): FormData {
159
+ const fd = new FormData();
160
+ if ("file" in body && body.file instanceof Blob) {
161
+ fd.append("file", body.file, body.name);
162
+ } else {
163
+ // Uint8Array branch — copy into a fresh ArrayBuffer so the Blob
164
+ // constructor sees a concrete ArrayBuffer (not ArrayBufferLike,
165
+ // which TS rejects under nodenext lib).
166
+ const u8 = (body as { file: Uint8Array }).file;
167
+ const ct =
168
+ (body as { contentType?: string }).contentType ??
169
+ "application/octet-stream";
170
+ const ab = u8.buffer.slice(
171
+ u8.byteOffset,
172
+ u8.byteOffset + u8.byteLength,
173
+ ) as ArrayBuffer;
174
+ fd.append("file", new Blob([ab], { type: ct }), body.name);
175
+ }
176
+ if (body.name) fd.append("name", body.name);
177
+ if (body.file_type) fd.append("file_type", body.file_type);
178
+ return fd;
179
+ }