@leaflow/sdk 0.36.0 → 0.38.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.
@@ -2,6 +2,8 @@ export type { paths, components, operations, webhooks } from "./schema.js";
2
2
  import type { operations } from "./schema.js";
3
3
  /** `POST /api/v1/attachments` 成功时的响应体。 */
4
4
  export type UploadAttachmentResult = operations["upload-attachment"]["responses"][201]["content"]["application/json"];
5
+ /** `POST /api/v1/attachments` 的查询参数。 */
6
+ export type UploadAttachmentQuery = operations["upload-attachment"]["parameters"]["query"];
5
7
  /** `GET /api/v1/bindings` 成功时的响应体。 */
6
8
  export type ListBindingsResult = operations["list-bindings"]["responses"][200]["content"]["application/json"];
7
9
  /** `GET /api/v1/bindings` 的查询参数。 */
@@ -13,8 +13,10 @@ export interface paths {
13
13
  get?: never;
14
14
  put?: never;
15
15
  /**
16
- * Upload an image
17
- * @description The body is the file bytes themselves, not multipart, one file per request. The type is determined from the content, not from Content-Type. Put the returned id in attachmentIds when sending a message; attachments never referenced by any message are cleared periodically.
16
+ * Upload a file
17
+ * @description The body is the file bytes themselves, not multipart, one file per request. The kind is determined from the content, not from Content-Type or from the name. Put the returned id in attachmentIds when sending a message; attachments never referenced by any message are cleared periodically.
18
+ *
19
+ * The returned `kind` says how the assistant will see it. An `image` is read directly, and only by models that accept image input. A small `text` file is placed inline in the message. A large `text` file, and anything `binary`, arrives as a reference the assistant reads on demand — for a binary that usually means downloading it onto one of the project's cloud instances.
18
20
  */
19
21
  post: operations["upload-attachment"];
20
22
  delete?: never;
@@ -31,8 +33,10 @@ export interface paths {
31
33
  cookie?: never;
32
34
  };
33
35
  /**
34
- * Fetch an image
35
- * @description Returns the original bytes for an attachment id, usable directly as the address of an <img>. The response carries long-lived cache headers because the content never changes. Returns 404 when the attachment does not exist or does not belong to the current user.
36
+ * Download a file
37
+ * @description Returns the original bytes for an attachment id. The response carries long-lived cache headers because the content never changes. Returns 404 when the attachment does not exist or does not belong to the current user.
38
+ *
39
+ * Only an attachment whose `kind` is `image` comes back with its own image type and is usable as the address of an `<img>`. Everything else is served as `application/octet-stream` with `Content-Disposition: attachment`, deliberately: an uploaded file is arbitrary bytes under a name its uploader chose, and serving it back inline would run it on this origin.
36
40
  */
37
41
  get: operations["download-attachment"];
38
42
  put?: never;
@@ -612,11 +616,32 @@ export interface components {
612
616
  status: number;
613
617
  };
614
618
  UploadedResource: {
615
- /** Format: int64 */
616
- height: number;
619
+ /**
620
+ * Format: int64
621
+ * @description Size of what was stored. For an image that has been resized, this is the resized size, not what was uploaded.
622
+ */
623
+ byteSize: number;
624
+ filename: string;
625
+ /**
626
+ * Format: int64
627
+ * @description Null unless kind is image.
628
+ */
629
+ height: number | null;
617
630
  id: string;
618
- /** Format: int64 */
619
- width: number;
631
+ /**
632
+ * @description How the assistant will see this file.
633
+ *
634
+ * - `image` — read directly, and only by models that accept image input
635
+ * - `text` — placed inline in the message when small enough, otherwise read on demand
636
+ * - `binary` — never read directly; the assistant downloads it onto a cloud instance to work with it
637
+ * @enum {string}
638
+ */
639
+ kind: "image" | "text" | "binary";
640
+ /**
641
+ * Format: int64
642
+ * @description Null unless kind is image.
643
+ */
644
+ width: number | null;
620
645
  };
621
646
  BindingResource: {
622
647
  /** Format: uuid */
@@ -934,7 +959,13 @@ export interface components {
934
959
  ContextResource: {
935
960
  /** Format: int64 */
936
961
  compactAt: number | null;
937
- /** @description What kinds of input the model behind this conversation accepts, as modality names: text, image. A client uses this to decide whether a control exists — an attach button on a model that cannot read pictures is a control whose only outcome is a refusal, and the refusal arrives after somebody has chosen a file. An empty list is not a claim that the model reads nothing: it means this deployment has not stated the modalities, or the conversation names a model that has since been retired. Treat empty as unknown and keep the control, because hiding one for a reason nobody can see is worse than a refusal that says why. */
962
+ /**
963
+ * @description What kinds of input the model behind this conversation accepts, as modality names: text, image.
964
+ *
965
+ * This governs images and nothing else. Text and binary attachments reach every model: a small text file is placed inline, a large one is read on demand, and a binary is downloaded onto a cloud instance — none of which asks the model to see a picture. So this decides whether pasting a screenshot does anything, not whether the attach control exists. Hiding file upload on a text-only model takes away something that would have worked.
966
+ *
967
+ * An empty list is not a claim that the model reads nothing: it means this deployment has not stated the modalities, or the conversation names a model that has since been retired. Treat empty as unknown and keep the control, because hiding one for a reason nobody can see is worse than a refusal that says why.
968
+ */
938
969
  inputModalities: string[];
939
970
  model: string;
940
971
  /** Format: int64 */
@@ -951,10 +982,24 @@ export interface components {
951
982
  };
952
983
  AttachmentResource: {
953
984
  /** Format: int64 */
954
- height: number;
985
+ byteSize: number;
986
+ filename: string;
987
+ /**
988
+ * Format: int64
989
+ * @description Null unless kind is image. Width and height are here so a client can hold the space before the image itself has loaded.
990
+ */
991
+ height: number | null;
955
992
  id: string;
956
- /** Format: int64 */
957
- width: number;
993
+ /**
994
+ * @description What this attachment is. A client renders an image in place and everything else as a file to download.
995
+ * @enum {string}
996
+ */
997
+ kind: "image" | "text" | "binary";
998
+ /**
999
+ * Format: int64
1000
+ * @description Null unless kind is image.
1001
+ */
1002
+ width: number | null;
958
1003
  };
959
1004
  ItemResource: {
960
1005
  /** @enum {string|null} */
@@ -993,8 +1038,8 @@ export interface components {
993
1038
  * @description The content of this entry, in the order it was written. A message that is only text is a
994
1039
  * single part, which is most of them.
995
1040
  *
996
- * An image belongs where it was written, so render these in order rather than putting
997
- * attachments at the end.
1041
+ * An attachment belongs where it was written, so render these in order rather than putting
1042
+ * them all at the end.
998
1043
  */
999
1044
  parts?: components["schemas"]["PartResource"][] | null;
1000
1045
  tool?: string | null;
@@ -1139,7 +1184,7 @@ export interface components {
1139
1184
  * - `data-<something>` — context from the client, in `data`. The name after `data-` is yours;
1140
1185
  * it is shown to the assistant so it can tell one kind of block from another.
1141
1186
  *
1142
- * Order matters: an image belongs where it was written, not at the end.
1187
+ * Order matters: an attachment belongs where it was written, not at the end.
1143
1188
  */
1144
1189
  MessagePart: {
1145
1190
  /** @description For `file` parts. The attachment must have been uploaded and not yet bound to another message. */
@@ -1272,7 +1317,10 @@ export type $defs = Record<string, never>;
1272
1317
  export interface operations {
1273
1318
  "upload-attachment": {
1274
1319
  parameters: {
1275
- query?: never;
1320
+ query?: {
1321
+ /** @description The name to show and to give the assistant. Images do not need one; anything else does, because the name is most of what says what the file is. Falls back to a generated name. */
1322
+ filename?: string;
1323
+ };
1276
1324
  header?: never;
1277
1325
  path?: never;
1278
1326
  cookie?: never;
@@ -1319,10 +1367,12 @@ export interface operations {
1319
1367
  headers: {
1320
1368
  /** @description Private and long-lived: these bytes are addressed by an id that is never reused, so they never change; and they belong to one person, so they must not enter any shared cache. */
1321
1369
  "Cache-Control"?: string;
1370
+ /** @description Present on everything that is not an image, carrying the original filename. Absent on images, which are meant to be rendered in place. */
1371
+ "Content-Disposition"?: string;
1322
1372
  [name: string]: unknown;
1323
1373
  };
1324
1374
  content: {
1325
- "image/*": string;
1375
+ "*/*": string;
1326
1376
  };
1327
1377
  };
1328
1378
  /** @description Error */
@@ -1058,6 +1058,13 @@ export interface components {
1058
1058
  key: string;
1059
1059
  /** Format: int64 */
1060
1060
  port: number;
1061
+ /**
1062
+ * @description The channel carrying announcements. It is public: subscribing to it needs no
1063
+ * authorization, because an announcement is addressed to everybody. The events on it
1064
+ * carry an identifier and nothing else, so a client fetches the list and sees the
1065
+ * announcements it is entitled to
1066
+ */
1067
+ announcements_channel: string;
1061
1068
  /** @description The channel carrying events about the project in the token; empty when the token names no project */
1062
1069
  project_channel: string;
1063
1070
  /** @description Whether to connect over TLS */
@@ -36,8 +36,8 @@ export type ListTicketCategoriesQuery = operations["list-ticket-categories"]["pa
36
36
  export type UploadAttachmentResult = operations["upload-attachment"]["responses"][201]["content"]["application/json"];
37
37
  /** `POST /api/v1/attachments` 的查询参数。 */
38
38
  export type UploadAttachmentQuery = operations["upload-attachment"]["parameters"]["query"];
39
- /** `GET /api/v1/attachments/{attachmentId}/download-url` 成功时的响应体。 */
40
- export type DescribeAttachmentDownloadResult = operations["describe-attachment-download"]["responses"][200]["content"]["application/json"];
39
+ /** `GET /api/v1/attachments/{attachmentId}/content` 的查询参数。 */
40
+ export type DownloadAttachmentQuery = operations["download-attachment"]["parameters"]["query"];
41
41
  /** `GET /api/v1/maintenances` 成功时的响应体。 */
42
42
  export type ListMaintenancesResult = operations["list-maintenances"]["responses"][200]["content"]["application/json"];
43
43
  /** `GET /api/v1/maintenances` 的查询参数。 */
@@ -202,7 +202,7 @@ export interface paths {
202
202
  patch?: never;
203
203
  trace?: never;
204
204
  };
205
- "/api/v1/attachments/{attachmentId}/download-url": {
205
+ "/api/v1/attachments/{attachmentId}/content": {
206
206
  parameters: {
207
207
  query?: never;
208
208
  header?: never;
@@ -210,13 +210,16 @@ export interface paths {
210
210
  cookie?: never;
211
211
  };
212
212
  /**
213
- * Get a download address for an attachment
214
- * @description Returns a temporary address that serves the file. The address expires; request a new one
215
- * rather than storing it.
213
+ * Download an attachment
214
+ * @description Serves the file itself. The bytes are proxied by this API; the object store is not reachable
215
+ * from outside, and no address to it is ever handed out.
216
216
  *
217
- * Returns 404 for an attachment uploaded in another project.
217
+ * `Content-Type` is the type determined from the content at upload time, not the one the
218
+ * client claimed. `Content-Disposition` is `attachment` unless `inline` is requested **and**
219
+ * the content type is one that can be rendered safely, in which case it is `inline`. Asking
220
+ * for `inline` on anything else still yields a download.
218
221
  */
219
- get: operations["describe-attachment-download"];
222
+ get: operations["download-attachment"];
220
223
  put?: never;
221
224
  post?: never;
222
225
  delete?: never;
@@ -469,15 +472,6 @@ export interface components {
469
472
  status: components["schemas"]["MaintenanceStatus"];
470
473
  title: string;
471
474
  };
472
- AttachmentDownloadResource: {
473
- /**
474
- * Format: date-time
475
- * @description After this moment the address stops working; request a new one
476
- */
477
- expires_at: string;
478
- /** @description A temporary address serving the file */
479
- url: string;
480
- };
481
475
  CreateTicketRequestBody: {
482
476
  /** @description Attachments to reference from the first message. Each must have been uploaded in this project and not yet referenced */
483
477
  attachment_ids?: string[];
@@ -940,9 +934,12 @@ export interface operations {
940
934
  };
941
935
  };
942
936
  };
943
- "describe-attachment-download": {
937
+ "download-attachment": {
944
938
  parameters: {
945
- query?: never;
939
+ query?: {
940
+ /** @description Render in the browser instead of downloading, where the content type allows it */
941
+ inline?: boolean;
942
+ };
946
943
  header?: never;
947
944
  path: {
948
945
  attachmentId: string;
@@ -954,10 +951,12 @@ export interface operations {
954
951
  /** @description OK */
955
952
  200: {
956
953
  headers: {
954
+ /** @description `inline` when the content type can be rendered safely and `inline` was asked for, `attachment` otherwise. Carries the original file name */
955
+ "Content-Disposition"?: string;
957
956
  [name: string]: unknown;
958
957
  };
959
958
  content: {
960
- "application/json": components["schemas"]["AttachmentDownloadResource"];
959
+ "*/*": string;
961
960
  };
962
961
  };
963
962
  /** @description Error */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leaflow/sdk",
3
- "version": "0.36.0",
3
+ "version": "0.38.0",
4
4
  "description": "Leaflow 平台 API 的 TypeScript SDK",
5
5
  "license": "MIT",
6
6
  "repository": {