@neta-art/cohub 1.3.1 → 1.4.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/dist/apis/spaces.d.ts +4 -1
- package/dist/apis/spaces.js +17 -0
- package/dist/apis/tasks.d.ts +2 -4
- package/dist/apis/user.d.ts +8 -2
- package/dist/apis/user.js +7 -0
- package/dist/session-patch-reducer.d.ts +8 -0
- package/dist/session-patch-reducer.js +133 -22
- package/dist/types.d.ts +81 -1
- package/package.json +1 -1
package/dist/apis/spaces.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { SpacePublicEndpoints } from "@neta-art/cohub-protocol/ports";
|
|
|
2
2
|
import type { WebsocketClient, WebsocketEventPayload } from "../websocket.js";
|
|
3
3
|
import type { HttpTransport, Fetch } from "../transport.js";
|
|
4
4
|
import { type SessionPatchApplyResult } from "../session-patch-reducer.js";
|
|
5
|
-
import type { CheckpointRecord, ContentBlock, SessionMessageResponse, SessionMessagesPaginatedResponse, SessionMessagesResponse, SessionTurnResponse, SessionTurnIndexResponse, SessionTurnWindowResponse, SessionTurnsPaginatedResponse, SessionTurnSignedUrlsResponse, SessionRecord, SpaceAccessPolicy, SpaceBootstrapSource, SpaceChannelBindingInput, SpaceCheckpointDetailResponse, SpaceCreateResponse, SpaceEnvInput, SpaceFsFileResponse, SpaceFsMoveInput, SpaceFsTreeResponse, SpaceFsUploadResponse, SpaceUsageResponse, SpaceFsWriteFileInput, SpaceMarkKind, SpaceMarkListItem, SpaceMarkResourceType, SpaceMember, SpaceRecord, SpaceRole, SpaceSessionsResponse } from "../types.js";
|
|
5
|
+
import type { CheckpointRecord, ContentBlock, SessionMessageResponse, SessionMessagesPaginatedResponse, SessionMessagesResponse, SessionTurnResponse, SessionTurnStreamSnapshotResponse, SessionTurnIndexResponse, SessionTurnWindowResponse, SessionTurnsPaginatedResponse, SessionTurnSignedUrlsResponse, SessionRecord, SpaceAccessPolicy, SpaceBootstrapSource, SpaceChannelBindingInput, SpaceCheckpointDetailResponse, SpaceCreateResponse, SpaceEnvInput, SpaceFsCompleteUploadInput, SpaceFsCompleteUploadResponse, SpaceFsCreateUploadInput, SpaceFsCreateUploadResponse, SpaceFsFileResponse, SpaceFsMoveInput, SpaceFsTreeResponse, SpaceFsUploadResponse, SpaceUsageResponse, SpaceFsWriteFileInput, SpaceMarkKind, SpaceMarkListItem, SpaceMarkResourceType, SpaceMember, SpaceRecord, SpaceRole, SpaceSessionsResponse } from "../types.js";
|
|
6
6
|
import { SpaceInvitationsApi } from "./invitations.js";
|
|
7
7
|
export type SessionSubscriptionHandlers = {
|
|
8
8
|
patch?: (event: WebsocketEventPayload) => void;
|
|
@@ -75,6 +75,8 @@ export declare class SpaceFilesApi {
|
|
|
75
75
|
toPath: string;
|
|
76
76
|
}>;
|
|
77
77
|
upload(files: File[], dir?: string): Promise<SpaceFsUploadResponse>;
|
|
78
|
+
createUpload(input: SpaceFsCreateUploadInput): Promise<SpaceFsCreateUploadResponse>;
|
|
79
|
+
completeUpload(uploadId: string, input: SpaceFsCompleteUploadInput): Promise<SpaceFsCompleteUploadResponse>;
|
|
78
80
|
}
|
|
79
81
|
declare class SessionMessagesClient {
|
|
80
82
|
private readonly transport;
|
|
@@ -117,6 +119,7 @@ declare class SessionTurnsClient {
|
|
|
117
119
|
before?: number;
|
|
118
120
|
after?: number;
|
|
119
121
|
}, customFetch?: Fetch): Promise<SessionTurnWindowResponse>;
|
|
122
|
+
streamSnapshot(customFetch?: Fetch): Promise<SessionTurnStreamSnapshotResponse>;
|
|
120
123
|
get(turnId: string, customFetch?: Fetch): Promise<SessionTurnResponse>;
|
|
121
124
|
signedUrls(turnId: string, objectKeys: string[]): Promise<SessionTurnSignedUrlsResponse>;
|
|
122
125
|
}
|
package/dist/apis/spaces.js
CHANGED
|
@@ -169,6 +169,20 @@ export class SpaceFilesApi {
|
|
|
169
169
|
body: formData,
|
|
170
170
|
});
|
|
171
171
|
}
|
|
172
|
+
createUpload(input) {
|
|
173
|
+
return this.transport.request(`/api/spaces/${this.spaceId}/fs/uploads`, {
|
|
174
|
+
method: "POST",
|
|
175
|
+
headers: { "Content-Type": "application/json" },
|
|
176
|
+
body: JSON.stringify(input),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
completeUpload(uploadId, input) {
|
|
180
|
+
return this.transport.request(`/api/spaces/${this.spaceId}/fs/uploads/${uploadId}/complete`, {
|
|
181
|
+
method: "POST",
|
|
182
|
+
headers: { "Content-Type": "application/json" },
|
|
183
|
+
body: JSON.stringify(input),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
172
186
|
}
|
|
173
187
|
class SessionMessagesClient {
|
|
174
188
|
transport;
|
|
@@ -273,6 +287,9 @@ class SessionTurnsClient {
|
|
|
273
287
|
const query = params.toString();
|
|
274
288
|
return this.transport.request(`/api/sessions/${this.sessionId}/turns/window${query ? `?${query}` : ""}`, { fetch: customFetch });
|
|
275
289
|
}
|
|
290
|
+
streamSnapshot(customFetch) {
|
|
291
|
+
return this.transport.request(`/api/sessions/${this.sessionId}/turns/stream-snapshot`, { fetch: customFetch });
|
|
292
|
+
}
|
|
276
293
|
get(turnId, customFetch) {
|
|
277
294
|
return this.transport.request(`/api/sessions/${this.sessionId}/turns/${turnId}`, { fetch: customFetch });
|
|
278
295
|
}
|
package/dist/apis/tasks.d.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import type { HttpTransport } from "../transport.js";
|
|
2
|
-
import type { CreateScheduledTaskInput, TaskRunRecord } from "../types.js";
|
|
2
|
+
import type { CreateScheduledTaskInput, TaskRunDetailResponse, TaskRunRecord } from "../types.js";
|
|
3
3
|
export declare class TasksApi {
|
|
4
4
|
private readonly transport;
|
|
5
5
|
constructor(transport: HttpTransport);
|
|
6
|
-
get(taskRunId: string): Promise<
|
|
7
|
-
run: TaskRunRecord;
|
|
8
|
-
}>;
|
|
6
|
+
get(taskRunId: string): Promise<TaskRunDetailResponse>;
|
|
9
7
|
list(filters?: {
|
|
10
8
|
cronJobId?: string;
|
|
11
9
|
spaceId?: string;
|
package/dist/apis/user.d.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { type HttpTransport, type Fetch } from "../transport.js";
|
|
2
|
-
import type { UserRulesResponse, UserSshKey } from "../types.js";
|
|
2
|
+
import type { MeResponse, UserProfile, UserRulesResponse, UserSshKey } from "../types.js";
|
|
3
3
|
export declare class UserApi {
|
|
4
4
|
private readonly transport;
|
|
5
5
|
private readonly transportBaseUrl;
|
|
6
6
|
private readonly setStoredAuthToken?;
|
|
7
7
|
private readonly clearStoredAuthToken?;
|
|
8
8
|
constructor(transport: HttpTransport, transportBaseUrl: string, setStoredAuthToken?: ((token: string) => void) | undefined, clearStoredAuthToken?: (() => void) | undefined);
|
|
9
|
-
getMe(customFetch?: Fetch): Promise<
|
|
9
|
+
getMe(customFetch?: Fetch): Promise<MeResponse>;
|
|
10
|
+
updateProfile(input: {
|
|
11
|
+
displayName?: string;
|
|
12
|
+
avatarUrl?: string | null;
|
|
13
|
+
}): Promise<{
|
|
14
|
+
profile: UserProfile;
|
|
15
|
+
}>;
|
|
10
16
|
getRules(customFetch?: Fetch): Promise<UserRulesResponse>;
|
|
11
17
|
setAuthToken(token: string): Promise<any>;
|
|
12
18
|
clearAuthToken(): Promise<null>;
|
package/dist/apis/user.js
CHANGED
|
@@ -13,6 +13,13 @@ export class UserApi {
|
|
|
13
13
|
getMe(customFetch) {
|
|
14
14
|
return this.transport.request("/api/me", { fetch: customFetch });
|
|
15
15
|
}
|
|
16
|
+
updateProfile(input) {
|
|
17
|
+
return this.transport.request("/api/me/profile", {
|
|
18
|
+
method: "PATCH",
|
|
19
|
+
headers: { "Content-Type": "application/json" },
|
|
20
|
+
body: JSON.stringify(input),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
16
23
|
getRules(customFetch) {
|
|
17
24
|
return this.transport.request("/api/me/rules", {
|
|
18
25
|
method: "GET",
|
|
@@ -28,6 +28,13 @@ export type SessionPatchApplyResult = {
|
|
|
28
28
|
reason: "duplicate" | "version_mismatch" | "invalid";
|
|
29
29
|
state: SessionPatchState;
|
|
30
30
|
};
|
|
31
|
+
export type SessionPatchSnapshotInput = SessionPatchKeyInput & {
|
|
32
|
+
turnId?: string | null;
|
|
33
|
+
seq: number;
|
|
34
|
+
contentBlocks: ContentBlock[];
|
|
35
|
+
anchorUserMessageId?: string | null;
|
|
36
|
+
appendPath?: string | null;
|
|
37
|
+
};
|
|
31
38
|
type SessionPatchKeyInput = {
|
|
32
39
|
spaceId?: string | null;
|
|
33
40
|
sessionId: string;
|
|
@@ -44,6 +51,7 @@ export declare class SessionPatchReducer {
|
|
|
44
51
|
complete(input: SessionPatchKeyInput): SessionPatchState;
|
|
45
52
|
fail(input: SessionPatchKeyInput): SessionPatchState;
|
|
46
53
|
reset(input: SessionPatchKeyInput): void;
|
|
54
|
+
applySnapshot(input: SessionPatchSnapshotInput): SessionPatchApplyResult;
|
|
47
55
|
resetAll(): void;
|
|
48
56
|
applyEvent(event: SessionTurnPatchEvent): SessionPatchApplyResult;
|
|
49
57
|
applyPatch(input: SessionPatchApplyInput): SessionPatchApplyResult;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const blockSubPathPattern = /^\/message\/content\/blocks\/(\d+)\/(.+)$/;
|
|
2
2
|
const blockPathPattern = /^\/message\/content\/blocks\/(\d+)$/;
|
|
3
3
|
const blockMetaPathPattern = /^\/message\/content\/blocks\/(\d+)\/_meta$/;
|
|
4
|
-
const blockSignaturePathPattern = /^\/message\/content\/blocks\/(\d+)\/signature$/;
|
|
5
4
|
const createIdleState = (input) => ({
|
|
6
5
|
spaceId: input.spaceId ?? null,
|
|
7
6
|
sessionId: input.sessionId,
|
|
@@ -38,6 +37,14 @@ function sortBlocksByStreamIndex(blocks) {
|
|
|
38
37
|
function isContentBlock(value) {
|
|
39
38
|
return Boolean(value && typeof value === "object" && "type" in value);
|
|
40
39
|
}
|
|
40
|
+
function isPlainObject(value) {
|
|
41
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
42
|
+
}
|
|
43
|
+
function decodePointerSegments(encoded) {
|
|
44
|
+
if (!encoded)
|
|
45
|
+
return [];
|
|
46
|
+
return encoded.split("/").map((s) => s.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
47
|
+
}
|
|
41
48
|
function ensureTextLikeBlock(blocks, streamIndex, field) {
|
|
42
49
|
const existingIndex = findBlockByStreamIndex(blocks, streamIndex);
|
|
43
50
|
const existing = existingIndex >= 0 ? blocks[existingIndex] : undefined;
|
|
@@ -62,21 +69,103 @@ function ensureTextLikeBlock(blocks, streamIndex, field) {
|
|
|
62
69
|
blocks.push(block);
|
|
63
70
|
return block;
|
|
64
71
|
}
|
|
65
|
-
function
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
72
|
+
function getOrCreateBlockForSubpath(blocks, streamIndex, firstSegment) {
|
|
73
|
+
const idx = findBlockByStreamIndex(blocks, streamIndex);
|
|
74
|
+
if (idx >= 0)
|
|
75
|
+
return blocks[idx] ?? null;
|
|
76
|
+
if (firstSegment === "text") {
|
|
77
|
+
return ensureTextLikeBlock(blocks, streamIndex, "text");
|
|
78
|
+
}
|
|
79
|
+
if (firstSegment === "thinking") {
|
|
80
|
+
return ensureTextLikeBlock(blocks, streamIndex, "thinking");
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
function setDeepOnContentBlock(root, segments, value) {
|
|
85
|
+
if (segments.length === 0)
|
|
68
86
|
return false;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
87
|
+
let cur = root;
|
|
88
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
89
|
+
const k = segments[i];
|
|
90
|
+
if (k === undefined)
|
|
91
|
+
return false;
|
|
92
|
+
if (!isPlainObject(cur))
|
|
93
|
+
return false;
|
|
94
|
+
const next = cur[k];
|
|
95
|
+
if (next === undefined)
|
|
96
|
+
return false;
|
|
97
|
+
cur = next;
|
|
74
98
|
}
|
|
75
|
-
|
|
76
|
-
|
|
99
|
+
const last = segments[segments.length - 1];
|
|
100
|
+
if (last === undefined)
|
|
101
|
+
return false;
|
|
102
|
+
if (!isPlainObject(cur))
|
|
103
|
+
return false;
|
|
104
|
+
const toAssign = value !== null && typeof value === "object"
|
|
105
|
+
? structuredClone(value)
|
|
106
|
+
: value;
|
|
107
|
+
cur[last] = toAssign;
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
function appendDeepOnContentBlock(root, segments, suffix) {
|
|
111
|
+
if (segments.length === 0)
|
|
112
|
+
return false;
|
|
113
|
+
let cur = root;
|
|
114
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
115
|
+
const k = segments[i];
|
|
116
|
+
if (k === undefined)
|
|
117
|
+
return false;
|
|
118
|
+
if (!isPlainObject(cur))
|
|
119
|
+
return false;
|
|
120
|
+
const next = cur[k];
|
|
121
|
+
if (next === undefined)
|
|
122
|
+
return false;
|
|
123
|
+
cur = next;
|
|
77
124
|
}
|
|
125
|
+
const last = segments[segments.length - 1];
|
|
126
|
+
if (last === undefined)
|
|
127
|
+
return false;
|
|
128
|
+
if (!isPlainObject(cur))
|
|
129
|
+
return false;
|
|
130
|
+
const parent = cur;
|
|
131
|
+
const leaf = parent[last];
|
|
132
|
+
if (typeof leaf !== "string")
|
|
133
|
+
return false;
|
|
134
|
+
parent[last] = leaf + suffix;
|
|
78
135
|
return true;
|
|
79
136
|
}
|
|
137
|
+
function resolveBlockForSubpath(blocks, streamIndex, firstSegment) {
|
|
138
|
+
const idx = findBlockByStreamIndex(blocks, streamIndex);
|
|
139
|
+
if (idx >= 0)
|
|
140
|
+
return blocks[idx] ?? null;
|
|
141
|
+
return getOrCreateBlockForSubpath(blocks, streamIndex, firstSegment);
|
|
142
|
+
}
|
|
143
|
+
function applyReplaceAtBlockSubpath(blocks, streamIndex, encodedTail, value) {
|
|
144
|
+
const segs = decodePointerSegments(encodedTail);
|
|
145
|
+
if (segs.length === 0)
|
|
146
|
+
return false;
|
|
147
|
+
const block = resolveBlockForSubpath(blocks, streamIndex, segs[0] ?? "");
|
|
148
|
+
if (!block)
|
|
149
|
+
return false;
|
|
150
|
+
return setDeepOnContentBlock(block, segs, value);
|
|
151
|
+
}
|
|
152
|
+
function applyAppendAtBlockSubpath(blocks, streamIndex, encodedTail, suffix) {
|
|
153
|
+
if (typeof suffix !== "string")
|
|
154
|
+
return false;
|
|
155
|
+
const segs = decodePointerSegments(encodedTail);
|
|
156
|
+
if (segs.length === 0)
|
|
157
|
+
return false;
|
|
158
|
+
const block = resolveBlockForSubpath(blocks, streamIndex, segs[0] ?? "");
|
|
159
|
+
if (!block)
|
|
160
|
+
return false;
|
|
161
|
+
return appendDeepOnContentBlock(block, segs, suffix);
|
|
162
|
+
}
|
|
163
|
+
function appendPatchStreamValue(blocks, path, value) {
|
|
164
|
+
const m = path.match(blockSubPathPattern);
|
|
165
|
+
if (!m)
|
|
166
|
+
return false;
|
|
167
|
+
return applyAppendAtBlockSubpath(blocks, Number(m[1]), m[2] ?? "", value);
|
|
168
|
+
}
|
|
80
169
|
function applyPatchOpsToBlocks(current, ops, initialAppendPath) {
|
|
81
170
|
const next = current.map(cloneBlock);
|
|
82
171
|
let anchorUserMessageId;
|
|
@@ -84,7 +173,7 @@ function applyPatchOpsToBlocks(current, ops, initialAppendPath) {
|
|
|
84
173
|
let failed = false;
|
|
85
174
|
for (const op of ops) {
|
|
86
175
|
if (!op.o && !op.p) {
|
|
87
|
-
if (!appendPath || !
|
|
176
|
+
if (!appendPath || !appendPatchStreamValue(next, appendPath, op.v)) {
|
|
88
177
|
failed = true;
|
|
89
178
|
break;
|
|
90
179
|
}
|
|
@@ -98,7 +187,7 @@ function applyPatchOpsToBlocks(current, ops, initialAppendPath) {
|
|
|
98
187
|
continue;
|
|
99
188
|
}
|
|
100
189
|
if (op.o === "append") {
|
|
101
|
-
if (!
|
|
190
|
+
if (typeof op.p !== "string" || !appendPatchStreamValue(next, op.p, op.v)) {
|
|
102
191
|
failed = true;
|
|
103
192
|
break;
|
|
104
193
|
}
|
|
@@ -118,15 +207,15 @@ function applyPatchOpsToBlocks(current, ops, initialAppendPath) {
|
|
|
118
207
|
continue;
|
|
119
208
|
}
|
|
120
209
|
if (op.o === "replace") {
|
|
121
|
-
const
|
|
122
|
-
if (
|
|
123
|
-
|
|
210
|
+
const sub = op.p.match(blockSubPathPattern);
|
|
211
|
+
if (sub?.[2] && typeof op.p === "string") {
|
|
212
|
+
const streamIndex = Number(sub[1]);
|
|
213
|
+
const encodedTail = sub[2];
|
|
214
|
+
if (applyReplaceAtBlockSubpath(next, streamIndex, encodedTail, op.v)) {
|
|
124
215
|
continue;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
block.signature = op.v;
|
|
129
|
-
continue;
|
|
216
|
+
}
|
|
217
|
+
failed = true;
|
|
218
|
+
break;
|
|
130
219
|
}
|
|
131
220
|
}
|
|
132
221
|
if (op.o === "replace" || op.o === "add") {
|
|
@@ -219,6 +308,28 @@ export class SessionPatchReducer {
|
|
|
219
308
|
reset(input) {
|
|
220
309
|
this.states.delete(this.key(input));
|
|
221
310
|
}
|
|
311
|
+
applySnapshot(input) {
|
|
312
|
+
const current = this.get(input);
|
|
313
|
+
const inputTurnId = input.turnId ?? null;
|
|
314
|
+
const currentTurnId = current.turnId;
|
|
315
|
+
const isDifferentKnownTurn = Boolean(currentTurnId && inputTurnId && currentTurnId !== inputTurnId);
|
|
316
|
+
if (!isDifferentKnownTurn && input.seq < current.patchSeq) {
|
|
317
|
+
return { applied: false, reason: "duplicate", state: current };
|
|
318
|
+
}
|
|
319
|
+
const state = {
|
|
320
|
+
...current,
|
|
321
|
+
spaceId: input.spaceId ?? current.spaceId ?? null,
|
|
322
|
+
sessionId: input.sessionId,
|
|
323
|
+
status: "streaming",
|
|
324
|
+
contentBlocks: sortBlocksByStreamIndex(input.contentBlocks.map(cloneBlock)),
|
|
325
|
+
anchorUserMessageId: input.anchorUserMessageId ?? current.anchorUserMessageId ?? null,
|
|
326
|
+
patchSeq: input.seq,
|
|
327
|
+
turnId: inputTurnId ?? current.turnId ?? null,
|
|
328
|
+
appendPath: input.appendPath ?? null,
|
|
329
|
+
};
|
|
330
|
+
this.states.set(this.key(input), state);
|
|
331
|
+
return { applied: true, state };
|
|
332
|
+
}
|
|
222
333
|
resetAll() {
|
|
223
334
|
this.states.clear();
|
|
224
335
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -6,6 +6,17 @@ export type { ChannelConfig, DiscordChannelConfig, } from "@neta-art/cohub-proto
|
|
|
6
6
|
export type ApiError = {
|
|
7
7
|
message: string;
|
|
8
8
|
};
|
|
9
|
+
export type UserProfile = {
|
|
10
|
+
userUuid: string;
|
|
11
|
+
logtoUserId?: string;
|
|
12
|
+
displayName: string;
|
|
13
|
+
avatarUrl: string | null;
|
|
14
|
+
syncedAt?: string;
|
|
15
|
+
};
|
|
16
|
+
export type MeResponse = {
|
|
17
|
+
uuid: string;
|
|
18
|
+
profile: UserProfile;
|
|
19
|
+
};
|
|
9
20
|
export type UserRulesResponse = {
|
|
10
21
|
content: string;
|
|
11
22
|
updatedAt: string | null;
|
|
@@ -55,13 +66,55 @@ export type SpaceFsUploadEntry = {
|
|
|
55
66
|
};
|
|
56
67
|
export type SpaceFsUploadError = {
|
|
57
68
|
name: string;
|
|
58
|
-
code: "file_too_large" | "name_invalid" | "write_failed";
|
|
69
|
+
code: "file_too_large" | "name_invalid" | "path_invalid" | "write_failed" | "object_missing";
|
|
59
70
|
message: string;
|
|
60
71
|
};
|
|
61
72
|
export type SpaceFsUploadResponse = {
|
|
62
73
|
uploaded: SpaceFsUploadEntry[];
|
|
63
74
|
errors: SpaceFsUploadError[];
|
|
64
75
|
};
|
|
76
|
+
export type SpaceFsUploadPlanEntryInput = {
|
|
77
|
+
id: string;
|
|
78
|
+
name: string;
|
|
79
|
+
relativePath: string;
|
|
80
|
+
size: number;
|
|
81
|
+
mimeType?: string | null;
|
|
82
|
+
lastModified?: number;
|
|
83
|
+
};
|
|
84
|
+
export type SpaceFsCreateUploadInput = {
|
|
85
|
+
targetDir?: string;
|
|
86
|
+
entries: SpaceFsUploadPlanEntryInput[];
|
|
87
|
+
};
|
|
88
|
+
export type SpaceFsUploadPlanEntry = {
|
|
89
|
+
id: string;
|
|
90
|
+
objectKey: string;
|
|
91
|
+
uploadUrl: string;
|
|
92
|
+
headers?: Record<string, string>;
|
|
93
|
+
};
|
|
94
|
+
export type SpaceFsCreateUploadResponse = {
|
|
95
|
+
uploadId: string;
|
|
96
|
+
expiresAt: string;
|
|
97
|
+
entries: SpaceFsUploadPlanEntry[];
|
|
98
|
+
};
|
|
99
|
+
export type SpaceFsCompleteUploadInput = {
|
|
100
|
+
entries: Array<{
|
|
101
|
+
id: string;
|
|
102
|
+
etag?: string | null;
|
|
103
|
+
}>;
|
|
104
|
+
};
|
|
105
|
+
export type SpaceFsCompleteUploadResponse = {
|
|
106
|
+
ok: true;
|
|
107
|
+
taskRunId: string;
|
|
108
|
+
};
|
|
109
|
+
export type SpaceFsUploadProgress = {
|
|
110
|
+
phase: "queued" | "importing" | "done" | "failed";
|
|
111
|
+
totalFiles: number;
|
|
112
|
+
importedFiles: number;
|
|
113
|
+
totalBytes: number;
|
|
114
|
+
importedBytes: number;
|
|
115
|
+
currentPath?: string;
|
|
116
|
+
errors: SpaceFsUploadError[];
|
|
117
|
+
};
|
|
65
118
|
export type SessionBindingRecord = ProtocolSessionBindingRecord;
|
|
66
119
|
export type SessionRecord = ProtocolSessionRecord & {
|
|
67
120
|
bindings?: SessionBindingRecord[];
|
|
@@ -154,6 +207,28 @@ export type SessionTurnResponse = {
|
|
|
154
207
|
export type SessionTurnSignedUrlsResponse = {
|
|
155
208
|
urls: Record<string, string>;
|
|
156
209
|
};
|
|
210
|
+
export type SessionTurnStreamSnapshotResponse = {
|
|
211
|
+
snapshot: {
|
|
212
|
+
version: 2;
|
|
213
|
+
spaceId: string;
|
|
214
|
+
sessionId: string;
|
|
215
|
+
turnId: string | null;
|
|
216
|
+
anchorUserMessageId: string | null;
|
|
217
|
+
seq: number;
|
|
218
|
+
current: {
|
|
219
|
+
messageId: string | null;
|
|
220
|
+
messageOrdinal: number | null;
|
|
221
|
+
content: ContentBlock[];
|
|
222
|
+
appendPath: string | null;
|
|
223
|
+
};
|
|
224
|
+
intermediateMessages: Array<{
|
|
225
|
+
messageId: string | null;
|
|
226
|
+
messageOrdinal: number | null;
|
|
227
|
+
content: ContentBlock[];
|
|
228
|
+
}>;
|
|
229
|
+
updatedAt: number;
|
|
230
|
+
} | null;
|
|
231
|
+
};
|
|
157
232
|
export type ModelCatalogEntry = {
|
|
158
233
|
provider: string;
|
|
159
234
|
id: string;
|
|
@@ -220,6 +295,10 @@ export type CronJobRecord = {
|
|
|
220
295
|
createdAt: string;
|
|
221
296
|
updatedAt: string;
|
|
222
297
|
};
|
|
298
|
+
export type TaskRunDetailResponse = {
|
|
299
|
+
run: TaskRunRecord;
|
|
300
|
+
progress: unknown;
|
|
301
|
+
};
|
|
223
302
|
export type TaskRunRecord = {
|
|
224
303
|
id: string;
|
|
225
304
|
jobId: string;
|
|
@@ -272,6 +351,7 @@ export type SpaceRole = "host" | "builder" | "guest";
|
|
|
272
351
|
export type SpaceMember = {
|
|
273
352
|
userId: string;
|
|
274
353
|
role: SpaceRole;
|
|
354
|
+
profile: UserProfile;
|
|
275
355
|
createdAt: string;
|
|
276
356
|
updatedAt: string;
|
|
277
357
|
};
|