@introspection-sdk/introspection-browser 0.5.4 → 0.5.6
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/.turbo/turbo-build.log +1 -1
- package/README.md +34 -29
- package/dist/api/client.d.ts +25 -17
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +39 -22
- package/dist/api/client.js.map +1 -1
- package/dist/api/index.d.ts +17 -11
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +17 -11
- package/dist/api/index.js.map +1 -1
- package/dist/api/tasks.d.ts +8 -47
- package/dist/api/tasks.d.ts.map +1 -1
- package/dist/api/tasks.js +7 -130
- package/dist/api/tasks.js.map +1 -1
- package/package.json +3 -3
- package/src/api/client.ts +59 -24
- package/src/api/index.ts +21 -14
- package/src/api/tasks.ts +18 -158
- package/dist/api/conversations.d.ts +0 -84
- package/dist/api/conversations.d.ts.map +0 -1
- package/dist/api/conversations.js +0 -172
- package/dist/api/conversations.js.map +0 -1
- package/dist/api/files.d.ts +0 -61
- package/dist/api/files.d.ts.map +0 -1
- package/dist/api/files.js +0 -141
- package/dist/api/files.js.map +0 -1
- package/dist/api/shares.d.ts +0 -29
- package/dist/api/shares.d.ts.map +0 -1
- package/dist/api/shares.js +0 -52
- package/dist/api/shares.js.map +0 -1
- package/src/api/conversations.ts +0 -214
- package/src/api/files.ts +0 -179
- package/src/api/shares.ts +0 -65
package/dist/api/tasks.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { parseSse } from "./sse.js";
|
|
1
|
+
import { RunHandle, TaskRunsClient, TasksClient as SharedTasksClient, } from "@introspection-sdk/http";
|
|
3
2
|
function toTaskBody(params) {
|
|
4
3
|
const { identity, metadata, ...rest } = params;
|
|
5
4
|
const body = { ...rest };
|
|
@@ -10,137 +9,15 @@ function toTaskBody(params) {
|
|
|
10
9
|
body.metadata = mergedMetadata;
|
|
11
10
|
return body;
|
|
12
11
|
}
|
|
13
|
-
/** Live handle on a task's run: stream its events, collect text, cancel. */
|
|
14
|
-
export class RunHandle {
|
|
15
|
-
task;
|
|
16
|
-
run;
|
|
17
|
-
runs;
|
|
18
|
-
constructor(task, run, runs) {
|
|
19
|
-
this.task = task;
|
|
20
|
-
this.run = run;
|
|
21
|
-
this.runs = runs;
|
|
22
|
-
}
|
|
23
|
-
stream() {
|
|
24
|
-
return this.runs.stream(this.run.task_id, this.run.id);
|
|
25
|
-
}
|
|
26
|
-
cancel() {
|
|
27
|
-
return this.runs.cancel(this.run.task_id, this.run.id);
|
|
28
|
-
}
|
|
29
|
-
/** Convenience: concatenate `data` from `text`/`message` SSE frames. */
|
|
30
|
-
async text() {
|
|
31
|
-
let out = "";
|
|
32
|
-
for await (const ev of this.stream()) {
|
|
33
|
-
if (ev.event === "text" || ev.event === "message")
|
|
34
|
-
out += ev.data;
|
|
35
|
-
}
|
|
36
|
-
return out;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
export class TaskRunsClient {
|
|
40
|
-
http;
|
|
41
|
-
constructor(http) {
|
|
42
|
-
this.http = http;
|
|
43
|
-
}
|
|
44
|
-
async create(taskId, body) {
|
|
45
|
-
const res = await this.http.request({
|
|
46
|
-
method: "POST",
|
|
47
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}/runs`,
|
|
48
|
-
body,
|
|
49
|
-
});
|
|
50
|
-
return new RunHandle(null, res.run, this);
|
|
51
|
-
}
|
|
52
|
-
get(taskId, runId) {
|
|
53
|
-
return this.http.request({
|
|
54
|
-
method: "GET",
|
|
55
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}/runs/${encodeURIComponent(runId)}`,
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
cancel(taskId, runId) {
|
|
59
|
-
return this.http.request({
|
|
60
|
-
method: "POST",
|
|
61
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}/runs/${encodeURIComponent(runId)}/cancel`,
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
async *stream(taskId, runId) {
|
|
65
|
-
const res = await this.http.stream({
|
|
66
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}/runs/${encodeURIComponent(runId)}/stream`,
|
|
67
|
-
});
|
|
68
|
-
yield* parseSse(res);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
12
|
/**
|
|
72
|
-
* Cookie-authenticated `/v1/tasks` client.
|
|
73
|
-
*
|
|
74
|
-
*
|
|
13
|
+
* Cookie-authenticated `/v1/tasks` client. The implementation is shared with
|
|
14
|
+
* Node's runner-bound task client; this browser subclass only adds the
|
|
15
|
+
* `identity -> metadata.identity` body mapping used by cookie-session calls.
|
|
75
16
|
*/
|
|
76
|
-
export class TasksClient {
|
|
77
|
-
http;
|
|
78
|
-
runs;
|
|
17
|
+
export class TasksClient extends SharedTasksClient {
|
|
79
18
|
constructor(http) {
|
|
80
|
-
|
|
81
|
-
this.runs = new TaskRunsClient(http);
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Tasks matching `params`. `await` it for the first page (preserving
|
|
85
|
-
* the wire envelope's counts + `next` cursor), or `for await` it to
|
|
86
|
-
* stream every task across pages (fetched lazily — `limit` sets the
|
|
87
|
-
* page size, `next` the starting cursor; stop early to stop fetching).
|
|
88
|
-
*
|
|
89
|
-
* Mirrors the Node SDK's `TasksApi.list`, which is the source of truth
|
|
90
|
-
* for the `/v1/tasks` shape.
|
|
91
|
-
*/
|
|
92
|
-
list(params) {
|
|
93
|
-
return cursorPaginate((next) => this.http.request({
|
|
94
|
-
method: "GET",
|
|
95
|
-
path: "/v1/tasks",
|
|
96
|
-
query: { ...params, next },
|
|
97
|
-
}), params?.next);
|
|
98
|
-
}
|
|
99
|
-
create(body) {
|
|
100
|
-
return this.http.request({
|
|
101
|
-
method: "POST",
|
|
102
|
-
path: "/v1/tasks",
|
|
103
|
-
body: toTaskBody(body),
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
get(taskId) {
|
|
107
|
-
return this.http.request({
|
|
108
|
-
method: "GET",
|
|
109
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}`,
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
update(taskId, body) {
|
|
113
|
-
return this.http.request({
|
|
114
|
-
method: "PATCH",
|
|
115
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}`,
|
|
116
|
-
body,
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
delete(taskId) {
|
|
120
|
-
return this.http.request({
|
|
121
|
-
method: "DELETE",
|
|
122
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}`,
|
|
123
|
-
expect: "empty",
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
archive(taskId) {
|
|
127
|
-
return this.http.request({
|
|
128
|
-
method: "POST",
|
|
129
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}/archive`,
|
|
130
|
-
expect: "empty",
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
unarchive(taskId) {
|
|
134
|
-
return this.http.request({
|
|
135
|
-
method: "POST",
|
|
136
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}/unarchive`,
|
|
137
|
-
expect: "empty",
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
/** Sugar: create a task + return a handle on its initial run. */
|
|
141
|
-
async start(params) {
|
|
142
|
-
const res = await this.create(params);
|
|
143
|
-
return new RunHandle(res.task, res.run, this.runs);
|
|
19
|
+
super(http, toTaskBody);
|
|
144
20
|
}
|
|
145
21
|
}
|
|
22
|
+
export { RunHandle, TaskRunsClient };
|
|
146
23
|
//# sourceMappingURL=tasks.js.map
|
package/dist/api/tasks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/api/tasks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/api/tasks.ts"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EACT,cAAc,EACd,WAAW,IAAI,iBAAiB,GAEjC,MAAM,yBAAyB,CAAC;AA0CjC,SAAS,UAAU,CAAC,MAAwB;IAC1C,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;IAC/C,MAAM,IAAI,GAA4B,EAAE,GAAG,IAAI,EAAE,CAAC;IAClD,MAAM,cAAc,GAAG,QAAQ;QAC7B,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE;QACnC,CAAC,CAAC,QAAQ,CAAC;IACb,IAAI,cAAc,KAAK,SAAS;QAAE,IAAI,CAAC,QAAQ,GAAG,cAAc,CAAC;IACjE,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,WAAY,SAAQ,iBAGhC;IACC,YAAY,IAAwB;QAClC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC1B,CAAC;CACF;AAED,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@introspection-sdk/introspection-browser",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.6",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Introspection observability SDK for the browser",
|
|
6
6
|
"engines": {
|
|
@@ -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/
|
|
35
|
-
"@introspection-sdk/
|
|
34
|
+
"@introspection-sdk/types": "0.5.6",
|
|
35
|
+
"@introspection-sdk/http": "0.5.6"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"lint": "eslint . --max-warnings 0",
|
package/src/api/client.ts
CHANGED
|
@@ -2,17 +2,22 @@
|
|
|
2
2
|
* Browser-side Introspection API client.
|
|
3
3
|
*
|
|
4
4
|
* Lets a single-page app create and stream Introspection tasks directly
|
|
5
|
-
* from the browser, with no API key in JavaScript. The
|
|
5
|
+
* from the browser, with no API key in JavaScript. The browser talks only
|
|
6
|
+
* to the Data Plane — runtime resolution and any other Control Plane work
|
|
7
|
+
* stays on the app's backend, so the CP never needs to serve CORS to
|
|
8
|
+
* customer web origins. The auth boundary:
|
|
6
9
|
*
|
|
7
|
-
* 1. The SPA's own backend ("broker") mints
|
|
8
|
-
* token — via RFC 8693 token-exchange of the partner IdP
|
|
9
|
-
* PKCE `authorization_code`, or `client_credentials
|
|
10
|
-
* secret never leaves the backend
|
|
11
|
-
*
|
|
10
|
+
* 1. The SPA's own backend ("broker") mints a short-lived Introspection
|
|
11
|
+
* access token — via RFC 8693 token-exchange of the partner IdP
|
|
12
|
+
* token, a PKCE `authorization_code`, or `client_credentials` (the
|
|
13
|
+
* IdP secret never leaves the backend) — and, when a specific runtime
|
|
14
|
+
* is needed, resolves its `runtime_id` server-side. The SPA fetches
|
|
15
|
+
* the token through the `getToken` callback.
|
|
12
16
|
* 2. `connect()` redeems the token at the DP `POST /v1/oauth/exchange`
|
|
13
17
|
* for the HttpOnly `intro_dp_session` cookie.
|
|
14
18
|
* 3. Every subsequent call rides that cookie (`credentials: "include"`)
|
|
15
|
-
* — `client.tasks.start(
|
|
19
|
+
* — `client.tasks.start({ runtime_id })`, `.get(...)`, run streaming,
|
|
20
|
+
* etc.
|
|
16
21
|
*
|
|
17
22
|
* When the session cookie expires, an in-flight request gets a 401, and
|
|
18
23
|
* the client transparently re-runs `getToken` + the DP exchange once
|
|
@@ -20,13 +25,26 @@
|
|
|
20
25
|
*/
|
|
21
26
|
|
|
22
27
|
import { BrowserHttpClient, stripTrailingSlash, toApiError } from "./http.js";
|
|
28
|
+
import {
|
|
29
|
+
ConversationsClient,
|
|
30
|
+
FilesClient,
|
|
31
|
+
SharesClient,
|
|
32
|
+
} from "@introspection-sdk/http";
|
|
23
33
|
import { TasksClient } from "./tasks.js";
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
|
|
35
|
+
type CookieClients = {
|
|
36
|
+
tasks: TasksClient;
|
|
37
|
+
files: FilesClient;
|
|
38
|
+
conversations: ConversationsClient;
|
|
39
|
+
shares: SharesClient;
|
|
40
|
+
};
|
|
27
41
|
|
|
28
42
|
export interface IntrospectionApiClientOptions {
|
|
29
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Data Plane REST base URL for the cookie-session APIs (`connect()` and
|
|
45
|
+
* `client.tasks` / `client.files` / `client.conversations` /
|
|
46
|
+
* `client.shares`). Required — the browser only talks to the DP.
|
|
47
|
+
*/
|
|
30
48
|
dpUrl: string;
|
|
31
49
|
/**
|
|
32
50
|
* Returns a fresh Introspection access token from the app's broker
|
|
@@ -43,16 +61,8 @@ export interface IntrospectionApiClientOptions {
|
|
|
43
61
|
}
|
|
44
62
|
|
|
45
63
|
export class IntrospectionApiClient {
|
|
46
|
-
/** `/v1/tasks` operations bound to the DP session cookie. */
|
|
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;
|
|
54
|
-
|
|
55
64
|
private readonly fetchImpl: typeof fetch;
|
|
65
|
+
private readonly cookieClients: CookieClients;
|
|
56
66
|
|
|
57
67
|
constructor(private readonly opts: IntrospectionApiClientOptions) {
|
|
58
68
|
this.fetchImpl = opts.fetch ?? globalThis.fetch;
|
|
@@ -61,16 +71,41 @@ export class IntrospectionApiClient {
|
|
|
61
71
|
"global fetch is unavailable; pass `fetch` or run in a modern browser",
|
|
62
72
|
);
|
|
63
73
|
}
|
|
74
|
+
if (!opts.dpUrl) {
|
|
75
|
+
throw new Error("IntrospectionApiClient requires a dpUrl");
|
|
76
|
+
}
|
|
64
77
|
const http = new BrowserHttpClient({
|
|
65
78
|
apiUrl: opts.dpUrl,
|
|
66
79
|
additionalHeaders: opts.additionalHeaders,
|
|
67
80
|
fetch: opts.fetch,
|
|
68
81
|
onUnauthorized: () => this.reexchange(),
|
|
69
82
|
});
|
|
70
|
-
this.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
83
|
+
this.cookieClients = {
|
|
84
|
+
tasks: new TasksClient(http),
|
|
85
|
+
files: new FilesClient(http),
|
|
86
|
+
conversations: new ConversationsClient(http),
|
|
87
|
+
shares: new SharesClient(http),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** `/v1/tasks` operations bound to the DP session cookie. */
|
|
92
|
+
get tasks(): TasksClient {
|
|
93
|
+
return this.cookieClients.tasks;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** `/v1/files` operations bound to the DP session cookie. */
|
|
97
|
+
get files(): FilesClient {
|
|
98
|
+
return this.cookieClients.files;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Read-only `/v1/conversations` projection bound to the session cookie. */
|
|
102
|
+
get conversations(): ConversationsClient {
|
|
103
|
+
return this.cookieClients.conversations;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** `/v1/shares` read-sharing grants bound to the session cookie. */
|
|
107
|
+
get shares(): SharesClient {
|
|
108
|
+
return this.cookieClients.shares;
|
|
74
109
|
}
|
|
75
110
|
|
|
76
111
|
/**
|
package/src/api/index.ts
CHANGED
|
@@ -6,22 +6,30 @@
|
|
|
6
6
|
* Separate from the package's default telemetry export so apps only pull
|
|
7
7
|
* in what they use.
|
|
8
8
|
*
|
|
9
|
+
* The browser talks only to the Data Plane. Resolving a runtime by name
|
|
10
|
+
* (a Control Plane call) stays on your backend, which hands the browser a
|
|
11
|
+
* short-lived access token plus the resolved `runtime_id`.
|
|
12
|
+
*
|
|
9
13
|
* @example
|
|
10
14
|
* ```typescript
|
|
11
15
|
* import { IntrospectionApiClient } from "@introspection-sdk/introspection-browser/api";
|
|
12
16
|
*
|
|
17
|
+
* // Your backend returns { token, runtimeId, dpUrl } — it mints the access
|
|
18
|
+
* // token, resolves the runtime id, and surfaces the DP URL (e.g. from the
|
|
19
|
+
* // Node SDK's serviceAccountToken response), so the browser never calls the CP.
|
|
20
|
+
* const { token, runtimeId, dpUrl } = await fetch(
|
|
21
|
+
* "/api/introspection/session",
|
|
22
|
+
* ).then((r) => r.json());
|
|
23
|
+
*
|
|
13
24
|
* const client = new IntrospectionApiClient({
|
|
14
|
-
* dpUrl
|
|
15
|
-
*
|
|
16
|
-
* // project is derived from its claims — no projectId option needed)
|
|
17
|
-
* getToken: () => fetch("/api/introspection/token").then((r) => r.text()),
|
|
25
|
+
* dpUrl,
|
|
26
|
+
* getToken: () => token,
|
|
18
27
|
* });
|
|
19
28
|
*
|
|
20
|
-
* await client.connect(); //
|
|
29
|
+
* await client.connect(); // -> intro_dp_session cookie
|
|
21
30
|
* const run = await client.tasks.start({
|
|
22
31
|
* prompt: "Summarize my latest order",
|
|
23
|
-
*
|
|
24
|
-
* identity: { user_id: "u_42" },
|
|
32
|
+
* runtime_id: runtimeId,
|
|
25
33
|
* });
|
|
26
34
|
* for await (const ev of run.stream()) console.log(ev.event, ev.data);
|
|
27
35
|
* ```
|
|
@@ -39,15 +47,13 @@ export {
|
|
|
39
47
|
type StartTaskParams,
|
|
40
48
|
} from "./tasks.js";
|
|
41
49
|
export {
|
|
42
|
-
|
|
50
|
+
ConversationItemsClient,
|
|
51
|
+
ConversationsClient,
|
|
43
52
|
FileVersionsClient,
|
|
53
|
+
FilesClient,
|
|
54
|
+
SharesClient,
|
|
44
55
|
type FileUploadBody,
|
|
45
|
-
} from "
|
|
46
|
-
export {
|
|
47
|
-
ConversationsClient,
|
|
48
|
-
ConversationItemsClient,
|
|
49
|
-
} from "./conversations.js";
|
|
50
|
-
export { SharesClient } from "./shares.js";
|
|
56
|
+
} from "@introspection-sdk/http";
|
|
51
57
|
export { BrowserHttpClient, type BrowserHttpConfig } from "./http.js";
|
|
52
58
|
export { parseSse } from "./sse.js";
|
|
53
59
|
export {
|
|
@@ -93,4 +99,5 @@ export {
|
|
|
93
99
|
InsufficientScopeError,
|
|
94
100
|
NotFoundError,
|
|
95
101
|
NetworkError,
|
|
102
|
+
RunnerExpiredError,
|
|
96
103
|
} from "@introspection-sdk/types";
|
package/src/api/tasks.ts
CHANGED
|
@@ -1,19 +1,10 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
TaskListParams,
|
|
9
|
-
TaskRun,
|
|
10
|
-
TaskRunCreateParams,
|
|
11
|
-
TaskRunResponse,
|
|
12
|
-
TaskUpdateParams,
|
|
13
|
-
} from "@introspection-sdk/types";
|
|
14
|
-
import { Paginator, cursorPaginate } from "@introspection-sdk/http";
|
|
15
|
-
import { BrowserHttpClient } from "./http.js";
|
|
16
|
-
import { parseSse } from "./sse.js";
|
|
1
|
+
import type { RunIdentityInput } from "@introspection-sdk/types";
|
|
2
|
+
import {
|
|
3
|
+
RunHandle,
|
|
4
|
+
TaskRunsClient,
|
|
5
|
+
TasksClient as SharedTasksClient,
|
|
6
|
+
type ResourceHttpClient,
|
|
7
|
+
} from "@introspection-sdk/http";
|
|
17
8
|
|
|
18
9
|
/**
|
|
19
10
|
* Body for creating a task directly against the DP from the browser.
|
|
@@ -65,149 +56,18 @@ function toTaskBody(params: CreateTaskParams): Record<string, unknown> {
|
|
|
65
56
|
return body;
|
|
66
57
|
}
|
|
67
58
|
|
|
68
|
-
/** Live handle on a task's run: stream its events, collect text, cancel. */
|
|
69
|
-
export class RunHandle {
|
|
70
|
-
constructor(
|
|
71
|
-
public readonly task: Task | null,
|
|
72
|
-
public readonly run: TaskRun,
|
|
73
|
-
private readonly runs: TaskRunsClient,
|
|
74
|
-
) {}
|
|
75
|
-
|
|
76
|
-
stream(): AsyncIterable<SseEvent> {
|
|
77
|
-
return this.runs.stream(this.run.task_id, this.run.id);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
cancel(): Promise<TaskCancelResponse> {
|
|
81
|
-
return this.runs.cancel(this.run.task_id, this.run.id);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/** Convenience: concatenate `data` from `text`/`message` SSE frames. */
|
|
85
|
-
async text(): Promise<string> {
|
|
86
|
-
let out = "";
|
|
87
|
-
for await (const ev of this.stream()) {
|
|
88
|
-
if (ev.event === "text" || ev.event === "message") out += ev.data;
|
|
89
|
-
}
|
|
90
|
-
return out;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export class TaskRunsClient {
|
|
95
|
-
constructor(private readonly http: BrowserHttpClient) {}
|
|
96
|
-
|
|
97
|
-
async create(taskId: string, body: TaskRunCreateParams): Promise<RunHandle> {
|
|
98
|
-
const res = await this.http.request<TaskRunResponse>({
|
|
99
|
-
method: "POST",
|
|
100
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}/runs`,
|
|
101
|
-
body,
|
|
102
|
-
});
|
|
103
|
-
return new RunHandle(null, res.run, this);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
get(taskId: string, runId: string): Promise<TaskRun> {
|
|
107
|
-
return this.http.request<TaskRun>({
|
|
108
|
-
method: "GET",
|
|
109
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}/runs/${encodeURIComponent(runId)}`,
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
cancel(taskId: string, runId: string): Promise<TaskCancelResponse> {
|
|
114
|
-
return this.http.request<TaskCancelResponse>({
|
|
115
|
-
method: "POST",
|
|
116
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}/runs/${encodeURIComponent(runId)}/cancel`,
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async *stream(taskId: string, runId: string): AsyncIterable<SseEvent> {
|
|
121
|
-
const res = await this.http.stream({
|
|
122
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}/runs/${encodeURIComponent(runId)}/stream`,
|
|
123
|
-
});
|
|
124
|
-
yield* parseSse(res);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
59
|
/**
|
|
129
|
-
* Cookie-authenticated `/v1/tasks` client.
|
|
130
|
-
*
|
|
131
|
-
*
|
|
60
|
+
* Cookie-authenticated `/v1/tasks` client. The implementation is shared with
|
|
61
|
+
* Node's runner-bound task client; this browser subclass only adds the
|
|
62
|
+
* `identity -> metadata.identity` body mapping used by cookie-session calls.
|
|
132
63
|
*/
|
|
133
|
-
export class TasksClient
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Tasks matching `params`. `await` it for the first page (preserving
|
|
142
|
-
* the wire envelope's counts + `next` cursor), or `for await` it to
|
|
143
|
-
* stream every task across pages (fetched lazily — `limit` sets the
|
|
144
|
-
* page size, `next` the starting cursor; stop early to stop fetching).
|
|
145
|
-
*
|
|
146
|
-
* Mirrors the Node SDK's `TasksApi.list`, which is the source of truth
|
|
147
|
-
* for the `/v1/tasks` shape.
|
|
148
|
-
*/
|
|
149
|
-
list(params?: TaskListParams): Paginator<Task> {
|
|
150
|
-
return cursorPaginate(
|
|
151
|
-
(next) =>
|
|
152
|
-
this.http.request<Paginated<Task>>({
|
|
153
|
-
method: "GET",
|
|
154
|
-
path: "/v1/tasks",
|
|
155
|
-
query: { ...params, next } as Record<string, unknown>,
|
|
156
|
-
}),
|
|
157
|
-
params?.next,
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
create(body: CreateTaskParams): Promise<TaskCreateResponse> {
|
|
162
|
-
return this.http.request<TaskCreateResponse>({
|
|
163
|
-
method: "POST",
|
|
164
|
-
path: "/v1/tasks",
|
|
165
|
-
body: toTaskBody(body),
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
get(taskId: string): Promise<Task> {
|
|
170
|
-
return this.http.request<Task>({
|
|
171
|
-
method: "GET",
|
|
172
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}`,
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
update(taskId: string, body: TaskUpdateParams): Promise<Task> {
|
|
177
|
-
return this.http.request<Task>({
|
|
178
|
-
method: "PATCH",
|
|
179
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}`,
|
|
180
|
-
body,
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
delete(taskId: string): Promise<void> {
|
|
185
|
-
return this.http.request<void>({
|
|
186
|
-
method: "DELETE",
|
|
187
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}`,
|
|
188
|
-
expect: "empty",
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
archive(taskId: string): Promise<void> {
|
|
193
|
-
return this.http.request<void>({
|
|
194
|
-
method: "POST",
|
|
195
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}/archive`,
|
|
196
|
-
expect: "empty",
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
unarchive(taskId: string): Promise<void> {
|
|
201
|
-
return this.http.request<void>({
|
|
202
|
-
method: "POST",
|
|
203
|
-
path: `/v1/tasks/${encodeURIComponent(taskId)}/unarchive`,
|
|
204
|
-
expect: "empty",
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/** Sugar: create a task + return a handle on its initial run. */
|
|
209
|
-
async start(params: StartTaskParams): Promise<RunHandle> {
|
|
210
|
-
const res = await this.create(params);
|
|
211
|
-
return new RunHandle(res.task, res.run, this.runs);
|
|
64
|
+
export class TasksClient extends SharedTasksClient<
|
|
65
|
+
CreateTaskParams,
|
|
66
|
+
StartTaskParams
|
|
67
|
+
> {
|
|
68
|
+
constructor(http: ResourceHttpClient) {
|
|
69
|
+
super(http, toTaskBody);
|
|
212
70
|
}
|
|
213
71
|
}
|
|
72
|
+
|
|
73
|
+
export { RunHandle, TaskRunsClient };
|
|
@@ -1,84 +0,0 @@
|
|
|
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
|
-
import type { ConversationItem, ConversationItemInclude, ConversationItemList, ConversationItemListParams, ConversationListParams, ConversationResponse, ConversationSummary } from "@introspection-sdk/types";
|
|
13
|
-
import { Paginator } from "@introspection-sdk/http";
|
|
14
|
-
import { BrowserHttpClient } from "./http.js";
|
|
15
|
-
/**
|
|
16
|
-
* Items of a conversation (`/v1/conversations/{id}/items`). Read-only.
|
|
17
|
-
*
|
|
18
|
-
* Paging is OpenAI-style underneath: the envelope has NO `next` token —
|
|
19
|
-
* `list()` drives `after` = the previous page's `last_id` while
|
|
20
|
-
* `has_more` is true.
|
|
21
|
-
*/
|
|
22
|
-
export declare class ConversationItemsClient {
|
|
23
|
-
private readonly http;
|
|
24
|
-
constructor(http: BrowserHttpClient);
|
|
25
|
-
/**
|
|
26
|
-
* List items of a conversation. `await` the result for the first page
|
|
27
|
-
* (an OpenAI-style {@link ConversationItemList} envelope), or
|
|
28
|
-
* `for await` it to stream every item across pages (fetched lazily —
|
|
29
|
-
* `limit` sets the page size, `after` the starting cursor; stop early to
|
|
30
|
-
* stop fetching). Pass `order: "asc"` to walk the transcript from the
|
|
31
|
-
* start.
|
|
32
|
-
*
|
|
33
|
-
* Items carry the turn-local delta in `input_messages` — only the
|
|
34
|
-
* messages new to that turn. Use `get()` for the full input history.
|
|
35
|
-
*/
|
|
36
|
-
list(conversationId: string, params?: ConversationItemListParams): Paginator<ConversationItem, ConversationItemList>;
|
|
37
|
-
/**
|
|
38
|
-
* Fetch a single conversation item. Unlike the list route, the
|
|
39
|
-
* detail's `input_messages` is the FULL input history for that span.
|
|
40
|
-
*/
|
|
41
|
-
get(conversationId: string, itemId: string, params?: {
|
|
42
|
-
include?: ConversationItemInclude[];
|
|
43
|
-
}): Promise<ConversationItem>;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Read-only Conversations client (`/v1/conversations`).
|
|
47
|
-
*
|
|
48
|
-
* Both `list()` and `items.list()` are auto-paging, but they drive
|
|
49
|
-
* different wire protocols underneath: `list()` walks the standard
|
|
50
|
-
* Introspection cursor envelope's opaque `next` token, while
|
|
51
|
-
* `items.list()` walks an OpenAI-style envelope via `after` = the
|
|
52
|
-
* previous page's `last_id` while `has_more` is true.
|
|
53
|
-
*/
|
|
54
|
-
export declare class ConversationsClient {
|
|
55
|
-
private readonly http;
|
|
56
|
-
/** Items of a conversation — `conversations.items.list(...)` etc. */
|
|
57
|
-
readonly items: ConversationItemsClient;
|
|
58
|
-
constructor(http: BrowserHttpClient);
|
|
59
|
-
/**
|
|
60
|
-
* List conversation summaries matching `params`. `await` the result for
|
|
61
|
-
* the first page, or `for await` it to stream every summary across
|
|
62
|
-
* pages (fetched lazily — `limit` sets the page size, `next` the
|
|
63
|
-
* starting cursor; stop early to stop fetching).
|
|
64
|
-
*/
|
|
65
|
-
list(params?: ConversationListParams): Paginator<ConversationSummary>;
|
|
66
|
-
/**
|
|
67
|
-
* Responses-API-style retrieve: load the state of a conversation as of
|
|
68
|
-
* one item — the full input history, output, system instructions, and
|
|
69
|
-
* tool definitions of that turn.
|
|
70
|
-
*
|
|
71
|
-
* When `itemId` is omitted, the latest LLM turn is used: the first
|
|
72
|
-
* item (in descending order) whose `node_type` is `"assistant"` or
|
|
73
|
-
* whose `operation_name` is `"chat"`, falling back to the first item
|
|
74
|
-
* with a non-null `output_message`. Returns `null` when the
|
|
75
|
-
* conversation has no items.
|
|
76
|
-
*
|
|
77
|
-
* For the full per-turn transcript instead, iterate
|
|
78
|
-
* `items.list(conversationId, { order: "asc" })`.
|
|
79
|
-
*/
|
|
80
|
-
retrieve(conversationId: string, itemId?: string): Promise<ConversationResponse | null>;
|
|
81
|
-
/** Scan items in descending order for the most recent LLM turn. */
|
|
82
|
-
private findLatestTurnId;
|
|
83
|
-
}
|
|
84
|
-
//# sourceMappingURL=conversations.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../../src/api/conversations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,EACpB,0BAA0B,EAC1B,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EAIpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,EAAkB,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAS9C;;;;;;GAMG;AACH,qBAAa,uBAAuB;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,iBAAiB;IAEpD;;;;;;;;;;OAUG;IACH,IAAI,CACF,cAAc,EAAE,MAAM,EACtB,MAAM,CAAC,EAAE,0BAA0B,GAClC,SAAS,CAAC,gBAAgB,EAAE,oBAAoB,CAAC;IAiBpD;;;OAGG;IACH,GAAG,CACD,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,uBAAuB,EAAE,CAAA;KAAE,GAC/C,OAAO,CAAC,gBAAgB,CAAC;CAO7B;AAED;;;;;;;;GAQG;AACH,qBAAa,mBAAmB;IAIlB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,qEAAqE;IACrE,QAAQ,CAAC,KAAK,EAAE,uBAAuB,CAAC;gBAEX,IAAI,EAAE,iBAAiB;IAIpD;;;;;OAKG;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,sBAAsB,GAAG,SAAS,CAAC,mBAAmB,CAAC;IAYrE;;;;;;;;;;;;;OAaG;IACG,QAAQ,CACZ,cAAc,EAAE,MAAM,EACtB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IA6BvC,mEAAmE;YACrD,gBAAgB;CAc/B"}
|