@anchrd/colab-sdk 0.1.16 → 0.1.18

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.
Files changed (38) hide show
  1. package/dist/actions/actions.d.ts +151 -2
  2. package/dist/actions/actions.js +50 -6
  3. package/dist/boards/boards.d.ts +253 -9
  4. package/dist/boards/boards.js +63 -12
  5. package/dist/card-kinds/card-kinds.d.ts +5 -5
  6. package/dist/documents/documents.d.ts +59 -2
  7. package/dist/documents/documents.js +18 -4
  8. package/dist/error/error.d.ts +58 -4
  9. package/dist/error/error.js +146 -3
  10. package/dist/events/events.d.ts +15 -0
  11. package/dist/events/events.js +10 -0
  12. package/dist/excerpt/excerpt.d.ts +16 -0
  13. package/dist/excerpt/excerpt.js +33 -0
  14. package/dist/files/files.d.ts +6 -0
  15. package/dist/files/files.js +5 -1
  16. package/dist/grammar/grammar.d.ts +6 -0
  17. package/dist/grammar/grammar.js +54 -0
  18. package/dist/instructions/instructions.d.ts +36 -0
  19. package/dist/instructions/instructions.js +29 -0
  20. package/dist/missing/missing.d.ts +56 -0
  21. package/dist/missing/missing.js +66 -0
  22. package/dist/nodes/nodes.d.ts +21 -5
  23. package/dist/nodes/nodes.js +10 -7
  24. package/dist/operators/operators.d.ts +13 -3
  25. package/dist/operators/operators.js +19 -4
  26. package/dist/primitives/primitives.js +1 -1
  27. package/dist/runs/runs.d.ts +1 -1
  28. package/dist/sdk.d.ts +13 -10
  29. package/dist/sdk.js +13 -10
  30. package/dist/sso/sso.js +3 -2
  31. package/dist/tables/tables.d.ts +32 -0
  32. package/dist/tables/tables.js +12 -1
  33. package/dist/tool.d.ts +5 -3
  34. package/dist/versions/versions.d.ts +102 -0
  35. package/dist/versions/versions.js +14 -0
  36. package/dist/written/written.d.ts +206 -0
  37. package/dist/written/written.js +90 -0
  38. package/package.json +1 -1
@@ -21,6 +21,7 @@ export declare const CardKindIcon: z.ZodEnum<{
21
21
  message: "message";
22
22
  user: "user";
23
23
  package: "package";
24
+ target: "target";
24
25
  search: "search";
25
26
  flag: "flag";
26
27
  route: "route";
@@ -28,7 +29,6 @@ export declare const CardKindIcon: z.ZodEnum<{
28
29
  "square-check": "square-check";
29
30
  "file-text": "file-text";
30
31
  bulb: "bulb";
31
- target: "target";
32
32
  calendar: "calendar";
33
33
  star: "star";
34
34
  bolt: "bolt";
@@ -68,6 +68,7 @@ export declare const CardKindInput: z.ZodObject<{
68
68
  message: "message";
69
69
  user: "user";
70
70
  package: "package";
71
+ target: "target";
71
72
  search: "search";
72
73
  flag: "flag";
73
74
  route: "route";
@@ -75,7 +76,6 @@ export declare const CardKindInput: z.ZodObject<{
75
76
  "square-check": "square-check";
76
77
  "file-text": "file-text";
77
78
  bulb: "bulb";
78
- target: "target";
79
79
  calendar: "calendar";
80
80
  star: "star";
81
81
  bolt: "bolt";
@@ -113,6 +113,7 @@ export declare const CardKindsInput: z.ZodArray<z.ZodObject<{
113
113
  message: "message";
114
114
  user: "user";
115
115
  package: "package";
116
+ target: "target";
116
117
  search: "search";
117
118
  flag: "flag";
118
119
  route: "route";
@@ -120,7 +121,6 @@ export declare const CardKindsInput: z.ZodArray<z.ZodObject<{
120
121
  "square-check": "square-check";
121
122
  "file-text": "file-text";
122
123
  bulb: "bulb";
123
- target: "target";
124
124
  calendar: "calendar";
125
125
  star: "star";
126
126
  bolt: "bolt";
@@ -183,6 +183,7 @@ export declare const CardKind: z.ZodObject<{
183
183
  message: "message";
184
184
  user: "user";
185
185
  package: "package";
186
+ target: "target";
186
187
  search: "search";
187
188
  flag: "flag";
188
189
  route: "route";
@@ -190,7 +191,6 @@ export declare const CardKind: z.ZodObject<{
190
191
  "square-check": "square-check";
191
192
  "file-text": "file-text";
192
193
  bulb: "bulb";
193
- target: "target";
194
194
  calendar: "calendar";
195
195
  star: "star";
196
196
  bolt: "bolt";
@@ -228,6 +228,7 @@ export declare const TaskKind: z.ZodObject<{
228
228
  message: "message";
229
229
  user: "user";
230
230
  package: "package";
231
+ target: "target";
231
232
  search: "search";
232
233
  flag: "flag";
233
234
  route: "route";
@@ -235,7 +236,6 @@ export declare const TaskKind: z.ZodObject<{
235
236
  "square-check": "square-check";
236
237
  "file-text": "file-text";
237
238
  bulb: "bulb";
238
- target: "target";
239
239
  calendar: "calendar";
240
240
  star: "star";
241
241
  bolt: "bolt";
@@ -8,6 +8,8 @@ export declare const DocumentCreateInput: z.ZodObject<{
8
8
  export type DocumentCreateInput = z.infer<typeof DocumentCreateInput>;
9
9
  export declare const DocumentGetInput: z.ZodObject<{
10
10
  documentId: z.ZodTemplateLiteral<`node_${string}`>;
11
+ cursor: z.ZodOptional<z.ZodString>;
12
+ known: z.ZodOptional<z.ZodPreprocess<z.ZodArray<z.ZodString>, unknown>>;
11
13
  }, z.core.$strict>;
12
14
  export type DocumentGetInput = z.infer<typeof DocumentGetInput>;
13
15
  export declare const DocumentUpdateInput: z.ZodObject<{
@@ -49,13 +51,68 @@ export declare const DocumentDetail: z.ZodObject<{
49
51
  appHandle: z.ZodNullable<z.ZodString>;
50
52
  rev: z.ZodNumber;
51
53
  archivedAt: z.ZodNullable<z.ZodISODateTime>;
52
- instructions: z.ZodOptional<z.ZodObject<{
54
+ instructions: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
53
55
  chain: z.ZodArray<z.ZodObject<{
54
56
  path: z.ZodString;
55
57
  status: z.ZodNullable<z.ZodString>;
56
58
  markdown: z.ZodString;
57
59
  }, z.core.$strip>>;
58
60
  hint: z.ZodOptional<z.ZodString>;
59
- }, z.core.$strip>>;
61
+ digest: z.ZodString;
62
+ }, z.core.$strip>, z.ZodObject<{
63
+ digest: z.ZodString;
64
+ known: z.ZodLiteral<true>;
65
+ }, z.core.$strip>]>>;
60
66
  }, z.core.$strip>;
61
67
  export type DocumentDetail = z.infer<typeof DocumentDetail>;
68
+ export declare const DocumentExcerpt: z.ZodObject<{
69
+ secret: z.ZodOptional<z.ZodLiteral<true>>;
70
+ locked: z.ZodOptional<z.ZodBoolean>;
71
+ documentId: z.ZodTemplateLiteral<`node_${string}`>;
72
+ name: z.ZodString;
73
+ hidden: z.ZodBoolean;
74
+ parentId: z.ZodNullable<z.ZodTemplateLiteral<`node_${string}`>>;
75
+ path: z.ZodObject<{
76
+ section: z.ZodEnum<{
77
+ users: "users";
78
+ own: "own";
79
+ shared: "shared";
80
+ }>;
81
+ items: z.ZodArray<z.ZodObject<{
82
+ nodeId: z.ZodTemplateLiteral<`node_${string}`>;
83
+ name: z.ZodString;
84
+ }, z.core.$strip>>;
85
+ }, z.core.$strip>;
86
+ content: z.ZodString;
87
+ version: z.ZodNullable<z.ZodNumber>;
88
+ savedAt: z.ZodNullable<z.ZodISODateTime>;
89
+ savedBy: z.ZodNullable<z.ZodObject<{
90
+ userId: z.ZodString;
91
+ name: z.ZodNullable<z.ZodString>;
92
+ kind: z.ZodNullable<z.ZodEnum<{
93
+ machine: "machine";
94
+ human: "human";
95
+ }>>;
96
+ }, z.core.$strip>>;
97
+ appHandle: z.ZodNullable<z.ZodString>;
98
+ archivedAt: z.ZodNullable<z.ZodISODateTime>;
99
+ instructions: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
100
+ chain: z.ZodArray<z.ZodObject<{
101
+ path: z.ZodString;
102
+ status: z.ZodNullable<z.ZodString>;
103
+ markdown: z.ZodString;
104
+ }, z.core.$strip>>;
105
+ hint: z.ZodOptional<z.ZodString>;
106
+ digest: z.ZodString;
107
+ }, z.core.$strip>, z.ZodObject<{
108
+ digest: z.ZodString;
109
+ known: z.ZodLiteral<true>;
110
+ }, z.core.$strip>]>>;
111
+ excerpt: z.ZodObject<{
112
+ offset: z.ZodNumber;
113
+ length: z.ZodNumber;
114
+ nextCursor: z.ZodNullable<z.ZodString>;
115
+ }, z.core.$strip>;
116
+ rev: z.ZodOptional<z.ZodNumber>;
117
+ }, z.core.$strip>;
118
+ export type DocumentExcerpt = z.infer<typeof DocumentExcerpt>;
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
- import { Instructions } from "../instructions/instructions.js";
2
+ import { ExcerptCursor, TextExcerpt } from "../excerpt/excerpt.js";
3
+ import { InstructionsRead, Known } from "../instructions/instructions.js";
3
4
  import { NodeId, NodePath, NodePerson, SecretFields } from "../nodes/nodes.js";
4
5
  import { IdempotencyKey, Rev } from "../primitives/primitives.js";
5
6
  // Documents (#39, Nodes › Dokument, E36, E59): the inputs of `intelligence_document_create`, `_get`
@@ -22,7 +23,11 @@ export const DocumentCreateInput = z.strictObject({
22
23
  content: Content,
23
24
  idempotencyKey: IdempotencyKey,
24
25
  });
25
- export const DocumentGetInput = z.strictObject({ documentId: DocumentId });
26
+ export const DocumentGetInput = z.strictObject({
27
+ documentId: DocumentId,
28
+ cursor: ExcerptCursor.optional(),
29
+ known: Known.optional(),
30
+ });
26
31
  export const DocumentUpdateInput = z.strictObject({
27
32
  documentId: DocumentId,
28
33
  content: Content,
@@ -52,8 +57,17 @@ export const DocumentDetail = z.object({
52
57
  // The state the next save sends (E70).
53
58
  rev: z.number().int(),
54
59
  archivedAt: z.iso.datetime().nullable(),
55
- // Over MCP only, the INSTRUCTIONS of the document's folder (#39).
56
- instructions: Instructions.optional(),
60
+ // Over MCP only, the INSTRUCTIONS of the document's folder (#39); not again with a cursor (#674),
61
+ // the reference when known (E123, #677).
62
+ instructions: InstructionsRead.optional(),
57
63
  // A secret document (#357): `content` is empty while it is `locked` for this caller.
58
64
  ...SecretFields,
59
65
  });
66
+ // One excerpt of a document over MCP whose text is above `excerptChars` (E127, #674): `content` is
67
+ // this part, `excerpt` where it stands and the cursor of the next. ⚠️ `rev` comes with the last
68
+ // excerpt only: a save sends the whole text, and a `rev` beside a part of it would let a save of
69
+ // that part cut the rest away without a conflict.
70
+ export const DocumentExcerpt = DocumentDetail.extend({
71
+ excerpt: TextExcerpt,
72
+ rev: z.number().int().optional(),
73
+ });
@@ -11,18 +11,60 @@ export type ErrorCode = z.infer<typeof ErrorCode>;
11
11
  export declare const ErrorIssue: z.ZodObject<{
12
12
  path: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
13
13
  message: z.ZodString;
14
+ expected: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
14
15
  }, z.core.$strict>;
15
16
  export type ErrorIssue = z.infer<typeof ErrorIssue>;
17
+ export declare const ErrorCurrent: z.ZodObject<{
18
+ taskId: z.ZodOptional<z.ZodTemplateLiteral<`node_${string}`>>;
19
+ boardId: z.ZodOptional<z.ZodTemplateLiteral<`node_${string}`>>;
20
+ documentId: z.ZodOptional<z.ZodTemplateLiteral<`node_${string}`>>;
21
+ tableId: z.ZodOptional<z.ZodTemplateLiteral<`node_${string}`>>;
22
+ fileId: z.ZodOptional<z.ZodTemplateLiteral<`node_${string}`>>;
23
+ gadgetId: z.ZodOptional<z.ZodTemplateLiteral<`node_${string}`>>;
24
+ nodeId: z.ZodOptional<z.ZodTemplateLiteral<`node_${string}`>>;
25
+ machineId: z.ZodOptional<z.ZodTemplateLiteral<`user_${string}`>>;
26
+ rev: z.ZodNumber;
27
+ savedBy: z.ZodOptional<z.ZodObject<{
28
+ userId: z.ZodString;
29
+ name: z.ZodString;
30
+ }, z.core.$strict>>;
31
+ savedAt: z.ZodISODateTime;
32
+ values: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
33
+ }, z.core.$strict>;
34
+ export type ErrorCurrent = z.infer<typeof ErrorCurrent>;
16
35
  export declare const ErrorResponse: z.ZodObject<{
17
36
  error: z.ZodDiscriminatedUnion<[z.ZodObject<{
18
- code: z.ZodEnum<{
19
- invalid: "invalid";
20
- conflict: "conflict";
21
- }>;
37
+ code: z.ZodLiteral<"invalid">;
22
38
  message: z.ZodString;
23
39
  issues: z.ZodOptional<z.ZodArray<z.ZodObject<{
24
40
  path: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
25
41
  message: z.ZodString;
42
+ expected: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
43
+ }, z.core.$strict>>>;
44
+ }, z.core.$strict>, z.ZodObject<{
45
+ code: z.ZodLiteral<"conflict">;
46
+ message: z.ZodString;
47
+ issues: z.ZodOptional<z.ZodArray<z.ZodObject<{
48
+ path: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
49
+ message: z.ZodString;
50
+ expected: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
51
+ }, z.core.$strict>>>;
52
+ current: z.ZodOptional<z.ZodArray<z.ZodObject<{
53
+ taskId: z.ZodOptional<z.ZodTemplateLiteral<`node_${string}`>>;
54
+ boardId: z.ZodOptional<z.ZodTemplateLiteral<`node_${string}`>>;
55
+ documentId: z.ZodOptional<z.ZodTemplateLiteral<`node_${string}`>>;
56
+ tableId: z.ZodOptional<z.ZodTemplateLiteral<`node_${string}`>>;
57
+ fileId: z.ZodOptional<z.ZodTemplateLiteral<`node_${string}`>>;
58
+ gadgetId: z.ZodOptional<z.ZodTemplateLiteral<`node_${string}`>>;
59
+ nodeId: z.ZodOptional<z.ZodTemplateLiteral<`node_${string}`>>;
60
+ machineId: z.ZodOptional<z.ZodTemplateLiteral<`user_${string}`>>;
61
+ rev: z.ZodNumber;
62
+ savedBy: z.ZodOptional<z.ZodObject<{
63
+ userId: z.ZodString;
64
+ name: z.ZodString;
65
+ }, z.core.$strict>>;
66
+ savedAt: z.ZodISODateTime;
67
+ values: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
26
68
  }, z.core.$strict>>>;
27
69
  }, z.core.$strict>, z.ZodObject<{
28
70
  code: z.ZodEnum<{
@@ -34,3 +76,15 @@ export declare const ErrorResponse: z.ZodObject<{
34
76
  }, z.core.$strict>], "code">;
35
77
  }, z.core.$strict>;
36
78
  export type ErrorResponse = z.infer<typeof ErrorResponse>;
79
+ export declare function invalidInput(schema: z.ZodType, error: z.ZodError): ErrorResponse;
80
+ export declare const Warning: z.ZodObject<{
81
+ code: z.ZodEnum<{
82
+ followup_failed: "followup_failed";
83
+ test_failed: "test_failed";
84
+ mail_failed: "mail_failed";
85
+ unused: "unused";
86
+ too_long: "too_long";
87
+ }>;
88
+ message: z.ZodString;
89
+ }, z.core.$strip>;
90
+ export type Warning = z.infer<typeof Warning>;
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { idSchema } from "../ids/ids.js";
2
3
  // The one error shape of API and MCP (E68, E70). Missing rights answer `not_found`, never a code of
3
4
  // their own: a caller must not learn that something exists which it may not see.
4
5
  export const errorCodes = [
@@ -9,23 +10,165 @@ export const errorCodes = [
9
10
  "unavailable",
10
11
  ];
11
12
  export const ErrorCode = z.enum(errorCodes);
12
- // One entry per rejected field: where, and a sentence why.
13
+ // One entry per rejected field: where, and a sentence why. `expected` only where the tool's schema
14
+ // refused the input (#678): the form that field takes, the JSON Schema `tools/list` shows for it,
15
+ // derived from the schema and never written by hand, so the AI's next try needs no guess.
13
16
  export const ErrorIssue = z.strictObject({
14
17
  path: z.array(z.union([z.string(), z.number()])),
15
18
  message: z.string(),
19
+ expected: z.record(z.string(), z.unknown()).optional(),
20
+ });
21
+ const NodeRef = idSchema("node");
22
+ // What stands now where a save met a newer one (E128, #678), one entry per stale node: its `rev`,
23
+ // who saved it last (the author of its current version; absent for a kind without versions) and
24
+ // when, and under `values` today's value of exactly each field the call wanted to change, under the
25
+ // field's name in the call. Never a document's text: there the answer is to read it again. The id
26
+ // under its resource's name, as in `changed`; an Operator's under `machineId` (E135, #739). Nothing
27
+ // is merged and nothing overwritten (E70).
28
+ export const ErrorCurrent = z.strictObject({
29
+ taskId: NodeRef.optional(),
30
+ boardId: NodeRef.optional(),
31
+ documentId: NodeRef.optional(),
32
+ tableId: NodeRef.optional(),
33
+ fileId: NodeRef.optional(),
34
+ gadgetId: NodeRef.optional(),
35
+ nodeId: NodeRef.optional(),
36
+ machineId: idSchema("user").optional(),
37
+ rev: z.number().int(),
38
+ savedBy: z.strictObject({ userId: z.string(), name: z.string() }).optional(),
39
+ savedAt: z.iso.datetime(),
40
+ values: z.record(z.string(), z.unknown()).optional(),
16
41
  });
17
42
  // `issues` exists only next to `invalid` and `conflict` (a change of many entries names each stale
18
- // one, #630, #625); on every other code a strict object rejects it.
43
+ // one, #630, #625), `current` only next to `conflict` (E128); on every other code a strict object
44
+ // rejects them.
19
45
  export const ErrorResponse = z.strictObject({
20
46
  error: z.discriminatedUnion("code", [
21
47
  z.strictObject({
22
- code: z.enum(["invalid", "conflict"]),
48
+ code: z.literal("invalid"),
23
49
  message: z.string(),
24
50
  issues: z.array(ErrorIssue).optional(),
25
51
  }),
52
+ z.strictObject({
53
+ code: z.literal("conflict"),
54
+ message: z.string(),
55
+ issues: z.array(ErrorIssue).optional(),
56
+ current: z.array(ErrorCurrent).optional(),
57
+ }),
26
58
  z.strictObject({
27
59
  code: ErrorCode.exclude(["invalid", "conflict"]),
28
60
  message: z.string(),
29
61
  }),
30
62
  ]),
31
63
  });
64
+ const isSchema = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
65
+ // A `$ref` of the converter (`#`, `#/definitions/…`, `#/$defs/…`), resolved against the root.
66
+ function resolved(node, root) {
67
+ const ref = node.$ref;
68
+ if (typeof ref !== "string" || !ref.startsWith("#"))
69
+ return node;
70
+ let found = root;
71
+ for (const part of ref.slice(1).split("/").filter(Boolean)) {
72
+ found = isSchema(found) ? found[part.replaceAll("~1", "/").replaceAll("~0", "~")] : undefined;
73
+ }
74
+ return isSchema(found) ? found : node;
75
+ }
76
+ // The alternatives a value may take at this place: a nullable or optional field is an `anyOf`.
77
+ function branches(node, root) {
78
+ const own = resolved(node, root);
79
+ const alternatives = [own.anyOf, own.oneOf, own.allOf].find(Array.isArray);
80
+ if (!alternatives)
81
+ return [own];
82
+ return alternatives.filter(isSchema).flatMap((branch) => branches(branch, root));
83
+ }
84
+ function child(node, part, root) {
85
+ for (const branch of branches(node, root)) {
86
+ if (typeof part === "number") {
87
+ if (Array.isArray(branch.items) && isSchema(branch.items[part]))
88
+ return branch.items[part];
89
+ if (isSchema(branch.items))
90
+ return branch.items;
91
+ if (Array.isArray(branch.prefixItems) && isSchema(branch.prefixItems[part])) {
92
+ return branch.prefixItems[part];
93
+ }
94
+ continue;
95
+ }
96
+ if (isSchema(branch.properties) && isSchema(branch.properties[part])) {
97
+ return branch.properties[part];
98
+ }
99
+ if (isSchema(branch.additionalProperties))
100
+ return branch.additionalProperties;
101
+ }
102
+ return undefined;
103
+ }
104
+ // The JSON Schema at a path of the input, as `tools/list` shows it (#678).
105
+ function schemaAt(root, path) {
106
+ let node = root;
107
+ for (const part of path) {
108
+ node = node && child(node, part, root);
109
+ }
110
+ if (!node)
111
+ return undefined;
112
+ const { $schema: _schema, ...shown } = resolved(node, root);
113
+ return shown;
114
+ }
115
+ // The fields an object at this place takes, to name beside a key it does not know.
116
+ function fieldsAt(root, path) {
117
+ const node = schemaAt(root, path);
118
+ if (!node)
119
+ return [];
120
+ return [
121
+ ...new Set(branches(node, root).flatMap((branch) => isSchema(branch.properties) ? Object.keys(branch.properties) : [])),
122
+ ];
123
+ }
124
+ // The options `@modelcontextprotocol/sdk` converts a tool's input with for `tools/list`.
125
+ function jsonSchemaOf(schema) {
126
+ try {
127
+ return z.toJSONSchema(schema, { target: "draft-7", io: "input" });
128
+ }
129
+ catch {
130
+ return null;
131
+ }
132
+ }
133
+ const dotted = (path) => path.length === 0 ? "its top level" : path.map(String).join(".");
134
+ // `invalid` for an input its tool's schema refused (#678), at `/api` and `/mcp` alike: each issue
135
+ // with the field's path, Zod's sentence and the form the field expects; a key the schema does not
136
+ // know names the fields that are there instead.
137
+ export function invalidInput(schema, error) {
138
+ const root = jsonSchemaOf(schema);
139
+ const issues = error.issues.map((issue) => {
140
+ const path = issue.path.map((part) => (typeof part === "symbol" ? String(part) : part));
141
+ if (issue.code === "unrecognized_keys") {
142
+ const fields = root ? fieldsAt(root, path) : [];
143
+ return {
144
+ path,
145
+ message: fields.length > 0
146
+ ? `${issue.message}; the fields here are ${fields.join(", ")}.`
147
+ : issue.message,
148
+ };
149
+ }
150
+ const expected = root ? schemaAt(root, path) : undefined;
151
+ return { path, message: issue.message, ...(expected && { expected }) };
152
+ });
153
+ const places = [...new Set(issues.map((issue) => dotted(issue.path)))];
154
+ return {
155
+ error: {
156
+ code: "invalid",
157
+ message: `The input does not match the schema at ${places.join(", ")}: issues name what each expects. Nothing was done.`,
158
+ issues,
159
+ },
160
+ };
161
+ }
162
+ // What a write answers beside what it changed when it went through and something stands out (E126,
163
+ // `Written`): a hint for the AI, never a refusal; a fixed code and a sentence.
164
+ // - `followup_failed`: the change is saved, and a step after the save failed and was reported
165
+ // (#623, #725); the answer holds only what the save itself knows.
166
+ // - `test_failed`: a credential or a connection was changed and then failed its test, with the
167
+ // provider's sentence (#743); the change stands.
168
+ // - `mail_failed`: the mail of an invitation was not accepted (#743); the invitation stands.
169
+ // - `unused`: a credential that no Operator uses yet (#676).
170
+ // - `too_long`: an INSTRUCTIONS was saved with more words than an AI follows reliably (E67, #675).
171
+ export const Warning = z.object({
172
+ code: z.enum(["followup_failed", "test_failed", "mail_failed", "unused", "too_long"]),
173
+ message: z.string(),
174
+ });
@@ -13,6 +13,11 @@ export declare const ActorKind: z.ZodEnum<{
13
13
  human: "human";
14
14
  }>;
15
15
  export type ActorKind = z.infer<typeof ActorKind>;
16
+ export declare const EventSource: z.ZodEnum<{
17
+ mcp: "mcp";
18
+ api: "api";
19
+ }>;
20
+ export type EventSource = z.infer<typeof EventSource>;
16
21
  export declare const EventListInput: z.ZodObject<{
17
22
  actorId: z.ZodOptional<z.ZodUnion<readonly [z.ZodTemplateLiteral<`user_${string}`>, z.ZodTemplateLiteral<`service_${string}`>]>>;
18
23
  actorKind: z.ZodOptional<z.ZodEnum<{
@@ -62,7 +67,12 @@ export declare const Event: z.ZodObject<{
62
67
  human: "human";
63
68
  }>>;
64
69
  image: z.ZodNullable<z.ZodString>;
70
+ appHandle: z.ZodNullable<z.ZodString>;
65
71
  }, z.core.$strip>>;
72
+ source: z.ZodNullable<z.ZodEnum<{
73
+ mcp: "mcp";
74
+ api: "api";
75
+ }>>;
66
76
  failed: z.ZodBoolean;
67
77
  code: z.ZodNullable<z.ZodString>;
68
78
  ip: z.ZodNullable<z.ZodString>;
@@ -93,7 +103,12 @@ export declare const EventList: z.ZodObject<{
93
103
  human: "human";
94
104
  }>>;
95
105
  image: z.ZodNullable<z.ZodString>;
106
+ appHandle: z.ZodNullable<z.ZodString>;
96
107
  }, z.core.$strip>>;
108
+ source: z.ZodNullable<z.ZodEnum<{
109
+ mcp: "mcp";
110
+ api: "api";
111
+ }>>;
97
112
  failed: z.ZodBoolean;
98
113
  code: z.ZodNullable<z.ZodString>;
99
114
  ip: z.ZodNullable<z.ZodString>;
@@ -13,6 +13,8 @@ export const EventKind = z.enum(["change", "signin", "app", "connector"]);
13
13
  // Who did it: a person or a machine, or an outside service that declared its own interfaces under
14
14
  // `/auth/service` (#178).
15
15
  export const ActorKind = z.enum([...UserKind.options, "service"]);
16
+ // The doors of `ToolSource`, as a row of the protocol stores them (#738).
17
+ export const EventSource = z.enum(["api", "mcp"]);
16
18
  export const EventListInput = z.strictObject({
17
19
  // Who did it: a user, or a service for what it declared itself (#178).
18
20
  actorId: z.union([UserId, ServiceId]).optional(),
@@ -51,14 +53,22 @@ export const Event = z.object({
51
53
  // `access.directory.resolve` gives it: null for a machine, a service and a person without one
52
54
  // (#140). ⚠️ `userId` also carries a `service_…` id when `kind` is `service` (#178): the field
53
55
  // keeps its name so the answer's shape stays as the UI reads it.
56
+ // `appHandle` is the app a person's AI came through over `/mcp` (#738, E134), by its registered
57
+ // name like a chat's sender (E49), the stored client id where `access` no longer knows the client;
58
+ // null from the UI, for a machine's own token and for every row from before.
54
59
  actor: z
55
60
  .object({
56
61
  userId: z.string(),
57
62
  name: z.string().nullable(),
58
63
  kind: ActorKind.nullable(),
59
64
  image: z.string().nullable(),
65
+ appHandle: z.string().nullable(),
60
66
  })
61
67
  .nullable(),
68
+ // The door the event came through (#738, E134): `api` for `/api` and `/auth` (the UI, a sign-in, a
69
+ // service's own door), `mcp` for `/mcp`; null for what Colab does itself in a job and for every row
70
+ // from before.
71
+ source: EventSource.nullable(),
62
72
  failed: z.boolean(),
63
73
  // The refusal's code, only next to `failed`.
64
74
  code: z.string().nullable(),
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ export declare const excerptChars = 20000;
3
+ export declare const ExcerptCursor: z.ZodString;
4
+ export declare const TextExcerpt: z.ZodObject<{
5
+ offset: z.ZodNumber;
6
+ length: z.ZodNumber;
7
+ nextCursor: z.ZodNullable<z.ZodString>;
8
+ }, z.core.$strip>;
9
+ export type TextExcerpt = z.infer<typeof TextExcerpt>;
10
+ export declare const RowsExcerpt: z.ZodObject<{
11
+ firstRow: z.ZodNumber;
12
+ lastRow: z.ZodNumber;
13
+ rowCount: z.ZodNumber;
14
+ nextCursor: z.ZodNullable<z.ZodString>;
15
+ }, z.core.$strip>;
16
+ export type RowsExcerpt = z.infer<typeof RowsExcerpt>;
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ // Large texts over `/mcp` (E127, #674): the text of a document, a file or a table comes in excerpts of
3
+ // at most `excerptChars` characters, each with where it stands in the whole and a `cursor` for the
4
+ // next one, until everything is read. A text that fits comes whole, without `excerpt`. Nothing is cut
5
+ // at the end of an answer: a result cut off in the middle of its JSON is useless. Claude Code warns at
6
+ // 10,000 tokens of tool output and puts a text over 50,000 characters into a file the AI must read
7
+ // again; 20,000 characters are about 5,000 tokens.
8
+ export const excerptChars = 20_000;
9
+ // One cursor for every kind: the next excerpt of the same text, refused once the node has changed.
10
+ export const ExcerptCursor = z
11
+ .string()
12
+ .min(1)
13
+ .max(500)
14
+ .describe("The nextCursor of the previous excerpt, unchanged, for the next part of the same text. If the node was saved in between, the answer is conflict: read it again without cursor.");
15
+ // Where an excerpt of a document's Markdown or a file's text stands, in characters.
16
+ export const TextExcerpt = z.object({
17
+ // The characters of the whole text before this excerpt.
18
+ offset: z.number().int(),
19
+ // The characters of the whole text.
20
+ length: z.number().int(),
21
+ // Null with the last excerpt.
22
+ nextCursor: z.string().nullable(),
23
+ });
24
+ // Where an excerpt of a table stands: whole rows, never a row cut in two; the CSV's header line comes
25
+ // with the first excerpt only, so the excerpts joined are the table's CSV.
26
+ export const RowsExcerpt = z.object({
27
+ // The positions of the first and the last row in this excerpt, 1 for the first data row.
28
+ firstRow: z.number().int(),
29
+ lastRow: z.number().int(),
30
+ // The data rows of the whole table.
31
+ rowCount: z.number().int(),
32
+ nextCursor: z.string().nullable(),
33
+ });
@@ -27,6 +27,7 @@ export declare const FileUpdateInput: z.ZodObject<{
27
27
  export type FileUpdateInput = z.infer<typeof FileUpdateInput>;
28
28
  export declare const FileGetInput: z.ZodObject<{
29
29
  fileId: z.ZodTemplateLiteral<`node_${string}`>;
30
+ cursor: z.ZodOptional<z.ZodString>;
30
31
  }, z.core.$strict>;
31
32
  export type FileGetInput = z.infer<typeof FileGetInput>;
32
33
  export declare const UploadTicket: z.ZodObject<{
@@ -71,6 +72,11 @@ export declare const FileDetail: z.ZodObject<{
71
72
  reading: "reading";
72
73
  none: "none";
73
74
  }>;
75
+ excerpt: z.ZodOptional<z.ZodObject<{
76
+ offset: z.ZodNumber;
77
+ length: z.ZodNumber;
78
+ nextCursor: z.ZodNullable<z.ZodString>;
79
+ }, z.core.$strip>>;
74
80
  contentUrl: z.ZodURL;
75
81
  sourceUrl: z.ZodOptional<z.ZodString>;
76
82
  fetchedAt: z.ZodOptional<z.ZodISODateTime>;
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { ExcerptCursor, TextExcerpt } from "../excerpt/excerpt.js";
2
3
  import { idSchema } from "../ids/ids.js";
3
4
  import { NodeId } from "../nodes/nodes.js";
4
5
  import { IdempotencyKey, Rev } from "../primitives/primitives.js";
@@ -142,7 +143,7 @@ export const FileUpdateInput = z.strictObject({
142
143
  size: Size,
143
144
  rev: Rev,
144
145
  });
145
- export const FileGetInput = z.strictObject({ fileId: FileId });
146
+ export const FileGetInput = z.strictObject({ fileId: FileId, cursor: ExcerptCursor.optional() });
146
147
  // What `_create` and `_update` answer: the door, the ticket and the whole command. ⚠️ `ticket` is a
147
148
  // credential, and it is in this answer on purpose: it opens ONE upload for ONE person for fifteen
148
149
  // minutes. It appears nowhere else, never in an error and never in a log.
@@ -173,8 +174,11 @@ export const FileDetail = z.object({
173
174
  // The node's revision, to send with the next `_update`.
174
175
  rev: z.number().int(),
175
176
  // The text read from the current version for search and AI; null unless `textState` is `done`.
177
+ // Over MCP a text above `excerptChars` comes in excerpts (E127, #674): then this is one of them.
176
178
  text: z.string().nullable(),
177
179
  textState: FileTextState,
180
+ // Over MCP only, when the text comes in excerpts: where this one stands, and the cursor of the next.
181
+ excerpt: TextExcerpt.optional(),
178
182
  // Where the bytes are read, with a session or a token and the right to read the file.
179
183
  contentUrl: z.url(),
180
184
  // Only on a version Colab fetched from an address (#556): the address asked for and when.
@@ -39,6 +39,11 @@ export declare const verbs: readonly ["invite", "resend", "disable", "enable", "
39
39
  export type Package = (typeof packages)[number];
40
40
  export type Resource = keyof typeof resources;
41
41
  export type Action = (typeof actions)[number] | (typeof verbs)[number];
42
+ export type ActionAnnotations = {
43
+ readOnlyHint: boolean;
44
+ destructiveHint?: boolean;
45
+ idempotentHint?: boolean;
46
+ };
42
47
  export type ToolName = {
43
48
  package: Package;
44
49
  resources: readonly Resource[];
@@ -60,4 +65,5 @@ export declare function parseToolName(name: string): ToolName;
60
65
  export declare function toolRoute(name: string): Route;
61
66
  export declare function toolPermission(name: string): string;
62
67
  export declare function toolEvent(name: string): string;
68
+ export declare function toolAnnotations(name: string): ActionAnnotations | undefined;
63
69
  export declare function toolSchemaName(name: string): string;