@camox/api-contract 0.74.1 → 0.76.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/drafts.d.ts +17 -0
- package/dist/drafts.js +6 -1
- package/dist/query-keys.d.ts +12 -2
- package/dist/query-keys.js +18 -0
- package/dist/router.d.ts +1043 -45
- package/dist/threads.d.ts +42 -8
- package/dist/threads.js +44 -12
- package/package.json +1 -1
- package/src/drafts.ts +16 -0
- package/src/query-keys.ts +17 -2
- package/src/threads.ts +57 -12
package/dist/threads.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DraftOutcome } from "./drafts.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { AgentEvent } from "@earendil-works/pi-durable";
|
|
4
3
|
import { Message } from "@earendil-works/pi-ai";
|
|
4
|
+
import { AgentEvent } from "@earendil-works/pi-durable";
|
|
5
5
|
//#region src/threads.d.ts
|
|
6
6
|
/**
|
|
7
7
|
* The kind of the transcript entry recording an editor's message, with its sender and the
|
|
@@ -69,6 +69,14 @@ export type PushOutcome = z.infer<typeof pushOutcomeSchema>;
|
|
|
69
69
|
* call of it went through ends on the draft's card.
|
|
70
70
|
*/
|
|
71
71
|
export declare const START_DRAFT_TOOL = "startDraft";
|
|
72
|
+
/**
|
|
73
|
+
* The agent on Live's tool restoring an archived draft and handing the editor to it, as
|
|
74
|
+
* `startDraft` does (ADR 0025, ADR 0046). A run whose call of it went through ends on the
|
|
75
|
+
* draft's card.
|
|
76
|
+
*/
|
|
77
|
+
export declare const RESTORE_DRAFT_TOOL = "restoreDraft";
|
|
78
|
+
/** Whether a call of the tool `name` hands the editor off to a draft, which ends the run on its card. */
|
|
79
|
+
export declare const handsOffToDraft: (name: string) => name is "restoreDraft" | "startDraft";
|
|
72
80
|
/** The agent's tool building its code changes mid-turn, which the end of a turn also does. */
|
|
73
81
|
export declare const BUILD_TOOL = "build";
|
|
74
82
|
/** The agent's tool rendering the draft in a browser and returning screenshots to the model. */
|
|
@@ -140,21 +148,27 @@ export declare const handsOff: (name: string) => boolean;
|
|
|
140
148
|
* keeps this in step with the tools themselves.
|
|
141
149
|
*/
|
|
142
150
|
export declare const CHANGING_TOOLS: ReadonlySet<string>;
|
|
143
|
-
/**
|
|
151
|
+
/**
|
|
152
|
+
* The draft a `startDraft` call started, or a `restoreDraft` call restored, as its result's
|
|
153
|
+
* details name it for the card.
|
|
154
|
+
*/
|
|
144
155
|
export declare const startedDraftCardSchema: z.ZodObject<{
|
|
145
156
|
draftId: z.ZodString;
|
|
146
157
|
name: z.ZodString;
|
|
158
|
+
restored: z.ZodOptional<z.ZodLiteral<true>>;
|
|
147
159
|
}, z.core.$strip>;
|
|
148
160
|
export type StartedDraftCard = z.infer<typeof startedDraftCardSchema>;
|
|
149
161
|
/**
|
|
150
162
|
* Where a draft a Live thread's card names stands, as the thread looks it up whenever it's shown
|
|
151
|
-
* (ADR 0025): its current name, or its last once it ended, and how it ended.
|
|
152
|
-
*
|
|
153
|
-
*
|
|
163
|
+
* (ADR 0025): its current name, or its last once it ended, and how it ended. An archived draft
|
|
164
|
+
* hasn't ended: `archived` says it's set aside until someone restores it (ADR 0046). Never written
|
|
165
|
+
* into the transcript, so the model's cached prompt keeps up. A name cleared by a rename is null:
|
|
166
|
+
* the card keeps the name the agent gave it.
|
|
154
167
|
*/
|
|
155
168
|
export type DraftCardState = {
|
|
156
169
|
name: string | null;
|
|
157
170
|
ended?: DraftOutcome;
|
|
171
|
+
archived?: true;
|
|
158
172
|
};
|
|
159
173
|
/** The drafts a Live thread's cards name, by id, as the thread last looked them up. */
|
|
160
174
|
export type DraftCardStates = Readonly<Record<string, DraftCardState>>;
|
|
@@ -190,6 +204,14 @@ export declare const connectedAgentClientSchema: z.ZodObject<{
|
|
|
190
204
|
verified: z.ZodBoolean;
|
|
191
205
|
}, z.core.$strip>;
|
|
192
206
|
export type ConnectedAgentClient = z.infer<typeof connectedAgentClientSchema>;
|
|
207
|
+
/** An Attachment a Connected Agent's message carries: an image the agent sees with it. */
|
|
208
|
+
export declare const messageAttachmentSchema: z.ZodObject<{
|
|
209
|
+
id: z.ZodString;
|
|
210
|
+
filename: z.ZodString;
|
|
211
|
+
mimeType: z.ZodString;
|
|
212
|
+
url: z.ZodString;
|
|
213
|
+
}, z.core.$strip>;
|
|
214
|
+
export type MessageAttachmentData = z.infer<typeof messageAttachmentSchema>;
|
|
193
215
|
/**
|
|
194
216
|
* What a Connected Agent's message entry records: the member it acts as, its client, the
|
|
195
217
|
* operation id it was sent with, and whether it answers the agent's questions (ADR 0042).
|
|
@@ -206,6 +228,12 @@ export declare const connectedAgentMessageDataSchema: z.ZodObject<{
|
|
|
206
228
|
}, z.core.$strip>;
|
|
207
229
|
operationId: z.ZodOptional<z.ZodString>;
|
|
208
230
|
answer: z.ZodOptional<z.ZodBoolean>;
|
|
231
|
+
attachments: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
232
|
+
id: z.ZodString;
|
|
233
|
+
filename: z.ZodString;
|
|
234
|
+
mimeType: z.ZodString;
|
|
235
|
+
url: z.ZodString;
|
|
236
|
+
}, z.core.$strip>>>;
|
|
209
237
|
}, z.core.$strip>;
|
|
210
238
|
export type ConnectedAgentMessageData = z.infer<typeof connectedAgentMessageDataSchema>;
|
|
211
239
|
/** What a push's entry records: who pushed, their commits' subjects, oldest first, and the build. */
|
|
@@ -231,13 +259,14 @@ export declare const editorMessageDataSchema: z.ZodObject<{
|
|
|
231
259
|
operationId: z.ZodOptional<z.ZodString>;
|
|
232
260
|
}, z.core.$strip>;
|
|
233
261
|
/**
|
|
234
|
-
* A draft the agent on Live started with `startDraft`,
|
|
235
|
-
* the run that
|
|
262
|
+
* A draft the agent on Live started with `startDraft`, or restored with `restoreDraft`, and the
|
|
263
|
+
* operation ids of the messages of the run that did: the studio that sent one of them enters the draft, if it still shows
|
|
236
264
|
* Live.
|
|
237
265
|
*/
|
|
238
266
|
export declare const startedDraftSchema: z.ZodObject<{
|
|
239
267
|
draftId: z.ZodString;
|
|
240
268
|
operationIds: z.ZodArray<z.ZodString>;
|
|
269
|
+
restored: z.ZodOptional<z.ZodLiteral<true>>;
|
|
241
270
|
}, z.core.$strip>;
|
|
242
271
|
export type StartedDraft = z.infer<typeof startedDraftSchema>;
|
|
243
272
|
/** How a write touched what it names. */
|
|
@@ -350,6 +379,8 @@ export type ThreadMessage = {
|
|
|
350
379
|
client: ConnectedAgentClient;
|
|
351
380
|
text: string;
|
|
352
381
|
answer: boolean;
|
|
382
|
+
/** The images it carries for the agent to see, if any (ADR 0044). */
|
|
383
|
+
attachments?: MessageAttachmentData[];
|
|
353
384
|
} |
|
|
354
385
|
/** Camox's own message, starting a turn it began itself: why it did. */
|
|
355
386
|
{
|
|
@@ -389,12 +420,14 @@ export type ThreadMessage = {
|
|
|
389
420
|
/**
|
|
390
421
|
* In place of the agent's message, for a Live turn handed off to a draft the agent started:
|
|
391
422
|
* the draft's card, with its current name, which opens it. Once the draft ended, it has its
|
|
392
|
-
* last name and how it ended, and opens nothing.
|
|
423
|
+
* last name and how it ended, and opens nothing. While the draft is archived, `archived` is set,
|
|
424
|
+
* and the card offers to restore it. The turn is finished.
|
|
393
425
|
*/
|
|
394
426
|
({
|
|
395
427
|
id: string;
|
|
396
428
|
from: "draft";
|
|
397
429
|
ended?: DraftOutcome;
|
|
430
|
+
archived?: true;
|
|
398
431
|
} & StartedDraftCard) |
|
|
399
432
|
/**
|
|
400
433
|
* A member's push to the draft's code from their own checkout: who pushed, their commits'
|
|
@@ -502,6 +535,7 @@ type ThreadStep = {
|
|
|
502
535
|
client: ConnectedAgentClient;
|
|
503
536
|
text: string;
|
|
504
537
|
answer: boolean;
|
|
538
|
+
attachments?: MessageAttachmentData[];
|
|
505
539
|
} |
|
|
506
540
|
/** Camox starting a turn of its own, saying why. */
|
|
507
541
|
{
|
package/dist/threads.js
CHANGED
|
@@ -66,6 +66,14 @@ const pushOutcomeSchema = z.enum([
|
|
|
66
66
|
* call of it went through ends on the draft's card.
|
|
67
67
|
*/
|
|
68
68
|
const START_DRAFT_TOOL = "startDraft";
|
|
69
|
+
/**
|
|
70
|
+
* The agent on Live's tool restoring an archived draft and handing the editor to it, as
|
|
71
|
+
* `startDraft` does (ADR 0025, ADR 0046). A run whose call of it went through ends on the
|
|
72
|
+
* draft's card.
|
|
73
|
+
*/
|
|
74
|
+
const RESTORE_DRAFT_TOOL = "restoreDraft";
|
|
75
|
+
/** Whether a call of the tool `name` hands the editor off to a draft, which ends the run on its card. */
|
|
76
|
+
const handsOffToDraft = (name) => name === "startDraft" || name === "restoreDraft";
|
|
69
77
|
/** The agent's tool building its code changes mid-turn, which the end of a turn also does. */
|
|
70
78
|
const BUILD_TOOL = "build";
|
|
71
79
|
/** The agent's tool rendering the draft in a browser and returning screenshots to the model. */
|
|
@@ -138,6 +146,7 @@ const CHANGING_TOOLS = /* @__PURE__ */ new Set([
|
|
|
138
146
|
"addBackToLocale",
|
|
139
147
|
"addLocale",
|
|
140
148
|
"applyFindingFix",
|
|
149
|
+
"copyFromPastWork",
|
|
141
150
|
"createBlock",
|
|
142
151
|
"createCollectionRecord",
|
|
143
152
|
"createPage",
|
|
@@ -158,10 +167,15 @@ const CHANGING_TOOLS = /* @__PURE__ */ new Set([
|
|
|
158
167
|
"rm",
|
|
159
168
|
"write"
|
|
160
169
|
]);
|
|
161
|
-
/**
|
|
170
|
+
/**
|
|
171
|
+
* The draft a `startDraft` call started, or a `restoreDraft` call restored, as its result's
|
|
172
|
+
* details name it for the card.
|
|
173
|
+
*/
|
|
162
174
|
const startedDraftCardSchema = z.object({
|
|
163
175
|
draftId: z.string(),
|
|
164
|
-
name: z.string()
|
|
176
|
+
name: z.string(),
|
|
177
|
+
/** The agent restored the archived draft rather than starting it (ADR 0046). */
|
|
178
|
+
restored: z.literal(true).optional()
|
|
165
179
|
});
|
|
166
180
|
const reconcileDataSchema = z.object({ message: z.string() });
|
|
167
181
|
const buildStatusSchema = z.enum(["building", "fixing"]);
|
|
@@ -182,6 +196,13 @@ const connectedAgentClientSchema = z.object({
|
|
|
182
196
|
name: z.string(),
|
|
183
197
|
verified: z.boolean()
|
|
184
198
|
});
|
|
199
|
+
/** An Attachment a Connected Agent's message carries: an image the agent sees with it. */
|
|
200
|
+
const messageAttachmentSchema = z.object({
|
|
201
|
+
id: z.string(),
|
|
202
|
+
filename: z.string(),
|
|
203
|
+
mimeType: z.string(),
|
|
204
|
+
url: z.string()
|
|
205
|
+
});
|
|
185
206
|
/**
|
|
186
207
|
* What a Connected Agent's message entry records: the member it acts as, its client, the
|
|
187
208
|
* operation id it was sent with, and whether it answers the agent's questions (ADR 0042).
|
|
@@ -190,7 +211,9 @@ const connectedAgentMessageDataSchema = z.object({
|
|
|
190
211
|
member: threadSenderSchema,
|
|
191
212
|
client: connectedAgentClientSchema,
|
|
192
213
|
operationId: z.string().optional(),
|
|
193
|
-
answer: z.boolean().optional()
|
|
214
|
+
answer: z.boolean().optional(),
|
|
215
|
+
/** The images the message carries for the agent to see, as studios list them (ADR 0044). */
|
|
216
|
+
attachments: z.array(messageAttachmentSchema).optional()
|
|
194
217
|
});
|
|
195
218
|
/** What a push's entry records: who pushed, their commits' subjects, oldest first, and the build. */
|
|
196
219
|
const pushDataSchema = z.object({
|
|
@@ -201,13 +224,18 @@ const pushDataSchema = z.object({
|
|
|
201
224
|
/** What an editor's message entry records: who sent it, and the operation id it was sent with. */
|
|
202
225
|
const editorMessageDataSchema = threadSenderSchema.extend({ operationId: z.string().optional() });
|
|
203
226
|
/**
|
|
204
|
-
* A draft the agent on Live started with `startDraft`,
|
|
205
|
-
* the run that
|
|
227
|
+
* A draft the agent on Live started with `startDraft`, or restored with `restoreDraft`, and the
|
|
228
|
+
* operation ids of the messages of the run that did: the studio that sent one of them enters the draft, if it still shows
|
|
206
229
|
* Live.
|
|
207
230
|
*/
|
|
208
231
|
const startedDraftSchema = z.object({
|
|
209
232
|
draftId: z.string(),
|
|
210
|
-
operationIds: z.array(z.string())
|
|
233
|
+
operationIds: z.array(z.string()),
|
|
234
|
+
/**
|
|
235
|
+
* The agent restored the archived draft rather than starting it: its thread goes on from its
|
|
236
|
+
* own messages, without the run's.
|
|
237
|
+
*/
|
|
238
|
+
restored: z.literal(true).optional()
|
|
211
239
|
});
|
|
212
240
|
/** How a write touched what it names. */
|
|
213
241
|
const touchKindSchema = z.enum([
|
|
@@ -419,7 +447,8 @@ function threadStepOf(entry) {
|
|
|
419
447
|
verified: data.client.verified
|
|
420
448
|
},
|
|
421
449
|
text: editorTextOf(message.content),
|
|
422
|
-
answer: data.answer ?? false
|
|
450
|
+
answer: data.answer ?? false,
|
|
451
|
+
...data.attachments?.length && { attachments: data.attachments }
|
|
423
452
|
};
|
|
424
453
|
}
|
|
425
454
|
if (entry.kind === "camox.brief") return {
|
|
@@ -450,7 +479,7 @@ function threadStepOf(entry) {
|
|
|
450
479
|
text: details.answer
|
|
451
480
|
};
|
|
452
481
|
}
|
|
453
|
-
const card = message.toolName
|
|
482
|
+
const card = handsOffToDraft(message.toolName) && !message.isError ? startedDraftCardSchema.safeParse(message.details).data : void 0;
|
|
454
483
|
return card ? {
|
|
455
484
|
id,
|
|
456
485
|
type: "draft",
|
|
@@ -525,7 +554,8 @@ function threadViewOf({ steps, running, toolCalls = [], callingTools = false, ch
|
|
|
525
554
|
member: step.member,
|
|
526
555
|
client: step.client,
|
|
527
556
|
text: step.text,
|
|
528
|
-
answer: step.answer
|
|
557
|
+
answer: step.answer,
|
|
558
|
+
...step.attachments && { attachments: step.attachments }
|
|
529
559
|
});
|
|
530
560
|
waiting = step.id;
|
|
531
561
|
break;
|
|
@@ -572,7 +602,9 @@ function threadViewOf({ steps, running, toolCalls = [], callingTools = false, ch
|
|
|
572
602
|
from: "draft",
|
|
573
603
|
draftId: step.draftId,
|
|
574
604
|
name: draft?.name ?? step.name,
|
|
575
|
-
...
|
|
605
|
+
...step.restored && { restored: true },
|
|
606
|
+
...draft?.ended && { ended: draft.ended },
|
|
607
|
+
...draft?.archived && { archived: true }
|
|
576
608
|
});
|
|
577
609
|
}
|
|
578
610
|
endTurn();
|
|
@@ -629,7 +661,7 @@ function activityOf({ status, toolCalls, callingTools, changing, checking, hande
|
|
|
629
661
|
if (status === "fixing") return "fixing";
|
|
630
662
|
if (toolCalls.some((call) => handsOff(call.name))) return handedOffActivity ?? "changing";
|
|
631
663
|
if (checking) return "checking";
|
|
632
|
-
if (
|
|
664
|
+
if (toolCalls.some((call) => handsOffToDraft(call.name))) return "startingDraft";
|
|
633
665
|
if (changing) return "changing";
|
|
634
666
|
if (callingTools || toolCalls.length > 0) return "exploring";
|
|
635
667
|
return "thinking";
|
|
@@ -761,4 +793,4 @@ function reduceThreadFrame(state, frame) {
|
|
|
761
793
|
}
|
|
762
794
|
|
|
763
795
|
//#endregion
|
|
764
|
-
export { ARTIFACT_REQUEST_ENTRY, ARTIFACT_TOOL, ASK_TOOL, BRIEF_ENTRY, BUILD_STATUS_ENTRY, BUILD_TOOL, CHANGING_TOOLS, CODE_REQUEST_ENTRY, CODE_TOOL, CONNECTED_AGENT_MESSAGE_ENTRY, DRAFT_CARD_ENTRY, DRAFT_ENDED_ENTRY, EDITOR_MESSAGE_ENTRY, EMPTY_THREAD_STATE, EMPTY_THREAD_VIEW, LOOK_TOOL, PUSH_ENTRY, QUESTIONS_ENTRY, RECONCILE_ENTRY, RUN_STOPPED_ENTRY, START_DRAFT_TOOL, THREAD_ENDED_CLOSE_CODE, agentActivitySchema, artifactRequestDataSchema, buildStatusDataSchema, buildStatusSchema, codeRequestDataSchema, connectedAgentClientSchema, connectedAgentMessageDataSchema, editorMessageDataSchema, editorSelectionSchema, editorTextOf, editorWhereSchema, handOffDetailsSchema, handsOff, isSender, pushDataSchema, pushOutcomeSchema, questionsDataSchema, reconcileDataSchema, reduceThreadEvents, reduceThreadFrame, reduceThreadState, startedDraftCardSchema, startedDraftSchema, textOf, threadClientMessageSchema, threadSenderSchema, threadViewOf, touchKindSchema, touchSchema, touchedBatchSchema };
|
|
796
|
+
export { ARTIFACT_REQUEST_ENTRY, ARTIFACT_TOOL, ASK_TOOL, BRIEF_ENTRY, BUILD_STATUS_ENTRY, BUILD_TOOL, CHANGING_TOOLS, CODE_REQUEST_ENTRY, CODE_TOOL, CONNECTED_AGENT_MESSAGE_ENTRY, DRAFT_CARD_ENTRY, DRAFT_ENDED_ENTRY, EDITOR_MESSAGE_ENTRY, EMPTY_THREAD_STATE, EMPTY_THREAD_VIEW, LOOK_TOOL, PUSH_ENTRY, QUESTIONS_ENTRY, RECONCILE_ENTRY, RESTORE_DRAFT_TOOL, RUN_STOPPED_ENTRY, START_DRAFT_TOOL, THREAD_ENDED_CLOSE_CODE, agentActivitySchema, artifactRequestDataSchema, buildStatusDataSchema, buildStatusSchema, codeRequestDataSchema, connectedAgentClientSchema, connectedAgentMessageDataSchema, editorMessageDataSchema, editorSelectionSchema, editorTextOf, editorWhereSchema, handOffDetailsSchema, handsOff, handsOffToDraft, isSender, messageAttachmentSchema, pushDataSchema, pushOutcomeSchema, questionsDataSchema, reconcileDataSchema, reduceThreadEvents, reduceThreadFrame, reduceThreadState, startedDraftCardSchema, startedDraftSchema, textOf, threadClientMessageSchema, threadSenderSchema, threadViewOf, touchKindSchema, touchSchema, touchedBatchSchema };
|
package/package.json
CHANGED
package/src/drafts.ts
CHANGED
|
@@ -158,6 +158,22 @@ export type EndedDraft = {
|
|
|
158
158
|
endedAt: number;
|
|
159
159
|
};
|
|
160
160
|
|
|
161
|
+
/**
|
|
162
|
+
* A draft set aside without ending it (ADR 0046): who archived it, a member or Camox, and when.
|
|
163
|
+
* It keeps its id, changes, thread and code until it's restored or deleted.
|
|
164
|
+
*/
|
|
165
|
+
export type ArchivedDraft = {
|
|
166
|
+
draftId: string;
|
|
167
|
+
archivedBy: { id: string; name: string };
|
|
168
|
+
archivedAt: number;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* The oRPC error code a request naming an archived draft fails with: its `data` is an
|
|
173
|
+
* `ArchivedDraft`. Nothing reads or writes the draft until it's restored.
|
|
174
|
+
*/
|
|
175
|
+
export const DRAFT_ARCHIVED_ERROR_CODE = "DRAFT_ARCHIVED";
|
|
176
|
+
|
|
161
177
|
/**
|
|
162
178
|
* The oRPC error code a request naming an ended draft fails with. Its `data` is an `EndedDraft`,
|
|
163
179
|
* so a page can render Live and say who published or deleted the draft.
|
package/src/query-keys.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EndedDraft } from "./drafts";
|
|
1
|
+
import type { ArchivedDraft, EndedDraft } from "./drafts";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Use TypeScript to enforce 'camox' as the first query key to ensure they're all namespaced.
|
|
@@ -58,6 +58,14 @@ export const queryKeys = {
|
|
|
58
58
|
list: ["camox", "drafts", "list"],
|
|
59
59
|
// The draft a viewer is in, scoped to it like content.
|
|
60
60
|
get: ["camox", "drafts", "get"],
|
|
61
|
+
// Archived drafts (ADR 0046): under `all`, so whatever changes the drafts list refreshes it.
|
|
62
|
+
archived: ["camox", "drafts", "archived"],
|
|
63
|
+
},
|
|
64
|
+
// Publications (ADR 0045): the same for every viewer, whatever they're in.
|
|
65
|
+
publications: {
|
|
66
|
+
all: ["camox", "publications"],
|
|
67
|
+
list: ["camox", "publications", "list"],
|
|
68
|
+
get: ["camox", "publications", "get"],
|
|
61
69
|
},
|
|
62
70
|
// The Specialists of a scope: their reports and pending work.
|
|
63
71
|
specialists: {
|
|
@@ -100,6 +108,9 @@ export type InvalidationMessage = {
|
|
|
100
108
|
/** A draft was published or deleted: its viewers go back to Live. */
|
|
101
109
|
export type DraftEndedMessage = { type: "draftEnded" } & EndedDraft;
|
|
102
110
|
|
|
111
|
+
/** A draft was archived: its viewers go back to Live (ADR 0046). */
|
|
112
|
+
export type DraftArchivedMessage = { type: "draftArchived" } & ArchivedDraft;
|
|
113
|
+
|
|
103
114
|
/** A draft with code has a new revision, built with Camox's `sdkVersion`. */
|
|
104
115
|
export type RevisionAnnouncement = { draftId: string; revisionId: string; sdkVersion: string };
|
|
105
116
|
|
|
@@ -107,4 +118,8 @@ export type RevisionAnnouncement = { draftId: string; revisionId: string; sdkVer
|
|
|
107
118
|
export type RevisionMessage = { type: "revision" } & RevisionAnnouncement;
|
|
108
119
|
|
|
109
120
|
/** Everything the project room broadcasts. */
|
|
110
|
-
export type ProjectRoomMessage =
|
|
121
|
+
export type ProjectRoomMessage =
|
|
122
|
+
| InvalidationMessage
|
|
123
|
+
| DraftEndedMessage
|
|
124
|
+
| DraftArchivedMessage
|
|
125
|
+
| RevisionMessage;
|
package/src/threads.ts
CHANGED
|
@@ -81,6 +81,17 @@ export type PushOutcome = z.infer<typeof pushOutcomeSchema>;
|
|
|
81
81
|
*/
|
|
82
82
|
export const START_DRAFT_TOOL = "startDraft";
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* The agent on Live's tool restoring an archived draft and handing the editor to it, as
|
|
86
|
+
* `startDraft` does (ADR 0025, ADR 0046). A run whose call of it went through ends on the
|
|
87
|
+
* draft's card.
|
|
88
|
+
*/
|
|
89
|
+
export const RESTORE_DRAFT_TOOL = "restoreDraft";
|
|
90
|
+
|
|
91
|
+
/** Whether a call of the tool `name` hands the editor off to a draft, which ends the run on its card. */
|
|
92
|
+
export const handsOffToDraft = (name: string) =>
|
|
93
|
+
name === START_DRAFT_TOOL || name === RESTORE_DRAFT_TOOL;
|
|
94
|
+
|
|
84
95
|
/** The agent's tool building its code changes mid-turn, which the end of a turn also does. */
|
|
85
96
|
export const BUILD_TOOL = "build";
|
|
86
97
|
|
|
@@ -169,6 +180,7 @@ export const CHANGING_TOOLS: ReadonlySet<string> = new Set([
|
|
|
169
180
|
"addBackToLocale",
|
|
170
181
|
"addLocale",
|
|
171
182
|
"applyFindingFix",
|
|
183
|
+
"copyFromPastWork",
|
|
172
184
|
"createBlock",
|
|
173
185
|
"createCollectionRecord",
|
|
174
186
|
"createPage",
|
|
@@ -191,17 +203,26 @@ export const CHANGING_TOOLS: ReadonlySet<string> = new Set([
|
|
|
191
203
|
"write",
|
|
192
204
|
]);
|
|
193
205
|
|
|
194
|
-
/**
|
|
195
|
-
|
|
206
|
+
/**
|
|
207
|
+
* The draft a `startDraft` call started, or a `restoreDraft` call restored, as its result's
|
|
208
|
+
* details name it for the card.
|
|
209
|
+
*/
|
|
210
|
+
export const startedDraftCardSchema = z.object({
|
|
211
|
+
draftId: z.string(),
|
|
212
|
+
name: z.string(),
|
|
213
|
+
/** The agent restored the archived draft rather than starting it (ADR 0046). */
|
|
214
|
+
restored: z.literal(true).optional(),
|
|
215
|
+
});
|
|
196
216
|
export type StartedDraftCard = z.infer<typeof startedDraftCardSchema>;
|
|
197
217
|
|
|
198
218
|
/**
|
|
199
219
|
* Where a draft a Live thread's card names stands, as the thread looks it up whenever it's shown
|
|
200
|
-
* (ADR 0025): its current name, or its last once it ended, and how it ended.
|
|
201
|
-
*
|
|
202
|
-
*
|
|
220
|
+
* (ADR 0025): its current name, or its last once it ended, and how it ended. An archived draft
|
|
221
|
+
* hasn't ended: `archived` says it's set aside until someone restores it (ADR 0046). Never written
|
|
222
|
+
* into the transcript, so the model's cached prompt keeps up. A name cleared by a rename is null:
|
|
223
|
+
* the card keeps the name the agent gave it.
|
|
203
224
|
*/
|
|
204
|
-
export type DraftCardState = { name: string | null; ended?: DraftOutcome };
|
|
225
|
+
export type DraftCardState = { name: string | null; ended?: DraftOutcome; archived?: true };
|
|
205
226
|
|
|
206
227
|
/** The drafts a Live thread's cards name, by id, as the thread last looked them up. */
|
|
207
228
|
export type DraftCardStates = Readonly<Record<string, DraftCardState>>;
|
|
@@ -232,6 +253,15 @@ export const isSender = (data: unknown): data is ThreadSender =>
|
|
|
232
253
|
export const connectedAgentClientSchema = z.object({ name: z.string(), verified: z.boolean() });
|
|
233
254
|
export type ConnectedAgentClient = z.infer<typeof connectedAgentClientSchema>;
|
|
234
255
|
|
|
256
|
+
/** An Attachment a Connected Agent's message carries: an image the agent sees with it. */
|
|
257
|
+
export const messageAttachmentSchema = z.object({
|
|
258
|
+
id: z.string(),
|
|
259
|
+
filename: z.string(),
|
|
260
|
+
mimeType: z.string(),
|
|
261
|
+
url: z.string(),
|
|
262
|
+
});
|
|
263
|
+
export type MessageAttachmentData = z.infer<typeof messageAttachmentSchema>;
|
|
264
|
+
|
|
235
265
|
/**
|
|
236
266
|
* What a Connected Agent's message entry records: the member it acts as, its client, the
|
|
237
267
|
* operation id it was sent with, and whether it answers the agent's questions (ADR 0042).
|
|
@@ -241,6 +271,8 @@ export const connectedAgentMessageDataSchema = z.object({
|
|
|
241
271
|
client: connectedAgentClientSchema,
|
|
242
272
|
operationId: z.string().optional(),
|
|
243
273
|
answer: z.boolean().optional(),
|
|
274
|
+
/** The images the message carries for the agent to see, as studios list them (ADR 0044). */
|
|
275
|
+
attachments: z.array(messageAttachmentSchema).optional(),
|
|
244
276
|
});
|
|
245
277
|
export type ConnectedAgentMessageData = z.infer<typeof connectedAgentMessageDataSchema>;
|
|
246
278
|
|
|
@@ -258,13 +290,18 @@ export const editorMessageDataSchema = threadSenderSchema.extend({
|
|
|
258
290
|
});
|
|
259
291
|
|
|
260
292
|
/**
|
|
261
|
-
* A draft the agent on Live started with `startDraft`,
|
|
262
|
-
* the run that
|
|
293
|
+
* A draft the agent on Live started with `startDraft`, or restored with `restoreDraft`, and the
|
|
294
|
+
* operation ids of the messages of the run that did: the studio that sent one of them enters the draft, if it still shows
|
|
263
295
|
* Live.
|
|
264
296
|
*/
|
|
265
297
|
export const startedDraftSchema = z.object({
|
|
266
298
|
draftId: z.string(),
|
|
267
299
|
operationIds: z.array(z.string()),
|
|
300
|
+
/**
|
|
301
|
+
* The agent restored the archived draft rather than starting it: its thread goes on from its
|
|
302
|
+
* own messages, without the run's.
|
|
303
|
+
*/
|
|
304
|
+
restored: z.literal(true).optional(),
|
|
268
305
|
});
|
|
269
306
|
export type StartedDraft = z.infer<typeof startedDraftSchema>;
|
|
270
307
|
|
|
@@ -326,6 +363,8 @@ export type ThreadMessage =
|
|
|
326
363
|
client: ConnectedAgentClient;
|
|
327
364
|
text: string;
|
|
328
365
|
answer: boolean;
|
|
366
|
+
/** The images it carries for the agent to see, if any (ADR 0044). */
|
|
367
|
+
attachments?: MessageAttachmentData[];
|
|
329
368
|
}
|
|
330
369
|
/** Camox's own message, starting a turn it began itself: why it did. */
|
|
331
370
|
| { id: string; from: "camox"; text: string }
|
|
@@ -346,9 +385,10 @@ export type ThreadMessage =
|
|
|
346
385
|
/**
|
|
347
386
|
* In place of the agent's message, for a Live turn handed off to a draft the agent started:
|
|
348
387
|
* the draft's card, with its current name, which opens it. Once the draft ended, it has its
|
|
349
|
-
* last name and how it ended, and opens nothing.
|
|
388
|
+
* last name and how it ended, and opens nothing. While the draft is archived, `archived` is set,
|
|
389
|
+
* and the card offers to restore it. The turn is finished.
|
|
350
390
|
*/
|
|
351
|
-
| ({ id: string; from: "draft"; ended?: DraftOutcome } & StartedDraftCard)
|
|
391
|
+
| ({ id: string; from: "draft"; ended?: DraftOutcome; archived?: true } & StartedDraftCard)
|
|
352
392
|
/**
|
|
353
393
|
* A member's push to the draft's code from their own checkout: who pushed, their commits'
|
|
354
394
|
* subjects, oldest first, and how the pushed head built. It's no turn: the agent doesn't
|
|
@@ -441,6 +481,7 @@ type ThreadStep = { id: string } & (
|
|
|
441
481
|
client: ConnectedAgentClient;
|
|
442
482
|
text: string;
|
|
443
483
|
answer: boolean;
|
|
484
|
+
attachments?: MessageAttachmentData[];
|
|
444
485
|
}
|
|
445
486
|
/** Camox starting a turn of its own, saying why. */
|
|
446
487
|
| { type: "camox"; text: string }
|
|
@@ -618,6 +659,7 @@ function threadStepOf(entry: EntryRecord): ThreadStep | undefined {
|
|
|
618
659
|
client: { name: data.client.name, verified: data.client.verified },
|
|
619
660
|
text: editorTextOf(message.content),
|
|
620
661
|
answer: data.answer ?? false,
|
|
662
|
+
...(data.attachments?.length && { attachments: data.attachments }),
|
|
621
663
|
}
|
|
622
664
|
);
|
|
623
665
|
}
|
|
@@ -644,7 +686,7 @@ function threadStepOf(entry: EntryRecord): ThreadStep | undefined {
|
|
|
644
686
|
if (details?.final && details.answer) return { id, type: "answer", text: details.answer };
|
|
645
687
|
}
|
|
646
688
|
const card =
|
|
647
|
-
message.toolName
|
|
689
|
+
handsOffToDraft(message.toolName) && !message.isError
|
|
648
690
|
? startedDraftCardSchema.safeParse(message.details).data
|
|
649
691
|
: undefined;
|
|
650
692
|
return card ? { id, type: "draft", ...card } : { id, type: "tools" };
|
|
@@ -722,6 +764,7 @@ export function threadViewOf({
|
|
|
722
764
|
client: step.client,
|
|
723
765
|
text: step.text,
|
|
724
766
|
answer: step.answer,
|
|
767
|
+
...(step.attachments && { attachments: step.attachments }),
|
|
725
768
|
});
|
|
726
769
|
waiting = step.id;
|
|
727
770
|
break;
|
|
@@ -755,7 +798,9 @@ export function threadViewOf({
|
|
|
755
798
|
from: "draft",
|
|
756
799
|
draftId: step.draftId,
|
|
757
800
|
name: draft?.name ?? step.name,
|
|
801
|
+
...(step.restored && { restored: true as const }),
|
|
758
802
|
...(draft?.ended && { ended: draft.ended }),
|
|
803
|
+
...(draft?.archived && { archived: true as const }),
|
|
759
804
|
});
|
|
760
805
|
}
|
|
761
806
|
endTurn();
|
|
@@ -834,7 +879,7 @@ function activityOf({
|
|
|
834
879
|
// the agent's.
|
|
835
880
|
if (toolCalls.some((call) => handsOff(call.name))) return handedOffActivity ?? "changing";
|
|
836
881
|
if (checking) return "checking";
|
|
837
|
-
if (
|
|
882
|
+
if (toolCalls.some((call) => handsOffToDraft(call.name))) return "startingDraft";
|
|
838
883
|
if (changing) return "changing";
|
|
839
884
|
if (callingTools || toolCalls.length > 0) return "exploring";
|
|
840
885
|
return "thinking";
|